Hi,
I am currently trying to connect a nrf52811 as an companion to an ESP32 user UART.
I am using the interrupt driven UART implementation as kind of the last resort.
I am facing the Problem, that i am getting the UART Messages not fully. It appears to be like this:
The message consists of 8 Bytes (thats not always the case. can be more but never less than 7 Byte).
I correctly get the first 4 Bytes. wich i immediatly put on a queue for further use.
Then nothing happens until the timeout in the ESP occurs as i am not sending any response.
The ESP now tries to re-send the message.
I now get the last 4 Bytes of the prrevious message as well as the first 4 Bytes of the current message!
So the message appears to still be in the UART Buffer but not correctly sent to the application.
I would greatly appreciate any answer regarding this behaviour.
I am using nrfConnect SDK V2.7 with mcuBoot using Serial Recovery.
I also want to use the same UART as the update port in Serial Recovery.
Here is my prj-conf:
CONFIG_LOG=y CONFIG_LOG_DEFAULT_LEVEL=3 CONFIG_LOG_MODE_IMMEDIATE=y CONFIG_LOG_BACKEND_RTT=y CONFIG_USE_SEGGER_RTT=y CONFIG_CBPRINTF_FP_SUPPORT=y CONFIG_SEGGER_RTT_MODE_NO_BLOCK_TRIM=y CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=2048 CONFIG_NCS_SAMPLES_DEFAULTS=y CONFIG_DEBUG=y CONFIG_SHELL=y CONFIG_INIT_STACKS=y CONFIG_THREAD_MONITOR=y CONFIG_THREAD_NAME=y CONFIG_HW_STACK_PROTECTION=n CONFIG_HEAP_MEM_POOL_SIZE=1024 CONFIG_CRC=y CONFIG_AUDIO=y CONFIG_AUDIO_CODEC=y CONFIG_AUDIO_TAS5828=y CONFIG_PWM=y CONFIG_PWM_LOG_LEVEL_OFF=y CONFIG_NRFX_SAADC=y CONFIG_NRFX_PPI=y # TIMER2 is 52 specific. for 54 use TIMER22 CONFIG_NRFX_TIMER2=y CONFIG_NRFX_TIMER0=y CONFIG_I2C=y CONFIG_LED=y CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_UART_0_INTERRUPT_DRIVEN=y CONFIG_UART_0_NRF_PARITY_BIT=y CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=n CONFIG_EVENTS=y CONFIG_ASSERT=y CONFIG_MAIN_STACK_SIZE=1024 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512 CONFIG_IDLE_STACK_SIZE=512 CONFIG_ASSERT_NO_MSG_INFO=n CONFIG_PM_DEVICE_RUNTIME=n CONFIG_PM=n
here is my DT-Configuration:
&uart0 {
status = "okay";
pinctrl-0 = <&uart0_default>;
pinctrl-names = "default";
current-speed = <31250>;
parity = "even";
stop-bits = "1";
data-bits = <8>;
};
As for DT: I am using a custom board definition which i recently updated to HWMv2 as part of the swap to nrf Connect SDK v2.7
here is part of the implementation of the UART in my application:
K_MSGQ_DEFINE(serial_rx_raw_q, sizeof(uint8_t), MSG_LENGTH_MAX * 2, 1);
K_MSGQ_DEFINE(serial_tx_raw_q, sizeof(uint8_t), 50, 1);
const struct device *uart = DEVICE_DT_GET(DT_NODELABEL(uart0));
void init() {
if (!device_is_ready(uart))
{
LOG_WRN("UART device not ready");
return 1;
}
int err = uart_irq_callback_set(uart, serial_interruptdriven_cb);
if (err < 0) {
if (err == -ENOTSUP) {
LOG_ERR("Interrupt-driven UART API support not enabled");
} else if (err == -ENOSYS) {
LOG_ERR("UART device does not support interrupt-driven API");
} else {
LOG_ERR("Error setting UART callback: %d", err);
}
return 0;
}
uart_irq_rx_enable(uart);
}
void serial_interruptdriven_cb(const struct device *dev, void *user_data) {
uint8_t c[MSG_LENGTH_MAX];
while(uart_irq_update(dev) && (uart_irq_rx_ready(dev) == 1 || uart_irq_tx_ready(dev) == 1)) {
uint8_t tx_r = uart_irq_tx_ready(dev);
if (tx_r == 1) {
LOG_INF("tx");
uint8_t data = 0;
uint32_t count = 0;
uint8_t buf[MSG_LENGTH_MAX] = {0};
while (k_msgq_get(&serial_tx_raw_q, &data, K_NO_WAIT) == 0) {
buf[count] = data;
count++;
if (count == MSG_LENGTH_MAX) {
LOG_ERR("BUFFER OVERFLOW!");
break;
}
}
if (count != 0) {
int8_t num = uart_fifo_fill(dev, buf, count);
if (num != count) {
LOG_ERR("!!!!!COULD NOT SEND ALL DATA!!!!! (%d/%d)", num, count);
}
} else {
LOG_WRN("nothing to send");
}
uart_irq_tx_disable(dev);
count = 0;
k_sem_give(&tx_byte_sync);
}
while (uart_irq_rx_ready(dev) == 1) {
LOG_INF("rx");
uint8_t read_bytes = 1;
while(read_bytes > 0) {
read_bytes = uart_fifo_read(dev, c, sizeof(c));
LOG_INF("num: %d", read_bytes);
for (uint8_t i = 0; i < read_bytes; i++) {
LOG_INF("%x", c[i]);
int status = k_msgq_put(&serial_rx_raw_q, &c[i], K_NO_WAIT);
if (status != 0) {
LOG_ERR("Error while putting on queue: %d", status);
k_oops();
}
}
}
}
}
}