2008-11-26 10:51 PM
I2C bizare behaviour
2011-05-17 03:53 AM
Using STM32F103ZET6, I am having a problem with I2C2. My application periodically (every 500ms) reads from all valid I2C addresses (0x01 -> 0x7F), to determine if any device is attached. This works correctly.
However, when there is activity on the USARTs, the I2C behaviour does not seem to be correct. The bad behaviour is intermittent, but somewhat repeatable. What I observe is, that after a start event (0x00030001), the address of the device is written to the DR by calling I2C_Send7bitAddress(), but no further event occurs. I expect an interrupt, indicating that an ACK failure has occured (0x00030400), but this interrupt does not arrive. When the USARTs are inactive, this interrupt always arrives. The I2C interrupts have higher priority than the USART interrupts. Anyone got any ideas? Brian F.2011-05-17 03:53 AM
Questions: (have no hard answers - just systematic suggestions)
a) Have you checked most current errata for this device? b) Have you reviewed most current ver. RM0008? c) Are you using code from ST's library? Any changes? d) Will any USART cause this effect? I recall past post in which conflicts between I2C & USART was noted.2011-05-17 03:53 AM
Hi brian,
I experienced exactly the same problem. Last week I was trying to write my I2C routines for eeprom, using interrupts, and this is what I have observed. I called I2C_GenerateSTART somewhere in main loop. Then I received interrupt with event I2C_EVENT_MASTER_MODE_SELECT in the same moment I sent I2C_Send7bitAddress and then quiet no further interrupts occurs. I use UART1 and many others peryf. I will start to work on this next week. I hope there is a solution?2011-05-17 03:53 AM
JJ,
Thanks for your reply, and yes, I've checked all of this. I am using the firmware code only, not the example code. The USART, nor USART driver code should not cause this effect. Basically, an interrupt from the I2C2 is not arriving as expected (I have write the target i2c device address to DR, but the device does not go into the next state, but instead returns to idle state, without interrupt). Jaroslaw, I'm sorry you are having difficulty, but at least I know I am not losing it! The only thing I can do is to start a timer at the same time as starting the I2C transaction, and stop the timer when the transaction is finished. If the timer expires, then things have gone bad. I ran a test last night for about 12 hours (without the USART) and it has not failed, so the problem seems to be related to the USART interacting with the I2C. Brian F.2011-05-17 03:53 AM
I may well have resolved my issue (to be confirmed over night this evening).
What I observed previously (the bad functionality); intermittently the last device address which was written to the DR did not appear on the SCL/SDA lines, but instead a START condition immediately followed by a STOP condition was observed. In the software, an interrupt corresponding to the START condition occurred, during which the i2c device address was written to the DR. Thereafter, no further I2C interrupts occurred. My software was waiting for an interrupt, indicating MASTER_ACK_FAILURE, which never arrived. The STOP condition immediately following the START condition should not have occurred, as I did not set the STOP bit during this transaction. I suspect that the STOP bit was not cleared by hardware after the previous stop request. Therefore, what I have done is cleared the STOP bit before setting START bit when starting a new transaction. This appears to have resolved my issue. Jaroslaw, I hope this resolves your issue also. Brian F.2011-05-17 03:53 AM
I understand now what was occurring. Previously I was setting the START bit before the previous STOP had been actioned. This resulted in a restart condition on the bus, immediately followed by a STOP. Either of the following solutions will resolve the issue;
a) explicitly clearing the STOP bit before setting the START bit b) don't set the START bit until the previous transaction STOP is completed (i.e. wait until the SRs are clear). Unfortunately, no interrupt is generated (in the Master) indicating that a STOP condition has completed, so no way of knowing when the device is ready to generate a START condition. The only way is to poll the SRs. Brian F.2011-05-17 03:53 AM
Hi brian,
Thanks for all help you gave for this forum. I have solve my problem. I didn't wait when eeprom finishes writing a byte, it takes up to 5ms to write one byte. I was trying to send eeprom address before this finishes writing and didn't get ACK. I know that this looks simple now ;-), but this waiting for SR's to clear is very good idea. I have now working drivers for byte read and write for EEPROM 24LC256 by microchip. If somebody wants to use it please write. best reg. J.O.