So I've got a setup where I want to use a Particle B524 (device OS 5.7.0) as I2C slave, but I am experiencing some issues. For test purposes I connected the Particle to an Arduino (SDA, SCL, ground and pullup resistors to 5v). However, the I2C communication seems to drop out after a few seconds.
Here is the particle code:
void requestEvent()
{
Wire.write("hello "); // respond with message of 6 bytes as expected by master
}
void setup()
{
Wire.setSpeed(400000);
Wire.stretchClock(true);
Wire.begin(2); // join i2c bus with address #2
Wire.onRequest(requestEvent); // register event
}
void loop()
{
delay(1);
}
Here is the Arduino code:
#include <Wire.h>
void setup() {
// put your setup code here, to run once:
Wire.setClock(400000);
Wire.begin();
Serial.begin(9600);
}
void loop() {
//Serial.println("looping");
// put your main code here, to run repeatedly:
Wire.requestFrom(2, 6);
int i=0;
while(!Wire.available()){
delay(1);
i++;
if(i==100){
break;
}
}
while(Wire.available()){
Serial.write(Wire.read());
}
delay(1000);
}
I've tried setting the clock speed to 100000Hz as well, but then the communication drops out even faster, This does make me suspect that there is a mismatch between the clock frequency produced by the Arduino and accepted by the Particle, and the mismatch must be larger than the Wire.strechClock() can handle.
Definitely do not do that! GPIO including I2C, SPI, and UART, are not 5V tolerant on the B-SoM, actually all nRF52 and RTL872x devices. You may permanently damage the MCU.
You can only use I2C at 3.3V unless you use a level shifter.
Okay, that sounds like some critical information I did not take into account. Although, switching to 3.3V, using a new Particle B524 and a Xiao esp32c3, the issue still persists. The longest I've seen the communication last is about 8s, but sometimes it doesnt connect at all.
It's not clear why it's not working, and you may need a logic analyzer to figure it out. However:
It's not a clock speed issue, as long as the master is 400 kHz or 100 kHz. In I2C slave mode, the clock setting in Wire.setSpeed() is ignored, as it's determined only by the pulses on SCL from the master.
It's not a clock stretching issue, as it's always enabled on nRF52 devices.
I do not see anything unusual about this. It appears as though it just works until is doesn't. What I have noticed, but forgot to mention is that simply unplugging the SDA & SDL lines or resetting the ESP does not restore communication for after dropping out. It takes a reset of the Particle (and some luck) to re-recieve a signal.
Is your B-SoM in the evaluation board or on your own custom board? In either case, my guess is that the power manager is causing issues for you.
You cannot use I2C slave mode on primary I2C (D0/D1, Wire) on boards with the PMIC/Fuel Gauge connected to primary I2C and enabled. This includes the bsom and b5som. It does not include the Boron, Tracker, and E404X that use secondary I2C (Wire1) for the PMIC.
In order to use I2C slave on primary I2C on the bsom and b5som you need to disable power management by disabling the SystemPowerFeature::PMIC_DETECTIONfeature. The reason is that I2C multi-master is not supported, and there's no way to stop the power manager from writing to the I2C bus at the same time as the other I2C master. Also it will change the settings of the I2C port, which probably is why slave mode stops working.
I think this should disable power management. You only really need to do it once because the setting is saved in the configuration flash.
Your suggestion on disabling the power manager worked. One final question remains: what is the downside of turning of the power manager? In the future I might switch to the wire1, but for now I will probably stick to the primary I2C scince a friend has already designed and build the pcb :).
Turning off the power manager will cause the PMIC (bq24195) to revert to default settings, which may affect charge rate and input current limit. If you have both power and a battery it should work fine, but things might not behave correctly without a battery.