Skip to main content
Visitor II
March 18, 2021
Question

Hi, I am trying to communicate Uart in interrupt mode.We are able to successfully transmit & receive data to PC (through USB-UART).But when we connect to UART based modem then we are getting HAL_UART_ErrorCallback & transmission is failing. Pls help

  • March 18, 2021
  • 8 replies
  • 4133 views

This error callback function is not getting called when we connect to PC. But we are getting during modem (UART based)communication only. Whats purpose of this callback ? Is there any configuration need to add ?

    This topic has been closed for replies.

    8 replies

    Super User
    March 18, 2021

    Which STM32?

    There's an error code in huart->ErrorCode indicating the type of error.

    /** @defgroup UART_Error_Code UART Error Code
     * @brief UART Error Code 
     * @{
     */ 
    #define HAL_UART_ERROR_NONE 0x00000000U /*!< No error */
    #define HAL_UART_ERROR_PE 0x00000001U /*!< Parity error */
    #define HAL_UART_ERROR_NE 0x00000002U /*!< Noise error */
    #define HAL_UART_ERROR_FE 0x00000004U /*!< Frame error */
    #define HAL_UART_ERROR_ORE 0x00000008U /*!< Overrun error */
    #define HAL_UART_ERROR_DMA 0x00000010U /*!< DMA transfer error */

    Does the modem's baudrate match the STM32's one? Observe Rx and Tx using oscilloscope.

    JW

    PBira.1Author
    Visitor II
    March 19, 2021

    Thank you for your response.

    I am trying to communicate with gsm module and it’s getting overrun error in TX call back function. Our uart transmit and receive line is 3.3 v ....We are setting converter for ttl match and result is same.

    Please guide us how we can resolve this issue? We are using STM32F411VE discovery.

    Super User
    March 19, 2021

    "it’s getting overrun error in TX call back"

    Really - in the TX callback?

    Overrun would normally be expected on RX

    Super User
    March 19, 2021

    > it’s getting overrun error in TX call back function

    Then you have to speed up your reception. If system clock is not at max, increase it; if baudrate can be changed, decrease it; if compiler optimization is off, switch it on; if you don't use DMA, start using it.

    JW

    Super User
    March 19, 2021

    "We are able to successfully transmit & receive data to PC (through USB-UART)"

    Presumably, you tested this by typing stuff at a terminal?

    "But when we connect to UART based modem then we are getting HAL_UART_ErrorCallback" ... "it’s getting overrun error"

    As @Community member​ says, that's because you're not handling the received characters quickly enough - possibly (probably?) because you're trying to do too much in your handler.

    Thing about it: when you type characters manually, you're only getting a few per second max - so the MCU has plenty of time to handle them.

    But a modem can send characters back-to-back - so you need to be quick.

    You should be able to demonstrate that by pasting stuff into your terminal, use using its file send facility ...

    PBira.1Author
    Visitor II
    March 22, 2021

     Hi ,

    Thank you for your replies.

    We are using dock light app for communicating between PC n STM32 discovery . Where data can be sent in junks simultaneously and stm32 get those bytes. But if we use gsm modem (with level converter ) , receive get fails.

    One more thing observed if you remove stm32 receive line and reconnect then you always next expected packet(like OK or Error)

    Even though we clear bits it’s not working.

    Please let us know your inputs.

    Super User
    March 23, 2021

    "using dock light app for communicating between PC n STM32 discovery"

    You mean this: https://docklight.de/ ?

    "data can be sent in chunks simultaneously and stm32 get those bytes"

    How big are the "chunks"? are you sure that the app isn't adding any inter-character delays?

    Do you have an analyser or oscilloscope to verify what's actually happening on the wires?

    "if we use gsm modem (with level converter ) , receive get fails"

    Are you sure that the modem is actually working?

    eg, can you communicate with it from Docklight ?

    Are you sure that the modem is actually receiving your commands?

    See https://www.avrfreaks.net/comment/2336161#comment-2336161 for some tips on debugging serial comms.

    Graduate II
    March 24, 2021

    If the code is implemented as receive-process-receive, then it is inherently broken. As a minimum receiving must be implemented with double buffering and processing must be done outside the ISR. And still that will not work reliably because the HAL is full of bugs and bloat. For a sane implementation example look here:

    https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx

    PBira.1Author
    Visitor II
    March 25, 2021

    Thank you all for your response.

    We have tried new interrupt based program and its working but we still see error and continuously UART error callback function (i.e. HAL_UART_ErrorCallback) getting called.

    0693W000008xsbuQAA.png 

    If this error is getting then we don't get any data in receive buffer. Please suggest us:

    1. How to handle this callback function so that it will clear and start receiving buffer again.
    2. How we can avoid this error ?

    Super User
    March 25, 2021

    Don't you need to clear the error once you've handled it?

    0693W000008xsqBQAQ.png 

    PBira.1Author
    Visitor II
    March 25, 2021
    /**
     ******************************************************************************
     * @file UART/UART_TwoBoards_ComIT/Src/main.c 
     * @author MCD Application Team
     * @brief This sample code shows how to use STM32F4xx UART HAL API to transmit 
     * and receive a data buffer with a communication process based on
     * IT transfer. 
     * The communication is done using 2 Boards.
     ******************************************************************************
     */
     
    /** @addtogroup STM32F4xx_HAL_Examples
     * @{
     */
     
    /** @addtogroup UART_TwoBoards_ComIT
     * @{
     */ 
     
    /* Private function prototypes -----------------------------------------------*/
    static void SystemClock_Config(void);
    static void Error_Handler(void);
     
    /* Private functions ---------------------------------------------------------*/
     
    /**
     * @brief Main program
     * @param None
     * @retval None
     */
    int main(void)
    {
     
     /* STM32F4xx HAL library initialization:
     - Configure the Flash prefetch, instruction and Data caches
     - Configure the Systick to generate an interrupt each 1 msec
     - Set NVIC Group Priority to 4
     - Global MSP (MCU Support Package) initialization
     */
     HAL_Init();
     
     /* Configure LED3, LED4, LED5 and LED6 */
     BSP_LED_Init(LED3);
     BSP_LED_Init(LED4);
     BSP_LED_Init(LED5);
     BSP_LED_Init(LED6);
     
     /* Configure the system clock to 100 MHz */
     SystemClock_Config(); 
     
     /*##-1- Configure the UART peripheral ######################################*/
     /* Put the USART peripheral in the Asynchronous mode (UART Mode) */
     /* UART1 configured as follow:
     - Word Length = 8 Bits
     - Stop Bit = One Stop bit
     - Parity = None
     - BaudRate = 9600 baud
     - Hardware flow control disabled (RTS and CTS signals) */
     UartHandle.Instance = USARTx;
     
     UartHandle.Init.BaudRate = 9600;
     UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
     UartHandle.Init.StopBits = UART_STOPBITS_1;
     UartHandle.Init.Parity = UART_PARITY_NONE;
     UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
     UartHandle.Init.Mode = UART_MODE_TX_RX;
     UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
     
     if(HAL_UART_Init(&UartHandle) != HAL_OK)
     {
     Error_Handler();
     }
     
     while (1)
     {
    	 switch (NumStage)
    	 {
    	 case 1:
    		 memset(txbuff,'\0',sizeof(txbuff));
    	 	 memcpy(txbuff,GPRS_ECHO_OFF, 5);
    	 	 if(HAL_UART_Transmit_IT(&UartHandle, (uint8_t*)txbuff, 5)!= HAL_OK)
    	 	 {
    	 		 Error_Handler();
    	 	 }
    	 	 
    	 	 /*##-3- Wait for the end of the transfer ###################################*/
    	 	 while (UartReady != SET)
    	 	 {
     
    	 	 }
    		 
     	 /* Reset transmission flag */
    		 UartReady = RESET;
     
    		 /*##-4- Put UART peripheral in reception process ###########################*/
    		 if(HAL_UART_Receive_IT(&UartHandle, (uint8_t *)aRxBuffer, 6) != HAL_OK)
    		 {
    			 Error_Handler();
    		 }
     
    		 /*##-5- Wait for the end of the transfer ###################################*/
    		 while (UartReady != SET)
    		 {
     
     		 }
    		 if (UartReady != SET)
    			NumStage = 1;
    		 else
    			NumStage = 2;
    		 /* Reset transmission flag */
    		 UartReady = RESET;
     
    		 break;
     
    	 default:
     	 break;
    	 }
    	 
    	 HAL_Delay(2000);
    	 memset(aRxBuffer,'\0',sizeof(aRxBuffer));
     }
     
    /**
     * @brief System Clock Configuration
     * The system Clock is configured as follow : 
     * System Clock source = PLL (HSI)
     * SYSCLK(Hz) = 100000000
     * HCLK(Hz) = 100000000
     * AHB Prescaler = 1
     * APB1 Prescaler = 2
     * APB2 Prescaler = 1
     * HSI Frequency(Hz) = 16000000
     * PLL_M = 16
     * PLL_N = 400
     * PLL_P = 4
     * PLL_Q = 7
     * VDD(V) = 3.3
     * Main regulator output voltage = Scale2 mode
     * Flash Latency(WS) = 3
     * @param None
     * @retval None
     */
    static void SystemClock_Config(void)
    {
     RCC_ClkInitTypeDef RCC_ClkInitStruct;
     RCC_OscInitTypeDef RCC_OscInitStruct;
     
     /* Enable Power Control clock */
     __HAL_RCC_PWR_CLK_ENABLE();
     
     /* The voltage scaling allows optimizing the power consumption when the device is 
     clocked below the maximum system frequency, to update the voltage scaling value 
     regarding system frequency refer to product datasheet. */
     __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
     
     /* Enable HSI Oscillator and activate PLL with HSI as source */
     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
     RCC_OscInitStruct.HSICalibrationValue = 0x10;
     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
     RCC_OscInitStruct.PLL.PLLM = 16;
     RCC_OscInitStruct.PLL.PLLN = 400;
     RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
     RCC_OscInitStruct.PLL.PLLQ = 7;
     if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
     {
     Error_Handler();
     }
     
     /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 
     clocks dividers */
     RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; 
     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; 
     if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
     {
     Error_Handler();
     }
    }
     
    /**
     * @brief Tx Transfer completed callback
     * @param UartHandle: UART handle. 
     * @note This example shows a simple way to report end of IT Tx transfer, and 
     * you can add your own implementation. 
     * @retval None
     */
    void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle)
    {
     /* Set transmission flag: transfer complete*/
     UartReady = SET;
     
     /* Turn LED6 on: Transfer in transmission process is correct */
     BSP_LED_On(LED6);
    }
     
    /**
     * @brief Rx Transfer completed callback
     * @param UartHandle: UART handle
     * @note This example shows a simple way to report end of IT Rx transfer, and 
     * you can add your own implementation.
     * @retval None
     */
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
    {
     /* Set transmission flag: transfer complete*/
     UartReady = SET;
     //memset(aRxBuffer,'\0',sizeof(aRxBuffer));
     /* Turn LED4 on: Transfer in reception process is correct */
     BSP_LED_On(LED4);
    }
     
    /**
     * @brief UART error callbacks
     * @param UartHandle: UART handle
     * @note This example shows a simple way to report transfer error, and you can
     * add your own implementation.
     * @retval None
     */
     void HAL_UART_ErrorCallback(UART_HandleTypeDef *UartHandle)
    {
     /* Turn LED3 on: Transfer error in reception/transmission process */
     // UartReady = SET;
     BSP_LED_On(LED3); 
    }
     
     
    /**
     * @brief This function is executed in case of error occurrence.
     * @param None
     * @retval None
     */
    static void Error_Handler(void)
    {
    	int loop = 0;
     /* Turn LED5 on */
     BSP_LED_On(LED5);
     while(loop++ < 80000)
     {
     
     }
    }
     
    #ifdef USE_FULL_ASSERT
    /**
     * @brief Reports the name of the source file and the source line number
     * where the assert_param error has occurred.
     * @param file: pointer to the source file name
     * @param line: assert_param error line source number
     * @retval None
     */
    void assert_failed(uint8_t* file, uint32_t line)
    { 
     /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
     
     /* Infinite loop */
     while (1)
     {
     }
    }
    #endif
     
    /**
     * @}
     */
     
    /**
     * @}
     */
     
    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

    In above code, we have wrote one of the sample uart transmit and receive flow. Please suggest how we can handle error callback.

    PBira.1Author
    Visitor II
    March 26, 2021

    After running initial command successfully then we start getting transmit error(callback) each time and failed to get receive data. Please help us to resolve this issue.

    Super User
    March 29, 2021

    "getting transmit error"

    Which error(s), exactly, are you getting ?

    PBira.1Author
    Visitor II
    March 30, 2021

    We are getting overrun error.

    Visitor II
    March 30, 2021

    Hello

    In the above code if rx wait loop completed without timeout then NumStage will get the value 2 but this case "case 2:" never implemented .