kopia lustrzana https://github.com/pimoroni/pimoroni-pico
Badger2040: Refactor to fix MicroPython issues
Move busy wait logic into MicroPython bindings so that MICROPY_EVENT_POLL_HOOK can be called.pull/252/head
rodzic
5b084c1b9a
commit
af230b5fd5
|
@ -115,6 +115,8 @@ namespace pimoroni {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
});
|
||||
|
||||
busy_wait();
|
||||
}
|
||||
|
||||
void UC8151::fast_luts() {
|
||||
|
@ -122,7 +124,7 @@ namespace pimoroni {
|
|||
command(LUT_VCOM, {
|
||||
0x00, 0x04, 0x04, 0x07, 0x00, 0x01,
|
||||
0x00, 0x0c, 0x0c, 0x00, 0x00, 0x02,
|
||||
0x00, 0x04, 0x04, 0x07, 0x00, 0x01,
|
||||
0x00, 0x04, 0x04, 0x07, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -133,7 +135,7 @@ namespace pimoroni {
|
|||
command(LUT_WW, {
|
||||
0x54, 0x04, 0x04, 0x07, 0x00, 0x01,
|
||||
0x60, 0x0c, 0x0c, 0x00, 0x00, 0x02,
|
||||
0xa8, 0x04, 0x04, 0x07, 0x00, 0x01,
|
||||
0xa8, 0x04, 0x04, 0x07, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -143,7 +145,7 @@ namespace pimoroni {
|
|||
command(LUT_BW, {
|
||||
0x54, 0x04, 0x04, 0x07, 0x00, 0x01,
|
||||
0x60, 0x0c, 0x0c, 0x00, 0x00, 0x02,
|
||||
0xa8, 0x04, 0x04, 0x07, 0x00, 0x01,
|
||||
0xa8, 0x04, 0x04, 0x07, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -153,7 +155,7 @@ namespace pimoroni {
|
|||
command(LUT_WB, {
|
||||
0xa8, 0x04, 0x04, 0x07, 0x00, 0x01,
|
||||
0x60, 0x0c, 0x0c, 0x00, 0x00, 0x02,
|
||||
0x54, 0x04, 0x04, 0x07, 0x00, 0x01,
|
||||
0x54, 0x04, 0x04, 0x07, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -163,12 +165,78 @@ namespace pimoroni {
|
|||
command(LUT_BB, {
|
||||
0xa8, 0x04, 0x04, 0x07, 0x00, 0x01,
|
||||
0x60, 0x0c, 0x0c, 0x00, 0x00, 0x02,
|
||||
0x54, 0x04, 0x04, 0x07, 0x00, 0x01,
|
||||
0x54, 0x04, 0x04, 0x07, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
});
|
||||
|
||||
command(PLL, {
|
||||
HZ_200
|
||||
});
|
||||
|
||||
busy_wait();
|
||||
}
|
||||
|
||||
void UC8151::faster_luts() {
|
||||
// 0x3c, 0x00, 0x2b, 0x2b, 0x24, 0x1a, ????
|
||||
command(LUT_VCOM, {
|
||||
0x00, 0x01, 0x01, 0x02, 0x00, 0x01,
|
||||
0x00, 0x02, 0x02, 0x00, 0x00, 0x02,
|
||||
0x00, 0x02, 0x02, 0x03, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00
|
||||
});
|
||||
|
||||
command(LUT_WW, {
|
||||
0x54, 0x01, 0x01, 0x02, 0x00, 0x01,
|
||||
0x60, 0x02, 0x02, 0x00, 0x00, 0x02,
|
||||
0xa8, 0x02, 0x02, 0x03, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
});
|
||||
|
||||
command(LUT_BW, {
|
||||
0x54, 0x01, 0x01, 0x02, 0x00, 0x01,
|
||||
0x60, 0x02, 0x02, 0x00, 0x00, 0x02,
|
||||
0xa8, 0x02, 0x02, 0x03, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
});
|
||||
|
||||
command(LUT_WB, {
|
||||
0xa8, 0x01, 0x01, 0x02, 0x00, 0x01,
|
||||
0x60, 0x02, 0x02, 0x00, 0x00, 0x02,
|
||||
0x54, 0x02, 0x02, 0x03, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
});
|
||||
|
||||
command(LUT_BB, {
|
||||
0xa8, 0x01, 0x01, 0x02, 0x00, 0x01,
|
||||
0x60, 0x02, 0x02, 0x00, 0x00, 0x02,
|
||||
0x54, 0x02, 0x02, 0x03, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
});
|
||||
|
||||
command(PLL, {
|
||||
HZ_200
|
||||
});
|
||||
|
||||
busy_wait();
|
||||
}
|
||||
|
||||
void UC8151::init() {
|
||||
|
@ -193,13 +261,33 @@ namespace pimoroni {
|
|||
gpio_set_function(SCK, GPIO_FUNC_SPI);
|
||||
gpio_set_function(MOSI, GPIO_FUNC_SPI);
|
||||
|
||||
setup();
|
||||
};
|
||||
|
||||
void UC8151::setup(uint8_t speed) {
|
||||
reset();
|
||||
|
||||
command(PSR, {
|
||||
RES_128x296 | LUT_REG | FORMAT_BW | SHIFT_RIGHT | BOOSTER_ON | RESET_NONE
|
||||
});
|
||||
|
||||
default_luts();
|
||||
if(speed == 0) {
|
||||
command(PSR, {
|
||||
RES_128x296 | LUT_OTP | FORMAT_BW | SHIFT_RIGHT | BOOSTER_ON | RESET_NONE
|
||||
});
|
||||
} else {
|
||||
command(PSR, {
|
||||
RES_128x296 | LUT_REG | FORMAT_BW | SHIFT_RIGHT | BOOSTER_ON | RESET_NONE
|
||||
});
|
||||
}
|
||||
switch(speed) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
fast_luts();
|
||||
break;
|
||||
case 2:
|
||||
faster_luts();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
command(PWR, {
|
||||
VDS_INTERNAL | VDG_INTERNAL,
|
||||
|
@ -306,9 +394,16 @@ namespace pimoroni {
|
|||
*p |= b; // set bit value
|
||||
}
|
||||
|
||||
void UC8151::update_speed(uint8_t speed) {
|
||||
setup(speed);
|
||||
}
|
||||
|
||||
void UC8151::partial_update(int x, int y, int w, int h, bool blocking) {
|
||||
// y is given in columns ("banks"), which are groups of 8 horiontal pixels
|
||||
// x is given in pixels
|
||||
if(blocking) {
|
||||
busy_wait();
|
||||
}
|
||||
|
||||
int cols = h / 8;
|
||||
int y1 = y / 8;
|
||||
|
@ -347,13 +442,17 @@ namespace pimoroni {
|
|||
|
||||
command(POF); // turn off
|
||||
}
|
||||
|
||||
command(PTOU); // disable partial mode
|
||||
}
|
||||
|
||||
void UC8151::update(bool blocking) {
|
||||
if(blocking) {
|
||||
busy_wait();
|
||||
}
|
||||
|
||||
command(PON); // turn on
|
||||
|
||||
command(PTOU); // disable partial mode
|
||||
|
||||
command(DTM2, (width * height) / 8, frame_buffer); // transmit framebuffer
|
||||
command(DSP); // data stop
|
||||
|
||||
|
|
|
@ -181,15 +181,19 @@ namespace pimoroni {
|
|||
void busy_wait();
|
||||
bool is_busy();
|
||||
void reset();
|
||||
void setup(uint8_t speed=0);
|
||||
|
||||
void default_luts();
|
||||
void fast_luts();
|
||||
void faster_luts();
|
||||
|
||||
void read(uint8_t reg, size_t len, uint8_t *data);
|
||||
void command(uint8_t reg, size_t len, const uint8_t *data);
|
||||
void command(uint8_t reg, std::initializer_list<uint8_t> values);
|
||||
void command(uint8_t reg) {command(reg, 0, nullptr);};
|
||||
void data(size_t len, const uint8_t *data);
|
||||
|
||||
void update_speed(uint8_t speed);
|
||||
void update(bool blocking = true);
|
||||
void partial_update(int x, int y, int w, int h, bool blocking = true);
|
||||
void off();
|
||||
|
|
|
@ -170,44 +170,20 @@ namespace pimoroni {
|
|||
_button_states |= gpio_get_all() & mask;
|
||||
}
|
||||
|
||||
void Badger2040::partial_update(int x, int y, int w, int h) {
|
||||
// wait for display to not be busy
|
||||
while(uc8151.is_busy()) {
|
||||
tight_loop_contents();
|
||||
}
|
||||
|
||||
uc8151.partial_update(x, y, w, h, true);
|
||||
|
||||
_button_states = 0;
|
||||
|
||||
// wait for display to not be busy but sample buttons in case they are
|
||||
// pressed during this time
|
||||
while(uc8151.is_busy()) {
|
||||
update_button_states();
|
||||
tight_loop_contents();
|
||||
}
|
||||
|
||||
uc8151.off();
|
||||
bool Badger2040::is_busy() {
|
||||
return uc8151.is_busy();
|
||||
}
|
||||
|
||||
void Badger2040::update() {
|
||||
// wait for display to not be busy
|
||||
while(uc8151.is_busy()) {
|
||||
tight_loop_contents();
|
||||
}
|
||||
void Badger2040::update_speed(uint8_t speed) {
|
||||
uc8151.update_speed(speed);
|
||||
}
|
||||
|
||||
uc8151.update(false);
|
||||
void Badger2040::partial_update(int x, int y, int w, int h, bool blocking) {
|
||||
uc8151.partial_update(x, y, w, h, blocking);
|
||||
}
|
||||
|
||||
_button_states = 0;
|
||||
|
||||
// wait for display to not be busy but sample buttons in case they are
|
||||
// pressed during this time
|
||||
while(uc8151.is_busy()) {
|
||||
update_button_states();
|
||||
tight_loop_contents();
|
||||
}
|
||||
|
||||
uc8151.off();
|
||||
void Badger2040::update(bool blocking) {
|
||||
uc8151.update(blocking);
|
||||
}
|
||||
|
||||
const hershey_font_glyph_t* Badger2040::glyph_data(unsigned char c) {
|
||||
|
|
|
@ -27,10 +27,12 @@ namespace pimoroni {
|
|||
: uc8151(296, 128, framebuffer, spi0, CS, DC, CLK, MOSI, BUSY, RESET) {
|
||||
};
|
||||
void init();
|
||||
void update();
|
||||
void partial_update(int x, int y, int w, int h);
|
||||
void update(bool blocking=false);
|
||||
void partial_update(int x, int y, int w, int h, bool blocking=false);
|
||||
void update_speed(uint8_t speed);
|
||||
void halt();
|
||||
void sleep();
|
||||
bool is_busy();
|
||||
|
||||
// state
|
||||
void led(uint8_t brightness);
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
import badger2040
|
||||
import machine
|
||||
import time
|
||||
|
||||
display = badger2040.Badger2040()
|
||||
display.update_speed(badger2040.UPDATE_TURBO)
|
||||
display.pen(15)
|
||||
display.clear()
|
||||
display.update()
|
||||
|
||||
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)
|
||||
|
||||
message = None
|
||||
message_y = 60
|
||||
|
||||
|
||||
def button(pin):
|
||||
global message
|
||||
if message is not None:
|
||||
return
|
||||
if pin == button_a:
|
||||
message = "Button A"
|
||||
return
|
||||
if pin == button_b:
|
||||
message = "Button B"
|
||||
return
|
||||
if pin == button_c:
|
||||
message = "Button C"
|
||||
return
|
||||
if pin == button_up:
|
||||
message = "Button U"
|
||||
return
|
||||
if pin == button_down:
|
||||
message = "Button D"
|
||||
return
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
while True:
|
||||
if message is not None:
|
||||
display.pen(15)
|
||||
display.clear()
|
||||
display.pen(0)
|
||||
display.thickness(4)
|
||||
display.text(message, 10, message_y, 2.0)
|
||||
for _ in range(2):
|
||||
display.update()
|
||||
message = None
|
||||
time.sleep(0.1)
|
|
@ -4,6 +4,8 @@
|
|||
/***** Methods *****/
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(Badger2040___del___obj, Badger2040___del__);
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(Badger2040_update_speed_obj, Badger2040_update_speed);
|
||||
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);
|
||||
|
||||
|
@ -13,7 +15,6 @@ MP_DEFINE_CONST_FUN_OBJ_2(Badger2040_pen_obj, Badger2040_pen);
|
|||
MP_DEFINE_CONST_FUN_OBJ_2(Badger2040_thickness_obj, Badger2040_thickness);
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(Badger2040_pressed_obj, Badger2040_pressed);
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(Badger2040_clear_obj, Badger2040_clear);
|
||||
MP_DEFINE_CONST_FUN_OBJ_3(Badger2040_pixel_obj, Badger2040_pixel);
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(Badger2040_line_obj, 4, Badger2040_line);
|
||||
|
@ -27,6 +28,8 @@ MP_DEFINE_CONST_FUN_OBJ_3(Badger2040_command_obj, Badger2040_command);
|
|||
/***** 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) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_is_busy), MP_ROM_PTR(&Badger2040_is_busy_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_update_speed), MP_ROM_PTR(&Badger2040_update_speed_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) },
|
||||
|
||||
|
@ -65,6 +68,10 @@ STATIC const mp_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_UPDATE_NORMAL), MP_ROM_INT(0) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_UPDATE_FAST), MP_ROM_INT(1) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_UPDATE_TURBO), MP_ROM_INT(2) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_BUTTON_A), MP_ROM_INT(12) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_BUTTON_B), MP_ROM_INT(13) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_BUTTON_C), MP_ROM_INT(14) },
|
||||
|
|
|
@ -94,10 +94,33 @@ mp_obj_t Badger2040_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
|
|||
return MP_OBJ_FROM_PTR(badger2040_obj);
|
||||
}
|
||||
|
||||
mp_obj_t Badger2040_is_busy(mp_obj_t self_in) {
|
||||
_Badger2040_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Badger2040_obj_t);
|
||||
return self->badger2040->is_busy() ? mp_const_true : mp_const_false;
|
||||
}
|
||||
|
||||
mp_obj_t Badger2040_update_speed(mp_obj_t self_in, mp_obj_t speed) {
|
||||
_Badger2040_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Badger2040_obj_t);
|
||||
self->badger2040->update_speed(mp_obj_get_int(speed));
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t Badger2040_update(mp_obj_t self_in) {
|
||||
_Badger2040_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Badger2040_obj_t);
|
||||
|
||||
self->badger2040->update();
|
||||
while(self->badger2040->is_busy()) {
|
||||
#ifdef MICROPY_EVENT_POLL_HOOK
|
||||
MICROPY_EVENT_POLL_HOOK
|
||||
#endif
|
||||
}
|
||||
|
||||
self->badger2040->update(false);
|
||||
|
||||
while(self->badger2040->is_busy()) {
|
||||
#ifdef MICROPY_EVENT_POLL_HOOK
|
||||
MICROPY_EVENT_POLL_HOOK
|
||||
#endif
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
@ -122,8 +145,22 @@ mp_obj_t Badger2040_partial_update(size_t n_args, const mp_obj_t *pos_args, mp_m
|
|||
int h = args[ARG_h].u_int;
|
||||
|
||||
_Badger2040_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, _Badger2040_obj_t);
|
||||
|
||||
|
||||
while(self->badger2040->is_busy()) {
|
||||
#ifdef MICROPY_EVENT_POLL_HOOK
|
||||
MICROPY_EVENT_POLL_HOOK
|
||||
#endif
|
||||
}
|
||||
|
||||
self->badger2040->partial_update(x, y, w, h);
|
||||
|
||||
while(self->badger2040->is_busy()) {
|
||||
#ifdef MICROPY_EVENT_POLL_HOOK
|
||||
MICROPY_EVENT_POLL_HOOK
|
||||
#endif
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ extern void Badger2040_print(const mp_print_t *print, mp_obj_t self_in, mp_print
|
|||
extern mp_obj_t Badger2040___del__(mp_obj_t self_in);
|
||||
extern mp_obj_t Badger2040_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);
|
||||
|
||||
extern mp_obj_t Badger2040_is_busy(mp_obj_t self_in);
|
||||
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);
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue