Reading and Writing Data

The SeeSaw operates as an I2C slave device using standard I2C protocol. It uses the SDA and SCL pins to communicate with the host system.

We do not use clock stretching. The I2C is 3.3V logic level (but often times a 5V microcontroller will work fine with 3.3V logic levels and it is an open-drain protocol). Only 7-bit addressing is supported.

I2C pullup resistors are included in our SeeSaw boards but if you are DIY'ing, be sure to add your own! 2.2K - 10K is a good range.

Setting the Device Address

Standard 7-bit addressing is used. The seesaw's default I2C address is initially configured in the compiled firmware (e.g for the SAM09 SeeSaw breakout we use 0x49) but other boards will have a different base address.

This address can be modified using the address select pins. If address select pin 0 (PA16) is tied to ground on boot, the I2C address is incremented by 1. If address select pin 1 (PA17) is pulled low, the I2C address is incremented by 2. If both address select pins are pulled low, the I2C address is incremented by 3. Thus you can, with the same hardware, have up to 4 devices

The I2C address can also be modified by writing a new address to EEPROM. See the EEPROM section for more information.

I2C Transactions

We recommend using 100KHz I2C, but speeds of up to 400KHz are supported. You may want to decrease the SDA/SCL pullups to 2.2K from 10K in that case.

Writing Data

A seesaw write command consists of the standard I2C write header (with the R/W bit set to 1), followed by 2 register bytes followed by zero or more data bytes.

The first register byte is the module base register address. Each module (GPIO, ADC, DAC, etc.) has it's own unique 8 bit base identifier.

The second register byte is the module function register address. This byte specifies the desired register within the module to be written.

Thus we have up to 254 modules available (0x00 is reserved) and 255 functions per module - plenty to allow all sorts of different capabilities!

In code, this may look like this (using the Arduino wire I2C object):

void Adafruit_seesaw::write(uint8_t moduleBase, uint8_t moduleFunction, uint8_t *buf, uint8_t num)
{ 
	Wire.beginTransmission((uint8_t)_i2caddr);
	Wire.write((uint8_t)moduleBase); //module base register address
	Wire.write((uint8_t)moduleFunction); //module function register address
	Wire.write((uint8_t *)buf, num); //data bytes
	Wire.endTransmission();
}
The Arduino UNO Wire library implementation has a limit of 32 bytes per transaction so be aware you may not be able to read/write more than that amount. We have designed the library to work within those constraints

Reading Data

A register read is accomplished by first sending the standard I2C write header, followed by the two register bytes corresponding to the data to be read. Allow a short delay, and then send a standard I2C read header (with the R/W bit set to 0) to read the data.

The length of the required delay depends on the data that is to be read. These delays are discussed in the sections specific to each module.

In code, this may look like this  (using the Arduino wire I2C object):

void Adafruit_seesaw::read(uint8_t moduleBase, uint8_t moduleFunction, uint8_t *buf, uint8_t num, uint16_t delay)
{
  Wire.beginTransmission((uint8_t)_i2caddr);
  Wire.write((uint8_t)moduleBase); //module base register address
  Wire.write((uint8_t)moduleFunction); //module function register address
  Wire.endTransmission();

  delayMicroseconds(delay);

  Wire.requestFrom((uint8_t)_i2caddr, num);

  for(int i=0; i<num; i++){
    buf[i] = Wire.read();
  }
}
Last updated on 2017-11-01 at 05.04.55 PM Published on 2017-11-01 at 05.26.25 PM