nrfx_uarte_rx_enable() hangs up

Hello,

A super-simple piece of code that enables UARTE1 to receive a byte stream does not seem to work.

It seems as if nrfx_uarte_rx_enable() hangs up.

When I single step through it, I can get it to complete without an error code (but still, something does not seem to operate correctly).

I do get to the first NRFX_UARTE_EVT_RX_BUF_REQUEST in the handler, but taht's as far as I get the software running.

The app is based/tested on BT_NUS_SHELL & tx_rx_non_blocking examples,  (not) running on nRF52840DK, NCS2.7.0

This is the code:

#include <zephyr/types.h>
#include <zephyr/kernel.h>
#include <nrfx_config.h>
#include <nrfx_uarte.h>
#include <zephyr/logging/log.h>
#include <nrfx_gpiote.h>
#include <stdio.h>


#define STACKSIZE   1024
#define PRIORITY    0

#define PC0                     NRF_GPIO_PIN_MAP(1, 4)
#define RES0                    NRF_GPIO_PIN_MAP(1, 6)  //(0, 13)
#define RES_AN0                 NRF_GPIO_PIN_MAP(1, 8)  //(0, 28)

#define UART_TX                 NRF_GPIO_PIN_MAP(1, 2)
#define UART_RX                 NRF_GPIO_PIN_MAP(1, 1)

#define UARTE_INST_IDX              1
static const nrfx_uarte_t uarte_inst = NRFX_UARTE_INSTANCE(UARTE_INST_IDX);

nrfx_uarte_config_t uarte_config = NRFX_UARTE_DEFAULT_CONFIG(UART_TX, UART_RX);


static uint8_t buff2[2][4] __attribute__((aligned(4)));;
static uint8_t buff_idx = 0;
void uarte_handler(nrfx_uarte_event_t const * p_event, void * p_context)
 {
     nrfx_err_t status;
     switch(p_event->type) {
        case NRFX_UARTE_EVT_TX_DONE:
            nrf_gpio_pin_toggle(PC0);  // DEBUG
            NRFX_ASSERT(p_event->data.tx.length < 50);
            break;

        case NRFX_UARTE_EVT_RX_BUF_REQUEST:
            nrf_gpio_pin_toggle(PC0);  // DEBUG
            status = nrfx_uarte_rx_buffer_set(&uarte_inst, buff2[buff_idx], 1);
            NRFX_ASSERT(status == NRFX_SUCCESS);
            buff_idx = buff_idx == 0 ? 1 : 0;
            break;
 
        case NRFX_UARTE_EVT_RX_DONE:
            nrf_gpio_pin_toggle(PC0);  // DEBUG
            break;
 
        default:
            nrf_gpio_pin_toggle(PC0);  // DEBUG
            // NRFX_ASSERT(0); // NOT allowed
    }
}

void thread_handler(void)
{
    nrfx_err_t status;  

    nrf_gpio_cfg_output(RES0);   // DEBUG
    nrf_gpio_pin_write(RES0, 0); // DEBUG
    nrf_gpio_cfg_output(PC0);   // DEBUG
    nrf_gpio_pin_write(PC0, 0); // DEBUG

    uarte_config.baudrate = NRF_UARTE_BAUDRATE_115200;
    uarte_config.p_context = (void*)&uarte_inst;

    if(nrfx_uarte_init_check(&uarte_inst)) {
        nrfx_uarte_uninit(&uarte_inst);
    }

    status = nrfx_uarte_init(&uarte_inst, &uarte_config, uarte_handler);
    NRFX_ASSERT(status == NRFX_SUCCESS);

    status = nrfx_uarte_rx_enable(&uarte_inst, 0); // << This one hangs up (but not if single stepping through it)
    NRFX_ASSERT(status == NRFX_SUCCESS);    

    while(1) {
        k_sleep(K_MSEC(100));
        nrf_gpio_pin_toggle(RES0);
    }
}


int main()
{
    thread_handler();
    return 0;
}

this is prj.conf

#
# Copyright (c) 2018 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
CONFIG_NCS_SAMPLES_DEFAULTS=y

CONFIG_HEAP_MEM_POOL_SIZE=2048

CONFIG_BT=y
CONFIG_BT_SMP=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="BT_NUS_shell"
CONFIG_BT_DEVICE_APPEARANCE=833
CONFIG_BT_MAX_CONN=2
CONFIG_BT_MAX_PAIRED=2

# Enable the BT NUS shell
CONFIG_SHELL_BT_NUS=y

CONFIG_SHELL_BT_NUS_LOG_LEVEL_DBG=y

# Next CONFIGs added to the sample
CONFIG_NRFX_UARTE1=y

and app.overlay

    &uart1 {
        status = "okay";
        interrupts = <40>, <2>;
    };

What am I missing?

I've been banging my head for days now Disappointed (even managed to exhaust chatGPT on that)

THANKS in advance to the savior..

Parents
  • Any reason why you wrote a driver yourself and no just use the zephyr driver API?

    ChatGPT may be less than helpful here, but there are examples on how to use the UART drivers.

  • good question -

    This is just a demo code, in practice I need to exchange pins functionality GPIOs<-->UART, which is not supported natively in Zephyr

    btw,

    I didn't find and NRFX demo that uses nrfx_uarte_rx_enable(), only code that uses nrfx_uarte_rx() which is deprecated

  • Pretty sure you missed the pinctrl stuff, which sounds like the zephyr solution to your pin problems to me.

    Your "driver" is still missing all of the required ZEPHYR glue code, which is why your interrupt handler function will never be called.

    You also would need to take care what you don't re-use a shared peripherial by accident. Your dts overlay would enable the zephyr drivers for UART(E)1 and their interrupt handling.

  • Hello @Turbo 1 (turbo reply indeed Slight smile)

    I'm piggying back Nordic's tx_rx_non_blocking sample. it uses nrf52840dk 'generic' DT files (part of the SDK) + board\nrf52840dk_nrf52840.overlay in the project tree.

    If I understand correctly, pinctrl is taken care of in the DK file.
    I've verified it in the nRF GUI:

    The UARTE1 node itself is also defined in the DK file (see GUI)

    and UARTE1 is being activated in the project's overlay file (boards\*):

    &uart1 {
        status = "okay";
        compatible = "nordic,nrf-uarte";
    };

    Also,

    Is there a way to handle UARTE1 in the old NRFX way, without having it defined in the DT.

    (the way it was done in the old nRF SDK ?)

    Thanks again

  • Quite possibly this is a simple issue where the UART_RX pin has no internal pull-up enabled. With no external driving input to that pin, when the UART is initialised, first a Framing Error will be generated followed by a Break and these can cause a crash.

    Should this be the case simply enable the internal pull-up on the UART_RX pin in the initialisation code.

Reply Children
No Data
Related