Skip to content

Commit 8b14eb1

Browse files
committed
Don't place accel and gyro into low power mode. Ensure gyro DLPF is enabled. Return chip to low power state changing DMP (even though accel and gyro are _not_ in low power mode).
1 parent 25606ad commit 8b14eb1

File tree

2 files changed

+30
-19
lines changed

2 files changed

+30
-19
lines changed

src/ICM_20948.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,8 +1215,9 @@ ICM_20948_Status_e ICM_20948::initializeDMP(void)
12151215
uint8_t pwrMgmt2 = 0x40; // Set the reserved bit 6 (pressure sensor disable?)
12161216
result = write(AGB0_REG_PWR_MGMT_2, &pwrMgmt2, 1); if (result > worstResult) worstResult = result; // Write one byte to the PWR_MGMT_2 register
12171217

1218-
// Configure I2C_Master/Gyro/Accel in Low Power Mode (cycled) with LP_CONFIG
1219-
result = setSampleMode((ICM_20948_Internal_Mst | ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), ICM_20948_Sample_Mode_Cycled); if (result > worstResult) worstResult = result;
1218+
// Place _only_ I2C_Master in Low Power Mode (cycled) via LP_CONFIG
1219+
// The InvenSense Nucleo example initially puts the accel and gyro into low power mode too, but then later updates LP_CONFIG so only the I2C_Master is in Low Power Mode
1220+
result = setSampleMode(ICM_20948_Internal_Mst, ICM_20948_Sample_Mode_Cycled); if (result > worstResult) worstResult = result;
12201221

12211222
// Disable the FIFO
12221223
result = enableFIFO(false); if (result > worstResult) worstResult = result;
@@ -1239,6 +1240,11 @@ ICM_20948_Status_e ICM_20948::initializeDMP(void)
12391240
// dps2000
12401241
result = setFullScale((ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), myFSS); if (result > worstResult) worstResult = result;
12411242

1243+
// The InvenSense Nucleo code also enables the gyro DLPF (but leaves GYRO_DLPFCFG set to zero = 196.6Hz (3dB))
1244+
// We found this by going through the SPI data generated by ZaneL's Teensy-ICM-20948 library byte by byte...
1245+
// The gyro DLPF is enabled by default (GYRO_CONFIG_1 = 0x01) so the following line should have no effect, but we'll include it anyway
1246+
result = enableDLPF(ICM_20948_Internal_Gyr, true); if (result > worstResult) worstResult = result;
1247+
12421248
// Enable interrupt for FIFO overflow from FIFOs through INT_ENABLE_2
12431249
// If we see this interrupt, we'll need to reset the FIFO
12441250
//result = intEnableOverflowFIFO( 0x1F ); if (result > worstResult) worstResult = result; // Enable the interrupt on all FIFOs
@@ -1262,7 +1268,10 @@ ICM_20948_Status_e ICM_20948::initializeDMP(void)
12621268
ICM_20948_smplrt_t mySmplrt;
12631269
mySmplrt.g = 19; // ODR is computed as follows: 1.1 kHz/(1+GYRO_SMPLRT_DIV[7:0]). 19 = 55Hz. InvenSense Nucleo example uses 19 (0x13).
12641270
mySmplrt.a = 19; // ODR is computed as follows: 1.125 kHz/(1+ACCEL_SMPLRT_DIV[11:0]). 19 = 56.25Hz. InvenSense Nucleo example uses 19 (0x13).
1265-
// ** Note: comment the next line to leave the sample rates at the maximum **
1271+
//mySmplrt.g = 4; // 225Hz
1272+
//mySmplrt.a = 4; // 225Hz
1273+
//mySmplrt.g = 8; // 112Hz
1274+
//mySmplrt.a = 8; // 112Hz
12661275
result = setSampleRate((ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), mySmplrt); if (result > worstResult) worstResult = result;
12671276

12681277
// Setup DMP start address through PRGM_STRT_ADDRH/PRGM_STRT_ADDRL
@@ -1345,17 +1354,20 @@ ICM_20948_Status_e ICM_20948::initializeDMP(void)
13451354

13461355
// Configure the Accel Only Gain: 15252014 (225Hz) 30504029 (112Hz) 61117001 (56Hz)
13471356
const unsigned char accelOnlyGain[4] = {0x03, 0xA4, 0x92, 0x49}; // 56Hz
1348-
//const unsigned char accelOnlyGain[4] = {0x00, 0xE8, 0xBA, 0x2E}; // InvenSense Nucleo example uses 225Hz
1357+
//const unsigned char accelOnlyGain[4] = {0x00, 0xE8, 0xBA, 0x2E}; // 225Hz
1358+
//const unsigned char accelOnlyGain[4] = {0x01, 0xD1, 0x74, 0x5D}; // 112Hz
13491359
result = writeDMPmems(ACCEL_ONLY_GAIN, 4, &accelOnlyGain[0]); if (result > worstResult) worstResult = result;
13501360

13511361
// Configure the Accel Alpha Var: 1026019965 (225Hz) 977872018 (112Hz) 882002213 (56Hz)
13521362
const unsigned char accelAlphaVar[4] = {0x34, 0x92, 0x49, 0x25}; // 56Hz
1353-
//const unsigned char accelAlphaVar[4] = {0x06, 0x66, 0x66, 0x66}; // Value taken from InvenSense Nucleo example
1363+
//const unsigned char accelAlphaVar[4] = {0x3D, 0x27, 0xD2, 0x7D}; // 225Hz
1364+
//const unsigned char accelAlphaVar[4] = {0x3A, 0x49, 0x24, 0x92}; // 112Hz
13541365
result = writeDMPmems(ACCEL_ALPHA_VAR, 4, &accelAlphaVar[0]); if (result > worstResult) worstResult = result;
13551366

13561367
// Configure the Accel A Var: 47721859 (225Hz) 95869806 (112Hz) 191739611 (56Hz)
13571368
const unsigned char accelAVar[4] = {0x0B, 0x6D, 0xB6, 0xDB}; // 56Hz
1358-
//const unsigned char accelAVar[4] = {0x39, 0x99, 0x99, 0x9A}; // Value taken from InvenSense Nucleo example
1369+
//const unsigned char accelAVar[4] = {0x02, 0xD8, 0x2D, 0x83}; // 225Hz
1370+
//const unsigned char accelAVar[4] = {0x05, 0xB6, 0xDB, 0x6E}; // 112Hz
13591371
result = writeDMPmems(ACCEL_A_VAR, 4, &accelAVar[0]); if (result > worstResult) worstResult = result;
13601372

13611373
// Configure the Accel Cal Rate

src/util/ICM_20948_C.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,10 +1297,9 @@ ICM_20948_Status_e inv_icm20948_firmware_load(ICM_20948_Device_t *pdev, const un
12971297
}
12981298

12991299
//Enable LP_EN since we disabled it at begining of this function.
1300-
1301-
// result = ICM_20948_low_power(pdev, true); // Put chip into low power state
1302-
// if (result != ICM_20948_Stat_Ok)
1303-
// return result;
1300+
result = ICM_20948_low_power(pdev, true); // Put chip into low power state
1301+
if (result != ICM_20948_Stat_Ok)
1302+
return result;
13041303

13051304
if (!flag)
13061305
{
@@ -1602,9 +1601,9 @@ ICM_20948_Status_e inv_icm20948_set_dmp_sensor_period(ICM_20948_Device_t *pdev,
16021601
break;
16031602
}
16041603

1605-
// result = ICM_20948_low_power(pdev, true); // Put chip into low power state
1606-
// if (result != ICM_20948_Stat_Ok)
1607-
// return result;
1604+
result = ICM_20948_low_power(pdev, true); // Put chip into low power state
1605+
if (result != ICM_20948_Stat_Ok)
1606+
return result;
16081607

16091608
if (result2 > result)
16101609
result = result2; // Return the highest error
@@ -1774,9 +1773,9 @@ ICM_20948_Status_e inv_icm20948_enable_dmp_sensor(ICM_20948_Device_t *pdev, enum
17741773
return result;
17751774
}
17761775

1777-
// result = ICM_20948_low_power(pdev, true); // Put chip into low power state
1778-
// if (result != ICM_20948_Stat_Ok)
1779-
// return result;
1776+
result = ICM_20948_low_power(pdev, true); // Put chip into low power state
1777+
if (result != ICM_20948_Stat_Ok)
1778+
return result;
17801779

17811780
return result;
17821781
}
@@ -1861,9 +1860,9 @@ ICM_20948_Status_e inv_icm20948_enable_dmp_sensor_int(ICM_20948_Device_t *pdev,
18611860
// Write the interrupt control bits into memory address DATA_INTR_CTL
18621861
result = inv_icm20948_write_mems(pdev, DATA_INTR_CTL, 2, (const unsigned char *)&data_intr_ctl);
18631862

1864-
// result = ICM_20948_low_power(pdev, true); // Put chip into low power state
1865-
// if (result != ICM_20948_Stat_Ok)
1866-
// return result;
1863+
result = ICM_20948_low_power(pdev, true); // Put chip into low power state
1864+
if (result != ICM_20948_Stat_Ok)
1865+
return result;
18671866

18681867
return result;
18691868
}

0 commit comments

Comments
 (0)