Interrupt Driven UART with Ring buffers

HI, I need UART communication as mentioned in title of this thread. Is there any example or application available ? 

  • Hi Gulzar, sorry for the delay. I will check what is available and get back to you.

  • I used following ISR function:

    static const struct device *bms_uart;
    uint8_t bms_double_buffer[2][CONFIG_BMS_UART_BUF_SIZE];
    uint8_t *bms_buf_ptr = bms_double_buffer[0];
    
    struct bms_msg_queue_item {
    	uint8_t bytes[CONFIG_BMS_UART_BUF_SIZE];
    	uint8_t length;
    };
    
    struct bms_msg_queue_item bms_incoming_message;
    // UART RX message queue
    K_MSGQ_DEFINE(bms_rx_msgq, sizeof(struct bms_msg_queue_item), CONFIG_BMS_UART_RX_MSG_QUEUE_SIZE, 2);
    
    
    void bms_uart_cb(const struct device *x, void *user_data)
    {
        int data_length = 0;
        uint8_t rcv, addr=0;
        bool new_data = false;
        while (uart_irq_update(x) && uart_irq_is_pending(x))
        {        
            if (uart_irq_rx_ready(x)) 
            {
                data_length += uart_fifo_read(x, bms_buf_ptr, CONFIG_BMS_UART_BUF_SIZE);
                new_data = true;            
            }
            else { 
                    if(new_data){
                    if(data_length == CONFIG_BMS_UART_BUF_SIZE)
                    {  
                        buffer_sel = !buffer_sel;    
    
                        if(buffer_sel == true)
                        memcpy(bms_incoming_message.bytes, bms_double_buffer[0], data_length);
                        else
                        memcpy(bms_incoming_message.bytes, bms_double_buffer[1], data_length);
    
                        bms_incoming_message.length = data_length;
                        if(k_msgq_put(&bms_rx_msgq, &bms_incoming_message, K_NO_WAIT) != 0){
                            printk("Error: Uart1 RX message queue full!\n");				
                        }
                    }
                    printk("RCVD: %d",data_length);
                    }
                }
                //int size = sizeof(bms_tx_buf);daly_cmd_array
                int size = CONFIG_BMS_UART_TX_BUF_SIZE;
                if(uart_irq_tx_ready(x))
                {
                    //data_length = uart_fifo_fill(x,bms_tx_buf,size);
                    data_length = uart_fifo_fill(x,daly_cmd_array,size);
                    // if(data_length == size)printk("Tx: %s", bms_tx_buf); 
                    if(data_length == size)
                    {
                        printk("Tx: %d \n", data_length);
                        for(data_length=0;data_length<13;data_length++)
                        {
                            printk("%x", daly_cmd_array[data_length]);
                            if(data_length != 12)printk(",");else printk("\n");
                        }
                        uart_irq_tx_disable(x);
                    }        
                }
        }
    }

    In this the issue is that, I sent 13 bytes from Serial Device, after receiving 8 bytes, isr_wrapper file is called, pointing to the problem a shown in image.

    I gone through the library function uart_fifo_read(). After Stepping through the ISR code, I reached to the function shown in image below.

    In this function, size>0 is only used and nowhere (size) number of bytes is captured to be equal to. The following code line saves only one byte always rx_data[0], because every time at the start of function is num_rx = 0.
    rx_data[num_rx++] = (uint8_t)data->rx_data; 
    I practically verified that only one byte is saved at index of rx_data[0] in every iteration and after 8 characters receive goes to isr_wrapper.
    1. What is use of third parameter in uart_fifo_read(x,x,Buffer_size) when it has not been used in implementation ?
    2. What is the issue related to isr_wrapper ?
    3. Does UART generate interrupt after every byte or may it be configured to interrupt after collecting Buffer_size bytes ? If yes, where to set ? If no, then, why to specify in uart_fifo_read() ?
     4. In the above ISR function, problem is in RX portion only, TX working well.
  • Hi Gulzar,

    We found this sample:

    https://devzone.nordicsemi.com/f/nordic-q-a/74600/uart-rx-interrupt-driven-does-not-receive-characters-properly-zephyr-os

    Does it look anything like what you are looking for?

    (I have not yet looked at all the details of your previous reply.)

Related