2017-03-02 10:45 PM
I have a problem with the i2c peripherie of a STM32f407.
If i get a bus error the i2c is always busy.
I try to solve this with a I2C_SoftwareResetCmd(I2C1, ENABLE), this works but then i cant start a new communication.I use the standard libary.
if(I2C_GetITStatus(I2C1,I2C_IT_BERR))
{ I2C_ClearITPendingBit(I2C1,I2C_IT_BERR); I2C_GenerateSTOP(I2C1, ENABLE); I2C_SoftwareResetCmd(I2C1, ENABLE); }#stm32f407 #i2c2017-03-03 04:12 PM
I found that you must wait for the busy to complete....
try: while(I2C_GetITStatus(I2C1,I2C_IT_BERR)){ add timeout here }
then it will progress..
this worked for me:
uint8_t Ds3231::read (uint8_t r_adrs, const char* data, int readLength){ int I2C_ADDRESS = DS3231_I2C_ADRS <<1;
/*##-3- Put I2C peripheral in reception process ############################*/ /* Timeout is set to 10S */
while(HAL_I2C_Master_Receive(&hi2c2, (uint16_t)I2C_ADDRESS, (uint8_t*)data, readLength, 1000) != HAL_OK) { /* Error_Handler() function is called when Timeout error occurs. When Acknowledge failure occurs (Slave don't acknowledge it's address) Master restarts communication */ } return readLength;}�?�?�?�?�?
2017-03-03 09:32 PM
I2C Bus is typically a slow serial bus (as it was for controlling devices originally). Being synchroneous, it is simple to generate a Master I2C by GPIOs. Display Monitors are 'plug and play' = no black screen. This is achieved by putting a 'display descriptor' info in a small EEPROM (24C21 for example) put on the display. Then an I2C bus is stuffed in the video cable and the graphics card reads the display presence and capability by reading the data regularly to manage boot and hot swapping (plugging a projector being 10m away from the source, etc...).
And to make sure interoperability is good, Plug Tests were organized between display vendors and graphics card makers, usually in the Embassy Suite of SFO Airport / Burlingame. Hot plug is very tough to manage, and most of the problems reported in this forum are about I2C errors. If your I2C does not run on cables, most likely things will be ok.
Add ESD glitches, add a cable wrapped around a drilling machine or hot plugged in an HDMI cable, things will ask for rugged implementation. So far, error recovery means testing that prior the start bit both SDA and SCL are high level (Bus idle). If not, you can't reset the slave. Generate 9 STOP bits (a byte transfer takes 9 clock pulses and at least one of them in read mode will turn SDA as input to get the STOP bit through) works like a charm. Implement this by SW GPIO and trigger the generation when an I2C Error Recovery is needed. This avoids power down/up the whole board...