Skip to content

arch/arm/nrf53: fix inverted GPIOTE per-instance channel index - #20002

Merged
xiaoxiang781216 merged 2 commits into
apache:masterfrom
AlmAck:fix/nrf53-gpiote-rchan
Aug 31, 2026
Merged

arch/arm/nrf53: fix inverted GPIOTE per-instance channel index#20002
xiaoxiang781216 merged 2 commits into
apache:masterfrom
AlmAck:fix/nrf53-gpiote-rchan

Conversation

@AlmAck

@AlmAck AlmAck commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Summary

The driver presents a single channel space of GPIOTE_CHANNELS entries
across the application core's two GPIOTE peripherals, and splits it:

inst  = (channel < GPIOTE_PER_CHANNEL) ? 0 : 1;
rchan = (inst == 1) ? channel : (channel - GPIOTE_PER_CHANNEL);

rchan is the channel index within the selected instance, used to
build the per-channel register offsets, so it must be

rchan = channel - GPIOTE_PER_CHANNEL * inst

The ternary has the two arms the other way round: a channel on instance
0 gets rchan = channel - GPIOTE_PER_CHANNEL, which is negative, and a
channel on instance 1 gets an index still offset by a full instance.

Corroboration

The interrupt handler in this same file already applies that mapping in
the opposite direction, converting a per-instance channel back to the
global one:

off = i + GPIOTE_PER_CHANNEL * inst;    /* nrf53_gpiote.c, nrf53_gpiote_isr() */

The two were inconsistent, and it is the rchan sites that disagreed
with the rest of the driver.

Per the nRF5340 Product Specification, GPIOTE - GPIO tasks and events,
the application core has two GPIOTE instances:

instance base channels CONFIG
GPIOTE0 (secure) 0x5000D000 8 CONFIG[n], n = 0..7
GPIOTE1 (non-secure) 0x4002F000 8 CONFIG[n], n = 0..7

CONFIG[n] sits at offset 0x510 + 4n. That matches
GPIOTE_PER_CHANNEL == 8 in the driver, the two base addresses in
hardware/nrf53_memorymap_cpuapp.h, and NRF53_GPIOTE_CONFIG_OFFSET()
in hardware/nrf53_gpiote.h - so rchan is required to be in 0..7 and
a negative value cannot address a CONFIG register.

Both call sites are corrected.

Impact

Any nRF5340 board using GPIOTE. For a channel on instance 0 the CONFIG
register write lands at a computed-negative offset and the GPIOTE
interrupt is never enabled, so the event never fires - on nrf5340-dk
this makes the board buttons dead.

Testing

Suggested reproduction to capture:

  1. nrf5340-dk with CONFIG_ARCH_BUTTONS=y and CONFIG_INPUT_BUTTONS,
    registering the board button lower-half as /dev/buttons.
  2. Before the patch, poll(POLLIN) on /dev/buttons never returns and
    no press is observed - the GPIOTE interrupt is never enabled for
    channels on instance 0.
  3. After the patch, presses and releases arrive.

@github-actions github-actions Bot added Arch: arm Issues related to ARM (32-bit) architecture Size: XS The size of the change in this PR is very small labels Aug 29, 2026
@github-actions

github-actions Bot commented Aug 29, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

@simbit18

Copy link
Copy Markdown
Contributor

Hi @AlmAck please fix and rebase

../nuttx/tools/checkpatch.sh -c -u -m -g  f9bf75ac62780ebe422258519a3e176bc607d9a4..HEAD
Error: /home/runner/work/nuttx/nuttx/nuttx/arch/arm/src/nrf53/nrf53_gpiote.c:185:14: error: Missing blank line after declarations
Error: /home/runner/work/nuttx/nuttx/nuttx/arch/arm/src/nrf53/nrf53_gpiote.c:213:14: error: Bad alignment
Error: /home/runner/work/nuttx/nuttx/nuttx/arch/arm/src/nrf53/nrf53_gpiote.c:216:14: error: Bad alignment
Error: /home/runner/work/nuttx/nuttx/nuttx/arch/arm/src/nrf53/nrf53_gpiote.c:259:7: error: Bad right brace alignment

AlmAck added 2 commits August 30, 2026 20:03
The driver presents a single channel space of GPIOTE_CHANNELS entries
across the application core's two GPIOTE peripherals, and splits it:

  inst  = (channel < GPIOTE_PER_CHANNEL) ? 0 : 1;
  rchan = (inst == 1) ? channel : (channel - GPIOTE_PER_CHANNEL);

rchan is the channel index within the selected instance, used to build
the per-channel register offsets, so it must be

  rchan = channel - GPIOTE_PER_CHANNEL * inst

The ternary has the two arms the other way round: a channel on instance
0 gets rchan = channel - GPIOTE_PER_CHANNEL, which is negative, and a
channel on instance 1 gets an index still offset by a full instance.

The interrupt handler in this same file already applies that mapping in
the opposite direction, converting a per-instance channel back to the
global one:

  off = i + GPIOTE_PER_CHANNEL * inst;

so the two were inconsistent, and it is the rchan sites that were wrong.

Per the nRF5340 Product Specification, 'GPIOTE - GPIO tasks and
events', the application core has two GPIOTE instances, GPIOTE0 (secure,
base 0x5000D000) and GPIOTE1 (non-secure, base 0x4002F000), each with
eight channels and its own CONFIG[n] array at offset 0x510 + 4n for
n = 0..7.  This matches GPIOTE_PER_CHANNEL == 8, the two base addresses
in hardware/nrf53_memorymap_cpuapp.h, and NRF53_GPIOTE_CONFIG_OFFSET()
in hardware/nrf53_gpiote.h, so rchan is required to be in 0..7 and a
negative value cannot address a CONFIG register.

With a negative rchan the CONFIG register write for a channel on
instance 0 lands below the instance base instead of in CONFIG[n], so the
channel is never configured and its GPIOTE interrupt is never enabled.
On nrf5340-dk this makes the board buttons dead.

Both call sites are corrected.

Signed-off-by: AlmAck <gluca86@gmail.com>
Pre-existing violations in this file, reported by checkpatch because the
preceding commit touches it:

  nrf53_gpiote.c:185: Missing blank line after declarations
  nrf53_gpiote.c:213: Bad alignment
  nrf53_gpiote.c:216: Bad alignment
  nrf53_gpiote.c:259: Bad right brace alignment

Add the blank line after the declarations in the channel-callback block,
indent the two `break;` statements into their case bodies, and align the
brace closing the per-port `for` loop with its opening at line 209 (it
sat at seven spaces, so neither the loop's eight nor anything else).

Whitespace only — no functional change, brace count unchanged.

Signed-off-by: AlmAck <gluca86@gmail.com>
@AlmAck
AlmAck force-pushed the fix/nrf53-gpiote-rchan branch from 9f1c849 to 16f8775 Compare August 30, 2026 18:07
@github-actions github-actions Bot added Size: S The size of the change in this PR is small and removed Size: XS The size of the change in this PR is very small labels Aug 30, 2026
@AlmAck

AlmAck commented Aug 30, 2026

Copy link
Copy Markdown
Contributor Author

Hi @AlmAck please fix and rebase

../nuttx/tools/checkpatch.sh -c -u -m -g  f9bf75ac62780ebe422258519a3e176bc607d9a4..HEAD
Error: /home/runner/work/nuttx/nuttx/nuttx/arch/arm/src/nrf53/nrf53_gpiote.c:185:14: error: Missing blank line after declarations
Error: /home/runner/work/nuttx/nuttx/nuttx/arch/arm/src/nrf53/nrf53_gpiote.c:213:14: error: Bad alignment
Error: /home/runner/work/nuttx/nuttx/nuttx/arch/arm/src/nrf53/nrf53_gpiote.c:216:14: error: Bad alignment
Error: /home/runner/work/nuttx/nuttx/nuttx/arch/arm/src/nrf53/nrf53_gpiote.c:259:7: error: Bad right brace alignment

those bad alignment are not part of my original PR, i added them too as requested. probably an entire check on those files is required separately to avoid mixing PR content.

@xiaoxiang781216
xiaoxiang781216 merged commit b496611 into apache:master Aug 31, 2026
38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: arm Issues related to ARM (32-bit) architecture Size: S The size of the change in this PR is small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants