Problem with Async UART Example from peripheral_uart

Trying to integrate the serial part of the example code for use with a custom nRF52840 board. The problem is that I'm getting an error in uart_callback_set(uart, uart_cb, NULL) that is causing "Cannot initialize UART callback" to be displayed. I'm using UART1 which works with a different interrupt version of this code. Not sure what I'm missing here to get the callback initialized.

int initUart() {
int err;
int pos;
struct uart_data_t *rx;
struct uart_data_t *tx;

   //fifoInit();
   uart = device_get_binding("UART_1");
	__ASSERT(uart, "Failed to get UART device");
	//interrupt_driven(uart);

	if (!uart) {
		return -ENXIO;
	}

	rx = k_malloc(sizeof(*rx));
	if (rx) {
		rx->len = 0;
	} else {
		return -ENOMEM;
	}

	k_work_init_delayable(&uart_work, uart_work_handler);

	err = uart_callback_set(uart, uart_cb, NULL);
	if (err) {
		LOG_ERR("Cannot initialize UART callback");
		return err;
	}

CONFIG_STDOUT_CONSOLE=n
CONFIG_UART_CONSOLE=n
CONFIG_NRF_SW_LPUART=n
CONFIG_NRF_SW_LPUART_INT_DRIVEN=y

# UART
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_UART_LINE_CTRL=n
CONFIG_UART_ASYNC_API=y
CONFIG_UART_0_ASYNC=y
CONFIG_UART_1_ASYNC=y
CONFIG_UART_0_NRF_HW_ASYNC=y
CONFIG_UART_1_NRF_HW_ASYNC=y
CONFIG_UART_0_NRF_HW_ASYNC_TIMER=1
CONFIG_UART_1_NRF_HW_ASYNC_TIMER=2
CONFIG_NRFX_UARTE=y
CONFIG_NRFX_UARTE0=y
CONFIG_NRFX_UARTE1=y
CONFIG_NRFX_TIMER=y
CONFIG_NRFX_TIMER1=y
CONFIG_NRFX_TIMER2=y
CONFIG_NRFX_PPI=y
CONFIG_NRFX_TIMER2=y

Parents
  • Hello Paul, 

    NautDesigner said:
    The problem is that api->callback_set is NULL. Where am I not setting this?

    I’m not quite sure why that happens. I took the Hello World sample as a starting point and added parts of the code you provided to it. 

    /*
     * Copyright (c) 2012-2014 Wind River Systems, Inc.
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr.h>
    #include <zephyr/device.h>
    #include <drivers/uart.h>
    #include <zephyr/logging/log.h>
    
    LOG_MODULE_REGISTER(application_module, CONFIG_APPLICATION_MODULE_LOG_LEVEL);
    
    
    static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
    {
    	// ARG_UNUSED(dev);
    
    	// static uint8_t *current_buf;
    	// static size_t aborted_len;
    	// static bool buf_release;
    	// struct uart_data_t *buf;
    	// static uint8_t *aborted_buf;
    
    	switch (evt->type) {
    	case UART_TX_DONE:
    		LOG_DBG("tx_done");
    		// if ((evt->data.tx.len == 0) ||
    		//     (!evt->data.tx.buf)) {
    		// 	return;
    		// }
    
    	// 	if (aborted_buf) {
    	// 		buf = CONTAINER_OF(aborted_buf, struct uart_data_t,
    	// 				   data);
    	// 		aborted_buf = NULL;
    	// 		aborted_len = 0;
    	// 	} else {
    	// 		buf = CONTAINER_OF(evt->data.tx.buf, struct uart_data_t,
    	// 				   data);
    	// 	}
    
    	// 	k_free(buf);
    
    	// 	buf = k_fifo_get(&fifo_uart_tx_data, K_NO_WAIT);
    	// 	if (!buf) {
    	// 		return;
    	// 	}
    
    	// 	if (uart_tx(uart, buf->data, buf->len, SYS_FOREVER_MS)) {
    	// 		LOG_WRN("Failed to send data over UART");
    	// 	}
    
    	// 	break;
    
    	case UART_RX_RDY:
    		LOG_DBG("rx_rdy");
    		// buf = CONTAINER_OF(evt->data.rx.buf, struct uart_data_t, data);
    		// buf->len += evt->data.rx.len;
    		// buf_release = false;
    
    		// if (buf->len == UART_BUF_SIZE) {
    		// 	k_fifo_put(&fifo_uart_rx_data, buf);
    		// } else if ((evt->data.rx.buf[buf->len - 1] == '\n') ||
    		// 	  (evt->data.rx.buf[buf->len - 1] == '\r')) {
    		// 	k_fifo_put(&fifo_uart_rx_data, buf);
    		// 	current_buf = evt->data.rx.buf;
    		// 	buf_release = true;
    		// 	uart_rx_disable(uart);
    		// }
    
    		break;
    
    	// case UART_RX_DISABLED:
    	// 	LOG_DBG("rx_disabled");
    	// 	buf = k_malloc(sizeof(*buf));
    	// 	if (buf) {
    	// 		buf->len = 0;
    	// 	} else {
    	// 		LOG_WRN("Not able to allocate UART receive buffer");
    	// 		k_work_reschedule(&uart_work, UART_WAIT_FOR_BUF_DELAY);
    	// 		return;
    	// 	}
    
    	// 	uart_rx_enable(uart, buf->data, sizeof(buf->data),
    	// 		       UART_WAIT_FOR_RX);
    
    	// 	break;
    
    	// case UART_RX_BUF_REQUEST:
    	// 	LOG_DBG("rx_buf_request");
    	// 	buf = k_malloc(sizeof(*buf));
    	// 	if (buf) {
    	// 		buf->len = 0;
    	// 		uart_rx_buf_rsp(uart, buf->data, sizeof(buf->data));
    	// 	} else {
    	// 		LOG_WRN("Not able to allocate UART receive buffer");
    	// 	}
    
    	// 	break;
    
    	// case UART_RX_BUF_RELEASED:
    	// 	LOG_DBG("rx_buf_released");
    	// 	buf = CONTAINER_OF(evt->data.rx_buf.buf, struct uart_data_t,
    	// 			   data);
    	// 	if (buf_release && (current_buf != evt->data.rx_buf.buf)) {
    	// 		k_free(buf);
    	// 		buf_release = false;
    	// 		current_buf = NULL;
    	// 	}
    
    	// 	break;
    
    	// case UART_TX_ABORTED:
    	// 		LOG_DBG("tx_aborted");
    	// 		if (!aborted_buf) {
    	// 			aborted_buf = (uint8_t *)evt->data.tx.buf;
    	// 		}
    
    	// 		aborted_len += evt->data.tx.len;
    	// 		buf = CONTAINER_OF(aborted_buf, struct uart_data_t,
    	// 				   data);
    
    	// 		uart_tx(uart, &buf->data[aborted_len],
    	// 			buf->len - aborted_len, SYS_FOREVER_MS);
    
    	// 	break;
    
    	default:
    		break;
    	}
    }
    
    void main(void)
    {
    	LOG_INF("Hello World! %s", CONFIG_BOARD);
    
    	int err;
    	//int pos;
    	//struct uart_data_t *rx;
    	//struct uart_data_t *tx;
    
       	//fifoInit();
    	const struct device *uart;
       	uart = device_get_binding("UART_1");
    	__ASSERT(uart, "Failed to get UART device");
    	//interrupt_driven(uart);
    
    	if (!uart) {
    		return /*-ENXIO*/;
    	}
    
    	// rx = k_malloc(sizeof(*rx));
    	// if (rx) {
    	// 	rx->len = 0;
    	// } else {
    	// 	return /*-ENOMEM*/;
    	// }
    
    	//k_work_init_delayable(&uart_work, uart_work_handler);
    
    	err = uart_callback_set(uart, uart_cb, NULL);
    	if (err) {
    		LOG_ERR("Cannot initialize UART callback");
    		return /*err*/;
    	}
    	else LOG_INF("UART callback handler successfully initialised!");
    }

    # nothing here
    CONFIG_UART_ASYNC_API=y
    CONFIG_LOG=y

    I’m not able to reproduce the error, see log below. 

    *** Booting Zephyr OS build v3.0.99-ncs1  ***
    [00:00:00.366,516] <inf> application_module: Hello World! nrf52840dk_nrf52840
    [00:00:00.366,516] <inf> application_module: UART callback handler successfully initialised!

    Could this maybe be a devicetree issue with your custom board? 

    Cheers, 

    Markus 

Reply
  • Hello Paul, 

    NautDesigner said:
    The problem is that api->callback_set is NULL. Where am I not setting this?

    I’m not quite sure why that happens. I took the Hello World sample as a starting point and added parts of the code you provided to it. 

    /*
     * Copyright (c) 2012-2014 Wind River Systems, Inc.
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr.h>
    #include <zephyr/device.h>
    #include <drivers/uart.h>
    #include <zephyr/logging/log.h>
    
    LOG_MODULE_REGISTER(application_module, CONFIG_APPLICATION_MODULE_LOG_LEVEL);
    
    
    static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
    {
    	// ARG_UNUSED(dev);
    
    	// static uint8_t *current_buf;
    	// static size_t aborted_len;
    	// static bool buf_release;
    	// struct uart_data_t *buf;
    	// static uint8_t *aborted_buf;
    
    	switch (evt->type) {
    	case UART_TX_DONE:
    		LOG_DBG("tx_done");
    		// if ((evt->data.tx.len == 0) ||
    		//     (!evt->data.tx.buf)) {
    		// 	return;
    		// }
    
    	// 	if (aborted_buf) {
    	// 		buf = CONTAINER_OF(aborted_buf, struct uart_data_t,
    	// 				   data);
    	// 		aborted_buf = NULL;
    	// 		aborted_len = 0;
    	// 	} else {
    	// 		buf = CONTAINER_OF(evt->data.tx.buf, struct uart_data_t,
    	// 				   data);
    	// 	}
    
    	// 	k_free(buf);
    
    	// 	buf = k_fifo_get(&fifo_uart_tx_data, K_NO_WAIT);
    	// 	if (!buf) {
    	// 		return;
    	// 	}
    
    	// 	if (uart_tx(uart, buf->data, buf->len, SYS_FOREVER_MS)) {
    	// 		LOG_WRN("Failed to send data over UART");
    	// 	}
    
    	// 	break;
    
    	case UART_RX_RDY:
    		LOG_DBG("rx_rdy");
    		// buf = CONTAINER_OF(evt->data.rx.buf, struct uart_data_t, data);
    		// buf->len += evt->data.rx.len;
    		// buf_release = false;
    
    		// if (buf->len == UART_BUF_SIZE) {
    		// 	k_fifo_put(&fifo_uart_rx_data, buf);
    		// } else if ((evt->data.rx.buf[buf->len - 1] == '\n') ||
    		// 	  (evt->data.rx.buf[buf->len - 1] == '\r')) {
    		// 	k_fifo_put(&fifo_uart_rx_data, buf);
    		// 	current_buf = evt->data.rx.buf;
    		// 	buf_release = true;
    		// 	uart_rx_disable(uart);
    		// }
    
    		break;
    
    	// case UART_RX_DISABLED:
    	// 	LOG_DBG("rx_disabled");
    	// 	buf = k_malloc(sizeof(*buf));
    	// 	if (buf) {
    	// 		buf->len = 0;
    	// 	} else {
    	// 		LOG_WRN("Not able to allocate UART receive buffer");
    	// 		k_work_reschedule(&uart_work, UART_WAIT_FOR_BUF_DELAY);
    	// 		return;
    	// 	}
    
    	// 	uart_rx_enable(uart, buf->data, sizeof(buf->data),
    	// 		       UART_WAIT_FOR_RX);
    
    	// 	break;
    
    	// case UART_RX_BUF_REQUEST:
    	// 	LOG_DBG("rx_buf_request");
    	// 	buf = k_malloc(sizeof(*buf));
    	// 	if (buf) {
    	// 		buf->len = 0;
    	// 		uart_rx_buf_rsp(uart, buf->data, sizeof(buf->data));
    	// 	} else {
    	// 		LOG_WRN("Not able to allocate UART receive buffer");
    	// 	}
    
    	// 	break;
    
    	// case UART_RX_BUF_RELEASED:
    	// 	LOG_DBG("rx_buf_released");
    	// 	buf = CONTAINER_OF(evt->data.rx_buf.buf, struct uart_data_t,
    	// 			   data);
    	// 	if (buf_release && (current_buf != evt->data.rx_buf.buf)) {
    	// 		k_free(buf);
    	// 		buf_release = false;
    	// 		current_buf = NULL;
    	// 	}
    
    	// 	break;
    
    	// case UART_TX_ABORTED:
    	// 		LOG_DBG("tx_aborted");
    	// 		if (!aborted_buf) {
    	// 			aborted_buf = (uint8_t *)evt->data.tx.buf;
    	// 		}
    
    	// 		aborted_len += evt->data.tx.len;
    	// 		buf = CONTAINER_OF(aborted_buf, struct uart_data_t,
    	// 				   data);
    
    	// 		uart_tx(uart, &buf->data[aborted_len],
    	// 			buf->len - aborted_len, SYS_FOREVER_MS);
    
    	// 	break;
    
    	default:
    		break;
    	}
    }
    
    void main(void)
    {
    	LOG_INF("Hello World! %s", CONFIG_BOARD);
    
    	int err;
    	//int pos;
    	//struct uart_data_t *rx;
    	//struct uart_data_t *tx;
    
       	//fifoInit();
    	const struct device *uart;
       	uart = device_get_binding("UART_1");
    	__ASSERT(uart, "Failed to get UART device");
    	//interrupt_driven(uart);
    
    	if (!uart) {
    		return /*-ENXIO*/;
    	}
    
    	// rx = k_malloc(sizeof(*rx));
    	// if (rx) {
    	// 	rx->len = 0;
    	// } else {
    	// 	return /*-ENOMEM*/;
    	// }
    
    	//k_work_init_delayable(&uart_work, uart_work_handler);
    
    	err = uart_callback_set(uart, uart_cb, NULL);
    	if (err) {
    		LOG_ERR("Cannot initialize UART callback");
    		return /*err*/;
    	}
    	else LOG_INF("UART callback handler successfully initialised!");
    }

    # nothing here
    CONFIG_UART_ASYNC_API=y
    CONFIG_LOG=y

    I’m not able to reproduce the error, see log below. 

    *** Booting Zephyr OS build v3.0.99-ncs1  ***
    [00:00:00.366,516] <inf> application_module: Hello World! nrf52840dk_nrf52840
    [00:00:00.366,516] <inf> application_module: UART callback handler successfully initialised!

    Could this maybe be a devicetree issue with your custom board? 

    Cheers, 

    Markus 

Children
No Data
Related