diff --git a/nrf5/drivers/display/epaper_sld00200p_driver.c b/nrf5/drivers/display/epaper_sld00200p_driver.c index 3deef46ecd..b4efe726bf 100644 --- a/nrf5/drivers/display/epaper_sld00200p_driver.c +++ b/nrf5/drivers/display/epaper_sld00200p_driver.c @@ -28,6 +28,420 @@ #if MICROPY_PY_DISPLAY_EPAPER_SLD00200P +#include "py/mphal.h" +#include "epaper_sld00200p_driver.h" +#include "hal_spi.h" +#include "hal_time.h" + +#define BYTE_ARRAY(...) ((uint8_t[]){ __VA_ARGS__}) +#define DATA_WRITE(...) (data_write_buffer(BYTE_ARRAY(__VA_ARGS__), sizeof(BYTE_ARRAY(__VA_ARGS__)))) + +static NRF_SPI_Type * mp_spi_instance; +static NRF_PWM_Type * mp_pwm_instance; +static pin_obj_t * mp_pin_cs; +static pin_obj_t * mp_pin_panel_on; +static pin_obj_t * mp_pin_border; +static pin_obj_t * mp_pin_busy; +static pin_obj_t * mp_pin_reset; +static pin_obj_t * mp_pin_discharge; + +#if 0 +static pin_obj_t * mp_pin_temp_sensor; +#endif + +static void wait_for_busy_release(void) { + while (mp_hal_pin_read(mp_pin_busy) == 1) { + ; + } +} + +static void data_write_buffer(uint8_t * p_bytes, uint16_t num_of_bytes) { + mp_hal_pin_low(mp_pin_cs); + + hal_spi_master_tx_rx(mp_spi_instance, num_of_bytes, p_bytes, NULL); + + mp_hal_pin_high(mp_pin_cs); +} + +static void raw_write(uint8_t value) +{ + hal_spi_master_tx_rx(mp_spi_instance, 1, &value, NULL); +} + +void driver_sld00200p_init(NRF_SPI_Type * p_spi_instance, + NRF_PWM_Type * p_pwm_instance, + pin_obj_t * p_pin_cs, + pin_obj_t * p_pin_panel_on, + pin_obj_t * p_pin_border, + pin_obj_t * p_pin_busy, + pin_obj_t * p_pin_reset, + pin_obj_t * p_pin_discharge) { + + mp_spi_instance = p_spi_instance; + mp_pwm_instance = p_pwm_instance; + mp_pin_cs = p_pin_cs; + mp_pin_panel_on = p_pin_panel_on; + mp_pin_border = p_pin_border; + mp_pin_busy = p_pin_busy; + mp_pin_reset = p_pin_reset; + mp_pin_discharge = p_pin_discharge; + + driver_sld00200p_reinit(); +} + +void driver_sld00200p_reinit(void) { + mp_hal_pin_low(mp_pin_reset); + mp_hal_pin_low(mp_pin_panel_on); + mp_hal_pin_low(mp_pin_discharge); + mp_hal_pin_low(mp_pin_border); + + // start the pwm + hal_pwm_start(mp_pwm_instance); + + mp_hal_delay_ms(5); + + mp_hal_pin_high(mp_pin_panel_on); + + mp_hal_delay_ms(10); + + mp_hal_pin_high(mp_pin_reset); + mp_hal_pin_high(mp_pin_border); + mp_hal_pin_high(mp_pin_cs); + + // make reset square wave + mp_hal_delay_ms(5); + mp_hal_pin_low(mp_pin_reset); + mp_hal_delay_ms(5); + mp_hal_pin_high(mp_pin_reset); + mp_hal_delay_ms(5); + + wait_for_busy_release(); + + // channel select + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x01); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xfe, 0x00, 0x00); + + // DC/DC frequency + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x06); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xfe, 0x00, 0x00); + + // high power mode osc + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x07); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x9d); + + // disable ADC + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x08); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x00); + + // Vcom level + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x09); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0xd0, 0x00); + + // gate and source voltage levels + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x04); + + // GS + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x00); + + mp_hal_delay_ms(5); + + // driver latch on + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x03); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x01); + + // driver latch off + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x03); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x00); + + mp_hal_delay_ms(5); + + // charge pump positive voltage on + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x05); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x01); + + // final delay before PWM off + mp_hal_delay_us(30); + + // stop the pwm + hal_pwm_start(mp_pwm_instance); + + // charge pump negative voltage on + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x05); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x03); + + mp_hal_delay_us(30); + + // Vcom driver on + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x05); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x0f); + + mp_hal_delay_ms(30); + + // output enable to disable + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x02); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x24); +} + +void driver_sld00200p_deinit(void) { + epaper_sld00200p_line(0x7fffu, 0, 0x55, EPD_NORM); + mp_hal_delay_ms(25); + mp_hal_pin_low(mp_pin_border); + mp_hal_delay_ms(250); + mp_hal_pin_high(mp_pin_border); + + // latch reset turn on + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x03); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x01); + + // output enable off + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x02); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x05); + + // Vcom power off + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x05); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x0e); + + // power off negative charge pump + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x05); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x02); + + // discharge + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x04); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x0c); + mp_hal_delay_us(120); + + // all charge pumps off + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x05); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x00); + + // turn of osc + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x07); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x0d); + + // discharge internal - 1 + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x04); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x50); + mp_hal_delay_us(40); + + // discharge internal - 2 + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x04); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0xA0); + mp_hal_delay_us(40); + + // discharge internal - 3 + mp_hal_delay_us(10); + DATA_WRITE(0x70, 0x04); + mp_hal_delay_us(10); + DATA_WRITE(0x72, 0x00); + + // turn of power and all signals + mp_hal_delay_ms(10); + mp_hal_pin_low(mp_pin_reset); + mp_hal_pin_low(mp_pin_panel_on); + mp_hal_pin_low(mp_pin_border); + + // discharge pulse + mp_hal_pin_high(mp_pin_discharge); + mp_hal_delay_us(250); + mp_hal_pin_low(mp_pin_discharge); + mp_hal_pin_high(mp_pin_cs); +} + +static void epaper_sld00200p_line(uint16_t line, const uint8_t * data, uint8_t fixed_value, epd_stage_t stage) +{ + mp_hal_delay_ms(10); + + DATA_WRITE(0x70, 0x04); + wait_for_busy_release(); + + // gate source + DATA_WRITE(0x72, 0x00); + wait_for_busy_release(); + + DATA_WRITE(0x70, 0x0a); + wait_for_busy_release(); + + mp_hal_pin_low(mp_pin_cs); + raw_write(0x72); + wait_for_busy_release(); + + uint16_t bytes_per_line = 264 / 8; + + // even pixels + for (uint16_t i = bytes_per_line; i > 0; --i) { + if (data != NULL) { + uint8_t pixels = data[i - 1] & 0xaa; + + switch (stage) { + case EPD_COMP: + // B -> W, W -> B (current image) + pixels = 0xaa | ((pixels ^ 0xaa) >> 1); + break; + + case EPD_WHITE: + // B -> N, W -> W (current image) + pixels = 0x55 + ((pixels ^ 0xaa) >> 1); + break; + + case EPD_INV: + // B -> N, W -> B (new image) + pixels = 0x55 | (pixels ^ 0xaa); + break; + + case EPD_NORM: + // B -> B, W -> W (new image) + pixels = 0xaa | (pixels >> 1); + break; + + default: + break; + } + + raw_write(pixels); + wait_for_busy_release(); + } else { + raw_write(fixed_value); + wait_for_busy_release(); + } + } + + uint16_t bytes_per_scan = 176 / 4; + // scan line + for (uint16_t i = 0; i < bytes_per_scan; i++) { + if (line / 4 == i) { + raw_write(0xc0 >> (2 * (line & 0x03))); + wait_for_busy_release(); + } else { + raw_write(0x00); + wait_for_busy_release(); + } + } + + // odd pixels + for (uint16_t i = 0; i < bytes_per_line; i++) { + if (data != NULL) { + uint8_t pixels; + pixels = data[i] & 0x55; + + switch (stage) { + case EPD_COMP: + pixels = 0xaa | (pixels ^ 0x55); + break; + + case EPD_WHITE: + pixels = 0x55 + (pixels ^ 0x55); + break; + + case EPD_INV: + pixels = 0x55 | ((pixels ^ 0x55) << 1); + break; + + case EPD_NORM: + pixels = 0xaa | pixels; + break; + + default: + break; + } + + uint8_t p1 = (pixels >> 6) & 0x03; + uint8_t p2 = (pixels >> 4) & 0x03; + uint8_t p3 = (pixels >> 2) & 0x03; + uint8_t p4 = (pixels >> 0) & 0x03; + pixels = (p1 << 0) | (p2 << 2) | (p3 << 4) | (p4 << 6); + + raw_write(pixels); + wait_for_busy_release(); + } else { + raw_write(fixed_value); + wait_for_busy_release(); + } + } + + // Complete line + raw_write(0x00); + wait_for_busy_release(); + + mp_hal_pin_high(mp_pin_cs); + wait_for_busy_release(); + + DATA_WRITE(0x70, 0x02); + wait_for_busy_release(); + + DATA_WRITE(0x72, 0x2f); +} + +void driver_sld00200p_clear(uint16_t color) { + uint16_t line_count = 176; + for (uint16_t i = 0; i < line_count; i++) { + epaper_sld00200p_line(i, NULL, 0xFF, EPD_COMP); + } + mp_hal_delay_ms(100); + + for (uint16_t i = 0; i < line_count; i++) { + epaper_sld00200p_line(i, NULL, 0xAA, EPD_WHITE); + } + mp_hal_delay_ms(100); + + for (uint16_t i = 0; i < line_count; i++) { + epaper_sld00200p_line(i, NULL, 0xFF, EPD_INV); + } + mp_hal_delay_ms(100); + + for (uint16_t i = 0; i < line_count; i++) { + epaper_sld00200p_line(i, NULL, 0xAA, EPD_NORM); + } + mp_hal_delay_ms(100); +} + +void driver_sld00200p_update_line(uint16_t line, fb_byte_t * p_bytes, fb_byte_t * p_old, uint16_t len, bool compressed) { + epaper_sld00200p_line(line, (uint8_t *)p_old, 0x00, EPD_COMP); + epaper_sld00200p_line(line, (uint8_t *)p_old, 0xAA, EPD_WHITE); + epaper_sld00200p_line(line, (uint8_t *)p_bytes, 0xAA, EPD_INV); + epaper_sld00200p_line(line, (uint8_t *)p_bytes, 0xFF, EPD_NORM); +} #endif diff --git a/nrf5/drivers/display/epaper_sld00200p_driver.h b/nrf5/drivers/display/epaper_sld00200p_driver.h index 2b641381f0..22fc2b56a9 100644 --- a/nrf5/drivers/display/epaper_sld00200p_driver.h +++ b/nrf5/drivers/display/epaper_sld00200p_driver.h @@ -27,6 +27,12 @@ #ifndef EPAPER_SLD00200P_DRIVER_H__ #define EPAPER_SLD00200P_DRIVER_H__ +#include "py/mphal.h" + +#include "hal_spi.h" +#include "hal_pwm.h" +#include "lcd_mono_fb.h" + typedef enum { EPD_COMP, @@ -35,4 +41,21 @@ typedef enum EPD_NORM } epd_stage_t; +void driver_sld00200p_init(NRF_SPI_Type * p_spi_instance, + NRF_PWM_Type * p_pwm_instance, + pin_obj_t * p_pin_cs, + pin_obj_t * p_pin_panel_on, + pin_obj_t * p_pin_border, + pin_obj_t * p_pin_busy, + pin_obj_t * p_pin_reset, + pin_obj_t * p_pin_discharge); + +void driver_sld00200p_reinit(void); + +void driver_sld00200p_deinit(void); + +void driver_sld00200p_clear(uint16_t color); + +void driver_sld00200p_update_line(uint16_t line, fb_byte_t * p_bytes, fb_byte_t * p_old, uint16_t len, bool compressed); + #endif // EPAPER_SLD00200P_DRIVER_H__ diff --git a/nrf5/drivers/display/epaper_sld00200p_obj.c b/nrf5/drivers/display/epaper_sld00200p_obj.c index 07cb2bd696..46ac21fe19 100644 --- a/nrf5/drivers/display/epaper_sld00200p_obj.c +++ b/nrf5/drivers/display/epaper_sld00200p_obj.c @@ -24,8 +24,14 @@ * THE SOFTWARE. */ +#include + #include "py/obj.h" #include "py/runtime.h" +#include "py/mphal.h" +#include "genhdr/pins.h" + +#include "epaper_sld00200p_driver.h" // For now PWM is only enabled for nrf52 targets. #if MICROPY_PY_DISPLAY_EPAPER_SLD00200P && NRF52 @@ -33,37 +39,118 @@ /// \moduleref epaper /// \class sld00200p - SLD00200P E-paper shield. +#include "pin.h" +#include "spi.h" +#include "pwm.h" #include "hal_spi.h" #include "hal_pwm.h" #include "lcd_mono_fb.h" typedef struct _epaper_sld00200p_obj_t { mp_obj_base_t base; - SPI_HandleTypeDef *spi; - PWM_HandleTypeDef *pwm; + machine_hard_spi_obj_t *spi; + machine_hard_pwm_obj_t *pwm; + pin_obj_t * pin_cs; + pin_obj_t * pin_panel_on; + pin_obj_t * pin_border; + pin_obj_t * pin_busy; + pin_obj_t * pin_reset; + pin_obj_t * pin_discharge; +#if 0 + pin_obj_t * pin_temp_sensor; +#endif + mp_obj_framebuf_t * framebuffer; } epaper_sld00200p_obj_t; +static void dirty_line_update_cb(mp_obj_framebuf_t * p_framebuffer, + uint16_t line, + fb_byte_t * p_new, + fb_byte_t * p_old) { + driver_sld00200p_update_line(line, p_new, p_old, p_framebuffer->bytes_stride, true); +} + /// \method __str__() /// Return a string describing the SLD00200P object. STATIC void epaper_sld00200_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { + epaper_sld00200p_obj_t *self = o; + + mp_printf(print, "ILI9341(SPI(mosi=%u, miso=%u, clk=%u),\n", + self->spi->pyb->spi->init.mosi_pin, + self->spi->pyb->spi->init.miso_pin, + self->spi->pyb->spi->init.clk_pin); + mp_printf(print, " PWM(pwm_pin=%u),\n", + self->pwm->pyb->pwm->init.pwm_pin); + + mp_printf(print, " cs=(port=%u, pin=%u), panel_on=(port=%u, pin=%u),\n", + self->pin_cs->port, + self->pin_cs->pin, + self->pin_panel_on->port, + self->pin_panel_on->pin); + + mp_printf(print, " border=(port=%u, pin=%u), busy=(port=%u, pin=%u),\n", + self->pin_border->port, + self->pin_border->pin, + self->pin_busy->port, + self->pin_busy->pin); + + mp_printf(print, " reset=(port=%u, pin=%u), discharge=(port=%u, pin=%u),\n", + self->pin_reset->port, + self->pin_reset->pin, + self->pin_discharge->port, + self->pin_discharge->pin); + + mp_printf(print, " FB(width=%u, height=%u, dir=%u))\n", + self->framebuffer->width, + self->framebuffer->height); + } // for make_new enum { + ARG_NEW_WIDTH, + ARG_NEW_HEIGHT, ARG_NEW_SPI, - ARG_NEW_CS, ARG_NEW_PWM, + ARG_NEW_CS, ARG_NEW_PANEL_ON, ARG_NEW_BORDER, - ARG_NEW_RESET, ARG_NEW_BUSY, + ARG_NEW_RESET, ARG_NEW_DISCHARGE, ARG_NEW_TEMP_SENSOR, }; +/* +from machine import Pin, SPI, PWM +from display import SLD00200P +cs = Pin("A16", mode=Pin.OUT, pull=Pin.PULL_UP) +reset = Pin("A17", mode=Pin.OUT, pull=Pin.PULL_UP) +panel_on = Pin("A13", mode=Pin.OUT, pull=Pin.PULL_UP) +discharge = Pin("A19", mode=Pin.OUT, pull=Pin.PULL_UP) +border = Pin("A14", mode=Pin.OUT, pull=Pin.PULL_UP) +busy = Pin("A18", mode=Pin.IN, pull=Pin.PULL_DISABLED) +cs = Pin("A22", mode=Pin.OUT, pull=Pin.PULL_UP) +spi = SPI(0, baudrate=8000000) +pwm = PWM(0, Pin("A16", mode=Pin.OUT), freq=PWM.FREQ_250KHZ, duty=50, period=2) +d = SLD00200P(264, 176, spi, pwm, cs, panel_on, border, busy, reset, discharge) +d.text("Hello World!", 32, 32) +d.show() +*/ STATIC mp_obj_t epaper_sld00200p_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { static const mp_arg_t allowed_args[] = { - { MP_QSTR_id, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)} }, + { ARG_NEW_WIDTH, MP_ARG_REQUIRED | MP_ARG_INT }, + { ARG_NEW_HEIGHT, MP_ARG_REQUIRED | MP_ARG_INT }, + { ARG_NEW_SPI, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { ARG_NEW_PWM, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { ARG_NEW_CS, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { ARG_NEW_PANEL_ON, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { ARG_NEW_BORDER, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { ARG_NEW_BUSY, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { ARG_NEW_RESET, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { ARG_NEW_DISCHARGE, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, +#if 0 + { ARG_NEW_TEMP_SENSOR, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, +#endif }; // parse args @@ -71,6 +158,113 @@ STATIC mp_obj_t epaper_sld00200p_make_new(const mp_obj_type_t *type, size_t n_ar mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); epaper_sld00200p_obj_t *s = m_new_obj_with_finaliser(epaper_sld00200p_obj_t); + s->base.type = type; + + mp_int_t width; + mp_int_t height; + + if (args[ARG_NEW_WIDTH].u_int > 0) { + width = args[ARG_NEW_WIDTH].u_int; + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Display width not set")); + } + + if (args[ARG_NEW_HEIGHT].u_int > 0) { + height = args[ARG_NEW_HEIGHT].u_int; + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Display height not set")); + } + + if (args[ARG_NEW_SPI].u_obj != MP_OBJ_NULL) { + s->spi = args[ARG_NEW_SPI].u_obj; + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Display SPI not set")); + } + + if (args[ARG_NEW_PWM].u_obj != MP_OBJ_NULL) { + s->pwm = args[ARG_NEW_PWM].u_obj; + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Display PWM not set")); + } + + if (args[ARG_NEW_CS].u_obj != MP_OBJ_NULL) { + s->pin_cs = args[ARG_NEW_CS].u_obj; + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Display CS Pin not set")); + } + + if (args[ARG_NEW_PANEL_ON].u_obj != MP_OBJ_NULL) { + s->pin_panel_on = args[ARG_NEW_PANEL_ON].u_obj; + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Display Panel-on Pin not set")); + } + + if (args[ARG_NEW_BORDER].u_obj != MP_OBJ_NULL) { + s->pin_border = args[ARG_NEW_BORDER].u_obj; + printf("BORDER PIN %u\n", s->pin_border->pin); + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Display Border Pin not set")); + } + + if (args[ARG_NEW_BUSY].u_obj != MP_OBJ_NULL) { + s->pin_busy = args[ARG_NEW_BUSY].u_obj; + printf("BUSY PIN %u\n", s->pin_busy->pin); + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Display Busy Pin not set")); + } + + if (args[ARG_NEW_RESET].u_obj != MP_OBJ_NULL) { + s->pin_reset = args[ARG_NEW_RESET].u_obj; + printf("RESET PIN %u\n", s->pin_reset->pin); + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Display Reset Pin not set")); + } + + if (args[ARG_NEW_DISCHARGE].u_obj != MP_OBJ_NULL) { + s->pin_discharge = args[ARG_NEW_DISCHARGE].u_obj; + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Display Reset Pin not set")); + } + +#if 0 + if (args[ARG_NEW_TEMP_SENSOR].u_obj != MP_OBJ_NULL) { + s->pin_temp_sensor = args[ARG_NEW_TEMP_SENSOR].u_obj; + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "Display Busy Pin not set)")); + } +#endif + + // direction arg not yet configurable + mp_int_t vertical = false; + s->framebuffer = lcd_mono_fb_helper_make_new(width, height, vertical); + + driver_sld00200p_init(s->spi->pyb->spi->instance, + s->pwm->pyb->pwm->instance, + s->pin_cs, + s->pin_panel_on, + s->pin_border, + s->pin_busy, + s->pin_reset, + s->pin_discharge); + + // Default to white background + driver_sld00200p_clear(0x00); + + display_clear_screen(s->framebuffer, 0x0); + + driver_sld00200p_deinit(); + return MP_OBJ_FROM_PTR(s); } @@ -96,14 +290,24 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(epaper_sld00200p_fill_obj, epaper_sld00200p_fil /// refresh() method explicitly. STATIC mp_obj_t epaper_sld00200p_show(size_t n_args, const mp_obj_t *args) { epaper_sld00200p_obj_t *self = MP_OBJ_TO_PTR(args[0]); + mp_int_t num_of_refresh = 0; if (n_args > 1) { num_of_refresh = mp_obj_get_int(args[1]); } + driver_sld00200p_reinit(); - (void)num_of_refresh; - (void)self; + display_update(self->framebuffer, false, dirty_line_update_cb); + + if (num_of_refresh > 0) { + while (num_of_refresh > 0) { + display_update(self->framebuffer, true, dirty_line_update_cb); + num_of_refresh--; + } + } + + driver_sld00200p_deinit(); return mp_const_none; } @@ -115,14 +319,32 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(epaper_sld00200p_show_obj, 1, 2, epap /// - With no argument, 1 refresh will be done. /// - With `num_of_refresh` given, The whole framebuffer will be considered /// dirty and will be refreshed the given number of times. -STATIC mp_obj_t epaper_sld00200p_refresh(mp_obj_t self_in) { - epaper_sld00200p_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t epaper_sld00200p_refresh(size_t n_args, const mp_obj_t *args) { + epaper_sld00200p_obj_t *self = MP_OBJ_TO_PTR(args[0]); - (void)self; + mp_int_t num_of_refresh = 0; + + if (n_args > 1) { + num_of_refresh = mp_obj_get_int(args[1]); + } + + driver_sld00200p_reinit(); + + if (num_of_refresh > 0) { + while (num_of_refresh > 0) { + display_update(self->framebuffer, true, dirty_line_update_cb); + num_of_refresh--; + } + } else { + // default to one refresh + display_update(self->framebuffer, true, dirty_line_update_cb); + } + + driver_sld00200p_deinit(); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(epaper_sld00200p_refresh_obj, epaper_sld00200p_refresh); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(epaper_sld00200p_refresh_obj, 1, 2, epaper_sld00200p_refresh); /// \method pixel(x, y, [color]) /// Write one pixel in framebuffer. @@ -160,12 +382,11 @@ STATIC mp_obj_t epaper_sld00200p_text(size_t n_args, const mp_obj_t *args) { if (n_args >= 4) { color = mp_obj_get_int(args[3]); } - (void)self; - (void)str; - (void)x; - (void)y; + (void)color; + display_print_string(self->framebuffer, x, y, str); + return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(epaper_sld00200p_text_obj, 4, 5, epaper_sld00200p_text);