fix(pinmux): hal_pinmux_set_pin_function()'s combined single-write leaves the pad unresponsive on real hardware #122

Closed
opened 2026-07-23 22:47:03 +00:00 by hoogv · 0 comments
Owner

Found on real AWR6843AOP hardware while debugging a GPIO/UART bring-up failure on a downstream consumer project (awr6843_mss_barebones_example), through an extensive bisection against a hardware-confirmed sibling driver (AWR6xxx_Toolchain's Universal_hal, pinmux_iwr68xx.c).

hal_pinmux_set_pin_function() computed the target PADxx_CFG_REG value (FUNC_SEL + IE/OE override bits cleared) and wrote it in a single combined store. This is logically equivalent to the reference driver's approach -- computes the exact same final register value -- but empirically the pad never actually reached its requested function on real hardware.

The reference driver instead performs five separate, sequential direct writes, one per field (FUNC_SEL, IE_OVERRIDE_BIT, IE_OVERRIDE_CTRL, OE_OVERRIDE_BIT, OE_OVERRIDE_CTRL), each one its own read-modify-write hardware access. Switching to that exact pattern (confirmed via a controlled bisection: same MPU config, same GPIO driver, only this one function swapped) fixed it.

No documented reason is available for why this particular pad-config register needs field-at-a-time writes rather than one combined write to reach the same final value -- possibly some undocumented internal latch/settle behavior specific to this pad-config hardware. Carried forward as an empirically-confirmed requirement, same as this driver's other undocumented specifics (the kick-register unlock/lock values).

Also switches the re-lock write order to IOCFGKICK1 then IOCFGKICK0 (both write 0 regardless of order, so not expected to matter, but matches what was confirmed working).

Fix: five separate direct field writes instead of one combined write.

Found on real AWR6843AOP hardware while debugging a GPIO/UART bring-up failure on a downstream consumer project (`awr6843_mss_barebones_example`), through an extensive bisection against a hardware-confirmed sibling driver (`AWR6xxx_Toolchain`'s `Universal_hal`, `pinmux_iwr68xx.c`). `hal_pinmux_set_pin_function()` computed the target `PADxx_CFG_REG` value (FUNC_SEL + IE/OE override bits cleared) and wrote it in a single combined store. This is logically equivalent to the reference driver's approach -- computes the exact same final register value -- but empirically the pad never actually reached its requested function on real hardware. The reference driver instead performs **five separate, sequential direct writes**, one per field (`FUNC_SEL`, `IE_OVERRIDE_BIT`, `IE_OVERRIDE_CTRL`, `OE_OVERRIDE_BIT`, `OE_OVERRIDE_CTRL`), each one its own read-modify-write hardware access. Switching to that exact pattern (confirmed via a controlled bisection: same MPU config, same GPIO driver, only this one function swapped) fixed it. No documented reason is available for why this particular pad-config register needs field-at-a-time writes rather than one combined write to reach the same final value -- possibly some undocumented internal latch/settle behavior specific to this pad-config hardware. Carried forward as an empirically-confirmed requirement, same as this driver's other undocumented specifics (the kick-register unlock/lock values). Also switches the re-lock write order to `IOCFGKICK1` then `IOCFGKICK0` (both write 0 regardless of order, so not expected to matter, but matches what was confirmed working). Fix: five separate direct field writes instead of one combined write.
hoogv closed this issue 2026-07-23 22:47:40 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
opendutchsolutions.public/hal_awr6843#122
No description provided.