Electronics Design AU
SensorsSolved

ICM-42688-P INT1 never fires after FIFO setup — FIFO count stuck at 0x0000 but WHO_AM_I reads back correctly

5 min read3 replies
Original Question

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.

From the knowledge baseWhat Is an Accelerometer and IMU?

3 Replies

imu_integrator
Accepted Answer

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.

register_jockey

For FIFO_CONFIG (0x16), the four FIFO_MODE states for bits [7:6] are:

Bits [7:6]HexMode
0b000x00BYPASS (default — FIFO disabled)
0b010x40STOP-ON-FULL
0b100x80Reserved — do not write
0b110xC0STREAM

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.

midnight_debugger

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