nox771 / i2c_t3

Enhanced I2C library for Teensy 3.x devices
156 stars 44 forks source link

Teensy 3.6 multi-master configuration not working. #26

Open vveliev opened 5 years ago

vveliev commented 5 years ago

I have issues using this lib with multi-master configuration:

The example code provided below(if replace with Wire lib, the code does work on Arduino uno/mega)

Master1:

#include <i2c_t3.h>
//#include <Wire.h>

#define I2C_ADDRESS_OTHER 0x2
#define I2C_ADDRESS_ME 0x1

void setup() {
    Serial.begin(9600);
    Wire.begin(I2C_MASTER, I2C_ADDRESS_ME, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
//    Wire.begin(I2C_ADDRESS_ME);
    Wire.onReceive(receiveI2C);
}

void loop() {
    delay(5000);
    Wire.beginTransmission(I2C_ADDRESS_OTHER);
    Wire.write("hello world from 0x1 to 0x2");
    Wire.endTransmission();
    Serial.println("Send to master2");
}

void receiveI2C(size_t howMany) {
    while (Wire.available() > 0) {
        char c = Wire.read();
        Serial.print(c);
    }
    Serial.println();
}

Master 2:

#include <i2c_t3.h>
//#include <Wire.h>

#define I2C_ADDRESS_OTHER 0x1
#define I2C_ADDRESS_ME 0x2

void receiveI2C(size_t count);

void setup() {
    Serial.begin(9600);
//    Wire.begin(I2C_ADDRESS_ME);
    Wire.begin(I2C_MASTER, I2C_ADDRESS_ME, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
    Wire.onReceive(receiveI2C);
}

void loop() {
    delay(5000);
    Wire.beginTransmission(I2C_ADDRESS_OTHER);
    Wire.write("hello world from 0x2 to 0x1");
    Wire.endTransmission();
    Serial.println("Send to master1");
}

void receiveI2C(size_t count) {
    while (Wire.available() > 0) {
        char c = Wire.read();
        Serial.print(c);
    }
    Serial.println();
}

I2C bass spesifications tells me that it should be working hardware wise. https://www.nxp.com/docs/en/user-guide/UM10204.pdf

nox771 commented 5 years ago

Your connection is probably correct, but unfortunately it will not work because arbitration is broken. The library currently does not handle ARBL properly, and I've never had a chance to fully investigate and fix it. It will be some time before I can try again to fix it, so I don't have a short-term fix. You can try the default Teensy Wire lib to see if that gives a different result.

However if your goal is simply to communicate between two Teensy devices then there is a workaround. Instead of running a half-duplex connection on one bus, you can split to single-direction on two buses. For instance: Device1(Wire) --> Device2(Wire1) Device1(Wire1)<-- Device2(Wire)

whereby on a given device Wire is the Master Tx and Wire1 is the Slave Rx. The penalty of this is if you are also adding additional Slaves on the bus, one Master device will not have visibility to those Slaves (it would have to relay through the Master which can see them).

vveliev commented 5 years ago

No Wire lib was my first option and it did not work.

Well, I have implemented the pulling on one master(teensy) instead. It's just unfortunate there it's not mentioned that multi-master configuration is not supported by the library.

If I will have time and brains to figure it out will open PR.

Thanks.