2020-11-27 05:51 AM
I have made a simple setup with 2 ICM-20948 IMU's and an AtSAMD21 MCU, which communicated through I2C and worked fine. Now I've chosen a more powerful MCU (STM32F410R8T6), and decided that a SPI setup would be advantageous. I have made the modifications, but now i get no response at all, from either IMU's. I wondered if someone could help me out.
Datasheet for the IMU is here: https://invensense.tdk.com/wp-content/uploads/2016/06/DS-000189-ICM-20948-v1.3.pdf Pins can be seen on page 1, and SPI interface on page 31.
My pin connections between the devices are as follows:
STM32 -> ICM-20948
PC6 (SPI2_NSS_IMU1) -> 22 (NCS IMU1)
PB12 (SPI2_NSS_IMU2) -> 22 (NCS IMU2)
PB15 (SPI2_MOSI) -> 24 (SDA/SDI IMU1&2)
PB14 (SPI2_MISO) -> 9 (AD0/SDO IMU1&2)
PB13 (SPI2_SCK) -> 23 (SCL/SCLK IMU1&2)
So both IMU's share all wires except NCS, where they have each their own.
I have set up the STM32's SPI with STM32CubeIDE, with settings shown below:
I try to read the register WHO_AM_I which returns an address using the following functions:
void ICM_WHOAMI(Sensor* imu)
{
uint8_t spiData;
ICM_ReadOneByte(imu->number, 0x00, &spiData);
imu->address = spiData;
}
void ICM_ReadOneByte(uint8_t imu_number, uint8_t reg, uint8_t* pData) // ***
{
reg = reg | 0x80; //MSB is always 1 - Indicates read operation
ICM_StartSpiTransfer(imu_number);
HAL_SPI_Transmit_DMA(&hspi2, ®, 1);
while (HAL_SPI_GetState(&hspi2) != HAL_SPI_STATE_READY)
;
HAL_SPI_Receive_DMA(&hspi2, pData, 1);
while (HAL_SPI_GetState(&hspi2) != HAL_SPI_STATE_READY)
;
ICM_EndSpiTransfer(imu_number);
}
void ICM_StartSpiTransfer(uint8_t imu_number)
{
if(imu_number == 1)
{
HAL_GPIO_WritePin(SPI2_NSS_1_GPIO_Port, SPI2_NSS_1_Pin, GPIO_PIN_RESET);
}
else if (imu_number == 2)
{
HAL_GPIO_WritePin(SPI2_NSS_2_GPIO_Port, SPI2_NSS_2_Pin, GPIO_PIN_RESET);
}
}
void ICM_EndSpiTransfer(uint8_t imu_number)
{
if(imu_number == 1)
{
HAL_GPIO_WritePin(SPI2_NSS_1_GPIO_Port, SPI2_NSS_1_Pin, GPIO_PIN_SET);
}
else if (imu_number == 2)
{
HAL_GPIO_WritePin(SPI2_NSS_2_GPIO_Port, SPI2_NSS_2_Pin, GPIO_PIN_SET);
}
}
When i look at the signals with a logic analyzer i see the following:
Nice and clean communication from the STM32, writing two bytes, first being address (Who am i 0x00 + readbit) and the second being empty, as it expects to receive data.
All lines are checked with multimeter, and are connected properly, no pullups or anything on the SPI lines. The device is receiving 2.5V VDDIO and 3.3V VDD
2020-11-27 06:59 AM
Are you sure you run the ICM-20948 at VDDIO=2.5V?
The data sheet of the ICM-20948 only allows a VDDIO in the range of 1.71V...1.95V. But no communication would be possible even if you operated it with 1.95V, since the STM32F410 expects 0.7*VDDmcu as Vih. Maybe either a level shifter or lowering VDD of the MCU would help.
/Peter
2020-11-30 12:24 AM
Hi @Victor Søby ,
as a side note on Peter's insight, please also consider the possibility to ask for support in the TDK community (ICM-20948 is a TDK IMU), in case the issue is device-related.
-Eleon
2020-11-30 01:22 AM
Hey Peter.
I have measured the Voltage on the pins, and I am indeed certain that I have VDDIO = 2.5 V and VDD = 3.3 V.
According to the datasheet, these fall under the absolute max ratings, as the VDD can be -0.5 to 4 V and VDDIO -0.3 to 2.5 V.
Since the output V_High and V_Low are scaled according to VDDIO V_High_Out = 0.9*VDDIO and V_Low_Out = 0.1*VDDIO, the thought was, that level shifters could be avoided, as a MCU supplied with 3.3 V could probably interpret 2.25 V as a high signal.
None of this seem to be the actual issue though, as I see absolutely nothing on the output from the ICM, not 2.25 V, 1.5 V or anything, only around 10 mV buzzing, indicating that something is going on. I don't know if I have destroyed the IC by supplying VDDIO with 2.5, but it seems unlikely, as it worked fine in the last PCB version, where the communication was through I2C instead of SPI, but supplied identical.
2020-11-30 01:23 AM
Hi Eleon.
I will definitely do that. Thank you.