UART Wakeup Callback called twice when receive uart message longer than 1 char
Hi,
I am currently trying to receive uart message when the MCU is in stop mode on a Nucleo-L073Rz board.
To do this I first wake up the mcu on uart start bit, and when the mcu receive the uart idle event.
I can then treat the received message in the main loop before entering again the main loop.
It works great when the received message is only one char long.
However if the received message is longer, the HAL_UARTEx_WakeupCallback is called a second time after all treatment has already be done.
Which is a problem, because it wake up the MCU whereas It doesn't trigger HAL_UARTEx_RxEventCallback in order to stop the mcu again.
I am quite new in embedded software so maybe I have to make some routine or clear flag, but I have no idea.
How does I assure the HAL_UARTEx_WakeupCallback not to be called twice ?
#define RX_BUFFER_SIZE 20
uint8_t charBuffer = 0;
uint8_t rxBuffer[RX_BUFFER_SIZE] = {0};
volatile uint8_t uartMessageCompleted = 0;
uint8_t enableStopMode = 0;
void enterStopMode()
{
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, RESET); // Green pin
// Suspend Tick increment to prevent wakeup by Systick interrupt.
// Otherwise the Systick interrupt will wake up the device within 1ms (HAL time base)
HAL_SuspendTick();
// Enter Stop Mode
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}
void leaveStopMode()
{
// Set system clock back to ... oscillator because when exiting Stop mode by using an interrupt or a wake up event,
// ... oscillator is selected as system clock
SystemClock_Config ();
//Resume Tick interrupt if disabled prior to Stop mode entry
HAL_ResumeTick();
}
void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
{
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, SET); // Green pin
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_10); // Yellow pin
leaveStopMode();
enableStopMode = 0; // To prevent the mcu to enter stop mode
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_10); // Yellow pin
}
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, SET); // Green pin
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_12); // Blue pin
if(huart->Instance == USART2)
{
uartMessageCompleted = 1; // Indicate uart message can be treated
enableStopMode = 1; // Accept the mcu to enter stop mode
HAL_UARTEx_ReceiveToIdle_IT(&huart2, rxBuffer, RX_BUFFER_SIZE);
}
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_12); // Blue pin
}
void commandTreatment()
{
//printf((char*)rxBuffer);
if (!strcmp((char*)rxBuffer, "help"))
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_9); // Pink pin
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_9); // Pink pin
}
else
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_9); // Pink pin
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_9); // Pink pin
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_9); // Pink pin
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_9); // Pink pin
}
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
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_USART2_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
printf("SandboxStopMode\n\r");
HAL_UARTEx_ReceiveToIdle_IT(&huart2, rxBuffer, RX_BUFFER_SIZE);
// set the wake-up event: specify wake-up on start-bit detection
UART_WakeUpTypeDef wakeUpSelection;
wakeUpSelection.WakeUpEvent = UART_WAKEUP_ON_STARTBIT;
if (HAL_UARTEx_StopModeWakeUpSourceConfig(&huart2, wakeUpSelection)!= HAL_OK)
{
Error_Handler();
}
// Enable the UART2 Wake UP from stop mode Interrupt
__HAL_UART_ENABLE_IT(&huart2, UART_IT_WUF);
// enable MCU wake-up by UART2
HAL_UARTEx_EnableStopMode(&huart2);
printf("Enter Stop mode in 3 seconds\n\r");
HAL_Delay(3000);
enableStopMode = 1;
while (1)
{
if (uartMessageCompleted == 1)
{
// Reset indication
uartMessageCompleted = 0;
// Treat userCommand
commandTreatment();
}
if (enableStopMode == 1)
{
enterStopMode();
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
In order to follow when and how many times I entered callback function, I activate pin accordingly.
See capture bellow:
Yellow: HAL_UARTEx_WakeupCallback
Blue: HAL_UARTEx_RxEventCallback
Pink: Command treatment
Green: Run Mode
