Use case
Always-on wake-on-motion (WOM): the ICM-42607-C accelerometer runs in Low-Power (LP) mode, duty-cycling at a low ODR and comparing samples against per-axis thresholds. On motion it asserts INT1, waking a sleeping host MCU. The gyro is off. The rest of this post answers the questions you need answered to write that firmware.
Q: What is the exact register write order for the ICM-42607-C?
All Bank 0 registers unless noted. MREG1 registers are reached indirectly: write the target address to MREG1_ADDR, then data to MREG1_DATA; use REG_BANK_SEL to switch user banks.
1. Soft reset -> SIGNAL_PATH_RESET (Bank 0 0x02), write bit 4 SOFT_RESET_DEVICE_CONFIG = 1 (auto-clearing)
2. Poll for reset done -> poll INT_STATUS bit 4 RESET_DONE_INT until it reads 1, then read it (clears it)
3. Confirm sensors off -> PWR_MGMT0 (0x1F): ACCEL_MODE = 00, GYRO_MODE = 00 (configure while device is off)
4. LP clock source -> PWR_MGMT0 (0x1F) bit 7 ACCEL_LP_CLK_SEL = 0 (wake-up oscillator; datasheet-recommended)
5. ODR + range -> ACCEL_CONFIG0 (0x21): ACCEL_ODR = LP-mode code, ACCEL_UI_FS_SEL as needed
6. WOM debounce/mode -> WOM_CONFIG (0x27): WOM_INT_DUR, WOM_INT_MODE, WOM_MODE (MUST be written before WOM_EN = 1)
7. WOM thresholds -> ACCEL_WOM_X_THR / _Y_THR / _Z_THR (MREG1 0x4B / 0x4C / 0x4D)
8. Route WOM to INT1 -> INT_SOURCE1 (Bank 0 0x2C), write 0x07 (WOM_X/Y/Z_INT1_EN = 1)
9. INT1 electrical -> INT_CONFIG (0x22): INT1_MODE (level/pulse), INT1_DRV (push-pull/open-drain), INT1_POL (active-high/low)
10. Arm + enable accel -> WOM_CONFIG (0x27): WOM_EN = 1; then PWR_MGMT0 (0x1F): ACCEL_MODE = 10 (LP), GYRO_MODE = 00
11. Honor the hold-off -> after the OFF-to-LP transition, issue no register writes for 200 us, then allow the accel start-up time before expecting valid samples
Notes on ordering:
- Steps 6-7 must precede step 10's WOM_EN write:
WOM_INT_DUR,WOM_INT_MODE, andWOM_MODE"cannot be changed if WOM_EN is already enabled." OnlyWOM_ENitself can be toggled freely; if you need to change one later, clear WOM_EN, change the field, re-arm. - The notes do not specify an ordering requirement between steps 8-9 and the sensor enable; they only constrain WOM_CONFIG internally (see step 6) and the 200 us no-write window after OFF-to-active transitions.
Q: Which settings on the ICM-42607-C are required vs. choices?
Required (dictated by the use case):
GYRO_MODE = 00(off) andACCEL_MODE = 10(LP) — the LP mode is explicitly "Gyro Off / Accel Duty-Cycled." Arming WOM with the accel off means there are no samples to compare, and no WOM event can ever fire.WOM_EN = 1to arm detection.- LP-mode ODR/averaging restrictions are constraints, not tuning: ODR = 1600/800 Hz forbids any averaging; ODR = 400 Hz forbids 16-64x; ODR = 200 Hz forbids 64x. Also,
ACCEL_ODRcodes0101(1.6 kHz) and0110(800 Hz) are LN-mode only;1101(6.25 Hz),1110(3.125 Hz),1111(1.5625 Hz) are LP-mode only. Do not write sub-6.25 Hz codes outside LP mode. - The soft reset +
RESET_DONE_INThandshake is procedure, not a value.
Choices, with the trade-off the datasheet states:
ACCEL_LP_CLK_SEL(PWR_MGMT0 bit 7): 0 = wake-up oscillator, described as the lowest-power and recommended setting; 1 = RC oscillator. Trade-off: lowest power vs. needing an RC-derived clock.ACCEL_ODR(1.5625-1600 Hz): higher ODR = fresher samples and lower detection latency but more duty-cycles = more power; lower ODR = lowest power but later detection and transient motion can slip between samples.ACCEL_UI_AVG(ACCEL_CONFIG1bits 6:4, LPM only — "cannot be changed when the accel sensor is in LPM"): the averaging filter applied to the LP-mode accel output. Encodings:000= 2x,001= 4x,010= 8x,011= 16x,100= 32x,101/110/111= 64x. The register resets to 0x41, i.e.100in these bits = 32x by default. More averaging smooths the output but is exactly the knob the ODR/averaging restriction table above constrains — don't raise it past what your chosen ODR permits.ACCEL_UI_FS_SEL(±2/4/8/16 g): sensitivity is 2048 LSB/g at ±16 g up to 16,384 LSB/g at ±2 g. Note it does not affect WOM: thresholds are fixed mg (~3.9 mg/LSB) independent of range. This choice is about post-wake readout fidelity vs. headroom.WOM_INT_DUR(WOM_CONFIG bits 4:3): 00 = assert on 1st over-threshold sample ... 11 = 4th. Higher count = fewer false wakes but longer latency; brief motions can be missed. Lowest count = fastest, most sensitive, noisiest.WOM_INT_MODE(bit 2): OR sets the interrupt when any enabled axis passes (sensitive, more false triggers); AND requires all enabled axes (stricter, can miss single-axis-directed motion).WOM_MODE(bit 1): 0 = compare against a stored initial sample (detects change from baseline; slow drift can sit above threshold); 1 = compare current to previous sample (catches continuous motion, ignores absolute offset).- INT1 electrical (
INT1_MODE,INT1_DRV,INT1_POL): pulse mode self-clears; latched requires a status read to clear. Open-drain needs an external pull-up and inverts logic; active-low open-drain means inverting the MCU EXTI polarity.
Threshold values: the datasheet publishes no recommended WOM threshold. ACCEL_WOM_X/Y/Z_THR span 0-1 g at ~3.9 mg/LSB. The only numeric inputs the datasheet gives are that resolution and the part's RMS noise of 1.0 mg-rms (100 Hz BW); any specific starting point — e.g. a value a few LSB above the noise floor, then tuned against bench false-wake/missed-wake tests — is engineering judgment, not a datasheet recommendation. [PRACTICE]
Q: What delays and polls are required?
- After power-up: the part is ready for register access within 1 ms of supply reaching valid level (supply ramp 0.1-100 ms for a valid power-on reset). The notes flag this figure as worth confirming against the part's start-up timing table before freezing the driver.
- After soft reset: poll
INT_STATUSbit 4RESET_DONE_INT. It sets to 1 when software reset is complete and clears on read. No timeout figure is given in the notes — poll, don't hard-delay. For reference, the fullINT_STATUS(0x3A) bit map is: bit7ST_INT, bit6FSYNC_INT, bit5PLL_RDY_INT, bit4RESET_DONE_INT, bit3 Reserved, bit2FIFO_THS_INT, bit1FIFO_FULL_INT, bit0AGC_RDY_INT— all read-to-clear, and bit3 is genuinely reserved, so don't assume the FIFO/AGC bits shift down to fill it. This is a different register fromINT_STATUS_DRDY(0x39) andINT_STATUS2(0x3B) used elsewhere in this post. - After any OFF-to-active
ACCEL_MODE/GYRO_MODEtransition: issue no register writes for 200 us. - Gyro start-up: the gyro must be kept on at least 45 ms — irrelevant here since the gyro is off, but do not confuse this with the 200 us accel window.
- Accel start-up before first valid data: approximately 10 ms typical from enable. The notes flag this as a typical to verify against the datasheet's start-up time table.
- After the final PWR_MGMT0 write: give the part time to reach LP mode before treating WOM as armed; the notes give no exact figure beyond the 200 us / start-up time above.
- FIFO_FLUSH (only if using FIFO): write
FIFO_FLUSH = 1inSIGNAL_PATH_RESET, wait 1.5 us, read it back — it should now read 0.
Q: How does firmware read the result?
This is an interrupt model — the host sleeps; no polling happens while it sleeps.
- MCU exits sleep on the INT1 edge/level.
- Read
INT_STATUS2(Bank 00x3B, read-to-clear). Bit 2 =WOM_X_INT, bit 1 =WOM_Y_INT, bit 0 =WOM_Z_INT, bit 3 =SMD_INT. This tells you which axis tripped. - The read itself clears the latch — all INT_STATUS bits are latched, read-to-clear — which releases INT1 (pulse mode) or releases it after the read (latched mode) and automatically re-arms WOM. No reconfigure write is needed before the host goes back to sleep.
- Optionally read
ACCEL_DATA_X1/X0 (0x0B/0x0C),Y1/Y0 (0x0D/0x0E),Z1/Z0 (0x0F/0x10)as one burst read (address auto-increments; registers are 16-bit two's complement) to see the actual motion —INT_STATUS2tells you which axis, not how much. - Sleep. The
INT_STATUS2read already re-armed WOM. [PRACTICE]
If the INT1 line is latched mode, remember the host must read INT_STATUS2 to de-assert it; failing to do so means the system cannot re-arm for the next event.
Q: How do I verify the configuration took on the ICM-42607-C?
Layered, cheapest first:
| Layer | Check | Register | Pass when |
|---|---|---|---|
| 0 | Clock running | MCLK_RDY (Bank 0 0x00) bit 3 |
reads 1 ("internal clock is currently running") |
| 0 | Identity | WHO_AM_I (Bank 0 0x75) |
reads 0x61. Must read Bank 0 first, or you read something else |
| 1 | Accel streaming | INT_STATUS_DRDY (0x39) bit 0 DATA_RDY_INT |
repeatedly sets and clears on read |
| 1 | Data sane | ACCEL_DATA_X/Y/Z (0x0B-0x10) |
Z about 1 g level, values change when moved |
| 2 | Writes landed | PWR_MGMT0, ACCEL_CONFIG0, WOM_CONFIG, WOM threshold regs |
each reads back exactly what you wrote |
| 3 | Reset done | INT_STATUS bit 4 RESET_DONE_INT |
observed 1, then 0 after the read |
| 4 | WOM functions | INT_STATUS2 (0x3B) |
WOM flag sets on a physical nudge, clears on read |
Two caveats on Layer 2: read-back proves the write landed, not that the combination is electrically valid — forbidden ODR/averaging pairs in LP mode will read back correctly and still not behave. Only the functional nudge test (Layer 4) catches that. And for MREG1 registers (ACCEL_WOM_X/Y/Z_THR), read back through the same MREG1_ADDR/MREG1_DATA indirect path you wrote through.
If you also poll DATA_RDY_INT in latched mode (Layer 1) rather than relying on it self-clearing, its clearing behavior is configured by UI_DRDY_INT_CLEAR — bits 5:4 of INT_CONFIG0, which is an MREG1 register, not Bank 0: 00/01 clear on a status-bit read, 10 clears on a sensor-register read, 11 clears on either. FIFO_THS_INT_CLEAR (bits 3:2) and FIFO_FULL_INT_CLEAR (bits 1:0) in the same register follow the same three-option pattern.
Common mistakes
- Arming WOM with
ACCEL_MODE = 00(the reset value) — no samples, no interrupts, ever. - Writing
WOM_INT_DUR/WOM_INT_MODE/WOM_MODEafterWOM_EN = 1— writes are silently ignored. - Using an LN-mode-only ODR code in LP mode, or a forbidden ODR/averaging pair.
- Writing registers inside the 200 us window after an OFF-to-active sensor transition.
- Leaving thresholds at reset
0x00— most sensitive edge, twitchy on noise. - Routing via
INT_SOURCE0(0x2B) — that register has no WOM bit. WOM-to-INT1 enables are per-axis inINT_SOURCE1(0x2C):WOM_X/Y/Z_INT1_EN(bits 2:0). (INT_SOURCE4routes to INT2;INT_SOURCE9routes to IBI.)
What's still unverified
Per-ODR current figures in LP mode were not recoverable from the datasheet corpus — the only current figure available is a features-list headline for Low-Noise mode (0.55 mA, 6-axis), which is a different mode and not broken out by ODR. Validate actual draw on your bench before locking the battery budget.
Part page: ICM-42607-C.