cancel
Showing results for 
Search instead for 
Did you mean: 

UART DMA Initialization problem while jumping from bootloader to application code

Ashvajit-CC
Associate II

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 ??

2 REPLIES 2
Ozone
Principal

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.

Ashvajit-CC
Associate II

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.