Arduino Zero Sercom I2C clock speed

I have created 3 I2c channels and am looking to change the default clock speed to different frequencies on each channel. I have initialised all 3 channels and am able to see the device on the bus, write to registers etc.

Is it possible to change the speed?

The following works at default speed

TwoWire I2C_CH1(&sercom3, 20, 21);

pinPeripheral(20, PIO_SERCOM);
pinPeripheral(21, PIO_SERCOM);

I am aware that wire.setClock(10000) changes the frequency on a non sercom board

So I tried

TwoWire I2C_CH1(&sercom3, 20, 21);
TwoWire I2C_CH1.setClock(10000);

pinPeripheral(20, PIO_SERCOM);
pinPeripheral(21, PIO_SERCOM);

But I get the error

sercom_test:7: error: expected initializer before '.' token

TwoWire I2C_CH1.setClock(10000);

Not sure that I have used setClock correctly??

Hi mattdd,

On the SAMD21 the Wire library setClock() function uses the following formula, to calculate the value in the I2C sercom's 8-bit BAUD register from the specified baud rate (clock speed):

sercom->I2CM.BAUD.bit.BAUD = SystemCoreClock / ( 2 * baudrate) - 5 - (((SystemCoreClock / 1000000) * WIRE_RISE_TIME_NANOSECONDS) / (2 * 1000));

where:
SystemCoreClock = 48000000
WIRE_RISE_TIME_NANOSECONDS = 125

A baud rate of 10000 generates a value 2392, however this number is too large for the 8-bit BAUD register.

The default baud rate of 100000 sets the BAUD register to 232, while the lowest baud rate possible is 91254, (sets BAUD to 255).

Hi Martin,

Thank you for getting back to me, so from the information you have provided, it looks like I can change the I2C clock from 10kHz to 3MHz. Was not aware of the formula you provided good to know.

That answers my first question but I'm still a bit lost with

TwoWire I2C_CH1.setClock(10000);

Will not compiling "error: expected initializer before '.' token" not sure what I'm missing

Hi mattdd,

The formula means that using the default Wire (or TwoWire) configuration, it's not possible to go below 100kHz. Therefore the following line of code correctly sets the SCL clock to 100kHz:

TwoWire I2C_CH1.setClock(100000);

...whereas attempting to set the SCL clock to 10kHz, doesn't work:

TwoWire I2C_CH1.setClock(10000);

...this is because the forumula generates a number too large for the SERCOM's 8-bit BAUD register.

The error is most likely a syntax error somewhere in your code.