The intent: Using the controller and I2C for turning a port high and low and querying for data from an agent.
The setup: Two Adafruit Itsybitsy M0 Express, but tested on the MKRWIFI1010 as well to same result so this seems to be ATSAMD21 specific. Testing with a NANO EVERY the problem does not occur. Connected via I2C, 4k7 pullups on SDA/SCL. Working example that shows the bug:
Controller:
//CONTROLLER
#include <Wire.h>
uint8_t data[6];
void setup()
{
Wire.begin(); //start I2C
}
void loop()
{
enablePort(0x22);
delay(10);
fetch(0x22);
delay(90);
disablePort(0x22);
delay(100);
}
void fetch(uint8_t add)
{
Wire.requestFrom(add,6,1); //address, quantity ~574uS, bus release
uint8_t n = 0;
while(Wire.available())
{
data[n] = Wire.read();
n++;
}
}
void enablePort(uint8_t port)
{
uint8_t send_status = 1;
while(send_status != 0)
{
Wire.beginTransmission(port);
Wire.write(1);
send_status = Wire.endTransmission();
}
}
void disablePort(uint8_t port)
{
uint8_t send_status = 1;
while(send_status != 0)
{
Wire.beginTransmission(port);
Wire.write(0);
send_status = Wire.endTransmission();
}
}
Agent:
//AGENT
#include <Wire.h>
uint8_t buffer[6] = {1,2,3,4,5,6};
void setup()
{
Wire.begin(0x22); //join I2C Bus at address 8 (0-7 is reserved)
Wire.onRequest(sendData); //what to do when being talked to
Wire.onReceive(receiveEvent); //what to do with data received
pinMode(13,OUTPUT);
pinMode(10,OUTPUT);
}
void loop() {}
void sendData()
{
Wire.write(buffer,6);
}
void receiveEvent(int bytes_incoming)
{
byte c = Wire.read();
if(c == 1)
{
REG_PORT_OUTSET0 = PORT_PA18; //pin on
digitalWrite(13,HIGH);
}
else
{
REG_PORT_OUTCLR0 = PORT_PA18; //pin off
digitalWrite(13,LOW);
}
}
What should happen: PA18 (D10) and D13 (the LED) should alternately go high and low with a 100ms interval.
What actually happens: Both Ports are pulled high only for 10ms and when the function fetch() is called, both ports are immediately pulled low. I'm not sure if the problems comes from the IIC library or the hardware or somewhere else.