ICM-42688-P INT1 never fires after FIFO setup — FIFO count stuck at 0x0000 but WHO_AM_I reads back correctly
Asked by stale_biscuit_03 ·
Working on a motion data logger — ICM-42688-P on an STM32F4 via SPI4 at 4 MHz. SPI seems fine: WHO_AM_I at register 0x75 reliably returns 0x47, and I can read back ACCEL_CONFIG0 and GYRO_CONFIG0 and they reflect what I wrote.
My init sequence:
- PWR_MGMT0 (0x4E) → 0x0F (both accel and gyro into Low Noise mode)
- ACCEL_CONFIG0 and GYRO_CONFIG0 set for 1 kHz ODR, ±4g / ±2000°/s
- FIFO_CONFIG1 (0x5F) → 0x03 (accel + gyro into FIFO)
- INT_CONFIG (0x14) left at default — INT1 active-low — GPIO on PA0 configured for falling edge
Problem: FIFO_COUNTH and FIFO_COUNTL (0x2E/0x2F) always read back 0x00 / 0x00, no matter how long I wait. INT1 never fires — have a GPIO toggle in the EXTI0 ISR that's never triggered.
Tried dropping ODR to 100 Hz to rule out a polling speed issue. Tried adding 50 ms delays between every register write. Tried starting with a soft reset via DEVICE_CONFIG. Every time, FIFO count is permanently 0.
What am I missing? The SPI reads back fine, the sensor powers up (I can see the output registers changing when I move the board), but the FIFO just never accumulates anything.
3 Replies
Two registers not written. The first is why your FIFO count is permanently 0.
1. FIFO_CONFIG (register 0x16) is still in BYPASS mode.
FIFO_CONFIG defaults to 0x00. Bits [7:6] = 00 means FIFO_MODE = BYPASS — the FIFO is physically disabled. Sensor data goes only to the output registers (0x1D onwards); none of it reaches the FIFO regardless of what you've written to FIFO_CONFIG1. That explains why FIFO_COUNTH/L stays at 0 while the output registers are live.
To enable FIFO, write one of:
- 0x40 (FIFO_MODE = 01 = STOP-ON-FULL): FIFO captures data until full, then pauses. Preserves your oldest samples. Good for fixed-rate burst reads.
- 0xC0 (FIFO_MODE = 11 = STREAM): FIFO continuously overwrites oldest data once full. Good for interrupt-driven reads where you drain at the watermark.
For 1 kHz with interrupts, STREAM mode (0xC0) is the usual choice.
2. INT_SOURCE0 (register 0x65) defaults to 0x00 — no interrupts are routed to INT1.
Even with the FIFO running, INT1 will not assert until you write the FIFO_FULL_INT1_EN or FIFO_THS_INT1_EN bit in INT_SOURCE0. Default is all-zeros, so INT1 is silent regardless of FIFO state. Check DS-000347 Table 14.34 for the exact bit positions and write the appropriate enable.
If you're using the watermark threshold interrupt (FIFO_THS), also configure the watermark byte count in FIFO_CONFIG2 (0x60) and FIFO_CONFIG3 (0x61) before relying on that interrupt. If you just want FIFO_FULL, skip the watermark registers for now.
Corrected minimal init for FIFO + INT1 in STREAM mode:
icm_write(0x11, 0x01); // DEVICE_CONFIG: soft reset
delay_ms(10); // wait for reset to complete
icm_write(0x4E, 0x0F); // PWR_MGMT0: accel LN + gyro LN
// Gyro startup: datasheet specifies ~45 ms typical from power-on to stable output.
// You can write the remaining config during this window.
icm_write(0x50, 0x46); // ACCEL_CONFIG0: ±4g, 1 kHz ODR (verify FS bits in DS-000347)
icm_write(0x4F, 0x06); // GYRO_CONFIG0: ±2000°/s, 1 kHz ODR
icm_write(0x5F, 0x03); // FIFO_CONFIG1: accel + gyro data into FIFO
icm_write(0x16, 0xC0); // FIFO_CONFIG: STREAM mode <-- THIS IS WHAT YOU'RE MISSING
// Enable FIFO interrupt on INT1 — see INT_SOURCE0 (0x65), DS-000347 Table 14.34
icm_write(0x65, <FIFO_FULL_INT1_EN or FIFO_THS_INT1_EN>); // <-- THIS IS ALSO MISSING
After writing 0xC0 to FIFO_CONFIG, poll FIFO_COUNTL after ~50 ms and it should be incrementing. Once the count is moving, add the INT_SOURCE0 write and INT1 will start firing.
The accelerometer and IMU guide covers FIFO benefits for real-time orientation tracking if you want the background on why the FIFO mode matters for sensor fusion pipelines.
For FIFO_CONFIG (0x16), the four FIFO_MODE states for bits [7:6] are:
| Bits [7:6] | Hex | Mode |
|---|---|---|
| 0b00 | 0x00 | BYPASS (default — FIFO disabled) |
| 0b01 | 0x40 | STOP-ON-FULL |
| 0b10 | 0x80 | Reserved — do not write |
| 0b11 | 0xC0 | STREAM |
Bits [5:0] are unused; writing 0x40 or 0xC0 is clean. That's Table 14.7 in DS-000347 Rev 1.3 if you want to confirm.
On STOP-ON-FULL vs STREAM: with accel + gyro in FIFO (no temperature, no timestamp), each sample packet is 12 bytes. The ICM-42688-P FIFO is 2,048 bytes — at 1 kHz that's roughly 170 samples, or about 170 ms before it fills. STOP-ON-FULL keeps your oldest 170 ms intact but discards new samples once full. STREAM keeps the most recent 170 ms but overwrites old data. For interrupt-driven reads where you drain at a watermark, STREAM is the right choice.
If you do use the watermark interrupt, note that FIFO_CONFIG2/3 watermark is a byte count, not a sample count. At 12 bytes/sample, setting a watermark of 120 gives you a 10-sample interrupt cadence — useful to know when sizing the handler.
Before chasing the interrupt wiring, polling FIFO_COUNTL in a tight loop right after init is a clean way to isolate which layer is broken. Two cases:
Count stays at 0: FIFO isn't accumulating data. The problem is in FIFO_CONFIG (0x16 not set to STREAM or STOP-ON-FULL) or, less commonly, sensors not actually running in a mode that feeds the FIFO. Fix FIFO_CONFIG first — don't touch INT_SOURCE0 until the count is moving.
Count is incrementing but INT1 still doesn't fire: FIFO is working, interrupt routing isn't. This is the simpler problem — just write INT_SOURCE0 (0x65) and you're done.
In your case (count permanently 0), that's definitively FIFO_CONFIG not FIFO mode. The output registers being live rules out a PWR_MGMT0 issue.
One timing note worth filing away: the ICM-42688-P gyro startup time is ~45 ms typical from power-on. If you start polling FIFO_COUNTL immediately after writing PWR_MGMT0, the gyro hasn't finished starting up and FIFO may look empty even in STREAM mode. Not your current issue — a count stuck at 0 is FIFO_CONFIG, not startup timing — but it'll matter once you're verifying the fixed init sequence. Wait at least 50 ms after the PWR_MGMT0 write before treating a 0 count as evidence of a real problem.
Related Discussions
MAX31865 reading fault bit on every conversion — VBIAS enabled but still faulting
Spent most of yesterday trying to get a MAX31865 talking to my STM32F4 and I'm stuck on the same problem no matter what I try: the fault bit
SPI reads all returning 0xFF — logic analyser shows MISO activity, W25Q32 not responding to commands
Been staring at this one for a day and a half. I'm trying to read the JEDEC ID from a W25Q32JV SPI flash chip on a custom STM32L432 board. T
NTC thermistor temperature reading jumping ±4°C — ADC noise or something in the circuit?
I've got an NTC thermistor (10 kΩ at 25°C, standard B = 3950) in a voltage divider with a 10 kΩ fixed resistor, top rail 3.3 V, thermistor t