This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Missing APP_UART_TX_EMPTY event

Hi!

I am working with an application were two nRF52832 shall communicate over UART in half-duplex 1-wire mode (similar to what is described here but I use different pins for Tx/Rx: devzone.nordicsemi.com/.../). The FIFO version of app_uart (app_uart_fifo.c) and SDK 13.0.0 is used.

APP_UART_TX_EMTY is used to check that data been sent before Tx pin is switched to input mode. The problem I am facing is that I don't get the event if I just use app_uart_put() to transmit single data bytes from unit 1 to unit 2. But if I add printf("\r\n") the event occur as expected. I have verified with oscilloscope that first data byte is sent. Code snippets are shown below.

    void uart_event_handler(app_uart_evt_t * p_event)
    {
        if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
        {
            APP_ERROR_HANDLER(p_event->data.error_communication);
        }
        else if (p_event->evt_type == APP_UART_FIFO_ERROR)
        {
            APP_ERROR_HANDLER(p_event->data.error_code);
        }
        else if (p_event->evt_type == APP_UART_TX_EMPTY)
        {
            tx_empty_flag = true;
        }
        else if (p_event->evt_type == APP_UART_DATA_READY)
        {
            data_ready_flag = true;
        }
    }
    
    
    
    while (true)
    {
       while (app_uart_put('A') != NRF_SUCCESS);
       printf("\r\n");  // no APP_UART_TX_EMPTY is received in uart_event_handler if line deleted 
    
       while (tx_empty_flag != true );
       tx_empty_flag = false;
       disable_tx();  
    
    }

Could anyone explain this?

Thanks in advance, Mattias

  • Hi,

    By APP_UART_TX_EVENT as you have written in your post I assume you mean APP_UART_TX_EMPTY?

    I did a quick test using the peripheral UART example from SDK 13 and your code snippets. My application reached the APP_UART_TX_EMPTY event in the handler regardless of whether the printf() line was commented out or not.

    1. Can you also show how you configure the UART?
    2. And do you have other things going on in your code? Any other peripherals using interrupts for example?
    3. Are tx_empty_flag and data_ready_flag declared as volatile booleans?
  • Thanks Martin

    Your right about APP_UART_TX_EVENT, it should of course be APP_UART_TX_EMPTY. I have corrected that now.

    1. UART initialization:

      int main(void) { uint32_t err_code; bsp_board_leds_init();

       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,
             false,
             UART_BAUDRATE_BAUDRATE_Baud115200
         };
      
         APP_UART_FIFO_INIT(&comm_params,
         UART_RX_BUF_SIZE,
         UART_TX_BUF_SIZE,
         uart_event_handler,
         APP_IRQ_PRIORITY_HIGH,
         err_code);
      
       APP_ERROR_CHECK(err_code);
      
  • '2'. The code is written to only test 1-wire communication over UART. No other peripherals are used.

    '3'. tx_empty_flag and data_ready_flag were declared as bool. I have changed them to volatile bool now but it does not make any difference.

  • I temporary gave up the event controlled approach and implemented a delay based version instead. Instead of waiting for the empty flag I added a 100 us delay after each reconfiguration of Tx pin. This works fine and is actually good enough at the moment since I am in a proof of concept phase with this project. But of course I need to understand and solve this in the end.

    /* Currently my code looks like this and it works */
    enable_tx();
    while (app_uart_put(0x7E) != NRF_SUCCESS);
    disable_tx(); // function now includes a 100 us delay after reconfiguration
    
  • /* I tried this version and it actually works as well */

        enable_tx();
        while (app_uart_put(0x7E) != NRF_SUCCESS);
        while( tx_empty_flag != true );
        tx_empty_flag = false;
        disable_tx();
    
        /* but if I move down disable_tx()like this it does not work */
        enable_tx();
        while (app_uart_put(0x7E) != NRF_SUCCESS);
        while( tx_empty_flag != true );
        tx_empty_flag = false;
        disable_tx();
        
    /* So I actually don't need the printf() now, it looks more like a timing issue */
    
Related