Pages: [1]   Go Down
Author Topic: Wire.requestFrom(SLAVE,BYTES) not working after Wire.endTransmission(false)  (Read 1149 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Code:
#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
Code:

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;
    }
   
  }
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 201
Posts: 8699
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wire.endTransmission() returns a status code.  What status code are you getting?

It looks like you use endTransmission(false) when you want to send another, separate, transmission. Is there some reason you want to use 'false' there instead of the default?  Does it not work with the default?
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Wire.endTransmission() returns Successful. I realize that SLAVE arduino doesn't responde I2C Combined Format.

Page 15 of the THE I2C-BUS SPECIFICATION VERSION 2.1 document
http://www.google.com.mx/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CB8QFjAA&url=http%3A%2F%2Fwww.cs.unc.edu%2FResearch%2Fstc%2FFAQs%2FInterfaces%2FI2C-BusSpec-V2.1.pdf&ei=S0ZyUJCRKMr5igKX64CoCQ&usg=AFQjCNGFG1psxfu2SC-DOMWNb22GVvvzEQ&cad=rja


That means,

MASTER sends    startbit-writeslaveaddress-ack-datafrommaster-startbit-readslaveaddress-ack-datafromslave-ack-stopbit.
the Slave do not activate the Interruption to send data to master.


It works fine when:
MASTER sends    startbit-writeslaveaddress-ack-datafrommaster-ack-stopbit
The slave active the interruption to read data from master

MASTER sends   startbit-readslaveaddress-ack-datafromslave-ack-stopbit
The slave active the interruption to send data to master.

Logged

Pages: [1]   Go Up
Jump to: