diff --git a/common/pimoroni_bus.cpp b/common/pimoroni_bus.cpp index 794ba973..d6c7eac1 100644 --- a/common/pimoroni_bus.cpp +++ b/common/pimoroni_bus.cpp @@ -4,12 +4,12 @@ namespace pimoroni { SPIPins get_spi_pins(BG_SPI_SLOT slot) { switch(slot) { case PICO_EXPLORER_ONBOARD: - return {PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, SPI_DEFAULT_MISO, PIN_UNUSED}; + return {PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, SPI_DEFAULT_DC, PIN_UNUSED}; case BG_SPI_FRONT: - return {PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, SPI_DEFAULT_MISO, SPI_BG_FRONT_PWM}; + return {PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, SPI_DEFAULT_DC, SPI_BG_FRONT_PWM}; case BG_SPI_BACK: - return {PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_BACK_CS, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, SPI_DEFAULT_MISO, SPI_BG_BACK_PWM}; + return {PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_BACK_CS, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, SPI_DEFAULT_DC, SPI_BG_BACK_PWM}; } - return {PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, SPI_DEFAULT_MISO, SPI_BG_FRONT_PWM}; + return {PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, SPI_DEFAULT_DC, SPI_BG_FRONT_PWM}; }; } \ No newline at end of file diff --git a/common/pimoroni_bus.hpp b/common/pimoroni_bus.hpp index eafecc19..8a9d400b 100644 --- a/common/pimoroni_bus.hpp +++ b/common/pimoroni_bus.hpp @@ -10,6 +10,7 @@ namespace pimoroni { uint sck; uint mosi; uint miso; + uint dc; uint bl; }; diff --git a/common/pimoroni_common.hpp b/common/pimoroni_common.hpp index 90c949b2..6300a3ac 100644 --- a/common/pimoroni_common.hpp +++ b/common/pimoroni_common.hpp @@ -32,6 +32,7 @@ namespace pimoroni { // SPI static const unsigned int SPI_DEFAULT_MOSI = 19; static const unsigned int SPI_DEFAULT_MISO = 16; + static const unsigned int SPI_DEFAULT_DC = 16; static const unsigned int SPI_DEFAULT_SCK = 18; static const unsigned int SPI_BG_FRONT_PWM = 20; diff --git a/drivers/st7789/st7789.hpp b/drivers/st7789/st7789.hpp index 1effcb41..228dc1f1 100644 --- a/drivers/st7789/st7789.hpp +++ b/drivers/st7789/st7789.hpp @@ -71,7 +71,7 @@ namespace pimoroni { ST7789(uint16_t width, uint16_t height, Rotation rotation, bool round, void *frame_buffer, SPIPins pins) : spi(pins.spi), width(width), height(height), rotation(rotation), round(round), - cs(pins.cs), dc(pins.miso), wr_sck(pins.sck), d0(pins.mosi), bl(pins.bl), frame_buffer(frame_buffer) { + cs(pins.cs), dc(pins.dc), wr_sck(pins.sck), d0(pins.mosi), bl(pins.bl), frame_buffer(frame_buffer) { // configure spi interface and pins spi_init(spi, SPI_BAUD); diff --git a/libraries/breakout_roundlcd/breakout_roundlcd.cpp b/libraries/breakout_roundlcd/breakout_roundlcd.cpp index 3684d3d2..c46f8cbb 100644 --- a/libraries/breakout_roundlcd/breakout_roundlcd.cpp +++ b/libraries/breakout_roundlcd/breakout_roundlcd.cpp @@ -11,7 +11,7 @@ namespace pimoroni { BreakoutRoundLCD::BreakoutRoundLCD(uint16_t *buf, spi_inst_t *spi, uint cs, uint dc, uint sck, uint mosi, uint bl) : PicoGraphics(WIDTH, HEIGHT, buf), - screen(WIDTH, HEIGHT, ROTATE_0, true, buf, SPIPins{spi, cs sck, mosi, dc, bl}) { + screen(WIDTH, HEIGHT, ROTATE_0, true, buf, SPIPins{spi, cs sck, mosi, PIN_UNUSED, dc, bl}) { __fb = buf; } diff --git a/micropython/modules/pimoroni_bus/micropython.cmake b/micropython/modules/pimoroni_bus/micropython.cmake index c9eb1aba..eec58f1a 100644 --- a/micropython/modules/pimoroni_bus/micropython.cmake +++ b/micropython/modules/pimoroni_bus/micropython.cmake @@ -3,13 +3,14 @@ string(TOUPPER ${MOD_NAME} MOD_NAME_UPPER) add_library(usermod_${MOD_NAME} INTERFACE) target_sources(usermod_${MOD_NAME} INTERFACE - #${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.c - #${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.cpp + ${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.c + ${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.cpp ${CMAKE_CURRENT_LIST_DIR}/../../../common/pimoroni_bus.cpp ) target_include_directories(usermod_${MOD_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/../../../common/ ) target_compile_definitions(usermod_${MOD_NAME} INTERFACE diff --git a/micropython/modules/pimoroni_bus/pimoroni_bus.c b/micropython/modules/pimoroni_bus/pimoroni_bus.c new file mode 100644 index 00000000..8a608ba1 --- /dev/null +++ b/micropython/modules/pimoroni_bus/pimoroni_bus.c @@ -0,0 +1,37 @@ +#include "pimoroni_bus.h" + +const mp_obj_type_t SPISlot_type = { + { &mp_type_type }, + .name = MP_QSTR_SPISlot, + .print = PimoroniBus_print, + .make_new = SPISlot_make_new +}; + +const mp_obj_type_t SPIPins_type = { + { &mp_type_type }, + .name = MP_QSTR_SPIBus, + .print = PimoroniBus_print, + .make_new = SPIPins_make_new +}; + +const mp_obj_type_t ParallelPins_type = { + { &mp_type_type }, + .name = MP_QSTR_ParallelBus, + .print = PimoroniBus_print, + .make_new = ParallelPins_make_new +}; + +STATIC const mp_map_elem_t pimoroni_bus_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pimoroni_bus) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SPIBus), (mp_obj_t)&SPIPins_type }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SPISlot), (mp_obj_t)&SPISlot_type }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ParallelBus), (mp_obj_t)&ParallelPins_type }, +}; +STATIC MP_DEFINE_CONST_DICT(mp_module_pimoroni_bus_globals, pimoroni_bus_globals_table); + +const mp_obj_module_t pimoroni_bus_user_cmodule = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_pimoroni_bus_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_pimoroni_bus, pimoroni_bus_user_cmodule, MODULE_PIMORONI_BUS_ENABLED); \ No newline at end of file diff --git a/micropython/modules/pimoroni_bus/pimoroni_bus.cpp b/micropython/modules/pimoroni_bus/pimoroni_bus.cpp new file mode 100644 index 00000000..170fd72e --- /dev/null +++ b/micropython/modules/pimoroni_bus/pimoroni_bus.cpp @@ -0,0 +1,114 @@ +#include "common/pimoroni_bus.hpp" +#include "micropython/modules/util.hpp" +#include + +using namespace pimoroni; + +extern "C" { +#include "pimoroni_bus.h" +#include "py/mperrno.h" + +void PimoroniBus_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + _PimoroniBus_obj_t *self = MP_OBJ_TO_PTR2(self_in, _PimoroniBus_obj_t); + if(self->base.type == &SPIPins_type) { + mp_print_str(print, "SPIBus()"); + } else { + mp_print_str(print, "ParallelBus()"); + } + (void)kind; +} + +mp_obj_t SPIPins_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_cs, ARG_dc, ARG_sck, ARG_mosi, ARG_bl }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_cs, MP_ARG_INT, {.u_int = SPI_BG_FRONT_CS} }, + { MP_QSTR_dc, MP_ARG_INT, {.u_int = SPI_DEFAULT_MISO} }, + { MP_QSTR_sck, MP_ARG_INT, {.u_int = SPI_DEFAULT_SCK} }, + { MP_QSTR_mosi, MP_ARG_INT, {.u_int = SPI_DEFAULT_MOSI} }, + { MP_QSTR_bl, MP_ARG_INT, {.u_int = SPI_BG_FRONT_PWM} }, + }; + + // Parse args. + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + _PimoroniBus_obj_t *self = m_new_obj(_PimoroniBus_obj_t); + self->base.type = &SPIPins_type; + self->pins = m_new(SPIPins, 1); + + SPIPins *pins = (SPIPins *)self->pins; + + pins->spi = ((args[ARG_sck].u_int >> 3) & 0b1) == 0 ? spi0 : spi1; + pins->cs = (uint)args[ARG_cs].u_int; + pins->sck = (uint)args[ARG_sck].u_int; + pins->mosi = (uint)args[ARG_mosi].u_int; + pins->miso = PIN_UNUSED; + pins->dc = (uint)args[ARG_dc].u_int; + pins->bl = args[ARG_bl].u_int == -1 ? PIN_UNUSED : (uint)args[ARG_bl].u_int; + + return MP_OBJ_FROM_PTR(self); +} + +mp_obj_t SPISlot_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_slot }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_slot, MP_ARG_INT | MP_ARG_REQUIRED }, + }; + + // Parse args. + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + _PimoroniBus_obj_t *self = m_new_obj(_PimoroniBus_obj_t); + self->base.type = &SPIPins_type; + //self->pins = m_new(SPIPins, 1); + + //SPIPins *pins = (SPIPins *)self->pins; + + SPIPins slot_pins = get_spi_pins((BG_SPI_SLOT)args[ARG_slot].u_int); + + self->pins = new(m_new(SPIPins, 1)) SPIPins(slot_pins); + + /* pins->spi = slot_pins.spi; + pins->cs = slot_pins.cs; + pins->sck = slot_pins.sck; + pins->mosi = slot_pins.mosi; + pins->miso = slot_pins.miso; + pins->dc = slot_pins.dc; + pins->bl = slot_pins.bl;*/ + + return MP_OBJ_FROM_PTR(self); +} + +mp_obj_t ParallelPins_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_cs, ARG_dc, ARG_wr_sck, ARG_rd_sck, ARG_d0, ARG_bl }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_cs, MP_ARG_INT, {.u_int = 10} }, + { MP_QSTR_dc, MP_ARG_INT, {.u_int = 11} }, + { MP_QSTR_wr_sck, MP_ARG_INT, {.u_int = 12} }, + { MP_QSTR_rd_sck, MP_ARG_INT, {.u_int = 13} }, + { MP_QSTR_d0, MP_ARG_INT, {.u_int = 14} }, + { MP_QSTR_bl, MP_ARG_INT, {.u_int = 2} }, + }; + + // Parse args. + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + _PimoroniBus_obj_t *self = m_new_obj(_PimoroniBus_obj_t); + self->base.type = &ParallelPins_type; + self->pins = m_new(ParallelPins, 1); + + ParallelPins *pins = (ParallelPins *)self->pins; + + pins->cs = (uint)args[ARG_cs].u_int; + pins->dc = (uint)args[ARG_dc].u_int; + pins->wr_sck = (uint)args[ARG_wr_sck].u_int; + pins->rd_sck = (uint)args[ARG_rd_sck].u_int; + pins->d0 = (uint)args[ARG_d0].u_int; + pins->bl = args[ARG_bl].u_int == -1 ? PIN_UNUSED : (uint)args[ARG_bl].u_int; + + return MP_OBJ_FROM_PTR(self); +} + +} \ No newline at end of file diff --git a/micropython/modules/pimoroni_bus/pimoroni_bus.h b/micropython/modules/pimoroni_bus/pimoroni_bus.h new file mode 100644 index 00000000..1ab4413b --- /dev/null +++ b/micropython/modules/pimoroni_bus/pimoroni_bus.h @@ -0,0 +1,15 @@ +#include "py/runtime.h" +#include "hardware/spi.h" + +extern const mp_obj_type_t SPIPins_type; +extern const mp_obj_type_t ParallelPins_type; + +typedef struct _PimoroniBus_obj_t { + mp_obj_base_t base; + void *pins; +} _PimoroniBus_obj_t; + +extern void PimoroniBus_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); +extern mp_obj_t SPIPins_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 SPISlot_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 ParallelPins_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args); \ No newline at end of file diff --git a/micropython/modules/st7789/st7789.c b/micropython/modules/st7789/st7789.c index bdfff890..243cf10b 100644 --- a/micropython/modules/st7789/st7789.c +++ b/micropython/modules/st7789/st7789.c @@ -73,26 +73,10 @@ const mp_obj_type_t GenericST7789_type = { .locals_dict = (mp_obj_dict_t*)&GenericST7789_locals_dict, }; -const mp_obj_type_t GenericST7789Parallel_type = { - { &mp_type_type }, - .name = MP_QSTR_st7789, - .make_new = GenericST7789Parallel_make_new, - .locals_dict = (mp_obj_dict_t*)&GenericST7789_locals_dict, -}; - -const mp_obj_type_t GenericST7789SPI_type = { - { &mp_type_type }, - .name = MP_QSTR_st7789, - .make_new = GenericST7789SPI_make_new, - .locals_dict = (mp_obj_dict_t*)&GenericST7789_locals_dict, -}; - /***** Module Globals *****/ STATIC const mp_map_elem_t st7789_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_st7789) }, { MP_ROM_QSTR(MP_QSTR_ST7789), (mp_obj_t)&GenericST7789_type }, - { MP_ROM_QSTR(MP_QSTR_ST7789Parallel), (mp_obj_t)&GenericST7789Parallel_type }, - { MP_ROM_QSTR(MP_QSTR_ST7789SPI), (mp_obj_t)&GenericST7789Parallel_type }, { MP_ROM_QSTR(MP_QSTR_RGB332), MP_ROM_PTR(&GenericST7789_module_RGB332_obj) }, { MP_ROM_QSTR(MP_QSTR_RGB565), MP_ROM_PTR(&GenericST7789_module_RGB565_obj) }, diff --git a/micropython/modules/st7789/st7789.cpp b/micropython/modules/st7789/st7789.cpp index 25dcaa8b..0e7efb34 100644 --- a/micropython/modules/st7789/st7789.cpp +++ b/micropython/modules/st7789/st7789.cpp @@ -10,6 +10,7 @@ using namespace pimoroni; extern "C" { #include "st7789.h" +#include "micropython/modules/pimoroni_bus/pimoroni_bus.h" enum ST7789Display { DISPLAY_LCD_240X240=0, @@ -30,11 +31,11 @@ typedef struct _GenericST7789_obj_t { mp_obj_t GenericST7789_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { GenericST7789_obj_t *self = nullptr; - enum { ARG_display, ARG_rotate, ARG_slot, ARG_buffer }; + enum { ARG_display, ARG_rotate, ARG_bus, ARG_buffer }; static const mp_arg_t allowed_args[] = { { MP_QSTR_display, MP_ARG_INT | MP_ARG_REQUIRED }, { MP_QSTR_rotate, MP_ARG_INT, { .u_int = Rotation::ROTATE_0 } }, - { MP_QSTR_slot, MP_ARG_INT, { .u_int = 0 } }, + { MP_QSTR_bus, MP_ARG_OBJ, { .u_obj = mp_const_none } }, { MP_QSTR_buffer, MP_ARG_OBJ, { .u_obj = mp_const_none } }, }; @@ -86,141 +87,26 @@ mp_obj_t GenericST7789_make_new(const mp_obj_type_t *type, size_t n_args, size_t self->buffer = m_new(uint8_t, width * height * sizeof(Pen)); } - if (display == DISPLAY_TUFTY_2040) { - self->st7789 = m_new_class(ST7789Generic, width, height, rotate, self->buffer, {10, 11, 12, 13, 14, 2}); - } else { - BG_SPI_SLOT slot = (BG_SPI_SLOT)args[ARG_slot].u_int; - self->st7789 = m_new_class(ST7789Generic, width, height, rotate, round, self->buffer, get_spi_pins(slot)); - } - - return MP_OBJ_FROM_PTR(self); -} - -mp_obj_t GenericST7789SPI_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - GenericST7789_obj_t *self = nullptr; - - enum { ARG_width, ARG_height, ARG_rotate, ARG_round, ARG_buffer, ARG_spi, ARG_cs, ARG_dc, ARG_sck, ARG_mosi, ARG_bl }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_width, MP_ARG_REQUIRED | MP_ARG_INT }, - { MP_QSTR_height, MP_ARG_REQUIRED | MP_ARG_INT }, - { MP_QSTR_rotate, MP_ARG_INT, {.u_int = Rotation::ROTATE_0} }, - { MP_QSTR_round, MP_ARG_OBJ, {.u_obj = mp_const_false} }, - { MP_QSTR_buffer, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_spi, MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_cs, MP_ARG_INT, {.u_int = pimoroni::SPI_BG_FRONT_CS} }, - { MP_QSTR_dc, MP_ARG_INT, {.u_int = pimoroni::SPI_DEFAULT_MISO} }, - { MP_QSTR_sck, MP_ARG_INT, {.u_int = pimoroni::SPI_DEFAULT_SCK} }, - { MP_QSTR_mosi, MP_ARG_INT, {.u_int = pimoroni::SPI_DEFAULT_MOSI} }, - { MP_QSTR_bl, MP_ARG_INT, {.u_int = pimoroni::SPI_BG_FRONT_PWM} }, - }; - - // Parse args. - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - self = m_new_obj(GenericST7789_obj_t); - self->base.type = &GenericST7789_type; - - bool round = args[ARG_round].u_obj == mp_const_true; - Rotation rotate = (Rotation)args[ARG_rotate].u_int; - int width = args[ARG_width].u_int; - int height = args[ARG_height].u_int; - - if (args[ARG_buffer].u_obj != mp_const_none) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_RW); - self->buffer = bufinfo.buf; - if(bufinfo.len < (size_t)(width * height * sizeof(Pen))) { - mp_raise_ValueError("Supplied buffer is too small!"); + if (args[ARG_bus].u_obj == mp_const_none) { + self->st7789 = m_new_class(ST7789Generic, width, height, rotate, self->buffer, {10, 11, 12, 13, 14, 2}); + } else if (mp_obj_is_type(args[ARG_bus].u_obj, &ParallelPins_type)) { + _PimoroniBus_obj_t *bus = (_PimoroniBus_obj_t *)MP_OBJ_TO_PTR(args[ARG_bus].u_obj); + self->st7789 = m_new_class(ST7789Generic, width, height, rotate, self->buffer, *(ParallelPins *)(bus->pins)); + } else { + mp_raise_ValueError("ParallelBus expected!"); } } else { - self->buffer = m_new(uint8_t, width * height * sizeof(Pen)); - } - - int spi_id = args[ARG_spi].u_int; - - // Get SPI bus. - SPIPins bus_pins = { - nullptr, - (uint)args[ARG_cs].u_int, - (uint)args[ARG_sck].u_int, - (uint)args[ARG_mosi].u_int, - (uint)args[ARG_dc].u_int, - args[ARG_bl].u_int == -1 ? PIN_UNUSED : (uint)args[ARG_bl].u_int - }; - - if(spi_id == -1) { - spi_id = (bus_pins.sck >> 3) & 0b1; // If no spi specified, choose the one for the given SCK pin - } - if(spi_id < 0 || spi_id > 1) { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SPI(%d) doesn't exist"), spi_id); - } - - if(!IS_VALID_SCK(spi_id, (int)bus_pins.sck)) { - mp_raise_ValueError(MP_ERROR_TEXT("bad SCK pin")); - } - - if(!IS_VALID_MOSI(spi_id, (int)bus_pins.mosi)) { - mp_raise_ValueError(MP_ERROR_TEXT("bad MOSI pin")); - } - - bus_pins.spi = (spi_id == 0) ? spi0 : spi1; - - self->st7789 = m_new_class(ST7789Generic, width, height, rotate, round, self->buffer, bus_pins); - - return MP_OBJ_FROM_PTR(self); -} - -mp_obj_t GenericST7789Parallel_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - enum { ARG_width, ARG_height, ARG_cs, ARG_dc, ARG_wr_sck, ARG_rd_sck, ARG_d0, ARG_bl, ARG_rotate, ARG_buffer }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_width, MP_ARG_REQUIRED | MP_ARG_INT }, - { MP_QSTR_height, MP_ARG_REQUIRED | MP_ARG_INT }, - { MP_QSTR_cs, MP_ARG_INT, {.u_int = 10} }, - { MP_QSTR_dc, MP_ARG_INT, {.u_int = 11} }, - { MP_QSTR_wr_sck, MP_ARG_INT, {.u_int = 12} }, - { MP_QSTR_rd_sck, MP_ARG_INT, {.u_int = 13} }, - { MP_QSTR_d0, MP_ARG_INT, {.u_int = 14} }, - - { MP_QSTR_bl, MP_ARG_INT, {.u_int = 2} }, - { MP_QSTR_rotate, MP_ARG_INT, {.u_int = Rotation::ROTATE_0} }, - { MP_QSTR_buffer, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - }; - - // Parse args. - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - GenericST7789_obj_t *self = m_new_obj(GenericST7789_obj_t); - self->base.type = &GenericST7789_type; - - Rotation rotate = (Rotation)args[ARG_rotate].u_int; - int width = args[ARG_width].u_int; - int height = args[ARG_height].u_int; - - if (args[ARG_buffer].u_obj != mp_const_none) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_RW); - self->buffer = bufinfo.buf; - if(bufinfo.len < (size_t)(width * height)) { - mp_raise_ValueError("Supplied buffer is too small!"); + if (args[ARG_bus].u_obj == mp_const_none) { + self->st7789 = m_new_class(ST7789Generic, width, height, rotate, round, self->buffer, get_spi_pins(BG_SPI_FRONT)); + } else if (mp_obj_is_type(args[ARG_bus].u_obj, &SPIPins_type)) { + _PimoroniBus_obj_t *bus = (_PimoroniBus_obj_t *)MP_OBJ_TO_PTR(args[ARG_bus].u_obj); + self->st7789 = m_new_class(ST7789Generic, width, height, rotate, round, self->buffer, *(SPIPins *)(bus->pins)); + } else { + mp_raise_ValueError("SPIBus expected!"); } - } else { - self->buffer = m_new(uint8_t, width * height); } - ParallelPins bus_pins = { - (uint)args[ARG_cs].u_int, - (uint)args[ARG_dc].u_int, - (uint)args[ARG_wr_sck].u_int, - (uint)args[ARG_rd_sck].u_int, - (uint)args[ARG_d0].u_int, - args[ARG_bl].u_int == -1 ? PIN_UNUSED : (uint)args[ARG_bl].u_int - }; - - self->st7789 = m_new_class(ST7789Generic, width, height, rotate, self->buffer, bus_pins); - return MP_OBJ_FROM_PTR(self); }