This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

cause UART to crash by transmit data continuously

Our project use 51822 and another MCU stm32 to transmit heart rate data by uart. then 51822 SPP heart rate to smart phone APP. Now, We meet a issue that 51822 UART will crash if coninuously transmit data over several minutes (i.e over 5 minutes) between STM32 and 51822. STM32 UART can send data to 51822 but 51822 UART can't receive it and send ACK to STM32. Even through we re-initialization 51822 UART but it take no effect. if transmit data time less than 3 Minutes the UART seem ok. we call your callback to init UART as below:

 const app_uart_comm_params_t comm_params =
    {
        RX_PIN_NUMBER,
        TX_PIN_NUMBER,
        RTS_PIN_NUMBER,
        CTS_PIN_NUMBER,
        APP_UART_FLOW_CONTROL_DISABLED, //APP_UART_FLOW_CONTROL_ENABLED
        false,
        UART_BAUDRATE_BAUDRATE_Baud57600  
    };
APP_UART_FIFO_INIT( &comm_params,
                       256,     
                       256,     
                       uart_event_handle,
                       APP_IRQ_PRIORITY_LOW,
                       err_code);
 We try to  decrease to  baud rate 38400 from 57600 but it still not fixed it. Another, i find if increase connection interval by modfiy min and max interval range that can delay UART crash time as below:
#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(8, UNIT_1_25_MS)
/*< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(10, UNIT_1_25_MS)

what cause 51822 UART crash?

Parents
  • You're probably overrunning the UART since you don't have flow control on and are using a high bitrate, eventually the softdevice interrupts for long enough the buffer fills, an error is flagged and depending on what the code does when there's an error (look at the code and see) the UART may appear to stop working. Have you checked the ERRORSRC register in the UART when you have this issue to see if any bits are set?

    I doubt the UART has 'crashed', I'm sure it's still working away, but it's in an error condition the code you're using to drive it is not recovering from.

    If you completely re-initialize the UART it should start receiving again, so it rather depends what you mean by 'even though we re-initialize .. ' and what the code you're using does on init if there was an outstanding error.

    High baudrates + no flow control + softdevice isn't a recipe for success. STM32 MCUs support flow control, why don't you use it and make all your problems go away.

Reply
  • You're probably overrunning the UART since you don't have flow control on and are using a high bitrate, eventually the softdevice interrupts for long enough the buffer fills, an error is flagged and depending on what the code does when there's an error (look at the code and see) the UART may appear to stop working. Have you checked the ERRORSRC register in the UART when you have this issue to see if any bits are set?

    I doubt the UART has 'crashed', I'm sure it's still working away, but it's in an error condition the code you're using to drive it is not recovering from.

    If you completely re-initialize the UART it should start receiving again, so it rather depends what you mean by 'even though we re-initialize .. ' and what the code you're using does on init if there was an outstanding error.

    High baudrates + no flow control + softdevice isn't a recipe for success. STM32 MCUs support flow control, why don't you use it and make all your problems go away.

Children
  • Thanks for your reply. we set 1S timeout to re-initialize UART. if receiving STM32 UART data it will reset 1S timeout. if not receiving STM32 UART data after 1S time out we will re-initialize UART every 1S. the code as below: function check_reset_uart_time is called in main loop.

    void check_reset_uart_time(void) { uint32_t err_code; if((reset_uart_data.reset_uart_state == RESET_RUN) &&(reset_uart_data.reset_uart_timeout == 0) ) {

    	reset_uart_data.reset_uart_state = RESET_RUN;
    	reset_uart_data.reset_uart_timeout = RESET_UART_TIME_NUM;
        const app_uart_comm_params_t comm_params =
        {
            RX_PIN_NUMBER,
            TX_PIN_NUMBER,
            RTS_PIN_NUMBER,
            CTS_PIN_NUMBER,
            APP_UART_FLOW_CONTROL_DISABLED, //APP_UART_FLOW_CONTROL_ENABLED
            false,
            UART_BAUDRATE_BAUDRATE_Baud57600
        };
    	  buffers.rx_buf      = rx_buf;                                                              
          buffers.rx_buf_size = sizeof (rx_buf);                                                    
          buffers.tx_buf      = tx_buf;                                                              
          buffers.tx_buf_size = sizeof (tx_buf);                                                    
          err_code = app_uart_init(&comm_params, &buffers, uart_event_handle, APP_IRQ_PRIORITY_LOW, &APP_UART_UID);   
    	  
         APP_ERROR_CHECK(err_code);
         
         Send_Data_Status.Flag.F_SendUploadNextPkt = true;
     nrf_delay_ms(500);
    
    }
    

    } variable APP_UART_UID is the value which first initial UART set . pls check if there was an outstanding error. Thanks.

  • so have you looked to see if there is an error on the UART when your timeout times out? If so, what is it, have you overrun? Does that code clear any outstanding error, like overrun? Why are you delaying 1/2 a second at the end of the reset as well? Depending on what other things you're doing you may just instantly overrun the buffer again.

    you need to understand what error is on the uart peripheral, whether you're clearing it and you need to look at the uart code to see what it does on overrun to understand why you stop getting data.

  • Not sure if my reply would fit as an answer so i am putting it as a comment. I am assuming that you are using SDK9.0 ble_app_uart as an template. In that example main.c uart_event_handle function is called whenever serial data is received. This function will send a notification by calling ble_nus_string_send. If your UART is receiving data too fast then it is possible that TX buffers are full and your app should handle the error BLE_ERROR_NO_TX_BUFFERS returned by sd_ble_gatts_hvx (ble_nus_string_send).

    I also agree with RK, that even without flow control, UART hardware should keep on working, ERRORSRC will be set accordingly and internal buffers will be overwritten, but hardware should not crash as it is tested to be still in valid working state.

    app_uart.c library handles all errors by just clearing ERRORSRC register in hardware and calling the registered uart event handler with error code APP_UART_COMMUNICATION_ERROR

  • Thanks for your reply. we use SDK8.1.0 ble_app_uart to develop our application. According to RK'advice. we add hardware flow control with baud rate 57600. but UART still crash.when it happened. we can't find no error in ERRORSRC register and if happen error uart_event_handle function will call APP_ERROR_HANDLER function to reset it and it will disconnect .but in fact it not reset and still connect APP all the time. if we change baud rate 9600 from 57600. it is ok by transmiting 20Min data more. but we can't accept it that will take long time to SPP data to APP. i suspect that UART interrupt over often cause the problem when using high baud rate.

  • The UART doesn't crash, it's a piece of hardware. And your last sentence doesn't really make any sense, you can't over-interrupt. The UART demonstrably works for a long time at high baud rates, the Nordic BLE sniffer for instance pumps data out at that kind of baud rate and runs for hours or days at a time.

    So you have a software issue and you need to go looking for it. Is APP_ERROR_HANDLER being called? I can't tell from what you wrote whether it is or whether it isn't. If it is, what's the error code, that will tall you what the error is.

Related