SPI communication with ICM42688P does not work well

By c1303982stkana… , 27 August 2024

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.

mustafayildiri…

1 year 6 months ago

Hello,

What firmware are you using? Did you try with MotionLink and eMD?

phpbb Post ID
46451

c1303982stkana…

1 year 6 months ago

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.

phpbb Post ID
46463

mustafayildiri…

1 year 6 months ago

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

phpbb Post ID
46489

c1303982stkana…

1 year 6 months ago

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?

phpbb Post ID
46498

mustafayildiri…

1 year 6 months ago

Yes, you need to make sure you are reading 0x47 from the whoami register.

phpbb Post ID
46594
phpbb Topic ID
46440