Nrf52840 uart1 interrupt callback can't work.

Hello,

I plan to use uart1 for serial port development based on the binary protocol. I will receive bytes using the interrupt method. But when I send bytes (such as FAFBFC), I can only receive FA from the fifo, even if I use while.

Also, when I send bytes again (such as FBFCFD), the interrupt will not enter again. I would like to know how to solve this problem.

The following is my code:

int uart_init(void* param)
{
    k_tid_t uart_rx_tid; 

    memset(tx_rb, 0, sizeof(tx_rb));
    ring_buf_init(&tx_ringbuf, sizeof(tx_rb), tx_rb);

    memset(rx_buf,0,sizeof(rx_buf));

    k_sem_init(&rx_handle_sem,0,1);

    k_mutex_init(&send_mutex);

    uart_rx_tid = k_thread_create(&rec_thread_data, rec_thread_stack,
                  K_THREAD_STACK_SIZEOF(rec_thread_stack),
                  rec_thread_entry, NULL, NULL, NULL,
                  1, 0, K_MSEC(10));
    k_thread_name_set(uart_rx_tid, "uart_rx_thread");

    uart_dev = device_get_binding(UART_LABEL);
	if (uart_dev == NULL)
    {
		return -1;
	}

    uart_irq_callback_user_data_set(uart_dev, int_driven_callback, &uart_user_data);
    uart_extra_port_init();

    uart_state = true;
    uart_irq_rx_enable(uart_dev);

    tx_state = false;
    rx_state = true;

    if(gpio_pin_get_dt(&rx_en_dt) == 0)
    {
        rx_state = false;
        uart_disable();
    }
    else
    {
        k_work_reschedule(&rx_timeout_work, K_MSEC(RX_TIMEOUT_INTERVAL));
    }


    return 0;
}

static int uart_extra_port_init(void)
{
    int ret;
    if(!device_is_ready(rx_en_dt.port))
    {
        ULOG_ERR("rx_en_dt not ready");
        return -1;
    }
    // gpio
    ret = gpio_pin_configure_dt(&rx_en_dt, GPIO_INPUT);
    if (ret != 0) {
    	ULOG_ERR("Error %d: failed to configure %s pin %d\n",
    	       ret, rx_en_dt.port->name, rx_en_dt.pin);
    	return -2;
    }
    //interrupt config
    ret = gpio_pin_interrupt_configure_dt(&rx_en_dt,
    				   GPIO_INT_EDGE_TO_ACTIVE);
    if (ret != 0) {
    	ULOG_ERR("Error %d: failed to configure interrupt on %s pin %d\n",
    		ret, rx_en_dt.port->name, rx_en_dt.pin);
    	return -3;
    }
    //interrupt callback 
	gpio_init_callback(&rx_en_pin_cb_data, rx_en_pin_handler, BIT(rx_en_dt.pin));
	gpio_add_callback(rx_en_dt.port, &rx_en_pin_cb_data);
	ULOG_INF("Set up rx en at %s pin %d\n", rx_en_dt.port->name, rx_en_dt.pin);

    
    if(!device_is_ready(tx_ntf_dt.port))
    {
        ULOG_ERR("tx_ntf_dt not ready");
        return -4;
    }
    ret = gpio_pin_configure_dt(&tx_ntf_dt, GPIO_OUTPUT);
	if (ret < 0) {
        ULOG_ERR("Error %d: failed to configure device %s pin %d",
        ret, tx_ntf_dt.port->name, tx_ntf_dt.pin);
		return -5;
	}
    gpio_pin_set_dt(&tx_ntf_dt, 0);

    return 0;
}

And my prj.conf about uart:
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_UART_1_INTERRUPT_DRIVEN=y
CONFIG_UART_0_INTERRUPT_DRIVEN=n
CONFIG_UART_1_ASYNC=n
CONFIG_UART_ASYNC_API=y
CONFIG_UART_0_ASYNC=y
CONFIG_UART_0_NRF_ASYNC_LOW_POWER=y


I am looking for your reply.

Jerry

Parents
  • Here is my interrupt callback:

    static void int_driven_callback(const struct device *dev, void *user_data)
    {
        uint8_t tx_data;
        uint8_t rx_data;
    
        uart_irq_update(dev);
    
        if (uart_irq_rx_ready(dev)) 
        {
            int len;
    
            while ((len = uart_fifo_read(dev, &rx_data, 1)) == 1) 
            {
                ULOG_INF("rx data:0x%02X", rx_data);
                rx_buf_push(rx_data); 
            }
            uart_irq_rx_enable(uart_dev);
            k_sem_give(&rx_handle_sem);
        }
    
        if (uart_irq_tx_ready(uart_dev))
        {
            if(ring_buf_get(&tx_ringbuf, &tx_data, 1) > 0)
            {
                uart_fifo_fill(uart_dev, &tx_data, sizeof(tx_data));
            }
            else if(uart_irq_tx_complete(uart_dev) > 0)
            {
                uart_irq_tx_disable(uart_dev);
                ULOG_DBG("tx irq disabled\r\n");
                tx_state = false;
                uart_disable();
                gpio_pin_set_dt(&tx_ntf_dt, 0);
            }
        }
    }

Reply
  • Here is my interrupt callback:

    static void int_driven_callback(const struct device *dev, void *user_data)
    {
        uint8_t tx_data;
        uint8_t rx_data;
    
        uart_irq_update(dev);
    
        if (uart_irq_rx_ready(dev)) 
        {
            int len;
    
            while ((len = uart_fifo_read(dev, &rx_data, 1)) == 1) 
            {
                ULOG_INF("rx data:0x%02X", rx_data);
                rx_buf_push(rx_data); 
            }
            uart_irq_rx_enable(uart_dev);
            k_sem_give(&rx_handle_sem);
        }
    
        if (uart_irq_tx_ready(uart_dev))
        {
            if(ring_buf_get(&tx_ringbuf, &tx_data, 1) > 0)
            {
                uart_fifo_fill(uart_dev, &tx_data, sizeof(tx_data));
            }
            else if(uart_irq_tx_complete(uart_dev) > 0)
            {
                uart_irq_tx_disable(uart_dev);
                ULOG_DBG("tx irq disabled\r\n");
                tx_state = false;
                uart_disable();
                gpio_pin_set_dt(&tx_ntf_dt, 0);
            }
        }
    }

Children
No Data
Related