Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52840 and SDK 15.3, want to use UARTE1 but NRFX_UARTE_INSTANCE(1) does not compile

I'm new to development with the Nordic SDK for the nRF52840 and during evaluation I run into the following problem with the UART ports, which I cannot resolve after hours. 
I'm using Segger Studio 4.16, the Nordic nRF52840 DK ( PCA10056), Nordic SDK 15.3. 

Since the overall concept of the SDK is new to me, I likely have some misunderstanding how some includes and macros should work.  The SDK examples\peripheral\spi can be used to reproduce my problem.  The spi example already provides support for the NRF LOG, so by configuring SDK_CONFIG.h I can either use RTT backend (nrf_log_backend_rtt.c) or UART backend (nrf_log_backend_uart.c) or even both. I want to use this and it works fine. 

So for my scenario UARTE0 is already used by the NRF LOG.  Since I also want to use another UART port for communcation, I thought that it should be easy to use UARTE1 for this purpose. (or use UARTE0 and let the LOG use UARTE1) .  Looking at the various options / levels how to use the UART, I decided to use a "low level" driver level API, just like nrf_log_backend_uart.c  does. 

This means that I need to fill some variable structures, make a call to nrf_drv_uart_init and then continue with TX and RX functions. 

There is a very basic Macro NRF_DRV_UART_INSTANCE which I think I have to use: 


nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(0); 
...
ret_code_t err_code = nrf_drv_uart_init(&m_uart, &config, async_mode ? uart_evt_handler : NULL);


But if I change the parameter for NRF_DRV_UART_INSTANCE from 0 to 1, then the code will not compile without error. 
 

4> In file included from ../../../../../../modules/nrfx/nrfx.h:45,
4>                  from ../../../../../../integration/nrfx/legacy/nrf_drv_uart.h:44,
4>                  from D:\BLE\Nordic\NRF5_SDK_15.3_Work\components\libraries\log\src\nrf_log_backend_uart.c:45:
4> ../../../../../../modules/nrfx/drivers/include/nrfx_uarte.h:89:35: error: 'NRFX_UARTE1_INST_IDX' undeclared here (not in a function); did you mean 'NRFX_UARTE0_INST_IDX'?
4> ../../../../../../modules/nrfx/drivers/nrfx_common.h:117:37: note: in definition of macro 'NRFX_CONCAT_3_'
4> ../../../../../../modules/nrfx/drivers/include/nrfx_uarte.h:89:21: note: in expansion of macro 'NRFX_CONCAT_3'
4> ../../../../../../integration/nrfx/legacy/nrf_drv_uart.h:56:18: note: in expansion of macro 'NRFX_UARTE_INSTANCE'
4> ../../../../../../integration/nrfx/legacy/nrf_drv_uart.h:171:5: note: in expansion of macro 'NRF_DRV_UART_CREATE_UARTE'
4> D:\BLE\Nordic\NRF5_SDK_15.3_Work\components\libraries\log\src\nrf_log_backend_uart.c:48:25: note: in expansion of macro 'NRF_DRV_UART_INSTANCE'
Build failed
 

At the first glance, it seems to be clear, why I receive this error, which manifests in nrfx_uarte.h

The NRFX_CONCAT_3 macro correctly forms the NRFX_UARTE1_INST_ID.  But since the part with UARTE1 of the enum is grayed out, there is no suitable definition in line 89, which then results in the error

#if NRFX_CHECK(NRFX_UARTE1_ENABLED)
NRFX_UARTE1_INST_IDX,
#endif

I checked the settings in sdk_config.h and tried almost any combination. 


// <e> NRFX_UARTE_ENABLED - nrfx_uarte - UARTE peripheral driver
//==========================================================
#ifndef NRFX_UARTE_ENABLED
#define NRFX_UARTE_ENABLED 1
#endif
// <o> NRFX_UARTE0_ENABLED - Enable UARTE0 instance 
#ifndef NRFX_UARTE0_ENABLED
#define NRFX_UARTE0_ENABLED 0
#endif

// <o> NRFX_UARTE1_ENABLED - Enable UARTE1 instance 
#ifndef NRFX_UARTE1_ENABLED
#define NRFX_UARTE1_ENABLED 0
#endif

It makes no difference whether NRFX_UARTE1_ENABLED is 0 or 1.
It even does not make a difference of whether NRFX_UARTE1_ENABLED is defined or not. (commenting out) 

So nrfx_uarte.h gets its definitions for NRFX_UARTE0from somewhere else, but I cannot find out, from where. 
Or more likely I do not understand how this mechanism works.  

How can I use NRF_DRV_UART_INSTANCE (1) without error,  or how should I used UARTE1 at all ? 

  • Hello,

    Please try to set UART1_ENABLED to 1 in your sdk_config.h file. Th

    // <e> UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver - legacy layer
    //==========================================================
    #ifndef UART_ENABLED
    #define UART_ENABLED 1
    #endif
    // <o> UART_DEFAULT_CONFIG_HWFC  - Hardware Flow Control
     
    // <0=> Disabled 
    // <1=> Enabled 
    
    #ifndef UART_DEFAULT_CONFIG_HWFC
    #define UART_DEFAULT_CONFIG_HWFC 0
    #endif
    
    // <o> UART_DEFAULT_CONFIG_PARITY  - Parity
     
    // <0=> Excluded 
    // <14=> Included 
    
    #ifndef UART_DEFAULT_CONFIG_PARITY
    #define UART_DEFAULT_CONFIG_PARITY 0
    #endif
    
    // <o> UART_DEFAULT_CONFIG_BAUDRATE  - Default Baudrate
     
    // <323584=> 1200 baud 
    // <643072=> 2400 baud 
    // <1290240=> 4800 baud 
    // <2576384=> 9600 baud 
    // <3862528=> 14400 baud 
    // <5152768=> 19200 baud 
    // <7716864=> 28800 baud 
    // <10289152=> 38400 baud 
    // <15400960=> 57600 baud 
    // <20615168=> 76800 baud 
    // <30801920=> 115200 baud 
    // <61865984=> 230400 baud 
    // <67108864=> 250000 baud 
    // <121634816=> 460800 baud 
    // <251658240=> 921600 baud 
    // <268435456=> 1000000 baud 
    
    #ifndef UART_DEFAULT_CONFIG_BAUDRATE
    #define UART_DEFAULT_CONFIG_BAUDRATE 30801920
    #endif
    
    // <o> UART_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
     
    
    // <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
    // <0=> 0 (highest) 
    // <1=> 1 
    // <2=> 2 
    // <3=> 3 
    // <4=> 4 
    // <5=> 5 
    // <6=> 6 
    // <7=> 7 
    
    #ifndef UART_DEFAULT_CONFIG_IRQ_PRIORITY
    #define UART_DEFAULT_CONFIG_IRQ_PRIORITY 6
    #endif
    
    // <q> UART_EASY_DMA_SUPPORT  - Driver supporting EasyDMA
     
    
    #ifndef UART_EASY_DMA_SUPPORT
    #define UART_EASY_DMA_SUPPORT 1
    #endif
    
    // <q> UART_LEGACY_SUPPORT  - Driver supporting Legacy mode
     
    
    #ifndef UART_LEGACY_SUPPORT
    #define UART_LEGACY_SUPPORT 1
    #endif
    
    // <e> UART0_ENABLED - Enable UART0 instance
    //==========================================================
    #ifndef UART0_ENABLED
    #define UART0_ENABLED 1
    #endif
    // <q> UART0_CONFIG_USE_EASY_DMA  - Default setting for using EasyDMA
     
    
    #ifndef UART0_CONFIG_USE_EASY_DMA
    #define UART0_CONFIG_USE_EASY_DMA 1
    #endif
    
    // </e>
    
    // <e> UART1_ENABLED - Enable UART1 instance
    //==========================================================
    #ifndef UART1_ENABLED
    #define UART1_ENABLED 1
    #endif
    // </e>
    
    // </e>
    
    // </h> 

    the NRFX_UARTE1_ENABLED define will be overridden by the UART1_ENABLED value.

  • Thanks, setting  UART1_ENABLED in sdk_config solved the problem. Afterwards the code compiles without errors and I can use both UARTE0 and UARTE1 in parallel.  I tested it by enabling using UARTE0 for NRF_LOG stuff (NRF_LOG_BACKEND_UART_ENABLED) and UARTE1 for my own serial communication. 

  • Glad to hear that it worked, thanks for the update. 

Related