LC76G(AB) over I2C: 0x54 permanently NACKs while 0x50 still ACKs — RESET_N does not recover, only long power-off

Hardware: Quectel LC76GABMD on a Waveshare ESP32-S3-Touch-AMOLED-1.75 (GPS variant), ESP32-S3 host, ESP-IDF 6.0.2, driver/i2c_master.h. Bus: shared I2C, SDA GPIO15 / SCL GPIO14, 100 kHz, 2.2 kΩ pull-ups. Other slaves: QMI8658 (0x6A), CST9217 (0x5A), PCF8563 (0x51), AXP2101 (0x34), TCA9554 (0x20). All access serialised by one mutex. GNSS VCC: hard-wired to the 3V3 system rail (not switchable). V_BCKP: permanently powered from the RTC rail. RESET_N: via TCA9554 P7.

What works

Full 4-step read and 4-step write protocol per Quectel’s I2C Application Note, with:

  • separate I2C frames per step (never repeated-START across 0x50/0x54);

  • ≥10 ms delay before every step;

  • 500 ms receive timeout on 0x54 (the module clock-stretches up to ~200 ms);

  • 512-byte read chunking;

  • continuous drain of the 4096-byte TX buffer to data_len == 0 every cycle;

  • dummy write to 0x50 after 5 consecutive zero-length results, to avoid inactivity sleep;

  • NMEA XOR checksum validation.

Result in normal operation: 3D fix, 7–14 satellites, stable RMC/GGA/GSA/GSV.

What does not work

  • 400 kHz — corrupt reads on this board. Stayed at 100 kHz.

  • Repeated-START — NACK or garbage.

  • Raw NMEA written to 0x50 — corrupts module state; recovered only by a long power-off.

  • $PAIR690,0 — left the module unresponsive; removed from our firmware entirely.

  • Short (20 ms) read timeouts — misread clock stretching as failure.

The failure

After a period of healthy operation the module’s transmit side jams: 0x50 keeps ACKing every command, 0x54 NACKs every read, permanently.

Measured over one 228 s session with per-cause counters separated:

gps_rxfail (read fail on 0x54, 4 B) : 849
gps_nack   (NACK on 0x50)           :   0
gps_dfail  (read fail on 0x54, data):   0
gps_busy   (genuine 0xFFFFFFFF)     :   0

Each failure returned in ~109 ms, not at the 500 ms timeout → active NACK from the module, not a bus timeout and not clock stretching. The rest of the bus stays healthy throughout.

Recovery attempts — all failed

  1. Dummy write to 0x50 (the documented wake-from-sleep trick) — no effect. Note that every GETLEN already is a write to 0x50, so hundreds of them were sent with no change.

  2. Host-side I2C bus reset — no effect.

  3. RESET_N pulsed low 10 ms, then 500 ms, with retries and back-off. Pin state verified by reading the expander register back — the pin really toggled. No effect.

  4. Attempted PMIC power cycle — electrically a no-op, GNSS VCC is not on a switchable rail.

  5. Physical power disconnect (USB + battery) for ~10 minutes — this is the only thing that works. Our interpretation: V_BCKP is never removed by anything else, so the module’s I2C state and TX buffer survive every reset available to us.

Questions

  • Has anyone else seen a permanently jammed 0x54 while 0x50 still ACKs on an LC76G(AB)?

  • Is there a software-side reset of the I2C slave block that does not require dropping V_BCKP?

  • Is a dedicated I2C bus effectively mandatory for this module, or should mixed-slave buses be fine?

  • Is there a known trigger (command, latency between GETLEN and GETDATA, partially drained buffer) that causes this?

  • Would migrating to UART be the recommended fix? That is the direction we are leaning: point-to-point, no shared-bus contention, no buffered protocol to jam.

Happy to post full transaction logs, CSV counter logs, driver source and the schematic if that helps. Any pointers appreciated.

Hi @mis3dzajecar,

Thank you for the detailed information.

Multi-slave operation is supported by LC76G. The main requirement is that no other I²C slave is accessed during an ongoing LC76G transaction.

The reported condition where 0x50 continues to ACK while 0x54 permanently NACKs is not described in the application note.

The application note mentions that the I²C transmitter can enter a sleep state if the TX buffer is not read in time. Please provide the GETLEN/GETDATA sequence and timing immediately before the failure so we can check whether this could be related.

Since RESET_N does not recover the issue but complete power removal does, it would be useful if you can provide schematic of your design.

UART is a possible workaround, if that is something you are leaning on, I would recommend it.

Could you please provide the FW version that you are currently using, schematic and capture covering the period immediately before and after the 0x54 NACK occurs?

Best regards, Dobrica