Skip to content

nrf: Update nrfx to v3.14.0 and modernize machine interfaces.#37

Closed
andrewleech wants to merge 8 commits intoreview/nrfx-updatefrom
nrfx-update
Closed

nrf: Update nrfx to v3.14.0 and modernize machine interfaces.#37
andrewleech wants to merge 8 commits intoreview/nrfx-updatefrom
nrfx-update

Conversation

@andrewleech
Copy link
Copy Markdown
Owner

@andrewleech andrewleech commented Apr 19, 2026

Summary

Updates the nrfx submodule from v2.0.0 (2019) to v3.14.0 and modernizes the nrf port's machine interfaces for consistency with rp2 and alif ports.

The nrfx upgrade is needed because TinyUSB's latest upstream broke its nrfx v2 code path in dcd_nrf5x.c, requiring v3+ for correct API detection. The v2-to-v3 migration touches port configuration, the startup vector table, and all peripheral drivers that call nrfx APIs directly.

While touching these drivers, the machine interfaces were brought in line with modern ports:

  • Pin.irq: Rewritten to use the shared mp_irq_obj_t infrastructure (matching rp2/alif). Adds hard kwarg for soft IRQ support via mp_sched_schedule, makes handler optional, returns a proper IRQ object with flags() and trigger() methods. Boards without MICROPY_ENABLE_SCHEDULER retain the direct ISR-only path.
  • SPI: init() now preserves current config when parameters aren't passed (matching rp2), instead of resetting everything to defaults.
  • I2C: Added timeout kwarg (default 50ms, matching rp2/alif). Implemented using non-blocking transfers with an ISR completion callback and mp_hal_ticks_us polling loop, so the timeout is actually enforced. Also fixed TWI peripheral not being disabled on the transfer error path.
  • Timer: Fixed silent regression where NRF_TIMER_FREQ_1MHz enum value (4) was interpreted as 4 Hz by the nrfx v3 config struct which now expects frequency in Hz.

All 23 nrf board configs compile clean.

Testing

Built and verified all 23 nrf board configurations (6 nRF51, 15 nRF52, 2 nRF9160). Hardware tested on nRF52840-Dongle (PCA10059) flashed via pyocd/CMSIS-DAP with the following results:

Peripheral Result Notes
USB CDC REPL PASS
Pin read/write PASS
Pin.irq PASS Returns <class 'irq'> object, no spurious triggers
Timer PASS Was broken before freq enum fix
PWM PASS freq and duty readback correct
SPI PASS init + readinto
I2C timeout PASS NACK on missing device: 244us/ENODEV, timeout=1us: ETIMEDOUT
ADC PASS
RNG PASS

Could not test successful I2C data transfer (no I2C slave device wired to the dongle). Could not hardware-test nRF51 or nRF9160 boards (no hardware), but they compile clean.

Trade-offs and Alternatives

Code size on PCA10059 increased from 252,880 to ~257,268 bytes text (+1.7%). The increase comes from nrfx v3's HALY (HAL extension) layer, atomic operations, GPIOTE channel allocator, and the mp_irq infrastructure.

Generative AI

I used generative AI tools when creating this PR, but a human has checked the code and is responsible for the code and the description above.

Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 19, 2026

Code size report:

Reference:  samd: Convert port to use new event waiting functions. [1f601e8]
Comparison: nrf: Add I2C timeout parameter and fix disable on error. [merge of 6228ff5]
  mpy-cross:    +0 +0.000% 
   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
      esp32:    +0 +0.000% ESP32_GENERIC
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO_W
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

pi-anl added 2 commits April 19, 2026 13:47
Add API version macros, convert NRFX_CHECK config to literal 0/1,
add NRF_GPIOTE0 compat alias, implement required nrfx_glue.h
macros (atomics, CLZ/CTZ, cache, event readback, IRQ pending),
add haly/helpers include paths and new source files, and update
startup_nrf52840.c IRQ handler names to match the nrfx v3 MDK
renames in nrf52840_name_change.h.

Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
Replace removed nrfx_gpiote_in_init/uninit/event_enable with the
v3 instance-based API: channel allocation, input_configure, and
trigger_enable. Allocates a hardware GPIOTE channel per pin to
preserve high-accuracy edge detection. Falls back to PORT SENSE
if all channels are in use.

Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
@andrewleech andrewleech changed the title nrf: Update nrfx submodule from v2.0.0 to v3.14.0. nrf: Update nrfx to v3.14.0 and modernize machine interfaces. Apr 19, 2026
@andrewleech andrewleech force-pushed the nrfx-update branch 2 times, most recently from 268d3ac to 616aa2a Compare April 19, 2026 06:01
pi-anl added 5 commits April 19, 2026 19:13
Adapt UART, ADC, PWM, SPI, I2C, and RTC drivers for nrfx v3
renamed structs, constants, and function signatures. Notably:
UARTE config members renamed and conditional on UART vs UARTE
for nRF51 compatibility, SAADC value type changed to int16_t,
pin-not-connected constants renamed, TWI vs TWIM pin config
split, and RTC prescaler macro renamed.

Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
Add fallback define for NRF_FPU_S which was removed from the
nRF9160 device headers in nrfx v3.

Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
Replace the nrf port's custom Pin.irq implementation with the
shared mp_irq_obj_t pattern used by rp2 and alif ports. Adds
support for the hard kwarg (soft IRQs via mp_sched_schedule
when hard=False), makes handler optional, and returns a proper
IRQ object with flags() and trigger() methods. Boards without
MICROPY_ENABLE_SCHEDULER retain the direct ISR-only path.

Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
Use -1 sentinels for SPI init parameters so that calling
spi.init(baudrate=X) no longer resets polarity, phase, and
other settings to defaults. Matches the rp2 port behavior.

Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
Accept the timeout kwarg (default 50ms) for compatibility with
rp2 and alif ports. Also fix TWI peripheral not being disabled
on the transfer error path.

Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants