2026-05-21 3:45 PM
Hello
I have custom PCB with STM32G491KE connected to an LSM6SV80X IMU directly via SPI. I'm having an issue with not being able to receive any data from the IMU, the the read value is always 0xFF which I've read is usually an issue with the slave/subnode/agent device not responding.
Here's how the SPI interface is configured (via CubeMX with X-CUBE-MEMS1)
__weak HAL_StatusTypeDef MX_SPI1_Init(SPI_HandleTypeDef* hspi)
{
HAL_StatusTypeDef ret = HAL_OK;
hspi->Instance = SPI1;
hspi->Init.Mode = SPI_MODE_MASTER;
hspi->Init.Direction = SPI_DIRECTION_2LINES;
hspi->Init.DataSize = SPI_DATASIZE_8BIT;
hspi->Init.CLKPolarity = SPI_POLARITY_LOW;
hspi->Init.CLKPhase = SPI_PHASE_1EDGE;
hspi->Init.NSS = SPI_NSS_SOFT;
hspi->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi->Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi->Init.TIMode = SPI_TIMODE_DISABLE;
hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi->Init.CRCPolynomial = 7;
hspi->Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi->Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(hspi) != HAL_OK)
{
ret = HAL_ERROR;
}
return ret;
}From the datasheet of the IMU I can say:
Furthermore, the pins are configured for no pull down/up and alternative function with push-pull. GPIO OSPEED is set to medium as the default was low which seemed slow. There is no external circuitry between the MCU and the IMU.
VDD and VDDIO on the IMU are both powered via 3V3 and the G4 is also powered from the same 3V3.
CubeMX generated an SPI send and SPI Recv functions to use with the interface generated using X-CUBE-MEMS1 but I swear they would not work as is since the write and read don't send the register value so I wrote my own using HAL. The odd parameters for the function is due to a generated struct expecting a function pointer of this type. That's why reg is 16 bits instead of 8 and dummy is cast to void (dummy is the device address used if the interface is configured for I2C).
int32_t my_SPI1_Send(uint16_t dummy, uint16_t reg, uint8_t * pData, uint16_t length){
(void)dummy;
uint8_t reg8 = (uint8_t)reg;
HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi1, ®8, 1, BUS_SPI1_POLL_TIMEOUT);
HAL_SPI_Transmit(&hspi1, (uint8_t*) pData, length, BUS_SPI1_POLL_TIMEOUT);
HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET);
return 0;
}
int32_t my_SPI1_Recv(uint16_t dummy, uint16_t reg, uint8_t * pData, uint16_t length){
(void)dummy;
reg |= 0x0080;
uint8_t reg8 = (uint8_t)reg;
HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi1, ®8, 1, BUS_SPI1_POLL_TIMEOUT);
HAL_SPI_Receive(&hspi1, pData, length, BUS_SPI1_POLL_TIMEOUT);
HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET);
return 0;
}Any data received is always 0xFF. All functions return fine (HAL_OK) but the data is always all ones. I've read this can be from the subnode device not doing anything with the MISO line. I've stepped through the code and the register and data to send are both good. It is important to mention I made two PCBs and the behaviour is the same (I've not done every test on both boards but neither work and receive only 0xFF) so it's hard to imagine it's damage unless I'm very unfortunate. A configuration issue, some HW issue, or some esoteric SPI thing are the only options I can imagine is going on at this point.
Fearing HAL could be doing something, I wrote a very slim register version, here just grabbing the WHO_AM_I register but same outcome. (__IO is a alias for volatile)
uint8_t reg = 0x80 | LSM6DSV80X_WHO_AM_I;
uint8_t whoami = 0xAA;
HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_RESET);
hspi1.Instance->CR1 |= SPI_CR1_SPE;
while (!(SPI1->SR & SPI_SR_TXE)) {};
*(__IO uint8_t *)&hspi1.Instance->DR = (* (uint8_t *)reg);
while (!(SPI1->SR & SPI_SR_RXNE)) {};
(* (uint8_t *)whoami) = *(__IO uint8_t *)&hspi1.Instance->DR;
while (SPI1->SR & SPI_SR_BSY) {};
HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET);Unfortunately the pins that I selected on the G4 (PA6, PA7) cannot be configured for I2C so swapping SPI for I2C is not an option.
I have not scoped any of the signal lines yet... and I still can but the PCB is very very small and would require scraping some of the soldermask off so I'm trying to fix it before it comes to that.
Thank you
2026-05-22 1:05 AM
Have you used a scope and/or logic analyser to see what's actually happening on the wires?
2026-05-22 5:45 AM
+1 to using the oscilloscope/LA; but you can/should also read out and check/post the relevant GPIO and/or SPI registers content, and also a good exercise may be to try to bit-bang the interface.
JW