Add ability to halt the Badger from Micropython and get wake button presses. Change badge app to halt when image displayed
This commit is contained in:
parent
fa2774b114
commit
51b0e472e1
|
@ -205,56 +205,21 @@ detail2_title = truncatestring(detail2_title, DETAILS_TEXT_SIZE, TEXT_WIDTH)
|
||||||
detail2_text = truncatestring(detail2_text, DETAILS_TEXT_SIZE,
|
detail2_text = truncatestring(detail2_text, DETAILS_TEXT_SIZE,
|
||||||
TEXT_WIDTH - DETAIL_SPACING - display.measure_text(detail2_title, DETAILS_TEXT_SIZE))
|
TEXT_WIDTH - DETAIL_SPACING - display.measure_text(detail2_title, DETAILS_TEXT_SIZE))
|
||||||
|
|
||||||
# Set up the buttons
|
# Show overlay if any of the buttons were pressed to wake up the Badger
|
||||||
button_a = machine.Pin(badger2040.BUTTON_A, machine.Pin.IN, machine.Pin.PULL_DOWN)
|
if (badger2040.pressed_to_wake(badger2040.BUTTON_A) or
|
||||||
button_b = machine.Pin(badger2040.BUTTON_B, machine.Pin.IN, machine.Pin.PULL_DOWN)
|
badger2040.pressed_to_wake(badger2040.BUTTON_B) or
|
||||||
button_c = machine.Pin(badger2040.BUTTON_C, machine.Pin.IN, machine.Pin.PULL_DOWN)
|
badger2040.pressed_to_wake(badger2040.BUTTON_C) or
|
||||||
button_up = machine.Pin(badger2040.BUTTON_UP, machine.Pin.IN, machine.Pin.PULL_DOWN)
|
badger2040.pressed_to_wake(badger2040.BUTTON_UP) or
|
||||||
button_down = machine.Pin(badger2040.BUTTON_DOWN, machine.Pin.IN, machine.Pin.PULL_DOWN)
|
badger2040.pressed_to_wake(badger2040.BUTTON_DOWN)):
|
||||||
|
|
||||||
|
|
||||||
# Button handling function
|
|
||||||
def button(pin):
|
|
||||||
global show_overlay
|
|
||||||
|
|
||||||
if pin == button_a:
|
|
||||||
show_overlay = True
|
show_overlay = True
|
||||||
return
|
|
||||||
|
|
||||||
if pin == button_b:
|
|
||||||
show_overlay = True
|
|
||||||
return
|
|
||||||
|
|
||||||
if pin == button_c:
|
|
||||||
show_overlay = True
|
|
||||||
return
|
|
||||||
|
|
||||||
if pin == button_up:
|
|
||||||
show_overlay = True
|
|
||||||
return
|
|
||||||
|
|
||||||
if pin == button_down:
|
|
||||||
show_overlay = True
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
# Register the button handling function with the buttons
|
|
||||||
button_a.irq(trigger=machine.Pin.IRQ_RISING, handler=button)
|
|
||||||
button_b.irq(trigger=machine.Pin.IRQ_RISING, handler=button)
|
|
||||||
button_c.irq(trigger=machine.Pin.IRQ_RISING, handler=button)
|
|
||||||
button_up.irq(trigger=machine.Pin.IRQ_RISING, handler=button)
|
|
||||||
button_down.irq(trigger=machine.Pin.IRQ_RISING, handler=button)
|
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
# Main program loop
|
# Main program
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
|
|
||||||
draw_badge()
|
draw_badge()
|
||||||
display.update()
|
|
||||||
|
|
||||||
while True:
|
if show_overlay:
|
||||||
if show_overlay:
|
|
||||||
draw_overlay("To change the text, connect Badger2040 to a PC, load up Thonny, and modify badge.txt",
|
draw_overlay("To change the text, connect Badger2040 to a PC, load up Thonny, and modify badge.txt",
|
||||||
WIDTH - OVERLAY_BORDER, HEIGHT - OVERLAY_BORDER, OVERLAY_SPACING, OVERLAY_TEXT_SIZE)
|
WIDTH - OVERLAY_BORDER, HEIGHT - OVERLAY_BORDER, OVERLAY_SPACING, OVERLAY_TEXT_SIZE)
|
||||||
display.update()
|
display.update()
|
||||||
|
@ -262,6 +227,12 @@ while True:
|
||||||
|
|
||||||
draw_badge()
|
draw_badge()
|
||||||
display.update()
|
display.update()
|
||||||
show_overlay = False
|
else:
|
||||||
|
display.update()
|
||||||
|
|
||||||
time.sleep(0.1)
|
# Tell launcher to relaunch this app on wake
|
||||||
|
with open("appstate.txt", "w") as f:
|
||||||
|
f.write("badge\n")
|
||||||
|
|
||||||
|
# Halt the Badger to save power, it will wake up if any of the front buttons are pressed
|
||||||
|
display.halt()
|
||||||
|
|
|
@ -11,6 +11,39 @@ import launchericons
|
||||||
MAX_BATTERY_VOLTAGE = 4.0
|
MAX_BATTERY_VOLTAGE = 4.0
|
||||||
MIN_BATTERY_VOLTAGE = 3.2
|
MIN_BATTERY_VOLTAGE = 3.2
|
||||||
|
|
||||||
|
# Reduce clock speed to 48MHz, that's fast enough!
|
||||||
|
machine.freq(48000000)
|
||||||
|
|
||||||
|
def launch(file):
|
||||||
|
for k in locals().keys():
|
||||||
|
if k not in ("gc", "file", "machine"):
|
||||||
|
del locals()[k]
|
||||||
|
gc.collect()
|
||||||
|
try:
|
||||||
|
__import__(file[1:]) # Try to import _[file] (drop underscore prefix)
|
||||||
|
except ImportError:
|
||||||
|
__import__(file) # Failover to importing [_file]
|
||||||
|
machine.reset() # Exit back to launcher
|
||||||
|
|
||||||
|
# Restore previously running app
|
||||||
|
try:
|
||||||
|
# Pressing A and C together at start quits app
|
||||||
|
if badger2040.pressed_to_wake(badger2040.BUTTON_A) and badger2040.pressed_to_wake(badger2040.BUTTON_C):
|
||||||
|
os.remove("appstate.txt")
|
||||||
|
else:
|
||||||
|
with open("appstate.txt", "r") as f:
|
||||||
|
# Try to launch app
|
||||||
|
launch("_" + f.readline().strip('\n'))
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
except ImportError:
|
||||||
|
# Happens if appstate names an unknown app. Delete appstate and reset
|
||||||
|
import os
|
||||||
|
os.remove("appstate.txt")
|
||||||
|
machine.reset()
|
||||||
|
|
||||||
|
badger2040.clear_pressed_to_wake()
|
||||||
|
|
||||||
|
|
||||||
page = 0
|
page = 0
|
||||||
font_size = 1
|
font_size = 1
|
||||||
|
@ -179,19 +212,9 @@ def render():
|
||||||
display.update()
|
display.update()
|
||||||
|
|
||||||
|
|
||||||
def launch(file):
|
|
||||||
for k in locals().keys():
|
|
||||||
if k not in ("gc", "file", "machine"):
|
|
||||||
del locals()[k]
|
|
||||||
gc.collect()
|
|
||||||
try:
|
|
||||||
__import__(file[1:]) # Try to import _[file] (drop underscore prefix)
|
|
||||||
except ImportError:
|
|
||||||
__import__(file) # Failover to importing [_file]
|
|
||||||
machine.reset() # Exit back to launcher
|
|
||||||
|
|
||||||
|
|
||||||
def launch_example(index):
|
def launch_example(index):
|
||||||
|
while button_a.value() or button_b.value() or button_c.value() or button_up.value() or button_down.value():
|
||||||
|
time.sleep(0.01)
|
||||||
try:
|
try:
|
||||||
launch(examples[(page * 3) + index][0])
|
launch(examples[(page * 3) + index][0])
|
||||||
return True
|
return True
|
||||||
|
@ -241,7 +264,7 @@ display.update_speed(badger2040.UPDATE_FAST)
|
||||||
|
|
||||||
# Wait for wakeup button to be released
|
# Wait for wakeup button to be released
|
||||||
while button_a.value() or button_b.value() or button_c.value() or button_up.value() or button_down.value():
|
while button_a.value() or button_b.value() or button_c.value() or button_up.value() or button_down.value():
|
||||||
pass
|
time.sleep(0.01)
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
|
@ -9,6 +9,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(Badger2040_is_busy_obj, Badger2040_is_busy);
|
||||||
MP_DEFINE_CONST_FUN_OBJ_1(Badger2040_update_obj, Badger2040_update);
|
MP_DEFINE_CONST_FUN_OBJ_1(Badger2040_update_obj, Badger2040_update);
|
||||||
MP_DEFINE_CONST_FUN_OBJ_KW(Badger2040_partial_update_obj, 4, Badger2040_partial_update);
|
MP_DEFINE_CONST_FUN_OBJ_KW(Badger2040_partial_update_obj, 4, Badger2040_partial_update);
|
||||||
|
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(Badger2040_halt_obj, Badger2040_halt);
|
||||||
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_2(Badger2040_invert_obj, Badger2040_invert);
|
MP_DEFINE_CONST_FUN_OBJ_2(Badger2040_invert_obj, Badger2040_invert);
|
||||||
MP_DEFINE_CONST_FUN_OBJ_2(Badger2040_led_obj, Badger2040_led);
|
MP_DEFINE_CONST_FUN_OBJ_2(Badger2040_led_obj, Badger2040_led);
|
||||||
MP_DEFINE_CONST_FUN_OBJ_2(Badger2040_font_obj, Badger2040_font);
|
MP_DEFINE_CONST_FUN_OBJ_2(Badger2040_font_obj, Badger2040_font);
|
||||||
|
@ -32,6 +34,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(Badger2040_measure_glyph_obj, 2, Badger2040_measure_g
|
||||||
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_3(Badger2040_command_obj, Badger2040_command);
|
MP_DEFINE_CONST_FUN_OBJ_3(Badger2040_command_obj, Badger2040_command);
|
||||||
|
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(Badger2040_pressed_to_wake_obj, Badger2040_pressed_to_wake);
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_0(Badger2040_clear_pressed_to_wake_obj, Badger2040_clear_pressed_to_wake);
|
||||||
|
|
||||||
/***** Binding of Methods *****/
|
/***** Binding of Methods *****/
|
||||||
STATIC const mp_rom_map_elem_t Badger2040_locals_dict_table[] = {
|
STATIC const mp_rom_map_elem_t Badger2040_locals_dict_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&Badger2040___del___obj) },
|
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&Badger2040___del___obj) },
|
||||||
|
@ -40,6 +45,8 @@ STATIC const mp_rom_map_elem_t Badger2040_locals_dict_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&Badger2040_update_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&Badger2040_update_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_partial_update), MP_ROM_PTR(&Badger2040_partial_update_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_partial_update), MP_ROM_PTR(&Badger2040_partial_update_obj) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_halt), MP_ROM_PTR(&Badger2040_halt_obj) },
|
||||||
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_invert), MP_ROM_PTR(&Badger2040_invert_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_invert), MP_ROM_PTR(&Badger2040_invert_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_led), MP_ROM_PTR(&Badger2040_led_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_led), MP_ROM_PTR(&Badger2040_led_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_font), MP_ROM_PTR(&Badger2040_font_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_font), MP_ROM_PTR(&Badger2040_font_obj) },
|
||||||
|
@ -78,10 +85,13 @@ const mp_obj_type_t Badger2040_type = {
|
||||||
|
|
||||||
/***** Globals Table *****/
|
/***** Globals Table *****/
|
||||||
|
|
||||||
STATIC const mp_map_elem_t badger2040_globals_table[] = {
|
STATIC const mp_rom_map_elem_t badger2040_globals_table[] = {
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_badger2040) },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_badger2040) },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Badger2040), (mp_obj_t)&Badger2040_type },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_Badger2040), (mp_obj_t)&Badger2040_type },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_pressed_to_wake), MP_ROM_PTR(&Badger2040_pressed_to_wake_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_clear_pressed_to_wake), MP_ROM_PTR(&Badger2040_clear_pressed_to_wake_obj) },
|
||||||
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_UPDATE_NORMAL), MP_ROM_INT(0) },
|
{ MP_ROM_QSTR(MP_QSTR_UPDATE_NORMAL), MP_ROM_INT(0) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_UPDATE_MEDIUM), MP_ROM_INT(1) },
|
{ MP_ROM_QSTR(MP_QSTR_UPDATE_MEDIUM), MP_ROM_INT(1) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_UPDATE_FAST), MP_ROM_INT(2) },
|
{ MP_ROM_QSTR(MP_QSTR_UPDATE_FAST), MP_ROM_INT(2) },
|
||||||
|
|
|
@ -3,6 +3,19 @@
|
||||||
|
|
||||||
#define MP_OBJ_TO_PTR2(o, t) ((t *)(uintptr_t)(o))
|
#define MP_OBJ_TO_PTR2(o, t) ((t *)(uintptr_t)(o))
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct Badger2040_ButtonStateOnWake {
|
||||||
|
Badger2040_ButtonStateOnWake()
|
||||||
|
: state(gpio_get_all())
|
||||||
|
{}
|
||||||
|
|
||||||
|
uint32_t get() const { return state; }
|
||||||
|
void clear() { state = 0; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t state;
|
||||||
|
} button_wake_state __attribute__ ((init_priority (101)));
|
||||||
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "badger2040.h"
|
#include "badger2040.h"
|
||||||
|
@ -170,7 +183,11 @@ MICROPY_EVENT_POLL_HOOK
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
// halt
|
mp_obj_t Badger2040_halt(mp_obj_t self_in) {
|
||||||
|
_Badger2040_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Badger2040_obj_t);
|
||||||
|
self->badger2040->halt();
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
// sleep
|
// sleep
|
||||||
|
|
||||||
mp_obj_t Badger2040_invert(mp_obj_t self_in, mp_obj_t invert) {
|
mp_obj_t Badger2040_invert(mp_obj_t self_in, mp_obj_t invert) {
|
||||||
|
@ -210,6 +227,16 @@ mp_obj_t Badger2040_pressed(mp_obj_t self_in, mp_obj_t button) {
|
||||||
return state ? mp_const_true : mp_const_false;
|
return state ? mp_const_true : mp_const_false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mp_obj_t Badger2040_pressed_to_wake(mp_obj_t button) {
|
||||||
|
bool state = (button_wake_state.get() >> mp_obj_get_int(button)) & 1;
|
||||||
|
return state ? mp_const_true : mp_const_false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t Badger2040_clear_pressed_to_wake() {
|
||||||
|
button_wake_state.clear();
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
// pressed
|
// pressed
|
||||||
// pressed_to_wake
|
// pressed_to_wake
|
||||||
// wait_for_press - implement in terms of MicroPython!
|
// wait_for_press - implement in terms of MicroPython!
|
||||||
|
|
|
@ -15,6 +15,8 @@ extern mp_obj_t Badger2040_update_speed(mp_obj_t self_in, mp_obj_t speed);
|
||||||
extern mp_obj_t Badger2040_update(mp_obj_t self_in);
|
extern mp_obj_t Badger2040_update(mp_obj_t self_in);
|
||||||
extern mp_obj_t Badger2040_partial_update(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
extern mp_obj_t Badger2040_partial_update(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
||||||
|
|
||||||
|
extern mp_obj_t Badger2040_halt(mp_obj_t self_in);
|
||||||
|
|
||||||
extern mp_obj_t Badger2040_invert(mp_obj_t self_in, mp_obj_t invert);
|
extern mp_obj_t Badger2040_invert(mp_obj_t self_in, mp_obj_t invert);
|
||||||
extern mp_obj_t Badger2040_led(mp_obj_t self_in, mp_obj_t brightness);
|
extern mp_obj_t Badger2040_led(mp_obj_t self_in, mp_obj_t brightness);
|
||||||
extern mp_obj_t Badger2040_font(mp_obj_t self_in, mp_obj_t font);
|
extern mp_obj_t Badger2040_font(mp_obj_t self_in, mp_obj_t font);
|
||||||
|
@ -38,3 +40,6 @@ extern mp_obj_t Badger2040_measure_text(size_t n_args, const mp_obj_t *pos_args,
|
||||||
extern mp_obj_t Badger2040_measure_glyph(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
extern mp_obj_t Badger2040_measure_glyph(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
||||||
|
|
||||||
extern mp_obj_t Badger2040_command(mp_obj_t self_in, mp_obj_t reg, mp_obj_t data);
|
extern mp_obj_t Badger2040_command(mp_obj_t self_in, mp_obj_t reg, mp_obj_t data);
|
||||||
|
|
||||||
|
extern mp_obj_t Badger2040_pressed_to_wake(mp_obj_t button);
|
||||||
|
extern mp_obj_t Badger2040_clear_pressed_to_wake();
|
||||||
|
|
Loading…
Reference in New Issue