35#define K_READ_OP 0x80U
36#define K_WRITE_OP 0x00U
38#define K_ICM20948_BASE_SAMPLE_RATE 1125L
39#define K_ICM20948_DMP_RUNNING_RATE 225L
40#define K_ICM20948_DMP_DIVIDER (K_ICM20948_BASE_SAMPLE_RATE / K_ICM20948_DMP_RUNNING_RATE)
41#define K_ICM20948_WHO_AM_I_VALUE 0xEAU
42#define K_ICM20948_DMP_PACKET_SIZE_BYTES 42U
43#define K_ICM20948_FIFO_RESET_THRESHOLD 512U
44#define K_ICM20948_DMP_START_ADDR_MSB 0x10U
45#define K_ICM20948_DMP_START_ADDR_LSB 0x00U
46#define K_ICM20948_LOG_TAG "ICM"
92 .p_nameProducer =
"icm20948",
138 if (p_fsmErrors == NULL)
162 p_fsmErrors->icmInitError = 1;
198#ifdef SPP_DEBUG_PRINT
207#ifdef SPP_DEBUG_PRINT
218#ifdef SPP_DEBUG_PRINT
220 "[ICM] A:[%.2f %.2f %.2f]g G:[%.1f %.1f %.1f]dps M:[%.1f %.1f "
222 " Q:[w=%.3f x=%.3f y=%.3f z=%.3f] ACC:%f\n",
290 *p_value = txRxBuffer[1];
346 regBankSel.
bits.bankSel = 0U;
349 regBankSel.
bits.bankSel = 1U;
352 regBankSel.
bits.bankSel = 2U;
355 regBankSel.
bits.bankSel = 3U;
374 fifoResetReg.
bits.fifoRst0 = 1U;
375 fifoResetReg.
bits.fifoRst1 = 1U;
376 fifoResetReg.
bits.fifoRst2 = 1U;
377 fifoResetReg.
bits.fifoRst3 = 1U;
378 fifoResetReg.
bits.fifoRst4 = 1U;
386 fifoResetReg.
bits.fifoRst0 = 0U;
402 void *p_spi = p_data;
405 if ((p_spi == NULL) || (p_bytes == NULL))
470 void *p_spi = p_data;
480 pwrMgmt1Reg.
bits.lpEn = 1U;
488 pwrMgmt1Reg.
value = 0U;
566 void *p_spi = p_data;
589 while (done < firmwareSize)
594 if (bank != lastBank)
647 void *p_spi = p_data;
683#ifdef SPP_DEBUG_PRINT
698 pwrMgmt1Reg.
bits.deviceReset = 1U;
707 pwrMgmt1Reg.
value = 0U;
715 userCtrlReg.
bits.i2cIfDis = 1U;
722 pwrMgmt2Reg.
bits.disableAccelX = 1U;
723 pwrMgmt2Reg.
bits.disableAccelY = 1U;
724 pwrMgmt2Reg.
bits.disableAccelZ = 1U;
725 pwrMgmt2Reg.
bits.disableGyroZ = 1U;
732 lpConfReg.
bits.i2cMstCyc = 1U;
803 intEnableReg.
bits.rawData0Rdy = 1U;
810 intEnable2Reg.
bits.fifoOverflowEn0 = 1U;
817 fifoPriorityReg.
value = 0xE4U;
824 hwFixDisableReg.
value = 0x48U;
909 pwrMgmt1Reg.
bits.lpEn = 1U;
916 pwrMgmt2Reg.
value = 0x7FU;
923 pwrMgmt1Reg.
bits.sleep = 1U;
932 pwrMgmt1Reg.
value = 0U;
934 pwrMgmt1Reg.
bits.lpEn = 1U;
943 pwrMgmt1Reg.
value = 0U;
1031 userCtrlReg.
bits.i2cIfDis = 1U;
1032 userCtrlReg.
bits.i2cMstEn = 1U;
1041 userCtrlReg.
value = 0U;
1042 userCtrlReg.
bits.i2cIfDis = 1U;
1077 userCtrlReg.
bits.i2cIfDis = 1U;
1086 for (
spp_uint8_t i = 0U; i < (
sizeof(s_cpassMatrix) /
sizeof(s_cpassMatrix[0])); i++)
1103 for (
spp_uint8_t i = 0U; i < (
sizeof(s_b2sMatrix) /
sizeof(s_b2sMatrix[0])); i++)
1183 gyroConfigReg.
bits.gyroFchoice = 1U;
1265 lpConfReg.
bits.i2cMstCyc = 1U;
1289 userCtrlReg.
bits.i2cIfDis = 1U;
1294 userCtrlReg.
bits.i2cIfDis = 1U;
1295 userCtrlReg.
bits.fifoEn = 1U;
1296 userCtrlReg.
bits.dmpEn = 1U;
1305 pwrMgmt2Reg.
value = 0x47U;
1313 userCtrlReg.
value = 0U;
1314 userCtrlReg.
bits.i2cIfDis = 1U;
1315 userCtrlReg.
bits.fifoEn = 1U;
1316 userCtrlReg.
bits.dmpEn = 1U;
1331 pwrMgmt2Reg.
value = 0x7FU;
1339 pwrMgmt1Reg.
bits.sleep = 1U;
1348 pwrMgmt1Reg.
value = 0U;
1483 pwrMgmt2Reg.
value = 0x40U;
1560 userCtrlReg.
bits.i2cIfDis = 1U;
1561 userCtrlReg.
bits.i2cMstEn = 1U;
1562 userCtrlReg.
bits.fifoEn = 1U;
1563 userCtrlReg.
bits.dmpEn = 1U;
1570 userCtrlReg.
bits.dmpRst = 1U;
1590 pwrMgmt1Reg.
bits.lpEn = 1U;
1634 void *p_spi = p_ctx->
p_spi;
1666 if ((intStatus & 0x02U) != 0U)
1718 fifoBuffer[0], fifoBuffer[1], fifoBuffer[2], fifoBuffer[3], fifoBuffer[8],
1752 float ax = accelX / 8192.0f;
1753 float ay = accelY / 8192.0f;
1754 float az = accelZ / 8192.0f;
1755 float gx = gyroX / 32.8f;
1756 float gy = gyroY / 32.8f;
1757 float gz = gyroZ / 32.8f;
1758 float mx = magX * 0.15f;
1759 float my = magY * 0.15f;
1760 float mz = magZ * 0.15f;
1761 float qx = q1Raw / 1073741824.0f;
1762 float qy = q2Raw / 1073741824.0f;
1763 float qz = q3Raw / 1073741824.0f;
1764 float qwSq = 1.0f - (qx * qx) - (qy * qy) - (qz * qz);
1765 float qw = (qwSq > 0.0f) ? sqrtf(qwSq) : 0.0f;
SPP_Packet_t * SPP_SERVICES_DATABANK_getPacket(void)
Acquire a free packet from the pool.
SPP_RetVal_t SPP_SERVICES_DATABANK_returnPacket(SPP_Packet_t *p_packet)
Return a packet to the pool after processing.
SPP_RetVal_t SPP_SERVICES_DATABANK_packetData(SPP_Packet_t *p_packet, spp_uint16_t apid, spp_uint16_t seq, const void *p_data, spp_uint16_t dataLen)
Fill a packet with data and compute its CRC.
Static packet pool manager.
spp_uint16_t * SPP_CORE_FSM_getErrorsBit(void)
Get the pointer to the FSM errors bit.
Finite State Machine (FSM) module for the SPP core.
SPP_RetVal_t SPP_HAL_GPIO_registerIsr(spp_uint32_t pin, void *p_isrCtx)
Register an ISR handler for a GPIO pin.
SPP_RetVal_t SPP_HAL_GPIO_configInterrupt(spp_uint32_t pin, spp_uint32_t intrType, spp_uint32_t pull)
Configure a GPIO pin as an interrupt input.
SPP GPIO HAL API — dispatches through the registered HAL port.
#define K_ICM20948_FIFO_RESET_THRESHOLD
#define K_ICM20948_DMP_START_ADDR_MSB
static SPP_RetVal_t readFifoBurst(void *p_spi, spp_uint8_t *p_dst, spp_uint8_t count)
Reads count bytes sequentially from the FIFO_R_W register.
#define K_ICM20948_WHO_AM_I_VALUE
static spp_int32_t SPP_SERVICES_ICM20948_calcGyroSf(spp_int8_t pll)
Computes the DMP gyroscope scale factor from the PLL trim value.
static SPP_RetVal_t SPP_SERVICES_ICM20948_lpWakeCycle(void *p_data)
Toggles PWR_MGMT_1 into low-power wake-cycle mode then back to normal.
static SPP_RetVal_t SPP_SERVICES_ICM20948_readReg(void *p_spi, spp_uint8_t reg, spp_uint8_t *p_value)
Reads a single byte from an ICM-20948 register over SPI.
static SPP_RetVal_t SPP_SERVICES_ICM20948_dmpWrite32(void *p_data, spp_uint16_t addr, spp_uint32_t value)
Writes a 32-bit big-endian value to DMP memory at addr.
#define K_ICM20948_LOG_TAG
static const spp_uint8_t s_dmp3Image[]
static void SPP_SERVICES_ICM20948_initGpio(ICM20948_Data_t *p_icm)
Initialises the ICM20948 interrupt context and registers the GPIO ISR.
static SPP_RetVal_t SPP_SERVICES_ICM20948_configDmpInit(void *p_data)
Executes the full DMP initialisation sequence.
const SPP_SERVICE_ProducerContract_t * SPP_SERVICES_ICM20948_getProducerContract(void)
Returns a pointer to the ICM20948 producer contract.
static SPP_RetVal_t SPP_SERVICES_ICM20948_init(void)
Service init callback — sets hardware config, registers GPIO ISR, loads DMP firmware.
#define K_ICM20948_DMP_PACKET_SIZE_BYTES
static SPP_RetVal_t SPP_SERVICES_ICM20948_writeReg(void *p_spi, spp_uint8_t reg, spp_uint8_t value)
Writes a single byte to an ICM-20948 register over SPI.
static void SPP_SERVICES_ICM20948_checkFifoData(ICM20948_t *p_ctx)
Reads and parses DMP FIFO packets, updating the sensor data fields.
static SPP_RetVal_t SPP_SERVICES_ICM20948_loadDmp(void *p_data)
Loads the DMP3 firmware image into ICM-20948 SRAM.
static SPP_RetVal_t SPP_SERVICES_ICM20948_dmpWrite16(void *p_data, spp_uint16_t addr, spp_uint16_t value)
Writes a 16-bit big-endian value to DMP memory at addr.
static SPP_RetVal_t SPP_SERVICES_ICM20948_dmpWriteBytes(void *p_data, spp_uint16_t addr, const spp_uint8_t *p_bytes, spp_uint8_t len)
Writes len bytes to DMP memory starting at address addr.
static ICM20948_t s_icmData
static const SPP_SERVICE_ProducerContract_t s_icm20948ProducerContract
#define K_ICM20948_DMP_DIVIDER
static SPP_RetVal_t SPP_SERVICES_ICM20948_resetFifo(void *p_spi)
Resets all five FIFO streams by toggling the FIFO_RST bits.
static SPP_RetVal_t SPP_SERVICES_ICM20948_setBank(void *p_spi, ICM20948_RegBank_t regBank)
Selects the active register bank by writing REG_BANK_SEL.
static SPP_RetVal_t SPP_SERVICES_ICM20948_acquireData(SPP_Kpid_t kpid)
Service acquire callback — reads FIFO data and publishes a packet.
#define K_ICM20948_DMP_START_ADDR_LSB
static SPP_RetVal_t ICM20948_dmpWriteOutputConfig(void *p_data, spp_uint16_t outCtl1, spp_uint16_t motionEvent)
Programs the DMP output control and motion event registers.
ICM20948 IMU driver and SPP service.
#define K_ICM20948_MAG_WR_ADDR
#define K_ICM20948_DMP_DATA_INTR_CTL
#define K_ICM20948_I2C_SLV1_REG
#define K_ICM20948_INT_PIN_NUM
#define K_ICM20948_REG_FIFO_RST
#define K_ICM20948_REG_TIMEBASE_CORRECTION_PLL
ICM20948_RegBank_t
ICM20948 register bank selector.
#define K_ICM20948_DMP_B2S_MTX_21
#define K_ICM20948_DMP_CPASS_TIME_BUFFER
#define K_ICM20948_REG_INT_ENABLE
#define K_ICM20948_I2C_SLV1_CTRL
#define K_ICM20948_REG_PWR_MGMT_1
#define K_ICM20948_DMP_ODR_QUAT6
#define K_ICM20948_REG_PWR_MGMT_2
#define K_ICM20948_REG_WHO_AM_I
#define K_ICM20948_REG_FIFO_EN_2
#define K_ICM20948_DMP_FIFO_WATERMARK
#define K_ICM20948_DMP_B2S_MTX_01
#define K_ICM20948_REG_ACCEL_SMPLRT_DIV_2
#define K_ICM20948_DMP_GYRO_SF
#define K_ICM20948_DMP_ACC_SCALE2
#define K_ICM20948_TASK_TIMEOUT_MS
#define K_ICM20948_INT_INTR_TYPE
#define K_ICM20948_MAG_CTRL_2
#define K_ICM20948_REG_DMP_ADDR_LSB
#define K_ICM20948_REG_DMP_ADDR_MSB
#define K_ICM20948_I2C_SLV1_DO
#define K_ICM20948_I2C_SLV1_ADDR
#define K_ICM20948_DMP_B2S_MTX_00
#define K_ICM20948_REG_ACCEL_SMPLRT_DIV_1
#define K_ICM20948_DMP_B2S_MTX_11
#define K_ICM20948_INT_PULL
#define K_ICM20948_DMP_ODR_CPASS
#define K_ICM20948_DMP_B2S_MTX_22
#define K_ICM20948_REG_HW_FIX_DISABLE
#define K_ICM20948_REG_SLV0_REG
#define K_ICM20948_DMP_DATA_OUT_CTL1
#define K_ICM20948_REG_LP_CONF
#define K_ICM20948_DMP_CPASS_MTX_00
#define K_ICM20948_DMP_B2S_MTX_02
#define K_ICM20948_DMP_DATA_OUT_CTL2
#define K_ICM20948_DMP_ACCEL_ONLY_GAIN
#define K_ICM20948_REG_BANK_SEL
#define K_ICM20948_DMP_BAC_RATE
#define K_ICM20948_REG_GYRO_CONFIG
#define K_ICM20948_DMP_ODR_QUAT9
#define K_ICM20948_DMP_ODR_ACCEL
#define K_ICM20948_REG_FIFO_R_W
#define K_ICM20948_DMP_CPASS_MTX_20
#define K_ICM20948_I2C_MST_ODR_CONFIG
#define K_ICM20948_REG_USER_CTRL
@ K_ICM20948_GYRO_FS_2000DPS
#define K_ICM20948_DMP_CPASS_MTX_01
#define K_ICM20948_REG_GYRO_SMPLRT_DIV
#define K_ICM20948_DMP_CPASS_MTX_12
#define K_ICM20948_DMP_MOTION_EVENT_CTL
#define K_ICM20948_DMP_ACCEL_A_VAR
#define K_ICM20948_DMP_ACC_SCALE
#define K_ICM20948_DMP_LOAD_START
#define K_ICM20948_DMP_ACCEL_CAL_INIT
#define K_ICM20948_REG_I2C_CTRL
#define K_ICM20948_DMP_B2S_RATE
#define K_ICM20948_DMP_CPASS_MTX_11
#define K_ICM20948_REG_SLV0_CTRL
#define K_ICM20948_MAG_RD_ADDR
#define K_ICM20948_DMP_B2S_MTX_20
#define K_ICM20948_REG_FIFO_CFG
#define K_ICM20948_REG_MEM_START_ADDR
#define K_ICM20948_REG_SLV0_ADDR
#define K_ICM20948_DMP_CPASS_MTX_10
#define K_ICM20948_DMP_B2S_MTX_10
#define K_ICM20948_DMP_CPASS_MTX_21
#define K_ICM20948_DMP_ODR_GYRO
#define K_ICM20948_REG_ACCEL_CONFIG_2
#define K_ICM20948_REG_INT_ENABLE_2
#define K_ICM20948_SPI_HOST_USED
#define K_ICM20948_DMP_CPASS_MTX_22
#define K_ICM20948_REG_INT_STATUS
#define K_ICM20948_REG_FIFO_EN_1
#define K_ICM20948_REG_MEM_R_W
#define K_ICM20948_REG_ACCEL_CONFIG
#define K_ICM20948_DMP_ACCEL_ALPHA_VAR
#define K_ICM20948_DMP_B2S_MTX_12
#define K_ICM20948_REG_MEM_BANK_SEL
#define K_ICM20948_DMP_GYRO_FULLSCALE
#define K_ICM20948_DMP_DATA_RDY_STATUS
#define K_ICM20948_REG_DMP_INT_STATUS
#define K_ICM20948_REG_FIFO_COUNTH
#define K_ICM20948_REG_SINGLE_FIFO_PRIORITY_SEL
#define K_ICM20948_DMP_CPASS_MTX_02
#define SPP_LOGI(tag, fmt,...)
#define SPP_LOGE(tag, fmt,...)
SPP_RetVal_t SPP_SERVICES_PUBSUB_publish(SPP_Packet_t *p_pkt)
Copies a packet into the internal buffer and returns it to the databank.
Publish-subscribe packet router.
Standard return-value type used across all SPP modules.
SPP_RetVal_t
Unified return type for all SPP API functions.
@ K_SPP_ERROR_NULL_POINTER
SPP module descriptor and registry API.
void * SPP_HAL_SPI_getHandle(spp_uint8_t deviceIdx)
Obtain the SPI device handle for the given device index.
SPP_RetVal_t SPP_HAL_SPI_deviceInit(void *p_handle)
Initialise a specific SPI device.
SPP_RetVal_t SPP_HAL_SPI_transmit(void *p_handle, spp_uint8_t *p_data, spp_uint8_t length)
Perform a full-duplex SPI transaction.
SPP SPI HAL API — dispatches through the registered HAL port.
ICM20948 interrupt and GPIO context.
volatile spp_bool_t drdyFlag
ICM20948 sensor instance.
ICM20948_SensorData_t lastData
volatile spp_bool_t * p_flag
Describes the contract of a producer module. This module needs to have:
void SPP_HAL_TIME_delayMs(spp_uint32_t ms)
Block for the requested number of milliseconds.
SPP HAL time API — dispatches through the registered HAL port.
Portable integer types and SPI/storage configuration types for SPP.
ACCEL_CONFIG_2 register bit layout.
ACCEL_CONFIG register bit layout.
struct ICM20948_RegAccelConfig_t::@105015127256256334376214066105107137252170116356 bits
REG_BANK_SEL register bit layout.
struct ICM20948_RegBankSel_t::@325125135051365156165251362113041170261051301056 bits
FIFO_CFG register bit layout.
FIFO_EN_1 register bit layout.
FIFO_EN_2 register bit layout.
FIFO_RST register bit layout.
struct ICM20948_RegFifoRst_t::@041065277126235241047134372226063255114241367201 bits
GYRO_CONFIG_1 register bit layout.
struct ICM20948_RegGyroConfig_t::@232176310072375053240213106010173004177117347241 bits
HW_FIX_DISABLE register bit layout.
INT_ENABLE_2 register bit layout.
struct ICM20948_RegIntEnable2_t::@250247060317310121157315035247225131256117306115 bits
INT_ENABLE register bit layout.
struct ICM20948_RegIntEnable_t::@106155203114352110244332375130240203066354261177 bits
LP_CONFIG register bit layout.
struct ICM20948_RegLpConf_t::@166315220372323112372004253100254373042267240270 bits
PWR_MGMT_1 register bit layout.
struct ICM20948_RegPwrMgmt1_t::@253125264070140253032213157135301362240260244352 bits
PWR_MGMT_2 register bit layout.
struct ICM20948_RegPwrMgmt2_t::@375266177224043361340021226124357137226225313223 bits
SINGLE_FIFO_PRIORITY_SEL register bit layout.
USER_CTRL register bit layout.
struct ICM20948_RegUserCtrl_t::@356065150070305204106352010301107244336331356261 bits