Solved: Second I2C/Wire port on M0

H/W: M0 and I2C EEPROM with own I2C pull-up resistors
IDE: 1.8.4

I am trying to set up an extra I2C/Wire port using this example: Creating a new Wire | Using ATSAMD21 SERCOM for more SPI, I2C and Serial ports | Adafruit Learning System However, I can’t get it to work. But using the default I2C/Wire port everything is fine. The only H/W difference is that the EEPROM has its own 10 kOhm pull-up resistors in parallel with the M0 I2C resistors on the default port but not on the extra port. But 10 kOhm vs 5 kOhm can hardly be the issue. Connecting an oscilloscope to D3 or D4 shows no communication going on. The lines are constantly high due to the pull-up resistors.

One thing I noticed is that the “extra I2C port” program seems to halt/crash the first time it attempts to read the EEPROM while executing the Wire.endTransmission(); line because inserting a SerialUSB.println before and after, the Wire.endTransmission(); line, are not printed in the case of the “extra I2C port”.

The not working “extra I2C port” code:

#include <Wire.h>
#include "wiring_private.h"
TwoWire myWire(&sercom2, 4, 3);

int EEPROMReadByte(int i2cAddr, int memAddr)
{
    int data = 0xFF;

    myWire.beginTransmission(i2cAddr);
    myWire.write((int)(memAddr >> 8));
    myWire.write((int)(memAddr & 0xFF));

    SerialUSB.println("Here 1");
    myWire.endTransmission();
    SerialUSB.println("Here 2");

    myWire.requestFrom(i2cAddr, 1);
    if (myWire.available())
        data = myWire.read();

    return data;
}

void setup()
{
    // Setup pins 4 & 3 to SERCOM functionality
    myWire.begin();
    pinPeripheral(4, PIO_SERCOM_ALT);
    pinPeripheral(3, PIO_SERCOM_ALT);

    SerialUSB.begin(9600);
    while (!SerialUSB);
    SerialUSB.println("Ready");

    for (int i = 0; i < 10; i++)
        SerialUSB.println(EEPROMReadByte(0x50, i));
}

void loop(){}

The default I2C port working code:

#include <Wire.h>

int EEPROMReadByte(int i2cAddr, int memAddr)
{
    int data = 0xFF;

    Wire.beginTransmission(i2cAddr);
    Wire.write((int)(memAddr >> 8));
    Wire.write((int)(memAddr & 0xFF));
    Wire.endTransmission();
    Wire.requestFrom(i2cAddr, 1);
    if (Wire.available())
        data = Wire.read();

    return data;
}

void setup()
{
    Wire.begin();

    SerialUSB.begin(9600);
    while (!SerialUSB);
    SerialUSB.println("Ready");

    for (int i = 0; i < 10; i++)
        SerialUSB.println(EEPROMReadByte(0x50, i));
}

void loop() {}

Mik D

The problem was an Arduino M0 vs Arduino Zero problem. It seems as if D2 and D4 are swapped. Thus the solution is for a M0 is:

TwoWire myWire(&sercom2, 2, 3);
pinPeripheral(2, PIO_SERCOM_ALT);
pinPeripheral(3, PIO_SERCOM_ALT);