Skip to content

Add ATtiny8x7 and examples #85

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Oct 11, 2021
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions adafruit_seesaw/attiny8x7.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# SPDX-FileCopyrightText: 2017 Dean Miller for Adafruit Industries
#
# SPDX-License-Identifier: MIT

# pylint: disable=missing-docstring,invalid-name,too-many-public-methods,too-few-public-methods

"""
`adafruit_seesaw.attiny8x7` - Pin definition for Adafruit ATtiny8x7 Breakout with seesaw
==================================================================================
"""

__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_seesaw.git"


class ATtiny8x7_Pinmap:
"""This class is automatically used by `adafruit_seesaw.seesaw.Seesaw` when
a ATtiny8x7 Breakout is detected.

It is also a reference for the capabilities of each pin."""

#: The pins capable of analog output
analog_pins = (0, 1, 2, 3, 6, 7, 18, 19, 20)

"""The effective bit resolution of the PWM pins"""
pwm_width = 16 # we dont actually use all 16 bits but whatever

"""The pins capable of PWM output"""
pwm_pins = (0, 1, 9, 12, 13)

"""No pins on this board are capable of touch input"""
touch_pins = ()
63 changes: 37 additions & 26 deletions adafruit_seesaw/seesaw.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ def const(x):

_TOUCH_CHANNEL_OFFSET = const(0x10)

_HW_ID_CODE = const(0x55)
_SAMD09_HW_ID_CODE = const(0x55)
_ATTINY8X7_HW_ID_CODE = const(0x87)
_EEPROM_I2C_ADDR = const(0x3F)

_ENCODER_STATUS = const(0x00)
Expand All @@ -126,33 +127,30 @@ class Seesaw:

:param ~busio.I2C i2c_bus: Bus the SeeSaw is connected to
:param int addr: I2C address of the SeeSaw device
:param ~digitalio.DigitalInOut drdy: Pin connected to SeeSaw's 'ready' output"""
:param ~digitalio.DigitalInOut drdy: Pin connected to SeeSaw's 'ready' output
:param bool reset: Whether to do a software reset on init"""

INPUT = const(0x00)
OUTPUT = const(0x01)
INPUT_PULLUP = const(0x02)
INPUT_PULLDOWN = const(0x03)

def __init__(self, i2c_bus, addr=0x49, drdy=None):
def __init__(self, i2c_bus, addr=0x49, drdy=None, reset=True):
self._drdy = drdy
if drdy is not None:
drdy.switch_to_input()

self.i2c_device = I2CDevice(i2c_bus, addr)
self.sw_reset()

def sw_reset(self):
"""Trigger a software reset of the SeeSaw chip"""
self.write8(_STATUS_BASE, _STATUS_SWRST, 0xFF)
time.sleep(0.500)
if reset:
self.sw_reset()

chip_id = self.read8(_STATUS_BASE, _STATUS_HW_ID)
self.chip_id = self.read8(_STATUS_BASE, _STATUS_HW_ID)

if chip_id != _HW_ID_CODE:
if self.chip_id not in (_ATTINY8X7_HW_ID_CODE, _SAMD09_HW_ID_CODE):
raise RuntimeError(
"Seesaw hardware ID returned (0x{:x}) is not "
"correct! Expected 0x{:x}. Please check your wiring.".format(
chip_id, _HW_ID_CODE
"correct! Expected 0x{:x} or 0x{:x}. Please check your wiring.".format(
self.chip_id, _SAMD09_HW_ID_CODE, _ATTINY8X7_HW_ID_CODE
)
)

Expand All @@ -166,12 +164,21 @@ def sw_reset(self):
from adafruit_seesaw.robohat import MM1_Pinmap

self.pin_mapping = MM1_Pinmap
else:
elif self.chip_id == _SAMD09_HW_ID_CODE:
from adafruit_seesaw.samd09 import SAMD09_Pinmap

self.pin_mapping = SAMD09_Pinmap
elif self.chip_id == _ATTINY8X7_HW_ID_CODE:
from adafruit_seesaw.attiny8x7 import ATtiny8x7_Pinmap

self.pin_mapping = ATtiny8x7_Pinmap
# pylint: enable=import-outside-toplevel

def sw_reset(self):
"""Trigger a software reset of the SeeSaw chip"""
self.write8(_STATUS_BASE, _STATUS_SWRST, 0xFF)
time.sleep(0.500)

def get_options(self):
"""Retrieve the 'options' word from the SeeSaw board"""
buf = bytearray(4)
Expand Down Expand Up @@ -241,9 +248,14 @@ def analog_read(self, pin):
if pin not in self.pin_mapping.analog_pins:
raise ValueError("Invalid ADC pin")

if self.chip_id == _ATTINY8X7_HW_ID_CODE:
offset = pin
elif self.chip_id == _SAMD09_HW_ID_CODE:
offset = self.pin_mapping.analog_pins.index(pin)

self.read(
_ADC_BASE,
_ADC_CHANNEL_OFFSET + self.pin_mapping.analog_pins.index(pin),
_ADC_CHANNEL_OFFSET + offset,
buf,
)
ret = struct.unpack(">H", buf)[0]
Expand Down Expand Up @@ -334,20 +346,19 @@ def digital_write_bulk_b(self, pins, value):

def analog_write(self, pin, value):
"""Set the value of an analog output by number"""
pin_found = False
if pin not in self.pin_mapping.pwm_pins:
raise ValueError("Invalid PWM pin")

if self.chip_id == _ATTINY8X7_HW_ID_CODE:
offset = pin
elif self.chip_id == _SAMD09_HW_ID_CODE:
offset = self.pin_mapping.pwm_pins.index(pin)

if self.pin_mapping.pwm_width == 16:
if pin in self.pin_mapping.pwm_pins:
pin_found = True
cmd = bytearray(
[self.pin_mapping.pwm_pins.index(pin), (value >> 8), value & 0xFF]
)
cmd = bytearray([offset, (value >> 8), value & 0xFF])
else:
if pin in self.pin_mapping.pwm_pins:
pin_found = True
cmd = bytearray([self.pin_mapping.pwm_pins.index(pin), value])
cmd = bytearray([offset, value])

if pin_found is False:
raise ValueError("Invalid PWM pin")
self.write(_TIMER_BASE, _TIMER_PWM, cmd)
time.sleep(0.001)

Expand Down
24 changes: 24 additions & 0 deletions examples/seesaw_analogin_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

# Simple seesaw test reading analog value
# on SAMD09, analog in can be pins 2, 3, or 4
# on Attiny8x7, analog in can be pins 0, 1, 2, 3, 6, 7, 18, 19, 20
#
# 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
from adafruit_seesaw.analoginput import AnalogInput

i2c_bus = board.I2C()
ss = Seesaw(i2c_bus)

analogin_pin = 2
analog_in = AnalogInput(ss, analogin_pin)

while True:
print(analog_in.value)
time.sleep(0.1)
31 changes: 31 additions & 0 deletions examples/seesaw_digitalio_test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

# Simple seesaw test using an LED attached to Pin 5 and a button on pin 2
#
# 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
import digitalio
from adafruit_seesaw.seesaw import Seesaw
from adafruit_seesaw.digitalio import DigitalIO

i2c_bus = board.I2C()
ss = Seesaw(i2c_bus)

button_pin = 2
led_pin = 5

button = DigitalIO(ss, button_pin)
button.direction = digitalio.Direction.INPUT
button.pull = digitalio.Pull.UP

led = DigitalIO(ss, led_pin)
led.direction = digitalio.Direction.OUTPUT

while True:
# simply set the LED to the same 'value' as the button pin
led.value = button.value
time.sleep(0.1)
29 changes: 29 additions & 0 deletions examples/seesaw_eeprom_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

# Simple seesaw test reading and writing the internal EEPROM
# The ATtiny8xx series has a true 128 byte EEPROM, the SAMD09 mimics it in flash with 64 bytes
# THE LAST BYTE IS USED FOR I2C ADDRESS CHANGE!
#
# 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 import seesaw

i2c_bus = board.I2C()
ss = seesaw.Seesaw(i2c_bus)

val = ss.eeprom_read8(0x02) # read from address 2
print("Read 0x%02x from EEPROM address 0x02" % val)

print("Incremening value")
ss.eeprom_write8(0x02, val + 1)

val = ss.eeprom_read8(0x02) # read from address 2
print("Second read 0x%02x from EEPROM address 0x02" % val)

while True:
# Do not write EEPROM in a loop, it has 100k cycle life
time.sleep(1)
32 changes: 32 additions & 0 deletions examples/seesaw_neopixel_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

# Simple seesaw test writing NeoPixels
# Can use any valid GPIO pin, up to 60 pixels!
#
# 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 rainbowio import colorwheel
from adafruit_seesaw import seesaw, neopixel

i2c_bus = board.I2C()
ss = seesaw.Seesaw(i2c_bus)

NEOPIXEL_PIN = 6 # change to any pin
NEOPIXEL_NUM = 30 # no more than 60!
pixels = neopixel.NeoPixel(ss, NEOPIXEL_PIN, NEOPIXEL_NUM)
pixels.brightness = 0.3 # not so brite!

color_offset = 0 # start at red

# cycle through all colors along the strip
while True:
for i in range(NEOPIXEL_NUM):
rc_index = (i * 256 // NEOPIXEL_NUM) + color_offset
pixels[i] = colorwheel(rc_index & 255)
pixels.show()
color_offset += 1
time.sleep(0.01)
25 changes: 25 additions & 0 deletions examples/seesaw_pwmout_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

# Simple seesaw test for writing PWM outputs
# On the SAMD09 breakout these are pins 5, 6, and 7
# On the ATtiny8x7 breakout these are pins 0, 1, 9, 12, 13
#
# 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 import seesaw, pwmout

i2c_bus = board.I2C()
ss = seesaw.Seesaw(i2c_bus)

PWM_PIN = 9 # change to a valid PWM output!
pwm = pwmout.PWMOut(ss, PWM_PIN)

while True:
# the API PWM range is 0 to 65535, but we increment by 256 since our
# resolution is often only 8 bits underneath
pwm.duty_cycle = (pwm.duty_cycle + 256) % 65536
time.sleep(0.01)