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.