2017-01-26 04:31 AM
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) */}&sharpdefine LSM9DS_WHO_AM_I 0x0F
int main(void)
{ hardware init(); // pseudo code // ... spi_read_acc(LSM9DS_WHO_AM_I | 0x80, 1); while(1);}#stm32l011k4 #lsm9ds1Solved! Go to Solution.
2017-01-31 03:16 PM
Wow, when you zoom into the logic analyzer image there is much more detail...
over 55 now, eyesight with focusing is difficult.
I can see on the data sheet, that address 0x1F looks suspiciously like your data...
try reading registers 0x21,0x22,0x23...
your CPOL and CPHA look good.
how long is the data cable ?
what speed are you running, 10khz ? this should be no problem.
where did you buy the chips ?
do you think they could be counterfeit ?
I have been touched by counterfeit product a few times...
Pins 7 and 8 should be low, did you check that ?
what is pin 13 all about ? no details in this sheet, looks like it needs to go high.
2017-01-29 02:39 AM
Any suggestions anyone? We still are struggling with this problem.
2017-01-29 04:32 AM
You might consider posting this question in the
https://community.st.com/community/mems-sensors-community/mems-sensors-forum/content
forum.JW
2017-01-29 06:05 AM
this works for the '091
void quickSendReceive8SPI(SPI_HandleTypeDef *hspi){ while( !( hspi->Instance->SR & SPI_FLAG_TXE)); *((__IO uint8_t *)&hspi->Instance->DR) = TxSPIByte; // force the SPI to transceive 8 bit while( !( hspi->Instance->SR & SPI_FLAG_TXE)); while( ( hspi->Instance->SR & SPI_FLAG_BSY)); while( ( hspi->Instance->SR & SPI_FLAG_RXNE)) RxSPIByte1 = hspi->Instance->DR; }�?�?�?�?�?�?�?�?�?�?
2017-01-29 07:01 AM
Thank you for your comment JW. Can forum admin move this to the 'Sensors and MEMS forum'? Or i can just repost this there?
2017-01-29 01:09 PM
I can see it exactly in your code,
#define SPI_SR_RXNE /*!< 0x00000001 */
#define SPI_SR_TXE /*!< 0x00000002 */#define SPI_SR_BSY /*!< 0x00000080 */You are not checking that the TX is still busy..
Sure the Txbuffer is empty, but the transmission is still in progress.
between lines (4) and (5) above...
add:
while(!(SPI1->SR & 0x02)); /* (4) */
while( SPI1->SR & 0x80 ); /* (4a) */
while(!(SPI1->SR & 0x01)); /* (5) */2017-01-29 01:59 PM
You should be able to move it yourself: on the right upper side just below your avatar there should be an 'Actions' pulldown, and in that a 'Move'.
JW
2017-01-30 06:12 AM
Hello Marsh.Nick, thank you for your answer. We tried to apply your suggestion, however sensor still responds with the same values as previously. So obviously waiting until Tx is not bussy is not the problem here. Any more ideas? Could it possible be something wrong with our SPI configuration?
2017-01-30 03:57 PM
Hi,
If you can check my code above that works on the '091 bxCan peripheral, you will see it is almost exactly the same as yours
did you notice that you needed to insert that line (4a) twice ?
other than that, I used the CubeMX to initialise the SPI port.
2017-01-31 09:04 AM
Yes, we are aware that we had to change the code in two spots. We actually tried today the piece of code which you showed above and it gave the same results. We are considering to change the chip to another. Maybe you have any more ideas? Thank you for your answers.