Particle as I2C slave

Hi!

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.

What could be the solution to this issue?

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.

Hi! Thanks for the fast reply.

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.

Alright, so I hooked the SDA and SDL up to an Oscilloscope. Here are some images:
This is with no reply:

This is with a correct response of sending 42:

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.

void setup() {
    SystemPowerConfiguration conf;
    System.setPowerConfiguration(conf);
}

Alright, will see if this helps, thanks!!

As for your question: All the results here are with the B-som in the evaluation board, but I hope to move to a custom board in the future.

You could also switch to using the secondary I2C port Wire1 on B-SoM pins D2/D3 for your I2C slave. That's probably an easier option.

1 Like

Thanks a lot for your help!!

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 :).

Thank you for testing it!

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.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.