cancel
Showing results for 
Search instead for 
Did you mean: 

Solved! - Stm32CubeMX - UART - DMA - ERROR DETECTION

silvio1
Associate
Posted on October 08, 2015 at 00:01

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?   

#stm32f0 #cubemx #uart #dma

3 REPLIES 3
silvio1
Associate
Posted on October 08, 2015 at 00:50

It just needs to enable UART_IT_ERR and UART_IT_PE...   So I add the following lines at the end of the function HAL_UART_MspInit(UART_HandleTypeDef* huart) and it works:   void

HAL_UART_MspInit(UART_HandleTypeDef* huart) {

...

/* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */

__HAL_UART_ENABLE_IT(huart, UART_IT_ERR);

/* Enable the UART Parity Error Interrupt */

__HAL_UART_ENABLE_IT(huart, UART_IT_PE);

}

  CEERS! 

Nesrine M_O
Lead II
Posted on October 08, 2015 at 10:19

Hi vallorani.silvio.001 ,

Thank you for posting your findings and how you fixed the issue, it is good to hear that it was solved. 

-Syrine –

engenharia2
Associate II
Posted on November 21, 2016 at 16:06

Hi, where can I find

STM32CubeMX v4.16.1 to download? I have problem with the upgrade to v4.17 and can't solve it.