Second I2C Interface

Hi

I am trying to set up a second I2C interface in the Nano 33 IOT. According to the SAMD21G18A datasheet, this should be possible but it seems is not supported at the moment.

Any suggestions on how to do this?

It is supported. The tutorial is here:

Note that the pin mapping of the Nano 33 IoT is different from other SAMD boards. So you can't use the MKR board pin mapping table provided in the tutorial. Instead, use the one in the nano_33_iot variant definition:

SDA must be PAD[0] and SCL must be PAD[1]. So you need to find two pins that are on the same SERCOM and have 00 and 01 after the slash in the table. I notice Arduino pins 6 and 5 meet those requirements and are conveniently located next to each other:

 +------------+------------------+--------+-----------------+--------+-----------------------+---------+---------+--------+--------+----------+----------+
| Pin number | NANO  Board pin  |  PIN   | Notes           | Peri.A |     Peripheral B      | Perip.C | Perip.D | Peri.E | Peri.F | Periph.G | Periph.H |
|            |                  |        |                 |   EIC  | ADC |  AC | PTC | DAC | SERCOMx | SERCOMx |  TCCx  |  TCCx  |    COM   | AC/GLCK  |
|            |                  |        |                 |(EXTINT)|(AIN)|(AIN)|     |     | (x/PAD) | (x/PAD) | (x/WO) | (x/WO) |          |          |
 +------------+------------------+--------+-----------------+--------+-----+-----+-----+-----+---------+---------+--------+--------+----------+----------+
...

| 5          | ~D5              |  PA05  |                 |   05   | *05 |  01 | Y03 |     |         |   0/01  |*TCC0/1 |        |          |          |
| 6          | ~D6              |  PA04  |                 |   04   | *04 |  00 | Y02 |     |         |   0/00  |*TCC0/0 |        |          |          |

So the "Create a new Wire instance" example sketch from the tutorial updated for Arduino pins 6 and 5 on the Nano 33 IoT looks like this:

#include <Wire.h>
#include "wiring_private.h"

TwoWire myWire(&sercom0, 6, 5);   // Create the new wire instance assigning it to pin 6 and 5

void setup()
{
  myWire.begin(2);                // join i2c bus with address #2

  pinPeripheral(6, PIO_SERCOM_ALT);   //Assign SDA function to pin 6
  pinPeripheral(5, PIO_SERCOM_ALT);   //Assign SCL function to pin 5

  myWire.onRequest(requestEvent); // register event
}

void loop()
{
  delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{
  myWire.write("hello "); // respond with message of 6 bytes
                          // as expected by master
}

// Attach the interrupt handler to the SERCOM
extern "C" {
  void SERCOM0_Handler(void);

  void SERCOM0_Handler(void) {
    myWire.onService();
  }
}

Note that in the pinPeripheral call I used PIO_SERCOM_ALT instead of the PIO_SERCOM used in the tutorial. This is because the SERCOM of the pins used in the tutorial were from the "Perip.C" column, while the SERCOM of the pins I used are in the "Perip.D" column.

Give it a try and let me know if you have any problems or questions.

The master reader sketch that goes with the "Wire Slave Sender" sketch from the tutorial is here:

why do you need a second I2C interface? it is a bus, you can wire more I2C devices to one pair of pins

Regarding the code supplied by Pert, loaded onto nano 33 IoT, does not work. The system was previously tested with original slave sender code using the default I2C port on the slave and it functions correctly.

Logic Analyzer scan shows master sending address but a NAK after every send.

Any suggestions would be appreciated.