Skip to main content
Visitor II
November 9, 2020
Solved

Getting wrong register value when reading "WHO_AM_I" register on I3G2450D mems. (STM32F429ZIT)

  • November 9, 2020
  • 1 reply
  • 3452 views

I'm using the following driver: STMems_Standard_C_drivers/i3g4250d_STdC at master · STMicroelectronics/STMems_Standard_C_drivers (github.com)

You can ignore the details of the driver code but the important thing to note is that

The driver requires you to write your own "platform_read" function since this is platform dependent.

I am using SPI and this is how my implementation looks like:

static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
{
 uint32_t msTimeOut = 1000;
 reg |= 0x80;
 //I3G2450D_CS_ENABLE;
 HAL_GPIO_WritePin(MEMS_CS_GPIO_Port, MEMS_CS_Pin, GPIO_PIN_RESET);
 HAL_SPI_Transmit(handle, &reg, 1, msTimeOut);
 HAL_SPI_Receive(handle, bufp, len, msTimeOut);
 //I3G2450D_CS_DISABLE;
 HAL_GPIO_WritePin(MEMS_CS_GPIO_Port, MEMS_CS_Pin, GPIO_PIN_SET);
 
 return 0;
}

When using this function to read the "WHO_AM_I" register (Address: 0x0FU) I am supposed to get the hex value "0xD3U" (Decimal: 211) but the function call sets the wrong value in "bufp". I get hex "0xd4", following is a screenshot from a debugging session:

 0693W000005AknEQAS.png"whoamI" is the value that gets sets from reading the register and "I3G240D_ID" is the expected value.

In binary the expected value is: 11010011, this is correct according to manual of the gyroscope, but what I get is: 11010100.

My SPI init:

static void MX_SPI5_Init(void)
{
 
 /* USER CODE BEGIN SPI5_Init 0 */
 
 /* USER CODE END SPI5_Init 0 */
 
 /* USER CODE BEGIN SPI5_Init 1 */
 
 /* USER CODE END SPI5_Init 1 */
 /* SPI5 parameter configuration*/
 hspi5.Instance = SPI5;
 hspi5.Init.Mode = SPI_MODE_MASTER;
 hspi5.Init.Direction = SPI_DIRECTION_2LINES;
 hspi5.Init.DataSize = SPI_DATASIZE_8BIT;
 hspi5.Init.CLKPolarity = SPI_POLARITY_LOW;
 hspi5.Init.CLKPhase = SPI_PHASE_1EDGE;
 hspi5.Init.NSS = SPI_NSS_SOFT;
 hspi5.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
 hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB;
 hspi5.Init.TIMode = SPI_TIMODE_DISABLE;
 hspi5.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
 hspi5.Init.CRCPolynomial = 10;
 if (HAL_SPI_Init(&hspi5) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN SPI5_Init 2 */
 
 /* USER CODE END SPI5_Init 2 */
 
}

What I have tried (without success):

  • Changing the baud rate prescaler.
  • Changing first bit from MSB to LSB. (manual says data is sent MSB first but I thought trying was worth it.)
  • changing CPOL to "High"
  • changing CPHA to "2 Edges" (note when I change this in combination with CPOL I get different results (decimal 255) but still not the correct one)
  • double checked Chip Select line (according to manual PC1 is the correct CS line for the I3G2450D)
  • set a delay after setting CS line to high/low
  • set a delay before/after reading with SPI_Transmit / SPI_Recieve

I'm out of options as to what the problem could be (other than hardware related), google suggests trying the same things I did above so maybe someone with more experience knows a solution.

Regards,

Fatih

    This topic has been closed for replies.
    Best answer by Eleon BORLINI

    Hi @Fatih​ ,

    well, I believe I found the issue...

    The fact is that on the STM32F429 the mounted device is the L3GD20 instead of I3G4250D, for which the WHO_AM_I is 0xD4.

    You can see it by considering the software package related to this hardware platform, the STSW-STM32138. In the folder Utilities\STM32F429I-Discovery, you can see that in the stm32f429i_discovery_l3gd20.h is declared the following:

    #define I_AM_L3GD20		 ((uint8_t)0xD4)

    So I suggest you to use this code as starting point, instead of the C libraries on Github.

    If it solved the issue, please mark this answer as Best answer so that t can be useful for future users.

    -Eleon

    1 reply

    ST Employee
    November 10, 2020

    Hi @Fatih​ ,

    yes, the WHO_AM_I value for the I3G2450D product should be 0xD3, not 0xD4...

    My question are:

    • Did you test a single device or also other devices?
    • Regardless the WHO_AM_I response value, were you able to read/write other registers?

    -Eleon

    FatihAuthor
    Visitor II
    November 10, 2020

    Hello Eleon thanks for the response,

    On your questions:

    • No other Peripherals are connected to the MCU.
    • I have not tested it on another MCU since I do not have access to a 2nd STM32F429ZI.
    • When I try to read other registers like the I3G4250D_OUT_X_L I get random values that do not change in accordance with the device changing angle/moving.
    • I have not yet tried setting specific register values and then reading them to verify the reading/writing process. I will do that next, thanks for the tip.

    ST Employee
    November 11, 2020

    Hi @Fatih,

    And do you have the possibility to try another I3G4250D?

    You can also send me a picture of the top marking of the device package, in order to understand if it is actually a I3G4250D device or something else.

    By the way, before reading the output registers, it is however required to write some configuration registers and wait the proper timings, as described in i3g4250d_read_data_polling.c and in the datasheet.

    -Eleon​