From c7abdd003f9e1a9ca571bdf02b7f7e1cedaf8ba5 Mon Sep 17 00:00:00 2001 From: Herbert Moers Date: Fri, 5 Dec 2025 14:58:34 +0100 Subject: [PATCH 1/3] intermediate commit --- ext_mod/lcd_bus/common_include/spi_bus.h | 6 + ext_mod/lcd_bus/common_src/i80_bus.c | 1 + ext_mod/lcd_bus/common_src/spi_bus.c | 19 +++- micropy_updates/common/mp_spi_common.h | 133 ++++++++++++++--------- micropy_updates/rp2/machine_spi.c | 4 +- 5 files changed, 106 insertions(+), 57 deletions(-) diff --git a/ext_mod/lcd_bus/common_include/spi_bus.h b/ext_mod/lcd_bus/common_include/spi_bus.h index cde39087..86519199 100644 --- a/ext_mod/lcd_bus/common_include/spi_bus.h +++ b/ext_mod/lcd_bus/common_include/spi_bus.h @@ -64,6 +64,12 @@ void *buf1; void *buf2; + /* buffer_flags is not used, but it needs to be here + * otherwise function pointers are no more aligned + * with the pointer use in _mp_lcd_bus_obj_t + */ + uint32_t buffer_flags; + bool trans_done; bool rgb565_byte_swap; diff --git a/ext_mod/lcd_bus/common_src/i80_bus.c b/ext_mod/lcd_bus/common_src/i80_bus.c index 2c97dfc2..991737d8 100644 --- a/ext_mod/lcd_bus/common_src/i80_bus.c +++ b/ext_mod/lcd_bus/common_src/i80_bus.c @@ -10,6 +10,7 @@ #include "py/obj.h" #include "py/runtime.h" #include "py/objarray.h" +#include "mphalport.h" // for mp_hal_pin_output //#include "mpconfigport.h" //#include "modmachine.h" diff --git a/ext_mod/lcd_bus/common_src/spi_bus.c b/ext_mod/lcd_bus/common_src/spi_bus.c index 2de31f7c..54d3a44a 100644 --- a/ext_mod/lcd_bus/common_src/spi_bus.c +++ b/ext_mod/lcd_bus/common_src/spi_bus.c @@ -5,7 +5,8 @@ // local includes #include "lcd_types.h" #include "modlcd_bus.h" -#include "spi_bus.h" +// compiler doesn't find spi_bus.h without ../common_include/ ?? +#include "../common_include/spi_bus.h" #include "../../../micropy_updates/common/mp_spi_common.h" // micropython includes @@ -14,6 +15,7 @@ // #else #include "py/obj.h" #include "py/runtime.h" +#include "extmod/modmachine.h" // for mp_machine_p_t // stdlib includes #include @@ -189,23 +191,26 @@ mp_lcd_spi_bus_obj_t *self = MP_OBJ_TO_PTR(obj); - uint8_t bits; + // uint8_t bits; no more used if (cmd_bits == 16) { self->send_cmd = send_cmd_16; - bits = 16; + // bits = 16; } else { self->send_cmd = send_cmd_8; - bits = 8; + // bits = 8; } if (param_bits == 16) { self->send_param = send_param_16; - bits = 16; + // bits = 16; } else { self->send_param = send_param_8; } + /* constructor above takes a machine_hw_spi_device as argument + so we should not create another one + mp_obj_base_t *spi; mp_obj_t spi_args[12]; @@ -228,6 +233,10 @@ self->bus_handle = spi; self->panel_io_config.spi_transfer = ((mp_machine_spi_p_t *)MP_OBJ_TYPE_GET_SLOT(spi->type, protocol))->transfer; + */ + + // we take the transfer pointer from the bus inside the existing device + self->panel_io_config.spi_transfer = ((mp_machine_spi_p_t *)MP_OBJ_TYPE_GET_SLOT(&machine_spi_type, protocol))->transfer; return LCD_OK; } diff --git a/micropy_updates/common/mp_spi_common.h b/micropy_updates/common/mp_spi_common.h index f92cb27c..30d527aa 100644 --- a/micropy_updates/common/mp_spi_common.h +++ b/micropy_updates/common/mp_spi_common.h @@ -14,55 +14,88 @@ MP_SPI_STATE_SENDING } mp_machine_hw_spi_state_t; - typedef struct _mp_machine_hw_spi_bus_obj_t mp_machine_hw_spi_bus_obj_t; - typedef struct _mp_machine_hw_spi_device_obj_t mp_machine_hw_spi_device_obj_t; - - struct _mp_machine_hw_spi_bus_obj_t { - mp_obj_base_t base; - uint8_t host; - mp_obj_t sck; - mp_obj_t data0; - mp_obj_t data1; - mp_obj_t data2; - mp_obj_t data3; - mp_obj_t data4; - mp_obj_t data5; - mp_obj_t data6; - mp_obj_t data7; - bool dual; - bool quad; - bool octal; - uint8_t device_count; - mp_machine_hw_spi_device_obj_t **devices; - mp_machine_hw_spi_state_t state; - const void *user_data; - void (*deinit)(mp_machine_hw_spi_bus_obj_t *bus); - }; - - struct _mp_machine_hw_spi_device_obj_t { - mp_obj_base_t base; - uint32_t freq; - uint8_t polarity; - uint8_t phase; - uint8_t bits; - uint8_t firstbit; - bool dual; - bool quad; - bool octal; - bool active; - mp_obj_t cs; - mp_machine_hw_spi_bus_obj_t *spi_bus; - void *user_data; - void (*deinit)(mp_machine_hw_spi_device_obj_t *device); - }; - - void mp_machine_hw_spi_bus_initilize(mp_machine_hw_spi_bus_obj_t *bus); - void mp_machine_hw_spi_bus_add_device(mp_machine_hw_spi_device_obj_t *device); - void mp_machine_hw_spi_bus_remove_device(mp_machine_hw_spi_device_obj_t *device); - - extern const mp_obj_type_t mp_machine_hw_spi_device_type; - extern const mp_obj_type_t mp_machine_hw_spi_bus_type; - - void mp_machine_hw_spi_bus_deinit_all(void); + #ifdef ESP_IDF_VERSION + typedef struct _mp_machine_hw_spi_bus_obj_t mp_machine_hw_spi_bus_obj_t; + typedef struct _mp_machine_hw_spi_device_obj_t mp_machine_hw_spi_device_obj_t; + struct _mp_machine_hw_spi_bus_obj_t { + mp_obj_base_t base; + uint8_t host; + mp_obj_t sck; + mp_obj_t data0; + mp_obj_t data1; + mp_obj_t data2; + mp_obj_t data3; + mp_obj_t data4; + mp_obj_t data5; + mp_obj_t data6; + mp_obj_t data7; + bool dual; + bool quad; + bool octal; + uint8_t device_count; + mp_machine_hw_spi_device_obj_t **devices; + mp_machine_hw_spi_state_t state; + const void *user_data; + void (*deinit)(mp_machine_hw_spi_bus_obj_t *bus); + }; + + struct _mp_machine_hw_spi_device_obj_t { + mp_obj_base_t base; + uint32_t freq; + uint8_t polarity; + uint8_t phase; + uint8_t bits; + uint8_t firstbit; + bool dual; + bool quad; + bool octal; + bool active; + mp_obj_t cs; + mp_machine_hw_spi_bus_obj_t *spi_bus; + void *user_data; + void (*deinit)(mp_machine_hw_spi_device_obj_t *device); + }; + + void mp_machine_hw_spi_bus_initilize(mp_machine_hw_spi_bus_obj_t *bus); + void mp_machine_hw_spi_bus_add_device(mp_machine_hw_spi_device_obj_t *device); + void mp_machine_hw_spi_bus_remove_device(mp_machine_hw_spi_device_obj_t *device); + + extern const mp_obj_type_t mp_machine_hw_spi_device_type; + extern const mp_obj_type_t mp_machine_hw_spi_bus_type; + + void mp_machine_hw_spi_bus_deinit_all(void); + + #else + // definitions in line with use in micropy_updates/machine_spi.c + // + typedef struct _mp_machine_hw_spi_bus_obj_t { + uint8_t host; + mp_obj_t sck; + mp_obj_t mosi; + mp_obj_t miso; + int16_t active_devices; + mp_machine_hw_spi_state_t state; + const void *user_data; + } mp_machine_hw_spi_bus_obj_t; + + + typedef struct _machine_hw_spi_obj_t { + mp_obj_base_t base; + uint32_t baudrate; + uint8_t polarity; + uint8_t phase; + uint8_t bits; + uint8_t firstbit; + bool active; // added as requested in machine_spi_make_new + mp_obj_t cs; + mp_machine_hw_spi_bus_obj_t *spi_bus; + void *user_data; + } machine_hw_spi_obj_t; + + // typedef added to align naming in spi_bus with naming in machine_spi + typedef struct _machine_hw_spi_obj_t machine_hw_spi_device_obj_t; + + + #endif /* ESP_IDF_VERSION*/ #endif /* __MP_SPI_COMMON_H__ */ diff --git a/micropy_updates/rp2/machine_spi.c b/micropy_updates/rp2/machine_spi.c index 1c5e6f2f..59520731 100644 --- a/micropy_updates/rp2/machine_spi.c +++ b/micropy_updates/rp2/machine_spi.c @@ -111,7 +111,7 @@ mp_machine_hw_spi_bus_obj_t rp2_machine_spi_bus_obj[] = { .miso = MP_OBJ_NULL, .active_devices = 0, .state = 0, - .user_data = (const void *)spi0 + .user_data = (void *)spi0 }, { .host = 1, @@ -120,7 +120,7 @@ mp_machine_hw_spi_bus_obj_t rp2_machine_spi_bus_obj[] = { .miso = MP_OBJ_NULL, .active_devices = 0, .state = 0, - .user_data = (const void *)spi1 + .user_data = (void *)spi1 } }; From 377ede33174f082e0aa5d3b39a1c7758e7fee85e Mon Sep 17 00:00:00 2001 From: Herbert Moers Date: Fri, 5 Dec 2025 16:00:38 +0100 Subject: [PATCH 2/3] works for SPI bus --- ext_mod/lcd_bus/common_src/spi_bus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext_mod/lcd_bus/common_src/spi_bus.c b/ext_mod/lcd_bus/common_src/spi_bus.c index 54d3a44a..59e176ef 100644 --- a/ext_mod/lcd_bus/common_src/spi_bus.c +++ b/ext_mod/lcd_bus/common_src/spi_bus.c @@ -236,6 +236,7 @@ */ // we take the transfer pointer from the bus inside the existing device + self->bus_handle = MP_OBJ_FROM_PTR(self->spi_bus); self->panel_io_config.spi_transfer = ((mp_machine_spi_p_t *)MP_OBJ_TYPE_GET_SLOT(&machine_spi_type, protocol))->transfer; return LCD_OK; From 96838e23b1edaf52d10035131aa4ac08fca78271 Mon Sep 17 00:00:00 2001 From: Herbert Moers Date: Mon, 8 Dec 2025 11:33:32 +0100 Subject: [PATCH 3/3] debug of i80_bus bitbang driver --- ext_mod/lcd_bus/common_include/i80_bus.h | 6 + ext_mod/lcd_bus/common_src/i80_bus.c | 137 +++++++++++++---------- 2 files changed, 86 insertions(+), 57 deletions(-) diff --git a/ext_mod/lcd_bus/common_include/i80_bus.h b/ext_mod/lcd_bus/common_include/i80_bus.h index 40819bbd..d238f9b8 100644 --- a/ext_mod/lcd_bus/common_include/i80_bus.h +++ b/ext_mod/lcd_bus/common_include/i80_bus.h @@ -80,6 +80,12 @@ void *buf1; void *buf2; + /* buffer_flags is not used, but it needs to be here + * otherwise function pointers are no more aligned + * with the pointer use in _mp_lcd_bus_obj_t + */ + uint32_t buffer_flags; + bool trans_done; bool rgb565_byte_swap; diff --git a/ext_mod/lcd_bus/common_src/i80_bus.c b/ext_mod/lcd_bus/common_src/i80_bus.c index 991737d8..9bf9853e 100644 --- a/ext_mod/lcd_bus/common_src/i80_bus.c +++ b/ext_mod/lcd_bus/common_src/i80_bus.c @@ -10,7 +10,6 @@ #include "py/obj.h" #include "py/runtime.h" #include "py/objarray.h" -#include "mphalport.h" // for mp_hal_pin_output //#include "mpconfigport.h" //#include "modmachine.h" @@ -73,6 +72,11 @@ mp_hal_pin_write(self->bus_config.data_gpio_nums[1], (buf[0] >> 1) & 1); \ mp_hal_pin_write(self->bus_config.data_gpio_nums[0], buf[0] & 1); \ } + + // sleep_us(1) to ensure minimum WR pulse width, so that I can follow it with my logic analyzer + // can be eliminated after debugging + #define WR_PULSE() { mp_hal_pin_write(self->bus_config.wr_gpio_num, 0)/*; sleep_us(1)*/; mp_hal_pin_write(self->bus_config.wr_gpio_num, 1);; } + /* end macros */ @@ -103,7 +107,7 @@ */ static mp_obj_t mp_lcd_i80_bus_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - enum { + enum { ARG_dc, ARG_wr, ARG_data0, @@ -128,8 +132,8 @@ ARG_dc_cmd_high, ARG_dc_dummy_high, ARG_dc_data_high, - ARG_cmd_bits, - ARG_param_bits, + //ARG_cmd_bits, + //ARG_param_bits, ARG_cs_active_high, ARG_reverse_color_bits, ARG_swap_color_bytes, @@ -199,7 +203,8 @@ self->callback = mp_const_none; - #if !defined(mp_hal_pin_output) && !defined(IDF_VER) + // mp_hal_pin_output if a function for rp2, so I have added PICO_HEAP_SIZE + #if !defined(mp_hal_pin_output) && !defined(IDF_VER) && !defined(PICO_HEAP_SIZE) mp_raise_msg(&mp_type_NotImplementedError, MP_ERROR_TEXT("LCD I80 but is not available for this MCU")); #else self->panel_io_config.user_ctx = self; @@ -220,7 +225,7 @@ #endif /* defined(MP_HAL_PIN_SPEED_VERY_HIGH) && !defined(MICROPY_INCLUDED_MIMXRT_MPHALPORT_H) */ mp_hal_pin_write(self->bus_config.dc_gpio_num, self->panel_io_config.dc_levels.dc_data_level); - mp_hal_pin_write(self->bus_config.wr_gpio_num, 0); + mp_hal_pin_write(self->bus_config.wr_gpio_num, !self->panel_io_config.flags.cs_active_high); self->bus_config.data_gpio_nums[0] = (mp_hal_pin_obj_t)mp_hal_get_pin_obj(args[ARG_data0].u_obj); self->bus_config.data_gpio_nums[1] = (mp_hal_pin_obj_t)mp_hal_get_pin_obj(args[ARG_data1].u_obj); @@ -285,51 +290,80 @@ CS_LOW(); DC_CMD(); - + if (self->bus_config.bus_width == 8) { - uint8_t *buf = NULL; + uint8_t buf[1]; if (self->panel_io_config.lcd_cmd_bits == 8) { buf[0] = (uint8_t)lcd_cmd; WRITE8(); } else { buf[0] = (uint8_t)((uint16_t)lcd_cmd >> 8); WRITE8(); - WR_LOW(); - WR_HIGH(); + WR_PULSE(); buf[0] = (uint8_t)((uint16_t)lcd_cmd & 0xFF); WRITE8(); } } else { - uint16_t *buf = NULL; + uint16_t buf[1]; buf[0] = (uint16_t)lcd_cmd; WRITE16(); } - - WR_LOW(); - WR_HIGH(); + + WR_PULSE(); DC_DATA(); - if (param != NULL) { - if (self->bus_config.bus_width == 8) { - uint8_t *buf = (uint8_t *)param; - uint16_t len = (uint16_t)param_size; - while (len--) { - WRITE8(); - WR_LOW(); - WR_HIGH(); - buf++; - } - } else { - uint16_t *buf = (uint16_t *)param; - uint16_t len = (uint16_t)(param_size / 2); - while (len--) { - WRITE16(); - WR_LOW(); - WR_HIGH(); - buf++; + if (param_size > 0 ) { + if (self->bus_config.bus_width == 8) { + if (self->panel_io_config.lcd_cmd_bits == 8) { + // 8 bit param over 8 bit bus + uint8_t *buf = (uint8_t *)param; + uint16_t len = (uint16_t)param_size; + while (len--) { + WRITE8(); + WR_PULSE(); + buf++; + } + } else { + // 16 bit param over 8 bit bus + uint16_t buf[1]; + uint16_t *p = (uint16_t *)param; + uint16_t len = (uint16_t)(param_size / 2); + while (len--) { + buf[0] = (uint8_t)(*p >> 8); + WRITE8(); + WR_PULSE(); + buf[0] = (uint8_t)(*p & 0xFF); + WRITE8(); + WR_PULSE(); + p++; + } } - } + } else { + if (self->panel_io_config.lcd_cmd_bits == 8) { + // 8 bit param over 16 bit bus + uint16_t buf[1]; + uint8_t *p = (uint8_t *)param; + uint16_t len = (uint16_t)param_size; + while (len--) { + buf[0] = (uint16_t)(*p); + WRITE16(); + WR_PULSE(); + //WR_LOW(); + //WR_HIGH(); + p++; + } + } else { + // 16 bit param over 16 bit bus + uint16_t *buf = (uint16_t *)param; + uint16_t len = (uint16_t)(param_size); + while (len--) { + WRITE16(); + WR_PULSE(); + buf++; + } + } + } } CS_HIGH(); @@ -361,25 +395,23 @@ DC_CMD(); if (self->bus_config.bus_width == 8) { - uint8_t *buf = NULL; + uint8_t buf[1]; if (self->panel_io_config.lcd_cmd_bits == 8) { buf[0] = (uint8_t)lcd_cmd; WRITE8(); } else { buf[0] = (uint8_t)((uint16_t)lcd_cmd >> 8); WRITE8(); - WR_LOW(); - WR_HIGH(); + WR_PULSE(); buf[0] = (uint8_t)((uint16_t)lcd_cmd & 0xFF); WRITE8(); } } else { - uint16_t *buf = NULL; + uint16_t buf[1]; buf[0] = (uint16_t)lcd_cmd; WRITE16(); } - WR_LOW(); - WR_HIGH(); + WR_PULSE(); DC_DATA(); self->write_color(self, color, color_size); @@ -464,8 +496,7 @@ WRITE8(); } buf++; - WR_LOW(); - WR_HIGH(); + WR_PULSE(); } } @@ -482,8 +513,7 @@ WRITE16(); } buf++; - WR_LOW(); - WR_HIGH(); + WR_PULSE(); } } @@ -501,8 +531,7 @@ last = buf[0]; WRITE8(); } - WR_LOW(); - WR_HIGH(); + WR_PULSE(); buf = &bd[i * 2]; @@ -510,8 +539,7 @@ last = buf[0]; WRITE8(); } - WR_LOW(); - WR_HIGH(); + WR_PULSE(); } } @@ -529,8 +557,7 @@ last = buf[0]; WRITE16(); } - WR_LOW(); - WR_HIGH(); + WR_PULSE(); buf = &bd[i * 2]; @@ -538,8 +565,7 @@ last = buf[0]; WRITE16(); } - WR_LOW(); - WR_HIGH(); + WR_PULSE(); } } @@ -556,15 +582,13 @@ last = bd[0]; *buf = bd[0] << 8; WRITE8(); - WR_LOW(); - WR_HIGH(); + WR_PULSE(); *buf = bd[0] >> 8; WRITE8(); WR_LOW(); WR_HIGH(); } - WR_LOW(); - WR_HIGH(); + WR_PULSE(); bd++; } } @@ -582,8 +606,7 @@ last = buf[0]; WRITE16(); } - WR_LOW(); - WR_HIGH(); + WR_PULSE(); buf++; } }