AnsweredAssumed Answered

STM32F207 - I2C error - No clock after start condition & ack failure AF after first call to SendData

Question asked by DonTseTse on Jun 9, 2011
Latest reply on Apr 3, 2012 by duraa.przemo
Hi,

i am using the code below to try to communicate with a I2C sensor. I have a STM32F207VG with the corresponding peripheral lib v1.0, both lines have 4k7 pull-ups.

The problem has 2 aspects:

- there is no clock signal on the SCL after the start condition

- the acknowledge failure AF is set after the first call to I2C_SendData

I don't know which one is the cause and which one is the consequence, but that AF is certainly nothing which has to do with its „real“ purpose, as no data has yet been transmitted, what acknowledge should have failed?

 

#define I2C1_PORT            GPIOB

#define I2C1_SCL_PIN         GPIO_Pin_8

#define I2C1_SDA_PIN         GPIO_Pin_9

GPIO_InitTypeDef GPIO_InitStructure;

I2C_InitTypeDef I2C_InitStructure;


/* ----Setup phase---- */

/* Enable I2C1 and I2C1_PORT & Alternate Function clocks */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

/* Reset I2C1 IP */

RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);

/* Release reset signal of I2C1 IP */

RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);

/* I2C1 SCL and SDA pins configuration */

GPIO_InitStructure.GPIO_Pin = I2C1_SCL_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_Init(I2C1_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = I2C1_SDA_PIN;

GPIO_Init(I2C1_PORT, &GPIO_InitStructure);

/* Alternate function remapping */

GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_I2C1);

GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);

/* I2C De-initialize to clean */

I2C_DeInit(I2C1);

/* I2C configuration */

I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;

I2C_InitStructure.I2C_OwnAddress1 = 0x00;

I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

I2C_InitStructure.I2C_AcknowledgedAddress =                            I2C_AcknowledgedAddress_7bit;

I2C_InitStructure.I2C_ClockSpeed = 400000;

/* I2C Initialize */

I2C_Init(I2C1, &I2C_InitStructure);

/* I2C ENABLE */

I2C_Cmd(I2C1, ENABLE);


/*----- Transmission Phase -----*/

/* Wait if the bus is busy */

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

/* Send START condition */

I2C_GenerateSTART(I2C1, ENABLE);

/* Test on EV5 and clear it */

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

/* Send sensor address */

I2C_SendData(I2C1,0xF1);

 

It is step by step register readout that makes me think that the problem is the first call to I2C_SendData. Up to there, all registers show what they should, but as soon as this call takes place, the register SR1 signals the AF. The data register is filled with the correct address but the AF disables the peripheral, the data will not be transmitted. I already tried to do some sw_rst, I2C_ClearITPendingFlags, re-enable peripheral or generate a second start condition – all useless.

On the scope one can see that after the initialization, both lines go high as they should. Then, after about 5(ms), SDA goes down for about a tenth of a ms before returning to high. At the same time, SCL also "tries" to go down, but it doesn't even arrive at 0V level before it's pulled high again. I suppose the MCU attempts to generate the start condition here, but should'nt there be a delay between the SDA and SCL transitions? Afterwards, both lines stay high forever and that's it...

 

Any ideas? Help would really be appreceated!

Don TseTse

 

Outcomes