I am trying to figure out why my custom board doesn't wake up and I was looking at the lpcxpressor54102_power_manager_lpc example.
Part of the example is the API_InitWakeupPin() function that has this code:
/* Configure the Input Mux block and connect the trigger source to PinInt channle. */
INPUTMUX_Init(INPUTMUX);
INPUTMUX_AttachSignal(INPUTMUX, kPINT_PinInt0, APP_USER_WAKEUP_KEY_INPUTMUX_SEL); /* Using channel 0. */
INPUTMUX_Deinit(INPUTMUX); /* Turnoff clock to inputmux to save power. Clock is only needed to make changes */
/* Enable wakeup for PinInt0. */
SYSCON->STARTERSET[0] |= APP_SYSCON_STARTER_MASK; /* GPIO pin interrupt 0 wake-up. */
/* Configure the interrupt for SW pin. */
PINT_Init(PINT);
PINT_PinInterruptConfig(PINT, kPINT_PinInt0, kPINT_PinIntEnableFallEdge, pint_intr_callback);
PINT_EnableCallback(PINT); /* Enable callbacks for PINT */
EnableDeepSleepIRQ(PIN_INT0_IRQn);
Granted, I haven't been able to get it to work yet, but the line with SYSCON->STARTERSET[0] does not appear to be correct to me. APP_SYSCON_STARTER_MASK is 0x4U which would cause a reserved bit in STARTERSET[0] to be set.
The EnableDeepSleepIRQ() function called at the end of the code sets the STARTERSET[0] PINT0 bit and enables the Int0 interrupt which does appear to be correct.
Is this an error in the example code?
解決済! 解決策の投稿を見る。
For some odd reason I don't understand, I had to set the 12 MHz clock right before going to sleep. It wakes up now.
Hi, James,
INPUTMUX_AttachSignal(INPUTMUX, kPINT_PinInt0, APP_USER_WAKEUP_KEY_INPUTMUX_SEL); /* Using channel 0. */
SYSCON->STARTERSET[0] |= APP_SYSCON_STARTER_MASK; /* GPIO pin interrupt 0 wake-up. */
For the above code, this is the definition:
#define APP_USER_WAKEUP_KEY_INPUTMUX_SEL kINPUTMUX_GpioPort0Pin24ToPintsel
In other words, the example uses PIO0_14 pin to trigger PINT0 pin interrupt via input_mux module.
Pls check which pin you are using to trigger the PINT0 interrupt for your application. For example, if you use PIO0_1, you can use the code:
INPUTMUX_AttachSignal(INPUTMUX, kPINT_PinInt0, kINPUTMUX_GpioPort0Pin1ToPintsel);
For the second line:
#define APP_SYSCON_STARTER_MASK SYSCON_STARTER_PINT5_MASK
SYSCON->STARTERSET[0] |= APP_SYSCON_STARTER_MASK; /* GPIO pin interrupt 0 wake-up. */
I suppose it is incorrect, the if you use PINT0 to wake-up from deep-sleep mode, pls try to use the line:
SYSCON->STARTERSET[0] |= SYSCON_STARTER_PINT0_MASK; or
SYSCON->STARTERSET[0] |= 0x20;
Hope it can help you
BR
XiangJun Rong
typedef enum _inputmux_connection_t
{
/*!< Frequency measure. */
kINPUTMUX_ClockInToFreqmeas = 0U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_Irc12MhzToFreqmeas = 1U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_WdtOscToFreqmeas = 2U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_32KhzOscToFreqmeas = 3U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_MainClkToFreqmeas = 4U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin4ToFreqmeas = 5U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin20ToFreqmeas = 6U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin24ToFreqmeas = 7U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin4ToFreqmeas = 8U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
/*!< Pin Interrupt. */
kINPUTMUX_GpioPort0Pin0ToPintsel = 0U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin1ToPintsel = 1U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin2ToPintsel = 2U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin3ToPintsel = 3U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin4ToPintsel = 4U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin5ToPintsel = 5U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin6ToPintsel = 6U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin7ToPintsel = 7U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin8ToPintsel = 8U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin9ToPintsel = 9U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin10ToPintsel = 10U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin11ToPintsel = 11U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin12ToPintsel = 12U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin13ToPintsel = 13U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin14ToPintsel = 14U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin15ToPintsel = 15U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin16ToPintsel = 16U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin17ToPintsel = 17U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin18ToPintsel = 18U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin19ToPintsel = 19U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin20ToPintsel = 20U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin21ToPintsel = 21U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin22ToPintsel = 22U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin23ToPintsel = 23U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin24ToPintsel = 24U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin25ToPintsel = 25U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin26ToPintsel = 26U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin27ToPintsel = 27U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin28ToPintsel = 28U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin29ToPintsel = 29U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin30ToPintsel = 30U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort0Pin31ToPintsel = 31U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin0ToPintsel = 32U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin1ToPintsel = 33U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin2ToPintsel = 34U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin3ToPintsel = 35U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin4ToPintsel = 36U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin5ToPintsel = 37U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin6ToPintsel = 38U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin7ToPintsel = 39U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin8ToPintsel = 40U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin9ToPintsel = 41U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin10ToPintsel = 42U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin11ToPintsel = 43U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin12ToPintsel = 44U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin13ToPintsel = 45U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin14ToPintsel = 46U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin15ToPintsel = 47U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin16ToPintsel = 48U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin17ToPintsel = 49U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin18ToPintsel = 50U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin19ToPintsel = 51U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin20ToPintsel = 52U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin21ToPintsel = 53U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin22ToPintsel = 54U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin23ToPintsel = 55U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin24ToPintsel = 56U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin25ToPintsel = 57U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin26ToPintsel = 58U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin27ToPintsel = 59U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin28ToPintsel = 60U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin29ToPintsel = 61U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin30ToPintsel = 62U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_GpioPort1Pin31ToPintsel = 63U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
/*!< DMA ITRIG. */
kINPUTMUX_Adc0SeqaIrqToDma = 0U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_Adc0SeqbIrqToDma = 1U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_Sct0DmaReq0ToDma = 2U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_Sct0DmaReq1ToDma = 3U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_Ctimer32B0M0ToDma = 4U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_Ctimer32B0M1ToDma = 5U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_Ctimer32B1M0ToDma = 6U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_Ctimer32B2M0ToDma = 7U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_Ctimer32B2M1ToDma = 8U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_Ctimer32B3M0ToDma = 9U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_Ctimer32B4M0ToDma = 10U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_Ctimer32B4M1ToDma = 11U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_PinInt0ToDma = 12U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_PinInt1ToDma = 13U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_PinInt2ToDma = 14U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_PinInt3ToDma = 15U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_Otrig0ToDma = 16U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_Otrig1ToDma = 17U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_Otrig2ToDma = 18U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_Otrig3ToDma = 19U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
/*!< DMA OTRIG. */
kINPUTMUX_DmaUsart0RxTrigoutToTriginChannels = 0U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaUsart0TxTrigoutToTriginChannels = 1U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaUsart1RxTrigoutToTriginChannels = 2U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaUsart1TxTrigoutToTriginChannels = 3U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaUsart2RxTrigoutToTriginChannels = 4U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaUsart2TxTrigoutToTriginChannels = 5U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaUsart3RxTrigoutToTriginChannels = 6U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaUsart3TxTrigoutToTriginChannels = 7U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaSpi0RxTrigoutToTriginChannels = 8U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaSpi0TxTrigoutToTriginChannels = 9U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaSpi1RxTrigoutToTriginChannels = 10U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaSpi1TxTrigoutToTriginChannels = 11U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaI2c0SlaveTrigoutToTriginChannels = 12U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaI2c0MasterTrigoutToTriginChannels = 13U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaI2c1SlaveTrigoutToTriginChannels = 14U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaI2c1MasterTrigoutToTriginChannels = 15U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaI2c2SlaveTrigoutToTriginChannels = 16U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaI2c2MasterTrigoutToTriginChannels = 17U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaI2c0MonitorTrigoutToTriginChannels = 18U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaI2c1MonitorTrigoutToTriginChannels = 19U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
kINPUTMUX_DmaI2c2MonitorTrigoutToTriginChannels = 20U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
} inputmux_connection_t;
The STARTERSET register is set in EnableDeepSleepIRQ():
void EnableDeepSleepIRQ(IRQn_Type interrupt)
{
uint32_t intNumber = (uint32_t)interrupt;
uint32_t index = 0;
while (intNumber >= 32u)
{
index++;
intNumber -= 32u;
}
SYSCON->STARTERSET[index] = 1u << intNumber;
EnableIRQ(interrupt); /* also enable interrupt at NVIC */
}
This is what I have:
/* Configure the Input Mux block and connect the trigger source to PinInt channel. */
INPUTMUX_Init(INPUTMUX);
INPUTMUX_AttachSignal(INPUTMUX, POWER_WAKEUP_DEST_PERIPHERAL, POWER_WAKEUP_KEY_INPUTMUX_SEL);
INPUTMUX_Deinit(INPUTMUX); /* Turnoff clock to inputmux to save power. Clock is only needed to make changes */
PINT_Init(PINT);
PINT_PinInterruptConfig(PINT, POWER_WAKEUP_DEST_PERIPHERAL, kPINT_PinIntEnableFallEdge, power_manager_pint_intr_callback);
PINT_EnableCallback(PINT);
EnableDeepSleepIRQ(POWER_WAKEUP_KEY_INTERRUPT);
The defines are:
#define POWER_WAKEUP_DEST_PERIPHERAL (kPINT_PinInt4)
#define POWER_WAKEUP_KEY_INPUTMUX_SEL (kINPUTMUX_GpioPort1Pin4ToPintsel)
#define POWER_WAKEUP_KEY_INTERRUPT (PIN_INT4_IRQn)
So it looks to me like I should be using Port 1, pin 4 which is what the button is connected to (the button works when not sleeping). The peripherals tool has the Port 1, pin 4 GPIO assigned to INT4 (pin 18).
Hi,
If you use the PIO1_4 as hardware button to trigger PINT4 interrupt, and use PINT4 module to wake-up the deep-sleep, I suggest you test in two steps.
The first step is you can enter the PINT4 ISR after you press PIO1_4 button, in the case, the core works normally.
After the first step works fine, you can take the second step, use the PINT4 to wake-up the core after the core enters deep-sleep.
Hope it can help you
BR
XiangJun Rong
Just to add some more data. These are what I think are the required registers immediately before calling POWER_EnterDeepSleep():
SYSCON->STARTER[0] = 0x0
SYSCON->STARTER[1] = 0x2
PINT->IENF = 0x1F
PINT->IENR = 0x1F
INPUTMUX->PINTSEL[0] = 32
INPUTMUX->PINTSEL[1] = 33
INPUTMUX->PINTSEL[2] = 34
INPUTMUX->PINTSEL[3] = 35
INPUTMUX->PINTSEL[4] = 36
NVIC->ISER[0] = 0x32001e0
NVIC->ISER[1] = 0x2
Keep in mind that I have five buttons on this board, all with interrupts for rising or falling. They all work. I'm trying to wake on the button connected to pin 18 (Port 1, Pin 4). So I see PINTSEL[4] set to 36 which looks correct. STARTER[1] = 0x2 which corresponds to wake on PINT4. STARTER[1] is 0x2 which corresponds to PINT4. It looks like NVIC->ISER[1] is also 0x2 which is PINT4.
I already know the ISR for the GPIO works. The button is working before it sleeps. I'm getting interrupts on button push and release. All of the PINT configurations above in my code are probably redundant since PINT is configured in peripherals.c.
I commented them out and tried again, same result.
The second step doesn't work. That's the problem.
I thought it might be crashing on wake (it may still be) so I used a spare GPIO on our board. I set it high before sleeping and low immediately after returning from POWER_EnterDeepSleep(). The GPIO goes high and when I push the button again, it does not go low. Current doesn't change either. In my experience if it woke and crashed on an assertion (or something else) current would increase. We're not seeing that.
For some odd reason I don't understand, I had to set the 12 MHz clock right before going to sleep. It wakes up now.