cancel
Showing results for 
Search instead for 
Did you mean: 

I2C problem, not getting the ACK bit

esovo1
Associate II
Posted on January 06, 2015 at 17:35

Hello,

I am trying to communicate with the Barometric sensor MS5611, using the I2C protocol. My micro is STM32f3discovery. The address of the sensor is send, but not the command. The code is stucked in the while loop waiting for TXIE bit to be set. The reason why TXIE is not ''one'', is because the acknowledge bit from the MS5611 is not showing up. Also the I2C status register is setting the NACK (not acknowledge), STOPF (stop flag) bit.

The address of the MS5611 sensor is 11101 This can be seen in the datasheet on the page In my case the value of CSB is zero.

http://www.meas-spec.com/downloads/MS5611-01BApdf

But the O-scope shows me different a picture:

http://s1photobucket.com/user/esovo/media/Newfile1_zps0461710c.jpeg.html

here is the code for reseting the sensor:

#define ADDR_W 0xEC // device address + write mode
void Alti_reset( uint8_t ComandAddr)
{
/* Test on BUSY Flag */
while(I2C_GetFlagStatus(I2C1, I2C_ISR_BUSY) != RESET);
/* Configure slave address, nbytes, reload, end mode and start or stop generation */ 
I2C_TransferHandling(I2C1, ADDR_W, 1, I2C_AutoEnd_Mode, I2C_CR2_START); // I2C_Reload_Mode
/* Wait until TXIS flag is set */ 
while(I2C_GetFlagStatus(I2C1, I2C_ISR_TXIS) == RESET); // I2C_ISR_TXE)
/* Send Register address */
I2C_SendData(I2C1, (uint8_t) ComandAddr);
/* Wait until STOPF flag is set */
while(I2C_GetFlagStatus(LSM303DLHC_I2C, I2C_ISR_STOPF) == RESET);
/* Clear STOPF flag */
I2C_ClearFlag(I2C1, I2C_ICR_STOPCF); 
}

So, What I am missing? ... TNX #i2c-stm32-ms5611
12 REPLIES 12
stm322399
Senior
Posted on January 06, 2015 at 17:46

The address bit is the *complementary* of CSB. Try address 0xEE.

--

laurent

esovo1
Associate II
Posted on January 07, 2015 at 13:00

Hei Laurent,

I have try it both, but it isn't working. Here is the proof:

0690X0000060581QAA.png

stm322399
Senior
Posted on January 07, 2015 at 14:02

Not sure that this may hurt, but can you make sure that GPIO are open drain and not push-pull ?

What about your sensor wiring ? What's the level of PS pin ?

esovo1
Associate II
Posted on January 07, 2015 at 15:06

okey, they are now in open drain. The PS is high.

here is the picture with the wiring:

http://s1378.photobucket.com/user/esovo/media/20150107_150054_zps51b4c937.jpg.html?filters%5buser%5d=142303127&filters%5brecent%5d=1&sort=1&o=0

Note: the capacitor is between VCC in GND. It is not obvious in the picture.

stm322399
Senior
Posted on January 07, 2015 at 15:18

I am a bit concerned with the level shift observed at high level at the moment the I2C starts. Are you sure that you correctly configured GPIO as open drain in the PIO controller of the STM32 ?

esovo1
Associate II
Posted on January 08, 2015 at 12:53

They are in open drain configuration. Here is the code:

void I2C_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
/* Enable the I2C periph */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
/* Enable SCK and SDA GPIO clocks - they are both on port B*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB , ENABLE);
/* I2C SCK and SDA pin configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_4); //SCK-> PB6
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_4); //SDA-> PB7
/* I2C configuration -------------------------------------------------------*/
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStructure.I2C_DigitalFilter = 0x00;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_Timing = 0x10420F0D;
/* Apply values to the I2C registers */
I2C_Init(I2C1, &I2C_InitStructure);
/*Enable I2C Peripheral */
I2C_Cmd(I2C1, ENABLE);
}

Could it be that my timing is off and thats way I get the high bit at 9th SCK place? Is this a STOP bit?
stm322399
Senior
Posted on January 09, 2015 at 10:34

Looks good. Except GPIO @50MHz, which is an overkill for I2C and creates ring effect, try to setup lower, just enough for 100KHz.

Can you address the sensor on the F3disco board (same i2C bus) ?

esovo1
Associate II
Posted on January 09, 2015 at 18:46

Okey, thanks for the tip. I have addressed the mems acellometers on the stm boards with the same pins and it worked flawlessly, like it should. I used the same code, but different timing values.

So, have I wrong initialized the timing register? However, I used the example of timing settings in ST reference manual.

Or, something is wrong with I2C protocol. Maybe I should go to SPI.

stm322399
Senior
Posted on January 09, 2015 at 19:12

So, you are close to the solution. Now that you have a working i2c with ST accel, you need to compare timings, and ask yourself which difference can be the root of your problem.

If your are not successful with this, you certainly need to focus on the I2C slave itself. Some flawed devices wrongly detect start conditions, and do not properly acts on stop conditions, they may completely lock your bus. Such device must be reset by *manually* toggling PIO until they recover a correct idle state. Googling for analog device AN-686 can help.