summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
m---------bootloader0
m---------reloader0
-rwxr-xr-xtools/hex2c.py13
-rw-r--r--wasp/apps/clock.py104
-rw-r--r--wasp/apps/fibonacci_clock.py79
-rw-r--r--wasp/apps/steps.py6
-rw-r--r--wasp/apps/stopwatch.py6
-rw-r--r--wasp/wasp.py2
9 files changed, 110 insertions, 102 deletions
diff --git a/Makefile b/Makefile
index 8cfbe62..470de25 100644
--- a/Makefile
+++ b/Makefile
@@ -46,7 +46,7 @@ bootloader: build-$(BOARD_SAFE)
reloader: bootloader build-$(BOARD_SAFE)
$(MAKE) -C reloader/ BOARD=$(BOARD)
- mv reloader/build-$(BOARD)/reloader.zip build-$(BOARD)/
+ cp reloader/build-$(BOARD)/reloader*.zip build-$(BOARD)
softdevice:
micropython/ports/nrf/drivers/bluetooth/download_ble_stack.sh
diff --git a/bootloader b/bootloader
-Subproject 477d2e07db0241d6d36ffa95740cb67eaa75a34
+Subproject 1d128f1311c084c23a662cb68263df9b187ebf9
diff --git a/reloader b/reloader
-Subproject 9f55c66be8f129fd00e3eda60988b4cbeffd884
+Subproject be876ac0bb44004885ba61b8cc1992826baa9a8
diff --git a/tools/hex2c.py b/tools/hex2c.py
index fa4762c..74f8431 100755
--- a/tools/hex2c.py
+++ b/tools/hex2c.py
@@ -20,7 +20,16 @@ def generate_c(ihex):
print('};')
print()
- for i, segment in enumerate(ihex.segments()):
+ segments = []
+ chunk = 32 * 1024
+ for (start, end) in ihex.segments():
+ while start + chunk < end:
+ segments.append((start, start + chunk))
+ start += chunk
+ if start < end:
+ segments.append((start, end))
+
+ for i, segment in enumerate(segments):
print(f'static const uint8_t segment{i}[] = {{', end='')
for j in range(segment[0], segment[1]):
@@ -30,7 +39,7 @@ def generate_c(ihex):
print('\n};\n')
print(f'const struct segment segments[] = {{')
- for i, segment in enumerate(ihex.segments()):
+ for i, segment in enumerate(segments):
sg = ihex.tobinarray(start=segment[0], end=segment[1]-1)
crc = binascii.crc32(sg)
print(f' 0x{segment[0]:08x}, 0x{segment[1]:08x}, 0x{crc:08x}, segment{i},')
diff --git a/wasp/apps/clock.py b/wasp/apps/clock.py
index 88ed2c7..106e712 100644
--- a/wasp/apps/clock.py
+++ b/wasp/apps/clock.py
@@ -13,16 +13,9 @@ import icons
import fonts.clock as digits
DIGITS = (
- digits.clock_0,
- digits.clock_1,
- digits.clock_2,
- digits.clock_3,
- digits.clock_4,
- digits.clock_5,
- digits.clock_6,
- digits.clock_7,
- digits.clock_8,
- digits.clock_9
+ digits.clock_0, digits.clock_1, digits.clock_2, digits.clock_3,
+ digits.clock_4, digits.clock_5, digits.clock_6, digits.clock_7,
+ digits.clock_8, digits.clock_9
)
MONTH = 'JanFebMarAprMayJunJulAugSepOctNovDec'
@@ -38,61 +31,76 @@ class ClockApp():
NAME = 'Clock'
ICON = icons.clock
- def __init__(self):
- self.meter = wasp.widgets.BatteryMeter()
- self.notifier = wasp.widgets.NotificationBar()
-
def foreground(self):
- """Activate the application."""
- self.on_screen = ( -1, -1, -1, -1, -1, -1 )
- self.draw()
+ """Activate the application.
+
+ Configure the status bar, redraw the display and request a periodic
+ tick callback every second.
+ """
+ wasp.system.bar.clock = False
+ self._draw(True)
wasp.system.request_tick(1000)
def sleep(self):
+ """Prepare to enter the low power mode.
+
+ :returns: True, which tells the system manager not to automatically
+ switch to the default application before sleeping.
+ """
return True
def wake(self):
- self.update()
+ """Return from low power mode.
- def tick(self, ticks):
- self.update()
-
- def draw(self):
- """Redraw the display from scratch."""
- draw = wasp.watch.drawable
+ Time will have changes whilst we have been asleep so we must
+ udpate the display (but there is no need for a full redraw because
+ the display RAM is preserved during a sleep.
+ """
+ self._draw()
- draw.fill()
- draw.rleblit(digits.clock_colon, pos=(2*48, 80), fg=0xb5b6)
- self.on_screen = ( -1, -1, -1, -1, -1, -1 )
- self.update()
- self.meter.draw()
+ def tick(self, ticks):
+ """Periodic callback to update the display."""
+ self._draw()
- def update(self):
- """Update the display (if needed).
+ def _draw(self, redraw=False):
+ """Draw or lazily update the display.
- The updates are a lazy as possible and rely on an prior call to
- draw() to ensure the screen is suitably prepared.
+ The updates are as lazy by default and avoid spending time redrawing
+ if the time on display has not changed. However if redraw is set to
+ True then a full redraw is be performed.
"""
- now = wasp.watch.rtc.get_localtime()
- if now[3] == self.on_screen[3] and now[4] == self.on_screen[4]:
- if now[5] != self.on_screen[5]:
- self.meter.update()
- self.notifier.update()
- self.on_screen = now
- return False
-
draw = wasp.watch.drawable
+
+ if redraw:
+ now = wasp.watch.rtc.get_localtime()
+
+ # Clear the display and draw that static parts of the watch face
+ draw.fill()
+ draw.rleblit(digits.clock_colon, pos=(2*48, 80), fg=0xb5b6)
+
+ # Redraw the status bar
+ wasp.system.bar.draw()
+ else:
+ # The update is doubly lazy... we update the status bar and if
+ # the status bus update reports a change in the time of day
+ # then we compare the minute on display to make sure we
+ # only update the main clock once per minute.
+ now = wasp.system.bar.update()
+ if not now or self._min == now[4]:
+ # Skip the update
+ return
+
+ # Format the month as text
+ month = now[1] - 1
+ month = MONTH[month*3:(month+1)*3]
+
+ # Draw the changeable parts of the watch face
draw.rleblit(DIGITS[now[4] % 10], pos=(4*48, 80))
draw.rleblit(DIGITS[now[4] // 10], pos=(3*48, 80), fg=0xbdb6)
draw.rleblit(DIGITS[now[3] % 10], pos=(1*48, 80))
draw.rleblit(DIGITS[now[3] // 10], pos=(0*48, 80), fg=0xbdb6)
- self.on_screen = now
-
- month = now[1] - 1
- month = MONTH[month*3:(month+1)*3]
draw.string('{} {} {}'.format(now[2], month, now[0]),
0, 180, width=240)
- self.meter.update()
- self.notifier.update()
- return True
+ # Record the minute that is currently being displayed
+ self._min = now[4]
diff --git a/wasp/apps/fibonacci_clock.py b/wasp/apps/fibonacci_clock.py
index de59bc3..3718cfc 100644
--- a/wasp/apps/fibonacci_clock.py
+++ b/wasp/apps/fibonacci_clock.py
@@ -1,6 +1,8 @@
# SPDX-License-Identifier: LGPL-3.0-or-later
# Copyright (C) 2020 Johannes Wache
+
"""Fibonacci clock
+~~~~~~~~~~~~~~~~~~
The Fibonacci sequence is a sequence of numbers created by the Italian
mathematician Fibonacci in the 13th century. This is a sequence starting with
@@ -22,6 +24,8 @@ result by 5 to get the actual number.
import wasp
import icons
+COLORS = [0xffff,0xf800,0x07e0,0x001f] # White, red, green and blue
+FIELDS = b'\x05\x03\x02\x01\x01'
MONTH = 'JanFebMarAprMayJunJulAugSepOctNovDec'
# 2-bit RLE, generated from res/fibo_icon.png, 246 bytes
@@ -48,54 +52,42 @@ icon = (
class FibonacciClockApp():
"""Displays the time as a Fibonacci Clock
+
+ .. figure:: res/FiboApp.png
+ :width: 179
+
+ Screenshot of the fibonacci clock application
"""
NAME = 'Fibo'
ICON = icon
- def __init__(self):
- self.meter = wasp.widgets.BatteryMeter()
- self.notifier = wasp.widgets.NotificationBar()
- self.fields = b'\x05\x03\x02\x01\x01'
- self.color_codes = [0xffff,0xf800,0x07e0,0x001f] # White, red, green and blue
-
def foreground(self):
"""Activate the application."""
- self.on_screen = ( -1, -1, -1, -1, -1, -1 )
- self.draw()
+ wasp.system.bar.clock = False
+ self._draw(True)
wasp.system.request_tick(1000)
def sleep(self):
return True
def wake(self):
- self.update()
+ self._draw()
def tick(self, ticks):
- self.update()
+ self._draw()
- def draw(self):
- """Redraw the display from scratch."""
+ def _draw(self, redraw=False):
+ """Draw or lazily update the display."""
draw = wasp.watch.drawable
- draw.fill()
- self.on_screen = ( -1, -1, -1, -1, -1, -1 )
- self.update()
- self.meter.draw()
-
- def update(self):
- """Update the display (if needed).
-
- The updates are a lazy as possible and rely on an prior call to
- draw() to ensure the screen is suitably prepared.
- """
- now = wasp.watch.rtc.get_localtime()
- if now[3] == self.on_screen[3] and now[4] == self.on_screen[4]:
- if now[5] != self.on_screen[5]:
- self.meter.update()
- self.notifier.update()
- self.on_screen = now
- return False
- draw = wasp.watch.drawable
+ if redraw:
+ now = wasp.watch.rtc.get_localtime()
+ draw.fill()
+ wasp.system.bar.draw()
+ else:
+ now = wasp.system.bar.update()
+ if not now or self._min == now[4]:
+ return
#calculate colors of fields:
field_colors = bytearray(5)
@@ -104,27 +96,24 @@ class FibonacciClockApp():
if (hr >= 12):
hr -= 12
for i in range(5):
- if ((hr - self.fields[i]) >= 0):
- hr -= self.fields[i]
+ if ((hr - FIELDS[i]) >= 0):
+ hr -= FIELDS[i]
field_colors[i] += 1
- if ((mn - self.fields[i]) >= 0):
- mn -= self.fields[i]
+ if ((mn - FIELDS[i]) >= 0):
+ mn -= FIELDS[i]
field_colors[i] += 2
- draw.fill(x=71,y=60,w=23,h=23,bg=self.color_codes[field_colors[4]]) # 1 field
- draw.fill(x=71,y=85,w=23,h=23,bg=self.color_codes[field_colors[3]]) # 1 field
- draw.fill(x=21,y=60,w=48,h=48,bg=self.color_codes[field_colors[2]]) # 2 field
- draw.fill(x=21,y=110,w=73,h=73,bg=self.color_codes[field_colors[1]]) # 3 field
- draw.fill(x=96,y=60,w=123,h=123,bg=self.color_codes[field_colors[0]]) # 5 field
-
- self.on_screen = now
+ draw.fill(x=71,y=60,w=23,h=23,bg=COLORS[field_colors[4]]) # 1 field
+ draw.fill(x=71,y=85,w=23,h=23,bg=COLORS[field_colors[3]]) # 1 field
+ draw.fill(x=21,y=60,w=48,h=48,bg=COLORS[field_colors[2]]) # 2 field
+ draw.fill(x=21,y=110,w=73,h=73,bg=COLORS[field_colors[1]]) # 3 field
+ draw.fill(x=96,y=60,w=123,h=123,bg=COLORS[field_colors[0]]) # 5 field
month = now[1] - 1
month = MONTH[month*3:(month+1)*3]
draw.string('{} {} {}'.format(now[2], month, now[0]),
0, 202, width=240)
- self.meter.update()
- self.notifier.update()
- return True
+ # Record the minute that is currently being displayed
+ self._min = now[4]
diff --git a/wasp/apps/steps.py b/wasp/apps/steps.py
index d7f16a3..cd888bd 100644
--- a/wasp/apps/steps.py
+++ b/wasp/apps/steps.py
@@ -42,12 +42,12 @@ class StepCounterApp():
def __init__(self):
watch.accel.reset()
- self._bar = wasp.widgets.StatusBar()
self._count = 0
self._prev_day = -1
def foreground(self):
"""Activate the application."""
+ wasp.system.bar.clock = True
self._draw()
wasp.system.request_tick(1000)
@@ -62,13 +62,13 @@ class StepCounterApp():
draw.blit(feet, 12, 132-24)
self._update()
- self._bar.draw()
+ wasp.system.bar.draw()
def _update(self):
draw = wasp.watch.drawable
# Update the status bar
- now = self._bar.update()
+ now = wasp.system.bar.update()
# Reset the step counter if we have move onto the next day
if now and now[2] != self._prev_day:
diff --git a/wasp/apps/stopwatch.py b/wasp/apps/stopwatch.py
index 807830c..43166a6 100644
--- a/wasp/apps/stopwatch.py
+++ b/wasp/apps/stopwatch.py
@@ -17,12 +17,12 @@ class StopwatchApp():
ICON = icons.app
def __init__(self):
- self._bar = wasp.widgets.StatusBar()
self._reset()
self._count = 0
def foreground(self):
"""Activate the application."""
+ wasp.system.bar.clock = True
self._draw()
wasp.system.request_tick(97)
wasp.system.request_event(wasp.EventMask.TOUCH |
@@ -111,7 +111,7 @@ class StopwatchApp():
self._last_count = -1
self._update()
- self._bar.draw()
+ wasp.system.bar.draw()
self._draw_splits()
def _update(self):
@@ -125,7 +125,7 @@ class StopwatchApp():
self._reset()
# Update the statusbar
- self._bar.update()
+ wasp.system.bar.update()
if self._last_count != self._count:
centisecs = self._count
diff --git a/wasp/wasp.py b/wasp/wasp.py
index 8f7e8a8..e2e728a 100644
--- a/wasp/wasp.py
+++ b/wasp/wasp.py
@@ -100,6 +100,8 @@ class Manager():
def __init__(self):
self.app = None
+ self.bar = widgets.StatusBar()
+
self.quick_ring = []
self.launcher = LauncherApp()
self.launcher_ring = []