STM32L0's UART1 not triggering interruption after waking up from stop1 mode
I'm using a STM32L051C8T6 in a custom board. The software function is to enter stop mode to reduce the current consumption and only wake the MCU up with GPIO EXTI, RTC wakeup timer and UART wake up.
The device is entering the low power mode and exiting successfully, but I'm facing issues with my UART after waking up. My UART is configured to use DMA on Rx and Tx, but now I'm only using the DMA on Tx, for testing purpose.
My problem is that after waking up via UART, I want to keep the microcontroller awaken attending to configuration commands, until receive a configuration ending command. However, the MCU wakes with the USART config command, but it's unable to trigger the UART RxEventCallback via DMA.
I think, maybe the MCU just need an specific configuration after waking up to make the UART Rx callback via DMA work well.
See the code below:
Part 1 of the code:
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART2_UART_Init();
MX_USART1_UART_Init();
MX_ADC_Init();
MX_TIM2_Init();
MX_RTC_Init();
/* USER CODE BEGIN 2 */
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, at_serial.rx_buffer, sizeof(at_serial.rx_buffer));
wakeUpSelection.WakeUpEvent = UART_WAKEUP_ON_STARTBIT;
HAL_UARTEx_StopModeWakeUpSourceConfig(&huart1, wakeUpSelection);
HAL_UARTEx_EnableStopMode(&huart1);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_WUF);
HAL_DBGMCU_EnableDBGStopMode();
HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED);
ATSerial_Init(&at_serial,&huart1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_BUSY)) {}
HAL_SuspendTick();
HAL_PWR_EnableSleepOnExit();
HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
Part 2 of the code:
void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
{
if (huart == &huart1)
{
HAL_ResumeTick();
SystemClock_Config();
__enable_irq();
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_WUF);
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, at_serial.rx_buffer, sizeof(at_serial.rx_buffer));
if(strncmp((char *)at_serial.rx_buffer, WAKE_UP_STR, strlen(WAKE_UP_STR))==0){
HAL_UART_Transmit(&huart1, (uint8_t *)CFG_MODE_STR, strlen(CFG_MODE_STR), 1000);
while(1);
HAL_UART_Transmit(&huart1, (uint8_t *)EXIT_CFG_MODE_STR, strlen(EXIT_CFG_MODE_STR), 1000);
}
HAL_UARTEx_StopModeWakeUpSourceConfig(&huart1, wakeUpSelection);
HAL_UARTEx_EnableStopMode(&huart1);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_WUF);
memset(at_serial.rx_buffer, 0, sizeof(at_serial.rx_buffer));
}
}At line 14 of part 2 of the code "the while(1)" will be used to check if a exit command has been sent. For now, I didn't change this yet, because I want to discover why the it doesn't trigger any interruption.
Part 3 of the code:
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
SystemClock_Config();
HAL_ResumeTick();
if(huart == &huart1){
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
ATSerial_Process_CMD(&at_serial);
}else{
if(huart == &huart2){
uart_rx_complete = 1;
__HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, sim.rx_buffer, Y7080_RX_BUFFER_SIZE);
}
}
}
The Rx pin is configured with internal pull-up to avoid floating pin waking up the MCU every time. And also the UART is clocked by the HSI(16MHz).
