tdk-invn-oss / motion.arduino.ICM42670P

Arduino Driver for TDK InvenSense consumer motion sensor ICM42670P
https://invensense.tdk.com/smartmotion
BSD 3-Clause "New" or "Revised" License
31 stars 3 forks source link

Failed IMU begin with error code -12 #14

Open SorabhR opened 1 month ago

SorabhR commented 1 month ago

Hey,

I have DK-42670-P development board. The spi pins are out on J4 for the development board. I have connected my esp32s3 spi pins there. But I am unable to initialise the IMU it is failing with error code -12. Please help if you have any idea to resolve this.

tdk-opensource commented 1 month ago

Thank you for opening this issue! We will look into it shortly.

Notifying @tdk-invn-oss/motion-maintainers @tdk-invn-oss/arduino-maintainers

rbuisson-invn commented 1 month ago

Hello @SorabhR,

Could you please you provide a trace of the SPI signals using scope or logic analyzer? That would greatly help us providing support.

Regards,

SorabhR commented 1 month ago

I am sorry I don't have a logic analyser.

But I tried raw code of spi reading the who_am_i register of the imu and that is working fine. So why is the initialisation only failing with this library?

rbuisson-invn commented 1 month ago

Could you please check the value you read for the who am i?

SorabhR commented 1 month ago

I got 0x67 for who_am_i

rbuisson-invn commented 1 month ago

Thanks, perfect so SPI signals integrity is OK. Could you please share the code you use for the raw who am i read?

SorabhR commented 1 month ago

include

// Define pins const int CS_PIN = 10; // Chip select pin for SPI const

void setup() {

// Initialize SPI

SPI.begin();

// Set CS pin as output

pinMode(CS_PIN, OUTPUT); digitalWrite(CS_PIN, HIGH); // Set CS high initially

Serial.begin(115200);

}

void loop() {

// Select the ICM-42670-P

digitalWrite(CS_PIN, LOW);

// Send a command (example: read from a register, 0x75 is WHO_AM_I register)

SPI.transfer(0x75 | 0x80); // Send WHO_AM_I command (read bit is 1) byte response =

SPI.transfer(0x00); // Read the response

// Deselect the ICM-42670-P

digitalWrite(CS_PIN, HIGH);

Serial.print("WHO_AM_I response: "); Serial.println(response, HEX);

delay(1000); }

rbuisson-invn commented 1 month ago

You don't use Arduino SPI.beginTransaction() method ? What mode is the SPI? (should be MSBFIRST, SPI_MODE3)

SorabhR commented 1 month ago

I have used the default spi mode

rbuisson-invn commented 1 month ago

Could you share the Arduino sketch source code ? At least the part initializing the device.

SorabhR commented 1 month ago

I have used this code only exactly No changes this uses SPI MODE 0

rbuisson-invn commented 1 month ago

Do you call following lines somewhere?: ICM42670 IMU(SPI,10); IMU.begin();

(sorry for the terrible questions, but I need to reduce the scope to understand what could be the issue)

SorabhR commented 1 month ago

During the examples code of the library yes I do call it but in my raw code I do not

Infact IMU.begin only fails

rbuisson-invn commented 1 month ago

Do you confirm that you use 10 in ICM42670 IMU(SPI,10); ? (default is pin 8)

SorabhR commented 1 month ago

Yes I did that change

rbuisson-invn commented 1 month ago

Ok can you try to add the following line in your raw code before starting the who am i read (before digitalWrite(CS_PIN, LOW);): SPI.beginTransaction(SPISettings(6000000, MSBFIRST, SPI_MODE3));

SorabhR commented 1 month ago

Okay I will try that and let you know Any other thing also can I try as I will try things after sometime

rbuisson-invn commented 1 month ago

Yes sure, try other valuesfor SPI clock frequecy and SPI_MODE parameters.

SorabhR commented 1 month ago

Does the library use SPI3 and 6MHz clock?

rbuisson-invn commented 1 month ago

Yes exactly! SPI frequency can be specified, for instance: IMU(SPI,10,1000000);

SorabhR commented 1 month ago

So as far as I understand library uses SPI mode 3 what if the sensor does not work on that and only works on spi mode 0?

rbuisson-invn commented 1 month ago

By default the ICM42670P supports both SPI modes 0 & 3: image

rbuisson-invn commented 1 month ago

Another possible issue, other than SPI settings, could be the delay function: delayMicroseconds(us); The library uses this function before reading the reset status, if this function is not correctly implemented on your platform, this read could occur too early.

SorabhR commented 1 month ago

I am using espcore3 in Arduino ide 2.1 If that helps you understand if delay function is implemented properly

So spi mode 0 and mode 3 both should work.

SorabhR commented 1 month ago

Hey The raw code is working with spi mode 3

rbuisson-invn commented 1 month ago

And with SPI clock @6MHz?

SorabhR commented 1 month ago

Yes that's working too

rbuisson-invn commented 1 month ago

Ok many thanks for these tests and feedback. So it looks like SPI works as implemented in the library...

Let's try validating the delayMicroseconds.... Could you try the following code on your platform? Serial.println(millis()); delayMicroseconds(1000); Serial.println(millis());

And check that the increment between the 2 println is around 1000us.

Regards,

SorabhR commented 1 month ago

Yeah so the difference between the two millis is of 1 which is 1000us

rbuisson-invn commented 1 month ago

That's correct ! So everything works separately :) Might be a stack size issue... Do you have any idea on how to increase stack size on your platform?

Alternatively, you could modify the Documents\Libraries\Arduino\ICM42670\src\ICM42670.cpp in function spi_read, something like following, to check every parameters: static int spi_read(inv_imu_serif serif, uint8_t reg, uint8_t rbuffer, uint32_t rlen) { ICM42670 obj = (ICM42670)serif->context; obj->spi->beginTransaction(SPISettings(obj->clk_freq, MSBFIRST, SPI_MODE3)); digitalWrite(obj->spi_cs,LOW); obj->spi->transfer(reg | SPI_READ); obj->spi->transfer(rbuffer,rlen); digitalWrite(obj->spi_cs,HIGH); obj->spi->endTransaction(); Serial.println(obj->clk_freq); Serial.println(rlen); Serial.println(rbuffer[0]); return 0; }

SorabhR commented 1 month ago

6000000 1 255 This is printed multiple times then ICM42670 initialization failed: -12

rbuisson-invn commented 1 month ago

Could you please add Serial.println(obj->spi_cs); and Serial.println(reg); The rbuffer[0]=0xFF means that MISO was not driven by the sensor.

SorabhR commented 1 month ago

10000000 1 103 10 117

Suddenly it started working but giving garbage values

rbuisson-invn commented 1 month ago

Hello @SorabhR , Your last reply shows a correct who am i read with SPI clock at 1M. What's the garbage you are mentioning?

SorabhR commented 1 month ago

Hey I change spi mode 0 in library and it started giving data

rbuisson-invn commented 1 month ago

Ok looks like SPI signal integrity is not so good finally. Could you please try to write the DRIVE_CONFIG3 register to 0x3 or 0x2 ? This will reduce the SPI slew rate, which is required to avoid crosstalk in some specific setup. image

SorabhR commented 1 month ago

But with mode0 it is working fine so what would changing slew rate help in?

rbuisson-invn commented 1 month ago

If SPI signals are not fully safe you will probably have other issues later in your dev. There should be no reason for mode 0 to work better than mode 3 (the only diff is the clock state when CS is high).

SorabhR commented 1 month ago

So In spi mode 0 I should change the slew rate but when I change the spimode3 will re powering both sensor and esp cause the settings to go back to factory default?

rbuisson-invn commented 1 month ago

The slew rate is reset at power up. The register I pointed out changes the SPI signal form only for MISO. So it doesn't impact write access.

SorabhR commented 1 month ago

So should I set that in the Imu.begin function?

rbuisson-invn commented 1 month ago

Yes before inv_imu_init, you could do something like: uint8_t data = 0x03; spi_write(&icm_serif,0x05,&data,1);

SorabhR commented 1 month ago

Okay

rbuisson-invn commented 1 month ago

Hello @SorabhR,

Any feedback on that test?

Regards,

SorabhR commented 1 month ago

Hey Sorry for late reply but it didn't work only spi mode 0 is working