Master Thesis  V1.0
Research and Design of Sensor Node for NMSD Treatment
ICM20948.c File Reference

Advanced funcions to control and read data from the ICM-20948. More...

#include "ICM20948.h"
#include "em_device.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_usart.h"
#include "debug_dbprint.h"
#include "delay.h"
#include <stdint.h>
#include "pinout.h"
#include "timer.h"
#include "I2C.h"
#include "em_i2c.h"
#include "i2cspm.h"
#include "em_core.h"
#include "em_wdog.h"
#include "rtcdriver.h"
#include "em_rtc.h"
#include "bsp.h"
Include dependency graph for ICM20948.c:

Go to the source code of this file.

Macros

#define M_PI   3.14159265358979323846
 

Functions

void ICM_20948_Init ()
 Init function for ICM20948. More...
 
void ICM_20948_Init2 ()
 Second init function for ICM20948, use when waking from sleep. More...
 
void ICM_20948_Init_SPI ()
 Initiate SPI functionality for ICM20948. More...
 
void ICM_20948_enable_SPI (bool enable)
 Enables the necessary SPI interface to communicate with ICM20948. More...
 
void ICM_20948_power (bool enable)
 Turns the GPIO pin high to provide power to the ICM20948. More...
 
void ICM_20948_printAllData ()
 Print all gyro + accel + magn data using dbprint. More...
 
void ICM_20948_check_WhoAmI ()
 Check WhoAmI register of ICM20948. More...
 
void ICM_20948_chipSelectSet (bool enable)
 Set chipselect pin for SPI functionality. More...
 
void ICM_20948_bankSelect (uint8_t bank)
 Select appropriate bank in ICM20948 based on first bits of address. More...
 
uint8_t ICM_20948_read (uint16_t addr)
 Read single register from IMU using SPI. More...
 
void ICM_20948_registerRead (uint16_t addr, int numBytes, uint8_t *data)
 Read registers from IMU. More...
 
void ICM_20948_registerWrite (uint16_t addr, uint8_t data)
 Writes registers from IMU. More...
 
uint32_t ICM_20948_sleepModeEnable (bool enable)
 Sleep mode enable function. More...
 
uint32_t ICM_20948_reset (void)
 Reset IMU. More...
 
uint32_t ICM_20948_gyroDataRead (float *gyro)
 Read gyroscope data from IMU. More...
 
uint32_t ICM_20948_gyroResolutionGet (float *gyroRes)
 Set gyro resolution. More...
 
uint32_t ICM_20948_interruptStatusRead (uint32_t *intStatus)
 Read staus of interrupt IMU. More...
 
uint32_t ICM_20948_interruptEnable (bool dataReadyEnable, bool womEnable)
 Enable interrupt for data ready or wake on motion. More...
 
uint32_t ICM_20948_sampleRateSet (float sampleRate)
 Combination function to set sample rate of gyro and accel at once. More...
 
float ICM_20948_gyroSampleRateSet (float sampleRate)
 Sets the gyro sample rate. More...
 
float ICM_20948_accelSampleRateSet (float sampleRate)
 Sets the accelerometer sample rate. More...
 
uint32_t ICM_20948_lowPowerModeEnter (bool enAccel, bool enGyro, bool enTemp)
 Enter low power mode for selected sensors. More...
 
uint32_t ICM_20948_sensorEnable (bool accel, bool gyro, bool temp)
 Enable selected sensors. More...
 
uint32_t ICM_20948_cycleModeEnable (bool enable)
 Enable cycle mode on IMU. More...
 
uint32_t ICM_20948_accelDataRead (float *accel)
 Read RAW accelerometer data. More...
 
uint32_t ICM_20948_accelResolutionGet (float *accelRes)
 Get accelerometer resultion. More...
 
uint32_t ICM_20948_accelFullscaleSet (uint8_t accelFs)
 Set accelerometer full scale range. More...
 
uint32_t ICM_20948_gyroFullscaleSet (uint8_t gyroFs)
 Set gyroscope full scale range. More...
 
uint32_t ICM_20948_wakeOnMotionITEnable (bool enable, uint8_t womThreshold, float sampleRate)
 Set wake on motion interrupt. More...
 
uint32_t ICM_20948_gyroBandwidthSet (uint8_t gyroBw)
 Set gyroscope bandwidth. More...
 
uint32_t ICM_20948_accelBandwidthSet (uint8_t accelBw)
 Set acceleromter bandwidth. More...
 
uint32_t ICM_20948_latchEnable (bool enable)
 Enables / disables the 50 micro seconds interrupt pin functionality. More...
 
void ICM_20948_set_mag_transfer (bool read)
 Set magnetometer data transfer on integrated I2C controller inside ICM20948. More...
 
void waitForSlave4 ()
 Wait for I2C slave (internal I2C controller on ICM20948) More...
 
unsigned char readMagRegister (unsigned char magreg)
 Read magnetometer register from I2C controller in ICM20948. More...
 
void writeMagRegister (unsigned char magreg, unsigned char val)
 Write magnetometer register using internal I2C interface on ICM20948. More...
 
void ICM_20948_read_mag_register (uint8_t addr, uint8_t numBytes, uint8_t *data)
 Read register in the AK09916 magnetometer device. More...
 
void ICM_20948_write_mag_register (uint8_t addr, uint8_t data)
 Writes a uint8_t to the I2C address of the magnetometer of the ICM_20948. More...
 
uint32_t ICM_20948_set_mag_mode (uint8_t magMode)
 Set magnetometer mode (sample rate / on-off) More...
 
void ICM_20948_magRawDataRead (float *raw_magn)
 Read magnetometer raw values. More...
 
void ICM_20948_magDataRead (float *magn)
 Convert raw magnetometer values to calibrated and scaled ones. More...
 
uint32_t ICM_20948_reset_mag (void)
 Reset magnetometer. More...
 
void ICM_20948_magn_to_angle (float *magn, float *angle)
 Test function for non-tilt compensated compass. More...
 
uint32_t ICM_20948_accelGyroCalibrate (float *accelBiasScaled, float *gyroBiasScaled)
 Accelerometer and gyroscope calibration function. Reads the gyroscope and accelerometer values while the device is at rest and in level. The resulting values are loaded to the accel and gyro bias registers to cancel the static offset error. More...
 
uint32_t ICM_20948_gyroCalibrate (float *gyroBiasScaled)
 Gyroscope calibration function. Reads the gyroscope values while the device is at rest and in level. The resulting values are loaded to the gyro bias registers to cancel the static offset error. More...
 
uint32_t ICM_20948_min_max_mag (int16_t *minMag, int16_t *maxMag)
 Calculate minimum and maximum magnetometer values, which are used for calibration. More...
 
bool ICM_20948_calibrate_mag (float *offset, float *scale)
 Magnetometer calibration function. Get magnetometer minimum and maximum values, while moving the device in a figure eight. Those values are then used to cancel out hard and soft iron distortions. More...
 

Variables

bool ICM_20948_Initialized = false
 
int32_t mag_minimumRange = 40
 
float mag_res = 4912.0f / 32752.0f
 
int16_t _hxcounts
 
int16_t _hycounts
 
int16_t _hzcounts
 
int16_t tX [3] = {1, 0, 0}
 
int16_t tY [3] = {0, -1, 0}
 
int16_t tZ [3] = {0, 0, -1}
 
float _hx
 
float _hy
 
float _hz
 
float accRawScaling = 32767.5f
 
float gyroRawScaling = 32767.5f
 
float magRawScaling = 32767.5f
 
float _magScale = (4912.0f) / (32767.5f)
 
bool IMU_MEASURING
 

Detailed Description

Advanced funcions to control and read data from the ICM-20948.

Partly copied from silabs thunderboard code for ICM-20689, partly self written

Version
1.0
Author
Jona Cappelle

Definition in file ICM20948.c.

Macro Definition Documentation

◆ M_PI

#define M_PI   3.14159265358979323846

Declaration of PI as a constant, used for conversion angle <--> rad

Definition at line 41 of file ICM20948.c.

Function Documentation

◆ ICM_20948_accelBandwidthSet()

uint32_t ICM_20948_accelBandwidthSet ( uint8_t  accelBw)

Set acceleromter bandwidth.

Parameters
[in]accelBwbandwidth, see datasheet for permitted values

Definition at line 1376 of file ICM20948.c.

1377 {
1378  uint8_t reg;
1379 
1380  /* Read the GYRO_CONFIG_1 register */
1382  reg &= ~(ICM_20948_MASK_ACCEL_BW);
1383 
1384  /* Write the new bandwidth value to the gyro config register */
1385  reg |= (accelBw & ICM_20948_MASK_ACCEL_BW);
1387 
1388  return ICM_20948_OK;
1389 }

References ICM_20948_MASK_ACCEL_BW, ICM_20948_OK, ICM_20948_REG_ACCEL_CONFIG, ICM_20948_registerRead(), and ICM_20948_registerWrite().

Referenced by ICM_20948_accelGyroCalibrate(), and ICM_20948_wakeOnMotionITEnable().

◆ ICM_20948_accelDataRead()

uint32_t ICM_20948_accelDataRead ( float *  accel)

Read RAW accelerometer data.

Parameters
[out]accelpointer to resulting memory locaion
Returns
OK when done

Definition at line 1170 of file ICM20948.c.

1171 {
1172  uint8_t rawData[6];
1173  float accelRes;
1174  int16_t temp;
1175 
1176  /* Retrieve the current resolution */
1177  ICM_20948_accelResolutionGet(&accelRes);
1178 
1179  /* Read the six raw data registers into data array */
1181 
1182  /* Convert the MSB and LSB into a signed 16-bit value and multiply by the resolution to get the G value */
1183  temp = ( (int16_t) rawData[0] << 8) | rawData[1];
1184  accel[0] = (float) temp * accelRes;
1185  temp = ( (int16_t) rawData[2] << 8) | rawData[3];
1186  accel[1] = (float) temp * accelRes;
1187  temp = ( (int16_t) rawData[4] << 8) | rawData[5];
1188  accel[2] = (float) temp * accelRes;
1189 
1190  return ICM_20948_OK;
1191 }

References ICM_20948_accelResolutionGet(), ICM_20948_OK, ICM_20948_REG_ACCEL_XOUT_H_SH, and ICM_20948_registerRead().

Referenced by measure_send().

◆ ICM_20948_accelFullscaleSet()

uint32_t ICM_20948_accelFullscaleSet ( uint8_t  accelFs)

Set accelerometer full scale range.

Parameters
[in]accelFsfull scale range, see datasheet for permitted values

Definition at line 1242 of file ICM20948.c.

1243 {
1244  uint8_t reg;
1245 
1246  accelFs &= ICM_20948_MASK_ACCEL_FULLSCALE;
1249  reg |= accelFs;
1251 
1252  return ICM_20948_OK;
1253 }

References ICM_20948_MASK_ACCEL_FULLSCALE, ICM_20948_OK, ICM_20948_REG_ACCEL_CONFIG, ICM_20948_registerRead(), and ICM_20948_registerWrite().

Referenced by ICM_20948_accelGyroCalibrate(), ICM_20948_Init2(), and ICM_20948_wakeOnMotionITEnable().

◆ ICM_20948_accelGyroCalibrate()

uint32_t ICM_20948_accelGyroCalibrate ( float *  accelBiasScaled,
float *  gyroBiasScaled 
)

Accelerometer and gyroscope calibration function. Reads the gyroscope and accelerometer values while the device is at rest and in level. The resulting values are loaded to the accel and gyro bias registers to cancel the static offset error.

Parameters
[out]accelBiasScaledThe mesured acceleration sensor bias in mg
[out]gyroBiasScaledThe mesured gyro sensor bias in deg/sec
Returns
Returns zero on OK, non-zero otherwise

Definition at line 1820 of file ICM20948.c.

1821 {
1822  uint8_t data[12];
1823  uint16_t i, packetCount, fifoCount;
1824  int32_t gyroBias[3] = { 0, 0, 0 };
1825  int32_t accelBias[3] = { 0, 0, 0 };
1826  int32_t accelTemp[3];
1827  int32_t gyroTemp[3];
1828  int32_t accelBiasFactory[3];
1829  int32_t gyroBiasStored[3];
1830  float gyroRes, accelRes;
1831 
1832  /* Enable the accelerometer and the gyro */
1833  ICM_20948_sensorEnable(true, true, false);
1834 
1835  /* Set 1kHz sample rate */
1836  ICM_20948_sampleRateSet(1100.0);
1837 
1838  /* 246Hz BW for the accelerometer and 200Hz for the gyroscope */
1841 
1842  /* Set the most sensitive range: 2G full scale and 250dps full scale */
1845 
1846  /* Retrieve the resolution per bit */
1847  ICM_20948_accelResolutionGet(&accelRes);
1848  ICM_20948_gyroResolutionGet(&gyroRes);
1849 
1850  /* The accel sensor needs max 30ms, the gyro max 35ms to fully start */
1851  /* Experiments show that the gyro needs more time to get reliable results */
1852  delay(50);
1853 
1854  /* Disable the FIFO */
1857 
1858  /* Enable accelerometer and gyro to store the data in FIFO */
1860 
1861  /* Reset the FIFO */
1864 
1865  /* Enable the FIFO */
1867 
1868  /* The max FIFO size is 4096 bytes, one set of measurements takes 12 bytes */
1869  /* (3 axes, 2 sensors, 2 bytes each value ) 340 samples use 4080 bytes of FIFO */
1870  /* Loop until at least 4080 samples gathered */
1871  fifoCount = 0;
1872  while ( fifoCount < 4080 ) {
1873  delay(5);
1874  /* Read FIFO sample count */
1876  /* Convert to a 16 bit value */
1877  fifoCount = ( (uint16_t) (data[0] << 8) | data[1]);
1878  }
1879 
1880  /* Disable accelerometer and gyro to store the data in FIFO */
1882 
1883  /* Read FIFO sample count */
1885 
1886  /* Convert to a 16 bit value */
1887  fifoCount = ( (uint16_t) (data[0] << 8) | data[1]);
1888 
1889  /* Calculate the number of data sets (3 axis of accel an gyro, two bytes each = 12 bytes) */
1890  packetCount = fifoCount / 12;
1891 
1892  /* Retrieve the data from the FIFO */
1893  for ( i = 0; i < packetCount; i++ ) {
1895  /* Convert to 16 bit signed accel and gyro x,y and z values */
1896  accelTemp[0] = ( (int16_t) (data[0] << 8) | data[1]);
1897  accelTemp[1] = ( (int16_t) (data[2] << 8) | data[3]);
1898  accelTemp[2] = ( (int16_t) (data[4] << 8) | data[5]);
1899  gyroTemp[0] = ( (int16_t) (data[6] << 8) | data[7]);
1900  gyroTemp[1] = ( (int16_t) (data[8] << 8) | data[9]);
1901  gyroTemp[2] = ( (int16_t) (data[10] << 8) | data[11]);
1902 
1903  /* Sum the values */
1904  accelBias[0] += accelTemp[0];
1905  accelBias[1] += accelTemp[1];
1906  accelBias[2] += accelTemp[2];
1907  gyroBias[0] += gyroTemp[0];
1908  gyroBias[1] += gyroTemp[1];
1909  gyroBias[2] += gyroTemp[2];
1910  }
1911 
1912  /* Divide by packet count to get the average */
1913  accelBias[0] /= packetCount;
1914  accelBias[1] /= packetCount;
1915  accelBias[2] /= packetCount;
1916  gyroBias[0] /= packetCount;
1917  gyroBias[1] /= packetCount;
1918  gyroBias[2] /= packetCount;
1919 
1920  /* Acceleormeter: add or remove (depending on the orientation of the chip) 1G (gravity) from the Z axis value */
1921  if ( accelBias[2] > 0L ) {
1922  accelBias[2] -= (int32_t) (1.0 / accelRes);
1923  } else {
1924  accelBias[2] += (int32_t) (1.0 / accelRes);
1925  }
1926 
1927  /* Convert the values to degrees per sec for displaying */
1928  gyroBiasScaled[0] = (float) gyroBias[0] * gyroRes;
1929  gyroBiasScaled[1] = (float) gyroBias[1] * gyroRes;
1930  gyroBiasScaled[2] = (float) gyroBias[2] * gyroRes;
1931 
1932  /* Read stored gyro trim values. After reset these values are all 0 */
1934  gyroBiasStored[0] = ( (int16_t) (data[0] << 8) | data[1]);
1936  gyroBiasStored[1] = ( (int16_t) (data[0] << 8) | data[1]);
1938  gyroBiasStored[2] = ( (int16_t) (data[0] << 8) | data[1]);
1939 
1940  /* The gyro bias should be stored in 1000dps full scaled format. We measured in 250dps to get */
1941  /* the best sensitivity, so need to divide by 4 */
1942  /* Substract from the stored calibration value */
1943  gyroBiasStored[0] -= gyroBias[0] / 4;
1944  gyroBiasStored[1] -= gyroBias[1] / 4;
1945  gyroBiasStored[2] -= gyroBias[2] / 4;
1946 
1947  /* Split the values into two bytes */
1948  data[0] = (gyroBiasStored[0] >> 8) & 0xFF;
1949  data[1] = (gyroBiasStored[0]) & 0xFF;
1950  data[2] = (gyroBiasStored[1] >> 8) & 0xFF;
1951  data[3] = (gyroBiasStored[1]) & 0xFF;
1952  data[4] = (gyroBiasStored[2] >> 8) & 0xFF;
1953  data[5] = (gyroBiasStored[2]) & 0xFF;
1954 
1955  /* Write the gyro bias values to the chip */
1962 
1963  /* Calculate the accelerometer bias values to store in the hardware accelerometer bias registers. These registers contain */
1964  /* factory trim values which must be added to the calculated accelerometer biases; on boot up these registers will hold */
1965  /* non-zero values. In addition, bit 0 of the lower byte must be preserved since it is used for temperature */
1966  /* compensation calculations(? the datasheet is not clear). Accelerometer bias registers expect bias input */
1967  /* as 2048 LSB per g, so that the accelerometer biases calculated above must be divided by 8. */
1968 
1969  /* Read factory accelerometer trim values */
1971  accelBiasFactory[0] = ( (int16_t) (data[0] << 8) | data[1]);
1973  accelBiasFactory[1] = ( (int16_t) (data[0] << 8) | data[1]);
1975  accelBiasFactory[2] = ( (int16_t) (data[0] << 8) | data[1]);
1976 
1977  /* Construct total accelerometer bias, including calculated average accelerometer bias from above */
1978  /* Scale the 2g full scale (most sensitive range) results to 16g full scale - divide by 8 */
1979  /* Clear the last bit (temperature compensation? - the datasheet is not clear) */
1980  /* Substract from the factory calibration value */
1981 
1982  accelBiasFactory[0] -= ( (accelBias[0] / 8) & ~1);
1983  accelBiasFactory[1] -= ( (accelBias[1] / 8) & ~1);
1984  accelBiasFactory[2] -= ( (accelBias[2] / 8) & ~1);
1985 
1986  /* Split the values into two bytes */
1987  data[0] = (accelBiasFactory[0] >> 8) & 0xFF;
1988  data[1] = (accelBiasFactory[0]) & 0xFF;
1989  data[2] = (accelBiasFactory[1] >> 8) & 0xFF;
1990  data[3] = (accelBiasFactory[1]) & 0xFF;
1991  data[4] = (accelBiasFactory[2] >> 8) & 0xFF;
1992  data[5] = (accelBiasFactory[2]) & 0xFF;
1993 
1994  /* Store them in the accelerometer offset registers */
2001 
2002  /* Convert the values to G for displaying */
2003  accelBiasScaled[0] = (float) accelBias[0] * accelRes;
2004  accelBiasScaled[1] = (float) accelBias[1] * accelRes;
2005  accelBiasScaled[2] = (float) accelBias[2] * accelRes;
2006 
2007  /* Turn off FIFO */
2009 
2010  /* Disable all sensors */
2011  ICM_20948_sensorEnable(false, false, false);
2012 
2013  return ICM_20948_OK;
2014 }

References data, delay(), ICM_20948_ACCEL_BW_246HZ, ICM_20948_ACCEL_FULLSCALE_2G, ICM_20948_accelBandwidthSet(), ICM_20948_accelFullscaleSet(), ICM_20948_accelResolutionGet(), ICM_20948_BIT_ACCEL_FIFO_EN, ICM_20948_BIT_FIFO_EN, ICM_20948_BITS_GYRO_FIFO_EN, ICM_20948_GYRO_BW_12HZ, ICM_20948_GYRO_FULLSCALE_250DPS, ICM_20948_gyroBandwidthSet(), ICM_20948_gyroFullscaleSet(), ICM_20948_gyroResolutionGet(), ICM_20948_OK, ICM_20948_REG_FIFO_COUNT_H, ICM_20948_REG_FIFO_EN_2, ICM_20948_REG_FIFO_MODE, ICM_20948_REG_FIFO_R_W, ICM_20948_REG_FIFO_RST, ICM_20948_REG_USER_CTRL, ICM_20948_REG_XA_OFFSET_H, ICM_20948_REG_XA_OFFSET_L, ICM_20948_REG_XG_OFFS_USRH, ICM_20948_REG_XG_OFFS_USRL, ICM_20948_REG_YA_OFFSET_H, ICM_20948_REG_YA_OFFSET_L, ICM_20948_REG_YG_OFFS_USRH, ICM_20948_REG_YG_OFFS_USRL, ICM_20948_REG_ZA_OFFSET_H, ICM_20948_REG_ZA_OFFSET_L, ICM_20948_REG_ZG_OFFS_USRH, ICM_20948_REG_ZG_OFFS_USRL, ICM_20948_registerRead(), ICM_20948_registerWrite(), ICM_20948_sampleRateSet(), and ICM_20948_sensorEnable().

Referenced by ICM_20948_Init().

◆ ICM_20948_accelResolutionGet()

uint32_t ICM_20948_accelResolutionGet ( float *  accelRes)

Get accelerometer resultion.

Parameters
[out]accelRespointer to accelerometer resulution

Definition at line 1202 of file ICM20948.c.

1203 {
1204  uint8_t reg;
1205 
1206  /* Read the actual acceleration full scale setting */
1209 
1210  /* Calculate the resolution */
1211  switch ( reg ) {
1213  *accelRes = 2.0 / 32768.0;
1214  break;
1215 
1217  *accelRes = 4.0 / 32768.0;
1218  break;
1219 
1221  *accelRes = 8.0 / 32768.0;
1222  break;
1223 
1225  *accelRes = 16.0 / 32768.0;
1226  break;
1227  }
1228 
1229  return ICM_20948_OK;
1230 }

References ICM_20948_ACCEL_FULLSCALE_16G, ICM_20948_ACCEL_FULLSCALE_2G, ICM_20948_ACCEL_FULLSCALE_4G, ICM_20948_ACCEL_FULLSCALE_8G, ICM_20948_MASK_ACCEL_FULLSCALE, ICM_20948_OK, ICM_20948_REG_ACCEL_CONFIG, and ICM_20948_registerRead().

Referenced by ICM_20948_accelDataRead(), and ICM_20948_accelGyroCalibrate().

◆ ICM_20948_accelSampleRateSet()

float ICM_20948_accelSampleRateSet ( float  sampleRate)

Sets the accelerometer sample rate.

will automatically calculate a sample rate that fits the sample rate divider register

Parameters
[in/out]sampleRate desired sample rate
Returns
the actual sample rate

Definition at line 988 of file ICM20948.c.

989 {
990  uint16_t accelDiv;
991  float accelSampleRate;
992 
993  /* Calculate the sample rate divider */
994  accelSampleRate = (1125.0 / sampleRate) - 1.0;
995 
996  /* Check if it fits in the divider registers */
997  if ( accelSampleRate > 4095.0 ) {
998  accelSampleRate = 4095.0;
999  }
1000 
1001  if ( accelSampleRate < 0 ) {
1002  accelSampleRate = 0.0;
1003  }
1004 
1005  /* Write the value to the registers */
1006  accelDiv = (uint16_t) accelSampleRate;
1007  ICM_20948_registerWrite(ICM_20948_REG_ACCEL_SMPLRT_DIV_1, (uint8_t) (accelDiv >> 8) );
1008  ICM_20948_registerWrite(ICM_20948_REG_ACCEL_SMPLRT_DIV_2, (uint8_t) (accelDiv & 0xFF) );
1009 
1010  /* Calculate the actual sample rate from the divider value */
1011  accelSampleRate = 1125.0 / (accelDiv + 1);
1012 
1013  return accelSampleRate;
1014 }

References ICM_20948_REG_ACCEL_SMPLRT_DIV_1, ICM_20948_REG_ACCEL_SMPLRT_DIV_2, and ICM_20948_registerWrite().

Referenced by ICM_20948_sampleRateSet().

◆ ICM_20948_bankSelect()

void ICM_20948_bankSelect ( uint8_t  bank)

Select appropriate bank in ICM20948 based on first bits of address.

Note
Works only with I2C

wBuffer[0] = ICM_20948_REG_BANK_SEL; wBuffer[1] = (bank << 4);

Parameters
[in]bankRegister to be read

Definition at line 528 of file ICM20948.c.

529 {
530  uint8_t wBuffer[2];
531  wBuffer[0] = ICM_20948_REG_BANK_SEL;
532  wBuffer[1] = (bank << 4);
533 
535 }

References ICM_20948_I2C_ADDRESS, ICM_20948_REG_BANK_SEL, and IIC_WriteBuffer().

Referenced by ICM_20948_read(), ICM_20948_registerRead(), and ICM_20948_registerWrite().

◆ ICM_20948_calibrate_mag()

bool ICM_20948_calibrate_mag ( float *  offset,
float *  scale 
)

Magnetometer calibration function. Get magnetometer minimum and maximum values, while moving the device in a figure eight. Those values are then used to cancel out hard and soft iron distortions.

Magnetometer calibration function. Get magnetometer minimum and maximum values, while moving the device in a figure eight. Those values are then used to cancel out hard and soft iron distortions.

Parameters
[out]offsetMagnetometer XYZ axis hard iron distortion correction.
[out]scaleMagnetometer XYZ axis soft iron distortion correction.
Returns
'true' if successful, 'false' on error.

Definition at line 2289 of file ICM20948.c.

2289  {
2290  int16_t minMag[3];
2291  int16_t maxMag[3];
2292  int32_t sum_mx, sum_my, sum_mz;
2293  int32_t dif_mx, dif_my, dif_mz, dif_m;
2294 
2295 // /* Reset hard and soft iron correction before calibration. */
2296  _hxb = 0.0f;
2297  _hyb = 0.0f;
2298  _hzb = 0.0f;
2299  _hxs = 1.0f;
2300  _hys = 1.0f;
2301  _hzs = 1.0f;
2302 
2303 // DEBUG_PRINTLN(F("Calibrating magnetometer. Move the device in a figure eight ..."));
2304 
2305  ICM_20948_min_max_mag( minMag, maxMag );
2306 
2307  sum_mx = (int32_t) maxMag[0] + minMag[0];
2308  sum_my = (int32_t) maxMag[1] + minMag[1];
2309  sum_mz = (int32_t) maxMag[2] + minMag[2];
2310 
2311  dif_mx = (int32_t) maxMag[0] - minMag[0];
2312  dif_my = (int32_t) maxMag[1] - minMag[1];
2313  dif_mz = (int32_t) maxMag[2] - minMag[2];
2314 
2315  offset[0] = -0.5f * sum_mx;
2316  offset[1] = -0.5f * sum_my;
2317  offset[2] = -0.5f * sum_mz;
2318 
2319  dif_m = (dif_mx + dif_my + dif_mz) / 3;
2320 
2321  scale[0] = (float) dif_m / dif_mx;
2322  scale[1] = (float) dif_m / dif_my;
2323  scale[2] = (float) dif_m / dif_mz;
2324 
2325 // Store offset values in local variables, to be accessable by magread functions
2326  _hxb = offset[0];
2327  _hyb = offset[1];
2328  _hzb = offset[2];
2329 
2330  _hxs = scale[0];
2331  _hys = scale[1];
2332  _hzs = scale[2];
2333 
2334 
2335 // DEBUG_PRINTLN(F("Hard iron correction values (center values):"));
2336 // DEBUG_PRINT2(offset_mx, 1);
2337 // DEBUG_PRINT("\t");
2338 // DEBUG_PRINT2(offset_my, 1);
2339 // DEBUG_PRINT("\t");
2340 // DEBUG_PRINT2(offset_mz, 1);
2341 // DEBUG_PRINT("\t");
2342 // DEBUG_PRINTLN();
2343 //
2344 // DEBUG_PRINTLN(F("Soft iron correction values (scale values):"));
2345 // DEBUG_PRINT2(scale_mx, 4);
2346 // DEBUG_PRINT("\t");
2347 // DEBUG_PRINT2(scale_my, 4);
2348 // DEBUG_PRINT("\t");
2349 // DEBUG_PRINT2(scale_mz, 4);
2350 // DEBUG_PRINTLN();
2351 
2352  return true;
2353 }

Referenced by ICM_20948_Init().

◆ ICM_20948_check_WhoAmI()

void ICM_20948_check_WhoAmI ( )

Check WhoAmI register of ICM20948.

Note
Hangs when WhoAmI is not found or is not correct

Definition at line 459 of file ICM20948.c.

460 {
461  uint8_t WhoAmI;
462  while( WhoAmI != 0xEA )
463  {
464  WhoAmI = ICM_20948_read( ICM_20948_BANK_0 | 0x00 );
465  }
466 }

References ICM_20948_BANK_0, and ICM_20948_read().

◆ ICM_20948_chipSelectSet()

void ICM_20948_chipSelectSet ( bool  enable)

Set chipselect pin for SPI functionality.

Only when using SPI

Parameters
[in]enable
  • 'true' - CS pin high
  • 'false' - CS pin low

Definition at line 480 of file ICM20948.c.

481 {
482  if ( enable )
483  {
484  /* Set CS low (active low) to start transmission */
485  GPIO_PinOutClear(ICM_20948_CS_PORT, ICM_20948_CS_PIN);
486  }
487  else
488  {
489  /* Set CS high (active low) */
490  GPIO_PinOutSet(ICM_20948_CS_PORT, ICM_20948_CS_PIN);
491  }
492 }

References ICM_20948_CS_PIN, and ICM_20948_CS_PORT.

Referenced by ICM_20948_read().

◆ ICM_20948_cycleModeEnable()

uint32_t ICM_20948_cycleModeEnable ( bool  enable)

Enable cycle mode on IMU.

Parameters
[in/out]enable
  • 'true' - enable cycle mode
  • 'false' - disable cycle mode

Definition at line 1142 of file ICM20948.c.

1143 {
1144  uint8_t reg;
1145 
1146  reg = 0x00;
1147 
1148  if ( enable ) {
1150  }
1151 
1153 
1154  return ICM_20948_OK;
1155 }

References ICM_20948_BIT_ACCEL_CYCLE, ICM_20948_BIT_GYRO_CYCLE, ICM_20948_OK, ICM_20948_REG_LP_CONFIG, and ICM_20948_registerWrite().

Referenced by ICM_20948_lowPowerModeEnter(), and ICM_20948_wakeOnMotionITEnable().

◆ ICM_20948_enable_SPI()

void ICM_20948_enable_SPI ( bool  enable)

Enables the necessary SPI interface to communicate with ICM20948.

Note
SPI can draw some power
SPI is not used
By setting the GPIO's to 0 state when going to sleep 150 micro A <--> 270 micro A
Parameters
[in]enable
  • true - Enable SPI communication.
  • false - Disable SPI communication.

Definition at line 344 of file ICM20948.c.

345 {
346  if (enable)
347  {
348  /* Enable USART clock and peripheral */
349  CMU_ClockEnable(cmuClock_USART0, true);
350 
351  USART_Enable(USART0, usartEnable);
352 
353  /* Configure GPIO */
354  /* In the case of gpioModePushPull", the last argument directly sets the pin state */
355  GPIO_PinModeSet(ICM_20948_CLK_PORT, ICM_20948_CLK_PIN, gpioModePushPull, 0); // US0_CLK is push pull
356  /* Normally this is gpioPortE: pin 13 */
357  /* Apparently, can't use the US0_CS port (PE13) to manually set/clear CS line */
358  GPIO_PinModeSet(ICM_20948_CS_PORT, ICM_20948_CS_PIN, gpioModePushPull, 1); // US0_CS is push pull
359  GPIO_PinModeSet(ICM_20948_MISO_PORT, ICM_20948_MISO_PIN, gpioModeInput, 1); // US0_RX (MISO) is input
360  GPIO_PinModeSet(ICM_20948_MOSI_PORT, ICM_20948_MOSI_PIN, gpioModePushPull, 1); // US0_TX (MOSI) is push pull
361  }
362  else
363  {
364  /* Disable USART clock and peripheral */
365  CMU_ClockEnable(cmuClock_USART0, false);
366 
367  USART_Enable(USART0, usartDisable);
368 
369  /* Configure GPIO */
370  /* In the case of gpioModePushPull", the last argument directly sets the pin state */
371  GPIO_PinModeSet(ICM_20948_CLK_PORT, ICM_20948_CLK_PIN, gpioModeDisabled, 0); // US0_CLK is push pull
372  /* Normally this is gpioPortE: pin 13 */
373  /* Apparently, can't use the US0_CS port (PE13) to manually set/clear CS line */
374  GPIO_PinModeSet(ICM_20948_CS_PORT, ICM_20948_CS_PIN, gpioModeDisabled, 1); // US0_CS is push pull
375  GPIO_PinModeSet(ICM_20948_MISO_PORT, ICM_20948_MISO_PIN, gpioModeDisabled, 1); // US0_RX (MISO) is input
376  GPIO_PinModeSet(ICM_20948_MOSI_PORT, ICM_20948_MOSI_PIN, gpioModeDisabled, 1); // US0_TX (MOSI) is push pull
377 
378  }
379 }

References ICM_20948_CLK_PIN, ICM_20948_CLK_PORT, ICM_20948_CS_PIN, ICM_20948_CS_PORT, ICM_20948_MISO_PIN, ICM_20948_MISO_PORT, ICM_20948_MOSI_PIN, and ICM_20948_MOSI_PORT.

◆ ICM_20948_gyroBandwidthSet()

uint32_t ICM_20948_gyroBandwidthSet ( uint8_t  gyroBw)

Set gyroscope bandwidth.

Parameters
[in]gyroBwbandwidth, see datasheet for permitted values

Definition at line 1352 of file ICM20948.c.

1353 {
1354  uint8_t reg;
1355 
1356  /* Read the GYRO_CONFIG_1 register */
1358  reg &= ~(ICM_20948_MASK_GYRO_BW);
1359 
1360  /* Write the new bandwidth value to the gyro config register */
1361  reg |= (gyroBw & ICM_20948_MASK_GYRO_BW);
1363 
1364  return ICM_20948_OK;
1365 }

References ICM_20948_MASK_GYRO_BW, ICM_20948_OK, ICM_20948_REG_GYRO_CONFIG_1, ICM_20948_registerRead(), and ICM_20948_registerWrite().

Referenced by ICM_20948_accelGyroCalibrate(), and ICM_20948_gyroCalibrate().

◆ ICM_20948_gyroCalibrate()

uint32_t ICM_20948_gyroCalibrate ( float *  gyroBiasScaled)

Gyroscope calibration function. Reads the gyroscope values while the device is at rest and in level. The resulting values are loaded to the gyro bias registers to cancel the static offset error.

Parameters
[out]gyroBiasScaledThe mesured gyro sensor bias in deg/sec
Returns
Returns zero on OK, non-zero otherwise

Definition at line 2031 of file ICM20948.c.

2032 {
2033  uint8_t data[12];
2034  uint16_t i, packetCount, fifoCount;
2035  int32_t gyroBias[3] = { 0, 0, 0 };
2036  int32_t gyroTemp[3];
2037  int32_t gyroBiasStored[3];
2038  float gyroRes;
2039 
2040  /* Enable the accelerometer and the gyro */
2041  ICM_20948_sensorEnable(true, true, false);
2042 
2043  /* Set 1kHz sample rate */
2044  ICM_20948_sampleRateSet(1100.0);
2045 
2046  /* Configure bandwidth for gyroscope to 12Hz */
2048 
2049  /* Configure sensitivity to 250dps full scale */
2051 
2052  /* Retrieve the resolution per bit */
2053  ICM_20948_gyroResolutionGet(&gyroRes);
2054 
2055  /* The accel sensor needs max 30ms, the gyro max 35ms to fully start */
2056  /* Experiments show that the gyro needs more time to get reliable results */
2057  delay(50);
2058 
2059  /* Disable the FIFO */
2062 
2063  /* Enable accelerometer and gyro to store the data in FIFO */
2065 
2066  /* Reset the FIFO */
2069 
2070  /* Enable the FIFO */
2072 
2073  /* The max FIFO size is 4096 bytes, one set of measurements takes 12 bytes */
2074  /* (3 axes, 2 sensors, 2 bytes each value ) 340 samples use 4080 bytes of FIFO */
2075  /* Loop until at least 4080 samples gathered */
2076  fifoCount = 0;
2077  while ( fifoCount < 4080 ) {
2078  delay(5);
2079 
2080  /* Read FIFO sample count */
2082 
2083  /* Convert to a 16 bit value */
2084  fifoCount = ( (uint16_t) (data[0] << 8) | data[1]);
2085  }
2086 
2087  /* Disable accelerometer and gyro to store the data in FIFO */
2089 
2090  /* Read FIFO sample count */
2092 
2093  /* Convert to a 16 bit value */
2094  fifoCount = ( (uint16_t) (data[0] << 8) | data[1]);
2095 
2096  /* Calculate the number of data sets (3 axis of accel an gyro, two bytes each = 12 bytes) */
2097  packetCount = fifoCount / 12;
2098 
2099  /* Retrieve the data from the FIFO */
2100  for ( i = 0; i < packetCount; i++ ) {
2102  /* Convert to 16 bit signed accel and gyro x,y and z values */
2103  gyroTemp[0] = ( (int16_t) (data[6] << 8) | data[7]);
2104  gyroTemp[1] = ( (int16_t) (data[8] << 8) | data[9]);
2105  gyroTemp[2] = ( (int16_t) (data[10] << 8) | data[11]);
2106 
2107  /* Sum the values */
2108  gyroBias[0] += gyroTemp[0];
2109  gyroBias[1] += gyroTemp[1];
2110  gyroBias[2] += gyroTemp[2];
2111  }
2112 
2113  /* Divide by packet count to get the average */
2114  gyroBias[0] /= packetCount;
2115  gyroBias[1] /= packetCount;
2116  gyroBias[2] /= packetCount;
2117 
2118  /* Convert the values to degrees per sec for displaying */
2119  gyroBiasScaled[0] = (float) gyroBias[0] * gyroRes;
2120  gyroBiasScaled[1] = (float) gyroBias[1] * gyroRes;
2121  gyroBiasScaled[2] = (float) gyroBias[2] * gyroRes;
2122 
2123  /* Read stored gyro trim values. After reset these values are all 0 */
2125  gyroBiasStored[0] = ( (int16_t) (data[0] << 8) | data[1]);
2126 
2128  gyroBiasStored[1] = ( (int16_t) (data[0] << 8) | data[1]);
2129 
2131  gyroBiasStored[2] = ( (int16_t) (data[0] << 8) | data[1]);
2132 
2133  /* The gyro bias should be stored in 1000dps full scaled format. We measured in 250dps to get */
2134  /* the best sensitivity, so need to divide by 4 */
2135  /* Substract from the stored calibration value */
2136  gyroBiasStored[0] -= gyroBias[0] / 4;
2137  gyroBiasStored[1] -= gyroBias[1] / 4;
2138  gyroBiasStored[2] -= gyroBias[2] / 4;
2139 
2140  /* Split the values into two bytes */
2141  data[0] = (gyroBiasStored[0] >> 8) & 0xFF;
2142  data[1] = (gyroBiasStored[0]) & 0xFF;
2143  data[2] = (gyroBiasStored[1] >> 8) & 0xFF;
2144  data[3] = (gyroBiasStored[1]) & 0xFF;
2145  data[4] = (gyroBiasStored[2] >> 8) & 0xFF;
2146  data[5] = (gyroBiasStored[2]) & 0xFF;
2147 
2148  /* Write the gyro bias values to the chip */
2155 
2156  /* Turn off FIFO */
2158 
2159  /* Disable all sensors */
2160  ICM_20948_sensorEnable(false, false, false);
2161 
2162  return ICM_20948_OK;
2163 }

References data, delay(), ICM_20948_BIT_FIFO_EN, ICM_20948_BITS_GYRO_FIFO_EN, ICM_20948_GYRO_BW_12HZ, ICM_20948_GYRO_FULLSCALE_250DPS, ICM_20948_gyroBandwidthSet(), ICM_20948_gyroFullscaleSet(), ICM_20948_gyroResolutionGet(), ICM_20948_OK, ICM_20948_REG_FIFO_COUNT_H, ICM_20948_REG_FIFO_EN_2, ICM_20948_REG_FIFO_MODE, ICM_20948_REG_FIFO_R_W, ICM_20948_REG_FIFO_RST, ICM_20948_REG_USER_CTRL, ICM_20948_REG_XG_OFFS_USRH, ICM_20948_REG_XG_OFFS_USRL, ICM_20948_REG_YG_OFFS_USRH, ICM_20948_REG_YG_OFFS_USRL, ICM_20948_REG_ZG_OFFS_USRH, ICM_20948_REG_ZG_OFFS_USRL, ICM_20948_registerRead(), ICM_20948_registerWrite(), ICM_20948_sampleRateSet(), and ICM_20948_sensorEnable().

◆ ICM_20948_gyroDataRead()

uint32_t ICM_20948_gyroDataRead ( float *  gyro)

Read gyroscope data from IMU.

Parameters
[out]gyropointer to store data

Definition at line 783 of file ICM20948.c.

784 {
785  uint8_t rawData[6];
786  float gyroRes;
787  int16_t temp;
788 
789  /* Retrieve the current resolution */
790  ICM_20948_gyroResolutionGet(&gyroRes);
791 
792  /* Read the six raw data registers into data array */
793  ICM_20948_registerRead(GYRO_XOUT_H, 6, &rawData[0]);
794 
795  /* Convert the MSB and LSB into a signed 16-bit value and multiply by the resolution to get the dps value */
796  temp = ( (int16_t) rawData[0] << 8) | rawData[1];
797  gyro[0] = (float) temp * gyroRes;
798  temp = ( (int16_t) rawData[2] << 8) | rawData[3];
799  gyro[1] = (float) temp * gyroRes;
800  temp = ( (int16_t) rawData[4] << 8) | rawData[5];
801  gyro[2] = (float) temp * gyroRes;
802 
803  return ICM_20948_OK;
804 }

References GYRO_XOUT_H, ICM_20948_gyroResolutionGet(), ICM_20948_OK, and ICM_20948_registerRead().

Referenced by measure_send().

◆ ICM_20948_gyroFullscaleSet()

uint32_t ICM_20948_gyroFullscaleSet ( uint8_t  gyroFs)

Set gyroscope full scale range.

Parameters
[in]gyroFsfull scale range, see datasheet for permitted values

Definition at line 1265 of file ICM20948.c.

1266 {
1267  uint8_t reg;
1268 
1272  reg |= gyroFs;
1274 
1275  return ICM_20948_OK;
1276 }

References ICM_20948_MASK_GYRO_FULLSCALE, ICM_20948_OK, ICM_20948_REG_GYRO_CONFIG_1, ICM_20948_registerRead(), and ICM_20948_registerWrite().

Referenced by ICM_20948_accelGyroCalibrate(), ICM_20948_gyroCalibrate(), and ICM_20948_Init2().

◆ ICM_20948_gyroResolutionGet()

uint32_t ICM_20948_gyroResolutionGet ( float *  gyroRes)

Set gyro resolution.

Parameters
[in/out]gyroRes gyro resulution input gyro actual resolution output

Definition at line 817 of file ICM20948.c.

818 {
819  uint8_t reg;
820 
821  /* Read the actual gyroscope full scale setting */
824 
825  /* Calculate the resolution */
826  switch ( reg ) {
828  *gyroRes = 250.0 / 32768.0;
829  break;
830 
832  *gyroRes = 500.0 / 32768.0;
833  break;
834 
836  *gyroRes = 1000.0 / 32768.0;
837  break;
838 
840  *gyroRes = 2000.0 / 32768.0;
841  break;
842  }
843 
844  return ICM_20948_OK;
845 }

References ICM_20948_GYRO_FULLSCALE_1000DPS, ICM_20948_GYRO_FULLSCALE_2000DPS, ICM_20948_GYRO_FULLSCALE_250DPS, ICM_20948_GYRO_FULLSCALE_500DPS, ICM_20948_MASK_GYRO_FULLSCALE, ICM_20948_OK, ICM_20948_REG_GYRO_CONFIG_1, and ICM_20948_registerRead().

Referenced by ICM_20948_accelGyroCalibrate(), ICM_20948_gyroCalibrate(), and ICM_20948_gyroDataRead().

◆ ICM_20948_gyroSampleRateSet()

float ICM_20948_gyroSampleRateSet ( float  sampleRate)

Sets the gyro sample rate.

will automatically calculate a sample rate that fits the sample rate divider register

Parameters
[in/out]sampleRate desired sample rate
Returns
the actual sample rate

Definition at line 947 of file ICM20948.c.

948 {
949  uint8_t gyroDiv;
950  float gyroSampleRate;
951 
952  /* Calculate the sample rate divider */
953  gyroSampleRate = (1125.0 / sampleRate) - 1.0;
954 
955  /* Check if it fits in the divider register */
956  if ( gyroSampleRate > 255.0 ) {
957  gyroSampleRate = 255.0;
958  }
959 
960  if ( gyroSampleRate < 0 ) {
961  gyroSampleRate = 0.0;
962  }
963 
964  /* Write the value to the register */
965  gyroDiv = (uint8_t) gyroSampleRate;
967 
968  /* Calculate the actual sample rate from the divider value */
969  gyroSampleRate = 1125.0 / (gyroDiv + 1);
970 
971  return gyroSampleRate;
972 }

References ICM_20948_REG_GYRO_SMPLRT_DIV, and ICM_20948_registerWrite().

Referenced by ICM_20948_sampleRateSet().

◆ ICM_20948_Init()

void ICM_20948_Init ( )

Init function for ICM20948.

I2C init Power on IMU Reset IMU Init 2 Calibrate Gyro + Accel Calibrate Magn

Definition at line 85 of file ICM20948.c.

86 {
87  /* Enable GPIO clock in order to set pin states */
88  CMU_ClockEnable(cmuClock_HFPER, true);
89  CMU_ClockEnable(cmuClock_GPIO, true);
90  delay(10);
91 
92  /* Setup SPI / IIC interface for ICM_20948 */
93  /* Comment / Uncomment to select */
94  //ICM_20948_Init_SPI();
95  IIC_Init();
96  delay(10);
97 
98  /* Power the ICM_20948 */
99  ICM_20948_power(true);
100  delay(200);
101 
102  /* Reset ICM_20948, just to be sure */
103  ICM_20948_reset();
104  delay(100); // 100ms delay needed for reset sequence
105 
106 
107  ICM_20948_Init2();
108 
109 
110 #if DIY == 0
111  BSP_LedSet(0);
112 #endif
113 
114  /* CALIBRATION */
116  float accelCal[3];
117  float gyroCal[3];
118  float magOffset[3];
119  float magScale[3];
120  ICM_20948_accelGyroCalibrate( accelCal, gyroCal );
122 
123 #if DIY == 0
124  BSP_LedClear(0);
125 #endif
126 
127 #if DIY == 0
128  BSP_LedSet(1);
129 #endif
130 
131  ICM_20948_Init2();
132 
134 #if DIY == 1
135  GPIO_PinModeSet(LED_PORT, LED_PIN, gpioModePushPull, 0);
136  GPIO_PinOutSet(LED_PORT, LED_PIN);
137 #endif
138  uint8_t temp[1];
140  delay(100);
141  ICM_20948_read_mag_register(0x31, 1, temp);
142  ICM_20948_read_mag_register(0x11, 8, temp);
143 
144  ICM_20948_calibrate_mag( magOffset, magScale );
145 
146 #if DIY == 1
147  GPIO_PinOutClear(LED_PORT, LED_PIN);
148  GPIO_PinModeSet(LED_PORT, LED_PIN, gpioModeDisabled, 0);
149 #endif
150 
152 #if DIY == 0
153  BSP_LedClear(1);
154 #endif
155 
156 
157 
158 
159  ICM_20948_Initialized = true;
160 }

References AK09916_MODE_100HZ, delay(), ICM_20948_accelGyroCalibrate(), ICM_20948_calibrate_mag(), ICM_20948_Init2(), ICM_20948_Initialized, ICM_20948_power(), ICM_20948_read_mag_register(), ICM_20948_reset(), ICM_20948_set_mag_mode(), IIC_Init(), LED_PIN, and LED_PORT.

◆ ICM_20948_Init2()

void ICM_20948_Init2 ( )

Second init function for ICM20948, use when waking from sleep.

Set sample rates, bandwidths, check whoAmI, enable sensors

Definition at line 169 of file ICM20948.c.

170 {
171 
172 
173  /* Auto select best available clock source PLL if ready, else use internal oscillator */
175  /* PLL startup time - no spec in data sheet */
176  delay(30);
177 
178  /* Reset I2C Slave module and use SPI */
179  /* Enable I2C Master I/F module */ /* ICM_20948_BIT_I2C_IF_DIS om te vermijden dat toch I2C zal gebruikt worden */
180  //ICM_20948_registerWrite(ICM_20948_REG_USER_CTRL, ICM_20948_BIT_I2C_MST_EN);//ICM_20948_BIT_I2C_IF_DIS | ICM_20948_BIT_I2C_MST_EN);
181 
182  /* Set I2C Master clock frequency */
183  //ICM_20948_registerWrite(ICM_20948_REG_I2C_MST_CTRL, ICM_20948_I2C_MST_CTRL_CLK_400KHZ);
184 
185  uint8_t temp[8];
186 
187  /* Read ICM20948 "Who am I" register */
189 
190  /* Check if "Who am I" register was successfully read */
191  if (temp[0] == ICM20948_DEVICE_ID) {
192  #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
193  dbprint("ICM20948 WHOAMI OKE");
194  #endif /* DEBUG_DBPRINT */
195 
196  }
197 
198 
199 
200  /* Make sure ICM_20948 is not in sleep mode */
201  ICM_20948_sleepModeEnable( false );
202 
203  /* Enable all ICM_20948 sensors */
204  ICM_20948_sensorEnable(true, true, true);
205  delay(10);
206 
207  /* Set ICM_20948 gyro and accel sample rate to 75Hz */
209 
210  /* Set full scale range: gyro & accel */
213 
214  /* Setup 50us interrupt */
215  ICM_20948_latchEnable(true);
216 
217  // TODO: Bandwidth gyro + accel
218  // Standard low pass filters are enabled
219 // ICM_20948_accelBandwidthSet( ICM_20948_ACCEL_BW_1210HZ );
220 // ICM_20948_gyroBandwidthSet( ICM_20948_GYRO_BW_120HZ );
221 
222  /* Auto select best available clock source PLL if ready, else use internal oscillator */
224  delay(30);
225 
226 
227  /* Magnetometer */
228  /* IIC passtrough: magnetometer can be accessed on IIC bus */
230  delay(10);
231 
232  /* Reset magnetometer */
233  ICM_20948_write_mag_register(0x32, 0x01);
234  delay(100); // reset takes 100ms
235 
236  /* Read AK09916 "Who am I" register */
238 
239  /* Check if AK09916 "Who am I" register was successfully read */
240  if (temp[0] == AK09916_DEVICE_ID) {
241  #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
242  dbprint("AK09916 WHOAMI OKE");
243  #endif /* DEBUG_DBPRINT */
244 
245  }
246 
247  /* Configure magnetometer */
249  delay(10);
250 
251  ICM_20948_read_mag_register(0x31, 1, temp);
252  /* Update data by reading through till ST2 register */
253  ICM_20948_read_mag_register(0x11, 8, temp);
254 
255 
256 
257 
258 
259  // /* Set interrupt to trigger every 100ms when the data is ready */
260  // IMU_MEASURING = true;
261  // ICM_20948_interruptEnable(true, false);
262 
263 }

References AK09916_DEVICE_ID, AK09916_MODE_50HZ, AK09916_REG_WHO_AM_I, dbprint(), delay(), ICM20948_DEVICE_ID, ICM_20948_ACCEL_FULLSCALE_4G, ICM_20948_accelFullscaleSet(), ICM_20948_BIT_CLK_PLL, ICM_20948_GYRO_FULLSCALE_2000DPS, ICM_20948_gyroFullscaleSet(), ICM_20948_latchEnable(), ICM_20948_read_mag_register(), ICM_20948_REG_INT_PIN_CFG, ICM_20948_REG_PWR_MGMT_1, ICM_20948_REG_WHO_AM_I, ICM_20948_registerRead(), ICM_20948_registerWrite(), ICM_20948_sampleRateSet(), ICM_20948_sensorEnable(), ICM_20948_set_mag_mode(), ICM_20948_sleepModeEnable(), and ICM_20948_write_mag_register().

Referenced by ICM_20948_Init().

◆ ICM_20948_Init_SPI()

void ICM_20948_Init_SPI ( )

Initiate SPI functionality for ICM20948.

Note
SPI not used

Definition at line 273 of file ICM20948.c.

274 {
275 
276  /*****************************/
277 
278  /* Enable necessary clocks */
279  CMU_ClockEnable(cmuClock_HFPER, true); /* GPIO and USART0/1 are High Frequency Peripherals */
280  CMU_ClockEnable(cmuClock_GPIO, true);
281  CMU_ClockEnable(cmuClock_USART0, true);
282 
283  /* Configure GPIO */
284  /* In the case of gpioModePushPull", the last argument directly sets the pin state */
285  GPIO_PinModeSet(ICM_20948_CLK_PORT, ICM_20948_CLK_PIN, gpioModePushPull, 0); // US0_CLK is push pull
286  /* Normally this is gpioPortE: pin 13 */
287  /* Apparently, can't use the US0_CS port (PE13) to manually set/clear CS line */
288  GPIO_PinModeSet(ICM_20948_CS_PORT, ICM_20948_CS_PIN, gpioModePushPull, 1); // US0_CS is push pull
289  GPIO_PinModeSet(ICM_20948_MISO_PORT, ICM_20948_MISO_PIN, gpioModeInput, 1); // US0_RX (MISO) is input
290  GPIO_PinModeSet(ICM_20948_MOSI_PORT, ICM_20948_MOSI_PIN, gpioModePushPull, 1); // US0_TX (MOSI) is push pull
291 
292  // Start with default config, then modify as necessary
293  USART_InitSync_TypeDef config = USART_INITSYNC_DEFAULT;
294  config.master = true; // master mode
295  //config.baudrate = 1000000; // CLK freq is 1 MHz
296  config.autoCsEnable = true; // CS pin controlled by hardware, not firmware
297  config.clockMode = usartClockMode0; // clock idle low, sample on rising/first edge
298  config.msbf = true; // send MSB first
299  config.enable = usartDisable; // making sure to keep USART disabled until we've set everything up
300 
301  /* Modify some settings */
302  config.clockMode = usartClockMode0; /* clock idle low, sample on rising/first edge (Clock polarity/phase mode = CPOL/CPHA) */
303  config.refFreq = 0; /* USART/UART reference clock assumed when configuring baud rate setup. Set to 0 to use the currently configured reference clock. */
304  config.baudrate = 4000000; // CLK freq is 4 MHz
305  config.databits = usartDatabits8; /* master mode */
306  config.autoTx = false; /* If enabled: Enable AUTOTX mode. Transmits as long as RX is not full. Generates underflows if TX is empty. */
307  config.autoCsEnable = false; /* CS pin controlled by hardware, not firmware */
308 
309  /* Initialize USART0/1 with the configured parameters */
310  USART_InitSync(USART0, &config);
311 
312  // Set and enable USART pin locations
313  USART0->ROUTE = USART_ROUTE_CLKPEN | USART_ROUTE_CSPEN | USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_LOC0;
314 
315  /* Enable USART0/1 */
316  USART_Enable(USART0, usartEnable);
317 
318  /* Set CS high (active low!) */
319  /* Normally this isn't needed, in the case of gpioModePushPull", the last argument directly sets the pin state */
320  GPIO_PinOutSet(gpioPortE, 13);
321 
322 
323  /*****************************/
324 }

References ICM_20948_CLK_PIN, ICM_20948_CLK_PORT, ICM_20948_CS_PIN, ICM_20948_CS_PORT, ICM_20948_MISO_PIN, ICM_20948_MISO_PORT, ICM_20948_MOSI_PIN, and ICM_20948_MOSI_PORT.

◆ ICM_20948_interruptEnable()

uint32_t ICM_20948_interruptEnable ( bool  dataReadyEnable,
bool  womEnable 
)

Enable interrupt for data ready or wake on motion.

Parameters
[in]dataReadyEnable
  • 'true' - enable
  • 'false' - disable
[in]womEnable
  • 'true' - enable
  • 'false' - disable

Definition at line 885 of file ICM20948.c.

886 {
887  uint8_t intEnable;
888 
889  /* All interrupts disabled by default */
890  intEnable = 0;
891 
892  /* Enable one or both of the interrupt sources if required */
893  if ( womEnable ) {
894  intEnable = ICM_20948_BIT_WOM_INT_EN;
895  }
896  /* Write value to register */
898 
899  /* All interrupts disabled by default */
900  intEnable = 0;
901 
902  if ( dataReadyEnable ) {
904  }
905 
906  /* Write value to register */
908 
909  return ICM_20948_OK;
910 }

References ICM_20948_BIT_RAW_DATA_0_RDY_EN, ICM_20948_BIT_WOM_INT_EN, ICM_20948_OK, ICM_20948_REG_INT_ENABLE, ICM_20948_REG_INT_ENABLE_1, and ICM_20948_registerWrite().

Referenced by CheckIMUidle(), and ICM_20948_wakeOnMotionITEnable().

◆ ICM_20948_interruptStatusRead()

uint32_t ICM_20948_interruptStatusRead ( uint32_t *  intStatus)

Read staus of interrupt IMU.

Parameters
[out]intStatuspointer to store status

Definition at line 857 of file ICM20948.c.

858 {
859  uint8_t reg[4];
860 
862  *intStatus = (uint32_t) reg[0];
863  *intStatus |= ( ( (uint32_t) reg[1]) << 8);
864  *intStatus |= ( ( (uint32_t) reg[2]) << 16);
865  *intStatus |= ( ( (uint32_t) reg[3]) << 24);
866 
867  return ICM_20948_OK;
868 }

References ICM_20948_OK, ICM_20948_REG_INT_STATUS, and ICM_20948_registerRead().

◆ ICM_20948_latchEnable()

uint32_t ICM_20948_latchEnable ( bool  enable)

Enables / disables the 50 micro seconds interrupt pin functionality.

Note
written myself, changes the whole register, maybe not so good...
Parameters
[in]enable
  • true - Enable 50 micro second interrupt.
  • false - INT1 pin level held until interrupt status is cleared.

Definition at line 1403 of file ICM20948.c.

1404 {
1405  uint8_t temp;
1407 
1408  if(enable)
1409  {
1410  /* Set interrupt pin to pulse, no need to read a interrupt register for proceeding */
1411  /* 1 � INT1 pin level held until interrupt status is cleared.
1412  * 0 � INT1 pin indicates interrupt pulse is width 50 us <----
1413  */
1415  //ICM_20948_registerWrite(ICM_20948_REG_INT_PIN_CFG, 0b00010000);
1416  }else{
1418  }
1419 
1420  return ICM_20948_OK;
1421 }

References ICM_20948_OK, ICM_20948_REG_INT_PIN_CFG, ICM_20948_registerRead(), and ICM_20948_registerWrite().

Referenced by ICM_20948_Init2().

◆ ICM_20948_lowPowerModeEnter()

uint32_t ICM_20948_lowPowerModeEnter ( bool  enAccel,
bool  enGyro,
bool  enTemp 
)

Enter low power mode for selected sensors.

Parameters
[in]enAccel
  • 'true' - go low power
  • 'false' - low noise mode
[in]enGyro
  • 'true' - go low power
  • 'false' - low noise mode
[in]enTemp
  • 'true' - go low power
  • 'false' - low noise mode
Returns
OK if successful

Definition at line 1037 of file ICM20948.c.

1038 {
1039  uint8_t data;
1040 
1042 
1043  if ( enAccel || enGyro || enTemp ) {
1044  /* Make sure that the chip is not in sleep */
1046 
1047  /* And in continuous mode */
1049 
1050  /* Enable the accelerometer and the gyroscope*/
1051  ICM_20948_sensorEnable(enAccel, enGyro, enTemp);
1052  delay(50);
1053 
1054  /* Enable cycle mode */
1056 
1057  /* Set the LP_EN bit to enable low power mode */
1059  } else {
1060  /* Enable continuous mode */
1062 
1063  /* Clear the LP_EN bit to disable low power mode */
1065  }
1066 
1067  /* Write the updated value to the PWR_MGNT_1 register */
1069 
1070  return ICM_20948_OK;
1071 }

References data, delay(), ICM_20948_BIT_LP_EN, ICM_20948_cycleModeEnable(), ICM_20948_OK, ICM_20948_REG_PWR_MGMT_1, ICM_20948_registerRead(), ICM_20948_registerWrite(), ICM_20948_sensorEnable(), and ICM_20948_sleepModeEnable().

Referenced by ICM_20948_wakeOnMotionITEnable().

◆ ICM_20948_magDataRead()

void ICM_20948_magDataRead ( float *  magn)

Convert raw magnetometer values to calibrated and scaled ones.

Parameters
[out]magncalibrated values in µT

Definition at line 1745 of file ICM20948.c.

1745  {
1746 
1747  uint8_t data[8];
1749 
1750  /* Convert the LSB and MSB into a signed 16-bit value */
1751  _hxcounts = (((int16_t) data[1] << 8) | data[0] );
1752  _hycounts = (((int16_t) data[3] << 8) | data[2] );
1753  _hzcounts = (((int16_t) data[5] << 8) | data[4] );
1754 
1755  magn[0] = (((float)(tX[0]*_hxcounts + tX[1]*_hycounts + tX[2]*_hzcounts) * _magScale) + _hxb)*_hxs;
1756  magn[1] = (((float)(tY[0]*_hxcounts + tY[1]*_hycounts + tY[2]*_hzcounts) * _magScale) + _hyb)*_hys;
1757  magn[2] = (((float)(tZ[0]*_hxcounts + tZ[1]*_hycounts + tZ[2]*_hzcounts) * _magScale) + _hzb)*_hzs;
1758 
1759 }

References _hxcounts, _hycounts, _hzcounts, _magScale, data, ICM_20948_read_mag_register(), and tX.

Referenced by ICM_20948_min_max_mag(), and measure_send().

◆ ICM_20948_magn_to_angle()

void ICM_20948_magn_to_angle ( float *  magn,
float *  angle 
)

Test function for non-tilt compensated compass.

Parameters
[in]magnmagnetometer values
[out]angleangle in degrees

Definition at line 1793 of file ICM20948.c.

1793  {
1794 
1795  angle[0] = atan2(magn[1], magn[0]) * M_PI/180.0f;
1796 
1797 }

References M_PI.

◆ ICM_20948_magRawDataRead()

void ICM_20948_magRawDataRead ( float *  raw_magn)

Read magnetometer raw values.

Note
To update values, read all the way through the registers
Parameters
[out]raw_magnoutput magnetometer raw values

Definition at line 1707 of file ICM20948.c.

1707  {
1708 
1709  uint8_t data[8];
1711 
1712  /* Convert the LSB and MSB into a signed 16-bit value */
1713  _hxcounts = (((int16_t) data[1] << 8) | data[0] );
1714  _hycounts = (((int16_t) data[3] << 8) | data[2] );
1715  _hzcounts = (((int16_t) data[5] << 8) | data[4] );
1716 
1717  /* Transform to same coordinate system as gyro & accel */
1718  raw_magn[0] = (float)(tX[0]*_hxcounts + tX[1]*_hycounts + tX[2]*_hzcounts);
1719  raw_magn[1] = (float)(tY[0]*_hxcounts + tY[1]*_hycounts + tY[2]*_hzcounts);
1720  raw_magn[2] = (float)(tZ[0]*_hxcounts + tZ[1]*_hycounts + tZ[2]*_hzcounts);
1721 
1722 #if DEBUG_DBPRINTs == 1 /* DEBUG_DBPRINT */
1723  dbprint("rawMag x: ");
1724  dbprintInt((int) raw_magn[0]);
1725  dbprint(" rawMag y: ");
1726  dbprintInt((int) raw_magn[1]);
1727  dbprint(" minMag z: ");
1728  dbprintInt((int) raw_magn[2]);
1729  dbprintln("");
1730 #endif /* DEBUG_DBPRINT */
1731 
1732 }

References _hxcounts, _hycounts, _hzcounts, data, dbprint(), dbprintInt(), dbprintln(), ICM_20948_read_mag_register(), tX, tY, and tZ.

◆ ICM_20948_min_max_mag()

uint32_t ICM_20948_min_max_mag ( int16_t *  minMag,
int16_t *  maxMag 
)

Calculate minimum and maximum magnetometer values, which are used for calibration.

Parameters
[out]minMagpointer to minima from each axis
[out]maxMagpointer to maxima from each axis
Returns
'OK' if successful, 'ERROR' on error.

Definition at line 2186 of file ICM20948.c.

2186  {
2187  float m[3];
2188 
2189  minMag[0] = 32767; // alles kleiner dan dit wordt het minimum, daar staat er hier geen '-'!
2190  minMag[1] = 32767;
2191  minMag[2] = 32767;
2192 
2193  maxMag[0] = -32768; // hier hetzelfde, starten met de kleinste waarde, dan aanpassen dat het groter en groter wordt tot het maximum gevonden wordt!
2194  maxMag[1] = -32768;
2195  maxMag[2] = -32768;
2196 
2197  uint32_t max_time = 15000;
2198  uint32_t t_start = millis();
2199 
2200  /* Flags for if axis mag_minimumRange is fulfilled */
2201  bool miniumRange_mx = false;
2202  bool miniumRange_my = false;
2203  bool miniumRange_mz = false;
2204 
2205 
2206  while (!miniumRange_mx || !miniumRange_my || !miniumRange_mz) {
2207  while ((millis() - t_start) < max_time) {
2208 
2209  /* read magnetometer measurement */
2210  ICM_20948_magDataRead( m );
2211 
2212  if (m[0] < minMag[0]) {
2213  minMag[0] = m[0];
2214  }
2215  if (m[0] > maxMag[0]) {
2216  maxMag[0] = m[0];
2217  }
2218 
2219  if (m[1] < minMag[1]) {
2220  minMag[1] = m[1];
2221  }
2222  if (m[1] > maxMag[1]) {
2223  maxMag[1] = m[1];
2224  }
2225 
2226  if (m[2] < minMag[2]) {
2227  minMag[2] = m[2];
2228  }
2229  if (m[2] > maxMag[2]) {
2230  maxMag[2] = m[2];
2231  }
2232 
2233  if ((maxMag[0] - minMag[0]) > mag_minimumRange) {
2234  miniumRange_mx = true;
2235  }
2236  if ((maxMag[1] - minMag[1]) > mag_minimumRange) {
2237  miniumRange_my = true;
2238  }
2239  if ((maxMag[2] - minMag[2]) > mag_minimumRange) {
2240  miniumRange_mz = true;
2241  }
2242 
2243 // DEBUG_PRINT(min_mx); DEBUG_PRINT("\t"); DEBUG_PRINT(min_my); DEBUG_PRINT("\t"); DEBUG_PRINTLN(min_mz);
2244 // DEBUG_PRINT(max_mx); DEBUG_PRINT("\t"); DEBUG_PRINT(max_my); DEBUG_PRINT("\t"); DEBUG_PRINTLN(max_mz);
2245 // DEBUG_PRINTLN();
2246 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
2247  dbprint("minMag: ");
2248  dbprintInt((int) minMag[0]);
2249  dbprint(" minMag: ");
2250  dbprintInt((int) minMag[1]);
2251  dbprint(" minMag: ");
2252  dbprintInt((int) minMag[2]);
2253  dbprint(" maxMag: ");
2254  dbprintInt((int) maxMag[0]);
2255  dbprint(" maxMag: ");
2256  dbprintInt((int) maxMag[1]);
2257  dbprint(" maxMag: ");
2258  dbprintInt((int) maxMag[2]);
2259  dbprintln("");
2260 #endif /* DEBUG_DBPRINT */
2261  }
2262  }
2263 
2264  return OK;
2265 }

References dbprint(), dbprintInt(), dbprintln(), ICM_20948_magDataRead(), mag_minimumRange, millis(), and OK.

◆ ICM_20948_power()

void ICM_20948_power ( bool  enable)

Turns the GPIO pin high to provide power to the ICM20948.

Note
max current 20mA, in total max 100mA (all GPIO pins combined)
Parameters
[in]enable
  • true - Provide power to the IMU.
  • false - Cut-off power to the IMU.

Definition at line 392 of file ICM20948.c.

393 {
394  /* Initialize VDD pin if not already the case */
395 // if (!ICM_20948_Initialized)
396 // {
397 // /* In the case of gpioModePushPull", the last argument directly sets the pin state */
398 // GPIO_PinModeSet(ICM_20948_POWER_PORT, ICM_20948_POWER_PIN, gpioModePushPull, enable);
399 
400 // ICM_20948_Initialized = true;
401 // }
402 // else
403 // {
404  if (enable) GPIO_PinModeSet(ICM_20948_POWER_PORT, ICM_20948_POWER_PIN, gpioModePushPull, enable); /* Enable VDD pin */
405  else GPIO_PinModeSet(ICM_20948_POWER_PORT, ICM_20948_POWER_PIN, gpioModeDisabled, 0); /* Disable VDD pin */
406 // }
407 }

References ICM_20948_POWER_PIN, and ICM_20948_POWER_PORT.

Referenced by ICM_20948_Init().

◆ ICM_20948_printAllData()

void ICM_20948_printAllData ( )

Print all gyro + accel + magn data using dbprint.

Definition at line 414 of file ICM20948.c.

415 {
416  /* Gyro [DPS]
417  * Accel [G *1000] (to print it in Integers
418  */
419 
420  /* Variables to store gyro & accel data
421  * GYRO: X --> ICM_20948_gyro[0];
422  * Y --> ICM_20948_gyro[1];
423  * Z --> ICM_20948_gyro[2];
424  * ACCEL: X --> ICM_20948_accel[0]:
425  * Y --> ICM_20948_accel[1]:
426  * Z --> ICM_20948_accel[2]:
427  */
428 #if DEBUG_DBPRINTs == 1 /* DEBUG_DBPRINT */
429  dbprint(" Gyro x: ");
430  dbprintInt((int) ICM_20948_gyro[0] );
431  dbprint(" Gyro y: ");
432  dbprintInt((int) ICM_20948_gyro[1] );
433  dbprint(" Gyro z: ");
434  dbprintInt((int) ICM_20948_gyro[2] );
435  dbprint(" Accel x: ");
436  dbprintInt((int) (ICM_20948_accel[0]*1000) );
437  dbprint(" Accel y: ");
438  dbprintInt((int) (ICM_20948_accel[1]*1000) );
439  dbprint(" Accel z: ");
440  dbprintInt((int) (ICM_20948_accel[2]*1000) );
441  dbprint(" Magn x: ");
442  dbprintInt((int) ICM_20948_magn[0] );
443  dbprint(" Magn y: ");
444  dbprintInt((int) ICM_20948_magn[1] );
445  dbprint(" Magn z: ");
446  dbprintlnInt((int) ICM_20948_magn[2] );
447 #endif /* DEBUG_DBPRINT */
448 
449 }

References dbprint(), dbprintInt(), and dbprintlnInt().

◆ ICM_20948_read()

uint8_t ICM_20948_read ( uint16_t  addr)

Read single register from IMU using SPI.

Parameters
[in]addraddress 16 bits - first bits are bank, the rest of the bits is the address

Definition at line 545 of file ICM20948.c.

546 {
547  uint8_t data;
548  uint8_t reg_address;
549  uint8_t bank;
550 
551  /* Select last 7 bytes (A6 - A0) to use as register address */
552  /* Address format: | R/W | A6 | A5 | A4 | A3 | A2 | A1 | A0 | */
553  /* Use AND to change only last 7 bytes */
554  reg_address = (uint8_t) (addr & 0b01111111);
555 
556  bank = (uint8_t) (addr >> 7);
557 
558  /* Select right bank */
559  ICM_20948_bankSelect(bank);
560 
561  /* Enable CS */
563 
564  /* Set the first byte to 1 to read (according to data sheet) */
565  /* Address format: | R/W | A6 | A5 | A4 | A3 | A2 | A1 | A0 | */
566  /* Read setup */
567  USART_SpiTransfer(SPI, (reg_address | 0b10000000));
568 
569  /* Read data */
570  data = USART_SpiTransfer(SPI, 0x00);
571 
572  /* Disable CS */
574 
575  return (data);
576 }

References data, ICM_20948_bankSelect(), ICM_20948_chipSelectSet(), and SPI.

Referenced by ICM_20948_check_WhoAmI(), readMagRegister(), and waitForSlave4().

◆ ICM_20948_read_mag_register()

void ICM_20948_read_mag_register ( uint8_t  addr,
uint8_t  numBytes,
uint8_t *  data 
)

Read register in the AK09916 magnetometer device.

Parameters
[in]addrRegister address to read from Bit[6:0] - register address
[in]numBytesNumber of bytes to read
[out]dataData read from register
Returns
None

Definition at line 1594 of file ICM20948.c.

1594  {
1595  uint8_t wBuffer[2];
1596  wBuffer[0] = addr;
1597  wBuffer[1] = 0x00;
1598 
1599  IIC_WriteReadBuffer( ( AK09916_BIT_I2C_SLV_ADDR << 1 ), wBuffer, 1, data, numBytes);
1600 }

References AK09916_BIT_I2C_SLV_ADDR, data, and IIC_WriteReadBuffer().

Referenced by ICM_20948_Init(), ICM_20948_Init2(), ICM_20948_magDataRead(), and ICM_20948_magRawDataRead().

◆ ICM_20948_registerRead()

void ICM_20948_registerRead ( uint16_t  addr,
int  numBytes,
uint8_t *  data 
)

Read registers from IMU.

Using I2C

Parameters
[in]addraddress
[in]numBytesnumer of bytes to read
[out]datapointer to store data

Definition at line 654 of file ICM20948.c.

655 {
656  uint8_t regAddr;
657  uint8_t bank;
658 
659 
660 
661  uint8_t rLength = (uint8_t) numBytes;
662 
663 
664  regAddr = (uint8_t) (addr & 0x7F);
665  bank = (uint8_t) (addr >> 7);
666 
667  ICM_20948_bankSelect(bank);
668 
669  uint8_t wBuffer[2];
670  wBuffer[0] = regAddr;
671  wBuffer[1] = 0x00; /* 0x00 to read */
672 
673  // TODO
674 
675  IIC_WriteReadBuffer(ICM_20948_I2C_ADDRESS, wBuffer, 1, data, rLength);
676 
677 
678  return;
679 }

References data, ICM_20948_bankSelect(), ICM_20948_I2C_ADDRESS, and IIC_WriteReadBuffer().

Referenced by ICM_20948_accelBandwidthSet(), ICM_20948_accelDataRead(), ICM_20948_accelFullscaleSet(), ICM_20948_accelGyroCalibrate(), ICM_20948_accelResolutionGet(), ICM_20948_gyroBandwidthSet(), ICM_20948_gyroCalibrate(), ICM_20948_gyroDataRead(), ICM_20948_gyroFullscaleSet(), ICM_20948_gyroResolutionGet(), ICM_20948_Init2(), ICM_20948_interruptStatusRead(), ICM_20948_latchEnable(), ICM_20948_lowPowerModeEnter(), ICM_20948_sensorEnable(), and ICM_20948_sleepModeEnable().

◆ ICM_20948_registerWrite()

void ICM_20948_registerWrite ( uint16_t  addr,
uint8_t  data 
)

Writes registers from IMU.

Using I2C

Parameters
[in]addraddress
[out]datadata to be written

Definition at line 697 of file ICM20948.c.

698 {
699  uint8_t regAddr;
700  uint8_t bank;
701 
702  regAddr = (uint8_t) (addr & 0x7F);
703  bank = (uint8_t) (addr >> 7);
704 
705  ICM_20948_bankSelect(bank);
706 
707  uint8_t wBuffer[2];
708  wBuffer[0] = regAddr;
709  wBuffer[1] = data;
710 
711 
713 
714  return;
715 }

References data, ICM_20948_bankSelect(), ICM_20948_I2C_ADDRESS, and IIC_WriteBuffer().

Referenced by ICM_20948_accelBandwidthSet(), ICM_20948_accelFullscaleSet(), ICM_20948_accelGyroCalibrate(), ICM_20948_accelSampleRateSet(), ICM_20948_cycleModeEnable(), ICM_20948_gyroBandwidthSet(), ICM_20948_gyroCalibrate(), ICM_20948_gyroFullscaleSet(), ICM_20948_gyroSampleRateSet(), ICM_20948_Init2(), ICM_20948_interruptEnable(), ICM_20948_latchEnable(), ICM_20948_lowPowerModeEnter(), ICM_20948_reset(), ICM_20948_sensorEnable(), ICM_20948_set_mag_transfer(), ICM_20948_sleepModeEnable(), ICM_20948_wakeOnMotionITEnable(), readMagRegister(), and writeMagRegister().

◆ ICM_20948_reset()

uint32_t ICM_20948_reset ( void  )

Reset IMU.

Definition at line 762 of file ICM20948.c.

763 {
764  /* Set H_RESET bit to initiate soft reset */
766 
767  /* Wait 100ms to complete the reset sequence */
768  delay(100);
769 
770  return ICM_20948_OK;
771 }

References delay(), ICM_20948_BIT_H_RESET, ICM_20948_OK, ICM_20948_REG_PWR_MGMT_1, and ICM_20948_registerWrite().

Referenced by ICM_20948_Init().

◆ ICM_20948_reset_mag()

uint32_t ICM_20948_reset_mag ( void  )

Reset magnetometer.

Definition at line 1768 of file ICM20948.c.

1768  {
1769  /* Set SRST bit to initiate soft reset */
1771 
1772  /* Wait 100ms to complete reset sequence */
1773  delay(100);
1774 
1775  return OK;
1776 }

References AK09916_BIT_SRST, AK09916_REG_CONTROL_3, delay(), ICM_20948_write_mag_register(), and OK.

◆ ICM_20948_sampleRateSet()

uint32_t ICM_20948_sampleRateSet ( float  sampleRate)

Combination function to set sample rate of gyro and accel at once.

will automatically calculate a sample rate that fits the sample rate divider register

Parameters
[in/out]sampleRate desired sample rate

Definition at line 924 of file ICM20948.c.

925 {
926  ICM_20948_gyroSampleRateSet(sampleRate);
927  ICM_20948_accelSampleRateSet(sampleRate);
928 
929  return ICM_20948_OK;
930 }

References ICM_20948_accelSampleRateSet(), ICM_20948_gyroSampleRateSet(), and ICM_20948_OK.

Referenced by ICM_20948_accelGyroCalibrate(), ICM_20948_gyroCalibrate(), ICM_20948_Init2(), and ICM_20948_wakeOnMotionITEnable().

◆ ICM_20948_sensorEnable()

uint32_t ICM_20948_sensorEnable ( bool  accel,
bool  gyro,
bool  temp 
)

Enable selected sensors.

Parameters
[in]accel
  • 'true' - enable
  • 'false' - disable
[in]gyro
  • 'true' - enable
  • 'false' - disable
[in]temp
  • 'true' - enable
  • 'false' - disable
Returns
OK if successful

Definition at line 1095 of file ICM20948.c.

1096 {
1097  uint8_t pwrManagement1;
1098  uint8_t pwrManagement2;
1099 
1100  ICM_20948_registerRead(ICM_20948_REG_PWR_MGMT_1, 1, &pwrManagement1);
1101  pwrManagement2 = 0;
1102 
1103  /* To enable the accelerometer clear the DISABLE_ACCEL bits in PWR_MGMT_2 */
1104  if ( accel ) {
1105  pwrManagement2 &= ~(ICM_20948_BIT_PWR_ACCEL_STBY);
1106  } else {
1107  pwrManagement2 |= ICM_20948_BIT_PWR_ACCEL_STBY;
1108  }
1109 
1110  /* To enable gyro clear the DISABLE_GYRO bits in PWR_MGMT_2 */
1111  if ( gyro ) {
1112  pwrManagement2 &= ~(ICM_20948_BIT_PWR_GYRO_STBY);
1113  } else {
1114  pwrManagement2 |= ICM_20948_BIT_PWR_GYRO_STBY;
1115  }
1116 
1117  /* To enable the temperature sensor clear the TEMP_DIS bit in PWR_MGMT_1 */
1118  if ( temp ) {
1119  pwrManagement1 &= ~(ICM_20948_BIT_TEMP_DIS);
1120  } else {
1121  pwrManagement1 |= ICM_20948_BIT_TEMP_DIS;
1122  }
1123 
1124  /* Write back the modified values */
1127 
1128  return ICM_20948_OK;
1129 }

References ICM_20948_BIT_PWR_ACCEL_STBY, ICM_20948_BIT_PWR_GYRO_STBY, ICM_20948_BIT_TEMP_DIS, ICM_20948_OK, ICM_20948_REG_PWR_MGMT_1, ICM_20948_REG_PWR_MGMT_2, ICM_20948_registerRead(), and ICM_20948_registerWrite().

Referenced by ICM_20948_accelGyroCalibrate(), ICM_20948_gyroCalibrate(), ICM_20948_Init2(), ICM_20948_lowPowerModeEnter(), and ICM_20948_wakeOnMotionITEnable().

◆ ICM_20948_set_mag_mode()

uint32_t ICM_20948_set_mag_mode ( uint8_t  magMode)

Set magnetometer mode (sample rate / on-off)

Note
Must read special register to update values
Parameters
[in]magModeMagnetometer mode

Definition at line 1670 of file ICM20948.c.

1670  {
1671  switch ( magMode ) {
1673  break;
1674  case AK09916_MODE_SINGLE:
1675  break;
1676  case AK09916_MODE_10HZ:
1677  break;
1678  case AK09916_MODE_20HZ:
1679  break;
1680  case AK09916_MODE_50HZ:
1681  break;
1682  case AK09916_MODE_100HZ:
1683  break;
1684  case AK09916_MODE_ST:
1685  break;
1686  default:
1687  return ERROR;
1688  }
1689 
1691 
1692  return OK;
1693 }

References AK09916_BIT_MODE_POWER_DOWN, AK09916_MODE_100HZ, AK09916_MODE_10HZ, AK09916_MODE_20HZ, AK09916_MODE_50HZ, AK09916_MODE_SINGLE, AK09916_MODE_ST, AK09916_REG_CONTROL_2, ERROR, ICM_20948_write_mag_register(), and OK.

Referenced by ICM_20948_Init(), and ICM_20948_Init2().

◆ ICM_20948_set_mag_transfer()

void ICM_20948_set_mag_transfer ( bool  read)

Set magnetometer data transfer on integrated I2C controller inside ICM20948.

Note
Not used, this function is only being used when using SPI, not working properly
Parameters
[in]read
  • 'true' - enable
  • 'false' - disable

Definition at line 1443 of file ICM20948.c.

1443  {
1444  uint8_t MAG_BIT_READ = AK09916_BIT_I2C_SLV_ADDR | ICM_20948_BIT_I2C_SLV_READ;
1445  uint8_t MAG_BIT_WRITE = AK09916_BIT_I2C_SLV_ADDR;
1446 
1447  bool read_old = !read;
1448 
1449  /* Set transfer mode if it has changed */
1450  if (read != read_old) {
1451  if (read) {
1453  }
1454  else {
1456  }
1457  read_old = read;
1458  }
1459  return;
1460 }

References AK09916_BIT_I2C_SLV_ADDR, ICM_20948_BIT_I2C_SLV_READ, ICM_20948_REG_I2C_SLV0_ADDR, and ICM_20948_registerWrite().

◆ ICM_20948_sleepModeEnable()

uint32_t ICM_20948_sleepModeEnable ( bool  enable)

Sleep mode enable function.

Parameters
[in]enable
  • 'true' - sleep
  • 'false' - active

Definition at line 728 of file ICM20948.c.

729 {
730  uint8_t reg;
731 
732  /* Read the Sleep Enable register */
734 
735  if ( enable ) {
736  /* Sleep: set the SLEEP bit */
737  reg |= ICM_20948_BIT_SLEEP;
738  } else {
739  /* Wake up: clear the SLEEP bit */
740  //reg &= ~(ICM_20948_BIT_SLEEP); /* this was the provided code */
741 
742  /* My own solution */
743  /* AND to define the bits that can be changed: here bit nr 6 */
744  reg &= 0b10111111;
745  /*OR met 0 to set the SLEEP bit to 0, not really necessary in this case */
746  reg |= 0b00000000;
747  }
748 
750 
751 
752  return ICM_20948_OK;
753 }

References ICM_20948_BIT_SLEEP, ICM_20948_OK, ICM_20948_REG_PWR_MGMT_1, ICM_20948_registerRead(), and ICM_20948_registerWrite().

Referenced by ICM_20948_Init2(), ICM_20948_lowPowerModeEnter(), and ICM_20948_wakeOnMotionITEnable().

◆ ICM_20948_wakeOnMotionITEnable()

uint32_t ICM_20948_wakeOnMotionITEnable ( bool  enable,
uint8_t  womThreshold,
float  sampleRate 
)

Set wake on motion interrupt.

Parameters
[in]enable
  • 'true' - enable wom interrupt
  • 'false' - disable wom interrupt
[in]womThresholdvalue above which an interrupt is generated
[in]sampleRatesample rate of accel in duty cycle mode (low power mode)

Definition at line 1295 of file ICM20948.c.

1296 {
1297  if ( enable ) {
1298  /* Make sure that the chip is not in sleep */
1300 
1301  /* And in continuous mode */
1303 
1304  /* Enable only the accelerometer */
1305  ICM_20948_sensorEnable(true, false, false);
1306 
1307  /* Set sample rate */
1308  ICM_20948_sampleRateSet(sampleRate);
1309 
1310  /* Set the bandwidth to 1210Hz */
1312 
1313  /* Accel: 2G full scale */
1315 
1316  /* Enable the Wake On Motion interrupt */
1317  ICM_20948_interruptEnable(false, true);
1318  delay(50);
1319 
1320  /* Enable Wake On Motion feature */
1322 
1323  /* Set the wake on motion threshold value */
1325 
1326  /* Enable low power mode */
1327  ICM_20948_lowPowerModeEnter(true, false, false);
1328  } else {
1329  /* Disable Wake On Motion feature */
1331 
1332  /* Disable the Wake On Motion interrupt */
1333  ICM_20948_interruptEnable(false, false);
1334 
1335  /* Disable cycle mode */
1337  }
1338 
1339  return ICM_20948_OK;
1340 }

References delay(), ICM_20948_ACCEL_BW_1210HZ, ICM_20948_ACCEL_FULLSCALE_2G, ICM_20948_accelBandwidthSet(), ICM_20948_accelFullscaleSet(), ICM_20948_BIT_ACCEL_INTEL_EN, ICM_20948_BIT_ACCEL_INTEL_MODE, ICM_20948_cycleModeEnable(), ICM_20948_interruptEnable(), ICM_20948_lowPowerModeEnter(), ICM_20948_OK, ICM_20948_REG_ACCEL_INTEL_CTRL, ICM_20948_REG_ACCEL_WOM_THR, ICM_20948_registerWrite(), ICM_20948_sampleRateSet(), ICM_20948_sensorEnable(), and ICM_20948_sleepModeEnable().

◆ ICM_20948_write_mag_register()

void ICM_20948_write_mag_register ( uint8_t  addr,
uint8_t  data 
)

Writes a uint8_t to the I2C address of the magnetometer of the ICM_20948.

Note
Values not updating, register must be read to update...
Parameters
[in]addrThe address that needs to be written to.
[in]dataThe data that needs to be written.

Definition at line 1648 of file ICM20948.c.

1648  {
1649  uint8_t wBuffer[2];
1650  wBuffer[0] = addr;
1651  wBuffer[1] = data;
1652 
1653  IIC_WriteBuffer( ( AK09916_BIT_I2C_SLV_ADDR << 1 ), wBuffer, 2);
1654 }

References AK09916_BIT_I2C_SLV_ADDR, data, and IIC_WriteBuffer().

Referenced by ICM_20948_Init2(), ICM_20948_reset_mag(), and ICM_20948_set_mag_mode().

◆ readMagRegister()

unsigned char readMagRegister ( unsigned char  magreg)

Read magnetometer register from I2C controller in ICM20948.

Note
Not used, not working properly
Parameters
[in/out]magreg register to be read
Returns
read value

Definition at line 1509 of file ICM20948.c.

References AK09916_BIT_I2C_SLV_ADDR, ICM_20948_BIT_I2C_READ, ICM_20948_BIT_I2C_SLV_EN, ICM_20948_read(), ICM_20948_REG_I2C_SLV4_ADDR, ICM_20948_REG_I2C_SLV4_CTRL, ICM_20948_REG_I2C_SLV4_DI, ICM_20948_REG_I2C_SLV4_REG, ICM_20948_registerWrite(), and waitForSlave4().

◆ waitForSlave4()

void waitForSlave4 ( )

Wait for I2C slave (internal I2C controller on ICM20948)

Note
Not used, not working properly

Definition at line 1472 of file ICM20948.c.

1473 {
1474  // Wait until the data is ready:
1475 
1476  delay(100);
1477  unsigned char status = ICM_20948_read(ICM_20948_REG_I2C_MST_STATUS);
1478  if (status & ICM_20948_BIT_SLV4_NACK)
1479  {
1480 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
1481  dbprint("Failed to communicate with compass: NACK");
1482 #endif /* DEBUG_DBPRINT */
1483  }
1484  if (status & ICM_20948_BIT_SLV4_DONE)
1485  {
1486 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
1487  dbprint("Transaction Done");
1488 #endif /* DEBUG_DBPRINT */
1489  }
1490 }

References dbprint(), delay(), ICM_20948_BIT_SLV4_DONE, ICM_20948_BIT_SLV4_NACK, ICM_20948_read(), and ICM_20948_REG_I2C_MST_STATUS.

Referenced by readMagRegister(), and writeMagRegister().

◆ writeMagRegister()

void writeMagRegister ( unsigned char  magreg,
unsigned char  val 
)

Write magnetometer register using internal I2C interface on ICM20948.

Note
Not used, not working properly
Parameters
[in]magregregister
[out]valoutput register

Definition at line 1538 of file ICM20948.c.

References AK09916_BIT_I2C_SLV_ADDR, ICM_20948_BIT_I2C_SLV_EN, ICM_20948_REG_I2C_SLV4_ADDR, ICM_20948_REG_I2C_SLV4_CTRL, ICM_20948_REG_I2C_SLV4_DO, ICM_20948_REG_I2C_SLV4_REG, ICM_20948_registerWrite(), and waitForSlave4().

Variable Documentation

◆ _hx

float _hx

Definition at line 57 of file ICM20948.c.

◆ _hxcounts

int16_t _hxcounts

Definition at line 47 of file ICM20948.c.

Referenced by ICM_20948_magDataRead(), and ICM_20948_magRawDataRead().

◆ _hy

float _hy

Definition at line 57 of file ICM20948.c.

◆ _hycounts

int16_t _hycounts

Definition at line 47 of file ICM20948.c.

Referenced by ICM_20948_magDataRead(), and ICM_20948_magRawDataRead().

◆ _hz

float _hz

Not used, int16_t _hxcounts,_hycounts,_hzcounts are used to store magnetometer values

Definition at line 57 of file ICM20948.c.

◆ _hzcounts

int16_t _hzcounts

Magnetometer x, y and z axis values (not calibrated)

Definition at line 47 of file ICM20948.c.

Referenced by ICM_20948_magDataRead(), and ICM_20948_magRawDataRead().

◆ _magScale

float _magScale = (4912.0f) / (32767.5f)

Factor to calulate magn in microTesla from raw values of registers, same as magscale

Definition at line 63 of file ICM20948.c.

Referenced by ICM_20948_magDataRead().

◆ accRawScaling

float accRawScaling = 32767.5f

=(2^16-1)/2 16 bit representation of acc value to cover +/- range

Definition at line 59 of file ICM20948.c.

◆ gyroRawScaling

float gyroRawScaling = 32767.5f

=(2^16-1)/2 16 bit representation of gyro value to cover +/- range

Definition at line 60 of file ICM20948.c.

◆ ICM_20948_Initialized

bool ICM_20948_Initialized = false

Variable to keep track if the IMU is initialized

Definition at line 40 of file ICM20948.c.

Referenced by ICM_20948_Init().

◆ IMU_MEASURING

bool IMU_MEASURING

Variable to check if IMU is measuring

Keep track of the state of the IMU

Definition at line 126 of file main.c.

◆ mag_minimumRange

int32_t mag_minimumRange = 40

Minimum value to look for on each axis of the magnetometer, to make sure the magnetomeres is being rotated

Definition at line 42 of file ICM20948.c.

Referenced by ICM_20948_min_max_mag().

◆ mag_res

float mag_res = 4912.0f / 32752.0f

Factor to calulate magn in microTesla from raw values of registers

Definition at line 46 of file ICM20948.c.

◆ magRawScaling

float magRawScaling = 32767.5f

=(2^16-1)/2 16 bit representation of gyro value to cover +/- range

Definition at line 61 of file ICM20948.c.

◆ tX

int16_t tX[3] = {1, 0, 0}

Transformation matrix to put magnetometer in same reference frame as gyro and accel

Definition at line 53 of file ICM20948.c.

Referenced by ICM_20948_magDataRead(), and ICM_20948_magRawDataRead().

◆ tY

int16_t tY[3] = {0, -1, 0}

Transformation matrix to put magnetometer in same reference frame as gyro and accel

Definition at line 54 of file ICM20948.c.

Referenced by ICM_20948_magRawDataRead().

◆ tZ

int16_t tZ[3] = {0, 0, -1}

Transformation matrix to put magnetometer in same reference frame as gyro and accel

Definition at line 55 of file ICM20948.c.

Referenced by ICM_20948_magRawDataRead().

tZ
int16_t tZ[3]
Definition: ICM20948.c:55
ICM_20948_REG_FIFO_MODE
#define ICM_20948_REG_FIFO_MODE
Definition: pinout.h:206
ICM_20948_CLK_PORT
#define ICM_20948_CLK_PORT
Definition: pinout.h:52
SPI
#define SPI
Definition: pinout.h:64
ICM_20948_REG_PWR_MGMT_2
#define ICM_20948_REG_PWR_MGMT_2
Definition: pinout.h:141
ICM_20948_REG_INT_ENABLE_1
#define ICM_20948_REG_INT_ENABLE_1
Definition: pinout.h:154
ICM_20948_BIT_SLEEP
#define ICM_20948_BIT_SLEEP
Definition: pinout.h:136
ICM_20948_ACCEL_FULLSCALE_8G
#define ICM_20948_ACCEL_FULLSCALE_8G
Definition: pinout.h:285
ICM_20948_gyroBandwidthSet
uint32_t ICM_20948_gyroBandwidthSet(uint8_t gyroBw)
Set gyroscope bandwidth.
Definition: ICM20948.c:1352
ICM_20948_MOSI_PORT
#define ICM_20948_MOSI_PORT
Definition: pinout.h:56
ICM_20948_BIT_LP_EN
#define ICM_20948_BIT_LP_EN
Definition: pinout.h:137
ICM_20948_GYRO_FULLSCALE_1000DPS
#define ICM_20948_GYRO_FULLSCALE_1000DPS
Definition: pinout.h:244
ICM_20948_chipSelectSet
void ICM_20948_chipSelectSet(bool enable)
Set chipselect pin for SPI functionality.
Definition: ICM20948.c:480
ICM_20948_GYRO_FULLSCALE_2000DPS
#define ICM_20948_GYRO_FULLSCALE_2000DPS
Definition: pinout.h:245
ICM_20948_MASK_ACCEL_FULLSCALE
#define ICM_20948_MASK_ACCEL_FULLSCALE
Definition: pinout.h:281
data
MeasurementData_t data
Definition: main.c:122
ICM_20948_accelResolutionGet
uint32_t ICM_20948_accelResolutionGet(float *accelRes)
Get accelerometer resultion.
Definition: ICM20948.c:1202
ICM_20948_REG_ACCEL_WOM_THR
#define ICM_20948_REG_ACCEL_WOM_THR
Definition: pinout.h:275
ICM20948_DEVICE_ID
#define ICM20948_DEVICE_ID
Definition: pinout.h:351
ICM_20948_REG_FIFO_COUNT_H
#define ICM_20948_REG_FIFO_COUNT_H
Definition: pinout.h:208
ICM_20948_latchEnable
uint32_t ICM_20948_latchEnable(bool enable)
Enables / disables the 50 micro seconds interrupt pin functionality.
Definition: ICM20948.c:1403
ICM_20948_ACCEL_BW_246HZ
#define ICM_20948_ACCEL_BW_246HZ
Definition: pinout.h:289
_hzcounts
int16_t _hzcounts
Definition: ICM20948.c:47
AK09916_REG_WHO_AM_I
#define AK09916_REG_WHO_AM_I
Definition: pinout.h:395
AK09916_BIT_I2C_SLV_ADDR
#define AK09916_BIT_I2C_SLV_ADDR
Definition: pinout.h:396
ICM_20948_write_mag_register
void ICM_20948_write_mag_register(uint8_t addr, uint8_t data)
Writes a uint8_t to the I2C address of the magnetometer of the ICM_20948.
Definition: ICM20948.c:1648
ICM_20948_lowPowerModeEnter
uint32_t ICM_20948_lowPowerModeEnter(bool enAccel, bool enGyro, bool enTemp)
Enter low power mode for selected sensors.
Definition: ICM20948.c:1037
ICM_20948_POWER_PORT
#define ICM_20948_POWER_PORT
Definition: pinout.h:31
ICM_20948_POWER_PIN
#define ICM_20948_POWER_PIN
Definition: pinout.h:30
ICM_20948_accelFullscaleSet
uint32_t ICM_20948_accelFullscaleSet(uint8_t accelFs)
Set accelerometer full scale range.
Definition: ICM20948.c:1242
ICM_20948_MISO_PIN
#define ICM_20948_MISO_PIN
Definition: pinout.h:53
_hycounts
int16_t _hycounts
Definition: ICM20948.c:47
ICM_20948_Initialized
bool ICM_20948_Initialized
Definition: ICM20948.c:40
AK09916_MODE_ST
#define AK09916_MODE_ST
Definition: pinout.h:390
ICM_20948_BIT_RAW_DATA_0_RDY_EN
#define ICM_20948_BIT_RAW_DATA_0_RDY_EN
Definition: pinout.h:155
mag_minimumRange
int32_t mag_minimumRange
Definition: ICM20948.c:42
ICM_20948_REG_ZG_OFFS_USRH
#define ICM_20948_REG_ZG_OFFS_USRH
Definition: pinout.h:263
waitForSlave4
void waitForSlave4()
Wait for I2C slave (internal I2C controller on ICM20948)
Definition: ICM20948.c:1472
AK09916_MODE_50HZ
#define AK09916_MODE_50HZ
Definition: pinout.h:388
AK09916_MODE_20HZ
#define AK09916_MODE_20HZ
Definition: pinout.h:387
ICM_20948_REG_FIFO_RST
#define ICM_20948_REG_FIFO_RST
Definition: pinout.h:205
dbprint
void dbprint(char *message)
ICM_20948_REG_XG_OFFS_USRL
#define ICM_20948_REG_XG_OFFS_USRL
Definition: pinout.h:260
delay
void delay(uint32_t msDelay)
Wait for a certain amount of milliseconds in EM2/3.
Definition: delay.c:116
ICM_20948_REG_I2C_SLV4_DI
#define ICM_20948_REG_I2C_SLV4_DI
Definition: pinout.h:337
ERROR
#define ERROR
Definition: pinout.h:401
ICM_20948_BIT_WOM_INT_EN
#define ICM_20948_BIT_WOM_INT_EN
Definition: pinout.h:152
dbprintInt
void dbprintInt(int32_t value)
ICM_20948_BIT_GYRO_CYCLE
#define ICM_20948_BIT_GYRO_CYCLE
Definition: pinout.h:132
ICM_20948_BIT_TEMP_DIS
#define ICM_20948_BIT_TEMP_DIS
Definition: pinout.h:138
ICM_20948_I2C_ADDRESS
#define ICM_20948_I2C_ADDRESS
Definition: pinout.h:26
ICM_20948_BIT_PWR_GYRO_STBY
#define ICM_20948_BIT_PWR_GYRO_STBY
Definition: pinout.h:143
ICM_20948_REG_XG_OFFS_USRH
#define ICM_20948_REG_XG_OFFS_USRH
Definition: pinout.h:259
ICM_20948_sensorEnable
uint32_t ICM_20948_sensorEnable(bool accel, bool gyro, bool temp)
Enable selected sensors.
Definition: ICM20948.c:1095
ICM_20948_accelSampleRateSet
float ICM_20948_accelSampleRateSet(float sampleRate)
Sets the accelerometer sample rate.
Definition: ICM20948.c:988
millis
uint32_t millis(void)
Millis Arduino like functionality for EFM32HG.
Definition: timer.c:33
tX
int16_t tX[3]
Definition: ICM20948.c:53
ICM_20948_REG_YG_OFFS_USRL
#define ICM_20948_REG_YG_OFFS_USRL
Definition: pinout.h:262
ICM_20948_REG_USER_CTRL
#define ICM_20948_REG_USER_CTRL
Definition: pinout.h:121
ICM_20948_REG_YA_OFFSET_H
#define ICM_20948_REG_YA_OFFSET_H
Definition: pinout.h:224
ICM_20948_BIT_ACCEL_CYCLE
#define ICM_20948_BIT_ACCEL_CYCLE
Definition: pinout.h:131
ICM_20948_GYRO_BW_12HZ
#define ICM_20948_GYRO_BW_12HZ
Definition: pinout.h:253
ICM_20948_ACCEL_BW_1210HZ
#define ICM_20948_ACCEL_BW_1210HZ
Definition: pinout.h:287
ICM_20948_ACCEL_FULLSCALE_4G
#define ICM_20948_ACCEL_FULLSCALE_4G
Definition: pinout.h:284
ICM_20948_REG_INT_ENABLE
#define ICM_20948_REG_INT_ENABLE
Definition: pinout.h:151
ICM_20948_REG_BANK_SEL
#define ICM_20948_REG_BANK_SEL
Definition: pinout.h:346
ICM_20948_min_max_mag
uint32_t ICM_20948_min_max_mag(int16_t *minMag, int16_t *maxMag)
Calculate minimum and maximum magnetometer values, which are used for calibration.
Definition: ICM20948.c:2186
AK09916_REG_CONTROL_3
#define AK09916_REG_CONTROL_3
Definition: pinout.h:392
tY
int16_t tY[3]
Definition: ICM20948.c:54
ICM_20948_MOSI_PIN
#define ICM_20948_MOSI_PIN
Definition: pinout.h:55
AK09916_MODE_100HZ
#define AK09916_MODE_100HZ
Definition: pinout.h:389
ICM_20948_sampleRateSet
uint32_t ICM_20948_sampleRateSet(float sampleRate)
Combination function to set sample rate of gyro and accel at once.
Definition: ICM20948.c:924
ICM_20948_GYRO_FULLSCALE_500DPS
#define ICM_20948_GYRO_FULLSCALE_500DPS
Definition: pinout.h:243
ICM_20948_BIT_ACCEL_FIFO_EN
#define ICM_20948_BIT_ACCEL_FIFO_EN
Definition: pinout.h:202
ICM_20948_REG_FIFO_R_W
#define ICM_20948_REG_FIFO_R_W
Definition: pinout.h:210
ICM_20948_REG_XA_OFFSET_L
#define ICM_20948_REG_XA_OFFSET_L
Definition: pinout.h:223
LED_PORT
#define LED_PORT
Definition: pinout.h:20
ICM_20948_BIT_H_RESET
#define ICM_20948_BIT_H_RESET
Definition: pinout.h:135
ICM_20948_REG_I2C_SLV4_DO
#define ICM_20948_REG_I2C_SLV4_DO
Definition: pinout.h:336
dbprintlnInt
void dbprintlnInt(int32_t value)
ICM_20948_REG_GYRO_SMPLRT_DIV
#define ICM_20948_REG_GYRO_SMPLRT_DIV
Definition: pinout.h:234
ICM_20948_REG_ACCEL_SMPLRT_DIV_2
#define ICM_20948_REG_ACCEL_SMPLRT_DIV_2
Definition: pinout.h:269
IIC_Init
void IIC_Init(void)
Setup I2C functionality.
Definition: I2C.c:52
ICM_20948_REG_I2C_SLV0_ADDR
#define ICM_20948_REG_I2C_SLV0_ADDR
Definition: pinout.h:313
ICM_20948_REG_ACCEL_CONFIG
#define ICM_20948_REG_ACCEL_CONFIG
Definition: pinout.h:277
IIC_WriteBuffer
bool IIC_WriteBuffer(uint8_t iicAddress, uint8_t *wBuffer, uint8_t wLength)
I2C write functionality.
Definition: I2C.c:112
AK09916_MODE_SINGLE
#define AK09916_MODE_SINGLE
Definition: pinout.h:385
ICM_20948_accelBandwidthSet
uint32_t ICM_20948_accelBandwidthSet(uint8_t accelBw)
Set acceleromter bandwidth.
Definition: ICM20948.c:1376
ICM_20948_REG_YG_OFFS_USRH
#define ICM_20948_REG_YG_OFFS_USRH
Definition: pinout.h:261
ICM_20948_BIT_SLV4_NACK
#define ICM_20948_BIT_SLV4_NACK
Definition: pinout.h:166
ICM_20948_Init2
void ICM_20948_Init2()
Second init function for ICM20948, use when waking from sleep.
Definition: ICM20948.c:169
ICM_20948_MISO_PORT
#define ICM_20948_MISO_PORT
Definition: pinout.h:54
ICM_20948_BIT_I2C_SLV_EN
#define ICM_20948_BIT_I2C_SLV_EN
Definition: pinout.h:339
ICM_20948_interruptEnable
uint32_t ICM_20948_interruptEnable(bool dataReadyEnable, bool womEnable)
Enable interrupt for data ready or wake on motion.
Definition: ICM20948.c:885
ICM_20948_cycleModeEnable
uint32_t ICM_20948_cycleModeEnable(bool enable)
Enable cycle mode on IMU.
Definition: ICM20948.c:1142
ICM_20948_read
uint8_t ICM_20948_read(uint16_t addr)
Read single register from IMU using SPI.
Definition: ICM20948.c:545
_magScale
float _magScale
Definition: ICM20948.c:63
ICM_20948_read_mag_register
void ICM_20948_read_mag_register(uint8_t addr, uint8_t numBytes, uint8_t *data)
Read register in the AK09916 magnetometer device.
Definition: ICM20948.c:1594
ICM_20948_MASK_GYRO_FULLSCALE
#define ICM_20948_MASK_GYRO_FULLSCALE
Definition: pinout.h:240
ICM_20948_BIT_FIFO_EN
#define ICM_20948_BIT_FIFO_EN
Definition: pinout.h:123
ICM_20948_gyroSampleRateSet
float ICM_20948_gyroSampleRateSet(float sampleRate)
Sets the gyro sample rate.
Definition: ICM20948.c:947
ICM_20948_set_mag_mode
uint32_t ICM_20948_set_mag_mode(uint8_t magMode)
Set magnetometer mode (sample rate / on-off)
Definition: ICM20948.c:1670
AK09916_BIT_SRST
#define AK09916_BIT_SRST
Definition: pinout.h:393
ICM_20948_MASK_GYRO_BW
#define ICM_20948_MASK_GYRO_BW
Definition: pinout.h:241
ICM_20948_calibrate_mag
bool ICM_20948_calibrate_mag(float *offset, float *scale)
Magnetometer calibration function. Get magnetometer minimum and maximum values, while moving the devi...
Definition: ICM20948.c:2289
ICM_20948_ACCEL_FULLSCALE_2G
#define ICM_20948_ACCEL_FULLSCALE_2G
Definition: pinout.h:283
ICM_20948_BIT_I2C_READ
#define ICM_20948_BIT_I2C_READ
Definition: pinout.h:343
LED_PIN
#define LED_PIN
Definition: pinout.h:21
ICM_20948_REG_LP_CONFIG
#define ICM_20948_REG_LP_CONFIG
Definition: pinout.h:129
ICM_20948_CS_PORT
#define ICM_20948_CS_PORT
Definition: pinout.h:49
ICM_20948_REG_ZA_OFFSET_L
#define ICM_20948_REG_ZA_OFFSET_L
Definition: pinout.h:227
OK
#define OK
Definition: pinout.h:402
ICM_20948_REG_ZA_OFFSET_H
#define ICM_20948_REG_ZA_OFFSET_H
Definition: pinout.h:226
ICM_20948_registerRead
void ICM_20948_registerRead(uint16_t addr, int numBytes, uint8_t *data)
Read registers from IMU.
Definition: ICM20948.c:654
AK09916_DEVICE_ID
#define AK09916_DEVICE_ID
Definition: pinout.h:368
ICM_20948_BANK_0
#define ICM_20948_BANK_0
Definition: pinout.h:70
AK09916_BIT_MODE_POWER_DOWN
#define AK09916_BIT_MODE_POWER_DOWN
Definition: pinout.h:384
ICM_20948_REG_YA_OFFSET_L
#define ICM_20948_REG_YA_OFFSET_L
Definition: pinout.h:225
ICM_20948_REG_I2C_SLV4_CTRL
#define ICM_20948_REG_I2C_SLV4_CTRL
Definition: pinout.h:335
ICM_20948_magDataRead
void ICM_20948_magDataRead(float *magn)
Convert raw magnetometer values to calibrated and scaled ones.
Definition: ICM20948.c:1745
ICM_20948_BIT_CLK_PLL
#define ICM_20948_BIT_CLK_PLL
Definition: pinout.h:139
ICM_20948_power
void ICM_20948_power(bool enable)
Turns the GPIO pin high to provide power to the ICM20948.
Definition: ICM20948.c:392
ICM_20948_OK
#define ICM_20948_OK
Definition: pinout.h:43
ICM_20948_accelGyroCalibrate
uint32_t ICM_20948_accelGyroCalibrate(float *accelBiasScaled, float *gyroBiasScaled)
Accelerometer and gyroscope calibration function. Reads the gyroscope and accelerometer values while ...
Definition: ICM20948.c:1820
ICM_20948_REG_ZG_OFFS_USRL
#define ICM_20948_REG_ZG_OFFS_USRL
Definition: pinout.h:264
ICM_20948_REG_INT_STATUS
#define ICM_20948_REG_INT_STATUS
Definition: pinout.h:172
ICM_20948_BIT_ACCEL_INTEL_EN
#define ICM_20948_BIT_ACCEL_INTEL_EN
Definition: pinout.h:272
ICM_20948_REG_ACCEL_XOUT_H_SH
#define ICM_20948_REG_ACCEL_XOUT_H_SH
Definition: pinout.h:181
ICM_20948_sleepModeEnable
uint32_t ICM_20948_sleepModeEnable(bool enable)
Sleep mode enable function.
Definition: ICM20948.c:728
GYRO_XOUT_H
#define GYRO_XOUT_H
Definition: pinout.h:82
ICM_20948_reset
uint32_t ICM_20948_reset(void)
Reset IMU.
Definition: ICM20948.c:762
ICM_20948_bankSelect
void ICM_20948_bankSelect(uint8_t bank)
Select appropriate bank in ICM20948 based on first bits of address.
Definition: ICM20948.c:528
ICM_20948_BIT_ACCEL_INTEL_MODE
#define ICM_20948_BIT_ACCEL_INTEL_MODE
Definition: pinout.h:273
AK09916_MODE_10HZ
#define AK09916_MODE_10HZ
Definition: pinout.h:386
ICM_20948_CS_PIN
#define ICM_20948_CS_PIN
Definition: pinout.h:48
ICM_20948_BIT_PWR_ACCEL_STBY
#define ICM_20948_BIT_PWR_ACCEL_STBY
Definition: pinout.h:142
ICM_20948_REG_INT_PIN_CFG
#define ICM_20948_REG_INT_PIN_CFG
Definition: pinout.h:146
ICM_20948_REG_ACCEL_SMPLRT_DIV_1
#define ICM_20948_REG_ACCEL_SMPLRT_DIV_1
Definition: pinout.h:268
ICM_20948_REG_WHO_AM_I
#define ICM_20948_REG_WHO_AM_I
Definition: pinout.h:119
M_PI
#define M_PI
Definition: ICM20948.c:41
ICM_20948_BIT_I2C_SLV_READ
#define ICM_20948_BIT_I2C_SLV_READ
Definition: pinout.h:360
ICM_20948_ACCEL_FULLSCALE_16G
#define ICM_20948_ACCEL_FULLSCALE_16G
Definition: pinout.h:286
ICM_20948_REG_XA_OFFSET_H
#define ICM_20948_REG_XA_OFFSET_H
Definition: pinout.h:222
AK09916_REG_CONTROL_2
#define AK09916_REG_CONTROL_2
Definition: pinout.h:383
ICM_20948_gyroResolutionGet
uint32_t ICM_20948_gyroResolutionGet(float *gyroRes)
Set gyro resolution.
Definition: ICM20948.c:817
IIC_WriteReadBuffer
bool IIC_WriteReadBuffer(uint8_t iicAddress, uint8_t *wBuffer, uint8_t wLength, uint8_t *rBuffer, uint8_t rLength)
I2C read/write functionality, to read and write at the same time.
Definition: I2C.c:190
ICM_20948_REG_GYRO_CONFIG_1
#define ICM_20948_REG_GYRO_CONFIG_1
Definition: pinout.h:236
ICM_20948_gyroFullscaleSet
uint32_t ICM_20948_gyroFullscaleSet(uint8_t gyroFs)
Set gyroscope full scale range.
Definition: ICM20948.c:1265
ICM_20948_REG_PWR_MGMT_1
#define ICM_20948_REG_PWR_MGMT_1
Definition: pinout.h:134
ICM_20948_MASK_ACCEL_BW
#define ICM_20948_MASK_ACCEL_BW
Definition: pinout.h:282
ICM_20948_BITS_GYRO_FIFO_EN
#define ICM_20948_BITS_GYRO_FIFO_EN
Definition: pinout.h:203
dbprintln
void dbprintln(char *message)
ICM_20948_REG_I2C_SLV4_ADDR
#define ICM_20948_REG_I2C_SLV4_ADDR
Definition: pinout.h:333
ICM_20948_registerWrite
void ICM_20948_registerWrite(uint16_t addr, uint8_t data)
Writes registers from IMU.
Definition: ICM20948.c:697
_hxcounts
int16_t _hxcounts
Definition: ICM20948.c:47
ICM_20948_REG_FIFO_EN_2
#define ICM_20948_REG_FIFO_EN_2
Definition: pinout.h:201
ICM_20948_REG_I2C_SLV4_REG
#define ICM_20948_REG_I2C_SLV4_REG
Definition: pinout.h:334
ICM_20948_CLK_PIN
#define ICM_20948_CLK_PIN
Definition: pinout.h:51
ICM_20948_REG_ACCEL_INTEL_CTRL
#define ICM_20948_REG_ACCEL_INTEL_CTRL
Definition: pinout.h:271
ICM_20948_BIT_SLV4_DONE
#define ICM_20948_BIT_SLV4_DONE
Definition: pinout.h:164
ICM_20948_GYRO_FULLSCALE_250DPS
#define ICM_20948_GYRO_FULLSCALE_250DPS
Definition: pinout.h:242
ICM_20948_REG_I2C_MST_STATUS
#define ICM_20948_REG_I2C_MST_STATUS
Definition: pinout.h:162