2015-10-07 03:01 PM
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 #dma2015-10-07 03:50 PM
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!2015-10-08 01:19 AM
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 –2016-11-21 07:06 AM
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.