I am using the WhoAmI register of the ICM42688P for bidirectional communication, but no matter which program I try, the value returned is 0x0, not 0x47.
Is there some other setting?
Best regards.
I am using the WhoAmI register of the ICM42688P for bidirectional communication, but no matter which program I try, the value returned is 0x0, not 0x47.
Is there some other setting?
Best regards.
Hello,
What firmware are you using? Did you try with MotionLink and eMD?
Thank you for your response.
I am writing my own firmware using the HAL function in STM32cubeIDE.
List of codes↓
.cpp
#define WHO_AM_I 0x75
#define PWR_MGMT_0 0x4E
#define DEVICE_CONFIG 0x11
#define DRIVE_CONFIG 0x13
#define GYRO_CONFIG 0x4F
#define GYRO_ZOUT_H 0x29
#define GYRO_ZOUT_L 0x2A
#define GYRO_FACTOR 16.4 // if ±2000 dps range is selected
ICM42688P::ICM42688P(SPI_HandleTypeDef &hspi, GPIO_TypeDef *cs_x, uint16_t cs_pin): hspi_(hspi), cs_x_(cs_x), cs_pin_(cs_pin){}
uint8_t ICM42688P::read_byte(uint8_t reg) {
uint8_t rx_data[2];
uint8_t tx_data[2];
tx_data[0] = reg | 0x80;
tx_data[1] = 0x00; // dummy
HAL_GPIO_WritePin(cs_x_, cs_pin_, GPIO_PIN_RESET);
HAL_SPI_TransmitReceive(&hspi_, tx_data, rx_data, 2, 1);
HAL_GPIO_WritePin(cs_x_, cs_pin_, GPIO_PIN_SET);
return rx_data[1];
}//rx:receive,tx:transmit
void ICM42688P::write_byte( uint8_t reg, uint8_t val) {
uint8_t rx_data[2];
uint8_t tx_data[2];
tx_data[0] = reg & 0x7F;
tx_data[1] = val; // write data
HAL_GPIO_WritePin(cs_x_, cs_pin_, GPIO_PIN_RESET);
HAL_SPI_TransmitReceive(&hspi_, tx_data, rx_data, 2, 1);
HAL_GPIO_WritePin(cs_x_, cs_pin_, GPIO_PIN_SET);
}
void ICM42688P::setup() {
uint8_t who_am_i;
HAL_Delay(50); // wait start up
who_am_i = read_byte(WHO_AM_I); // 1. read who am i
printf( "who : 0x%x\n",who_am_i); // 2. check who am i value
// error check
if ( who_am_i != 0x47){
while(1){
printf( "gyro_error\r");
}
}
HAL_Delay(50); // wait
write_byte(DEVICE_CONFIG, 0x00);
HAL_Delay(50);
write_byte(PWR_MGMT_0, 0x1F); // set pwr_might
HAL_Delay(50);
write_byte(DRIVE_CONFIG, 0x03); // set config
HAL_Delay(50);
write_byte(GYRO_CONFIG, 0x06); // set gyro config 32kHz 2000dps
HAL_Delay(50);
}
float ICM42688P::read_gyro_z(){
int16_t gyro_z;
float omega;
// H:8bit shift, Link h and l
gyro_z = (int16_t)( (int16_t)(read_byte(GYRO_ZOUT_H) << 8 ) | read_byte(GYRO_ZOUT_L) );
omega = (float)( gyro_z / GYRO_FACTOR ); // dps to deg/sec
return omega;
}
.hpp
class ICM42688P {
public:
ICM42688P(SPI_HandleTypeDef &hspi, GPIO_TypeDef *cs_x, uint16_t cs_pin);
uint8_t read_byte(uint8_t reg);
void write_byte(uint8_t reg, uint8_t val);
void setup();
float read_gyro_z();
private:
SPI_HandleTypeDef &hspi_;
GPIO_TypeDef *cs_x_;
uint16_t cs_pin_;
};
Best regards.
Hello,
Unfortunately, I can’t help with debugging your code. Please take a peek at our eMD firmware on Microchip Studio to see how we set it up: https://invensense.tdk.com/developers/software-downloads/#smartmotion
Thank you for your response.
I have tried everything and the value returned by the whoami() register is 0xe7, does this mean that the communication is not going well?
Yes, you need to make sure you are reading 0x47 from the whoami register.