diff --git a/wasp/boards/pinetime/manifest.py b/wasp/boards/pinetime/manifest.py index 073e1a0..59061b6 100644 --- a/wasp/boards/pinetime/manifest.py +++ b/wasp/boards/pinetime/manifest.py @@ -17,6 +17,7 @@ freeze('../..', 'drivers/bma421.py', 'drivers/battery.py', 'drivers/cst816s.py', + 'drivers/hrs3300.py', 'drivers/nrf_rtc.py', 'drivers/signal.py', 'drivers/st7789.py', diff --git a/wasp/boards/pinetime/watch.py.in b/wasp/boards/pinetime/watch.py.in index 058cdfd..d98c99d 100644 --- a/wasp/boards/pinetime/watch.py.in +++ b/wasp/boards/pinetime/watch.py.in @@ -20,6 +20,7 @@ from machine import SPI from drivers.battery import Battery from drivers.bma421 import BMA421 from drivers.cst816s import CST816S +from drivers.hrs3300 import HRS3300 from drivers.signal import Signal from drivers.st7789 import ST7789_SPI from drivers.vibrator import Vibrator @@ -81,6 +82,7 @@ try: Signal(Pin('USB_PWR', Pin.IN), invert=True)) i2c = I2C(1, scl='I2C_SCL', sda='I2C_SDA') accel = BMA421(i2c) + hrs = HRS3300(i2c) touch = CST816S(i2c, Pin('TP_INT', Pin.IN), Pin('TP_RST', Pin.OUT, value=0)) vibrator = Vibrator(Pin('MOTOR', Pin.OUT, value=0), active_low=True) @@ -93,7 +95,7 @@ try: # Mount the filesystem boot_msg("Init SPINOR") - flash = FLASH(spi, (Pin('NOR_CS', Pin.OUT, value=1),)) + flash = FLASH(spi, (nor_cs,)) try: boot_msg("Mount FS") os.mount(flash, '/flash') diff --git a/wasp/drivers/hrs3300.py b/wasp/drivers/hrs3300.py new file mode 100644 index 0000000..3843887 --- /dev/null +++ b/wasp/drivers/hrs3300.py @@ -0,0 +1,94 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +# Copyright (C) 2020 Daniel Thompson + +"""HRS3300 driver +~~~~~~~~~~~~~~~~~ + +""" + +from micropython import const + +_I2CADDR = const(0x44) + +_ID = const(0x00) +_ENABLE = const(0x01) +_ENABLE_HEN = const(0x80) +_C1DATAM = const(0x08) +_C0DATAM = const(0x09) +_C0DATAH = const(0x0a) +_PDRIVER = const(0x0c) +_C1DATAH = const(0x0d) +_C1DATAL = const(0x0e) +_C0DATAL = const(0x0f) +_RES = const(0x16) +_HGAIN = const(0x17) + +class HRS3300: + def __init__(self, i2c): + self._i2c = i2c + + w = self.write_reg + + # HRS disabled, 12.5 ms wait time between cycles, (partly) 20mA drive + w(_ENABLE, 0x60) + + # (partly) 20mA drive, power on, "magic" (datasheet says both + # "reserved" and "set low nibble to 8" but 0xe gives better results + # and is used by at least two other HRS3300 drivers + w(_PDRIVER, 0x6e) + + # HRS and ALS both in 16-bit mode + w(_RES, 0x88) + + # 64x gain + w(_HGAIN, 0x10) + + def read_reg(self, addr): + return self._i2c.readfrom_mem(_I2CADDR, addr, 1)[0] + + def write_reg(self, addr, val): + self._i2c.writeto_mem(_I2CADDR, addr, bytes((val,))) + + def enable(self): + enable = self.read_reg(_ENABLE) + enable |= _ENABLE_HEN + self.write_reg(_ENABLE, enable) + + def disable(self): + enable = self.read_reg(_ENABLE) + enable &= ~_ENABLE_HEN + self.write_reg(_ENABLE, enable) + + def read_hrs(self): + # TODO: Try fusing the read of H & L + m = self.read_reg(_C0DATAM) + h = self.read_reg(_C0DATAH) + l = self.read_reg(_C0DATAL) + + return (m << 8) | ((h & 0x0f) << 4) | (l & 0x0f) | ((l & 0x30) << 12) + + def read_als(self): + # TODO: Try fusing the read of H & L + m = self.read_reg(_C1DATAM) + h = self.read_reg(_C1DATAH) + l = self.read_reg(_C1DATAL) + + return (m << 3) | ((h & 0x3f) << 11) | (l & 0x07) + + def set_gain(self, gain): + if gain > 64: + gain = 64 + hgain = 0 + while (1 << hgain) < gain: + hgain += 1 + self.write_reg(_HGAIN, hgain << 2) + + def set_drive(self, drive): + en = self.read_reg(_ENABLE) + pd = self.read_reg(_PDRIVER) + + en = (en & 0xf7) | ((drive & 2) << 2) + pd = (pd & 0xbf) | ((drive & 1) << 6) + + self.write_reg(_ENABLE, en) + self.write_reg(_PDRIVER, pd)