Adafruit seesaw
Created by Dean Miller

https://learn.adafruit.com/adafruit-seesaw-atsamd09-breakout

Last updated on 2024-06-10 12:25:40 PM EDT©Adafruit Industries

Page 1 of 46

Table of Contents
Overview

5

Pinouts

7• Power Pins:• Logic Pins:• GPIO Pins:• Neopixel Pins:• Address Pins:• ADC Pins:• PWM Pins:• Interrupt Pins:• Programming Pins:

Arduino Wiring & Test

9

• Arduino Wiring & Test
• I2C Wiring• Download Adafruit_Seesaw library• Load Test Example• Documentation

CircuitPython Wiring & Test

12

• CircuitPython Wiring & Test
• I2C Wiring• Download Adafruit_CircuitPython_Seesaw library

Python Docs

14

Raspberry Pi Wiring & Test

14

• Install Python Software• Enable I2C• Run example code
• Documentation• Full Example CodeUsing the Seesaw Platform

19• Repo Summary

Reading and Writing Data

19

• Setting the Device Address• I2C Transactions• Writing Data
• Base Register Summary• Reading Data

Status23• Function Register Summary• Function Register Description• 0x01 - HW_ID• 0x02 - VERSION• 0x03 - OPTIONS• 0x04 - TEMP

©Adafruit Industries

Page 2 of 46

• 0x7F - SWRST

GPIO

26

• Function Registers• GPIO register setup on SAMD09:• GPIO register setup on ATTiny8x7:• DIRSET (0x02, 32 bits, Write Only)• DIRCLR (0x03, 32 bits, Write Only)• GPIO (0x04, 32 bits, Read/Write)• SET (0x05, 32 bits, Write Only)• CLR (0x06, 32 bits, Write Only)• TOGGLE (0x07, 32 bits, Write Only)• INTENSET (0x08, 32 bits, Write Only)• INTENCLR (0x09, 32 bits, Write Only)• INTFLAG (0x0A, 32 bits, Read Only)• PULLENSET (0x0B, 32 bits, Write Only)• PULLENCLR (0x0C, 32 bits, Write Only)

UART

30

• Function Registers• Status (0x00, 8bits, Read Only)• INTEN (0x2, 8bits, Read/Write)• INTENCLR (0x03, 8bits, Write Only)• BAUD (0x04, 32bits, Read/Write)• DATA (0x05, 32bytes, Read/Write )

PWM

33

• Nomenclature• Function Register Summary• Function Register Description• 0x01 - PWM_VAL• 0x02 - PWM_FREQ• Port Specific Details• SAMD• ATtiny

Analog to Digital Converter

35• SAMD09 ADC channels are:• ATtiny8x7 ADC channels are:• Function Registers• STATUS (0x00, 8bits, Read Only)•• INTENSET (0x02, 8bits, Write Only)• INTENCLR (0x03, 8bits, Write Only)• WINMODE (0x04, 8bits, Write Only)• WINTHRESH (0x05, 32bits, Write Only)• CHANNEL_0 (0x07, 16bits, Read Only)• CHANNEL_1 (0x08, 16bits, Read Only)• CHANNEL_2 (0x09, 16bits, Read Only)• CHANNEL_3 (0x0A, 16bits, Read Only)• CHANNEL_20 (0x1B, 16bits, Read Only)

Interrupts

39

EEPROM40• Function Registers©Adafruit Industries

Page 3 of 46

• SAMD09• ATtiny817

NeoPixel

41• Function Registers• PIN (0x01, 8bits, Write Only)• SPEED (0x02, 8bits, Write Only)• BUF_LENGTH (0x03, 16bits LE, Write Only)• BUF (0x04, 32 bytes, Write Only)• SHOW (0x05, no args, Write Only)

Encoder42• Function Register Summary• Function Register Description• 0x00 - Status• 0x10 - Interrupt Set• 0x20 - Interrupt Clear• 0x30 - Position• 0x40 - Delta

Downloads

44• Documents• Schematic• Dimensions

Documentation

46©Adafruit Industries

Page 4 of 46

Overview

Adafruit seesaw is a near-universal converter framework which allows you to add andextend hardware support to any I2C-capable microcontroller or microcomputer.
Instead of getting separate I2C GPIO expanders, ADCs, PWM drivers, etc, seesaw canbe configured to give a wide range of capabilities.

For example, our ATSAMD09 breakout with seesaw gives you• 3 x 12-bit ADC inputs©Adafruit Industries

Page 5 of 46

• 3 x 8-bit PWM outputs• 7 x GPIO with selectable pullup or pulldown• 1 x NeoPixel output (up to 170 pixels)• 1 x EEPROM with 64 byte of NVM memory (handy for storing small access tokens
or MAC addresses)• 1 x Interrupt output that can be triggered by any of the accessories• 2 x I2C address selection pins
• 1 x Activity LED
But you can reprogram and reconfigure the chip to have more or less of each
peripheral - as long as it fits into the ATSAMD09D14's firmware! For example, there's
also a UART converter but it isn't included in the default firmware.

The ATSAMD09 breakout is great for development of seesaw capabilities (we use it
in-house for our design work) or you can use it as-is to give your Raspberry Pi or
ESP8266 more hardware support! Each breakout comes with the assembled andtested board, as well as some header strips.
Please note: The boards do not come with a bootloader. If you want to do
development using seesaw you'll need to pick up a J-Link (https://adafru.it/BrS)and
we recommend a SWD adapter breakout (http://adafru.it/2743) - at this time our
project is for Atmel Studio but you could probably get it working with arm gcc and a
Makefile. We don't provide any support for custom builds of seesaw - we think this iscool and useful for the Maker community!

©Adafruit Industries

Page 6 of 46

Pinouts©Adafruit Industries

Page 7 of 46

Power Pins:• Vin - this is the power pin. Since the ATSAMD09 uses 3.3V, we have included an
on-board voltage regulator that will take 3-5VDC and safely convert it down. You
can power from 3.3V to 5V• 3Vo - this is the 3.3V output from the voltage regulator, you can grab up to
100mA from this if you like
• GND - common ground for power and logic

Logic Pins:• 23 / SCL - this is the I2C clock pin, connect to your microcontrollers I2C clockline. There is a 10K pullup on this pin to 3.3V. I2C is 'open drain' which means aslong as you don't add an extra pullup you can use with 5V logic devices.
• 22 / SDA - this is the I2C data pin, connect to your microcontrollers I2C dataline. There is a 10K pullup on this pin to 3.3V. I2C is 'open drain' which means aslong as you don't add an extra pullup you can use with 5V logic devices.
• RST - this is the reset pin. Pulling this pin to ground resets the device.

GPIO Pins:• Pins 9, 10, 11, 14, 15, 24, and 25 can be used as GPIO.

Neopixel Pins:• Pins 9, 10, 11, 14, 15, 24, and 25 can be used as the NeoPixel output.

Address Pins:• 16 / AD0 - this is the ADDR0 pin. Connect this to ground to increment thedevices I2C address by 1.
• 17 / AD1 - this is the ADDR1 pin. Connect this to ground to increment the devices
I2C addres by 2.

ADC Pins:• 2 - this pin can be configured as an ADC input.
• 3 - this pin can be configured as an ADC input.

©Adafruit Industries

Page 8 of 46

• 4 - this pin can be configured as an ADC input.

PWM Pins:• 5 - this pin can be configured as a PWM output.
• 6 - this pin can be configured as a PWM output.
• 7 - this pin can be configured as a PWM output.

Interrupt Pins:• 8 / IRQ - this pin gets pulled low by the seesaw to signal to your hostmicrocontroller that an interrupt has occurred.

Programming Pins:• SWD - this pin connects to SWDIO of an SWD compatible programmer toprogram the device over SWD.
• SWC - this pin connects to SWCLK of an SWD compatible programmer toprogram the device over SWD.
• RST - this pin connects to RESET of an SWD compatible programmer to program
the device over SWD.

Arduino Wiring & Test
Arduino Wiring & Test
You can easily wire this breakout to any microcontroller, we'll be using an Adafruit
Metro M0 Express (Arduino compatible) with the Arduino IDE. But, you can use anyother kind of microcontroller as well as long as it has I2C clock and I2C data lines.

I2C Wiring• Connect Vin to the power supply, 3-5V is fine.
• Connect GND to common power/data ground• Connect the SCL pin (23) to the I2C clock SCL pin on your Microcontroller.
• Connect the SDA pin (22) to the I2C data SDA pin on your Microcontroller.

©Adafruit Industries

Page 9 of 46

• Connect the positive (long lead) of an LED to pin 15 on the seesaw breakout andthe other lead to GND through a 1k ohm resistor.
This seesaw uses I2C address 0x49 by default. You can change this by grounding theAD0/16 and/or AD1/17 pins, but we recommend not doing that until you have it
working

Download Adafruit_Seesaw library
To begin reading sensor data, you will need to download Adafruit_Seesaw from theArduino library manager.
Open up the Arduino library manager:

Search for the Adafruit Seesaw library and install it©Adafruit Industries

Page 10 of 46

We also have a great tutorial on Arduino library installation at:
http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use (https://
adafru.it/aYM)

Load Test Example
Open up File->Examples->Adafruit_Seesaw->digital->blink and upload to yourArduino wired up to the seesaw breakout. If everything is wired up correctly, the led
should blink on and off repeatedly.

Documentation
see here (https://adafru.it/BrT) for documentation of the seesaw python API.

©Adafruit Industries

Page 11 of 46

CircuitPython Wiring & Test
CircuitPython Wiring & Test
You can easily wire this breakout to a microcontroller running CircuitPython. We will
be using a Metro M0 Express.

I2C Wiring• Connect Vin to the power supply, 3-5V is fine.
• Connect GND to common power/data ground• Connect the SCL pin (23) to the I2C clock SCL pin on your CircuitPython board,usually marked SCL. On a Gemma M0 this would be Pad #2/ A1• Connect the SDA pin (22) to the I2C data SDA pin on your CircuitPython board,usually marked SDA. On an Gemma M0 this would be Pad #0/A2• Connect the positive (long lead) of an LED to pin 15 on the samd09 breakout
and the other lead to GND through a 1k ohm resistor.
The seesaw uses I2C address 0x49 by default. You can change this by grounding theAD0/16 and/or AD1/15 pins, but we recommend not doing that until you have it
working©Adafruit Industries

Page 12 of 46

Download Adafruit_CircuitPython_Seesaw
library
To begin using the seesaw, you will need to download
Adafruit_CircuitPython_Seesaw from our github repository. You can do that by visiting
the github repo and manually downloading or, easier, just click this button to
download the zip

Adafruit CircuitPython Seesaw
Library
https://adafru.it/10bv
Extract the zipped folder and rename the folder it contains to Adafruit_seesaw. dragthe Adafruit_seesaw folder to the lib folder that appears on the CIRCUITPY drive.
You'll also need the adafruit_busdevice driver.

Our CircuitPython library may change APIs so consider this beta!
Open the code.py file on the CIRCUITPY drive and copy and paste the followingcode:from board import *import busio
from adafruit_seesaw.seesaw import Seesaw
import time
myI2C = busio.I2C(SCL, SDA)
ss = Seesaw(myI2C)
ss.pin_mode(15, ss.OUTPUT);©Adafruit Industries

Page 13 of 46

while True:
ss.digital_write(15, True)time.sleep(1)ss.digital_write(15, False)time.sleep(1)# turn the LED on (True is the voltage level)# wait for a second# turn the LED off by making the voltage LOW

The LED attached to pin 15 should blink on and off repeatedly.

Python Docs
Python Docs (https://adafru.it/C5y)

Raspberry Pi Wiring & Test
The Raspberry Pi also has an I2C interface that can be used to communicate with thisseesaw. You can use this breakout with the CircuitPython library and Python thanks to
Adafruit_Blinka, our CircuitPython-for-Python compatibility library (https://adafru.it/
BSN).

Install Python Software
You'll need to install the Adafruit_Blinka library that provides the CircuitPython librarysupport in Python. This may also require enabling I2C on your platform and verifying
you are running Python 3.
Once that's done, from your command line run the following command:• sudo pip3 install adafruit-circuitpython-seesaw©Adafruit Industries

Page 14 of 46

If your default Python is version 3 you may need to run ' pip ' instead. Just make sure
you aren't trying to use CircuitPython on Python 2.x, it isn't supported!

Enable I2C
We need to enable the I2C bus so we can communicate with the seesaw.
sudo raspi-config

select Advanced options, enable I2C, andthen finish.

©Adafruit Industries

Page 15 of 46

With the Pi powered off, we can wire up the sensor to the Pi Cobbler like this:• Connect Vin to the 3V or 5V power supply (either is fine)• Connect GND to the ground pin on the Cobbler• Connect SDA (22) to SDA on the Cobbler• Connect SCL (23) to SCL on the Cobbler• Connect the positive (long lead) of an LED to pin 15 on the samd09 breakout
and the other lead to GND through a 1k ohm resistor.
You can also use direct wires, we happen to have a Cobbler ready. remember you canplug the cobbler into the bottom of the PiTFT to get access to all the pins!

Now you should be able to verify that the sensor is wired up correctly by asking the Pi
to detect what addresses it can see on the I2C bus:

©Adafruit Industries

Page 16 of 46

sudo i2cdetect -y 1

It should show up under it's default address (0x49). If you don't see 49, check yourwiring, did you install I2C support, etc?

Run example code
At long last, we are finally ready to run our example code. Open the Python REPL tobegin.
First we'll import the necessary libraries, initialise the I2C bus and setup the LED pin
for use:import time
import board
import busio
from adafruit_seesaw.seesaw import Seesaw
i2c_bus = busio.I2C(board.SCL, board.SDA)
ss = Seesaw(i2c_bus)
ss.pin_mode(15, ss.OUTPUT)

Now you're ready to blink the LED using digital_write :while True:
ss.digital_write(15, True)time.sleep(1)ss.digital_write(15, False)time.sleep(1)©Adafruit Industries

Page 17 of 46

If everything is set up correctly, the LED attached to pin 15 on the SAMD09 breakout
should blink on and off repeatedly. Press CTRL + C to stop the program running once
you are satisfied with the blinking.

Documentation
See here (https://adafru.it/C5y) for documentation of the seesaw CircuitPython API.

Full Example Code# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries# SPDX-License-Identifier: MIT# Simple seesaw test using an LED attached to Pin 15.
## See the seesaw Learn Guide for wiring details:# https://learn.adafruit.com/adafruit-seesaw-atsamd09-breakout?
view=all#circuitpython-wiring-and-test
import time
import board
from adafruit_seesaw.seesaw import Seesaw
i2c_bus = board.I2C() # uses board.SCL and board.SDA# i2c_bus = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a
microcontroller
ss = Seesaw(i2c_bus)
ss.pin_mode(15, ss.OUTPUT)
while True:
ss.digital_write(15, True) # turn the LED on (True is the voltage level)
time.sleep(1) # wait for a second
ss.digital_write(15, False) # turn the LED off by making the voltage LOWtime.sleep(1)©Adafruit Industries

Page 18 of 46

Using the Seesaw Platform

The sections under this heading contain more detailed information about how the
Seesaw platform works. If you are using our Arduino, CircuitPython, or Python API
you can skip these sections. These sections are intended for people who either wantto understand and modify seesaw, or who want to make their own API for a platformthat is not officially supported by Adafruit such as C/C++ on Raspberry Pi.

Repo Summary
There are numerous code repositories with "seesaw" in the name. The firmware
repositories contain the code running on the seesaw device itself. The support
libraries are used to interact with *any* seesaw device.
If you are an end user of a seesaw device, then it is the support libraries you want.
There is no support for custom firmware development.
Firmware• seesaw (https://adafru.it/D1-) - for SAMD based boards• Adafruit_seesawPeripheral (https://adafru.it/VdL) - for ATtiny 1-series based
boardsSupport Libraries• Adafruit_CircuitPython_seesaw (https://adafru.it/BrW) - for use with
CircuitPython or Blinka• Adafruit_Seesaw (https://adafru.it/BrV) - for use with Arduino

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

©Adafruit Industries

Page 19 of 46

The I2C bus on the SAMD09 is 3.3V logic level, but all boards other than the SAMD09
breakout have level shifting so you can use 3 or 5V logic. Boards with Attiny chips are
3 or 5V safe so you can use either for power and logic
Only 7-bit addressing is supported.
I2C pullup resistors are included in our SeeSaw boards but if you are DIY'ing, be sureto 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 initiallyconfigured in the compiled firmware (e.g for theSeeSaw breakouts we use 0x49) but
other boards will have a different base address. Check the board documentation forthe default base I2C address, or you can plug it in and scan the I2C bus to findit (https://adafru.it/YEf).
This address can be modified using the address select pins, there can be multiple
address pins. If address select pin 0 (A0) is tied to ground on boot, the I2C address isincremented by 1. If address select pin 1 (A1) is pulled low, the I2C address isincremented by 2. If both address select pins are pulled low, the I2C address isincremented by 3. Thus you can, with the same hardware, have up to 4 devices
On both the SAMD09 and Attiny817 breakouts, the default A0 pin is 16, default A1 pin
is 17. On boards where the chips are embedded, there may be as many as 4 addresspins, they'll be labeled with jumpers
The base 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 0), followed by 2 register bytes followed by zero or more data bytes.

©Adafruit Industries

Page 20 of 46

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 pertransaction so be aware you may not be able to read/write more than thatamount. We have designed the library to work within those constraints

Base Register Summary
The following table summarizes the module base registers addresses. Further details
about the function registers associated for each base register are covered in later
sections.
Not all seesaw products implement all of these features.

Base Register Address

Module0x00

Status0x01©Adafruit Industries

GPIO

Page 21 of 46

0x02 - 0x07

SERCOM

0x08

PWM

0x09

ADC

0x0A

DAC

0x0B

Interrupt

0x0C

DAP

0x0D

EEPROM

0x0E

NeoPixel

0x0F

Touch

0x10

0x11

KeypadEncoder

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 shortdelay, and then send a standard I2C read header (with the R/W bit set to 1) to read thedata.

©Adafruit Industries

Page 22 of 46

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&lt;num; i++){buf[i] = Wire.read();}}StatusBase Register Address

0x00

This module provides hardware specific information, status, and soft reset.

Function Register Summary
Register Address

Register Name

Register Size

Access

0x01

HW_ID

1 byteR

0x02

VERSION

4 bytesR

0x03

OPTIONS

4 bytes

R

0x04

TEMP

4 bytes

R©Adafruit Industries

Page 23 of 46

0x7F

SWRST

0 bytesW

Function Register Description
0x01 - HW_ID
Byte 0Hardware ID CodeA single byte value that provides the hardware specific Hardware ID Code.

0x02 - VERSION
Byte 0

Byte 1

Byte 2Byte 3

Product Code MSB

Product Code LSB

Date Code MSB

Date Code LSB

The Product Code is a unique 16 bit number assigned to each product.
The Date Code is a 16 bit value that indicates the year, month, and day of thefirmware build:• Top 5 bits are day of the month (1-31)• Middle 4 bits are month (1-12)• Bottom 7 bits are 20xx year (00-99)
Here's a Python function for decoding a Date Code into year, month, and day:def datecode_decode(code):year = code &amp; 0x7F// bottom 7 bits are 20xx year (00-99)
month = (code &gt;&gt; 7) &amp; 0x0F// middle 4 bits are month (1-12)
day = (code &gt;&gt; 11) &amp; 0x1F// top 5 bits are day of month (1-31)
return year, month, day©Adafruit Industries

Page 24 of 46

0x03 - OPTIONS
Byte 0

Byte 1

Byte 2Byte 3

Options MSB

Options

Options

Options LSB

Options is a 32 bit field register indicating if a specific option (ADC, PWM, etc.) has
been enabled or not within the firmware. If enabled, the bit reads a 1, otherwise 0.
Bit locations for options are defined below:#define SEESAW_STATUS_BASE 0x00
#define SEESAW_GPIO_BASE 0x01
#define SEESAW_SERCOM0_BASE 0x02
#define SEESAW_SERCOM1_BASE 0x03
#define SEESAW_SERCOM2_BASE 0x04
#define SEESAW_SERCOM3_BASE 0x05
#define SEESAW_SERCOM4_BASE 0x06
#define SEESAW_SERCOM5_BASE 0x07
#define SEESAW_TIMER_BASE 0x08
#define SEESAW_ADC_BASE 0x09
#define SEESAW_DAC_BASE 0x0A
#define SEESAW_INTERRUPT_BASE 0x0B
#define SEESAW_DAP_BASE 0x0C
#define SEESAW_EEPROM_BASE 0x0D
#define SEESAW_NEOPIXEL_BASE 0x0E
#define SEESAW_TOUCH_BASE 0x0F
#define SEESAW_KEYPAD_BASE 0x10
#define SEESAW_ENCODER_BASE 0x11

0x04 - TEMP
Byte 0

Byte 1

Byte 2Byte 3Temperature MSB

Temperature

Temperature

Temperature LSB

The on board Temperature of the device, as a signed 32 bit integer.

0x7F - SWRST
Writing to the register address will initiate a software reset.

©Adafruit Industries

Page 25 of 46

GPIO
The GPIO module provides every day input and outputs. You'll get logic GPIO pinsthat can act as outputs or inputs. With pullups or pulldowns. When inputs, you canalso create pin-change interrupts that are routed the the IRQ pin.
On SAMD09-based boards the GPIO is 3V only. On ATtiny-based boards, the GPIO
logic is whatever the power pin is, 3V or 5V.
The module base register address for the GPIO module is 0x01.

Function Registers
Register
Address

Function
Name

Register
Size

Notes

0x02

DIRSET

32 bits

Write Only

0x03

DIRCLR

32 bits

Write Only

0x04

GPIO

32 bits

Read/Write

0x05

SET

32 bits

Write Only

0x06

CLR

32 bits

Write Only

0x07

TOGGLE

32 bits

Write Only

0x08

INTENSET

32 bits

Write Only

0x09

INTENCLR

32 bits

Write Only

©Adafruit Industries

Page 26 of 46

0x0A

INTFLAG

32 bits

Read Only

0x0B

PULLENSET

32 bits

Write Only

0x0C

PULLENCLR

32 bits

Write Only

Writes of GPIO function registers should contain 4 data bytes (32 bits) following theinitial register data bytes. Each bit in these registers represents a GPIO pin on PORTA
of the seesaw device.
If the corresponding pin does not exist on the SeeSaw device, then reading or writing
the bit has no effect.
We decided to go with this method to make GPIO toggling fast (rather than having
one i2c transaction per individual pin control) but the host processor will need to do alittle work to keep the pins identified.

GPIO register setup on SAMD09:
Bit 31

Bit 30

Bit 29Bit 28Bit 27

. . .

Bit 4

Bit 3

Bit 2

Bit 1

PA31

PA30

PA29

PA28

PA27

. . .

PA04

PA03

PA02

PA01

GPIO register setup on ATTiny8x7:(this is the same as the megaTinyCore pin mapping (https://adafru.it/YEh))• Bit 0: PA4• Bit 1: PA5• Bit 2: PA6• Bit 3: PA7• Bit 4: PB7• Bit 5: PB6• Bit 6: PB5• Bit 7: PB4©Adafruit Industries

Page 27 of 46

• Bit 8: PB3• Bit 9: PB2• Bit 10: PB1• Bit 11: PB0• Bit 12: PC0• Bit 13: PC1• Bit 14: PC2• Bit 15: PC3• Bit 16: PC4• Bit 17: PC5• Bit 18: PA1• Bit 19: PA2• Bit 20: PA3

DIRSET (0x02, 32 bits, Write Only)
Writing a 1 to any bit in this register sets the direction of the corresponding pin to
OUTPUT.
Writing zeros to this register has no effect.

DIRCLR (0x03, 32 bits, Write Only)
Writing a 1 to any bit in this register sets the direction of the corresponding pin to
INPUT.
Writing zeros to this register has no effect.

GPIO (0x04, 32 bits, Read/Write)
When this register is written, all bits that are set to 0 will have their corresponding
pins set LOW.
All bits that are set to 1 will have their corresponding pins set HIGH.
Reading this register reads all pins on of the seesaw device. On the Attiny series
please wait at least 250uS between command write and data read to allow the data
to be read and formatted for retrieval. Reading this register will also reset the IRQ pin
if it was configured.
©Adafruit Industries

Page 28 of 46

SET (0x05, 32 bits, Write Only)
Writing a 1 to any bit in this register writes the corresponding pin HIGH.
Writing zeros to this register has no effect.

CLR (0x06, 32 bits, Write Only)
Writing a 1 to any bit in this register writes the corresponding pin LOW.
Writing zeros to this register has no effect.

TOGGLE (0x07, 32 bits, Write Only)
Writing a 1 to any bit in this register toggles the corresponding pin.
Writing zeros to this register has no effect.

INTENSET (0x08, 32 bits, Write Only)
Writing a 1 to any bit in this register enables the interrupt on the corresponding pin.
When the value on this pin changes, the corresponding bit will be set in the INTFLAG
register.
Writing zeros to this register has no effect.

INTENCLR (0x09, 32 bits, Write Only)
Writing a 1 to any bit in this register disables the interrupt on the corresponding pin.
Writing zeros to this register has no effect.

©Adafruit Industries

Page 29 of 46

INTFLAG (0x0A, 32 bits, Read Only)
This register hold the status of all GPIO interrupts. When an interrupt fires, thecorresponding bit in this register gets set. Reading this register clears all interrupts.
This will also reset the IRQ pin if it was configured.
Writing to this register has no effect.

PULLENSET (0x0B, 32 bits, Write Only)
Writing a 1 to any bit in this register enables the internal pullup or pulldown on thecorresponding pin. The pull direction (up/down) is determined by the GPIO (output)
value - if the corresponding GPIO register bit is low, its a pulldown. High, its a pullup.
Writing zeros to this register has no effect.

PULLENCLR (0x0C, 32 bits, Write Only)
Writing a 1 to any bit in this register disables the pull up/down on the correspondingpin.
Writing zeros to this register has no effect.

UART
Note that the default firmware on the SAMD09 breakout does not include UART
support.
When the UART module is configured, the seesaw can act as an I2C UART bridge.
UART Pins are:
RX: PA11
TX: PA10
The module base register address for the UART is 0x02.

©Adafruit Industries

Page 30 of 46

The I2C <-> UART bridge is still in beta at the time of writing this guide. Detailed
specs are not yet available.

Function Registers
Register Address

Register Name

Regsiter Size

Notes

0x00

STATUS

8 bitsRead Only

0x02

INTEN

8 bitsRead/Write

0x03

INTENCLR

8 bitsWrite Only

0x04

BAUD

32 bits

Read/Write

0x05

DATA

32 bytes

Read/Write

Status (0x00, 8bits, Read Only)
bits 7-2

bit 1

bit 0

Reserved

DATA_RDY

ERROR

The ERROR bit is set when the UART encounters an error.
The DATA_RDY bit is set when there is data available in the RX buffer. This bit getscleared when the data is read.

©Adafruit Industries

Page 31 of 46

INTEN (0x2, 8bits, Read/Write)

bits 7-1

bit 0

Reserved

DATA_RDY

If the DATA_RDY bit is set, the interrupt will fire when there is data in the RX buffer.
Writing zeros to this register has no effect.

INTENCLR (0x03, 8bits, Write Only)same bits as INTEN. Writing 1 to any bit in this register disabled the corresponding
interrupt.
Writing zeros to this register has no effect.

BAUD (0x04, 32bits, Read/Write)
Writing to this register sets the BAUD rate.
Default 9600

DATA (0x05, 32bytes, Read/Write )Writing to the DATA register puts the data into the TX buffer to be output on the TX
pin.
Reading from the DATA register reads the data from the RX buffer.
When this register is read, the DATA_RDY bit is cleared.

©Adafruit Industries

Page 32 of 46

PWM
Base Register Address

0x08This module provides support for Pulse Width Modulation (PWM) output.

Nomenclature
The seesaw PWM Function Registers are defined using a generic nomenclature as
follows:• PWM Number - Specifies a specific PWM output (pin).
• PWM Value - Specifies the PWM duty cycle.
• PWM Frequency - Specifies the PWM frequency.
See the Port Specific Details section below for further information.

Function Register Summary
Register Address

Register Name

Register Size

Access0x01

PWM_VAL

3 bytesW

0x02

PWM_FREQ

3 bytesW

Function Register Description
0x01 - PWM_VAL
Byte 0©Adafruit Industries

Byte 1

Byte 2

Page 33 of 46

PWM Number

PWM Value MSB

PWM Value LSB

Sets the PWM Value for a specified PWM Number. The first byte written is the PWM
Number. The next two bytes are the 16 bit PWM Value, most significant byte (MSB)
followed by least significant byte (LSB).

0x02 - PWM_FREQ
Byte 0PWM Number

Byte 1

Byte 2PWM Frequency MSB

PWM Frequency LSB

Sets the PWM Frequency for a specified PWM Number. The first byte written is the
PWM Number. The next two bytes are the 16 bit PWM Frequency, most significant
byte (MSB) followed by least significant byte (LSB).

Port Specific Details
SAMD
PWM outputs are available on pins PA04, PA05, PA06, and PA07. The PWM Number
for each is shown in the table below.
PWM Number

Output Pin

0

PA04

1

PA05

2

PA06

©Adafruit Industries

Page 34 of 46

3

PA07

The full 16 bit PWM Value is used. This value should be an unsigned integer ranging
from 0 for full off to 65535 for full on.
The PWM Frequency is a 16 bit unsigned integer value which specifies the frequency
in hertz (Hz).

ATtinyThe PWM Number is the Arduino GPIO pin number.
Currently, only the MSB of the 16 bit PWM Value is used. This is due to the 8 bit limitof analogWrite() used internally. However, a full 16 bit value should be sent from 0 for
full off to 65535 for full on.
The PWM Frequency is a 16 bit unsigned integer value which specifies the frequency
in hertz (Hz). (NOTE: uses tone() internally)

Analog to Digital Converter
The ADC provides the ability to measure analog voltages at 10-bit resolution. The
SAMD09 seesaw has 4 ADC inputs, the Attiny8x7 has 11 ADC inputs.
The module base register address for the ADC is 0x09
Conversions can be read by reading the corresponding CHANNEL register.
When reading ADC data, there should be at least a 500 uS delay between writing theregister number you would like to read from and attempting to read the data.
Allow a delay of at least 1ms in between sequential ADC reads on different channels.

SAMD09 ADC channels are:
Channel 0©Adafruit Industries

PA02

Page 35 of 46

Channel 1

PA03

Channel 2

PA04

Channel 3

PA05

ATtiny8x7 ADC channels are:• Channel 0: PA4• Channel 1: PA5• Channel 2: PA6• Channel 3: PA7• Channel 6: PB5• Channel 7: PB4• Channel 10: PB1• Channel 11: PB0• Channel 18: PA1• Channel 19: PA2• Channel 20: PA3(These are the same as the Arduino GPIO pin names for the ADCs in
megaTinyCore (https://adafru.it/YEh))

Function Registers
Register Address

Register Name

Register Size

Notes

0x00

STATUS

8 bitsRead Only

0x02

INTENSET

8 bitsWrite Only

0x03

INTENCLR

8 bitsWrite Only

©Adafruit Industries

Page 36 of 46

0x04

WINMODE

0x05

WINTHRESH

32 bits

Write Only

0x07

CHANNEL_0

16 bits

Read Only

0x08

CHANNEL_1

16 bits

Read Only

0x09

CHANNEL_2

16 bits

Read Only

0x0A

CHANNEL_3

16 bits

Read Only

...

...

...

...

CHANNEL_20

16-bitRead Only

0x1B

Write Only

Window mode or ADC interrupts is not yet supported as of the time of writing thisguide.

STATUS (0x00, 8bits, Read Only)
This register contains status information on the ADC
Bit 7

Bit 6

Bit 5

Bit 4

Bit 3

Bit 2

Bit 1

Bit 0

Reserved Reserved Reserved Reserved Reserved Reserved WINMON_INT ERROR©Adafruit Industries

Page 37 of 46

INTENSET (0x02, 8bits, Write Only)
Writing a 1 to any bit in this register enables the corresponding interrupt.
Writing zeros to this register has no effect.
Bit 7

Bit 6

Bit 5

Bit 4

Bit 3

Bit 2

Bit 1

Bit 0

Reserved Reserved Reserved Reserved Reserved Reserved Reserved WINMON

INTENCLR (0x03, 8bits, Write Only)
Writing a 1 to any bit in this register enables the corresponding interrupt.
Writing zeros to this register has no effect.

WINMODE (0x04, 8bits, Write Only)
Writing 1 to this register sets window control.

WINTHRESH (0x05, 32bits, Write Only)
This register sets the threshold values for window mode.
Bits 31 - 16

Bits 15 - 0

High Threshold

Low Threshold©Adafruit Industries

Page 38 of 46

CHANNEL_0 (0x07, 16bits, Read Only)
ADC value for channel 0

CHANNEL_1 (0x08, 16bits, Read Only)
ADC value for channel 1

CHANNEL_2 (0x09, 16bits, Read Only)
ADC value for channel 2

CHANNEL_3 (0x0A, 16bits, Read Only)
ADC value for channel 3...

CHANNEL_20 (0x1B, 16bits, Read Only)
ADC value for channel 20

Interrupts
The seesaw has a configurable interrupt pin that can be triggered through various
channels.
Once the interrupt is triggered, it can be only be cleared when the conditions of it'ssource module(s) have been met (e.g. data has been read, an interrupt has beencleared by reading an INTFLAG register).
See individual module sections for details on their available interrupt configurations.
The hardware interrupt pin is available on PA08 (#8)

©Adafruit Industries

Page 39 of 46

EEPROM
The EEPROM module provides persistent storage of data across reboots.
On the SAMD09, there are 64 bytes of emulated EEPROM available for use. Byte 63(0x3F) can be written to change the devices default I2C address.
On the ATtiny817, there are 128 bytes of actual EEPROM available for use. Byte 127(0x7F) can be written to change the device's default I2C address.
The module base register address for the EEPROM module is 0x0D
The SAMD09 does not have true EEPROM, but flash memory on the seesaw that
performs the same function. Performing a chip erase will erase all data stored in
the emulated EEPROM. Also, be aware that the emulated EEPROM has a limited
write/erase cycle lifespan. Care should be taken to not write/erase too manytimes or you will get inconsistant results and possibly damage the FLASH! The
FLASH is rated for 100,000 cycles

Function Registers
SAMD09Register Address

Function Name

Register Size

Notes

0x00 - 0x3E

General Purpose EEPROM

8 bits each

Read/Write

0x3F

I2C Address

8 bitsRead/Write

Function Name

Register Size

Notes

ATtiny817
Register Address©Adafruit Industries

Page 40 of 46

0x00 - 0x7E

General purpose EEPROM

8 bits each

Read/write

0x7F

I2C Address

8 bitsRead/write

NeoPixel
The seesaw has built in NeoPixel support for up to 170 RGB or 127 RGBW pixels. The
output pin as well as the communication protocol frequency are configurable. Note:older firmware is limited to 63 pixels max.
The module base register address for the NeoPixel module is 0x0E.

Function Registers
Register Address

Register Name

Register Size

Notes

0x01

PIN

8 bitsWrite Only

0x02

SPEED

8 bitsWrite Only

0x03

BUF_LENGTH

16 bits

Write Only

0x04

BUF

32 bytes

Write Only

0x05

SHOW

none

Write Only

PIN (0x01, 8bits, Write Only)
This register sets the pin number (PORTA) that is used for the NeoPixel output.

©Adafruit Industries

Page 41 of 46

SPEED (0x02, 8bits, Write Only)
The protocol speed.
0x00 = 400khz
0x01 = 800khz (default)

BUF_LENGTH (0x03, 16bits LE, Write Only)
the number of bytes currently used for the pixel array. This is dependent on when the
pixels you are using are RGB or RGBW. 2 Bytes, little endian order

BUF (0x04, 32 bytes, Write Only)
The data buffer. The first 2 bytes are the start address, and the data to write follows.
Data should be written in blocks of maximum size 30 bytes at a time.
Bytes 0 - 1

Bytes 2 - 32

Start address

DataSHOW (0x05, no args, Write Only)
Sending the SHOW command will cause the output to update. There's no arguments/
data after the command

Encoder
0x11

Base Register AddressThis module provides incremental encoder support.

©Adafruit Industries

Page 42 of 46

Function Register Summary
Register Address

Register Name

Register Size

Access0x00

Status?

?

0x10Interrupt Set

1 byteW

0x20

Interrupt Clear

1 byteW

0x30

Position

4 bytes

R/W

0x40

Delta

4 bytesR

More than one encoder can be supported. The upper 4 bits of the function register
address specifies the function (summarized in table above) while the lower 4 bits
indicates the encoder number, starting with 0 for the 1st encoder. For example, toread the position (0x30) of the 2nd encoder (0x01), the resulting function register
address would be 0x31 (0x30 | 0x01).

Function Register Description
0x00 - Status
Currently unused.

0x10 - Interrupt Set
Writing a 1 to any bit in this register will enable the interrupt for the specified encoder.
The interrupt will fire when the encoder changes position.

©Adafruit Industries

Page 43 of 46

0x20 - Interrupt Clear
Writing a 1 to any bit in this register will disable the interrupt for the specified encoder.

0x30 - Position
Byte 0

Byte 1

Position MSB

Byte 2...

Byte 4...

Position LSB

Reading this register returns the current encoder position. Writing to this register sets
the current position to the specified value. The position value is a signed 32 bit
integer.

0x40 - Delta
Byte 0

Delta MSB

Byte 1

Byte 2...

Byte 3...

Delta LSB

Reading this register returns the change (delta) in position, as a signed 32 bit integer
value, since the last read. The delta will also be reset to zero.

Downloads
Documents• Seesaw Arduino Driver (https://adafru.it/BrV)• Seesaw CircuitPython Driver (https://adafru.it/BrW)• Fritzing object in the Adafruit Fritzing library (https://adafru.it/aP3)• SAMD09 breakout PCB files (EAGLE format) (https://adafru.it/BrX)• SAMD09 datasheet (https://adafru.it/BrY)©Adafruit Industries

Page 44 of 46

Schematic
click to enlarge

Dimensions
in inches. Click to enlarge©Adafruit Industries

Page 45 of 46

Documentation• Python API Documentation (https://adafru.it/BrT)• Arduino API Documentation (https://adafru.it/CBQ)©Adafruit Industries

Page 46 of 46