diff --git a/bootloader b/bootloader index 85a9b76..89ba9a8 160000 --- a/bootloader +++ b/bootloader @@ -1 +1 @@ -Subproject commit 85a9b76d8451eba2e2c9e5d9b3b1b8450178105f +Subproject commit 89ba9a874fa052ae7b0df8a9b6a6f8916309cd29 diff --git a/micropython b/micropython index 89f48ac..c7cf47a 160000 --- a/micropython +++ b/micropython @@ -1 +1 @@ -Subproject commit 89f48aca20920073d0c88782df0a8881651a5b28 +Subproject commit c7cf47a3681ab1625b52b7b8663bfa95dd5d9096 diff --git a/reloader b/reloader index 2888b28..b4512e5 160000 --- a/reloader +++ b/reloader @@ -1 +1 @@ -Subproject commit 2888b288763a1a612b9d9aa2554b5d2901c2be12 +Subproject commit b4512e5d92d062a65a216d68bffcdc03ff1625cf diff --git a/res/p8dfu.png b/res/p8dfu.png index a5dcfd0..c997190 100644 Binary files a/res/p8dfu.png and b/res/p8dfu.png differ diff --git a/wasp/boards/p8/manifest.py b/wasp/boards/p8/manifest.py new file mode 100644 index 0000000..3a525e1 --- /dev/null +++ b/wasp/boards/p8/manifest.py @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +# Copyright (C) 2020 Daniel Thompson + +freeze('.', 'watch.py', opt=3) +freeze('../..', + ( + 'apps/clock.py', + 'apps/flashlight.py', + 'apps/heart.py', + 'apps/launcher.py', + 'apps/pager.py', + 'apps/settings.py', + 'apps/steps.py', + 'apps/stopwatch.py', + 'apps/testapp.py', + 'boot.py', + 'draw565.py', + 'drivers/bma421.py', + 'drivers/battery.py', + 'drivers/cst816s.py', + 'drivers/hrs3300.py', + 'drivers/nrf_rtc.py', + 'drivers/signal.py', + 'drivers/st7789.py', + 'drivers/vibrator.py', + 'fonts/__init__.py', + 'fonts/clock.py', + 'fonts/sans24.py', + 'fonts/sans28.py', + 'fonts/sans36.py', + 'gadgetbridge.py', + 'icons.py', + 'ppg.py', + 'shell.py', + 'wasp.py', + 'widgets.py', + ), + opt=3 +) +freeze('../../drivers/flash', + ( + 'bdevice.py', + 'flash/flash_spi.py' + ), opt=3 +) diff --git a/wasp/boards/p8/watch.py.in b/wasp/boards/p8/watch.py.in new file mode 100644 index 0000000..1e52ccb --- /dev/null +++ b/wasp/boards/p8/watch.py.in @@ -0,0 +1,132 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +# Copyright (C) 2020 Daniel Thompson + +def nop(): + pass +schedule = nop +def _callback(obj): + schedule() + +# Start measuring time (and feeding the watchdog) before *anything* else +from machine import RTCounter +from drivers.nrf_rtc import RTC +rtc = RTC(RTCounter(1, mode=RTCounter.PERIODIC, period=1, callback=_callback)) +rtc.counter.start() + +import os +import time + +import draw565 + +from machine import I2C +from machine import Pin +#from machine import Signal +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 +from flash.flash_spi import FLASH + +from ubluepy import uart_connected as connected + +class Backlight(object): + lo = Pin("BL_LO", Pin.OUT, value=0) + mid = Pin("BL_MID", Pin.OUT, value=1) + hi = Pin("BL_HI", Pin.OUT, value=1) + + def __init__(self, level=1): + self.set(level) + + def set(self, level): + hi = 1 + mid = 1 + lo = 1 + + if level >= 3: + hi = 0 + elif level == 2: + mid = 0 + elif level == 1: + lo = 0 + + self.hi(hi) + self.mid(mid) + self.lo(lo) + +# Setup the display (and manage the backlight) +backlight = Backlight(0) +spi = SPI(0) +spi.init(polarity=1, phase=1, baudrate=8000000) +display = ST7789_SPI(240, 240, spi, + cs=Pin("DISP_CS", Pin.OUT), + dc=Pin("DISP_DC", Pin.OUT), + res=Pin("DISP_RST", Pin.OUT)) +drawable = draw565.Draw565(display) + +def boot_msg(s): + drawable.string(s, 0, 108, width=240) + if safe_mode: + time.sleep_ms(500) + +safe_mode = False +boot_msg("Init button") +button = Pin('BUTTON', Pin.IN) +safe_mode = button.value() +if safe_mode: + backlight.set(1) + time.sleep(1) + +try: + # Setup the last few bits and pieces + boot_msg("Init hardware") + usb_pwr = Signal(Pin('USB_PWR', Pin.IN), invert=True) + battery = Battery(Pin('BATTERY', Pin.IN), usb_pwr, usb_pwr) + 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), + _callback) + vibrator = Vibrator(Pin('MOTOR', Pin.OUT, value=0), active_low=True) + + # Release flash from deep power-down + boot_msg("Wake SPINOR") + nor_cs = Pin('NOR_CS', Pin.OUT, value=1) + nor_cs(0) + spi.write('\xAB') + nor_cs(1) + + # Mount the filesystem + boot_msg("Init SPINOR") + flash = FLASH(spi, (nor_cs,)) + try: + boot_msg("Mount FS") + os.mount(flash, '/flash') + except AttributeError: + # Format the filesystem (and provide a default version of main.py) + boot_msg("Format FS") + os.VfsLfs2.mkfs(flash) + boot_msg("Retry mount FS") + os.mount(flash,'/flash') + boot_msg("Write main.py") + with open('/flash/main.py', 'w') as f: + f.write('''\ +#include('main.py') +''') + + # Only change directory if the button is not pressed (this will + # allow us access to fix any problems with main.py)! + if not safe_mode: + boot_msg("Enter /flash") + os.chdir('/flash') + boot_msg("Run main.py") + else: + boot_msg("Safe mode") +except: + drawable.string("FAILED", 0, 136, width=240) + backlight.set(1)