uart_callback_set is returning ENSOYS error.

Hi,

I’m working on enabling the asynchronous API on UART1 in the nRF Cloud Multi-Service sample for the nRF9151. Despite setting the necessary configurations, when I call uart_callback_set() for UART1, it returns -ENOSYS, which indicates that the device does not support the asynchronous API.

This is my prj.conf

#
# Copyright (c) 2022 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

# Log level
# For more verbose and detailed log output, set the log level to
# CONFIG_MULTI_SERVICE_LOG_LEVEL_DBG=y instead.
CONFIG_MULTI_SERVICE_LOG_LEVEL_INF=y

# General config
CONFIG_EVENTS=y
CONFIG_PICOLIBC_IO_FLOAT=y
CONFIG_RESET_ON_FATAL_ERROR=y
CONFIG_NCS_SAMPLES_DEFAULTS=y

# LED indication
# Uncomment these to minimize LED state indication when power savings are necessary
# CONFIG_LED_VERBOSE_INDICATION=n
# CONFIG_LED_CONTINUOUS_INDICATION=n

# Or, uncomment this to completely disable LED state indication
# CONFIG_LED_INDICATION_DISABLED=y

# Improved Logging
# CONFIG_LOG_MODE_DEFERRED allows logging from multiple threads simultaneously without creating
# splintered log entries, at the cost of needing a buffer for storing logs.
CONFIG_LOG_MODE_DEFERRED=y

# CONFIG_LOG_BUFFER_SIZE is the aforementioned buffer. A size of 4096 bytes is useful for debugging
# and prototyping, but is probably more than necessary for production-ready firmware.
CONFIG_LOG_BUFFER_SIZE=4096

# Heap and stacks
# Extended AT host/monitor stack/heap sizes since some nrf_cloud credentials are longer than 1024 bytes.
CONFIG_AT_MONITOR_HEAP_SIZE=2048
CONFIG_AT_HOST_STACK_SIZE=2048
# Extended memory heap size needed both for PGPS and for encoding JSON-based nRF Cloud Device Messages.
CONFIG_HEAP_MEM_POOL_SIZE=19000
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096

# Enable Networking and Connection Manager.
CONFIG_NETWORKING=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_OFFLOAD=y
CONFIG_NET_MGMT_EVENT_STACK_SIZE=2048
CONFIG_NET_CONNECTION_MANAGER_MONITOR_STACK_SIZE=1024
CONFIG_MAIN_STACK_SIZE=2048

# Enable LTE Connectivity using Connection Manager
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=y
CONFIG_NET_IPV6_NBR_CACHE=n
CONFIG_NET_IPV6_MLD=n
CONFIG_NET_CONNECTION_MANAGER=y
CONFIG_NRF_MODEM_LIB_NET_IF=y
CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_DOWN=y
CONFIG_NRF_MODEM_LIB_NET_IF_DOWN_DEFAULT_LTE_DISCONNECT=y

# Enable power savings mode
CONFIG_LTE_PSM_REQ=y
# Set the PSM Requested Active Time to 20 seconds
CONFIG_LTE_PSM_REQ_RAT="00001010"

# Modem library
CONFIG_NRF_MODEM_LIB=y

# AT commands interface
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_AT_HOST_LIBRARY=y

# nRF Cloud
CONFIG_NRF_CLOUD_MQTT=y # This also enables FOTA by implicitly setting CONFIG_NRF_CLOUD_FOTA=y

# MQTT
CONFIG_MQTT_KEEPALIVE=120

# MCUBOOT - Needed by FOTA
CONFIG_BOOTLOADER_MCUBOOT=y
CONFIG_IMG_MANAGER=y
CONFIG_MCUBOOT_IMG_MANAGER=y
CONFIG_STREAM_FLASH_ERASE=y

# Location Services configuration
CONFIG_LOCATION=y
CONFIG_LOCATION_METHOD_GNSS=y
CONFIG_LOCATION_METHOD_CELLULAR=y
CONFIG_NRF_CLOUD_AGNSS=y
CONFIG_NRF_CLOUD_LOCATION=y
CONFIG_MODEM_INFO=y
CONFIG_MODEM_INFO_ADD_NETWORK=y
CONFIG_NRF_CLOUD_PGPS=y
CONFIG_NRF_CLOUD_PGPS_REPLACEMENT_THRESHOLD=4
CONFIG_NRF_CLOUD_PGPS_REQUEST_UPON_INIT=y

# Date Time lib - Used by PGPS and main application
CONFIG_DATE_TIME=y

# LTE link control - used by PGPS and main application
CONFIG_LTE_LINK_CONTROL=y

# Settings - used by nRF Cloud library and PGPS
CONFIG_SETTINGS=y
CONFIG_SETTINGS_FCB=y
CONFIG_FCB=y

# Download Client - used by FOTA and PGPS
CONFIG_DOWNLOAD_CLIENT=y
CONFIG_DOWNLOAD_CLIENT_HTTP_FRAG_SIZE_1024=y
CONFIG_DOWNLOAD_CLIENT_STACK_SIZE=4096
CONFIG_DOWNLOAD_CLIENT_BUF_SIZE=2300
CONFIG_DOWNLOAD_CLIENT_MAX_HOSTNAME_SIZE=128

# Flash - Used by FOTA and PGPS
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_STREAM_FLASH=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y
CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=n
CONFIG_NRF_CLOUD_ALERT=y
CONFIG_NRF_CLOUD_LOG_DIRECT=y
CONFIG_NRF_CLOUD_LOG_OUTPUT_LEVEL=3

# On initial connection to the cloud, add info sections to the shadow
CONFIG_NRF_CLOUD_SEND_DEVICE_STATUS=y
CONFIG_NRF_CLOUD_SEND_DEVICE_STATUS_NETWORK=y
CONFIG_NRF_CLOUD_SEND_DEVICE_STATUS_SIM=y
CONFIG_NRF_CLOUD_SEND_SERVICE_INFO_FOTA=y
CONFIG_NRF_CLOUD_SEND_SERVICE_INFO_UI=y

CONFIG_NRF_CLOUD_CLIENT_ID_SRC_IMEI=y
CONFIG_NRF_CLOUD_CLIENT_ID_PREFIX="nrf-"
CONFIG_NRF_CLOUD_IPV6=y # disable this for US
CONFIG_LTE_NETWORK_MODE_NBIOT_GPS=y # use LTE-M for US
CONFIG_AT_CMD_REQUESTS=n

CONFIG_TFM_SECURE_UART=n
CONFIG_TFM_LOG_LEVEL_SILENCE=y
CONFIG_UART_USE_RUNTIME_CONFIGURE=y

CONFIG_LOCATION_TRACKING_SAMPLE_INTERVAL_SECONDS=300

CONFIG_UART_ASYNC_API=y
CONFIG_LOCATION_REQUEST_DEFAULT_TIMEOUT=60000
CONFIG_LOCATION_DATA_DETAILS=y

and this is my overlay file.

&uart1 {
	status = "okay";
};

Parents Reply
  • Hi,

    This is how I'm setting up the async uart

    const struct device *serialComm = DEVICE_DT_GET(DT_NODELABEL(uart1));
    static uint8_t rx_buffer[RX_BUFFER_SIZE] = {0};
    
    static void serialCommHandler(const struct device *dev, struct uart_event *evt, void *user_data)
    {
        switch(evt->type){
    
            case UART_RX_RDY:
                if(evt->data.rx.buf[evt->data.rx.offset] == CMD_START_BYTE){
    
                    buffer_index = 0;
                }
                data_buffer[buffer_index++] = evt->data.rx.buf[evt->data.rx.offset];
    
                if(data_buffer[buffer_index - 1] == CMD_END_BYTE){
    
                    serial_packet_header_t* serial_header;
                    serial_header = (serial_packet_header_t*)data_buffer;
                    serialCmdParser(serial_header);
                }
            break;
    
            case UART_RX_DISABLED:
                uart_rx_enable(serialComm,rx_buffer,sizeof(rx_buffer),SYS_FOREVER_US);
            break;
    
            default:
            break;
    
        }
    }
    
    int serialInit(void) 
    {
        int ret;
    
        if(!device_is_ready(serialComm)){
            return 1;
        }
    
        const struct uart_config uart_cfg = {
    		.baudrate = 115200,
    		.parity = UART_CFG_PARITY_NONE,
    		.stop_bits = UART_CFG_STOP_BITS_1,
    		.data_bits = UART_CFG_DATA_BITS_8,
    		.flow_ctrl = UART_CFG_FLOW_CTRL_NONE
    	};
    
        int err = uart_configure(serialComm, &uart_cfg);
    
    	if (err == -ENOSYS) {
    		return -ENOSYS;
    	}
    
    
        ret = uart_callback_set(serialComm,serialCommHandler,NULL);
        if(ret){
            return 1;
        }
    
        ret = uart_rx_enable(serialComm,rx_buffer,sizeof(rx_buffer),SYS_FOREVER_US);
        if(ret){
            return 1;
        }
    
        return 0;
    }

    The serial_init function is then called inside the main application thread.

    Since the asynchronous uart api isn't working for me, I have decided to use the interrupt driven api and that's working just fine.

Children
Related