I am trying to reproduce the EDID Fuzzer from http://media.blackhat.com/bh-eu-12/Davis/bh-eu-12-Davis-HDMI-Slides.pdf
The problem arises when I put Wire.endTransmission(false) instead of Wire.endTransmission(true) and then use Wire.requestFrom in the MASTER. The slave never activate the interruption RequestEvent.
How can I use Wire.endTransmission(false) with the SLAVE ?
MASTER
#include <Wire.h>
#define EDID_SLAVE 0x50
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
Serial.println("PC START");
}
byte cont = 0;
byte x = 0x00;
void loop()
{
Wire.beginTransmission(EDID_SLAVE); // transmit to device #4
Wire.write(x); // sends one byte
Wire.endTransmission(false); // stop transmitting PROBLEM HERE if I change to TRUE it works fine
delay(20);
///////////////////////////////////////
// Request EDID configuration
Wire.requestFrom(EDID_SLAVE,128); // PROBLEM HERE
Serial.print("requestFrom -- ");
cont = 0;
Serial.println("***********************");
while(Wire.available()) // loop through all but the last
{
byte c = Wire.read(); // receive byte as a character
Serial.print(cont);
Serial.print(" :");
Serial.println(c,HEX); // print the character
cont++;
}
Serial.println("***********************");
//////////////////////////////////////
if(x == 0x00)
x = 0x80;
delay(1000);
}
SLAVE
void setup()
{
pinMode(hotplugpin, OUTPUT); // initialize as output
digitalWrite(hotplugpin, LOW); // unplug the cable
Wire.begin(EDID_SLAVE); // join i2c bus with address #4
Wire.onReceive(receiveEvent); // register event
Wire.onRequest (requestEvent);
Serial.begin(9600); // start serial for output
Serial.println("RECEPTOR v1.8 START");
digitalWrite(hotplugpin, HIGH); // plug in cable
}
void loop()
{
Serial.println("Ciclo");
byte y = 0;
int x = 0;
byte temp = 0;
while (z < 128)
{
y = 0;
while (y < 1)
{
temp = EDIDArray[z]; // save off current value
EDIDArray[z] = 0xff; // modify each value in turn to be 0xff (use y to iterate through each value per byte)
digitalWrite(hotplugpin, LOW); // unplug the cable
delay (10);
digitalWrite(hotplugpin, HIGH); // plug in cable
delay (1500);
Serial.print(z);
Serial.print(":");
x = y;
Serial.print(x);
Serial.print("\n");
EDIDArray[z] = temp; // restore value to structure
y = y + 1;
}
z = z + 1;
}
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
Serial.print("receiveEvent ");
Serial.print(howMany);
Serial.print(" bytes --");
while(1 < Wire.available()) // loop through all but the last
{
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
int x = Wire.read(); // receive byte as an integer
Serial.println(x); // print the integer
}
void requestEvent()
{
Serial.println("requestEvent --"); // PROBLEM HERE - Never enter here
int c = 0;
int d = 0;
byte csum = 0;
for (int x = 0; x < 127; x++)
csum += EDIDArray[x];
c = csum;
d = 256 - c;
EDIDArray[127] = d;
c = 0;
d = 0;
csum = 0;
for (int x = 0; x < 127; x++)
csum += EDIDArray2[x];
c = csum;
d = 256 - c;
EDIDArray2[127] = d;
////// fix up checksums /////
if (count==1)
{
Wire.write(EDIDArray,128); // !!Need to change BUFFER_LENGTH to 128 in wire.h and TWI_BUFFER_LENGTH to 128 in twi.h
count = 2;
}
else
{
Wire.write(EDIDArray2,128); // replace Wire.send(EDIDArray2,128)
count = 1;
}
}