cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F429I-DISC1 I2C Communication with onboard ST MEMS Gyroscope

SAgaz.1
Associate II

I am trying to retrieve data from the onboard ST MEMS gyroscope, but while setting up I2C I have been running into issues. At first I consulted the gyroscope data sheet to find the address associated with it, but both values (0x68 and 0x69) shifted to the left did not work.

https://www.st.com/resource/en/datasheet/i3g4250d.pdf

As such I decided to try and find different addresses on the board as a starting point, but using HAL_I2C_IsDeviceReady() yielded no results, I tried some tracing and then a switch statement to see what type of HAL return types I was receiving (HAL_BUSY, HAL_TIMEOUT, HAL_ERROR) and all of the responses from addresses 0-128 were all HAL_BUSY.

Some searching led me to __HAL_RCC_I2C1_FORCE_RESET(); as well as the reset release function, using the force reset on its own renders all the addresses as HAL_TIMEOUT instead, releasing afterwards sends me back to HAL_BUSY again.

I restarted my code again and used CUBEMX but ended up with the same problems, I can't seem to see if there's something I'm missing either.

3 REPLIES 3
SAgaz.1
Associate II

After doing a bit more searching, I came across the fact that in the documentation that the busy bit in the SR2 register is only set to 1 when either SDA or SCL is low, the issue being that as soon as i initialize the clock this seems to happen. given that however from my understanding editing the PUPDR register for pin 6 and 7 and setting it to pull up should force both lines to be high by default? However it doesn't seem to be changing the fact that the busy bit is still set to 1 on IC21 clock enable, leading me to assume that it is still somehow pulling both or at least one line low.

SAgaz.1
Associate II

I've done a bit more looking and some more possible configuration with my GPIO pins, though no matter what I try I cant seem to pull the lines up, the busy register is still set the moment I initiate the I2C1 clock in apb1. Resetting, using the software reset in the I2C control register, reset and reset releasing, DeInit also does not work which leads me to believe that theres something very wrong with my initialization though the only that comes up to mind is pullup, though from what I understand setting the appropriate bits to '10' in PUPDR should fix that. I also trimmed out all the code including USART1 that I was using to isolate it even more, though still no luck.

SAgaz.1
Associate II

So after initiating the I2C Alternate function pins using the HAL initiation method (GPIO_InitTypeDef) the busy bit is no longer set, I'm not entirely sure why using this method to initiate the pins stopped this problem from happening, but at least its done for now. And so I decided to do more tracing because now I get HAL_ERROR instead. The error itself comes from

hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress);

Which saves a value into the DR register in my instance of IC2 (IC21). The I2C_7BIT_ADD_WRITE() macro is defined as

((uint8_t)((__ADDRESS__) & (uint8_t)(~I2C_OAR1_ADD0)))

Which I can only assume that it pulls the Lsb from I2C1's OAR1 register, nots it and then bitwise & with the input address. I believe when this operation occurs and no response was received from any slaves the AF bit is then set instead of ADDR, which branches me away from the possible HAL_OK return value and instead towards HAL_ERROR. The issue with this is that I am trying to poll ALL possible addresses on my board trying to find the gyroscope using

HAL_I2C_IsDeviceReady(&hi2c1,i << 1, 5, 50);

&hi2c1 being my I2C1 handle, i starting at 0 iterated all the way to 128, and every single address returns a HAL_ERROR, not a single response comes from any possible address on the bus, the ST-MEMS I3G4250D gyroscope included

On a side note alongside these traces I was watching some of the registers to see if values inside of the IC21 registers were changing/being enabled such as SB and PE, and they were indeed being changed as I traced the code as well as the busy bit which would set and then unset at the end of HAL_I2C_IsDeviceReady(), which I assume is standard to hold the bus and be able to transact with whatever slave I am communicating with.