This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Zephyr + Argon (nRF52840) + UART with interrupts

Howdy,

I'm trying to get Zypher up and running with the Particle Argon board using the nRF52840 chipset. The goal is to get both Bluetooth and UART working, but for now the question is, "How do I enable UART0 with interrupts".

Background: I'm using using PlatformIO as the IDE, a J-Link for debugging / programming, and Zephyr as the RTOS. PlatformIO is configured and able to write and debug to the board. Zephyr has the call uart_callback_set that let's a user register a callback. However, the compiler report back: undefined reference to `uart_callback_set'. In the uart.h file, uart_callback_set relies on a #define called CONFIG_UART_ASYNC_API. After reading around, this should be unlockable through the project.conf file. I've configured mine based on the Zephyr docs and this post, though it is a different chipset. Here is the config file:

CONFIG_DEBUG_OPTIMIZATIONS=y
CONFIG_EXCEPTION_STACK_TRACE=y
CONFIG_DEBUG_INFO=y

BOARD_ADAFRUIT_FEATHER_NRF52840=n

#UART Config
CONFIG_SERIAL=y
CONFIG_UART_CONSOLE=n
CONFIG_SERIAL_SUPPORT_ASYNC=y
CONFIG_SERIAL_SUPPORT_INTERRUPT=y

CONFIG_UART_ASYNC_API=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_UART_0_INTERRUPT_DRIVEN=y
CONFIG_UART_0_NRFE_UART=y
CONFIG_UART_ASYNC_API=y
CONFIG_UART_NRF=y

Extra: I can find the device using the device tree label:

struct device *uart_device = device_get_binding("UART_0");

Edit 1 - uart_poll_out and uart_poll_in work, but pretty much none of the other uart_ calls will compile. Checked via a loop back wire and a logic analyzer.

  • I was able to make interrupt-based UART work by using uart_irq_callback_set(..) which only requires CONFIG_UART_INTERRUPT_DRIVEN to be set to y (in addition to CONFIG_SERIAL, CONFIG_UART_<instance>_NRF_UARTE). Please tell me if this is sufficient for you or if you want to use the async API, then I'll look into it.

    Best regards,

    Simon

  • Hey Simon,

    Thank you for the quick response. I've updated the .conf file to read:

    #CONFIG_DEBUG_OPTIMIZATIONS=y
    #CONFIG_EXCEPTION_STACK_TRACE=y
    #CONFIG_DEBUG_INFO=y
    
    #BOARD_ADAFRUIT_FEATHER_NRF52840=n
    
    #UART Config
    CONFIG_SERIAL=y
    # CONFIG_UART_CONSOLE=n
    # CONFIG_SERIAL_SUPPORT_ASYNC=y
    # CONFIG_SERIAL_SUPPORT_INTERRUPT=y
    
    #CONFIG_UART_ASYNC_API=y
    CONFIG_UART_INTERRUPT_DRIVEN=y
    #CONFIG_UART_0_INTERRUPT_DRIVEN=y
    CONFIG_UART_0_NRF_UARTE=y
    #CONFIG_UART_ASYNC_API=y
    #CONFIG_UART_NRF=y

    Then, I tried to call uart_irq_callback_set, but the compiler is still reporting, "undefined reference to `uart_irq_callback_set'".

    Attached are the outputs of the "Packages" that Zephyr is using:

     

    CONFIGURATION: https://docs.platformio.org/page/boards/nordicnrf52/particle_argon.html
    PLATFORM: Nordic nRF52 4.4.0 > Particle Argon
    HARDWARE: NRF52840 64MHz, 243KB RAM, 796KB Flash
    DEBUG: Current (jlink) External (jlink)
    PACKAGES:
     - framework-zephyr 2.20300.200623 (2.3.0)
     - framework-zephyr-canopennode 0.0.0-alpha+sha.5c6b0566d5
     - framework-zephyr-civetweb 0.0.0-alpha+sha.99129c5efc
     - framework-zephyr-cmsis 0.0.0-alpha+sha.542b2296e6
     - framework-zephyr-fatfs 0.0.0-alpha+sha.9ee6b9b951
     - framework-zephyr-hal-nordic 0.0.0-alpha+sha.742d8fb839
     - framework-zephyr-libmetal 0.0.0-alpha+sha.3c3c9ec83b
     - framework-zephyr-littlefs 0.0.0-alpha+sha.0aefdda69d
     - framework-zephyr-loramac-node 0.0.0-alpha+sha.29e516ec58
     - framework-zephyr-lvgl 0.0.0-alpha+sha.74fc2e753a
     - framework-zephyr-mbedtls 0.0.0-alpha+sha.4bf099f125
     - framework-zephyr-mcuboot 0.0.0-alpha+sha.e88113bbeb 
     - framework-zephyr-mcumgr 0.0.0-alpha+sha.5885efb7ca
     - framework-zephyr-mipi-sys-t 0.0.0-alpha+sha.957d46bc3c
     - framework-zephyr-open-amp 0.0.0-alpha+sha.724f7e2a45
     - framework-zephyr-openthread 0.0.0-alpha+sha.a83d18cf18
     - framework-zephyr-segger 0.0.0-alpha+sha.6fcf61606d
     - framework-zephyr-tinycbor 0.0.0-alpha+sha.40daca97b4
     - framework-zephyr-tinycrypt 0.0.0-alpha+sha.3e9a49d267
     - framework-zephyr-trusted-firmware-m 0.0.0-alpha+sha.7de2daa196
     - tool-cmake 3.16.4
     - tool-dtc 1.4.7
     - tool-ninja 1.9.0
     - tool-sreccat 1.164.0 (1.64)
     - toolchain-gccarmnoneeabi 1.80201.190214 (8.2.1)

  • Ok, so I figured it out. After reading the PlatformIO docs on Zephyr, they require the prj.conf file in the Zephyr folder along with the CMakeLists.txt file. This is different than the Zephyr docs, as they request the prj.conf to be at the top level. 

    Secondly, any change to the prj.conf requires a Clean -> Build under PlatformIO. Not sure if this is a feature or a bug.

    The final prj.cong file UART settings that work are:

     

    CONFIG_SERIAL=y
    # CONFIG_UART_CONSOLE=n
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_UART_ASYNC_API=y

    This unlocks all the uart functions as documented by Zephyr. 

    The clue was that the .config file compiled by Zephyr was not matching the prj.conf settings.

    Sorry for the trouble and hope this helps someone in the future.

    Austin

    Edit 1 - Thanks to Simon for confirming that the code worked on his end!

Related