In the UART interrupt, I am entering the error_isr, and the UART_RX_STOPPED state is causing me to fail to receive data.

I am using nRF Connect SDK v2.1.0 in the Toolchain Manager of nRF Connect for Desktop.

The UART data is sent from PC to the board.

I am using the nRF52833 chip, and I believe it is unlikely to be a hardware issue because UART reception works fine in other versions.

The board is unable to receive all the data and only receives a portion of it. The data that is not received enters the UART_RX_STOPPED state in the error_isr.

Even after disabling both Bluetooth Beacon and ESB, when attempting to use UART, I still encounter the error_isr.

I am unable to determine the reason for entering the error_isr.

static void error_isr(const struct device *dev)
{
	if (uart0_cb.rx_timeout != SYS_FOREVER_US) {
		k_timer_stop(&uart0_cb.rx_timeout_timer);
	}
	nrf_uart_event_clear(uart0_addr, NRF_UART_EVENT_ERROR);

	if (!uart0_cb.rx_enabled) {
		nrf_uart_task_trigger(uart0_addr, NRF_UART_TASK_STOPRX);
	}
	struct uart_event event = {
		.type = UART_RX_STOPPED,											// ERROR CODE OCCURED 2023 05 25
		.data.rx_stop.reason =
			UART_ERROR_FROM_MASK(
				nrf_uart_errorsrc_get_and_clear(uart0_addr)),
		.data.rx_stop.data.len = uart0_cb.rx_counter
					 - uart0_cb.rx_offset,
		.data.rx_stop.data.offset = uart0_cb.rx_offset,
		.data.rx_stop.data.buf = uart0_cb.rx_buffer
	};

	user_callback(dev, &event);
	/* Abort transfer. */
	// uart_nrfx_rx_disable(dev);
}



void uart_nrfx_isr(const struct device *uart)
{
	if (nrf_uart_int_enable_check(uart0_addr, NRF_UART_INT_MASK_ERROR) &&
	    nrf_uart_event_check(uart0_addr, NRF_UART_EVENT_ERROR)) {
		error_isr(uart);
	} else if (nrf_uart_int_enable_check(uart0_addr,
					     NRF_UART_INT_MASK_RXDRDY) &&
		   nrf_uart_event_check(uart0_addr, NRF_UART_EVENT_RXDRDY)) {
		rx_isr(uart);
	}

	if (nrf_uart_event_check(uart0_addr, NRF_UART_EVENT_TXDRDY)
	    && nrf_uart_int_enable_check(uart0_addr,
					 NRF_UART_INT_MASK_TXDRDY)) {
		tx_isr(uart);
	}

	if (nrf_uart_event_check(uart0_addr, NRF_UART_EVENT_RXTO)) {
		rxto_isr(uart);
	}
}


Do you need any more additional information?

Parents Reply Children
  • In an overlay file, pin configuration is performed for setting up the pins.

    /*
     * Copyright (c) 2016-2019 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    /**
     * @brief Driver for Nordic Semiconductor nRF5X UART
     */
    
    #include <zephyr/drivers/uart.h>
    #include <zephyr/pm/device.h>
    #include <soc.h>
    #include <hal/nrf_uart.h>
    
    #ifdef CONFIG_PINCTRL
    #include <zephyr/drivers/pinctrl.h>
    #else
    #include <hal/nrf_gpio.h>
    #endif /* CONFIG_PINCTRL */
    
    /*
     * Extract information from devicetree.
     *
     * This driver only supports one instance of this IP block, so the
     * instance number is always 0.
     */
    #define DT_DRV_COMPAT	nordic_nrf_uart
    
    #define PROP(prop)	DT_INST_PROP(0, prop)
    #define HAS_PROP(prop)	DT_INST_NODE_HAS_PROP(0, prop)
    
    #define BAUDRATE	PROP(current_speed)
    
    #ifdef CONFIG_PINCTRL
    #define DISABLE_RX	PROP(disable_rx)
    #else
    #define DISABLE_RX	!HAS_PROP(rx_pin)
    #endif /* CONFIG_PINCTRL */
    #define HW_FLOW_CONTROL_AVAILABLE	PROP(hw_flow_control)
    
    #define IRQN		DT_INST_IRQN(0)
    #define IRQ_PRIO	DT_INST_IRQ(0, priority)
    
    static NRF_UART_Type *const uart0_addr = (NRF_UART_Type *)DT_INST_REG_ADDR(0);
    
    struct uart_nrfx_config {
    #ifdef CONFIG_PINCTRL
    	const struct pinctrl_dev_config *pcfg;
    #else
    	uint32_t tx_pin;
    	uint32_t rx_pin;
    	uint32_t rts_pin;
    	uint32_t cts_pin;
    	bool rx_pull_up;
    	bool cts_pull_up;
    #endif /* CONFIG_PINCTRL */
    };
    
    /* Device data structure */
    struct uart_nrfx_data {
    	struct uart_config uart_config;
    };
    
    #ifdef CONFIG_UART_0_ASYNC
    static struct {
    	uart_callback_t callback;
    	void *user_data;
    
    	uint8_t *rx_buffer;
    	uint8_t *rx_secondary_buffer;
    	size_t rx_buffer_length;
    	size_t rx_secondary_buffer_length;
    	volatile size_t rx_counter;
    	volatile size_t rx_offset;
    	int32_t rx_timeout;
    	struct k_timer rx_timeout_timer;
    	bool rx_enabled;
    
    	bool tx_abort;
    	const uint8_t *volatile tx_buffer;
    	/* note: this is aliased with atomic_t in uart_nrfx_poll_out() */
    	unsigned long tx_buffer_length;
    	volatile size_t tx_counter;
    #if HW_FLOW_CONTROL_AVAILABLE
    	int32_t tx_timeout;
    	struct k_timer tx_timeout_timer;
    #endif
    } uart0_cb;
    #endif /* CONFIG_UART_0_ASYNC */
    
    #ifdef CONFIG_UART_0_INTERRUPT_DRIVEN
    
    static uart_irq_callback_user_data_t irq_callback; /**< Callback function pointer */
    static void *irq_cb_data; /**< Callback function arg */
    
    /* Variable used to override the state of the TXDRDY event in the initial state
     * of the driver. This event is not set by the hardware until a first byte is
     * sent, and we want to use it as an indication if the transmitter is ready
     * to accept a new byte.
     */
    static volatile uint8_t uart_sw_event_txdrdy;
    static volatile bool disable_tx_irq;
    
    #endif /* CONFIG_UART_0_INTERRUPT_DRIVEN */
    
    #ifndef CONFIG_PINCTRL
    static void uart_nrfx_pins_configure(const struct device *dev, bool sleep)
    {
    	const struct uart_nrfx_config *cfg = dev->config;
    
    	if (!sleep) {
    		if (cfg->tx_pin != NRF_UART_PSEL_DISCONNECTED) {
    			nrf_gpio_pin_write(cfg->tx_pin, 1);
    			nrf_gpio_cfg_output(cfg->tx_pin);
    		}
    
    		if (cfg->rx_pin != NRF_UART_PSEL_DISCONNECTED) {
    			nrf_gpio_cfg_input(cfg->rx_pin,
    					   (cfg->rx_pull_up ?
    					    NRF_GPIO_PIN_PULLUP :
    					    NRF_GPIO_PIN_NOPULL));
    		}
    
    		if (cfg->rts_pin != NRF_UART_PSEL_DISCONNECTED) {
    			nrf_gpio_pin_write(cfg->rts_pin, 1);
    			nrf_gpio_cfg_output(cfg->rts_pin);
    		}
    
    		if (cfg->cts_pin != NRF_UART_PSEL_DISCONNECTED) {
    			nrf_gpio_cfg_input(cfg->cts_pin,
    					   (cfg->cts_pull_up ?
    					    NRF_GPIO_PIN_PULLUP :
    					    NRF_GPIO_PIN_NOPULL));
    		}
    	} else {
    		if (cfg->tx_pin != NRF_UART_PSEL_DISCONNECTED) {
    			nrf_gpio_cfg_default(cfg->tx_pin);
    		}
    
    		if (cfg->rx_pin != NRF_UART_PSEL_DISCONNECTED) {
    			nrf_gpio_cfg_default(cfg->rx_pin);
    		}
    
    		if (cfg->rts_pin != NRF_UART_PSEL_DISCONNECTED) {
    			nrf_gpio_cfg_default(cfg->rts_pin);
    		}
    
    		if (cfg->cts_pin != NRF_UART_PSEL_DISCONNECTED) {
    			nrf_gpio_cfg_default(cfg->cts_pin);
    		}
    	}
    
    	nrf_uart_txrx_pins_set(uart0_addr, cfg->tx_pin, cfg->rx_pin);
    	nrf_uart_hwfc_pins_set(uart0_addr, cfg->rts_pin, cfg->cts_pin);
    }
    #endif /* !CONFIG_PINCTRL */
    
    static bool event_txdrdy_check(void)
    {
    	return (nrf_uart_event_check(uart0_addr, NRF_UART_EVENT_TXDRDY)
    #ifdef CONFIG_UART_0_INTERRUPT_DRIVEN
    		|| uart_sw_event_txdrdy
    #endif
    	       );
    }
    
    static void event_txdrdy_clear(void)
    {
    	nrf_uart_event_clear(uart0_addr, NRF_UART_EVENT_TXDRDY);
    #ifdef CONFIG_UART_0_INTERRUPT_DRIVEN
    	uart_sw_event_txdrdy = 0U;
    #endif
    }
    
    
    /**
     * @brief Set the baud rate
     *
     * This routine set the given baud rate for the UART.
     *
     * @param dev UART device struct
     * @param baudrate Baud rate
     *
     * @retval 0 on success.
     * @retval -EINVAL for invalid baudrate.
     */
    
    static int baudrate_set(const struct device *dev, uint32_t baudrate)
    {
    	nrf_uart_baudrate_t nrf_baudrate; /* calculated baudrate divisor */
    
    	switch (baudrate) {
    	case 300:
    		/* value not supported by Nordic HAL */
    		nrf_baudrate = 0x00014000;
    		break;
    	case 600:
    		/* value not supported by Nordic HAL */
    		nrf_baudrate = 0x00027000;
    		break;
    	case 1200:
    		nrf_baudrate = NRF_UART_BAUDRATE_1200;
    		break;
    	case 2400:
    		nrf_baudrate = NRF_UART_BAUDRATE_2400;
    		break;
    	case 4800:
    		nrf_baudrate = NRF_UART_BAUDRATE_4800;
    		break;
    	case 9600:
    		nrf_baudrate = NRF_UART_BAUDRATE_9600;
    		break;
    	case 14400:
    		nrf_baudrate = NRF_UART_BAUDRATE_14400;
    		break;
    	case 19200:
    		nrf_baudrate = NRF_UART_BAUDRATE_19200;
    		break;
    	case 28800:
    		nrf_baudrate = NRF_UART_BAUDRATE_28800;
    		break;
    	case 31250:
    		nrf_baudrate = NRF_UART_BAUDRATE_31250;
    		break;
    	case 38400:
    		nrf_baudrate = NRF_UART_BAUDRATE_38400;
    		break;
    	case 56000:
    		nrf_baudrate = NRF_UART_BAUDRATE_56000;
    		break;
    	case 57600:
    		nrf_baudrate = NRF_UART_BAUDRATE_57600;
    		break;
    	case 76800:
    		nrf_baudrate = NRF_UART_BAUDRATE_76800;
    		break;
    	case 115200:
    		nrf_baudrate = NRF_UART_BAUDRATE_115200;
    		break;
    	case 230400:
    		nrf_baudrate = NRF_UART_BAUDRATE_230400;
    		break;
    	case 250000:
    		nrf_baudrate = NRF_UART_BAUDRATE_250000;
    		break;
    	case 460800:
    		nrf_baudrate = NRF_UART_BAUDRATE_460800;
    		break;
    	case 921600:
    		nrf_baudrate = NRF_UART_BAUDRATE_921600;
    		break;
    	case 1000000:
    		nrf_baudrate = NRF_UART_BAUDRATE_1000000;
    		break;
    	default:
    		return -EINVAL;
    	}
    
    	nrf_uart_baudrate_set(uart0_addr, nrf_baudrate);
    
    	return 0;
    }
    
    /**
     * @brief Poll the device for input.
     *
     * @param dev UART device struct
     * @param c Pointer to character
     *
     * @return 0 if a character arrived, -1 if the input buffer if empty.
     */
    
    static int uart_nrfx_poll_in(const struct device *dev, unsigned char *c)
    {
    	if (!nrf_uart_event_check(uart0_addr, NRF_UART_EVENT_RXDRDY)) {
    		return -1;
    	}
    
    	/* Clear the interrupt */
    	nrf_uart_event_clear(uart0_addr, NRF_UART_EVENT_RXDRDY);
    
    	/* got a character */
    	*c = nrf_uart_rxd_get(uart0_addr);
    
    	return 0;
    }
    
    #ifdef CONFIG_UART_0_ASYNC
    static void uart_nrfx_isr(const struct device *dev);
    #endif
    
    /**
     * @brief Output a character in polled mode.
     *
     * @param dev UART device struct
     * @param c Character to send
     */
    static void uart_nrfx_poll_out(const struct device *dev, unsigned char c)
    {
    	atomic_t *lock;
    #ifdef CONFIG_UART_0_ASYNC
    	while (uart0_cb.tx_buffer) {
    		/* If there is ongoing asynchronous transmission, and we are in
    		 * ISR, then call uart interrupt routine, otherwise
    		 * busy wait until transmission is finished.
    		 */
    		if (k_is_in_isr()) {
    			uart_nrfx_isr(dev);
    		}
    	}
    	/* Use tx_buffer_length as lock, this way uart_nrfx_tx will
    	 * return -EBUSY during poll_out.
    	 */
    	lock = &uart0_cb.tx_buffer_length;
    #else
    	static atomic_val_t poll_out_lock;
    
    	lock = &poll_out_lock;
    #endif
    
    	if (!k_is_in_isr()) {
    		uint8_t safety_cnt = 100;
    
    		while (atomic_cas((atomic_t *) lock,
    				  (atomic_val_t) 0,
    				  (atomic_val_t) 1) == false) {
    			if (IS_ENABLED(CONFIG_MULTITHREADING)) {
    				/* k_sleep allows other threads to execute and finish
    				 * their transactions.
    				 */
    				k_msleep(1);
    			} else {
    				k_busy_wait(1000);
    			}
    			if (--safety_cnt == 0) {
    				break;
    			}
    		}
    	} else {
    		*lock = 1;
    	}
    	/* Reset the transmitter ready state. */
    	event_txdrdy_clear();
    
    	/* Activate the transmitter. */
    	nrf_uart_task_trigger(uart0_addr, NRF_UART_TASK_STARTTX);
    
    	/* Send the provided character. */
    	nrf_uart_txd_set(uart0_addr, (uint8_t)c);
    
    	/* Wait until the transmitter is ready, i.e. the character is sent. */
    	int res;
    
    	NRFX_WAIT_FOR(event_txdrdy_check(), 1000, 1, res);
    
    	/* Deactivate the transmitter so that it does not needlessly
    	 * consume power.
    	 */
    	nrf_uart_task_trigger(uart0_addr, NRF_UART_TASK_STOPTX);
    
    	/* Release the lock. */
    	*lock = 0;
    }
    
    /** Console I/O function */
    static int uart_nrfx_err_check(const struct device *dev)
    {
    	/* register bitfields maps to the defines in uart.h */
    	return nrf_uart_errorsrc_get_and_clear(uart0_addr);
    }
    
    static int uart_nrfx_configure(const struct device *dev,
    			       const struct uart_config *cfg)
    {
    	struct uart_nrfx_data *data = dev->data;
    	nrf_uart_config_t uart_cfg;
    
    #if defined(UART_CONFIG_STOP_Msk)
    	switch (cfg->stop_bits) {
    	case UART_CFG_STOP_BITS_1:
    		uart_cfg.stop = NRF_UART_STOP_ONE;
    		break;
    	case UART_CFG_STOP_BITS_2:
    		uart_cfg.stop = NRF_UART_STOP_TWO;
    		break;
    	default:
    		return -ENOTSUP;
    	}
    #else
    	if (cfg->stop_bits != UART_CFG_STOP_BITS_1) {
    		return -ENOTSUP;
    	}
    #endif
    
    	if (cfg->data_bits != UART_CFG_DATA_BITS_8) {
    		return -ENOTSUP;
    	}
    
    	switch (cfg->flow_ctrl) {
    	case UART_CFG_FLOW_CTRL_NONE:
    		uart_cfg.hwfc = NRF_UART_HWFC_DISABLED;
    		break;
    	case UART_CFG_FLOW_CTRL_RTS_CTS:
    		if (HW_FLOW_CONTROL_AVAILABLE) {
    			uart_cfg.hwfc = NRF_UART_HWFC_ENABLED;
    		} else {
    			return -ENOTSUP;
    		}
    		break;
    	default:
    		return -ENOTSUP;
    	}
    
    #if defined(UART_CONFIG_PARITYTYPE_Msk)
    	uart_cfg.paritytype = NRF_UART_PARITYTYPE_EVEN;
    #endif
    	switch (cfg->parity) {
    	case UART_CFG_PARITY_NONE:
    		uart_cfg.parity = NRF_UART_PARITY_EXCLUDED;
    		break;
    	case UART_CFG_PARITY_EVEN:
    		uart_cfg.parity = NRF_UART_PARITY_INCLUDED;
    		break;
    #if defined(UART_CONFIG_PARITYTYPE_Msk)
    	case UART_CFG_PARITY_ODD:
    		uart_cfg.parity = NRF_UART_PARITY_INCLUDED;
    		uart_cfg.paritytype = NRF_UART_PARITYTYPE_ODD;
    		break;
    #endif
    	default:
    		return -ENOTSUP;
    	}
    
    	if (baudrate_set(dev, cfg->baudrate) != 0) {
    		return -ENOTSUP;
    	}
    
    	nrf_uart_configure(uart0_addr, &uart_cfg);
    
    	data->uart_config = *cfg;
    
    	return 0;
    }
    
    #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
    static int uart_nrfx_config_get(const struct device *dev,
    				struct uart_config *cfg)
    {
    	struct uart_nrfx_data *data = dev->data;
    
    	*cfg = data->uart_config;
    	return 0;
    }
    #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
    
    #ifdef CONFIG_UART_0_ASYNC
    
    static void user_callback(const struct device *dev, struct uart_event *event)
    {
    	if (uart0_cb.callback) {
    		uart0_cb.callback(dev, event, uart0_cb.user_data);
    	}
    }
    
    static int uart_nrfx_callback_set(const struct device *dev,
    				  uart_callback_t callback,
    				  void *user_data)
    {
    	uart0_cb.callback = callback;
    	uart0_cb.user_data = user_data;
    
    	return 0;
    }
    
    static int uart_nrfx_tx(const struct device *dev, const uint8_t *buf,
    			size_t len,
    			int32_t timeout)
    {
    	if (atomic_cas((atomic_t *) &uart0_cb.tx_buffer_length,
    		       (atomic_val_t) 0,
    		       (atomic_val_t) len) == false) {
    		return -EBUSY;
    	}
    
    	uart0_cb.tx_buffer = buf;
    #if	HW_FLOW_CONTROL_AVAILABLE
    	uart0_cb.tx_timeout = timeout;
    #endif
    	nrf_uart_event_clear(uart0_addr, NRF_UART_EVENT_TXDRDY);
    	nrf_uart_task_trigger(uart0_addr, NRF_UART_TASK_STARTTX);
    	nrf_uart_int_enable(uart0_addr, NRF_UART_INT_MASK_TXDRDY);
    
    	uint8_t txd = uart0_cb.tx_buffer[uart0_cb.tx_counter];
    
    	nrf_uart_txd_set(uart0_addr, txd);
    
    	return 0;
    }
    
    static int uart_nrfx_tx_abort(const struct device *dev)
    {
    	if (uart0_cb.tx_buffer_length == 0) {
    		return -EINVAL;
    	}
    #if	HW_FLOW_CONTROL_AVAILABLE
    	if (uart0_cb.tx_timeout != SYS_FOREVER_US) {
    		k_timer_stop(&uart0_cb.tx_timeout_timer);
    	}
    #endif
    	nrf_uart_task_trigger(uart0_addr, NRF_UART_TASK_STOPTX);
    
    	struct uart_event evt = {
    		.type = UART_TX_ABORTED,
    		.data.tx.buf = uart0_cb.tx_buffer,
    		.data.tx.len = uart0_cb.tx_counter
    	};
    
    	uart0_cb.tx_buffer_length = 0;
    	uart0_cb.tx_counter = 0;
    
    	user_callback(dev, &evt);
    
    	return 0;
    }
    
    static int uart_nrfx_rx_enable(const struct device *dev, uint8_t *buf,
    			       size_t len,
    			       int32_t timeout)
    {
    	if (DISABLE_RX) {
    		__ASSERT(false, "TX only UART instance");
    		return -ENOTSUP;
    	}
    
    	if (uart0_cb.rx_buffer_length != 0) {
    		return -EBUSY;
    	}
    
    	uart0_cb.rx_enabled = 1;
    	uart0_cb.rx_buffer = buf;
    	uart0_cb.rx_buffer_length = len;
    	uart0_cb.rx_counter = 0;
    	uart0_cb.rx_secondary_buffer_length = 0;
    	uart0_cb.rx_timeout = timeout;
    
    	nrf_uart_event_clear(uart0_addr, NRF_UART_EVENT_ERROR);
    	nrf_uart_event_clear(uart0_addr, NRF_UART_EVENT_RXDRDY);
    	nrf_uart_event_clear(uart0_addr, NRF_UART_EVENT_RXTO);
    	nrf_uart_task_trigger(uart0_addr, NRF_UART_TASK_STARTRX);
    	nrf_uart_int_enable(uart0_addr, NRF_UART_INT_MASK_RXDRDY |
    					NRF_UART_INT_MASK_ERROR |
    					NRF_UART_INT_MASK_RXTO);
    
    	return 0;
    }
    
    static int uart_nrfx_rx_buf_rsp(const struct device *dev, uint8_t *buf,
    				size_t len)
    {
    	int err;
    	unsigned int key = irq_lock();
    
    	if (!uart0_cb.rx_enabled) {
    		err = -EACCES;
    	} else if (uart0_cb.rx_secondary_buffer_length != 0) {
    		err = -EBUSY;
    	} else {
    		uart0_cb.rx_secondary_buffer = buf;
    		uart0_cb.rx_secondary_buffer_length = len;
    		err = 0;
    	}
    
    	irq_unlock(key);
    
    	return err;
    }
    
    static int uart_nrfx_rx_disable(const struct device *dev)
    {
    	if (uart0_cb.rx_buffer_length == 0) {
    		return -EFAULT;
    	}
    
    	uart0_cb.rx_enabled = 0;
    	if (uart0_cb.rx_timeout != SYS_FOREVER_US) {
    		k_timer_stop(&uart0_cb.rx_timeout_timer);
    	}
    	nrf_uart_task_trigger(uart0_addr, NRF_UART_TASK_STOPRX);
    
    	return 0;
    }
    
    static void rx_rdy_evt(const struct device *dev)
    {
    	struct uart_event event;
    	size_t rx_cnt = uart0_cb.rx_counter;
    
    	event.type = UART_RX_RDY;
    	event.data.rx.buf = uart0_cb.rx_buffer;
    	event.data.rx.len = rx_cnt - uart0_cb.rx_offset;
    	event.data.rx.offset = uart0_cb.rx_offset;
    
    	uart0_cb.rx_offset = rx_cnt;
    
    	user_callback(dev, &event);
    }
    
    static void buf_released_evt(const struct device *dev)
    {
    	struct uart_event event = {
    		.type = UART_RX_BUF_RELEASED,
    		.data.rx_buf.buf = uart0_cb.rx_buffer
    	};
    	user_callback(dev, &event);
    }
    
    static void rx_disabled_evt(const struct device *dev)
    {
    	struct uart_event event = {
    		.type = UART_RX_DISABLED
    	};
    	user_callback(dev, &event);
    }
    
    static void rx_reset_state(void)
    {
    	nrf_uart_int_disable(uart0_addr,
    			     NRF_UART_INT_MASK_RXDRDY |
    			     NRF_UART_INT_MASK_ERROR |
    			     NRF_UART_INT_MASK_RXTO);
    	uart0_cb.rx_buffer_length = 0;
    	uart0_cb.rx_enabled = 0;
    	uart0_cb.rx_counter = 0;
    	uart0_cb.rx_offset = 0;
    	uart0_cb.rx_secondary_buffer_length = 0;
    }
    
    static void rx_isr(const struct device *dev)
    {
    	struct uart_event event;
    
    	nrf_uart_event_clear(uart0_addr, NRF_UART_EVENT_RXDRDY);
    
    	if (!uart0_cb.rx_buffer_length || !uart0_cb.rx_enabled) {
    		/* Byte received when receiving is disabled - data lost. */
    		nrf_uart_rxd_get(uart0_addr);
    	} else {
    		if (uart0_cb.rx_counter == 0) {
    			event.type = UART_RX_BUF_REQUEST;
    			user_callback(dev, &event);
    		}
    		uart0_cb.rx_buffer[uart0_cb.rx_counter] =
    			nrf_uart_rxd_get(uart0_addr);
    		uart0_cb.rx_counter++;
    		if (uart0_cb.rx_timeout == 0) {
    			rx_rdy_evt(dev);
    		} else if (uart0_cb.rx_timeout != SYS_FOREVER_US) {
    			k_timer_start(&uart0_cb.rx_timeout_timer,
    				      K_USEC(uart0_cb.rx_timeout),
    				      K_NO_WAIT);
    		}
    	}
    
    	if (uart0_cb.rx_buffer_length == uart0_cb.rx_counter) {
    		if (uart0_cb.rx_timeout != SYS_FOREVER_US) {
    			k_timer_stop(&uart0_cb.rx_timeout_timer);
    		}
    		rx_rdy_evt(dev);
    
    		unsigned int key = irq_lock();
    
    		if (uart0_cb.rx_secondary_buffer_length == 0) {
    			uart0_cb.rx_enabled = 0;
    		}
    		irq_unlock(key);
    
    		if (uart0_cb.rx_secondary_buffer_length) {
    			buf_released_evt(dev);
    			/* Switch to secondary buffer. */
    			uart0_cb.rx_buffer_length =
    				uart0_cb.rx_secondary_buffer_length;
    			uart0_cb.rx_buffer = uart0_cb.rx_secondary_buffer;
    			uart0_cb.rx_secondary_buffer_length = 0;
    			uart0_cb.rx_counter = 0;
    			uart0_cb.rx_offset = 0;
    
    			event.type = UART_RX_BUF_REQUEST;
    			user_callback(dev, &event);
    		} else {
    			uart_nrfx_rx_disable(dev);
    		}
    	}
    }
    
    static void tx_isr(const struct device *dev)
    {
    	uart0_cb.tx_counter++;
    	if (uart0_cb.tx_counter < uart0_cb.tx_buffer_length &&
    	    !uart0_cb.tx_abort) {
    #if	HW_FLOW_CONTROL_AVAILABLE
    		if (uart0_cb.tx_timeout != SYS_FOREVER_US) {
    			k_timer_start(&uart0_cb.tx_timeout_timer,
    				      K_USEC(uart0_cb.tx_timeout),
    				      K_NO_WAIT);
    		}
    #endif
    		nrf_uart_event_clear(uart0_addr, NRF_UART_EVENT_TXDRDY);
    
    		uint8_t txd = uart0_cb.tx_buffer[uart0_cb.tx_counter];
    
    		nrf_uart_txd_set(uart0_addr, txd);
    	} else {
    #if	HW_FLOW_CONTROL_AVAILABLE
    
    		if (uart0_cb.tx_timeout != SYS_FOREVER_US) {
    			k_timer_stop(&uart0_cb.tx_timeout_timer);
    		}
    #endif
    		nrf_uart_task_trigger(uart0_addr, NRF_UART_TASK_STOPTX);
    		struct uart_event event = {
    			.type = UART_TX_DONE,
    			.data.tx.buf = uart0_cb.tx_buffer,
    			.data.tx.len = uart0_cb.tx_counter
    		};
    		nrf_uart_event_clear(uart0_addr, NRF_UART_EVENT_TXDRDY);
    		uart0_cb.tx_buffer_length = 0;
    		uart0_cb.tx_counter = 0;
    		uart0_cb.tx_buffer = NULL;
    
    		nrf_uart_int_disable(uart0_addr, NRF_UART_INT_MASK_TXDRDY);
    		user_callback(dev, &event);
    	}
    }
    
    #define UART_ERROR_FROM_MASK(mask) \
    	(mask & NRF_UART_ERROR_OVERRUN_MASK ? UART_ERROR_OVERRUN	\
    	 : mask & NRF_UART_ERROR_PARITY_MASK ? UART_ERROR_PARITY	\
    	 : mask & NRF_UART_ERROR_FRAMING_MASK ? UART_ERROR_FRAMING	\
    	 : mask & NRF_UART_ERROR_BREAK_MASK ? UART_BREAK		\
    	 : 0)
    
    static void error_isr(const struct device *dev)
    {
    	if (uart0_cb.rx_timeout != SYS_FOREVER_US) {
    		k_timer_stop(&uart0_cb.rx_timeout_timer);
    	}
    	nrf_uart_event_clear(uart0_addr, NRF_UART_EVENT_ERROR);
    
    	if (!uart0_cb.rx_enabled) {
    		nrf_uart_task_trigger(uart0_addr, NRF_UART_TASK_STOPRX);
    	}
    	struct uart_event event = {
    		.type = UART_RX_STOPPED,											// ERROR CODE OCCURED 2023 05 25
    		.data.rx_stop.reason =
    			UART_ERROR_FROM_MASK(
    				nrf_uart_errorsrc_get_and_clear(uart0_addr)),
    		.data.rx_stop.data.len = uart0_cb.rx_counter
    					 - uart0_cb.rx_offset,
    		.data.rx_stop.data.offset = uart0_cb.rx_offset,
    		.data.rx_stop.data.buf = uart0_cb.rx_buffer
    	};
    
    	user_callback(dev, &event);
    	/* Abort transfer. */
    	// uart_nrfx_rx_disable(dev);
    }
    
    /*
     * In nRF hardware RX timeout can occur only after stopping the peripheral,
     * it is used as a sign that peripheral has finished its operation and is
     * disabled.
     */
    static void rxto_isr(const struct device *dev)
    {
    	nrf_uart_event_clear(uart0_addr, NRF_UART_EVENT_RXTO);
    
    	/* Send rxrdy if there is any data pending. */
    	if (uart0_cb.rx_counter - uart0_cb.rx_offset) {
    		rx_rdy_evt(dev);
    	}
    
    	buf_released_evt(dev);
    	if (uart0_cb.rx_secondary_buffer_length) {
    		uart0_cb.rx_buffer = uart0_cb.rx_secondary_buffer;
    		buf_released_evt(dev);
    	}
    
    	rx_reset_state();
    	rx_disabled_evt(dev);
    }
    
    void uart_nrfx_isr(const struct device *uart)
    {
    	if (nrf_uart_int_enable_check(uart0_addr, NRF_UART_INT_MASK_ERROR) &&
    	    nrf_uart_event_check(uart0_addr, NRF_UART_EVENT_ERROR)) {
    		error_isr(uart);
    	} else if (nrf_uart_int_enable_check(uart0_addr,
    					     NRF_UART_INT_MASK_RXDRDY) &&
    		   nrf_uart_event_check(uart0_addr, NRF_UART_EVENT_RXDRDY)) {
    		rx_isr(uart);
    	}
    
    	if (nrf_uart_event_check(uart0_addr, NRF_UART_EVENT_TXDRDY)
    	    && nrf_uart_int_enable_check(uart0_addr,
    					 NRF_UART_INT_MASK_TXDRDY)) {
    		tx_isr(uart);
    	}
    
    	if (nrf_uart_event_check(uart0_addr, NRF_UART_EVENT_RXTO)) {
    		rxto_isr(uart);
    	}
    }
    
    static void rx_timeout(struct k_timer *timer)
    {
    	rx_rdy_evt(DEVICE_DT_INST_GET(0));
    }
    
    #if HW_FLOW_CONTROL_AVAILABLE
    static void tx_timeout(struct k_timer *timer)
    {
    	struct uart_event evt;
    
    	if (uart0_cb.tx_timeout != SYS_FOREVER_US) {
    		k_timer_stop(&uart0_cb.tx_timeout_timer);
    	}
    	nrf_uart_task_trigger(uart0_addr, NRF_UART_TASK_STOPTX);
    	evt.type = UART_TX_ABORTED;
    	evt.data.tx.buf = uart0_cb.tx_buffer;
    	evt.data.tx.len = uart0_cb.tx_buffer_length;
    	uart0_cb.tx_buffer_length = 0;
    	uart0_cb.tx_counter = 0;
    	user_callback(DEVICE_DT_INST_GET(0), &evt);
    }
    #endif
    
    #endif /* CONFIG_UART_0_ASYNC */
    
    
    #ifdef CONFIG_UART_0_INTERRUPT_DRIVEN
    
    /** Interrupt driven FIFO fill function */
    static int uart_nrfx_fifo_fill(const struct device *dev,
    			       const uint8_t *tx_data,
    			       int len)
    {
    	uint8_t num_tx = 0U;
    
    	while ((len - num_tx > 0) &&
    	       event_txdrdy_check()) {
    
    		/* Clear the interrupt */
    		event_txdrdy_clear();
    
    		/* Send a character */
    		nrf_uart_txd_set(uart0_addr, (uint8_t)tx_data[num_tx++]);
    	}
    
    	return (int)num_tx;
    }
    
    /** Interrupt driven FIFO read function */
    static int uart_nrfx_fifo_read(const struct device *dev,
    			       uint8_t *rx_data,
    			       const int size)
    {
    	uint8_t num_rx = 0U;
    
    	while ((size - num_rx > 0) &&
    	       nrf_uart_event_check(uart0_addr, NRF_UART_EVENT_RXDRDY)) {
    		/* Clear the interrupt */
    		nrf_uart_event_clear(uart0_addr, NRF_UART_EVENT_RXDRDY);
    
    		/* Receive a character */
    		rx_data[num_rx++] = (uint8_t)nrf_uart_rxd_get(uart0_addr);
    	}
    
    	return num_rx;
    }
    
    /** Interrupt driven transfer enabling function */
    static void uart_nrfx_irq_tx_enable(const struct device *dev)
    {
    	uint32_t key;
    
    	disable_tx_irq = false;
    
    	/* Indicate that this device started a transaction that should not be
    	 * interrupted by putting the SoC into the deep sleep mode.
    	 */
    	pm_device_busy_set(dev);
    
    	/* Activate the transmitter. */
    	nrf_uart_task_trigger(uart0_addr, NRF_UART_TASK_STARTTX);
    
    	nrf_uart_int_enable(uart0_addr, NRF_UART_INT_MASK_TXDRDY);
    
    	/* Critical section is used to avoid any UART related interrupt which
    	 * can occur after the if statement and before call of the function
    	 * forcing an interrupt.
    	 */
    	key = irq_lock();
    	if (uart_sw_event_txdrdy) {
    		/* Due to HW limitation first TXDRDY interrupt shall be
    		 * triggered by the software.
    		 */
    		NVIC_SetPendingIRQ(IRQN);
    	}
    	irq_unlock(key);
    }
    
    /** Interrupt driven transfer disabling function */
    static void uart_nrfx_irq_tx_disable(const struct device *dev)
    {
    	/* Disable TX interrupt in uart_nrfx_isr() when transmission is done. */
    	disable_tx_irq = true;
    }
    
    /** Interrupt driven receiver enabling function */
    static void uart_nrfx_irq_rx_enable(const struct device *dev)
    {
    	nrf_uart_int_enable(uart0_addr, NRF_UART_INT_MASK_RXDRDY);
    }
    
    /** Interrupt driven receiver disabling function */
    static void uart_nrfx_irq_rx_disable(const struct device *dev)
    {
    	nrf_uart_int_disable(uart0_addr, NRF_UART_INT_MASK_RXDRDY);
    }
    
    /** Interrupt driven transfer empty function */
    static int uart_nrfx_irq_tx_ready_complete(const struct device *dev)
    {
    	/* Signal TX readiness only when the TX interrupt is enabled and there
    	 * is no pending request to disable it. Note that this function may get
    	 * called after the TX interrupt is requested to be disabled but before
    	 * the disabling is actually performed (in the IRQ handler).
    	 */
    	return nrf_uart_int_enable_check(uart0_addr,
    					 NRF_UART_INT_MASK_TXDRDY) &&
    	       !disable_tx_irq &&
    	       event_txdrdy_check();
    }
    
    /** Interrupt driven receiver ready function */
    static int uart_nrfx_irq_rx_ready(const struct device *dev)
    {
    	return nrf_uart_event_check(uart0_addr, NRF_UART_EVENT_RXDRDY);
    }
    
    /** Interrupt driven error enabling function */
    static void uart_nrfx_irq_err_enable(const struct device *dev)
    {
    	nrf_uart_int_enable(uart0_addr, NRF_UART_INT_MASK_ERROR);
    }
    
    /** Interrupt driven error disabling function */
    static void uart_nrfx_irq_err_disable(const struct device *dev)
    {
    	nrf_uart_int_disable(uart0_addr, NRF_UART_INT_MASK_ERROR);
    }
    
    /** Interrupt driven pending status function */
    static int uart_nrfx_irq_is_pending(const struct device *dev)
    {
    	return ((nrf_uart_int_enable_check(uart0_addr,
    					   NRF_UART_INT_MASK_TXDRDY) &&
    		 uart_nrfx_irq_tx_ready_complete(dev))
    		||
    		(nrf_uart_int_enable_check(uart0_addr,
    					   NRF_UART_INT_MASK_RXDRDY) &&
    		 uart_nrfx_irq_rx_ready(dev)));
    }
    
    /** Interrupt driven interrupt update function */
    static int uart_nrfx_irq_update(const struct device *dev)
    {
    	return 1;
    }
    
    /** Set the callback function */
    static void uart_nrfx_irq_callback_set(const struct device *dev,
    				       uart_irq_callback_user_data_t cb,
    				       void *cb_data)
    {
    	(void)dev;
    	irq_callback = cb;
    	irq_cb_data = cb_data;
    }
    
    /**
     * @brief Interrupt service routine.
     *
     * This simply calls the callback function, if one exists.
     *
     * @param arg Argument to ISR.
     */
    static void uart_nrfx_isr(const struct device *dev)
    {
    	if (disable_tx_irq &&
    	    nrf_uart_event_check(uart0_addr, NRF_UART_EVENT_TXDRDY)) {
    		nrf_uart_int_disable(uart0_addr, NRF_UART_INT_MASK_TXDRDY);
    
    		/* Deactivate the transmitter so that it does not needlessly
    		 * consume power.
    		 */
    		nrf_uart_task_trigger(uart0_addr, NRF_UART_TASK_STOPTX);
    
    		/* The transaction is over. It is okay to enter the deep sleep
    		 * mode if needed.
    		 */
    		pm_device_busy_clear(dev);
    
    		disable_tx_irq = false;
    
    		return;
    	}
    
    	if (nrf_uart_event_check(uart0_addr, NRF_UART_EVENT_ERROR)) {
    		nrf_uart_event_clear(uart0_addr, NRF_UART_EVENT_ERROR);
    	}
    
    	if (irq_callback) {
    		irq_callback(dev, irq_cb_data);
    	}
    }
    #endif /* CONFIG_UART_0_INTERRUPT_DRIVEN */
    
    /**
     * @brief Initialize UART channel
     *
     * This routine is called to reset the chip in a quiescent state.
     * It is assumed that this function is called only once per UART.
     *
     * @param dev UART device struct
     *
     * @return 0 on success
     */
    static int uart_nrfx_init(const struct device *dev)
    {
    	struct uart_nrfx_data *data = dev->data;
    	int err;
    #ifdef CONFIG_PINCTRL
    	const struct uart_nrfx_config *config = dev->config;
    #endif /* CONFIG_PINCTRL */
    
    	nrf_uart_disable(uart0_addr);
    
    #ifdef CONFIG_PINCTRL
    	err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
    	if (err < 0) {
    		return err;
    	}
    #else
    	uart_nrfx_pins_configure(dev, false);
    #endif /* CONFIG_PINCTRL */
    
    	/* Set initial configuration */
    	err = uart_nrfx_configure(dev, &data->uart_config);
    	if (err) {
    		return err;
    	}
    
    	/* Enable the UART and activate its receiver. With the current API
    	 * the receiver needs to be active all the time. The transmitter
    	 * will be activated when there is something to send.
    	 */
    	nrf_uart_enable(uart0_addr);
    
    	if (!DISABLE_RX) {
    		nrf_uart_event_clear(uart0_addr, NRF_UART_EVENT_RXDRDY);
    
    		nrf_uart_task_trigger(uart0_addr, NRF_UART_TASK_STARTRX);
    	}
    
    #ifdef CONFIG_UART_0_INTERRUPT_DRIVEN
    	/* Simulate that the TXDRDY event is set, so that the transmitter status
    	 * is indicated correctly.
    	 */
    	uart_sw_event_txdrdy = 1U;
    #endif
    
    #if defined(CONFIG_UART_0_ASYNC) || defined(CONFIG_UART_0_INTERRUPT_DRIVEN)
    
    	IRQ_CONNECT(IRQN,
    		    IRQ_PRIO,
    		    uart_nrfx_isr,
    		    DEVICE_DT_INST_GET(0),
    		    0);
    	irq_enable(IRQN);
    #endif
    
    #ifdef CONFIG_UART_0_ASYNC
    	k_timer_init(&uart0_cb.rx_timeout_timer, rx_timeout, NULL);
    #if HW_FLOW_CONTROL_AVAILABLE
    	k_timer_init(&uart0_cb.tx_timeout_timer, tx_timeout, NULL);
    #endif
    #endif
    	return 0;
    }
    
    /* Common function: uart_nrfx_irq_tx_ready_complete is used for two API entries
     * because Nordic hardware does not distinguish between them.
     */
    static const struct uart_driver_api uart_nrfx_uart_driver_api = {
    #ifdef CONFIG_UART_0_ASYNC
    	.callback_set	  = uart_nrfx_callback_set,
    	.tx		  = uart_nrfx_tx,
    	.tx_abort	  = uart_nrfx_tx_abort,
    	.rx_enable	  = uart_nrfx_rx_enable,
    	.rx_buf_rsp	  = uart_nrfx_rx_buf_rsp,
    	.rx_disable	  = uart_nrfx_rx_disable,
    #endif /* CONFIG_UART_0_ASYNC */
    	.poll_in          = uart_nrfx_poll_in,
    	.poll_out         = uart_nrfx_poll_out,
    	.err_check        = uart_nrfx_err_check,
    #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
    	.configure        = uart_nrfx_configure,
    	.config_get       = uart_nrfx_config_get,
    #endif
    #ifdef CONFIG_UART_0_INTERRUPT_DRIVEN
    	.fifo_fill        = uart_nrfx_fifo_fill,
    	.fifo_read        = uart_nrfx_fifo_read,
    	.irq_tx_enable    = uart_nrfx_irq_tx_enable,
    	.irq_tx_disable   = uart_nrfx_irq_tx_disable,
    	.irq_tx_ready     = uart_nrfx_irq_tx_ready_complete,
    	.irq_rx_enable    = uart_nrfx_irq_rx_enable,
    	.irq_rx_disable   = uart_nrfx_irq_rx_disable,
    	.irq_tx_complete  = uart_nrfx_irq_tx_ready_complete,
    	.irq_rx_ready     = uart_nrfx_irq_rx_ready,
    	.irq_err_enable   = uart_nrfx_irq_err_enable,
    	.irq_err_disable  = uart_nrfx_irq_err_disable,
    	.irq_is_pending   = uart_nrfx_irq_is_pending,
    	.irq_update       = uart_nrfx_irq_update,
    	.irq_callback_set = uart_nrfx_irq_callback_set,
    #endif /* CONFIG_UART_0_INTERRUPT_DRIVEN */
    };
    
    #ifdef CONFIG_PM_DEVICE
    static int uart_nrfx_pm_action(const struct device *dev,
    			       enum pm_device_action action)
    {
    #ifdef CONFIG_PINCTRL
    	const struct uart_nrfx_config *config = dev->config;
    	int ret;
    #endif
    
    	switch (action) {
    	case PM_DEVICE_ACTION_RESUME:
    		if (IS_ENABLED(CONFIG_UART_0_GPIO_MANAGEMENT)) {
    #ifdef CONFIG_PINCTRL
    			ret = pinctrl_apply_state(config->pcfg,
    						  PINCTRL_STATE_DEFAULT);
    			if (ret < 0) {
    				return ret;
    			}
    #else
    			uart_nrfx_pins_configure(dev, false);
    #endif /* CONFIG_PINCTRL */
    		}
    
    		nrf_uart_enable(uart0_addr);
    		if (!DISABLE_RX) {
    			nrf_uart_task_trigger(uart0_addr,
    					      NRF_UART_TASK_STARTRX);
    		}
    		break;
    	case PM_DEVICE_ACTION_SUSPEND:
    		nrf_uart_disable(uart0_addr);
    
    		if (IS_ENABLED(CONFIG_UART_0_GPIO_MANAGEMENT)) {
    #ifdef CONFIG_PINCTRL
    			ret = pinctrl_apply_state(config->pcfg,
    						  PINCTRL_STATE_SLEEP);
    			if (ret < 0) {
    				return ret;
    			}
    #else
    			uart_nrfx_pins_configure(dev, true);
    #endif /* CONFIG_PINCTRL */
    		}
    		break;
    	default:
    		return -ENOTSUP;
    	}
    
    	return 0;
    }
    #endif /* CONFIG_PM_DEVICE */
    
    #ifdef CONFIG_PINCTRL
    PINCTRL_DT_INST_DEFINE(0);
    #endif /* CONFIG_PINCTRL */
    
    NRF_DT_CHECK_PIN_ASSIGNMENTS(DT_DRV_INST(0), 1,
    			     tx_pin, rx_pin, rts_pin, cts_pin);
    
    static const struct uart_nrfx_config uart_nrfx_uart0_config = {
    #ifdef CONFIG_PINCTRL
    	.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
    #else
    	.tx_pin = DT_INST_PROP_OR(0, tx_pin, NRF_UART_PSEL_DISCONNECTED),
    	.rx_pin = DT_INST_PROP_OR(0, rx_pin, NRF_UART_PSEL_DISCONNECTED),
    	.rts_pin = DT_INST_PROP_OR(0, rts_pin, NRF_UART_PSEL_DISCONNECTED),
    	.cts_pin = DT_INST_PROP_OR(0, cts_pin, NRF_UART_PSEL_DISCONNECTED),
    	.rx_pull_up = DT_INST_PROP(0, rx_pull_up),
    	.cts_pull_up = DT_INST_PROP(0, cts_pull_up)
    #endif /* CONFIG_PINCTRL */
    };
    
    static struct uart_nrfx_data uart_nrfx_uart0_data = {
    	.uart_config = {
    		.stop_bits = UART_CFG_STOP_BITS_1,
    		.data_bits = UART_CFG_DATA_BITS_8,
    		.baudrate  = BAUDRATE,
    #ifdef CONFIG_UART_0_NRF_PARITY_BIT
    		.parity    = UART_CFG_PARITY_EVEN,
    #else
    		.parity    = UART_CFG_PARITY_NONE,
    #endif /* CONFIG_UART_0_NRF_PARITY_BIT */
    		.flow_ctrl = PROP(hw_flow_control) ?
    			UART_CFG_FLOW_CTRL_RTS_CTS : UART_CFG_FLOW_CTRL_NONE,
    	}
    };
    
    PM_DEVICE_DT_INST_DEFINE(0, uart_nrfx_pm_action);
    
    DEVICE_DT_INST_DEFINE(0,
    	      uart_nrfx_init,
    	      PM_DEVICE_DT_INST_GET(0),
    	      &uart_nrfx_uart0_data,
    	      &uart_nrfx_uart0_config,
    	      /* Initialize UART device before UART console. */
    	      PRE_KERNEL_1,
    	      CONFIG_SERIAL_INIT_PRIORITY,
    	      &uart_nrfx_uart_driver_api);
    

    static void uartCallback(const struct device *dev, struct uart_event *evt, void *user_data)
    {
        int err;
        static uint16_t pos;
    
        ARG_UNUSED(user_data);
    
        switch (evt->type) {
            case UART_TX_DONE:
                sendData(0x01);
                break;
            case UART_TX_ABORTED:
                sendData(0x02);
                break;
            case UART_RX_RDY:
                for (int i = pos; i < (pos + evt->data.rx.len); i++) 
                {
                    if( ++UART_BUF->head == MAX_UART_BUF_SIZE )
                    {
                        UART_BUF->head = 0;
                    }
                    sendData(evt->data.rx.buf[i]);
                    UART_BUF->queue[UART_BUF->head] = evt->data.rx.buf[i];                   // data save
                    if( UART_BUF->head == UART_BUF->tail )
                    {
                        UART_BUF->overflow = 1;
                    }
                }
                pos += evt->data.rx.len;
                break;
            case UART_RX_BUF_REQUEST:
                pos = 0;
                err = uart_rx_buf_rsp(pUartDev, pNextUartBuf, sizeof(uartRxBuf[0]));
                if (err) {
                    LOG_ERR("UART RX buf rsp: %d", err);
                }
                sendData(0x03);
                break;
            case UART_RX_BUF_RELEASED:
                sendData(0x04);
                pNextUartBuf = evt->data.rx_buf.buf;
                break;
            case UART_RX_STOPPED:
                sendData(0x05);
                uartErr = evt->data.rx_stop.reason;
                break;
            case UART_RX_DISABLED:
                sendData(0x06);
                break;
            default:
                break;
        }
    }

    When sending 21 bytes, the output is functioning correctly for about 12 to 13 bytes. However, after that, when it transitions to the UART_RX_STOPPED state, the output becomes 0x05.

    I would be grateful if you could provide me with the details of the problem you're facing so that I can assist you in finding a solution.

    Additionally, there was no applicable error source for the explanation provided earlier.

    Here is a captured picture of entering the error ISR (Interrupt Service Routine) in debug mode.

  • Hi,

     

    You are currently selecting NRF_UART, and not the DMA capable NRF_UARTE peripheral.

    Could you try with the NRF_UARTE peripheral instead? This is done by selecting nrf-uarte in device tree:

    compatible = "nordic,nrf-uarte";

     

    Kind regards,

    Håkon

  • I don't know how to modify it to use UARTE.

    Do I need to use a different driver?

  • I was using nRF Connect SDK v1.5.0 in the Toolchain Manager of nRF Connect for Desktop, but I changed it to nRF Connect SDK v2.1.0.

    I didn't encounter this issue with nRF Connect SDK v1.5.0, even though the source code remains the same.

    Why is this happening?

    I tried using UARTE in Kconfig, but it failed to build due to an error.

  • Hi,

     

    In order to use the UARTE peripheral, you set this in your overlay file.

    That should be in my_project/boards/my_board.overlay

     

    If you are using nRF52833 DK board, replace "my_board.overlay" with "nrf52833dk_nrf52833.overlay".

     

    And contain something like this:

    https://github.com/nrfconnect/sdk-zephyr/blob/v3.3.99-ncs1/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts#L146

     

    Ie.

    &uart0 
    {
        compatible = "nordic,nrf-uarte";
    };

     

    Kind regards,

    Håkon

Related