cancel
Showing results for 
Search instead for 
Did you mean: 

Exit STOP mode using USART on STM32L496

pauljohnston
Associate II
Posted on January 31, 2018 at 00:26

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 #usart
1 ACCEPTED SOLUTION

Accepted Solutions
Clonimus74
Senior II
Posted on February 19, 2018 at 11:56

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

https://community.st.com/0D50X00009XkfHjSAJ

View solution in original post

2 REPLIES 2
Clonimus74
Senior II
Posted on February 19, 2018 at 11:56

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

https://community.st.com/0D50X00009XkfHjSAJ

pauljohnston
Associate II
Posted on February 19, 2018 at 19:39

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

         }

}