2009-10-06 11:34 PM
i2c master hangup/missing interrupt
2011-05-17 04:25 AM
I have a very strange problem with the i2c on a STM32 (high density 103ZE).
The symptom is that I can issue a write command (start, address, bytes, stop) just fine, but when I want to execute a read command afterwards and I execute a start, the hardware never issues an interrupt at all and I am unable to write the read address to the bus. The hardware on the bus shows that the start is issued, but it is followed immediately by a stop. After this the hardware is locked up. Re-programming or resetting the chip will not re-enable i2c communication. Only re-programming with valid code followed by a power cycle will re-enable the i2c hardware. I am using I2C1 and I2C2 both in master mode with interrupts. The NVIC is set to preemption priority 0 and sub priority 0 and 1 for i2c1 and i2c2 respectively, so I have the highest interrupt priority possible. I have trapped the interrupt calls to the ISR and everything seems appears exactly as expected from the reference manual, except for 1 call where I2C_GetLastEvent returns 0x00000000 in between the write and reads. Just ignoring this ISR call appears to be the right thing to do. When it is NOT working there is no call to the ISR at all, except for the 0x00030001 event. After the ISR executes for this event I can see the address of the device (0xE3) in the data register, but it never appears on the bus. After many hours of struggle I am able to get the hardware to work most of the time in the following conditions: Clock rate is 100, 99, 98 or 97 kHz, and I need to use IARs high speed compiler option. If I use any other clock rates, e.g. 50kHz (and other even lower speeds), 101kHz the system hangs. If I use low level optimization the system hangs. It ran >3,000,000 times overnight when I issues write/read combinations every 10ms, but when I vary the interval of write/reads the system hangs again. If I change the order from write followed by a read to a read followed by a write, the same problem occurs. It is always the second start event that causes the hangup. It is independent of whether the master or the slave controls the SDA line. What could possibly be going on? Please help. Thanks -- Gerard2011-05-17 04:25 AM
I still do not know why the i2c hardware is acting up, but the solution to the problem is to de-init the i2c hardware and then initialize at the startup of the chip. Then you also need to de-init and reinitialize the i2c peripheral each time after a stop event has been generated.
I had tried re-initialization after the stop before, but without the de-init it does not work. -- Gerard2011-05-17 04:25 AM
The sensitivity to timing that you report should ring alarm bells (''works at 100.0 kHz, not at 99 or 101'').
That makes me think that there are other parts of your code, either in your main flow or other interrupts, that are interfering with the I2C module. Perhaps you are reading one of the I2C module registers to get a status in the background. But the act of reading makes the module think it has been serviced and a vital interrupt will never happen. Better to set a flag from your interrupt-service-routine. Other software slips could cause the failure. Perhaps you have not declared something volatile that needs to be so in your main program. Perhaps your I2C state-machine software is not being properly reset from the previous message. What is the I2C device you are communicating with? Is it a commercial piece of I2C hardware, or is it another microcontroller which is emulating an I2c slave either in hardware or software. Less likely but still possible is a bug in the code for that device which is causing the frequency-sensitivity you report. Hope this helps, Danish2011-05-17 04:25 AM
Hello,
I have the same problem, the code normally execute when i want to do a write via I2C , but after some read instruction via I2C, the main is hanged. When i say the main is hanged, it means that the infini loop while() in the main is really stopped, i tried to put one instruction i++ in this loop, but it didn't increase. In my hardware, we have a buzzer who connect to an ouput PWM of TIM_3 and a signal PWM of TIM_2, this two signals work very well even the hanged problem occurs. From 2 tests, can i conlude that the problem is from soft but not from hard ( the core M3)? because the hard still works. And then, we tried everythings to simplify the soft, the final conlusion is : if you work with only I2C, the problem won't occur, but when u active the counter TIM2, the problem will appear right away. I maked a lot of research on another forum STM32, and find some same article about this problem too. by example : . And i think the problem must be from the library STM I2C or from his protocole. BUT I HAVENT FOUND THE SOLUTION TO THIS PROBLEM YET...... DOES ANYONE KNOW TO SOLVE IT? IT IS SO PITY TO WRITE A PROTOLE I2C OURSELF WHEN WE HAVE ONE who is ready... while ( SOLUTION=WORKED_WELL) { RESEACH TEST RETEST OH MY GOD..... :-Y :-[ } Thx all