diff --git a/inc/icm20948_api.h b/inc/icm20948_api.h index bc33dab..e6ff5a3 100644 --- a/inc/icm20948_api.h +++ b/inc/icm20948_api.h @@ -29,11 +29,56 @@ #ifndef _ICM20948_API_H_ #define _ICM20948_API_H_ +#include +#include + +#define ICM20948_GYRO_ENABLE (true) +#define ICM20948_GYRO_DISABLE (false) + +#define ICM20948_ACCEL_ENABLE (true) +#define ICM20948_ACCEL_DISABLE (false) + +#define ICM20948_MAG_ENABLE (true) +#define ICM20948_MAG_DISABLE (false) + typedef int8_t(*icm20948_read_fptr_t)(uint8_t addr, uint8_t *data, uint32_t len); typedef int8_t(*icm20948_write_fptr_t)(uint8_t addr, uint8_t *data, uint32_t len); typedef void(*icm20948_delay_us_fptr_t)(uint32_t period); -int8_t icm20948_intf_init(icm20948_read_fptr_t r, icm20948_write_fptr_t w, icm20948_delay_us_fptr_t delay); -int8_t icm20948_writeRegs(void); +typedef enum { + ICM20948_RET_OK = 0, + ICM20948_RET_GEN_FAIL = -1, + ICM20948_RET_INV_PARAM = -2, + ICM20948_RET_NULL_PTR = -3, + ICM20948_RET_INV_CONFIG = -4, + ICM20948_RET_TIMEOUT = -5 +} icm20948_return_code_t; + +typedef struct { + bool gyro_en; + bool accel_en; + bool mag_en; +} icm20948_settings_t; + +typedef struct { + uint16_t x; + uint16_t y; + uint16_t z; +} icm20948_gyro_t; + +typedef struct { + uint16_t x; + uint16_t y; + uint16_t z; +} icm20948_accel_t; + +typedef struct { + uint16_t x; + uint16_t y; + uint16_t z; +} icm20948_mag_t; + +icm20948_return_code_t icm20948_init(icm20948_read_fptr_t r, icm20948_write_fptr_t w, icm20948_delay_us_fptr_t delay); +icm20948_return_code_t icm20948_applySettings(icm20948_settings_t *newSettings); #endif // _ICM20948_API_H_ \ No newline at end of file diff --git a/src/icm20948.c b/src/icm20948.c index 730416a..a290b4c 100644 --- a/src/icm20948.c +++ b/src/icm20948.c @@ -26,32 +26,70 @@ * @brief Source file for the ICM20948 9-Axis MEMS device driver. */ +#include #include "icm20948.h" #include "icm20948_api.h" static icm20948_dev_t dev; +static icm20948_settings_t settings; -int8_t icm20948_intf_init(icm20948_read_fptr_t r, icm20948_write_fptr_t w, icm20948_delay_us_fptr_t delay) { +icm20948_return_code_t icm20948_init(icm20948_read_fptr_t r, icm20948_write_fptr_t w, icm20948_delay_us_fptr_t delay) { - uint8_t reg[5]; - // Store the interface passed in to us. This has pointer references - // for our read, write, and delay functions. + icm20948_return_code_t ret = ICM20948_RET_OK; + + // Verify that the function pointers given to us are not invalid + if( (r == NULL) || (w == NULL) || (delay == NULL) ) { + // One of the functions given to us was a NULL pointer, return with a + // NULL PTR return code + ret = ICM20948_RET_NULL_PTR; + } + + // Store the interface functions passed in to us to be used to + // communicate with the IC. dev.intf.read = r; dev.intf.write = w; dev.intf.delay_us = delay; - dev.intf.read(0x01, dev.usr_bank.bank0.arr, sizeof(dev.usr_bank.bank0.arr)); - dev.intf.write(0x01, dev.usr_bank.bank0.arr, sizeof(dev.usr_bank.bank0.arr)); - dev.intf.delay_us(56); + // Select user register bank 0 + dev.usr_bank.reg_bank_sel = ICM20948_USER_BANK_0; - return 1; -} + if( ret == ICM20948_RET_OK ) { + // Write to the reg bank select to select bank 0 + ret = dev.intf.write(ICM20948_ADDR_REG_BANK_SEL, (uint8_t *)&dev.usr_bank.reg_bank_sel, 0x01); + } -int8_t icm20948_writeRegs(void) { - dev.intf.write(0x00, dev.usr_bank.bank0.arr, sizeof(dev.usr_bank.bank0.arr)); - dev.intf.write(0x01, dev.usr_bank.bank1.arr, sizeof(dev.usr_bank.bank1.arr)); - dev.intf.write(0x02, dev.usr_bank.bank2.arr, sizeof(dev.usr_bank.bank2.arr)); - dev.intf.write(0x03, dev.usr_bank.bank3.arr, sizeof(dev.usr_bank.bank3.arr)); + if( ret == ICM20948_RET_OK) { + // If the bank was selected, read the WHO_AM_I register + ret = dev.intf.read(ICM20948_ADDR_WHO_AM_I, &dev.usr_bank.bank0.bytes.WHO_AM_I, 0x01); - return 1; + // If we read the register, and the ID doesn't match, return with a general failure + if( (ret == ICM20948_RET_OK) && (dev.usr_bank.bank0.bytes.WHO_AM_I != ICM20948_WHO_AM_I_DEFAULT) ) { + // The WHO_AM_I ID was incorrect. + ret = ICM20948_RET_GEN_FAIL; + } + else { + // We read the ID and it matched to what we expected. All is good. + ret = ICM20948_RET_OK; + } + } + + // Return our init status + return ret; } + +icm20948_return_code_t icm20948_applySettings(icm20948_settings_t *newSettings) { + + // Copy over the new settings + memcpy(&settings, newSettings, sizeof(settings)); + + // Act upon and apply the new settings + + if( settings.accel_en == ICM20948_ACCEL_ENABLE ) { + // Enable the accelerometer + } + else { + // Disable the accelerometer + } + + return ICM20948_RET_OK; +} \ No newline at end of file diff --git a/src/icm20948.h b/src/icm20948.h index 1a998d3..f44275d 100644 --- a/src/icm20948.h +++ b/src/icm20948.h @@ -37,14 +37,22 @@ #define ICM20948_BANK2_REG_COUNT (20) #define ICM20948_BANK3_REG_COUNT (25) -#define ICM20948_USER_BANK_0 (0) -#define ICM20948_USER_BNAK_1 (1) -#define ICM20948_USER_BANK_2 (2) -#define ICM20948_USER_BANK_3 (3) - #define ICM20948_WHO_AM_I_DEFAULT (0xEA) #define ICM20948_EXT_SLV_SENS_DATA_COUNT (25) +typedef enum { + ICM20948_USER_BANK_0 = 0x00, + ICM20948_USER_BANK_1 = 0x01, + ICM20948_USER_BANK_2 = 0x02, + ICM20948_USER_BANK_3 = 0x03 +} icm20948_reg_bank_sel_t; + +typedef enum { + ICM20948_ADDR_WHO_AM_I = 0x00, + ICM20948_ADDR_REG_BANK_SEL = 0x7F +} icm20948_reg_bank0_addr_t; + + typedef union { struct { uint8_t WHO_AM_I; @@ -621,6 +629,7 @@ typedef struct { icm20948_reg_bank_1_t bank1; icm20948_reg_bank_2_t bank2; icm20948_reg_bank_3_t bank3; + icm20948_reg_bank_sel_t reg_bank_sel; } icm20948_usr_bank_t; typedef struct { diff --git a/template/main.c b/template/main.c index 3088e3f..5717198 100644 --- a/template/main.c +++ b/template/main.c @@ -51,10 +51,7 @@ void usr_delay_us(uint32_t period) { int main(void) { // Init the ICM20948 dev SPI interface - icm20948_intf_init(usr_write, usr_read, usr_delay_us); - - // Write the regs - icm20948_writeRegs(); + icm20948_init(usr_write, usr_read, usr_delay_us); return 0; } \ No newline at end of file