Code Monkey home page Code Monkey logo

nrfx's Introduction

nrfx

Overview

nrfx is a standalone set of drivers for peripherals present in Nordic Semiconductor's SoCs and SiPs. It originated as an extract from the nRF5 SDK. The intention was to provide drivers that can be used in various environments without the necessity to integrate other parts of the SDK into them. For the user's convenience, the drivers come with the MDK package. This package contains definitions of register structures and bitfields for all supported SoCs, as well as startup and initialization files for them.

Supported SoCs and SiPs

  • nRF51 Series
  • nRF52805
  • nRF52810
  • nRF52811
  • nRF52820
  • nRF52832
  • nRF52833
  • nRF52840
  • nRF5340
  • nRF9131
  • nRF9160
  • nRF9161

Directories

 .
 ├── doc             # Project documentation files
 ├── drivers         # nrfx driver files
 │   ├── include     # nrfx driver headers
 │   └── src         # nrfx driver sources
 ├── hal             # Hardware Access Layer files
 ├── haly            # Extended Hardware Access Layer files
 ├── helpers         # nrfx driver helper files
 ├── mdk             # nRF MDK files
 ├── soc             # SoC specific files
 └── templates       # Templates of nrfx integration files

Generating documentation

nrfx documentation is available in the doc\html folder of the release package.

Refer to this guide for more details.

nrfx's People

Contributors

aescolar avatar anangl avatar aykevl avatar beetix avatar glennrub avatar goofacz avatar kl-cruz avatar nika-nordic avatar nitz avatar nordic-krch avatar oyvindronningstad avatar pawelzadrozniak avatar petterssonandreas avatar sebastianboe avatar stephanosio avatar xenoamor avatar zyan-wu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nrfx's Issues

drivers/NVMC: address range checks don't take into account flash start address

Bug:
address range checks don't take into account flash start address, which might be non-zero for new devices.
for instance:

NRFX_ASSERT(addr < flash_total_size_get());

affected version:
any version since nRF53 support was included
master head of time this issue was opened:
9136253

consequence:
driver will fail on assertion if used on nRF53 network cpu flash controller.

workaround:
disable assertions

nRF5340 TWIM @1mbps: driver sets incorrect gpio drive strength

In nrfx_twim.c at line 75:

#define TWIM_PIN_INIT(_pin) nrf_gpio_cfg((_pin),
NRF_GPIO_PIN_DIR_INPUT,
NRF_GPIO_PIN_INPUT_CONNECT,
NRF_GPIO_PIN_PULLUP,
NRF_GPIO_PIN_S0D1,
NRF_GPIO_PIN_NOSENSE)

We need a drive strength of NRF_GPIO_PIN_E0E1 according to nRF5340 Prod Spec's Pin assignments:

"TWI - For the fastest TWI 1 Mbps mode, the two high-speed TWI pins must be configured in the TWI peripheral's PSEL registers, and the 20 mA open drain driver enabled using the E0E1 drive setting in the DRIVE field of the PIN_CNF GPIO register."

NRFX_CHECK(NRFX_FOO_ENABLED)

nrfx should not be using source code guards like #ifdef NRFX_CHECK(NRFX_FOO_ENABLED).

Instead build systems should be including or excluding whole source files in the build.

intentional warning about uint16_t?

#define NRF_PWM_VALUES_LENGTH(array) (sizeof(array) / sizeof(uint16_t))

^this gives me a compile time warning complaining about incompatibly of uint16_t and my used array of type nrf_pwm_values_grouped_t (I m using nRF Connect SDK 2.2.0)

however when parentheses are used for the sizeof(uint16_t)

#define NRF_PWM_VALUES_LENGTH(array) (sizeof(array) / (sizeof(uint16_t)))

the warning is surpressed, is there are reason why is this not used in the first placed?

nrfx_qspi.h non C++ friendly initialialiser

nrfx_qspi.h has a C++ guard but then uses an NRFX_QSPI_DEFAULT_CONFIG initialiser with out of order definitions, this is not C++ friendly and easily fixed, just initialise the structure in the correct order

nrfx: mdk: missing `nrf52832.svd`

There is no nrf52832.svd file in the nrfx/mdk folder, which is unexpected given that all other microcontrollers seem to be represented.

user@comp mdk % ls *.svd
nrf51.svd		nrf52810.svd		nrf52833.svd		nrf5340_network.svd
nrf52.svd		nrf52811.svd		nrf52840.svd		nrf9160.svd
nrf52805.svd		nrf52820.svd		nrf5340_application.svd

Unable to get UARTE TX more than once (interrupt handler not running)

On my NRF52840 DK, I'm using the nrfx library for the first time and it works perfectly fine in blocking mode. However, as soon as I provide a callback to nrfx_uarte_init - I'm only able to send a single TX, and all future TX's return NRFX_ERROR_BUSY.

HWFC is disabled, and there is nothing else this application does but try to send 1 TX every second.

I've tried playing with the NRFX_PRS_ENABLED flags, even though I only have 1 running peripheral - but no luck there.

In addition to this, I'm unable to receive any data either - since my UARTE interrupt handler never runs. I can only assume I'm not setting interrupt handlers or something, so example code would be helpful to reference.

Slimmed down, relevant code (mashed up from multiple files):

// nrfx_config.h
#define NRFX_UARTE_ENABLED 1
#define NRFX_UARTE0_ENABLED 1
// main.cpp
static const nrfx_uarte_t console = NRFX_UARTE_INSTANCE(0);
static volatile bool txDone_ = true;

void uartEventHandler(nrfx_uarte_event_t const* event, void* p_context) {
    (void)p_context;
    nrf_gpio_pin_toggle(led1);

    switch (event->type) {
    case NRFX_UARTE_EVT_TX_DONE:
        txDone_ = true;
        break;

    case NRFX_UARTE_EVT_ERROR:
    default:
        break;
    }
}

int main() {
    nrfx_uarte_config_t consoleConfig = NRFX_UARTE_DEFAULT_CONFIG(txPin, rxPin);
    nrfx_uarte_init(&console, &consoleConfig, uartEventHandler);
    // I've tried adding nrfx_uarte_rx(...) here - but handler never runs

    uint8_t message[] = "Hi\n";
    while(1) {
        nrf_gpio_pin_toggle(led4);
        txDone_ = false; // Contrived variable to ensure the interrupt wasn't being optimized away
        auto result = nrfx_uarte_tx(&console, message, sizeof(message));
        // This always returns NRFX_ERROR_BUSY
        // ... sleep 1 second ...
    }
}

Allow NRFX_DELAY_DWT_BASED to be defined outside nrfx_glue.h

I was experimenting with NRFX_DELAY_DWT_BASED and it would be convenient to be able to define it per project instead of having to change nrfx_glue.h, perhaps change it to:

#ifndef NRFX_DELAY_DWT_BASED
#define NRFX_DELAY_DWT_BASED 0
#endif

Some I2S master clock frequencies were removed from nrf52840_bitfields.h in release 1.6.0

Master clock frequency defines for divider values 6 through 2 were removed from the nrf52840_bitfields.h header file in release 1.6.0. This is an issue for us because we have been using I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV4 in our configuration.

We can add these defines back in our codebase, as we know it is supported by the NRF52840, but I would like to understand why they were removed. Is there an underlying issue that was the root cause for this change?

nrfx_twi.h - incorrect config struct causes excessive power consumption

typedef struct
{
    uint32_t            scl;                 ///< SCL pin number.
    uint32_t            sda;                 ///< SDA pin number.
    nrf_twi_frequency_t frequency;           ///< TWI frequency.
    uint8_t             interrupt_priority;  ///< Interrupt priority.
    bool                hold_bus_uninit;     ///< Hold pull up state on gpio pins after uninit.
} nrfx_twi_config_t;

typedef struct
{
    uint32_t                scl;                 ///< SCL pin number.
    uint32_t                sda;                 ///< SDA pin number.
    nrf_drv_twi_frequency_t frequency;           ///< TWI frequency.
    uint8_t                 interrupt_priority;  ///< Interrupt priority.
    bool                    clear_bus_init;      ///< Clear bus during init.
    bool                    hold_bus_uninit;     ///< Hold pull up state on gpio pins after uninit.
} nrf_drv_twi_config_t;

The struct nrfx_twi_config_t missed a member named clear_bus_init .

ret_code_t nrf_drv_twi_init(nrf_drv_twi_t const *        p_instance,
                            nrf_drv_twi_config_t const * p_config,
                            nrf_drv_twi_evt_handler_t    event_handler,
                            void *                       p_context)
{
    uint32_t inst_idx = p_instance->inst_idx;
    m_handlers[inst_idx] = event_handler;
    m_contexts[inst_idx] = p_context;

    if(p_config->clear_bus_init)
    {
        /* Send clocks (max 9) until slave device back from stuck mode */
        twi_clear_bus(p_config);
    }

    ret_code_t result = 0;
    if (NRF_DRV_TWI_USE_TWIM)
    {
        result = nrfx_twim_init(&p_instance->u.twim,
                                (nrfx_twim_config_t const *)p_config,
                                event_handler ? twim_evt_handler : NULL,
                                (void *)inst_idx);
    }
    else if (NRF_DRV_TWI_USE_TWI)
    {
        result = nrfx_twi_init(&p_instance->u.twi,
                               (nrfx_twi_config_t const *)p_config,
                               event_handler ? twi_evt_handler : NULL,
                               (void *)inst_idx);
    }
    return result;
}

When the legacy twi driver nrf_drv_twi_init() pass its config pointer to the nrfx_twi_init() , it makes the nrfx_twi_init() take clear_bus_init field as the hold_bus_uninit field. Because of enable the hold_bus_uninit feature, the SCL/SDA will not be restore to the default mode in nrf_drv_twi_uninit(). Finally, it will cause excessive power consumption.

High power consumption when using nrfx_qspi in blocking mode

Hello, I've found that the QSPI driver causes high power consumption when used in blocking mode (initialized with NULL as a handler.) It seems this is because nrfx_qspi_cinstr_xfer calls the nrf_qspi_int_enable function after the transfer is finished. Any generated interrupts never trigger a handler, since NRFX_IRQ_ENABLE isn't called in the init function in the non-blocking case. Uniniting the qspi driver doesn't help in this case, since the interrupt isn't cleared in the disable function. It seems the device doesn't go into sleep mode because of this unhandled interrupt, resulting in a current draw of around 3 mA.

I found 2 fixes for this issue. First, I removed the call to nrf_qspi_int_enable function in nrfx_qspi_cinstr_xfer. I don't think this is needed since nrf_qspi_int_enable is called when needed in qspi_task_perform anyway. My second fix was to add NVIC_ClearPendingIRQ in NRFX_IRQ_DISABLE (in nrfx_glue.h) after the call to NVIC_DisableIRQ. This recovers the power consumption state upon uniniting, even without the first fix. I'm wondering if this is good practice to have in general, or whether it might cause any other issues.

Can you comment on the issue and fixes, and whether they might have some negative repercussions? Thanks!

Error: sizeof-array-div error in pwm driver

With Zephyr 3.2 and SDK 15.1 I get the following new error message

/home/xxx/repos/zephyr/zephyr-workspace/modules/hal/nordic/nrfx/hal/nrf_pwm.h:64:54: error: expression does not compute the number of elements in this array; element type is 'nrf_pwm_values_wave_form_t', not 'uint16_t' {aka 'short unsigned int'} [-Werror=sizeof-array-div]
   64 | #define NRF_PWM_VALUES_LENGTH(array)  (sizeof(array) / sizeof(uint16_t))
      |                                                      ^
/home/xxx/repos/zephyr/zephyr-workspace/xxx/application/xxx/src/rocket_trim.c:686:52: note: in expansion of macro 'NRF_PWM_VALUES_LENGTH'
  686 |                                          .length = NRF_PWM_VALUES_LENGTH(m_pwm_soft_start_table),

which makes sense because sizeof(nrf_pwm_values_wave_form_t) divided by sizeof(uint16_t) is not allowed when -Werror=sizeof-array-div is active.

My current workaround is using a custom macro like

#define MY_NRF_PWM_VALUES_LENGTH(array)  (sizeof(array) / 2)

to get the number of 16-bit elements. However, since the affected code is also used in the examples I guess this should be properly fixed upstream.

Thanks in advance

ARRAY_SIZE is not defined

nrf_power (and some other files) check for ARRAY_SIZE but it is only defined in sdk files.

__STATIC_INLINE void nrf_power_rampower_mask_on(uint8_t block, uint32_t section_mask)
{
    NRFX_ASSERT(block < ARRAY_SIZE(NRF_POWER->RAM));
    NRF_POWER->RAM[block].POWERSET = section_mask;
}

It should be in nrfx_glues or locally defined to decouple nrfx and sdk

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif

nrfx_saadc: nrf5340: Samples offset in results buffer

Device: nRF5340 PDK

I'm currently sampling 4 channels using nrfx_saadc_simple_mode_set(...) in blocking mode, and calling nrfx_saadc_mode_trigger() after calibrating the saadc in blocking mode.

The first time sampling the buffer looks like {CH0, CH1, CH3, CH2} (which is an issue of its own) and each time it is sampled afterwards it looks like {~2473, CH0, CH1, CH3}. I will post some code which isolates my implementation from the rest of my code.

nfrx_power and nrfx_clock coexistence issue

I found a possible bug when initialising the clock and the power drivers.
If you initialise the clock driver without a handler and initialise the power driver.
Since they share the same interrupt, at least on the nrf52840, the interrupt handler will call the power driver handler and then call the clock driver handler without checking if the handler is there.
The power driver always has the interrupt handler but on the clock you don't need to have the handler.

nrfx_gpiote: Possible RAM violation

Hi,

Trying to use nrfx_gpiote_in_uninit on a non initialized GPIO causes RAM violation due to the returned value of channel_port_get(pin) (0xFF).

See line 638 of nrfx_gpiote.c :

    channel_free((uint8_t)channel_port_get(pin));

and line 220

static void channel_free(uint8_t channel_id)
{
    m_cb.handlers[channel_id] = FORBIDDEN_HANDLER_ADDRESS;
    if (channel_id >= GPIOTE_CH_NUM)
    {
        m_cb.port_handlers_pins[channel_id - GPIOTE_CH_NUM] = (int8_t)PIN_NOT_USED;
    }
}

The follwing instruction, with channel_id = 0xFF causes the RAM to be overriden outside of the m_cb.handlers array range.

m_cb.handlers[channel_id] = FORBIDDEN_HANDLER_ADDRESS;

Doxygen warnings

Doxygen version 1.8.14

warning: Tag SYMBOL_CACHE_SIZE' at line 350 of file nrfx.doxyfile' has become obsolete.
warning: Tag XML_SCHEMA' at line 1486 of file nrfx.doxyfile' has become obsolete.
warning: Tag XML_DTD' at line 1492 of file nrfx.doxyfile' has become obsolete.

qdec without reportrdy interrupt - nRF52840

I was trying to use the qdec driver (through the zephyr driver) without using interrupts by setting NRF_QDEC_EVENT_REPORTRDY_DISABLED. The idea is to retrieve the ACC value only when manually "fetching" and "getting".
Doing this I always got at most 1(-1) when reading the ACCREAD register.
It seems to be because of this line:

nrf_qdec_shorts_enable(NRF_QDEC, NRF_QDEC_SHORT_REPORTRDY_READCLRACC_MASK);

The short SHORT_REPORTRDY_READCLRACC clears ACC and sets ACCREAD automatically at each REPORTRDY event, which seems to happen even with NRF_QDEC_EVENT_REPORTRDY_DISABLED, but no interrupt is called. Therefore the counted steps are lost.
Is there anything I missed?

Warnings when building 3.0.0 release with -pedantic

When building in a project with -pedantic and the latest release,

There is now lot's (thousands) of warnings akin to:

nrfx/hal/nrf_spim.h:134:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro
134 | #if NRFX_FEATURE_PRESENT(SPIM, _FEATURE_RXDELAY_PRESENT) || defined(__NRFX_DOXYGEN__)
     | ^~~~~~~~~~~~~~

nrfx/hal/nrf_egu.h:298:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro
  298 |     NRF_INTERNAL_EGU_CHAN_NUM_EXTRACT(chan_num, p_reg);
      | ^   ~~~~~~~~~~

They all seem to boil down to the same issue:

nrfx/hal/nrf_egu.h:298:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro
nrfx/hal/nrf_gpio.h:1299:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro
nrfx/hal/nrf_gpio.h:821:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro
nrfx/hal/nrf_gpiote.h:180:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro
nrfx/hal/nrf_gpiote.h:181:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro
nrfx/hal/nrf_gpiote.h:182:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro
nrfx/hal/nrf_gpiote.h:183:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro
nrfx/hal/nrf_gpiote.h:185:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro
nrfx/hal/nrf_gpiote.h:186:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro
nrfx/hal/nrf_gpiote.h:187:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro
nrfx/hal/nrf_gpiote.h:188:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro
nrfx/hal/nrf_spim.h:118:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro
nrfx/hal/nrf_spim.h:125:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro
nrfx/hal/nrf_spim.h:126:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro
nrfx/hal/nrf_spim.h:134:1: warning: ISO C99 requires at least one argument for the "..." in a variadic macro

SPIM Soft SS Not working

If .ss_pin is set to NRFX_SPIM_PIN_NOT_USED in nrfx_spim_init, the setting is not copied into the stored config in m_cb. This results in pin 0 being toggled during every SPIM transaction (since ss_pin in m_cb defaults to 0).

The config is only copied here:

m_cb[p_instance->drv_inst_idx].ss_pin = p_config->ss_pin;

Which only happens if ss_pin is != NRFX_SPIM_PIN_NOT_USED

if (p_config->ss_pin != NRFX_SPIM_PIN_NOT_USED)

Later, in spim_xfer(), the ss_pin setting (which is now 0) is used to determine whether or not to toggle, which causes the issue:

if (p_cb->ss_pin != NRFX_SPIM_PIN_NOT_USED)

nrfx_qspi - nrfx_qspi_lfm_start/xfer handler mode bug

The nrfx_qspi_cinstr_xfer() function disables the ready interrupt so that the qspi_ready_wait() can poll the event status.

nrfx_qspi_lfm_start/()xfer() functions does not do this. So when handler mode is used, the interrupt will trigger and clear the event, causing qspi_ready_wait() to return NRFX_ERROR_TIMEOUT.

Make nrfx_<peripheral>_uninit() be idempotent

Right now nearly all the nrfx device driver routines carefully check to make sure the driver instance is in the right state. nrfx_*_init() makes sure the instance is in state NRFX_DRV_STATE_UNINITIALIZED, and returns an error code if it's not in that state. Almost other all routines make sure it is not in state NRFX_DRV_STATE_UNINITIALIZED, by doing an NRFX_ASSERT(state != NRFX_DRV_STATE_UNINITIALIZED), directly or indirectly. Most notably, even nrfx_*_uninit() does this check.

Unfortunately, this means that if you have a driver instance whose state is unknown, there's no simple way to force it it to be uninitialized. If you try to uninit() you risk causing a fatal error if NRFX_ASSERT() is enabled (e.g., in an NDEBUG build). A somewhat awkward workaround is to always init() the instance first, get an error return if it's already initialized, and then uninit(). But this might cause side effects from init()-ing that you don't want to happen.

This has come up for us (https://github.com/adafruit/circuitpython) because we want to be able to do a soft reset of our application and set all our driver instances to uninitialized, without having to track their state.

I propose that uninit() be made idempotent, so it can safely be called on an instance that's in any state. If you call uninit() on an instance that's already in state NRFX_DRV_STATE_UNINITIALIZED, it will simply return.

I have a PR already made up to do this. I haven't submitted it yet, but will do so if you like this idea.

An alternative is to add API calls that return the state, but that's more work. Making uninit() be idempotent is simpler, I think.

Thanks for thinking about this.

'missing binary operator before token "("' For Macros "NRFX_CHECK"

arm-none-eabi-gcc (Arch Repository) 11.2.0
nrfx{,lib}: latest master as of today

I thought I'd explore nrfx{,lib} instead of using zephyr (for now), and the simplest program fails to compile:

/usr/bin/arm-none-eabi-gcc -g --specs=nosys.specs -mcpu=cortex-m4 -O0 -Wpedantic -Wno-attributes -I<pathTo>CMSIS_5/CMSIS/Core/Include/ -I<pathTo>/nrfx/ -I<pathTo>/nrfx/drivers/ -I<pathTo>/nrfx/drivers/include/ -I<pathTo>/nrfx/hal/ -I<pathTo>/nrfx/soc/ -I<pathTo>/nrfx/mdk/ -I<pathTo>/nrfx/templates/ -I<pathTo>/<project>// -DNRF52840_XXAA main.c -o<pathto>/<project>.elf
In file included from <pathTo>/nrfx/soc/nrfx_irqs.h:52,
                 from main.h:4,
                 from main.c:1:
<pathTo>/nrfx/soc/nrfx_irqs_nrf52840.h:48:15: error: missing binary operator before token "("
   48 | #if NRFX_CHECK(NRFX_PRS_ENABLED) && NRFX_CHECK(NRFX_PRS_BOX_4_ENABLED)
      |               ^
<pathTo>/nrfx/soc/nrfx_irqs_nrf52840.h:56:15: error: missing binary operator before token "("
   56 | #if NRFX_CHECK(NRFX_PRS_ENABLED) && NRFX_CHECK(NRFX_PRS_BOX_0_ENABLED)
      |               ^
<pathTo>/nrfx/soc/nrfx_irqs_nrf52840.h:68:15: error: missing binary operator before token "("
   68 | #if NRFX_CHECK(NRFX_PRS_ENABLED) && NRFX_CHECK(NRFX_PRS_BOX_1_ENABLED)
      |               ^
<pathTo>/nrfx/soc/nrfx_irqs_nrf52840.h:120:15: error: missing binary operator before token "("
  120 | #if NRFX_CHECK(NRFX_PRS_ENABLED) && NRFX_CHECK(NRFX_PRS_BOX_3_ENABLED)
      |               ^
<pathTo>/nrfx/soc/nrfx_irqs_nrf52840.h:166:15: error: missing binary operator before token "("
  166 | #if NRFX_CHECK(NRFX_PRS_ENABLED) && NRFX_CHECK(NRFX_PRS_BOX_2_ENABLED)
      |               ^

EDIT0: function call is not allowed in a constant expression C/C++(59)
EDIT1: Also added -I<pathTo>/nrfx/drivers/ since I see headers are in there as well (which is where this macro is located)
EDIT2: Also added -I<pathTo>/nrfx/soc and -I<pathTo>/nrfx/hal
EDIT3: Dummy here, figuring order matters:
No:

#include "nrfx.h"
#include <soc/nrfx_irqs.h>

Yes:

#include <soc/nrfx_irqs.h>
#include "nrfx.h"

Weird ADC outliers on nrf52832

Describe the bug
When using the nrfx_saadc in advanced mode as per https://github.com/NordicSemiconductor/nrfx/wiki/SAADC-Advanced-mode-with-IRQs with continuous mode and oversampling enabled, some strange outliers are observed when oversampling.

To Reproduce
Steps to reproduce the behavior:

  1. Build the aforementioned sample with the following adc configuration:
const nrfx_saadc_channel_t channel_config = {
{
	.resistor_p = NRF_SAADC_RESISTOR_DISABLED,
	.resistor_n = NRF_SAADC_RESISTOR_DISABLED,
	.gain       = NRF_SAADC_GAIN1_6,
	.reference  = NRF_SAADC_REFERENCE_INTERNAL,
	.acq_time   = NRF_SAADC_ACQTIME_3US,
	.mode       = NRF_SAADC_MODE_SINGLE_ENDED,
	.burst      = NRF_SAADC_BURST_ENABLED,
  	},
.pin_p          = NRF_SAADC_INPUT_AIN2,
.pin_n          = NRF_SAADC_INPUT_DISABLED,
.channel_index  = 0,
};

const nrfx_saadc_adv_config_t advanced_config = {
	.oversampling = NRF_SAADC_OVERSAMPLE_8X,
	.burst = NRF_SAADC_BURST_ENABLED,
	.internal_timer_cc = ACOUSTIC_TIMER_CC,
	.start_on_end = true,
};

And using the drivers IRQ with priority of 6:

/* Hook up the internal ADC IRQ */
IRQ_CONNECT(DT_N_S_soc_S_adc_40007000_IRQ_IDX_0_VAL_irq,
	6,
	nrfx_saadc_irq_handler, 0, 0);

With a IRQ priority of 7 there are no outliers but we get system instabilities..

Expected behavior
I would not expect any outliers when sampling continuously.

Impact
For my application this is a showstopper, as we're relying on maximum / minmum values and with outliers these cannot be used.

Logs and console output
Example where the peak to peak is being calculated on each buffer of 1024 samples, a sudden outlier of 224 is observed:

[00:18:34.547,332] <dbg> acoustic.process_window: current_ptp: 1                                                                                                                               
[00:18:34.593,566] <wrn> acoustic: NRFX_SAADC_EVT_DONE size 1024                                                                                                                               
[00:18:34.593,811] <dbg> acoustic.process_window: current_ptp: 1                                                                                                                               
[00:18:34.640,075] <wrn> acoustic: NRFX_SAADC_EVT_DONE size 1024                                                                                                                               
[00:18:34.640,319] <dbg> acoustic.process_window: current_ptp: 1                                                                                                                               
[00:18:34.686,553] <wrn> acoustic: NRFX_SAADC_EVT_DONE size 1024                                                                                                                               
[00:18:34.686,798] <dbg> acoustic.process_window: current_ptp: 1                                                                                                                               
[00:18:34.733,001] <wrn> acoustic: NRFX_SAADC_EVT_DONE size 1024                                                                                                                               
[00:18:34.733,245] <dbg> acoustic.process_window: current_ptp: 1                                                                                                                               
[00:18:34.779,510] <wrn> acoustic: NRFX_SAADC_EVT_DONE size 1024                                                                                                                               
[00:18:34.779,754] <dbg> acoustic.process_window: current_ptp: 1                                                                                                                               
[00:18:34.826,019] <wrn> acoustic: NRFX_SAADC_EVT_DONE size 1024                                                                                                                               
[00:18:34.826,019] <wrn> acoustic: raw: 2683                                                                                                                                                   
[00:18:34.826,263] <dbg> acoustic.process_window: current_ptp: 224

Environment:

  • Zephyr 2.3.0
  • Toolchain gnuarmembedded

Additional context
Related question that I posted on devzone: https://devzone.nordicsemi.com/f/nordic-q-a/63067/nrfx_saadc-advanced-mode-oversampling
Also posted this on zephyr github: zephyrproject-rtos/zephyr#27846

nrfx_twim cannot start TXRX transfer after no_stop transfer

Driver does not call resume task in case of TXRX transfer. If TWIM got suspended before that (because previous transfer did not have stop condition) it will not start next transfer.

Possible solution: in twim_xfer function in case of NRFX_TWIM_XFER_TXRX add nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME) call (it is present in other cases).

NFCT RX/TX example

I want to write a library to emulate a nfc tag without t2t and t4t NRF library.

so now, I am using nrfx_nfct library directly. but there is a problem.

To demonstrate how to work the t4t library, I write logs on all function in nrfx_nfct.c file.
Because t4t library also use the core nrfx_nfct library.

when I use t4t library, it work correctly.
it work in correct sequence RX -> TX -> RX.
you can check the RX ended event and TX ended event below logs

---------- t2t library logs ----------
Selected
rxtx enable mask:0460
RX start- size:256, data:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
RX Frame End
rxtx enable mask:0018
TX start- delay mode: NRF_NFCT_FRAME_DELAY_MODE_WINDOWGRID, size:5, data:05 78 80 42 02
TX Frame End
rxtx enable mask:0460
RX start- size:256, data:e0 81 b8 62 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
RX Frame End
rxtx enable mask:0460
RX start- size:256, data:0a 01 00 ca 01 01 08 60 42 00 00 00 00 00 00 00 00 00 00 00
rxtx enable mask:0018
TX start- delay mode: NRF_NFCT_FRAME_DELAY_MODE_EXACTVAL, size:3, data:fa 01 08

But When I write a code by using only nrfx_nfct and receive event and RX/TX by myself.

the TX ended event never be called.

when I do tx, it always return RX ended event.

is there any other config? or something that i missed?

---------- nrfx_nfct logs ------------
Selected
nfct event : NRFX_NFCT_EVT_SELECTED
rxtx enable mask:0460
RX start- size:256, data:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 53 45
RX Frame End
nfct event : NRFX_NFCT_EVT_RX_FRAMEEND
receive RATS, DID:1, FSD:0
rxtx enable mask:0018
TX start- delay mode: NRF_NFCT_FRAME_DELAY_MODE_WINDOWGRID, size:5, data:05 78 80 42 02
RX Frame End
nfct event : NRFX_NFCT_EVT_RX_FRAMEEND

unable to get nrfx_nfct to detect field lost on 82540

I have been struggling to get the nrfx_nfct driver to do anything sensible on my 82540 board, I don't suppose there is any example code or test code available, I get a field detected once and then nothing, im only trying to get field detected and field lost events

TWIS broken in nrfx 2.5 ( ncs v1.6 )

Dear Nordic,

Seams like the twis driver in nrfx2.5 is broken. I just updated from ncs v1.5 and my twis driver not working properly.
The issue is that the driver only sending every second bytes from my buffer. I went back to ncs v1.5 and there is no such a problem over there.
Am I missed something about the migration from ncs 1.5 to ncs 1.6?
I am looking forward to hear about this issue.
Thank you.

I am using the nRF9160_DK for testing with Zephyr OS build v2.6.0-rc1-ncs1

Question/documentation: what does MDK stand for?

It's used all over and I know what it does but I can't find an explanation of why it's called "mdk" (which might be helpful in documenting my own build rules, to explain at point of use why it's being pulled in)

NRFx mismatch with SDK NRFx changelog or version?

Hi,

Inside NRF SDK 17, in the modules/nrfx directory there is this change log:

## [1.8.4] - 2020-04-27

## [1.8.3] - 2020-03-20

## [1.8.2] - 2020-03-05

But in this repo there are different entries with dates also being in 2020. Am i looking at the same project??

## [2.2.0] - 2020-04-28

## [2.1.0] - 2020-01-24

## [2.0.0] - 2019-11-06

## [1.8.1] - 2019-10-21

Which NRFx source shall we use?

How is the NRFx development going vs. NRF connect and your nrf_drv legacy drivers? It is really confusing what to choose.

Thanks!

Incorrect workaround for nRF53 anomaly 161

nrf_reset_network_force_off uses nrf53_errata_161 to decide if the workaround for anomaly 161 is needed:

nrfx/hal/nrf_reset.h

Lines 175 to 187 in 1c72117

else if (nrf53_errata_161())
{
*(volatile uint32_t *)0x50005618UL = 1UL;
p_reg->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release <<
RESET_NETWORK_FORCEOFF_FORCEOFF_Pos;
NRFX_DELAY_US(5);
p_reg->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Hold <<
RESET_NETWORK_FORCEOFF_FORCEOFF_Pos;
NRFX_DELAY_US(1);
p_reg->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release <<
RESET_NETWORK_FORCEOFF_FORCEOFF_Pos;
*(volatile uint32_t *)0x50005618UL = 0UL;
}

However that function only returns true when compiled for the network core:

nrfx/mdk/nrf53_erratas.h

Lines 5876 to 5909 in 1c72117

static bool nrf53_errata_161(void)
{
#ifndef NRF53_SERIES
return false;
#else
#if defined (NRF5340_XXAA) || defined (DEVELOP_IN_NRF5340)
#if defined(NRF_NETWORK)
uint32_t var1 = *(uint32_t *)0x01FF0130ul;
uint32_t var2 = *(uint32_t *)0x01FF0134ul;
#endif
#endif
#if defined (NRF5340_XXAA) || defined (DEVELOP_IN_NRF5340)
#if defined (NRF_NETWORK)
if (var1 == 0x07)
{
switch(var2)
{
case 0x02ul:
return false;
case 0x03ul:
return false;
case 0x04ul:
return false;
case 0x05ul:
return true;
default:
return true;
}
}
#endif
#endif
return false;
#endif
}

nRF5340 Audio clock - requested features

There are some desired features in the ACLK driver/nrf_clock.h. (Tested by using the I2S module).

nrf_clock_hfclkaudio_config_set should have upper and lower bounds on the allowed write values as per nRF5340_OPS_v0.5.1.pdf. In addition, there should be a limiter to ensure that the user does not request too large step changes from the PLL.

In order to use the PLL, One needs to write to the NRF_CLOCK->TASKS_HFCLKAUDIOSTART register.
There should be an API for this.

NFCT example

We are using the nrfx library within micropython and have worked on integrating nfc functionality, without linking the t4t binary.

Unfortunately we are stuck on how to use the driver to emulate eg a simple url tag. We have raised this already here https://devzone.nordicsemi.com/f/nordic-q-a/41705/trouble-with-nrfx-nfct-driver

but the response was not convincing.

So my question is if somebody could point us to sample code that uses the driver.

So far we were able to detect FIELD, switch on HCLK and the received a read error event.

My feeling is that we are really close to getting the driver to work so it would be a pitty if we have to abandon this development path.

Thanks for any feedback

Martin

nrf_radio_power_set() use directly a bool to write a register

in [(https://github.com/NordicSemiconductor/nrfx/blob/master/hal/nrf_radio.h#L1896] use a bool to directly write the register but bool is not guaranteed to have a 0 or 1 value. It should be like the function nrf_radio_modecnf0_set() that also use a bool.

p_reg->POWER = radio_power ? (RADIO_POWER_POWER_Enabled << RADIO_POWER_POWER_Pos) : (RADIO_POWER_POWER_Disabled << RADIO_POWER_POWER_Pos);

No nrfx IRQs for nRF5340

Currently the nrfx drivers are useless on any RTOS when in non-blocking mode because there are no interrupts. Files like soc/nrfx_irqs_nrf5340.h are missing.

Full support for nRF9160 (at least to nRF52840 'level')

Hello All,

First - thank all of you that are involved in this effort and maintaining this repository on github for the rest of us to use.

I have a request - after looking here:
https://infocenter.nordicsemi.com/index.jsp?topic=%2Fdrivers_nrfx_v2.7.0%2Findex.html

The far right hand column has the nRF9160.

And, there's quite a list of unsupported features(thus far):

The most important (obviously): RADIO.

Support for UART, and SPI also have 'x's'.

So, the question here is - when will the nRF9160 be as fully supported as the nRF52840?
Can you give an estimate as to when that will happen?

I realize there are some M33 issues that don't pertain to the M4 on the nRF52840 - but key features like RADIO, SPI, and UART are worth knowing about as to when they will be supported.

Thanks In Advance,
jwest247

Add NRFX_IRQ_NUMBER_GET macro

In <nrfx_common.h> there is an inline function called nrfx_get_irq_macro that returns the IRQ number assigned to a given peripheral. There should be also a macro that does the same thing because sometimes the function cannot be used, e.g. when the IRQ number needs to be provided as a macro parameter or in initialization of some structure.

nrfx_gpiote: loss of level detection interrupts

zephyrproject-rtos/zephyr#11806 identifies an error in processing the GPIOTE PORT event that can cause sense changes to be lost because the rising edge of DETECT was not captured. The same problem appears to be present in nrfx through 1.4.0.

Consider the following execution of nrfx_gpiote_irq_handler:

On entry the PORT event is set. The implementation captures the pins, and clears the event. The DETECT signal remains asserted.

All that is necessary for the failure to occur is a run through the rest of the function that exits with repeat false while the DETECT signal is never deasserted. The following sequences reaches this state:

  • Assume that SENSE is asserted for GPIO pins 0 and 31. Between the point the ISR is entered and the check for pin state of GPIO 0 the input of pin 0 changes so its SENSE is no longer asserted. DETECT remains asserted due to pin 31. The mismatch in sense means repeat is not incremented for pin 0.
  • Between checking pin 0 and pin 31 pin 0 changes state again, so that its SENSE signal is asserted; after this pin 31 changes state so its SENSE signal is deasserted. DETECT remains asserted at all times, but the test for pin 31 succeeds and repeat is not incremented.

At the bottom of the loop repeat is zero so the ISR exits. The PORT event has been cleared, and DETECT remains asserted. No further level interrupts will be signalled.

An real-world application where level can change without any application control like this is monitoring dry contacts, a situation perfectly suited to level detection and where a device may have more inputs than there are edge detection resources on the chip.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.