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,63 +205,34 @@ detail2_title = truncatestring(detail2_title, DETAILS_TEXT_SIZE, TEXT_WIDTH)
|
|||
detail2_text = truncatestring(detail2_text, DETAILS_TEXT_SIZE,
|
||||
TEXT_WIDTH - DETAIL_SPACING - display.measure_text(detail2_title, DETAILS_TEXT_SIZE))
|
||||
|
||||
# Set up the buttons
|
||||
button_a = machine.Pin(badger2040.BUTTON_A, machine.Pin.IN, machine.Pin.PULL_DOWN)
|
||||
button_b = machine.Pin(badger2040.BUTTON_B, machine.Pin.IN, machine.Pin.PULL_DOWN)
|
||||
button_c = machine.Pin(badger2040.BUTTON_C, machine.Pin.IN, machine.Pin.PULL_DOWN)
|
||||
button_up = machine.Pin(badger2040.BUTTON_UP, machine.Pin.IN, machine.Pin.PULL_DOWN)
|
||||
button_down = machine.Pin(badger2040.BUTTON_DOWN, machine.Pin.IN, machine.Pin.PULL_DOWN)
|
||||
|
||||
|
||||
# Button handling function
|
||||
def button(pin):
|
||||
global show_overlay
|
||||
|
||||
if pin == button_a:
|
||||
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)
|
||||
|
||||
# Show overlay if any of the buttons were pressed to wake up the Badger
|
||||
if (badger2040.pressed_to_wake(badger2040.BUTTON_A) or
|
||||
badger2040.pressed_to_wake(badger2040.BUTTON_B) or
|
||||
badger2040.pressed_to_wake(badger2040.BUTTON_C) or
|
||||
badger2040.pressed_to_wake(badger2040.BUTTON_UP) or
|
||||
badger2040.pressed_to_wake(badger2040.BUTTON_DOWN)):
|
||||
show_overlay = True
|
||||
|
||||
# ------------------------------
|
||||
# Main program loop
|
||||
# Main program
|
||||
# ------------------------------
|
||||
|
||||
draw_badge()
|
||||
display.update()
|
||||
|
||||
while True:
|
||||
if show_overlay:
|
||||
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)
|
||||
display.update()
|
||||
time.sleep(4)
|
||||
if show_overlay:
|
||||
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)
|
||||
display.update()
|
||||
time.sleep(4)
|
||||
|
||||
draw_badge()
|
||||
display.update()
|
||||
show_overlay = False
|
||||
draw_badge()
|
||||
display.update()
|
||||
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
|
||||
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
|
||||
font_size = 1
|
||||
|
@ -179,19 +212,9 @@ def render():
|
|||
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):
|
||||
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:
|
||||
launch(examples[(page * 3) + index][0])
|
||||
return True
|
||||
|
@ -241,7 +264,7 @@ display.update_speed(badger2040.UPDATE_FAST)
|
|||
|
||||
# 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():
|
||||
pass
|
||||
time.sleep(0.01)
|
||||
|
||||
|
||||
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_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_led_obj, Badger2040_led);
|
||||
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_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 *****/
|
||||
STATIC const mp_rom_map_elem_t Badger2040_locals_dict_table[] = {
|
||||
{ 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_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_led), MP_ROM_PTR(&Badger2040_led_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 *****/
|
||||
|
||||
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_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_MEDIUM), MP_ROM_INT(1) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_UPDATE_FAST), MP_ROM_INT(2) },
|
||||
|
@ -121,4 +131,4 @@ const mp_obj_module_t badger2040_user_cmodule = {
|
|||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&mp_module_badger2040_globals,
|
||||
};
|
||||
MP_REGISTER_MODULE(MP_QSTR_badger2040, badger2040_user_cmodule, MODULE_BADGER2040_ENABLED);
|
||||
MP_REGISTER_MODULE(MP_QSTR_badger2040, badger2040_user_cmodule, MODULE_BADGER2040_ENABLED);
|
||||
|
|
|
@ -3,6 +3,19 @@
|
|||
|
||||
#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" {
|
||||
#include "badger2040.h"
|
||||
|
@ -170,7 +183,11 @@ MICROPY_EVENT_POLL_HOOK
|
|||
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
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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_to_wake
|
||||
// wait_for_press - implement in terms of MicroPython!
|
||||
|
@ -467,4 +494,4 @@ mp_obj_t Badger2040_measure_glyph(size_t n_args, const mp_obj_t *pos_args, mp_ma
|
|||
return mp_obj_new_int(self->badger2040->measure_glyph(c, scale));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_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_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);
|
||||
|
@ -37,4 +39,7 @@ extern mp_obj_t Badger2040_glyph(size_t n_args, const mp_obj_t *pos_args, mp_map
|
|||
extern mp_obj_t Badger2040_measure_text(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