ST7789/PicoDisplay: Collapse make_new into one using pimoroni_bus.

driver/sh1107
Phil Howard 2022-05-28 23:00:43 +01:00
rodzic 38efc7de62
commit 13f0813d8a
11 zmienionych plików z 194 dodań i 155 usunięć

Wyświetl plik

@ -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};
};
}

Wyświetl plik

@ -10,6 +10,7 @@ namespace pimoroni {
uint sck;
uint mosi;
uint miso;
uint dc;
uint bl;
};

Wyświetl plik

@ -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;

Wyświetl plik

@ -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);

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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);

Wyświetl plik

@ -0,0 +1,114 @@
#include "common/pimoroni_bus.hpp"
#include "micropython/modules/util.hpp"
#include <cstdio>
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);
}
}

Wyświetl plik

@ -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);

Wyświetl plik

@ -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) },

Wyświetl plik

@ -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);
}