2025-04-22 10:41 PM - edited 2025-04-22 10:43 PM
Hi, I am facing an issue on STM32F469 where UART is not initialized with DMA properly if I dont add some delay around 300ms as show in my initialization.
/* 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_ADC1_Init();
MX_ADC3_Init();
MX_I2C1_Init();
MX_RTC_Init();
MX_SPI2_Init();
MX_TIM1_Init();
MX_TIM2_Init();
MX_TIM5_Init();
MX_SPI3_Init();
MX_UART8_Init();
//MX_USART2_UART_Init();
MX_RNG_Init();
MX_USB_DEVICE_Init();
/* USER CODE BEGIN 2 */
HAL_GPIO_WritePin(EN_3V3_SW_GPIO_Port, EN_3V3_SW_Pin, GPIO_PIN_SET);
HAL_Delay(300);
Serial_Receive();
This serial receive function
void Serial_Receive(void)
{
HAL_UARTEx_ReceiveToIdle_DMA(&huart8,Serial_RX_Buffer, SERIAL_RX_BUFF_SIZE);
__HAL_DMA_DISABLE_IT(&hdma_uart8_rx,DMA_IT_HT);
}
Here's my UART Initialization code
/* UART8 init function */
void MX_UART8_Init(void)
{
/* USER CODE BEGIN UART8_Init 0 */
/* USER CODE END UART8_Init 0 */
/* USER CODE BEGIN UART8_Init 1 */
/* USER CODE END UART8_Init 1 */
huart8.Instance = UART8;
huart8.Init.BaudRate = 115200;
huart8.Init.WordLength = UART_WORDLENGTH_8B;
huart8.Init.StopBits = UART_STOPBITS_1;
huart8.Init.Parity = UART_PARITY_NONE;
huart8.Init.Mode = UART_MODE_TX_RX;
huart8.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart8.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart8) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN UART8_Init 2 */
/* USER CODE END UART8_Init 2 */
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==UART8)
{
/* USER CODE BEGIN UART8_MspInit 0 */
/* USER CODE END UART8_MspInit 0 */
/* UART8 clock enable */
__HAL_RCC_UART8_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
/**UART8 GPIO Configuration
PE1 ------> UART8_TX
PE0 ------> UART8_RX
*/
GPIO_InitStruct.Pin = RF_UART8_TX_Pin|RF_UART8_RX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_UART8;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* UART8 DMA Init */
/* UART8_RX Init */
hdma_uart8_rx.Instance = DMA1_Stream6;
hdma_uart8_rx.Init.Channel = DMA_CHANNEL_5;
hdma_uart8_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_uart8_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_uart8_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_uart8_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_uart8_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_uart8_rx.Init.Mode = DMA_NORMAL;
hdma_uart8_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_uart8_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_uart8_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_uart8_rx);
/* UART8 interrupt Init */
HAL_NVIC_SetPriority(UART8_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(UART8_IRQn);
/* USER CODE BEGIN UART8_MspInit 1 */
/* USER CODE END UART8_MspInit 1 */
}
else if(uartHandle->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/* USART2 clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/**USART2 GPIO Configuration
PD6 ------> USART2_RX
PD5 ------> USART2_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|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_USART2;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* USER CODE BEGIN USART2_MspInit 1 */
/* USER CODE END USART2_MspInit 1 */
}
}
I am de initializing my UART before jumping from bootloader code to application but still I am getting this issue
void UART8_DeInit(void) {
// De-initialize the UART peripheral
// Stop any ongoing UART DMA transfers
HAL_UART_AbortReceive(&huart8);
HAL_UART_AbortTransmit(&huart8);
// Deinitialize the DMA
HAL_DMA_DeInit(huart8.hdmarx);
// Deinitialize the UART
HAL_UART_DeInit(&huart8);
// Reset the UART and DMA clocks
__HAL_RCC_UART8_FORCE_RESET();
__HAL_RCC_UART8_RELEASE_RESET();
__HAL_RCC_DMA1_FORCE_RESET();
__HAL_RCC_DMA1_RELEASE_RESET();
// Disable UART interrupts
HAL_NVIC_DisableIRQ(USART_IRQn);
}
But this is not an only case for this.
In other project where I use 2 UARTs with DMA and other peripherals like SPI and I2C on STM32G0, same thing happens with UART2 but in that project I have set a timeout, where if I don't get interrupt on USART2 I re initialize USART2 and sort of works.
So, I suspect there's something in initialization that's causing this problem or could be something that am doing wrong ??
2025-04-22 11:53 PM
It seems your code implicitely relies upon reset values of peripheral config registers.
This is not the case when you use a peripheral in the bootloader, and then directly jump to your application.
I'm not a HAL/Cube user, but I'm pretty sure there is a corresponding Deinit - call for every init function.
Call this deinitialisation routines for every peripheral you use in the BL - either within the BL or in your application.
IMHO the BL (immediately before starting the application) is the best place to do this.
2025-04-23 2:25 AM
I am de-initialzing every peripheral that I use from bootloader section before jumping to application address.
HAL_NVIC_DisableIRQ(EXTI1_IRQn);
//-- reset peripherals to guarantee flawless start of user application
HAL_GPIO_DeInit(GPIOE,GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11);
//USBD_DeInit(&hUsbDeviceFS);
UART8_DeInit();
USBD_DeInit(&hUsbDeviceFS);
__HAL_RCC_GPIOH_CLK_DISABLE();
__HAL_RCC_GPIOE_CLK_DISABLE();
__HAL_RCC_GPIOA_CLK_DISABLE();
HAL_RCC_DeInit();
HAL_DeInit();
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
But as I mentioned, this error is not only limited to only one case.
@Ashvajit-CC wrote:In other project where I use 2 UARTs with DMA and other peripherals like SPI and I2C on STM32G0, same thing happens with UART2 but in that project I have set a timeout, where if I don't get interrupt on USART2 I re initialize USART2 and sort of works.
2025-04-23 5:38 AM
Debug the code. Run it and hit pause when it "doesn't work". Examine where execution is at. Look at the uart handle to see if it has any error codes. You are handling errors right? Look at the register values to understand why it isn't currently receiving.
2025-04-23 8:43 AM
The best way to de-initialize stuff in STM32 is to avoid initializing it at all. So many times advised in this forum by @Piranha IIRC and others. When bootloader decides to jump to the app, it stores a magic in the SRAM and calls NVIC_SystemReset, which does the reset job. Then the bootloader regains control and checks the magic BEFORE initializing anything else. If it sees the magic, it just jumps to the app.