2018-01-30 03:26 PM
I wish to place my Nucleo system into STOP1 mode and then have it wake up when a character is received on UART3. With the code below, I can successfully stop all the clocks and halt at the 'WFI' instruction. When a character is sent to the UART from my terminal, the interrupt routine runs and echoes the character back to me as expected, but the code remains stuck at the 'WFI' instruction (inside the call to HAL_PWREx_EnterSTOP1Mode). I have tried the code with and without the debugger and get the same results. How do I get the code to continue past the 'WFI'? My apologies for my use of the low level hardware instructions....I'm an old-school hardware guy so this is where I go when things aren't working!
//**************************************************************************************
__HAL_RCC_PWR_CLK_ENABLE();
/* Ensure that MSI is wake-up system clock */
__HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI);
USART3->
CR1
&= ~0x00000001;
// UE bit must be 0 to change WUS bits in CR3
USART3->
CR3
|= 0x00700000;
// set WFIE bit and WUS = 11 (RXNE interrupt)
USART3->
CR1
|= 0x00000002;
// set the UESM bit to allow UART to wake up the MCU from stop mode
USART3->
CR1
|= 0x00000001;
// re-enable UART3
SCB->
SCR
&= ~0x02;
// clear the SLEEPONEXIT bit so the system will restart
DBGMCU->
CR
&= ~0x02;
// clear the DBG_STOP bit so debugger does not get clock signal
HAL_PWREx_EnterSTOP1Mode
(PWR_STOPENTRY_WFI);
// System should now be stopped here waiting for UART interrupt to occur
__HAL_RCC_PWR_CLK_ENABLE();
<-----I NEVER GET TO HERE!
//*********************************************************************************************
void
USART3_IRQHandler(
void)
{
if
((USART3->
ISR
& 0x20) == 0x20)
// check for RXNE bit
{
* UART3_RX_Pointer = USART3->
RDR
;
// read available byte which should clear the RXNE flag
UART3_RX_Pointer ++;
// update pointer
while
((USART3->
ISR
& 0x80) != 0x80);
// wait for TX data register empty (or ready).
USART3->
TDR
= (
uint8_t
)USART3->
RDR
;
//echo character to the COM port
}
}
//*************************************************************************************************
#exit-stop #stop-mode #usartSolved! Go to Solution.
2018-02-19 02:56 AM
I would suggest staring with the CubeMX example.
If your clock source to the LPUART is HSI (and it should) but your system clock on wakeup is MSI you might have to re-enable the HSI clock in the LPUART interrupt, see
https://community.st.com/0D50X00009XkW1lSAF
I don't see the clear of theWUF flag and the UESM flag which is recommended
When the debugger is connected you should disable systick interrupt and setDBG_STOP inDBGMCU->CR or you'll have unpredictable behavior.
See also
2018-02-19 02:56 AM
I would suggest staring with the CubeMX example.
If your clock source to the LPUART is HSI (and it should) but your system clock on wakeup is MSI you might have to re-enable the HSI clock in the LPUART interrupt, see
https://community.st.com/0D50X00009XkW1lSAF
I don't see the clear of theWUF flag and the UESM flag which is recommended
When the debugger is connected you should disable systick interrupt and setDBG_STOP inDBGMCU->CR or you'll have unpredictable behavior.
See also
2018-02-19 10:39 AM
Thank you Clonimus74! I had the clearing of the UESM enable bit in the code immediately after the stop command (not shown above). By moving the bit clear into the ISR, all is now good!
//*********************************************************************************************
void
USART3_IRQHandler(
void)
{
if
((USART3->
ISR
& 0x20) == 0x20)
// check for RXNE bit
{
* UART3_RX_Pointer = USART3->
RDR
;
// read available byte which should clear the RXNE flag
USART3->
CR1
&= ~0x00000002;
// clear UESM bit (
wakeup
in STOP mode disabled)UART3_RX_Pointer ++;
// update pointer
while
((USART3->
ISR
& 0x80) != 0x80);
// wait for TX data register empty (or ready).
USART3->
TDR
= (
uint8_t
)USART3->
RDR
;
//echo character to the COM port
}
}