Skip to content

Commit

Permalink
Merge pull request #57 from sparkfun/dmpStartup__WEAK
Browse files Browse the repository at this point in the history
v1.2.5
  • Loading branch information
PaulZC committed Apr 26, 2021
2 parents 77316d2 + b49e413 commit 8341270
Show file tree
Hide file tree
Showing 25 changed files with 8,766 additions and 6,647 deletions.
32 changes: 24 additions & 8 deletions DMP.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ The DMP allows the accelerometer, gyro and magnetometer data to be combined (fus
The DMP firmware binary has been available for quite some time. It is included in InvenSense's "MotionLink" and "Embedded Motion Driver (eMD)" examples
which can be downloaded from the InvenSense Developers Corner. However, the code is opaque and difficult to follow.

Users like @ericalbers have [ported the InvenSense example code to the Arduino environment](https://github.com/ericalbers/ICM20948_DMP_Arduino) previously. We are
grateful to Eric as his code allowed us to reverse-engineer some of the ICM-20948 configuration steps.
Users like [@ericalbers](https://github.com/ericalbers/ICM20948_DMP_Arduino) and [@ZaneL](https://github.com/ZaneL/Teensy-ICM-20948) have ported the
InvenSense example code to the Arduino environment previously. We are grateful to Eric and Zane as their code allowed us to reverse-engineer some of the
ICM-20948 configuration steps.

We are also grateful to InvenSense themselves for sharing with us a _confidential & proprietary_ document called "_Application Note: Programming Sequence for
ICM-20648 DMP Hardware Function_". InvenSense admit that the document is not complete and have asked us not to share it openly.
Expand Down Expand Up @@ -52,12 +53,17 @@ You will find ```ICM_20948_C.h``` in the library _src\util_ folder. If you are u

## How is the DMP loaded and started?

In version 1.2.5 we added a new helper function named ```initializeDMP```. This is a weak function which you can overwrite e.g. if you want to change the sample rate
(see [Example10](https://github.com/sparkfun/SparkFun_ICM-20948_ArduinoLibrary/blob/master/examples/Arduino/Example10_DMP_FastMultipleSensors/Example10_DMP_FastMultipleSensors.ino) for details).
```initializeDMP``` does most of the heavy lifting for you: it downloads the DMP firmware; and configures all of the registers with the appropriate values. The only things
you need to do manually are: select which DMP sensors to enable; reset and start both FIFO and DMP.

The DMP firmware is loaded into the ICM-20948's processor memory space via three special Bank 0 registers:
- **AGB0_REG_MEM_START_ADDR** (0x7C) - the address which AGB0_REG_MEM_R_W reads from or writes to (it auto-increments after each read or write)
- **AGB0_REG_MEM_R_W** (0x7D) - the memory read/write register
- **AGB0_REG_MEM_BANK_SEL** (0x7E) - the memory bank select. The complete read/write address is: (AGB0_REG_MEM_BANK_SEL * 256) + AGB0_REG_MEM_START_ADDR

The firmware binary (14301 Bytes) is written into processor memory starting at address 0x90. ```loadDMPFirmware``` automatically breaks the code up into 256 byte blocks and increments
The firmware binary (14290 or 14301 Bytes) is written into processor memory starting at address 0x90. ```loadDMPFirmware``` automatically breaks the code up into 256 byte blocks and increments
**AGB0_REG_MEM_BANK_SEL** during the writing.

Before the DMP is enabled, the 16-bit register **AGB2_REG_PRGM_START_ADDRH** (Bank 2, 0x50) needs to be loaded with the program start address. ```setDMPstartAddress``` does this for you.
Expand Down Expand Up @@ -116,11 +122,21 @@ INV_ICM20948_SENSOR_LINEAR_ACCELERATION (16-bit accel + 32-bit 6-axis qu
INV_ICM20948_SENSOR_ORIENTATION (32-bit 9-axis quaternion + heading accuracy)
```

## The DMP examples are verbose. Is that deliberate?

Yes, it certainly is! As you can tell from the examples, we are still gaining experience with the DMP. We have _deliberately_ written the examples so you can follow each step as the DMP is configured.

At some point in the future, we may hide the DMP configuration in a separate function. But, for now, you get to see the full configuration, warts and all!
## What changes did you make in v1.2.5?

In v1.2.5 we added some critical missing configuration steps:
- We use I2C_SLV0 and I2C_SLV1 to request the magnetometer data and trigger the next Single Measurement. We no longer use the 100Hz continuous mode for the DMP
- We now read ten bytes of data from the magnetometer, starting at register 0x03; instead of reading nine bytes, starting at register 0x10
- Register 0x03 is reserved and the other nine registers are undocumented. They appear to contain the raw magnetometer reading in big-endian format (instead of little-endian)
- We had to dig deep into InvenSense's Icm20948AuxCompassAkm.c to find this out...
- We configure the I2C Master ODR which reduces the magnetometer read rate from a silly 1100Hz to a sensible 69Hz
- We had to monitor the Aux I2C pins and study the AK09916 traffic to figure this out...

The DMP configuration code was becoming so verbose that we decided to move it into its own function called ```initializeDMP```. This is a weak function which you can overwrite
e.g. if you want to change the sample rate
(see [Example10](https://github.com/sparkfun/SparkFun_ICM-20948_ArduinoLibrary/blob/master/examples/Arduino/Example10_DMP_FastMultipleSensors/Example10_DMP_FastMultipleSensors.ino) for details).
```initializeDMP``` does most of the heavy lifting for you: it downloads the DMP firmware; and configures all of the registers with the appropriate values. The only things
you need to do manually are: select which DMP sensors to enable; reset and start both FIFO and DMP. Please see the revised DMP examples for more details.

## Where are the DMP registers defined?

Expand Down
Loading

0 comments on commit 8341270

Please sign in to comment.