summaryrefslogtreecommitdiff
path: root/wasp
diff options
context:
space:
mode:
Diffstat (limited to 'wasp')
-rw-r--r--wasp/boards/pinetime/manifest.py1
-rw-r--r--wasp/boards/pinetime/watch.py.in4
-rw-r--r--wasp/drivers/hrs3300.py94
3 files changed, 98 insertions, 1 deletions
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)