cancel
Showing results for 
Search instead for 
Did you mean: 

Using LSM9DS1 Sensors on the STM32 WB55RG (SPI)

junhee
Associate

Hello. I wrote the following code to use the LSM9DS1 sensor with the STM32 WB55RG board. The current issue is that when I set the gyro to 0x18 and the accel to 0x28, as specified in the sensor datasheet, the accelerometer and gyro values are swapped when read. However, gyro x, gyro y, accel x, accel y, and accel z values are correct in terms of their output, even though they are read from the wrong position. The issue is that the gyro z value does not respond to sensor movement.

void lsm9ds1_read_data_polling(void)

{

stmdev_ctx_t dev_ctx_imu;



/* Initialize inertial sensors (IMU) driver interface */

dev_ctx_imu.write_reg = platform_write_imu;

dev_ctx_imu.read_reg = platform_read_imu;

dev_ctx_imu.handle = &hspi1;



/* Wait sensor boot time */

platform_delay(20);



/* Check device ID */

uint8_t who_am_i = LSM9DS1_ReadRegister(LSM9DS1_WHO_AM_I_AG);

if (who_am_i != LSM9DS1_WHO_AM_I_VALUE) {

while (1) {

/* Device not found, handle error */

}

}



LSM9DS1_InitGyro();

platform_delay(100);

LSM9DS1_InitAccel();

platform_delay(100);



/* Read samples in polling mode */

while (1) {

LSM9DS1_ReadGyro();

platform_delay(20);



LSM9DS1_ReadAccel();

platform_delay(20);

}

}



/* Platform-dependent functions */

static int32_t platform_write_imu(void *handle, uint8_t reg, const uint8_t *bufp, uint16_t len)

{

uint8_t txData[1 + len];

txData[0] = reg & ~LSM9DS1_READ_MASK; // Write operation

memcpy(&txData[1], bufp, len);



LSM9DS1_CS_Enable();

HAL_SPI_Transmit((SPI_HandleTypeDef*)handle, txData, 1 + len, 1000);

LSM9DS1_CS_Disable();

return 0;

}



static int32_t platform_read_imu(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)

{

reg |= LSM9DS1_READ_MASK; // Read operation



LSM9DS1_CS_Enable();

HAL_SPI_Transmit((SPI_HandleTypeDef*)handle, &reg, 1, 1000);

HAL_SPI_Receive((SPI_HandleTypeDef*)handle, bufp, len, 1000);

LSM9DS1_CS_Disable();

return 0;

}



static void platform_delay(uint32_t ms)

{

HAL_Delay(ms);

}



/* SPI Communication Functions */

static void LSM9DS1_CS_Enable(void)

{

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS Low

}



static void LSM9DS1_CS_Disable(void)

{

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS High

}



static void LSM9DS1_WriteRegister(uint8_t reg, uint8_t data)

{

uint8_t txData[2];

txData[0] = reg & ~LSM9DS1_READ_MASK; // Write operation

txData[1] = data;



LSM9DS1_CS_Enable();

HAL_SPI_Transmit(&hspi1, txData, 2, HAL_MAX_DELAY);

LSM9DS1_CS_Disable();



HAL_Delay(5);

}



static uint8_t LSM9DS1_ReadRegister(uint8_t reg)

{

uint8_t txData = reg | LSM9DS1_READ_MASK;

uint8_t rxData;



LSM9DS1_CS_Enable();

HAL_SPI_Transmit(&hspi1, &txData, 1, HAL_MAX_DELAY);

HAL_SPI_Receive(&hspi1, &rxData, 1, HAL_MAX_DELAY);

LSM9DS1_CS_Disable();



return rxData;

}



static void LSM9DS1_InitGyro(void)

{

LSM9DS1_WriteRegister(LSM9DS1_CTRL_REG1_G, 0x60); // 119 Hz, 2000 dps

LSM9DS1_WriteRegister(LSM9DS1_CTRL_REG4, 0x38); // X, Y, Z axis enabled

LSM9DS1_WriteRegister(LSM9DS1_CTRL_REG3_G, 0x00); // Set to normal mode

HAL_Delay(10);

}



static void LSM9DS1_InitAccel(void)

{

LSM9DS1_WriteRegister(LSM9DS1_CTRL_REG6_XL, 0x60); // 119 Hz, ±2g

HAL_Delay(10);

}



static void LSM9DS1_ReadGyro(void)

{

uint8_t rxData[6];

uint8_t regAddr = (LSM9DS1_OUT_X_L_G) | LSM9DS1_READ_MASK;



LSM9DS1_CS_Enable();

HAL_SPI_Transmit(&hspi1, &regAddr, 1, HAL_MAX_DELAY);

HAL_Delay(1);

HAL_SPI_Receive(&hspi1, rxData, 6, HAL_MAX_DELAY);

LSM9DS1_CS_Disable();



gyroX = (int16_t)(rxData[0] | (rxData[1] << 8));

gyroY = (int16_t)(rxData[2] | (rxData[3] << 8));

gyroZ = (int16_t)(rxData[4] | (rxData[5] << 8));

}



static void LSM9DS1_ReadAccel(void)

{

uint8_t rxData[6];

uint8_t regAddr = LSM9DS1_OUT_X_L_XL | LSM9DS1_READ_MASK;



LSM9DS1_CS_Enable();

HAL_SPI_Transmit(&hspi1, &regAddr, 1, HAL_MAX_DELAY);

HAL_Delay(1);

HAL_SPI_Receive(&hspi1, rxData, 6, HAL_MAX_DELAY);

HAL_Delay(10);

LSM9DS1_CS_Disable();



accelX = (int16_t)(rxData[0] | (rxData[1] << 8));

accelY = (int16_t)(rxData[2] | (rxData[3] << 8));

accelZ = (int16_t)(rxData[4] | (rxData[5] << 8));

}
1 ACCEPTED SOLUTION

Accepted Solutions
Peter BENSCH
ST Employee

Unfortunately, the LSM9DS1 was cancelled a long time ago, which is why there is no longer any official information available. I'm afraid that if none of the users here can help, you won't get an answer.

I am very sorry not to be able to give you a more positive answer.

Regards
/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

1 REPLY 1
Peter BENSCH
ST Employee

Unfortunately, the LSM9DS1 was cancelled a long time ago, which is why there is no longer any official information available. I'm afraid that if none of the users here can help, you won't get an answer.

I am very sorry not to be able to give you a more positive answer.

Regards
/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.