title: I²C EEPROM read error in a specific address block
body: <p>I have an Arduino's <a href="http://en.wikipedia.org/wiki/I%C2%B2C" rel="nofollow">I²C</a> bus connected to the I²C bus of a Microchip <a href="http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;nodeId=1406&amp;dDocName=en010072" rel="nofollow">PICDEM 2</a> board to program its 32K byte EEPROM. The code below has a read problem. Specifically, I have written the entire EEPROM with a 16-bit counting pattern and verified that all of the data is correct.</p>
  
  <p>The following code is driven by a Java program on a PC. I am reading and writing 16 byte pages. I have monitored the addresses coming from the PC, and they are all correct. The data coming back is all correct except for the 256 byte block of address at <code>0x0AXX</code>. The read data looks like the line from <code>0x9F0</code>. I have not be able to figure out why the error is occurs.</p>
  
  <pre class="lang-cpp prettyprint-override"><code>#include "Wire.h"
  
  const int bufsize = 68;
  char ibuf[bufsize];
  int bytecnt;
  int result;
  
  void setup() {
      Wire.begin();
      Serial.begin(9600);
  }
  
  void i2c_init() {
      Wire.begin();
  }
  
  void i2c_write( int addr, int count ){
      Wire.beginTransmission( addr );
      for(int i=0;i&lt;count;i++) {
         Wire.write(ibuf[3+i]);
      }
      result = Wire.endTransmission();
      delay(20);
      Serial.write(result);
  }
  
  void i2c_read( int addr, int count ){
      result = Wire.requestFrom( addr, count );
      Serial.write( result );
  }
  
  void i2c_xfer( int count ){
      for(int i=0; i&lt;count; i++ ){
          Serial.write( Wire.read() );
      }
  }
  
  
  void loop() {
      // Accept a line of input
      bytecnt = Serial.readBytesUntil('\n', ibuf, bufsize);
      if ( bytecnt &gt; 0 ) {
          switch( ibuf[0] ) {
              case 0: i2c_init(); break;
              case 1: i2c_write(ibuf[1],ibuf[2]); break;
              case 2: i2c_read(ibuf[1],ibuf[2]); break;
              case 3: i2c_xfer(ibuf[1]); break;
              default: break;
          }
      }
  }
  </code></pre>
  
  <p>The data received by the PC is all correct except for the following block:</p>
  
  <pre><code>09c0  e0 04 e1 04 e2 04 e3 04 e4 04 e5 04 e6 04 e7 04
  09d0  e8 04 e9 04 ea 04 eb 04 ec 04 ed 04 ee 04 ef 04
  09e0  f0 04 f1 04 f2 04 f3 04 f4 04 f5 04 f6 04 f7 04
  09f0  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0a00  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0a10  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0a20  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0a30  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0a40  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0a50  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0a60  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0a70  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0a80  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0a90  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0aa0  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0ab0  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0ac0  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0ad0  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0ae0  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0af0  f8 04 f9 04 fa 04 fb 04 fc 04 fd 04 fe 04 ff 04
  0b00  80 05 81 05 82 05 83 05 84 05 85 05 86 05 87 05
  0b10  88 05 89 05 8a 05 8b 05 8c 05 8d 05 8e 05 8f 05
  0b20  90 05 91 05 92 05 93 05 94 05 95 05 96 05 97 05
  </code></pre>
  
  <p>Everything before and after this block is fine, but 0x0A00 - 0x0AFF repeat the data from line 0x09F0.  The following code was used to write and verify all of the counting pattern:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>#include "Wire.h"
  
  int EEPROM = 0x50;
  int pageSize = 0x10;
  unsigned int length = 0x8000;
  unsigned int addr = 0;
  unsigned int data = 0;
  unsigned int datah = 0;
  unsigned int datal = 0;
  int result;
  unsigned int i;
  unsigned int r;
  long j;
  int k;
  int errors;
  
  void setup() {
      Wire.begin();
      Serial.begin(9600);
  }
  
  void eeprom_check() {
      for(i=0; i&lt;length; i+=pageSize) {
          // Write to set address pointer
          Wire.beginTransmission( EEPROM );
          Wire.write( (i&gt;&gt;8) &amp; 0xFF );
          Wire.write(  i &amp; 0xFF   );
          Wire.endTransmission();
  
          if(( i &amp; 0xfF ) == 0 ) {
              Serial.write('\n');
              Serial.print( i,HEX);
              Serial.write(": ");
          }
  
          errors = 0;
          result = Wire.requestFrom( EEPROM, pageSize );
          for(j=0; j&lt;8; j++) {
              datal = Wire.read();
              datah = Wire.read();
              data = (i&gt;&gt;1)+j;
              if( datal != (data &amp; 0xFF) )
                  errors += 1;
              if( datah != ( (data&gt;&gt;8) &amp; 0xFF) )
                  errors += 1;
          }
          if( errors &gt; 0 )
              Serial.write('X');
          else
              Serial.write('_');
      }
  }
  
  void eeprom_dump() {
      for(i=0; i&lt;length; i+=pageSize) {
          // Write to set address pointer
          Wire.beginTransmission( EEPROM );
          Wire.write( (i&gt;&gt;8) &amp; 0xFF );
          Wire.write(  i &amp; 0xFF   );
          Wire.endTransmission();
  
          if(( i &amp; 0xF ) == 0 ) {
              Serial.write('\n');
              Serial.print( i,HEX);
              Serial.write(": ");
          }
  
          result = Wire.requestFrom( EEPROM, pageSize );
          for(j=0; j&lt;result; j++) {
              data = Wire.read();
              if( data &lt; 16 ){
                  Serial.print('0');
                  Serial.print(data,HEX);
              }
              else {
                  Serial.print(data,HEX);
              }
              Serial.print(' ');
          }
      }
  }
  
  void eeprom_write() {
      for(i=0; i&lt;length; i+=pageSize) {
          for(k=0; k&lt;10; k++){
              Wire.beginTransmission( EEPROM );
              Wire.write( (i&gt;&gt;8) &amp; 0xFF );
              Wire.write(  i &amp; 0xFF   );
  
              for(j=0; j&lt;8; j++ ){
                  data = (i&gt;&gt;1)+j;
                  Wire.write(  data     &amp; 0xFF );
                  Wire.write( (data&gt;&gt;8) &amp; 0xff );
              }
  
              result = Wire.endTransmission();
              delay(10);
              if( result==0 )
                  break;
              else
                  Serial.write(result);
          }
          k = i / pageSize;
          if(( k &amp; 0xF ) == 0 ) {
              Serial.write('\n');
              Serial.print( i,HEX);
              Serial.write(": ");
          }
          Serial.write('W');
      }
  }
  
  void eeprom_break() {
      i = 0xa00;
      Wire.beginTransmission( EEPROM );
      Wire.write( (i&gt;&gt;8) &amp; 0xFF );
      Wire.write(  i &amp; 0xFF   );
      Wire.write( 0x55 );
      Wire.write( 0xAA );
      Wire.endTransmission();
      Serial.write("Break Compelted\n");
  }
  
  void loop() {
      char ch;
      Serial.write("Interactive EEPROM Test Tool\n");
      while( true ) {
          Serial.write('&gt;');
          while(  Serial.available() == 0 );
          ch = Serial.read();
          Serial.write( ch );
          Serial.write('\n');
          while( Serial.available() != 0)
              Serial.read();
          switch( ch ) {
              case 'c': eeprom_check(); break;
              case 'd': eeprom_dump(); break;
              case 'w': eeprom_write(); break;
              case 'z': eeprom_break(); break;
              default: break;
          }
      }
  }
  </code></pre>
  
  <p>I have been struggling with this for days.  Any insight would be greatly appreciated.</p>