2015-03-11 01:04 AM
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.
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
2015-03-11 07:58 AM
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=keywordhttp://www.st.com/st-web-ui/static/active/en/resource/technical/document/errata_sheet/CD00197763.pdf?s_searchtype=keywordI'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.2015-03-13 12:56 AM
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. Maybe capture device mist one more pulse (bit).2015-03-13 11:15 AM
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: