guild icon
Toit
#I2c Communication with RP2040
Thread channel in help
theHuanter
theHuanter 11/30/2023 03:03 PM
I try to implement a I2C Communication between a RP2040 and the ESP32. I am at a state right now that I can send data from the ESP32 (master) to a RP2040 (slave) perfectly. But reading data somehow only works one time. I start an i2c communication like: device.registers.read-bytes 0x02 1 the device was already found.
Once after a fresh hard-reset of both devices, this works and I receive the byte I was sending from the RP2040. If I try it again it fails with:

EXCEPTION error. I2C_READ_FAILED 0: Device.read-reg.<block> <sdk>\i2c.toit:235:36 1: Bus.read-reg_ <sdk>\i2c.toit:116:22 2: Device.read-reg <sdk>\i2c.toit:242:17 3: Device.read-reg <sdk>\i2c.toit:235:12 4: Registers.read-bytes <sdk>\i2c.toit:291:20 5: main.<block> master\src\main.toit:26:33 6: HashedInsertionOrderedCollection_.hash-do_ <sdk>\core\collections.toit:2241:3 7: Set.do <sdk>\core\collections.toit:2414:10 8: main master\src\main.toit:22:11

once this error appeared the SDA line is kept LOW (SDA and SCL have pull-up resistors of 10k). Only if I reset both devices it will work again (once).
I am pretty sure this is ma fault in the RP2040 code somehow but I can not firgure out whats the issue and why the SDA is kept low after this issue (which might be a ESP32/toit issue)
Somehow something is missing after this working first time, maybe I forgot to clear a register or something?! I am a bit confused where this is actually coming from. (toit or rp2040) Maybe someone can help me here.
theHuanter
theHuanter 11/30/2023 03:29 PM
I was running the good case and received the following output:
status: 0b10000 status: 0b1011100110100 Read request pending, processing... Received register:0x02 replayed with 0x10 status: 0b1011110010000
the status in the second line indicates, that there was a master requesting a "read". (bit 5). The slave then reads the addressed register 0x02 and sends out 0x10 back to the master. The state after that is in the last line where bit 5 is disabled (no read request pending) but bit 7 is enabled which according to the datasheet of the RP2040 means, that the master did not ACK the reading of the data.

on the ESP32 master side the code looks as follows:
[test] DEBUG: Starting... [test] DEBUG: scanning start... 0x08 0x11 [test] DEBUG: done bye
It scanned for I2C devices and found the device with 0x08 and then is requesting a read (as posted above) and in the good case also received the 0x11 (I actually send 0x11 not 0x10, the print out was hardcoded in the rp2040).

the state on the RP2040 stays like this. Could it be that the toit implementation somehow does not aknowledge the receiving of that byte and therefor leaves the I2C in a weird state? I am pretty sure that I2C works perfectly fine with toit, I used it a lot already.
floitsch
floitsch 12/01/2023 05:09 AM
Program your microcontrollers in a fast and robust high-level language. - toitlang/toit
floitsch
floitsch 12/01/2023 05:09 AM
Write is first. Read is after that.
floitsch
floitsch 12/01/2023 05:10 AM
Looks like the master doesn't ack but seems a stop instead.
theHuanter
theHuanter 12/01/2023 10:19 AM
I tried to run a simple Arduino Wire code to read from a device (somehow I can not define a register to read from) but it receives every byte I send multiple times.
Somehow something must be wrong here but I still can not figure out what it is.
theHuanter
theHuanter 12/01/2023 10:20 AM
#include <Wire.h> void setup() { Wire.begin(); // join i2c bus (address optional for master) Serial.begin(115200); // start serial for output } void loop() { Wire.requestFrom(8, 1); // request 6 bytes from peripheral device #8 while (Wire.available()) { // peripheral may send less than requested int c = Wire.read(); // receive a byte as character Serial.print(c, HEX); // print the character } delay(500); }
If I am running this on the ESP32 (Master) I can receive the data without issue
theHuanter
theHuanter 12/01/2023 10:45 AM
okay I found the issue.... -.-
in my code I am running the I2C communication with uasyncio so I can have both I2C channel working. I2C0 is doing communication with the ESP and the other is reading sensor data etc. but I put a delay to wait of like 10ms before it answers the I2C.. this seems to produce a timeout!
I tried the same code with micropython on the ESP side and I received an timeout which pointed me to that delay.
theHuanterOPtheHuanter
okay I found the issue.... -.- in my code I am running the I2C communication with uasyncio so I can have both I2C channel working. I2C0 is doing communication with the ESP and the...
floitsch
floitsch 12/01/2023 11:34 AM
Good find
theHuanter
theHuanter 12/01/2023 11:35 AM
the question is: does toit not recognize the timeout? I guess there is no differenciation between an error and timeout?
floitsch
floitsch 12/01/2023 11:36 AM
We might not make that distinction. Could also be that the "bundled" way we use the esp-idf underneath doesn't give us the timeout error.
👍1
11 messages in total