Trying to Implement central_uart on a nrf52840 dongle

Hello! I am a newcomer to nrf and embedded programming (other than basic arduino and micropython projects). So far I have gone through many of the devacademy walkthroughs. What I want to do is simply implement central_uart and peripheral_uart on two nrf52840 dongles so I can use NUS to send messages back and forth between them. I already have my peripheral send messages to my phone's nrf connect app and this works well, however it is very basic (I wrote it myself with peripheral_nus example) so I want to transition to peripheral_uart. My first step was to get central_uart and/or peripheral_uart working on my dongles. I started with central_uart. However, when flashing it onto my device and looking at the log through the serial port I run into "<err> central_uart: uart_init failed (err -88). After adding some debugging messages into the uart_init function I find that the -88 error is coming from the "uart_callback_set" command. I am not sure how to remedy this, or if additional work needs to be done from the stock central_uart before I flash it onto my nrf 52840 dongle.

Other than debug messages and enabling them I have not edited the code from the stock.

Thoughts? Advice?

Parents
  • Hello,

    Your overlay and shared code snippet look fine to me. I assume that the device binding is properly configured for UART0, as indicated by `static const struct device *uart = DEVICE_DT_GET(DT_NODELABEL(uart0))`. This configuration may differ from the sample code.

    Could you also check if the issue might be related to the UART callback (`uart_cb`)?

    Kind Regards,

    Abhijith

Reply
  • Hello,

    Your overlay and shared code snippet look fine to me. I assume that the device binding is properly configured for UART0, as indicated by `static const struct device *uart = DEVICE_DT_GET(DT_NODELABEL(uart0))`. This configuration may differ from the sample code.

    Could you also check if the issue might be related to the UART callback (`uart_cb`)?

    Kind Regards,

    Abhijith

Children
  • Abhijith thanks for your continued support.

    I also agree that the issue might be related to the uart_cb function. I doubt there is anything wrong with the function as it sits though because I am pulling it directly from the sample file.

    Regardless here it is:

    static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
    {
    	ARG_UNUSED(dev);
    
    	static size_t aborted_len;
    	struct uart_data_t *buf;
    	static uint8_t *aborted_buf;
    	static bool disable_req;
    
    	switch (evt->type) {
    	case UART_TX_DONE:
    		LOG_DBG("UART_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[0]);
    			aborted_buf = NULL;
    			aborted_len = 0;
    		} else {
    			buf = CONTAINER_OF(evt->data.tx.buf,
    					   struct uart_data_t,
    					   data[0]);
    		}
    
    		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("UART_RX_RDY");
    		buf = CONTAINER_OF(evt->data.rx.buf, struct uart_data_t, data[0]);
    		buf->len += evt->data.rx.len;
    
    		if (disable_req) {
    			return;
    		}
    
    		if ((evt->data.rx.buf[buf->len - 1] == '\n') ||
    		    (evt->data.rx.buf[buf->len - 1] == '\r')) {
    			disable_req = true;
    			uart_rx_disable(uart);
    		}
    
    		break;
    
    	case UART_RX_DISABLED:
    		LOG_DBG("UART_RX_DISABLED");
    		disable_req = false;
    
    		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_RX_TIMEOUT);
    
    		break;
    
    	case UART_RX_BUF_REQUEST:
    		LOG_DBG("UART_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("UART_RX_BUF_RELEASED");
    		buf = CONTAINER_OF(evt->data.rx_buf.buf, struct uart_data_t,
    				   data[0]);
    
    		if (buf->len > 0) {
    			k_fifo_put(&fifo_uart_rx_data, buf);
    		} else {
    			k_free(buf);
    		}
    
    		break;
    
    	case UART_TX_ABORTED:
    		LOG_DBG("UART_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[0]);
    
    		uart_tx(uart, &buf->data[aborted_len],
    			buf->len - aborted_len, SYS_FOREVER_MS);
    
    		break;
    
    	default:
    		break;
    	}
    }
     

    Is it possible that it is something to do with the configuration file though?

Related