Use Shell over UART and UART ASYNC API on nRF52840

(I was asked to create a new post for this specific query. The original post where this investigation started is here: Async UART and shell module in Zephyr on nRF52480)

Is it possible to enable async UART support and the shell module in the same (VS Code) project?

I'm trying to use the shell on uart0 and the UART async API on uart1, but I'm beginning to think that these features are mutually exclusive.

When I enable UART async API support with these settings (in prj.conf),

CONFIG_SERIAL=y
CONFIG_UART_ASYNC_API=y

I see these settings being applied to the project as a whole (in .config):

#
# Serial Drivers
#
CONFIG_UART_NRFX=y
CONFIG_UART_ASYNC_TX_CACHE_SIZE=8
CONFIG_UART_0_NRF_UARTE=y
CONFIG_UART_0_ENHANCED_POLL_OUT=y
CONFIG_UART_0_ASYNC=y # <======================================
# CONFIG_UART_0_NRF_PARITY_BIT is not set
CONFIG_UART_0_NRF_TX_BUFFER_SIZE=32
# CONFIG_UART_0_NRF_HW_ASYNC is not set
# CONFIG_UART_0_NRF_ASYNC_LOW_POWER is not set
CONFIG_UART_1_NRF_UARTE=y
CONFIG_UART_1_ASYNC=y # <======================================
CONFIG_UART_1_ENHANCED_POLL_OUT=y
# CONFIG_UART_1_NRF_PARITY_BIT is not set
# CONFIG_UART_1_NRF_HW_ASYNC is not set
# CONFIG_UART_1_NRF_ASYNC_LOW_POWER is not set
CONFIG_UART_ENHANCED_POLL_OUT=y
CONFIG_NRF_UARTE_PERIPHERAL=y

Note the "CONFIG_UART_0_ASYNC=y" and "CONFIG_UART_1_ASYNC=y" settings.

However, when I add shell module support with these settings (in prj.conf),

CONFIG_SERIAL=y
CONFIG_UART_ASYNC_API=y
CONFIG_SHELL=y # <======================================

I see these settings being applied to the project as a whole (in .config):

#
# Serial Drivers
#
CONFIG_UART_NRFX=y
CONFIG_UART_ASYNC_TX_CACHE_SIZE=8
CONFIG_UART_0_NRF_UARTE=y
CONFIG_UART_0_ENHANCED_POLL_OUT=y
CONFIG_UART_0_INTERRUPT_DRIVEN=y # <======================================
# CONFIG_UART_0_NRF_PARITY_BIT is not set
CONFIG_UART_0_NRF_TX_BUFFER_SIZE=32
# CONFIG_UART_0_NRF_HW_ASYNC is not set
# CONFIG_UART_0_NRF_ASYNC_LOW_POWER is not set
CONFIG_UART_1_NRF_UARTE=y
CONFIG_UART_1_INTERRUPT_DRIVEN=y # <======================================
CONFIG_UART_1_ENHANCED_POLL_OUT=y
# CONFIG_UART_1_NRF_PARITY_BIT is not set
CONFIG_UART_1_NRF_TX_BUFFER_SIZE=32
# CONFIG_UART_1_NRF_ASYNC_LOW_POWER is not set
CONFIG_UART_ENHANCED_POLL_OUT=y
CONFIG_NRF_UARTE_PERIPHERAL=y

Note the "CONFIG_UART_0_INTERRUPT_DRIVEN=y" and "CONFIG_UART_1_INTERRUPT_DRIVEN=y" settings.

With this project change, the async API function "uart_callback_set" now errors out because the define "UARTE_INTERRUPT_DRIVEN" is now defined instead of "UARTE_ANY_ASYNC" in uart_nrfx_uarte.c, line 1771 (SDK v2.1.0) since the struct element ".callback_set" no longer exists.

Is there a way to have "CONFIG_UART_0_INTERRUPT_DRIVEN=y" (the 2nd project settings window above - compatible with the shell module) while "CONFIG_UART_1_ASYNC=y" (the 1st project settings window above - compatible with the UART async API)?

FYI, I am using the DevAcademy, lesson 5, exercise 1 example code to reproduce this on an nRF52840 DK.

  • Hello,

    I have created an internal for the developers to take a look.

    Kenneth

  • You can enable both api's but then you need to explicitly specify which instance is using what (otherwise it relies on the defaults). So something like this should be ok:

    CONFIG_SERIAL=y
    CONFIG_UART_ASYNC_API=y
    CONFIG_SHELL=y

    CONFIG_UART_0_INTERRUPT_DRIVEN=y # Instance used by shell

    CONFIG_UART_1_ASYNC=y #instance for other purposes supporting async api

  • Kenneth,

    Thank you - your recommendations were very helpful.  I was able to get them co-existing with one modification.

    My .conf file:

    CONFIG_SHELL=y
    CONFIG_UART_0_INTERRUPT_DRIVEN=y
    CONFIG_UART_0_ASYNC=n # <===================================
    
    CONFIG_SERIAL=y
    CONFIG_UART_ASYNC_API=y
    CONFIG_UART_1_ASYNC=y
    CONFIG_UART_1_INTERRUPT_DRIVEN=n # <===================================

    If I didn't add the 2 additional lines above (the two "...=n" lines), I got this message:

    warning: UART_1_ASYNC (defined at drivers/serial/Kconfig.nrfx:161) was assigned the value 'y' but
    got the value 'n'. Check these unsatisfied dependencies: (!UART_1_INTERRUPT_DRIVEN) (=n). See
    http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_UART_1_ASYNC and/or look up UART_1_ASYNC in
    the menuconfig/guiconfig interface. The Application Development Primer, Setting Configuration
    Values, and Kconfig - Tips and Best Practices sections of the manual might be helpful too.

    With the above .conf file alterations, my larger project (not just the example code) is able to use the Shell on uart0 and the UART ASYNC API on uart1.

Related