AnsweredAssumed Answered

STM32L011K4+LSM9ds1tr SPI wrong readings

Question asked by Vycas.Arturas.001 on Jan 26, 2017
Latest reply on Feb 8, 2017 by Vycas.Arturas.001

Hello, we are having problems with communicating to sensor LSM9ds1tr via SPI with sm32l011k4 mcu. The problem is that SPI seems to work good and looking with logic analyzer proves that everything is okey, we are seeing exactly the same thing as mcu reads. We are trying to read the WHO_AM_I register of accelerometer/gyroscope and magnetometer and for some reason we read wrong values compared to the datasheet. According to the data sheet, then reading ACC/Gyro  WHO_AM_I register the value should be 0x68 and then reading Magnetometer WHO_AM_I register the value should be 0x3D. However, when reading these, we always get 0x40 when reading accelerometer/gyro register and we always get 0x38 when reading magnetometer WHO_AM_I register. Could anyone help us to solve the problem and point out what we are doing wrong? I attach the schematics of the sensor, spi initialization code and our reading function + snapshots from logic analyzer. 

 

/*
* @brief: function to configure SPI1 peripheral.
* (1) Set MCU as a master, configure baud rate to fpclk/256
* (2) Slave select output enable
* (3) Enable SPI1 peripheral.
*/
void spi_config(void)
{
SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_BR; /* (1) */
SPI1->CR2 = SPI_CR2_SSOE; /* (2) */
SPI1->CR1 |= SPI_CR1_SPE; /* (3) */
}

/*
* @brief: function to read data from slave via SPI.
* @params: arg1 - reg_ptr: address of the register which you want to read
* arg2 - b_count: number of bytes to read starting from the address given by reg_ptr.
* (1) Create local variable called index, to follow read byte number
* (2) Chip select goes to low level
* (3) Write value to the SPI Tx buffer
* (4) Wait until data is transmitted and Tx fifo is empty
* (5) Wait until Rx fifo is not empty (means some data is received).
* (6) Read received Data.
* (7) Start a loop with number of iterations equal to arg2.
* (8) Send dummy byte so master generates clock for the communication
* (9) Small delay before setting CS back to high
* (10) Chip select goes to high level
* ----------------------------------------------------------------------------------------------
* @Note: Delay (9) will change when changing mcu clock settings
*/
void spi_read_acc(uint8_t reg_ptr, uint8_t b_count)
{
uint8_t index = 0; /* (1) */

GPIOB->ODR &= ~0x20; /* (2) */
SPI1->DR = reg_ptr; /* (3) */
while(!(SPI1->SR & 0x02)); /* (4) */
while(!(SPI1->SR & 0x01)); /* (5) */
spi_rx_data[index++] = SPI1->DR; /* (6) */

for(; index < b_count + 1; index++) /* (7) */
{
SPI1->DR = 0xFF; /* (8) */
while(!(SPI1->SR & 0x02)); /* (4) */
while(!(SPI1->SR & 0x01)); /* (5) */
spi_rx_data[index] = SPI1->DR; /* (6) */
}

for(index = 0; index < 20; index++); /* (9) */
GPIOB->ODR |= 0x20; /* (10) */
}

#define LSM9DS_WHO_AM_I 0x0F

int main(void)
{
hardware init(); // pseudo code
// ...
spi_read_acc(LSM9DS_WHO_AM_I | 0x80, 1);
while(1);
}

Outcomes