USART with DMA after stop2 mode not working.
Hi folks,
I,m using STM32l4 MCU, I have configured USART3 with DMA1 with 1Mb/s baudrate. My concern is its worked fine if I don't put MCU in a Stop2 mode state. But if I put MCU in Stop2 mode state after waking up its not working. Here is the uart Init and sleep function:
void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
/* DMA1_Channel2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
/* DMA1_Channel3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
}
void MX_USART3_UART_Init(void)
{
huart3.Instance = USART3;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.BaudRate = 1000000;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE; //*** DEBUG ONLY; UART_HWCONTROL_RTS_CTS;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart3) != HAL_OK)
{
Error_Handler();
}
}
/*MSPInit*/
else if(huart->Instance==USART3)
{
/* Peripheral clock enable */
__HAL_RCC_USART3_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/**USART3 GPIO Configuration
PC4 ------> USART3_TX
PC5 ------> USART3_RX
PB1 ------> USART3_RTS
PD11 ------> USART3_CTS
*/
GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* USART3 DMA Init */
/* USART3_RX Init */
hdma_usart3_rx.Instance = DMA1_Channel3;
hdma_usart3_rx.Init.Request = DMA_REQUEST_2;
hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart3_rx.Init.Mode = DMA_CIRCULAR;//DMA_NORMAL;
hdma_usart3_rx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_usart3_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(huart,hdmarx,hdma_usart3_rx);
/* USART3_TX Init */
hdma_usart3_tx.Instance = DMA1_Channel2;
hdma_usart3_tx.Init.Request = DMA_REQUEST_2;
hdma_usart3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart3_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart3_tx.Init.Mode = DMA_NORMAL;
hdma_usart3_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_usart3_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(huart,hdmatx,hdma_usart3_tx);
/* USART3 interrupt Init */
HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART3_IRQn);
}
/*Here is the Sleep functionality */
while (1){
/*Disabling Modules and powers............*/
DisablePWR();
DeInit_Modules();
/*Enter in STOP2 MODE.....................*/
HAL_SuspendTick();
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
HAL_ResumeTick();
/*Enabling and Initializing the modules and powers........*/
if (Init_Modules()){
HAL_Delay(10);
Daug_Board_PinSet(IO_LED_ALL_OFF, DB_LED_ALL, ALL_OFF);
if (wakeup_required()){
break;
}
/* else just keep the OK LED on for 100msec and then back to sleep. */
ERRTS_Delay(100);
Daug_Board_PinSet(IO_LED_ALL_OFF, DB_LED_ALL, ALL_OFF);
}
}
bool Init_Modules(void){
/*Exiting from the STOP2Mode and Re-Initializing the modules...............................*/
if (do_wakeup){
do_wakeup = false;
wake_flag = Set;
SystemClock_Config();
MX_DMA_Init();
MX_USART3_UART_Init();
MX_SPI2_Init();
enablePWR();
// MX_GPIO_Init();
MX_USART2_UART_Init();
MX_I2C1_Init();
MX_UART4_Init(); // BLE
MX_SDMMC1_SD_Init();
MX_ADC1_Init();
MX_SPI3_Init();
return true;
}
return false;
}
NOTE::
void HAL_PWREx_EnterSTOP2Mode(uint8_t STOPEntry)
{
/* Check the parameter */
assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
/* Set Stop mode 2 */
MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_STOP2);
/* Set SLEEPDEEP bit of Cortex System Control Register */
//SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
/* Select Stop mode entry --------------------------------------------------*/
if(STOPEntry == PWR_STOPENTRY_WFI)
{
/* Request Wait For Interrupt */
__WFI();
}
else
{
/* Request Wait For Event */
__SEV();
__WFE();
__WFE();
}
/* Reset SLEEPDEEP bit of Cortex System Control Register */
// CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
}
By removing deepsleep set and clear instruction it start working without any problem, its looks like I,m missing to enable some specific clock which is not included in SystemClock_Config();
