Good evening. I am trying to use a Raspberry Pi Zero W 2 as an I2C Slave. Trying to implement some of the solutions using bsc_xfer in this forum, I simply cannot get any data back and forth to the master.
The master is an Arduino MKR1010. It transmits some bytes, then requests bytes back. I can sucessfully communicate with other I2C devices that I put on the bus. And when I use i2cdetect -y 1, I can see the other i2c devices on the raspberry pi. Based on this, I think my connections are okay.
Here's the master arduino code:
void setup(void)
{
Wire.begin();
Wire.setClock(100000);
Serial.begin(115200);
}
void loop(void)
{
Serial.print("Send slave data...");
// Send data to slave
Wire.beginTransmission(0x55);
Serial.print("5...");
Wire.write(0x05);
Serial.print("6...");
Wire.write(0x06);
Serial.print("7...");
Wire.write(0x07);
Serial.print("8...");
Wire.write(0x08);
Wire.endTransmission();
Serial.println("Done.");
delay(10);
// Pull data from slave
Serial.print("Request slave data...");
Wire.requestFrom(0x55, 4);
if (Wire.available()) {
Serial.print("Receiving bytes from slave:");
while (Wire.available()) {
uint8_t b = Wire.read();
Serial.print("B=");Serial.print(b);
if (Wire.available()) Serial.print(", ");
}
Serial.println();
} else {
Serial.print("No data waiting...");
}
Serial.println("Done.");
delay(10);
}
The Raspberry Pi uses the pigpiod_if2 libraries talking to a pigpiod -s 2
. The daemon is started using systemctl
start pigpiod
, and the pigpiod.service
file added the -s 2 option.
Question: When using as a slave, do you configure the i2c interface or not? I've seen conflicting info. I have actually tried both enabling i2c and disabling it with the dtparam=i2c_arm=on
and also removing this line. Does anyone know if it should or should not be configured when using the pi as a slave?
Regardless of how I configure, no data ever goes back and forth. Here is the pi code:
#include <stdio.h>
#include <unistd.h>
#include <cstring>
#include <pigpiod_if2.h>
int pi_handle;
bsc_xfer_t xfer;
uint8_t i2caddr = 0x55;
void setup()
{
pi_handle = pigpio_start(0, 0);
if (pi_handle < 0) {
printf("WHOAAAAAA!\n");
}
xfer.control = (uint32_t)((uint32_t)i2caddr << 16) | (1<<7) /*BK*/;
bsc_xfer(pi_handle, &xfer);
}
void loop()
{
int status;
xfer.control = (uint32_t)((uint32_t)i2caddr << 16) | (1<<9) /*RE*/ | (1<<8) /*TE*/ | (1<<2) /*I2C*/ | (
1<<0) /*EN*/;
while (true) {
printf("Check i2c requests...\n");
printf("Transfer control: 0x%x\n", xfer.control);
xfer.control = (uint32_t)((uint32_t)i2caddr << 16)
| (1<<9) /*RE*/ | (1<<8) /*TE*/ | (1<<2) /*I2C*/ | (1<<0) /*EN*/;
usleep(1000);
status = bsc_xfer(pi_handle, &xfer);
printf("Done. status=0x%x, rx=%d, tx=%d\n", status, xfer.rxCnt, xfer.txCnt);
if ((status >= 0) && (xfer.rxCnt > 0))
{
printf("Received %d bytes of control data.\n", xfer.rxCnt);
printf("Control data = ");
for (int i = 0; i < xfer.rxCnt; i++) {
printf("b[%d]=%d", i, xfer.rxBuf[i]);
if (i < xfer.rxCnt-1) printf(", ");
}
printf("\n");
xfer.rxCnt = 0;
}
// SHORT PAUSE
usleep (1000);
}
printf("Done looping.\n");
}
int
main(int argc, char **argv)
{
setup();
loop();
}
That's pretty much it. The status coming back from bsc_xfer
will change if I add bytes to the transmit queue, but the buffer never drains. It never receives any bytes back in the rxBuf
.
I tried it without the pigpiod
, direct to the libraries using gpInitialise()
and bscXfer()
, but it didn't work either.
Any pointers are appreciated. Thank you.
Here is the output from the slave running on the Pi:
Check i2c requests...
Transfer control: 0x550305
Done. status=0x12000000, rx=0, tx=0
Check i2c requests...
Transfer control: 0x550305
Done. status=0x12000000, rx=0, tx=0
Check i2c requests...
Transfer control: 0x550305
Done. status=0x12000000, rx=0, tx=0
lsmod
output is as follows:
$ lsmod | grep i2c
i2c_bcm2835 16384 0
i2c_dev 20480 0