5656
5757// GYRO_FS_SEL = 0 -> +/-2000dps, 16.4 LSB/(deg/s)
5858#define ICM40609D_GYRO_FS_SEL_2000DPS (0 << 5)
59- #define ICM40609D_GYRO_ODR_1KHZ 6
6059
6160// ACCEL_FS_SEL = 1 -> +/-16g, 2048 LSB/g (FS_SEL=0 is +/-32g on this chip,
6261// unlike ICM42605 where 0 is the narrowest common range)
6362#define ICM40609D_ACCEL_FS_SEL_16G (1 << 5)
64- #define ICM40609D_ACCEL_ODR_1KHZ 6
6563
6664// Low-latency UI filter bandwidth select, both fields set to the "trivial"
6765// low-latency option (verified numeric meaning against the same bit layout
8078#define ICM40609D_RA_INT_SOURCE0 0x65
8179#define ICM40609D_UI_DRDY_INT1_EN_ENABLED (1 << 3)
8280
81+ // ODR select values (bits[3:0] of GYRO_CONFIG0/ACCEL_CONFIG0) verified
82+ // against the datasheet's ODR tables -- identical encoding to ICM42605
83+ // for these five rates, so reusing the same gyroFilterAndRateConfig_t
84+ // mechanism and DLPF tag (unused here; this driver doesn't vary the UI
85+ // filter bandwidth by requested LPF, see icm40609dAccAndGyroInit).
86+ static const gyroFilterAndRateConfig_t icm40609dGyroConfigs [] = {
87+ /* DLPF ODR */
88+ { GYRO_LPF_256HZ , 8000 , { 0 , 3 } },
89+ { GYRO_LPF_256HZ , 4000 , { 0 , 4 } },
90+ { GYRO_LPF_256HZ , 2000 , { 0 , 5 } },
91+ { GYRO_LPF_256HZ , 1000 , { 0 , 6 } },
92+ { GYRO_LPF_256HZ , 500 , { 0 , 15 } },
93+ };
94+
8395static void icm40609dAccInit (accDev_t * acc )
8496{
8597 acc -> acc_1G = 512 * 4 ; // 2048 LSB/g, matches ACCEL_FS_SEL=1 (+/-16g)
@@ -123,18 +135,19 @@ bool icm40609dAccDetect(accDev_t *acc)
123135static void icm40609dAccAndGyroInit (gyroDev_t * gyro )
124136{
125137 busDevice_t * dev = gyro -> busDev ;
126-
127- gyro -> sampleRateIntervalUs = 1000 ; // 1kHz ODR
138+ const gyroFilterAndRateConfig_t * config = chooseGyroConfig (gyro -> lpf , 1000000 / gyro -> requestedSampleIntervalUs ,
139+ & icm40609dGyroConfigs [0 ], ARRAYLEN (icm40609dGyroConfigs ));
140+ gyro -> sampleRateIntervalUs = 1000000 / config -> gyroRateHz ;
128141
129142 busSetSpeed (dev , BUS_SPEED_INITIALIZATION );
130143
131144 busWrite (dev , ICM40609D_RA_PWR_MGMT0 , ICM40609D_PWR_MGMT0_TEMP_DISABLE_OFF | ICM40609D_PWR_MGMT0_ACCEL_MODE_LN | ICM40609D_PWR_MGMT0_GYRO_MODE_LN );
132145 delay (15 );
133146
134- busWrite (dev , ICM40609D_RA_GYRO_CONFIG0 , ICM40609D_GYRO_FS_SEL_2000DPS | ICM40609D_GYRO_ODR_1KHZ );
147+ busWrite (dev , ICM40609D_RA_GYRO_CONFIG0 , ICM40609D_GYRO_FS_SEL_2000DPS | ( config -> gyroConfigValues [ 1 ] & 0x0F ) );
135148 delay (15 );
136149
137- busWrite (dev , ICM40609D_RA_ACCEL_CONFIG0 , ICM40609D_ACCEL_FS_SEL_16G | ICM40609D_ACCEL_ODR_1KHZ );
150+ busWrite (dev , ICM40609D_RA_ACCEL_CONFIG0 , ICM40609D_ACCEL_FS_SEL_16G | ( config -> gyroConfigValues [ 1 ] & 0x0F ) );
138151 delay (15 );
139152
140153 // Low latency, same convention as ICM42605
@@ -144,6 +157,11 @@ static void icm40609dAccAndGyroInit(gyroDev_t *gyro)
144157 busWrite (dev , ICM40609D_RA_INT_CONFIG , ICM40609D_INT1_MODE_PULSED | ICM40609D_INT1_DRIVE_CIRCUIT_PP | ICM40609D_INT1_POLARITY_ACTIVE_HIGH );
145158 delay (15 );
146159
160+ // Unlike ICM42605, this chip's Bank 0 register map has no INT_CONFIG1
161+ // (0x64) / ASYNC_RESET bit -- confirmed absent from DS-000272 rev 0.8
162+ // (register map jumps from INT_CONFIG0 at 0x63 straight to INT_SOURCE0
163+ // at 0x65). ICM42605's "clear ASYNC_RESET for proper INT1/INT2
164+ // operation" erratum step is therefore intentionally omitted here.
147165 busWrite (dev , ICM40609D_RA_INT_CONFIG0 , ICM40609D_UI_DRDY_INT_CLEAR_ON_SBR );
148166 delay (100 );
149167
0 commit comments