cancel
Showing results for 
Search instead for 
Did you mean: 

USART with DMA after stop2 mode not working.

ARehm
Associate III

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();

3 REPLIES 3
ARehm
Associate III

Here is the clock configuration:

void SystemClock_Config(void)

{

 RCC_OscInitTypeDef RCC_OscInitStruct = {0};

 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

 HAL_PWR_EnableBkUpAccess();

 __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_MEDIUMHIGH);

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_LSE

 |RCC_OSCILLATORTYPE_MSI;

 RCC_OscInitStruct.LSIState = RCC_LSI_ON;

 RCC_OscInitStruct.MSIState = RCC_MSI_ON;

 RCC_OscInitStruct.LSEState = RCC_LSE_ON;

 RCC_OscInitStruct.MSICalibrationValue = 0;

 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;

 RCC_OscInitStruct.PLL.PLLM = 1;

 RCC_OscInitStruct.PLL.PLLN = 38;

 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

 RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;

 RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;

 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

 {

Error_Handler();

 }

 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)

 {

  Error_Handler();

 }

 PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USART2

               |RCC_PERIPHCLK_I2C1|RCC_PERIPHCLK_USB |RCC_PERIPHCLK_UART4

               |RCC_PERIPHCLK_SDMMC1|RCC_PERIPHCLK_ADC |RCC_PERIPHCLK_USART1

 |RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_LPTIM1 ;

 PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;

 PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;

 PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;

 PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1;

 PeriphClkInit.Uart4ClockSelection = RCC_UART4CLKSOURCE_PCLK1;

 PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;

 PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1;

 PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1;

 PeriphClkInit.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_PLLSAI1;

 PeriphClkInit.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSE;

 PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_MSI;

 PeriphClkInit.PLLSAI1.PLLSAI1M = 1;

 PeriphClkInit.PLLSAI1.PLLSAI1N = 24;

 PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV2;

 PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;

 PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;

 PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_48M2CLK|RCC_PLLSAI1_ADC1CLK;

 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)

 {

  Error_Handler();

 }

 if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)

 {

Error_Handler();

 }

 HAL_RCCEx_EnableMSIPLLMode();

}

K-.1
Associate

Had simillar problem

"In most of the cases the DMA cannot be used in combination with the Stop mode, hence all DMA channels have to be disabled before entering the Stop Low-power mode. STM32H7 MCUs are an exception to this rule, as detailed in Section 6.3: Measurement on the STM32H743 Nucleo144 board."

Taken from AN4635

ARehm
Associate III

Fixed this issue. I was using Systick in Freertos So, I changed it to timerbase and fixed it. @K-.1​  yes I'm disabling everything before going to sleep.