2406827_en-US

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

2406827_en-US

2406827_en-US

LPC55S69: I2C registers all correct, but SDA/SCL never physically move

LPC55S69: I2C4 (Flexcomm 4) master never physically drives SDA/SCL despite fully correct register configuration - I2C_MasterStart() hangs permanently in I2C_MasterCheckStartResponse()

Summary

On an LPC55S69-EVK, I2C_MasterTransferBlocking() hangs permanently (no timeout, confirmed via SDK source inspection) on the very first transaction attempted after I2C_MasterInit(). Every peripheral configuration register I can inspect - CFG, PSELID, CLKDIV, MSTTIME, IOCON pin function, and the Secure AHB Controller's peripheral access rules - reads back as correctly configured. However, a direct multimeter measurement of the physical SDA/SCL lines, taken while execution is frozen mid-hang inside the driver, shows both lines sitting at a clean, unchanged idle ~3.3V - meaning the I2C master's internal state machine never actually asserts a START condition onto the physical bus at all, despite software believing it did.

Environment

  • Board: LPCXpresso55S69-EVK, LPC55S69JBD100
  • IDE: MCUXpresso IDE v25.6 [Build 136]
  • I2C peripheral: I2C4 (Flexcomm 4), pins P1_20 (SCL) / P1_21 (SDA)
  • This is Core 1 (non-secure, no TrustZone - confirmed this chip's Core 1 has no TrustZone capability at all per AN12278) of a dual-core project. Core 1 is confirmed booting and executing correctly (proven via a working LED heartbeat and independent shared-memory diagnostics) - this report is specifically about the I2C peripheral, not the multicore boot sequence.
  • Sensor: Adafruit BME688 (STEMMA QT, onboard pull-ups), address 0x77, connected via genuine Adafruit STEMMA QT-to-header cable

The core evidence

1. The hang location, confirmed via SDK source inspection

Reading fsl_i2c.c directly: I2C_MasterTransferBlocking() calls I2C_MasterStart() then I2C_MasterCheckStartResponse(). The latter calls I2C_PendingStatusWait(), which polls kI2C_MasterPendingFlag in a loop with no timeout at all when I2C_RETRY_TIMES is 0/undefined (confirmed this is the active code path in this project - the #else branch with an unconditional while(...) and no exit condition). Execution never returns from this call, confirmed by a shared-memory diagnostic checkpoint written immediately before the call, which is reached, and one written immediately after, which is never reached, even after 5+ seconds of continuous execution.

2. Register state at the moment of the hang (read live via debugger, not assumed)

Register Address Value Meaning

I2C4->STAT0x5008A0000x00000000Idle. MSTPENDING=0, MSTSTATE=0, no error flags
I2C4->CFG0x5008A8000x00000001MSTEN=1 - master mode enabled
FLEXCOMM4->PSELID0x5008AFF80x1020F3PERSEL=3 (I2C personality genuinely selected), I2CPRESENT=1
I2C4->CLKDIV0x5008A81474Non-zero, plausible divider
I2C4->MSTTIME0x5008A824102Non-zero, plausible SCL timing
IOCON->PIO[1][20] (P1_20/SCL)0x500010D00x323FUNC=3 (Flexcomm alt-function), pull-up + open-drain enabled
IOCON->PIO[1][21] (P1_21/SDA)0x500010D40x323Same - correctly configured
AHB_SECURE_CTRL FLEXCOMM4_RULE0x500AC12400b00 = "Non-secure and Non-privilege user access allowed" (most permissive)
AHB_SECURE_CTRL IOCON_RULE0x500AC1300Same - fully open, non-secure access unrestricted

Every one of these is exactly what a correctly-configured, unrestricted, ready-to-transact I2C master should show.

3. Physical measurement (the decisive evidence)

With execution frozen mid-hang (confirmed via the checkpoint diagnostic, STAT still reading 0x00000000 at this exact moment):

  • SDA to GND: 3.299 V
  • SCL to GND: 3.299 V

Both lines are indistinguishable from a fully idle, untouched bus. The physical pins never moved at all, despite I2C_MasterStart() having already executed (it's called before I2C_MasterCheckStartResponse(), where we're actually hung) and despite every register above showing a fully configured, unrestricted master.

What has been ruled out

  • Sensor/cable/breadboard fault - wiring continuity confirmed with a multimeter across multiple different physical wire positions (5+ attempts); genuine Adafruit STEMMA QT cable; sensor address pad confirmed consistent with the documented 0x77 default; identical result reproduces regardless of which physical header pins are used
  • Clock source/frequency - explicitly re-asserted CLOCK_SetupFROClocking(12000000U) immediately before attaching Flexcomm4's clock; no change
  • Baud rate/timing miscalculation - reduced from 100 kHz to 10 kHz (10x); identical hang; CLKDIV/MSTTIME both confirmed non-zero and plausible
  • Pin mux - confirmed via IOCON_FUNC3 write and independently re-verified via direct register read at the exact moment of the hang
  • I2C personality selection - confirmed via PSELID
  • Sensor driver library - bypassed bme68x.c entirely; a raw, minimal zero-length address probe built directly with the SDK's i2c_master_transfer_t struct produces the identical hang
  • MasterEnable off/on toggle workaround (from a similar-sounding NXP community report for a different part) - no effect
  • TrustZone/Secure AHB Controller peripheral access restriction - confirmed both IOCON and FLEXCOMM4 are set to the most permissive non-secure access rule

Question

Given every software-visible register indicates a correctly configured, unrestricted I2C master, but the physical SDA/SCL pins provably never move (confirmed by direct voltage measurement while frozen inside the driver call), what remaining hardware-level step is required to get the I2C4 peripheral to actually drive its pads on this part?

Specifically:

  • Is there a known LPC55S69 errata affecting Flexcomm I2C pad drive that isn't captured by the CFG/PSELID/IOCON registers I've checked?
  • Is there an additional power-domain, pad-supply, or analog block that needs to be explicitly enabled for Flexcomm I2C physical output (something outside the digital peripheral configuration registers) that I may have missed?
  • Given this is Core 1 (bare-metal, no RTOS, no TrustZone) in a dual-core multicore project where Core 0 runs FreeRTOS - is there any known interaction between Core 0's own boot-time configuration and Core 1's ability to drive Flexcomm4's physical pads, beyond what a register-level snapshot would reveal (e.g., something in SYSCON clock-gating for the pad IO cell itself, distinct from CLOCK_AttachClk's peripheral function clock)?

Happy to provide the full project, a logic analyzer capture, or any additional register dump on request.

LPC55xxRe: LPC55S69: I2C registers all correct, but SDA/SCL never physically move

Resolved - root cause was an incorrect IOCON alternate function number

Posting the resolution in case anyone finds this thread later with a similar symptom.

The actual root cause

IOCON_PIO_FUNC3 does not route P1_20/P1_21 to FC4 I2C on this board. The correct alternate function is FUNC5, with open-drain disabled at the IOCON level (the I2C peripheral's own CFG register handles open-drain behavior internally - enabling it again at the IOCON pad level was also wrong).

I had derived FUNC3 by reading the pin_signal ordering in a comment (PIO1_20/FC7_RTS_SCL_SSEL1/CT_INP14/FC4_TXD_SCL_MISO_WS/PLU_OUT2) and assuming 0-indexed position = function number. That assumption was incorrect for this pin.

Why this produced such a confusing symptom

With the wrong alternate function selected, every I2C-internal register still read back as perfectly configured:

  • I2C4->CFG.MSTEN = 1 (master enabled)
  • FLEXCOMM4->PSELID showed I2C personality genuinely selected
  • CLKDIV/MSTTIME were valid, non-zero
  • Even IOCON->PIO[1][20/21] showed a function selected (just the wrong one) - nothing about this register's value alone signals "wrong function," only "some function is selected"

None of that depends on the physical pin actually being connected to the I2C block - PSELID and CFG are entirely internal to the Flexcomm/I2C logic, independent of which alternate function the IOCON mux happens to route to. So the peripheral was internally fully configured and "ready," while the physical SDA/SCL pins were never actually wired to it at all. This produced a permanent hang in I2C_MasterTransferBlocking() (confirmed via SDK source: no timeout when I2C_RETRY_TIMES is 0) with zero error flags ever raised, and - the piece that finally proved it - a multimeter measurement showing the physical bus completely unchanged at idle voltage even while frozen mid-transaction, since the pins genuinely were never driven.

How it was found

Created a fresh, separate single-core test project for the same board and used the MCUXpresso wizard's own auto-generated BOARD_InitACCELPins() function (this board has an onboard accelerometer wired to the same I2C4 bus, so the wizard ships a working, verified pin mux for these exact pins). Reading that function's actual generated source showed IOCON_PIO_FUNC5 with open-drain disabled - directly contradicting my own hand-derived FUNC3/open-drain-enabled configuration. Switching to match NXP's own verified values immediately resolved the permanent hang; a subsequent, unrelated address-NAK (0x77 not acknowledging) turned out to just be a loose header-pin contact, resolved by moving the connection to different header pins.

Lesson for anyone else hitting an identical symptom

If a Flexcomm peripheral's own registers (PSELID, CFG, CLKDIV, etc.) all read back as correctly configured but the physical bus never shows any activity (confirmed via multimeter/scope) - don't trust a hand-derived alternate function number from reading the pin_signal comment ordering. Cross-check against any wizard-auto-generated pin mux function this SDK ships for the same physical pins on the same board (peripherals the eval board itself uses - accelerometers, codecs, etc. - are a good source of a genuinely verified reference), or regenerate the pin mux via the MCUXpresso Pins tool directly rather than hand-writing IOCON_PinMuxSet() calls from an assumed function index.

Thanks again to everyone who engaged with the earlier posts in this thread and the original multicore boot thread - the register-level verification work across both investigations is what eventually made this contradiction (everything configured correctly, yet nothing on the bus) visible enough to chase down.

タグ(1)
評価なし
バージョン履歴
最終更新日:
金曜日
更新者: