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

[nRF Connect SDK] Async UART Rx loss

Target nRF52832(nrf52dk_nrf52832)
SDK NCS v1.9.1
Base source: C:\Users\user\ncs\v1.9.1\nrf\samples\bluetooth\peripheral_hids_keyboard
I add uart implementation from following source.
C:\Users\user\ncs\v1.9.1\nrf\samples\peripheral\lpuart

baud rate: 921600
flow control: hw

I found some of data are missing.

UART Rx buffer size: 128
----------------------------------
(last received. 122)
00> E: received 122
----------------------------------
(0123456789 <- 10 bytes was sent.)

00> evt->type 2 (UART_RX_RDY)
00> E: evt->data.rx.len 6 <- actually 6 bytes received. 4 bytes are lost.
00>
00> E: evt->data.rx.offset 122
00>
00> E: received 128
00> evt->type 4 (UART_RX_BUF_RELEASED)
00> evt->type 3 (UART_RX_BUF_REQUEST)
----------------------------------
Finally 4 bytes are lost.

I review doc regarding uart, but no loss issue was found.
academy.nordicsemi.com/.../
Do you have any idea? I'm afraid that flow control is working properly.

Parents
  • static void uart_callback(const struct device *dev,
    			  struct uart_event *evt,
    			  void *user_data)
    {
    	struct device *uart = user_data;
    	int err;
    
    	printk("evt->type %d\n", evt->type);
    
    	switch (evt->type) {
    	case UART_TX_DONE:
    		//LOG_INF("Tx sent %d bytes", evt->data.tx.len);
    		break;
    
    	case UART_TX_ABORTED:
    		//LOG_ERR("Tx aborted");
    		break;
    
    	case UART_RX_RDY:
    		recv += evt->data.rx.len;
    		LOG_ERR("evt->data.rx.len %d", evt->data.rx.len);
    		LOG_ERR("evt->data.rx.offset %d", evt->data.rx.offset);
    		LOG_ERR("recv2 %d", recv);
    		break;
    
    	case UART_RX_BUF_REQUEST:
    	{
    		uint8_t *buf;
    		//LOG_ERR("UART_RX_BUF_REQUEST");
    
    		err = k_mem_slab_alloc(&uart_slab, (void **)&buf, K_NO_WAIT);
    		__ASSERT(err == 0, "Failed to allocate slab");
    
    		err = uart_rx_buf_rsp(uart, buf, BUF_SIZE);
    		__ASSERT(err == 0, "Failed to provide new buffer");
    		break;
    	}
    
    	case UART_RX_BUF_RELEASED:
    		//LOG_ERR("UART_RX_BUF_RELEASED");
    		k_mem_slab_free(&uart_slab, (void **)&evt->data.rx_buf.buf);
    		break;
    
    	case UART_RX_DISABLED:
    		//LOG_ERR("UART_RX_DISABLED");
    		{
    		uint8_t *buf;
    		err = k_mem_slab_alloc(&uart_slab, (void **)&buf, K_NO_WAIT);
    		__ASSERT(err == 0, "Failed to alloc slab");
    
    		err = uart_rx_enable(uart, buf, BUF_SIZE, SYS_FOREVER_MS/*UART_WAIT_FOR_RX*/);
    		__ASSERT(err == 0, "Failed to enable RX");
    		}
    		break;
    
    	case UART_RX_STOPPED:
    		break;
    	}
    }
    
    static void uart_init(void)
    {
    	static const struct device *lpuart;
    	lpuart = device_get_binding("UART_0");
    	int err;
    	uint8_t *buf;
    
    	if (lpuart == NULL) {
            printk("Cannot initialize UART0 device\n");
        }
    	else {
    	   printk("Getting done UART_0\n");
    
    		err = k_mem_slab_alloc(&uart_slab, (void **)&buf, K_NO_WAIT);
    		__ASSERT(err == 0, "Failed to alloc slab");
    
    		err = uart_callback_set(lpuart, uart_callback, (void *)lpuart);
    		__ASSERT(err == 0, "Failed to set callback");
    
    		err = uart_rx_enable(lpuart, buf, BUF_SIZE, 10000/*UART_WAIT_FOR_RX*/);
    		__ASSERT(err == 0, "Failed to enable RX");
    	}
    }

Reply
  • static void uart_callback(const struct device *dev,
    			  struct uart_event *evt,
    			  void *user_data)
    {
    	struct device *uart = user_data;
    	int err;
    
    	printk("evt->type %d\n", evt->type);
    
    	switch (evt->type) {
    	case UART_TX_DONE:
    		//LOG_INF("Tx sent %d bytes", evt->data.tx.len);
    		break;
    
    	case UART_TX_ABORTED:
    		//LOG_ERR("Tx aborted");
    		break;
    
    	case UART_RX_RDY:
    		recv += evt->data.rx.len;
    		LOG_ERR("evt->data.rx.len %d", evt->data.rx.len);
    		LOG_ERR("evt->data.rx.offset %d", evt->data.rx.offset);
    		LOG_ERR("recv2 %d", recv);
    		break;
    
    	case UART_RX_BUF_REQUEST:
    	{
    		uint8_t *buf;
    		//LOG_ERR("UART_RX_BUF_REQUEST");
    
    		err = k_mem_slab_alloc(&uart_slab, (void **)&buf, K_NO_WAIT);
    		__ASSERT(err == 0, "Failed to allocate slab");
    
    		err = uart_rx_buf_rsp(uart, buf, BUF_SIZE);
    		__ASSERT(err == 0, "Failed to provide new buffer");
    		break;
    	}
    
    	case UART_RX_BUF_RELEASED:
    		//LOG_ERR("UART_RX_BUF_RELEASED");
    		k_mem_slab_free(&uart_slab, (void **)&evt->data.rx_buf.buf);
    		break;
    
    	case UART_RX_DISABLED:
    		//LOG_ERR("UART_RX_DISABLED");
    		{
    		uint8_t *buf;
    		err = k_mem_slab_alloc(&uart_slab, (void **)&buf, K_NO_WAIT);
    		__ASSERT(err == 0, "Failed to alloc slab");
    
    		err = uart_rx_enable(uart, buf, BUF_SIZE, SYS_FOREVER_MS/*UART_WAIT_FOR_RX*/);
    		__ASSERT(err == 0, "Failed to enable RX");
    		}
    		break;
    
    	case UART_RX_STOPPED:
    		break;
    	}
    }
    
    static void uart_init(void)
    {
    	static const struct device *lpuart;
    	lpuart = device_get_binding("UART_0");
    	int err;
    	uint8_t *buf;
    
    	if (lpuart == NULL) {
            printk("Cannot initialize UART0 device\n");
        }
    	else {
    	   printk("Getting done UART_0\n");
    
    		err = k_mem_slab_alloc(&uart_slab, (void **)&buf, K_NO_WAIT);
    		__ASSERT(err == 0, "Failed to alloc slab");
    
    		err = uart_callback_set(lpuart, uart_callback, (void *)lpuart);
    		__ASSERT(err == 0, "Failed to set callback");
    
    		err = uart_rx_enable(lpuart, buf, BUF_SIZE, 10000/*UART_WAIT_FOR_RX*/);
    		__ASSERT(err == 0, "Failed to enable RX");
    	}
    }

Children
Related