From d3d98c8ffb1feded5b77c34f67aa1f2b4ae19a2e Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Wed, 29 Jan 2020 17:30:57 +0000 Subject: [PATCH] wasp: Re-enable REPL by default The demo is still there but it needs to be activated by hand (or the manifest can be updated to include main.py by default. --- README.md | 58 ++++++++++++++++++++++++++++++-------------- TODO.md | 2 +- manifest/pinetime.py | 2 +- micropython | 2 +- wasp/boot.py | 6 +++++ wasp/demo.py | 8 ++---- wasp/pinetime.py | 52 +++++++++++++++++++++++++++++---------- 7 files changed, 90 insertions(+), 40 deletions(-) create mode 100644 wasp/boot.py diff --git a/README.md b/README.md index 4c0be7a..dcdec06 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,55 @@ Watch Application System in Python ================================== -Despite the grand ambitions of the name, currently this repo simply -combines a bootloader, derived from the Adafruit NRF52 bootloader, with -MicroPython. Both have been ported to Pine64 PineTime and the Desay -DS-D6 fitness band. +Currently WASP is primarily useful as a pre-packaged MicroPython +development environment for PineTime. Whilst there are plans to grow +it into a smart watch runtime for Pine64 PineTime and the Desay +DS-D6 fitness tracker this goal has yet to be achieved. -Try: +WASP includes a robust bootloader based on the Adafruit NRF52 +Bootloader. It has been extended to make it robust for development on +form-factor devices without a reset button, power switch, SWD debugger +or UART. This allows us to confidently develop on sealed devices relying +only on BLE for updates. + +Building from a git clone +------------------------- ~~~ make submodules make softdevice -make -j `nproc` all -make flash +make -j `nproc` BOARD=pinetime all ~~~ -Then use nRFConnect (for Android) to program micropython.zip. +Installing +---------- -At the end of this process your watch may *look* dead but, if it works, -you will be able to use the Nordic UART Service to access the -MicroPython REPL. +Note: *If you have a new PineTime then it will have been delivered with +flash protection enabled. You must disable the flash protection before +trying to program it.* -Drivers are, for the most part, an exercise for the reader but -there is a proof-of-concept display driver. To experiment try: +* Use an SWD programmer to install `bootloader.hex` to the PineTime. + This file is an Intel HEX file containing both the bootloader and + the Nordic SoftDevice. Be careful to disconnect cleanly from the + debug software since just pulling out the SWD cable will mean the + nRF52 will still believe it is being debugged. +* Copy `micropython.zip` to your Android device and download nRF Connect + for Android if you do not already have it. +* In nRF Connect, choose settings and reduce the DFU packet count from + 10 to 4. +* Connect to PineDFU using nRFConnect, click the DFU button and send + `micropython.zip` to the device. + +At the end of this process your watch you will see a couple of splash +screens (bootloader shows a small Pine64 logo, MicroPython shows are +larger one). Once the second splash screen appears you will be able to +use the Nordic UART Service to access the MicroPython REPL. + +Drivers are still in development, see the [TODO list](todo.md) for +current status. In the mean time try the following and then take +a look at the `wasp/` directory to see how it works: ~~~ -import pinetime, time -tft = pinetime.st7789() -tft.white() -time.sleep(2) -tft.black() +import demo +demo.run() ~~~ diff --git a/TODO.md b/TODO.md index a94ea66..9def553 100644 --- a/TODO.md +++ b/TODO.md @@ -34,7 +34,7 @@ The TODO list helps keep track on progress towards that goal. It is not - [ ] Bitmap blitting - [X] RLE coder and decoder - [ ] Optimized RLE inner loops - * [ ] Backlight driver + * [X] Backlight driver * [ ] Button driver (interrupt based) * [ ] Battery/charger driver * [ ] Simple clock and battery level application diff --git a/manifest/pinetime.py b/manifest/pinetime.py index 3bb1290..f622878 100644 --- a/manifest/pinetime.py +++ b/manifest/pinetime.py @@ -1,6 +1,6 @@ freeze('$(MPY_DIR)/../wasp', ( - 'main.py', + 'boot.py', 'demo.py', 'drivers/st7789.py', 'logo.py', diff --git a/micropython b/micropython index b6f0dee..e668ed3 160000 --- a/micropython +++ b/micropython @@ -1 +1 @@ -Subproject commit b6f0dee43e4c51afad6a0b1badd534df7a4494ad +Subproject commit e668ed3ed3778bf5aea08e766cc8d82eb0a4c247 diff --git a/wasp/boot.py b/wasp/boot.py new file mode 100644 index 0000000..79601e7 --- /dev/null +++ b/wasp/boot.py @@ -0,0 +1,6 @@ +import logo +import pinetime + +pinetime.display.rleblit(logo.pine64, fg=0xffff) + + diff --git a/wasp/demo.py b/wasp/demo.py index 1470ff5..b74d3e6 100644 --- a/wasp/demo.py +++ b/wasp/demo.py @@ -24,10 +24,6 @@ colors = ( 0xf81f, # magenta ) -# Let's keep this where we can find it if someone delivers ^C to the -# demo -tft = pinetime.st7789() - def run(): l = logo.pine64 i = 0 @@ -42,8 +38,8 @@ def run(): l = logo.micropython else: l = logo.pine64 - tft.fill(0) + pinetime.display.fill(0) - tft.rleblit(l, fg=c) + pinetime.display.rleblit(l, fg=c) time.sleep(2) gc.collect() diff --git a/wasp/pinetime.py b/wasp/pinetime.py index cdbb230..1a771aa 100644 --- a/wasp/pinetime.py +++ b/wasp/pinetime.py @@ -3,18 +3,44 @@ from machine import SPI from drivers.st7789 import ST7789_SPI -def st7789(): - spi = SPI(0) - # Mode 3, maximum clock speed! - spi.init(polarity=1, phase=1, baudrate=8000000) +class Display(ST7789_SPI): + def __init__(self): + spi = SPI(0) + # Mode 3, maximum clock speed! + spi.init(polarity=1, phase=1, baudrate=8000000) - # Configure the display - cs = Pin("SPI_SS2", Pin.OUT) - dc = Pin("P18", Pin.OUT) - rst = Pin("P26", Pin.OUT) - tft = ST7789_SPI(240, 240, spi, cs=cs, dc=dc, res=rst) + # Configure the display + cs = Pin("DISP_CS", Pin.OUT) + dc = Pin("DISP_DC", Pin.OUT) + rst = Pin("DISP_RST", Pin.OUT) - # Bring up the backlight - bl = Pin("P22", Pin.OUT) - bl.off() # active low - return tft + super().__init__(240, 240, spi, cs=cs, dc=dc, res=rst) + +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) + +backlight = Backlight(0) +display = Display() + +backlight.set(1)