I2c Communication with RP2040
# help
i
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:
Copy code
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.
I was running the good case and received the following output:
Copy code
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:
Copy code
[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.
Write is first. Read is after that.
Looks like the master doesn't ack but seems a stop instead.
i
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.
Copy code
#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
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.
f
Good find
i
the question is: does toit not recognize the timeout? I guess there is no differenciation between an error and timeout?
f
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.