AnsweredAssumed Answered

Solved! - Stm32CubeMX - UART - DMA - ERROR DETECTION

Question asked by vallorani.silvio.001 on Oct 8, 2015
Latest reply on Nov 21, 2016 by jeremy_cis
Hi, I have a problem in catching errors when using UART in DMA mode.
I use CubeMx to generate the code.

The functions which I use to catch interrupts are the following (obviously my code is more complex, this is just a reference):

void USART2_IRQHandler(void) {
  HAL_UART_IRQHandler(&huart2);
}
     
void DMA1_Ch4_7_DMA2_Ch3_5_IRQHandler(void) {
    HAL_DMA_IRQHandler(&hdma_usart2_tx);
    HAL_DMA_IRQHandler(&hdma_usart2_rx);
}
     
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
    __NOP();
}
     
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    __NOP();
}
     
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
    __NOP();
}


I can send/receive without problems, but if I prepare the UART/DMA for receive something and then I send a wrong pattern (i.e. using a wrong parity) the program don't calls the HAL_UART_ErrorCallback() function as I aspect.
I can't find no other ISR or Callback function which is called after an UART error.

This is the API that I call to prepare for receive:
HAL_UART_Receive_DMA(&huart2, &Buffer, FRAME_LENGTH);

This API have this code inside:
...
    /* Set the DMA error callback */
    huart->hdmarx->XferErrorCallback = UART_DMAError;
...

And the UART_DMAError() function is:
static void UART_DMAError(DMA_HandleTypeDef *hdma) 
{
  UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  huart->RxXferCount = 0;
  huart->TxXferCount = 0;
  huart->State= HAL_UART_STATE_READY;
  huart->ErrorCode |= HAL_UART_ERROR_DMA;
  HAL_UART_ErrorCallback(huart);
}
which calls theHAL_UART_ErrorCallback(huart) which I aspect.



My UART and DMA initializations are the following:
void MX_USART2_UART_Init(void) {
    huart2.Instance = USART2;
    huart2.Init.BaudRate = 125000;
    huart2.Init.WordLength = UART_WORDLENGTH_9B;
    huart2.Init.StopBits = UART_STOPBITS_1;
    huart2.Init.Parity = UART_PARITY_EVEN;
    huart2.Init.Mode = UART_MODE_TX_RX;
    huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart2.Init.OverSampling = UART_OVERSAMPLING_16;
    huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
    huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_DMADISABLEONERROR_INIT;
    huart2.AdvancedInit.DMADisableonRxError = UART_ADVFEATURE_DMA_DISABLEONRXERROR;
    HAL_RS485Ex_Init(&huart2, UART_DE_POLARITY_HIGH, 0, 0);
}
   
void HAL_UART_MspInit(UART_HandleTypeDef* huart)  {
  GPIO_InitTypeDef GPIO_InitStruct;
  if(huart->Instance==USART2)
  {
     /* Peripheral clock enable */
    __USART2_CLK_ENABLE();
     
    /**USART2 GPIO Configuration 
    PA1     ------> USART2_DE
    PA2     ------> USART2_TX
    PA3     ------> USART2_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF1_USART2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
   
    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF1_USART2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
   
    /* Peripheral DMA init*/
    hdma_usart2_rx.Instance = DMA1_Channel5;
    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart2_rx.Init.Mode = DMA_NORMAL;
    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
    HAL_DMA_Init(&hdma_usart2_rx);
   
    __HAL_DMA1_REMAP(HAL_DMA1_CH5_USART2_RX);
    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
    hdma_usart2_tx.Instance = DMA1_Channel4;
    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart2_tx.Init.Mode = DMA_NORMAL;
    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
    HAL_DMA_Init(&hdma_usart2_tx);
    __HAL_DMA1_REMAP(HAL_DMA1_CH4_USART2_TX);
    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
    /* Peripheral interrupt init*/
    HAL_NVIC_SetPriority(USART2_IRQn, 3, 0);
    HAL_NVIC_EnableIRQ(USART2_IRQn);
}
 
void MX_DMA_Init(void)
{
  __DMA1_CLK_ENABLE();
  HAL_NVIC_SetPriority(DMA1_Ch4_7_DMA2_Ch3_5_IRQn, 3, 0);
  HAL_NVIC_EnableIRQ(DMA1_Ch4_7_DMA2_Ch3_5_IRQn);
 
}


Can you help me to find a solution, please?


Outcomes