SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By dksmall
#192782
I have an external EEPROM connected to the SCL and SDA pins and created a simple sketch that uses the wire library. This setup works great on a RedBoard, but with the SAMD21, all I get back from the EEPROM reads is 0xFF. And after running a few minutes the code goes off into wonderland and stops responding. As you can see from the screen shots, the signals on the SAMD21 aren't even close to what they should be.

Any ideas what I need to do here? Does the SAMD21 have a special setup I need to use for I2C?
Code: Select all
/*  SAMD21

    Simple program to read/write a AT24C256 EEprom
*/

  #include <Wire.h> //I2C library

  void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
    int rdata = data; 
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.write(rdata);
    Wire.endTransmission();
  }

  // WARNING: address is a page address, 6-bit end will wrap around
  // also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes
  void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddresspage >> 8)); // MSB
    Wire.write((int)(eeaddresspage & 0xFF)); // LSB
    byte c;
    for ( c = 0; c < length; c++)
      Wire.write(data[c]);
    Wire.endTransmission();
  }

  byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
    byte rdata = 0xFF;
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,1);
    if (Wire.available()) rdata = Wire.read();
    return rdata;
  }

  // maybe let's not read more than 30 or 32 bytes at a time!
  void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) {
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,length);
    int c = 0;
    for ( c = 0; c < length; c++ )
      if (Wire.available()) buffer[c] = Wire.read();
  }

  void setup()
  {
    char somedata[] = "Team Small Robots says HI"; // data to write
    SerialUSB.begin(19200);
    delay(5000);
    SerialUSB.println("Ready");
//    while (!SerialUSB);
    Wire.begin();                       // initialise the connection
    i2c_eeprom_write_page(0x50, 0, (byte *)somedata, sizeof(somedata)); // write to EEPROM
//    i2c_eeprom_write_byte(0x50, 0x1234, 0x56);
    delay(1000); //add a small delay
    SerialUSB.println("Memory written ");                              
  }

  void loop()
  {
    int addr=0; //first address
    byte b = i2c_eeprom_read_byte(0x50, 0); // access the first address from the memory

    while (b!=0)
    {
        SerialUSB.print((char)b);                  //print content to SerialUSB port
//        SerialUSB.print(b,HEX);
        addr++;                                 //increase address
        b = i2c_eeprom_read_byte(0x50, addr);   //access an address from the memory
    }
    SerialUSB.println("");
    delay(1000);

  }
You do not have the required permissions to view the files attached to this post.
By dksmall
#192790
Yep, that's what it was. After I added some pull-ups, it's working fine with the SAMD21. Now why did it work for the RedBoard? I'm guessing the internal pull-ups were used for the mega328, does the SAMD21 not have pull-ups? I haven't dived that deep into that huge data sheet yet.

Thanks for the help.
User avatar
By darrellg
#192799
I don't know why it worked on one but not the other, but lack of pullup resistors is the most common problem with I2C communication. Perhaps the the Redboard just happened to float high enough to allow it to work.