No SPI response from ICM-20948 (IMU) on STM32
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
