|
| 1 | +# SPDX-FileCopyrightText: 2019 Limor Fried for Adafruit Industries |
| 2 | +# |
| 3 | +# SPDX-License-Identifier: MIT |
| 4 | + |
| 5 | +# Adafruit Seesaw / CRICKIT driver for MicroPython |
| 6 | +# MIT License by Adafruit Industries Limor Fried |
| 7 | +# Copy onto the micro:bit with main.py using Mu Files icon |
| 8 | +from microbit import i2c |
| 9 | +import struct |
| 10 | +import time |
| 11 | + |
| 12 | +_SIGNALS = (2, 3, 40, 41, 11, 10, 9, 8) |
| 13 | +_PWMS = (14, 15, 16, 17, 19, 18, 22, 23, 42, 43, 12, 13) |
| 14 | +_SERVOS = (17, 16, 15, 14) |
| 15 | +_MOTORS = (22, 23, 19, 18) |
| 16 | +_DRIVES = (13, 12, 43, 42) |
| 17 | +_TOUCHES = (0, 1, 2, 3) |
| 18 | +_ADDR = 0x49 |
| 19 | + |
| 20 | +reg_buf = bytearray(2) |
| 21 | +pwm_buf = bytearray(3) |
| 22 | + |
| 23 | +def _read(reghi, reglo, n, delay_s=0.01): |
| 24 | + reg_buf[0] = reghi |
| 25 | + reg_buf[1] = reglo |
| 26 | + i2c.write(_ADDR, reg_buf) |
| 27 | + time.sleep(delay_s) |
| 28 | + return i2c.read(_ADDR, n) |
| 29 | + |
| 30 | +def _write(reghi, reglo, cmd): |
| 31 | + reg_buf[0] = reghi |
| 32 | + reg_buf[1] = reglo |
| 33 | + #print("sswrite: ", [hex(i) for i in reg_buf+cmd]) |
| 34 | + i2c.write(_ADDR, reg_buf+cmd) |
| 35 | + |
| 36 | +# t is between 1 and 4 |
| 37 | +def read_touch(t): |
| 38 | + return struct.unpack(">H", _read(0x0F, 0x10+_TOUCHES[t-1], 2))[0] |
| 39 | + |
| 40 | +def pwm_write(pwm, val): |
| 41 | + pwm_buf[0] = _PWMS.index(pwm) |
| 42 | + pwm_buf[1] = val >> 8 |
| 43 | + pwm_buf[2] = val & 0xFF |
| 44 | + _write(0x08, 0x01, pwm_buf) |
| 45 | + |
| 46 | +def set_pwmfreq(pwm, freq): |
| 47 | + pwm_buf[0] = _PWMS.index(pwm) |
| 48 | + pwm_buf[1] = freq >> 8 |
| 49 | + pwm_buf[2] = freq & 0xFF |
| 50 | + _write(0x08, 0x02, pwm_buf) |
| 51 | + |
| 52 | +# signal is between 1 and 8 |
| 53 | +def analog_read(signal): |
| 54 | + return struct.unpack(">H", _read(0x09, 0x07+signal-1, 2))[0] |
| 55 | + |
| 56 | +def pin_config(pin, mode, pull=None, val=None): |
| 57 | + if pin >= 32: |
| 58 | + cmd = struct.pack(">I", 1 << (pin - 32)) |
| 59 | + cmd = bytearray(4) + cmd |
| 60 | + else: |
| 61 | + cmd = struct.pack(">I", 1 << pin) |
| 62 | + if 0 <= mode <= 1: |
| 63 | + _write(0x01, 0x03-mode, cmd) |
| 64 | + if pull is not None and 0 <= pull <= 1: |
| 65 | + _write(0x01, 0x0C-pull, cmd) |
| 66 | + if val is not None and 0 <= val <= 1: |
| 67 | + _write(0x01, 0x06-val, cmd) |
| 68 | + |
| 69 | + |
| 70 | +def init(): |
| 71 | + i2c.init() |
| 72 | + while not _ADDR in i2c.scan(): |
| 73 | + print("Crickit not found!") |
| 74 | + time.sleep(1) |
| 75 | + reg_buf[0] = 0x7F |
| 76 | + reg_buf[1] = 0xFF |
| 77 | + i2c.write(_ADDR, reg_buf) |
| 78 | + |
| 79 | +# s is between 1 and 4 |
| 80 | +def servo(s, degree, min=1.0, max=2.0): |
| 81 | + set_pwmfreq(_SERVOS[s-1], 50) |
| 82 | + val = 3276*min + (max-min)*3276*degree/180 |
| 83 | + pwm_write(_SERVOS[s-1], int(val)) |
| 84 | + |
| 85 | +# d is between 1 and 4 |
| 86 | +def drive(d, frac, freq=1000): |
| 87 | + set_pwmfreq(_DRIVES[d-1], freq) |
| 88 | + pwm_write(_DRIVES[d-1], int(frac*65535)) |
| 89 | + |
| 90 | +# m is 1 or 2 |
| 91 | +def motor(m, frac, freq=1000): |
| 92 | + m -= 1 # start with 1 |
| 93 | + pin1,pin2 = _MOTORS[m*2:m*2+2] |
| 94 | + set_pwmfreq(pin1, freq) |
| 95 | + set_pwmfreq(pin2, freq) |
| 96 | + if frac < 0: |
| 97 | + pin1, pin2 = pin2, pin1 |
| 98 | + pwm_write(pin1, 0) |
| 99 | + pwm_write(pin2, abs(int(frac*65535))) |
| 100 | + |
| 101 | +# signal is between 1 and 8, val is 0 or 1 |
| 102 | +def write_digital(signal, val): |
| 103 | + pin_config(_SIGNALS[signal-1], 1, 0, val) # output, pullup, value |
| 104 | + |
| 105 | +# signal is between 1 and 8 |
| 106 | +def read_digital(signal): |
| 107 | + pin = _SIGNALS[signal-1] |
| 108 | + pin_config(pin, 0, 1, 1) # input, pullup, pullvalue |
| 109 | + ret = _read(0x01, 0x04, 8) |
| 110 | + b = 0 |
| 111 | + if pin > 32: |
| 112 | + b = 4 |
| 113 | + pin -= 32 |
| 114 | + b += 3 - (pin // 8) |
| 115 | + return (ret[b] & 1<<(pin % 8)) != 0 |
0 commit comments