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

APP stucks in simple_uart.c

Hi Guys,

i've a problem with the simple_uart.c module. I print some intermediate values with app_trace_log -> simple_uart.c and sometimes, the application stucks at:

void simple_uart_put(uint8_t cr)
{
    NRF_UART0->TXD = (uint8_t)cr;
      
    while (NRF_UART0->EVENTS_TXDRDY != 1) //<<<< in this line
    {
        // Wait for TXD data to be sent.
    }

    NRF_UART0->EVENTS_TXDRDY = 0;
}

Does anybody know, how i can avoid this or continue without resetting the device?

Thanks in advance, cheers

  • You use this simple_uart_put() in both main loop and in interrupts?

  • exactly.. :/ is there a way to use mutex or something like that?

  • I'd recommend not to send the data through uart from interrupts. I'd go with using TX circular buffer in which I'd store the data to be sent by uart. And in the main loop I'd check for any data in TX buffer to be sent and send it if there is any.

    UPD:

    Something like this:

    #define UART_TX_BUF_SIZE   256 // Buf size is power of 2 for MASK. If you need more than 256 bytes then change buffer size and idxIN and idxOUT types to uint16_t
    #define UART_TX_BUF_MASK   (UART_TX_BUF_SIZE-1)
    
    volatile bool uart_tx_is_busy = false;
    volatile uint8_t idxIN = 0; // Buffer index input data
    uint8_t idxOUT = 0; // Buffer index output data
    volatile uint8_t uart_tx_buffer[UART_TX_BUF_SIZE];
    
    void put_data_in_uarf_buf(uint8_t data)
    {
        uint8_t nested;
        sd_nvic_critical_region_enter(&nested);
        if (uart_tx_is_busy == false && idxIN == idxOUT)
        {
            uart_tx_is_busy = true;
            NRF_UART0->TXD = data;
        }
        else
        {
            uart_tx_buffer[idxIN++] = data;
    #if UART_TX_BUF_SIZE != 256
            idxIN &= BUF_MASK;
    #endif
        }
        sd_nvic_critical_region_exit(nested);
    }
    uint8_t get_data_from_uarf_buf(void)
    {
        uint8_t data;
        data = uart_tx_buffer[idxOUT++];
    #if UART_TX_BUF_SIZE != 256
        idxOUT &= BUF_MASK;
    #endif
        return data;
    }
    ...
        simple_uart_config(RTS_PIN_NUMBER, TX_PIN_NUMBER, CTS_PIN_NUMBER, RX_PIN_NUMBER, HWFC);
        // Enable UART interrupt
        NRF_UART0->INTENCLR = 0xffffffffUL;
        NRF_UART0->INTENSET = (UART_INTENSET_TXDRDY_Set << UART_INTENSET_TXDRDY_Pos);
    ...
        // Enter main loop.
        for (;;)
        {
            if (NRF_UART0->EVENTS_TXDRDY == 1)
            {
                NRF_UART0->EVENTS_TXDRDY = 0;
                uart_tx_is_busy = false;
            }
            if (uart_tx_is_busy == false && idxIN != idxOUT)
            {
                uart_tx_is_busy = true;
                NRF_UART0->TXD = get_data_from_uarf_buf();
            }
            app_sched_execute();
            power_manage();
        }
    
  • Thanks nikita. Sounds good, since i don't know how i can consume the buffer in the main loop.. do you know if there is an example in the sdk for such an application?

  • wow thanks a lot! i'm going to test it right now!

Related