I use CONFIG_UART_ASYNC_API feature of NCS v2.0 with nRF52840DK, but when UART_RX_RDY event triggered, evt->data.rx.len is smaller than the number of bytes it has received. I use dslogic tool to analysis uart signal, and print out evt->data.rx.len+2 bytes and can be sure that data is all there, but evt->data.rx.len is just smaller than it should be. And next UART_RX_RDY is only triggered when more data arrives.
**To Reproduce**
related configuations in prj.conf:
CONFIG_SERIAL=y
CONFIG_CBPRINTF_FP_SUPPORT=y
CONFIG_UART_ASYNC_API=y
CONFIG_UART_1_ASYNC=y
uart handler:
void uart1_handler_callback(const struct device *dev, struct uart_event *evt, void *user_data) { // int err; ARG_UNUSED(dev); switch (evt->type) { case UART_TX_DONE: sent = evt->data.tx.len; ilog("UART_TX_DONE: %d bytes sent.", sent); hex_dump2("UART_TX_DONE: ", evt->data.tx.buf, evt->data.tx.len); k_sem_give(&tx_done); break; case UART_TX_ABORTED: sent = evt->data.tx.len; ilog("UART_TX_ABORTED: %d bytes sent.", sent); k_sem_give(&tx_aborted); break; case UART_RX_RDY: received = evt->data.rx.len; ilog("UART_RX_RDY: %d bytes recved at 0x%x.", received, (unsigned int)(evt->data.rx.buf+evt->data.rx.offset)); hex_dump2("UART_RX_RDY: ", evt->data.rx.buf+evt->data.rx.offset, received); k_sem_give(&rx_rdy); break; case UART_RX_DISABLED: ilog("UART_RX_DISABLED"); // err = k_sem_take(&rx_buf_released, K_NO_WAIT); // failed_in_isr |= (err < 0); k_sem_give(&rx_disabled); break; default: break; } } static void uart1_dorx_thread(void *p1, void *p2, void *p3) { ARG_UNUSED(p1); ARG_UNUSED(p2); ARG_UNUSED(p3); while (true) { if (!device_is_ready(uart1_dev)) { // printk("UART1 device not ready\n"); k_yield(); k_sleep(K_MSEC(5)); continue; } if (get_free_buf(&rxBuf, &tmp_rx, &tmp_rx_len) < 0) { k_yield(); // printk("no free space in rx buffer.\n"); k_sleep(K_MSEC(5)); continue; } const int rx_period = 10; received = 0; // printk("uart_rx_enable 0x%x, %d.\n", tmp_rx, tmp_rx_len); uart_rx_enable(uart1_dev, tmp_rx, tmp_rx_len, rx_period*USEC_PER_MSEC); while (tmp_rx_len > 0) { int ret = k_sem_take(&rx_rdy, K_MSEC(rx_period+1)); while (ret != 0) { ret = k_sem_take(&rx_disabled, K_MSEC(10)); if (ret == 0) { uart_rx_enable(uart1_dev, tmp_rx, tmp_rx_len, rx_period*USEC_PER_MSEC); // only reenable after disabled. } ret = k_sem_take(&rx_rdy, K_MSEC(rx_period+1)); } if (received > 0) { tmp_rx += received; tmp_rx_len -= received; lba_putdata_len(&rxBuf, received); //no data copy, just modify loop buffer position variables. ilog("%d bytes put into uart rx buffer.", received); received = 0; if (tmp_rx_len < 0) { ilog("rx: this should never happen! after -%d, %d left", received, tmp_rx_len); break; } } else { ilog("rx: this should not happen!"); } } } }
I have a 10K loop buffer, the packets are no more than 30 bytes, and another thread is keeping handling data, I can be sure
that buffer is long enough.
**Logs and console output**
Some log:
[17.438] ========== sending packet, id = 12 ==========
[17.447] UART_TX_DONE: 34 bytes sent.
[17.450] UART_TX_DONE: 34 0c 00 a5 86 1b 00 17 00 04 00 09 07 0b 00 02 4...............
[17.458] UART_TX_DONE: 0c 00 29 2a 0d 00 02 0e 00 24 2a 0f 00 02 10 00 ..)*.....$*.....
[17.465] UART_TX_DONE: 27 2a '*
[18.853] ========== receiving packet, id = 12 ==========
[18.856] UART_RX_RDY: 33 bytes recved at 0x20001b2c.
[18.860] UART_RX_RDY: 34 0c 00 a5 86 1b 00 17 00 04 00 09 07 0b 00 02 4...............
[18.868] UART_RX_RDY: 0c 00 29 2a 0d 00 02 0e 00 24 2a 0f 00 02 10 00 ..)*.....$*.....
[18.875] UART_RX_RDY: 27 '
** 0x2a is there acturally. **
[17.730] ========== sending packet, id = 13 ==========
[17.738] UART_TX_DONE: 20 bytes sent.
[17.741] UART_TX_DONE: 34 0d 00 43 71 0d 00 09 00 04 00 09 07 11 00 02 4..Cq...........
[17.749] UART_TX_DONE: 12 00 28 2a ..(*
[19.145] ========== receiving packet, id = 13 ==========
[19.148] UART_RX_RDY: 20 bytes recved at 0x20001b4d.
[19.152] UART_RX_RDY: 2a 34 0d 00 43 71 0d 00 09 00 04 00 09 07 11 00 *4..Cq..........
[19.160] UART_RX_RDY: 02 12 00 28 ...(
** it should have received 21 bytes, but it tell me 20, so another 0x2a at the end of packet is delayed.**
[18.030] ========== sending packet, id = 14 ==========
[18.037] UART_TX_DONE: 16 bytes sent.
[18.041] UART_TX_DONE: 34 0e 00 19 bb 09 00 05 00 04 00 01 08 12 00 0a 4...............
[19.442] ========== receiving packet, id = 14 ==========
[19.445] UART_RX_RDY: 16 bytes recved at 0x20001b61.
[19.450] UART_RX_RDY: 2a 34 0e 00 19 bb 09 00 05 00 04 00 01 08 12 00 *4..............
** 0x0a is delayed too.**
**Impact**
When protocal packet has fixed sizes, I can use a litten trick to work around this, but in other cases it's blocking my way.
It happens quite often, not always though, which means it should be a bug.
**Environment (please complete the following information):**
- NCS 2.0
- nRF52840DK
Please help, thanks:)