cancel
Showing results for 
Search instead for 
Did you mean: 

Invalid clock pulse on I2C

sdianoff
Associate II
Posted on March 11, 2015 at 09:04

I am using microcontroller STM32F On reading EEPROM operation with I2C microcontroller gives 7 clock pulses instead required 9. There is fragment of transmitting on picture.

0690X00000605F0QAI.png When this cause occured EEPROM receives last bit at first bit of next byte. After this it receives NACK bit and stops transmitting. There is function reading EEPROM:


uint8_t readPage(uint8_t addr, uint8_t * res, uint8_t length)

{

if
(i2c_waitflag(I2C, I2C_FLAG_BUSY))

return
-1;

I2C_AcknowledgeConfig(I2C, ENABLE); 

I2C_GenerateSTART(I2C, ENABLE);

if
(i2c_waitevent(I2C, I2C_EVENT_MASTER_MODE_SELECT))

return
-1;

DELAY; //Just delay by cycle


I2C_Send7bitAddress(I2C, APV_ADDR, I2C_Direction_Transmitter); 

if
(i2c_waitevent(I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))

return
-1;

(
void
)I2C->SR2; 

DELAY;

I2C_SendData(I2C, addr);

if
(i2c_waitevent(I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))

return
-1;

DELAY;


I2C_GenerateSTART(I2C, ENABLE);

if
(i2c_waitevent(I2C, I2C_EVENT_MASTER_MODE_SELECT))

return
-1;

DELAY;

I2C_Send7bitAddress(I2C, APV_ADDR, I2C_Direction_Receiver);

DELAY;

if
(i2c_waitevent(I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))

return
-1; 

uint8_t flag = 0;

for
(uint8_t i = 0; i < length; i++)

{


if
(i == length - 2)

I2C_AcknowledgeConfig(I2C, DISABLE);

if
((i == 1) && (flag == 0)) {flag = 1; i--;} //Workarond from ERRATA for last uncorrect byte


if
(I2C_GetFlagStatus(I2C, I2C_FLAG_ARLO | I2C_FLAG_BERR | I2C_FLAG_OVR))

return
-1;

res[i] = I2C_ReceiveData(I2C); 

if
(i2c_waitevent(I2C, I2C_EVENT_MASTER_BYTE_RECEIVED))

return
-1;

 DELAY;


}

if
(I2C->CR1 & I2C_CR1_STOP)

return
-1;

I2C_GenerateSTOP(I2C, ENABLE);

(
void
)I2C->SR1;

(
void
)I2C->SR2;

return
0;

}

Flags ARLO, BERR, OVR are not raised. How do I resolve this problem? #i2c-sample #stm32-stm32f1xx-i2c-errata
3 REPLIES 3
jansen
Associate II
Posted on March 11, 2015 at 15:58

I'm not sure if this covers exactly what you are seeing, but there is a lot of errata on i2c for these chips.  Using polling methods is the worst.  Basically, either manually bit-bang i2c without using hardware support or use DMA.  Depending on your environment, interrupts don't work as advertised either.   Refer to the following docs for help:

http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/CD00209826.pdf?s_searchtype=keyword

http://www.st.com/st-web-ui/static/active/en/resource/technical/document/errata_sheet/CD00197763.pdf?s_searchtype=keyword

I'm attempting to take legacy bit-bang'd i2c code into use of hardware.  I've gotten DMA to work in some debug code.  I don't use the interrupt methods since interrupt preemption doesn't work and it doesn't guarantee good enough timing to handle next bytes.  I've not completely validated the DMA approach in the context of all the other interrupts, etc going on in my product.

sdianoff
Associate II
Posted on March 13, 2015 at 08:56

Using I2C optimized library does not resolves this problem.

When I increased frequency of capture I found other reason of problem. Lost clock pulse exists but it is so short and EEPROM can not send bit over it.

0690X00000605F6QAI.png

0690X000006058kQAA.png

Maybe capture device mist one more pulse (bit).

jansen
Associate II
Posted on March 13, 2015 at 19:15

Read the errata and app note, they talk to the requirement to set the STOP bit very early, protecting from timing and interrupt concerns, etc.  If you don't follow this, there are bit issues that cause various problems.  The provided libraries do not do this and you need to apply the app not example.  There is even some sample C code you can downloaded from here:  

http://www.st.com/web/en/catalog/tools/FM147/CL1794/SC961/SS1743/LN1734/PF257856?s_searchtype=keyword#