Receiving data from L3GD20 gyroscope sensor via SPI
I'm trying to understand how SPI works on STM32. I use a STM32L472-discovery kit which includes a L3GD20 gyroscope sensor. On the board, STM32L4 is connected to the sensor via SPI2. I configured the GPIO pins needed for SPI2 and provided clocks to the GPIO, SPI units. Below are some of my settings. Note that I'm not suing the HAL library, as it has too many, complex codes.
SPIx->CR1 |= SPI_CR1_CPOL |
SPI_CR1_CPHA |
SPI_CR1_BR_1 |
SPI_CR1_SSM |
SPI_CR1_SSI |
SPI_CR1_MSTR; // STM32 is the master device.
SPIx->CR1 &= ~SPI_CR1_LSBFIRST; // MSB first
/* Data length is 8-bit*/
SPIx->CR2 &= ~(0b1111 << SPI_CR2_DS_Pos); // reset the 4 bits
SPIx->CR2 |= 0b0111 << SPI_CR2_DS_Pos;
/* motorola mode */
SPIx->CR2 &= ~SPI_CR2_FRF;
/* no NSS bit (See Figure 14 in the datasheet) */
SPIx->CR2 &= ~SPI_CR2_NSSP;
/* RXFIFO threshold : half of 8-bit */
SPIx->CR2 |= SPI_CR2_FRXTH;
SPIx->CR1 |= SPI_CR1_SPE;After initializing the MCU, I wanted to send 8-bit data to the sensor and then read the 8-bit received from the sensor. Next I tried to send 8-bit dummy data (0x27) to the sensor and read 8-bit received from the sensor. Below is the content of the Write_and_Read function that I'm using.
uint8_t RW = 1;
uint8_t MS = 0;
uint8_t word = (RW << 7) | (MS << 6);
uint8_t dummy[3] = {0,0,0};
uint8_t dummy_2[10];
uint8_t value[3] = {0,0,0};
word = word + addr;
GPIOD->ODR &= ~(0b1 << 7);
USART_Delay(30000);
for (int k = 0; k < 10; k++) {
dummy_2[k] = SPIx->DR;
}
int i = 0;
int j = 0;
while(!(SPI2->SR & SPI_SR_TXE));
SPI2->DR = word;
while(!(SPI2->SR & SPI_SR_TXE));
while(SPI2->SR & SPI_SR_BSY);
while(SPI2->SR & SPI_SR_RXNE){
dummy[i] = SPI2->DR;
i++;
};
while(SPI2->SR & SPI_SR_BSY);
while(!(SPI2->SR & SPI_SR_TXE));
SPI2->DR = word;
while(!(SPI2->SR & SPI_SR_TXE));
while(SPI2->SR & SPI_SR_BSY);
while(SPI2->SR & SPI_SR_RXNE){
value[i] = SPI2->DR;
j++;
}
while(SPI2->SR & SPI_SR_BSY);
/* copy the value to rBuffer */
*rBuffer = value[i];
USART_Delay(300);
GPIOD->ODR |= (0b1 << 7);
return 0;When a 8-bit number 0x20 is sent, then right after the transmission I red 3 bytes from the RXFIFO. After sending 0x27, this function red 3 bytes again. Below are the sent data and received data. Note that the 0x27 is just dummy data for sending a SCLK signal to the sensor.
addr value
0x20 -> 0xFF 0xFF 0x00
0x27 -> 0x00 0x00 0xFF
0x0F -> 0xFF 0xD4 0x00
0x27 -> 0x00 0x00 0xD4
0x20 -> 0xFF 0x07 0x00
0x27 -> 0x00 0x00 0x07
0x0F -> 0xFF 0xD4 0x00
0x27 -> 0x00 0x00 0xD4
0x20 -> 0xFF 0x07 0x00
0x27 -> 0x00 0x00 0x07I see a couple of problems.
(1) When a byte is sent, then 3 bytes are read from the RXFIFO buffer. The buffer is supposed to have only 1 byte, isn't it?
(The dummy_2 contains only zeros. So there was no data in RXFIFO before the data transmission.)
(2) When 0x0F is sent, then 0xD4 should be received. But this number appears two times among the 6 bytes received after sending 0x0F. When 0x20 is sent, I expect to receive 0x07. This number appears also two times among the next 6 bytes.
(3) For some reason, the first 3 bytes contain two 0xFF 0xFF bytes. This was reproduced many times. It happens once after each MCU reset.
Can someone suggest what might be wrong with my codes?