2020-11-09 01:23 AM
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, ®, 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:
"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):
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
Solved! Go to Solution.
2020-11-11 06:02 AM
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
2020-11-10 03:40 AM
Hi @Fatih ,
yes, the WHO_AM_I value for the I3G2450D product should be 0xD3, not 0xD4...
My question are:
-Eleon
2020-11-10 12:37 PM
Hello Eleon thanks for the response,
On your questions:
2020-11-11 01:00 AM
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
2020-11-11 03:30 AM
Hi @Eleon BORLINI ,
I also do not have access to another mems unit, I'm using the I3G4250D built into the STM32F429ZI (STM32F4-DISC1).
Here is a picture of the board 'm using:I have also succesfully set and read other registers:
i3g4250d_data_rate_set(&dev_ctx, I3G4250D_ODR_800Hz);
HAL_Delay(1000);
i3g4250d_dr_t test_value;
i3g4250d_data_rate_get(&dev_ctx, &test_value);
the value of "test_value" succesfully becomes "I3G4250D_ODR_800Hz". So setting/reading other registers works fine it seems.
Do you have any other idea what the problem might be?
2020-11-11 06:02 AM
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
2020-11-11 06:09 AM
Hi @Eleon BORLINI ,
Thanks a lot, this clarifies everything. But before I continue development I have one last question;
The manual of the STm32F429i says that the MEMS unit being used is a I34250D : Discovery kit with STM32F429ZI MCU - User manual (chapter 6.8)
Did I refer to the wrong manual? or is it a mistake in the manual.
Thanks in advance.
2020-11-11 09:48 AM
No it is the correct manual, but checking the 7.2 Board revision history chapter p.30 you can see that from Revision MB1075 - E01 there is a change:
>> U3: L3GD20 replaced by I3G4250D and R75, C54 added
Maybe the board you have is from another version, the B01 or the C01 (it looks "C" version from your picture, from MB1075C marking)
-Eleon
2020-11-11 11:05 AM
Thanks for clarifying everything @Eleon BORLINI . I am new to the ST eco system/community so I and many others appreciate the help a lot.
Regards,
Fatih
2020-11-12 11:12 PM
Thank you for the appreciation Fatih!
-Eleon