Hi all,
I am setting up a Zero with two I2C interfaces. The default Wire interface is being used as a slave while I added an I2C interface as a master to pins D3 and D4 using sercom2. For now I wrap the master/slave interfaces around to each other on the same Zero for testing. Pull ups are included in my wiring. While this works, I find that the setClock function does not alter the master's frequency the same it did on AVR devices. For example, using:
I2CMaster.setClock(400000L);
results in a (approximate) 340kHz clock speed. The closest I can get to 400 kHz is by using:
I2CMaster.setClock(462000L);
and results in a (approximate) 390kHz clock speed.
Trial and error of different values has gotten me close to 400Khz. I've attached a sketch below that makes this easy to replicate. Any info on how to use setClock on the Zero is appreciated.
Thanks,
Lenny
#include <Wire.h>
#include "wiring_private.h" // pinPeripheral() function
uint8_t message_count = 0;
uint8_t myBuff[] = {0x00, 0x00, 0x00};
uint8_t i2cMessage[32] = {0};
volatile boolean timer1HzFired = false;
uint8_t interrupt_count = 0;
volatile boolean LEDON = false;
TwoWire I2CMaster(&sercom2, 4, 3);
void setup() {
/* Init the serial port */
Serial.begin(115200); // Init UART at 115.2 kbps (USB COM Port)
Serial.setTimeout(1); // 1 ms timeout on reads from USB COM Port
// while the serial stream is not open, do nothing (useful for seeing setup prints):
while (!Serial) ;
Serial.println("Serial port init complete");
Wire.begin(0x0C); // Init I2C with controller slave address
Wire.onRequest(requestEvent); // Register interrupt call back for an I2C read
Wire.onReceive(receiveEvent); // Register interrupt call back for an I2C write
Serial.println("Wire init complete");
/*
* Used as a visual indication of the 1Hz timing
*/
pinMode(LED_BUILTIN, OUTPUT);
Serial.println("LED init complete");
I2CMaster.begin();
I2CMaster.setClock(465000L);
// Assign pins 4 & 3 to SERCOM functionality
pinPeripheral(4, PIO_SERCOM_ALT);
pinPeripheral(3, PIO_SERCOM_ALT);
Serial.println("I2C Master init complete");
}
void loop() {
if (millis() % 1000 == 0) {
timer1HzFired = true;
}
if (timer1HzFired) {
Serial.println("1Hz Flag True");
timer1HzFired = false;
callback1Hz();
}
}
void sendMessage(const uint8_t *buf, uint8_t size)
{
uint8_t i2cAddress = buf[0];
for (int j = 0; j < size; j++) {
i2cMessage[j] = buf[j+1];
}
I2CMaster.beginTransmission(i2cAddress);
I2CMaster.write(i2cMessage,(size-1));
I2CMaster.endTransmission();
}
//--------------------------------------------
// onRequest Interrupt Handler
//--------------------------------------------
void requestEvent() {
}
//--------------------------------------------
// onReceive Interrupt Handler
//--------------------------------------------
void receiveEvent(int bytesReceived) {
}
// Callback at 1Hz
void callback1Hz()
{
/*
* The LED will be on for 1 second and then off for 1 second
*/
if (LEDON) {
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
Serial.println("LED Off");
}
else {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on by making the voltage HIGH
Serial.println("LED On");
}
LEDON = !LEDON;
message_count++;
myBuff[0] = 0x0C;
myBuff[1] = 0xFF;
myBuff[2] = message_count;
sendMessage(myBuff, 3);
}