cancel
Showing results for 
Search instead for 
Did you mean: 

I2C Delay time

Kim.Andy
Associate III
Posted on January 05, 2016 at 09:18

Hello!!

I test  an access to eeprom by I2C Fastmode(polling) like following programs.

But when writing a block to eeprom, it happens an I2C error.

So I insert a delay time(1ms : _delay_ms(I2C_DLY)), and then it operates properly.

I want to delete this delay time to get the best performance of I2C.

How can I do it????

void I2C_LowLevel_Init(void){

GPIO_InitTypeDef  GPIO_InitStructure;

I2C_InitTypeDef  I2C_InitStructure;

 

/* RCC Configuration */

/*I2C Peripheral clock enable */

RCC_APB1PeriphClockCmd(I2Cx_CLK, ENABLE);

/*SDA GPIO clock enable */

RCC_AHB1PeriphClockCmd(I2Cx_SDA_GPIO_CLK, ENABLE);

/*SCL GPIO clock enable */

RCC_AHB1PeriphClockCmd(I2Cx_SCL_GPIO_CLK, ENABLE);

/* Reset I2Cx IP */

RCC_APB1PeriphResetCmd(I2Cx_CLK, ENABLE);

/* Release reset signal of I2Cx IP */

RCC_APB1PeriphResetCmd(I2Cx_CLK, DISABLE);

/* GPIO Configuration */

/*Configure I2C SCL pin */

GPIO_InitStructure.GPIO_Pin = I2Cx_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(I2Cx_SCL_GPIO_PORT, &GPIO_InitStructure);

/*Configure I2C SDA pin */

GPIO_InitStructure.GPIO_Pin = I2Cx_SDA_PIN;

GPIO_Init(I2Cx_SDA_GPIO_PORT, &GPIO_InitStructure);

 

/* Connect PXx to I2C_SCL */

GPIO_PinAFConfig(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_SOURCE, I2Cx_SCL_AF);

/* Connect PXx to I2C_SDA */

GPIO_PinAFConfig(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_SOURCE, I2Cx_SDA_AF);

/*I2C Struct Initialize */

I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

I2C_InitStructure.I2C_DutyCycle = I2C_DUTYCYCLE;

I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE_ADDRESS7;

I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;

I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

/*I2C Initialize */

I2C_Init(I2Cx, &I2C_InitStructure);

/* I2C ENABLE */

I2C_Cmd(I2Cx, ENABLE);

}

#define I2C_DLY 1000

U8 I2C_Write(I2C_TypeDef *I2Cn, U8* buf,  U32 nbyte){

__IO U32 Timeout = 0;

/* Enable Error IT (used in all modes: DMA, Polling and Interrupts */

//    I2Cx->CR2 |= I2C_IT_ERR;

if (nbyte) {

_delay_us(I2C_DLY);

Timed(I2C_GetFlagStatus(I2Cn, I2C_FLAG_BUSY));

// Intiate Start Sequence

I2C_GenerateSTART(I2Cn, ENABLE);

Timed(!I2C_CheckEvent(I2Cn, I2C_EVENT_MASTER_MODE_SELECT));

// Send Address  EV5

I2C_Send7bitAddress(I2Cn, I2C_SLAVE_ADDRESS7, I2C_Direction_Transmitter);

Timed(!I2C_CheckEvent(I2Cn, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

// EV6

// Write first byte EV8_1

I2C_SendData(I2Cn, *buf++);

while (--nbyte) {

// wait on BTF

Timed(!I2C_GetFlagStatus(I2Cn, I2C_FLAG_BTF));  

I2C_SendData(I2Cn, *buf++);

}

Timed(!I2C_GetFlagStatus(I2Cn, I2C_FLAG_BTF));  

I2C_GenerateSTOP(I2Cn, ENABLE);

_delay_us(I2C_DLY);

Timed(I2C_GetFlagStatus(I2Cn, I2C_FLAG_STOPF));

_delay_us(I2C_DLY);

}

return TRUE;

errReturn:

return FALSE;

}

#ifdef FAST_I2C_MODE

 #define I2C_SPEED 400000

 #define I2C_DUTYCYCLE I2C_DutyCycle_16_9  

#else /* STANDARD_I2C_MODE*/

 #define I2C_SPEED 100000

 #define I2C_DUTYCYCLE  I2C_DutyCycle_2

#endif /* FAST_I2C_MODE*/

The error happens when checking I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED.

#define  I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED        ((uint32_t)0x00070082)  /* BUSY, MSL, ADDR, TXE and TRA flags */

1 REPLY 1
Kim.Andy
Associate III
Posted on January 07, 2016 at 13:15

I have solved this problem.

The slave device of I2C is AT24C1024 EEPROM.

This device need the write cycle timing from a valid stop condition of a write sequence to the end of the internal clear/write cycle(max 10ms).

So I insert a delay time(5ms) between a write access and the next access.

Then I2C Communication is ok!!.

Thanks