Electrical – Why will HAL_SPI_Receive() not read the L3GD20H gyro on the STM32F303 Discovery board

spistm32f3

I have an STM32F303 discovery board for which the mems gyro L3GD20H is connected to the SPI1 peripheral by default, that is the Sclk, MISO and MOSI are connected to pins PA5, PA6 and PA7 respectively. The chip enable is connected to PE3. I need to understand the high level functions from the HAL library for the STM32F3 microcontroller. Hence, for experimentation, I try to communicate with the gyro using HAL_SPI_Transmit() and HAL_SPI_Receive().

I use CubeMX to initialize all peripherals. Settings for the SPI1 is shown below

enter image description here

Since CubeMX takes care of initialization code, I will only show the additional code that enables the control register ctrlReg1 with 0x0f (see figure)

enter image description here

I do not care about settings, I just wish to get some data in polling mode.
The XDataOut_L register (0x28) is the one that I try to read

I use CubeMX and AC6, that is System Workbench (Eclipse-based), to build/compile and run/debug the project. The user-defined code is as follows

uint8_t data_ctrl1, address_ctrl1;
uint8_t data_out1, address_out1;

HAL_GPIO_WritePin(GPIOE,GPIO_PIN_3, GPIO_PIN_RESET);
address_ctrl1 = 0x20;
data_ctrl1 = 0x0f;
HAL_SPI_Transmit(&hspi1, &address_ctrl1, 1, 50);
HAL_SPI_Transmit(&hspi1, &data_ctrl1, 1, 50);
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_3, GPIO_PIN_SET);

while(1)
{
    HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);
    address_out1 = 0x28 | 0x80;  // MSB bit = 1 to read
    HAL_SPI_Transmit(&hspi1, &address_out1, 1, 50);
    HAL_SPI_Receive(&hspi1, &data_out1, 1, 50);
    HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);
    HAL_Delay(100);
 }

The code is based on an example on YouTube (MohamedYaqoobSTM) where Mohamed successfully reads his LIS302DL on his STM32F4 Discovery board.

My question is why will not the SPI_HAL_Receive() work as intended?
I always get result 255 on the data_out1 buffer…

Best Answer

Don't worry, you might be getting correct data. It could or should be 255, depending on how youre reading it in through software. The first thing to do to see if you can properly communicate with the L3GD20 is try to read its name by reading from the WhoAmI register. It should return a value set for the L3GD20 and you can verify it quickly.

The data in the registers will be in a signed 16 bit format, which is done by sending half of the data in the first register and half in the second, and you need to either have both to see if theres a negative or you need to be careful about interpreting your data.

Heres what I mean. If you receive a positive signed number the two registers might look like this: UPPER LOWER 00000000 00010100 But if the same number is negative it will look like this: UPPER LOWER 11111111 11101100 This data is in two's complement. Now if you read the data as an unsigned 8 bit (uint8_t) for both the value will say one thing and if you read to a signed 8 bit for both the data will read quite differently. A 255 likely means a smaller number for the upper half register read as a uint8_t or maybe some kther combinations. If you try to read as a signed or unsigned 16 integer you'll likely get the same data as unsigned 8 bit.

To put both together, you'll have to do some trickery with the bits. In essence, read both in, bit shift one of them, concatenate, make sure to check and delete for the negative bit, and convert from twos comp if needed. There are also ways to fix this with casting, but I couldnt say off the top of my head how.

You can see this in my library for the L3GD20 which is in a git repository located here: https://github.com/sjgallagher2/MEMS-USB?files=1 It can be annoying, when you just want something to work and you keep realizing there are more things you have to consider. The library L3GD20.h is just a riff on the Discovery header from ST. I just made it more practical, not dependent on as much.

Let me know if you're having trouble, it's late but when I look I'm sure theres plenty of detail available I can point out. Good luck.

Sam