pasko-zh / brzo_i2c

Brzo I2C is a fast I2C Implementation written in Assembly for the esp8266
GNU General Public License v3.0
244 stars 47 forks source link

after 1 slave fails others stop working #36

Closed igagis closed 5 years ago

igagis commented 5 years ago

I'm using brzo_i2c in my hobby project. I have ESP8266 as master and 3 slaves on i2c line (2 displays and 1 sensor). Esp8266 communicates with all slaves every 500ms. All works fine when all 3 salves are connected. But, if I disconnect 1 of the slaves, all 3 stop working.

So, in this case communication with absent slave fails, i.e. it just does not respond to its address, but all other slaves which are connected stop responding as well.

Any idea why could this happen?

I'm planning to have several instances of my device in different configurations, for example with one display only, or without sensor, so, I would like to have same software flashed to ESP8266 and detect if i2c slave device is present or not in runtime.

pasko-zh commented 5 years ago

You wrote

But, if I disconnect 1 of the slaves, all 3 stop working.

So you don't do a "hot disconnect", i.e. while your esp is running, right?

Furthermore, I understood you do first a "find all the slaves being present on the bus" and then "communicate with the present ones", right? And if understood correctly, the first part fails, right? If so, could you please post your code of this first phase?

igagis commented 5 years ago

Yes, it is not hot-disconnect. I turn everything off then disconnect, then turn on.

And I don't search for devices on the bus, I just know the addresses and try to send/receive data to/from those addresses. And if one send/recieve fails, then all subsequent fail as well. But now I'm not sure if the problem is exactly like this, I need to experiment more. Because right now I encountered another problem. If I try to do several subsequent send operations from master to slave then second one fails for some reason and third one succeeds, fourth fails and so on. The failure reported by brzo is "bus not free", i.e. it fails in the very beginning of the operation when checking for free bus.

I'm working on 400 kHz.

One of the slave devices on i2c bus is AVR microcontroller (atmega8), coded by me. Problem can be also if I coded something wrong there, as using its hardware TWI is not obvious.

I also marked all brzo functions as ICACHE_FLASH_ATTR because I had problems with fitting it to iram. Can that cause this kind of problems?

pasko-zh commented 5 years ago

What other i2c slaves are you using? Maybe one of the slaves does not free the bus fast enough? And then following i2c commands fail?

I also marked all brzo functions as ICACHE_FLASH_ATTR because I had problems with fitting it to iram. Can that cause this kind of problems?

This is most likely not the source of your issues. The esp8266 uses some sort of instruction "caching" . So, when it has to move some instructions out of iram and load others into it, then you encounter some delays. And since it's a software-based i2c implementation this means some stretching of SDA or SCL signals, cf. my issue here. And since the goal of brzo_i2c is to offer i2c timing as precisely as possible, I moved all instructions into iram to remove such stretchings.

igagis commented 5 years ago

Maybe one of the slaves does not free the bus fast enough?

Yes, looks like you were right. My ATmega8 slave running on 8MHz does not release line fast enough. I added 1ms delay after each communication with it and all works fine now! Thanks for help!