diff --git a/drivers/st7789/st7789.cpp b/drivers/st7789/st7789.cpp index eb23f7e1..089f1cd4 100644 --- a/drivers/st7789/st7789.cpp +++ b/drivers/st7789/st7789.cpp @@ -219,8 +219,13 @@ namespace pimoroni { gpio_put(cs, 1); } + // Native 16-bit framebuffer update + void ST7789::update() { + command(reg::RAMWR, width * height * sizeof(uint16_t), (const char*)frame_buffer); + } + + // 8-bit framebuffer with palette conversion update void ST7789::update(uint16_t *palette) { - //command(reg::RAMWR, width * height * sizeof(uint16_t), (const char*)frame_buffer); command(reg::RAMWR); uint16_t row[width]; gpio_put(dc, 1); // data mode @@ -228,8 +233,9 @@ namespace pimoroni { for(auto y = 0u; y < height; y++) { for(auto x = 0u; x < width; x++) { auto i = y * width + x; - row[x] = palette[frame_buffer[i]]; + row[x] = palette[((uint8_t *)frame_buffer)[i]]; } + // TODO: Add DMA->SPI / PIO while we prep the next row if(spi) { spi_write_blocking(spi, (const uint8_t*)row, width * sizeof(uint16_t)); } else { diff --git a/drivers/st7789/st7789.hpp b/drivers/st7789/st7789.hpp index d74d65b4..df15d747 100644 --- a/drivers/st7789/st7789.hpp +++ b/drivers/st7789/st7789.hpp @@ -36,10 +36,10 @@ namespace pimoroni { public: // frame buffer where pixel data is stored - uint8_t *frame_buffer; + void *frame_buffer; // Parallel init - ST7789(uint16_t width, uint16_t height, uint8_t *frame_buffer, + ST7789(uint16_t width, uint16_t height, void *frame_buffer, uint cs, uint dc, uint wr_sck, uint rd_sck, uint d0, uint bl = PIN_UNUSED) : spi(nullptr), width(width), height(height), round(false), @@ -68,7 +68,7 @@ namespace pimoroni { } // Serial init - ST7789(uint16_t width, uint16_t height, bool round, uint8_t *frame_buffer, + ST7789(uint16_t width, uint16_t height, bool round, void *frame_buffer, spi_inst_t *spi, uint cs, uint dc, uint sck, uint mosi, uint bl = PIN_UNUSED) : spi(spi), @@ -101,6 +101,7 @@ namespace pimoroni { uint get_bl() const; void command(uint8_t command, size_t len = 0, const char *data = NULL); + void update(); void update(uint16_t *palette); void set_backlight(uint8_t brightness); void flip(); diff --git a/libraries/generic_st7789/generic_st7789.hpp b/libraries/generic_st7789/generic_st7789.hpp index e1157ee9..4ccebd0a 100644 --- a/libraries/generic_st7789/generic_st7789.hpp +++ b/libraries/generic_st7789/generic_st7789.hpp @@ -10,21 +10,21 @@ namespace pimoroni { ST7789 st7789; public: - ST7789Generic(uint16_t width, uint16_t height, bool round=false, uint8_t *frame_buffer=nullptr) : + ST7789Generic(uint16_t width, uint16_t height, bool round=false, void *frame_buffer=nullptr) : PicoGraphics(width, height, frame_buffer), st7789(width, height, round, frame_buffer, PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_MISO, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, SPI_BG_FRONT_PWM) { this->frame_buffer = (Pen *)st7789.frame_buffer; this->st7789.init(); }; - ST7789Generic(uint16_t width, uint16_t height, bool round, uint8_t *frame_buffer, BG_SPI_SLOT slot) : + ST7789Generic(uint16_t width, uint16_t height, bool round, void *frame_buffer, BG_SPI_SLOT slot) : PicoGraphics(width, height, frame_buffer), st7789(width, height, round, frame_buffer, PIMORONI_SPI_DEFAULT_INSTANCE, st7789.get_slot_cs(slot), SPI_DEFAULT_MISO, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, st7789.get_slot_bl(slot)) { this->frame_buffer = (Pen *)st7789.frame_buffer; this->st7789.init(); }; - ST7789Generic(uint16_t width, uint16_t height, bool round, uint8_t *frame_buffer, + ST7789Generic(uint16_t width, uint16_t height, bool round, void *frame_buffer, spi_inst_t *spi, uint cs, uint dc, uint sck, uint mosi, uint bl = PIN_UNUSED) : PicoGraphics(width, height, frame_buffer), @@ -33,7 +33,7 @@ namespace pimoroni { this->st7789.init(); }; - ST7789Generic(uint16_t width, uint16_t height, uint8_t *frame_buffer, + ST7789Generic(uint16_t width, uint16_t height, void *frame_buffer, uint cs, uint dc, uint wr_sck, uint rd_sck, uint d0, uint bl = PIN_UNUSED) : PicoGraphics(width, height, frame_buffer), st7789(width, height, frame_buffer, cs, dc, wr_sck, rd_sck, d0, bl) { diff --git a/libraries/pico_display/pico_display.cpp b/libraries/pico_display/pico_display.cpp index d8d6ac2f..4b5cee47 100644 --- a/libraries/pico_display/pico_display.cpp +++ b/libraries/pico_display/pico_display.cpp @@ -8,13 +8,13 @@ namespace pimoroni { - PicoDisplay::PicoDisplay(uint16_t *buf) + PicoDisplay::PicoDisplay(void *buf) : PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, false, buf, PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_MISO, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, SPI_BG_FRONT_PWM) { __fb = buf; } - PicoDisplay::PicoDisplay(uint16_t *buf, int width, int height) + PicoDisplay::PicoDisplay(void *buf, int width, int height) : PicoGraphics(width, height, buf), screen(width, height, false, buf, PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_MISO, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, SPI_BG_FRONT_PWM) { __fb = buf; diff --git a/libraries/pico_display/pico_display.hpp b/libraries/pico_display/pico_display.hpp index 17bb65a6..fea52674 100644 --- a/libraries/pico_display/pico_display.hpp +++ b/libraries/pico_display/pico_display.hpp @@ -19,13 +19,13 @@ namespace pimoroni { static const uint8_t LED_G = 7; static const uint8_t LED_B = 8; - uint16_t *__fb; + void *__fb; private: ST7789 screen; public: - PicoDisplay(uint16_t *buf); - PicoDisplay(uint16_t *buf, int width, int height); + PicoDisplay(void *buf); + PicoDisplay(void *buf, int width, int height); void init(); void update(); diff --git a/libraries/pico_display_2/pico_display_2.cpp b/libraries/pico_display_2/pico_display_2.cpp index 4738433f..969df230 100644 --- a/libraries/pico_display_2/pico_display_2.cpp +++ b/libraries/pico_display_2/pico_display_2.cpp @@ -8,13 +8,13 @@ namespace pimoroni { - PicoDisplay2::PicoDisplay2(uint16_t *buf) + PicoDisplay2::PicoDisplay2(void *buf) : PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, false, buf, PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_MISO, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, SPI_BG_FRONT_PWM) { __fb = buf; } - PicoDisplay2::PicoDisplay2(uint16_t *buf, int width, int height) + PicoDisplay2::PicoDisplay2(void *buf, int width, int height) : PicoGraphics(width, height, buf), screen(width, height, false, buf, PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_MISO, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, SPI_BG_FRONT_PWM) { __fb = buf; diff --git a/libraries/pico_display_2/pico_display_2.hpp b/libraries/pico_display_2/pico_display_2.hpp index 67ceb52c..769b983f 100644 --- a/libraries/pico_display_2/pico_display_2.hpp +++ b/libraries/pico_display_2/pico_display_2.hpp @@ -19,13 +19,13 @@ namespace pimoroni { static const uint8_t LED_G = 7; static const uint8_t LED_B = 8; - uint16_t *__fb; + void *__fb; private: ST7789 screen; public: - PicoDisplay2(uint16_t *buf); - PicoDisplay2(uint16_t *buf, int width, int height); + PicoDisplay2(void *buf); + PicoDisplay2(void *buf, int width, int height); void init(); void update(); diff --git a/libraries/pico_explorer/pico_explorer.cpp b/libraries/pico_explorer/pico_explorer.cpp index a29b9ae2..946935a2 100644 --- a/libraries/pico_explorer/pico_explorer.cpp +++ b/libraries/pico_explorer/pico_explorer.cpp @@ -14,7 +14,7 @@ const uint8_t MOTOR2P = 11; namespace pimoroni { - PicoExplorer::PicoExplorer(uint8_t *buf) + PicoExplorer::PicoExplorer(void *buf) : PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, false, buf, PIMORONI_SPI_DEFAULT_INSTANCE, screen.get_slot_cs(PICO_EXPLORER_ONBOARD), SPI_DEFAULT_MISO, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, screen.get_slot_bl(PICO_EXPLORER_ONBOARD)) { __fb = buf; diff --git a/libraries/pico_explorer/pico_explorer.hpp b/libraries/pico_explorer/pico_explorer.hpp index ab0504b3..13933204 100644 --- a/libraries/pico_explorer/pico_explorer.hpp +++ b/libraries/pico_explorer/pico_explorer.hpp @@ -34,13 +34,13 @@ namespace pimoroni { static const uint GP6 = 6; static const uint GP7 = 7; - uint8_t *__fb; + void *__fb; private: ST7789 screen; int8_t audio_pin = -1; public: - PicoExplorer(uint8_t *buf); + PicoExplorer(void *buf); void init(); void update(); diff --git a/libraries/pico_graphics/pico_graphics.cpp b/libraries/pico_graphics/pico_graphics.cpp index cd28831d..d5e62871 100644 --- a/libraries/pico_graphics/pico_graphics.cpp +++ b/libraries/pico_graphics/pico_graphics.cpp @@ -4,6 +4,7 @@ namespace pimoroni { PicoGraphics::PicoGraphics(uint16_t width, uint16_t height, void *frame_buffer) : frame_buffer((Pen *)frame_buffer), bounds(0, 0, width, height), clip(0, 0, width, height) { set_font(&font6); + default_palette(); }; void PicoGraphics::set_font(const bitmap::font_t *font){ @@ -11,28 +12,36 @@ namespace pimoroni { } void PicoGraphics::set_pen(uint8_t r, uint8_t g, uint8_t b) { - pen = create_pen(r, g, b); + pen = put_palette(create_pen_rgb332(r, g, b)); } void PicoGraphics::set_pen(Pen p) { pen = p; } - void PicoGraphics::set_pen_raw(uint16_t p) { - for(auto i=0u; i < palette_ptr; i++) { - if(palette[i] == p) { - pen = i; - return; - }; - } + uint16_t PicoGraphics::get_palette(uint8_t i) { + return palette[i]; + } - if(palette_ptr < 256) { - palette[palette_ptr] = p; - pen = palette_ptr; - palette_ptr += 1; + void PicoGraphics::put_palette(uint16_t p, uint8_t i) { + palette[i] = p; + if (i > palette_entries) { + palette_entries = i; } } + uint8_t PicoGraphics::put_palette(uint16_t p) { + for(auto i=0u; i < palette_entries; i++) { + if(palette[i] == p) return i; + } + + if(palette_entries < 256) { + palette[palette_entries] = p; + palette_entries += 1; + } + return palette_entries - 1; + }; + void PicoGraphics::set_clip(const Rect &r) { clip = bounds.intersection(r); } @@ -136,6 +145,10 @@ namespace pimoroni { }, t, p.x, p.y, wrap, scale); } + void PicoGraphics::measure_text(const std::string &t, uint8_t scale) { + bitmap::measure_text(font, t, scale); + } + int32_t orient2d(Point p1, Point p2, Point p3) { return (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x); } diff --git a/libraries/pico_graphics/pico_graphics.hpp b/libraries/pico_graphics/pico_graphics.hpp index 87c7cd41..c7af8f1b 100644 --- a/libraries/pico_graphics/pico_graphics.hpp +++ b/libraries/pico_graphics/pico_graphics.hpp @@ -55,32 +55,48 @@ namespace pimoroni { const bitmap::font_t *font; uint16_t palette[256]; - uint16_t palette_ptr = 0; + uint16_t palette_entries = 0; public: PicoGraphics(uint16_t width, uint16_t height, void *frame_buffer); void set_font(const bitmap::font_t *font); void set_pen(uint8_t r, uint8_t g, uint8_t b); void set_pen(Pen p); - void set_pen_raw(uint16_t p); - constexpr Pen create_pen(uint8_t r, uint8_t g, uint8_t b) { + constexpr uint16_t create_pen_rgb565(uint8_t r, uint8_t g, uint8_t b) { uint16_t p = ((r & 0b11111000) << 8) | - ((g & 0b11111100) << 3) | - ((b & 0b11111000) >> 3); + ((g & 0b11111100) << 3) | + ((b & 0b11111000) >> 3); - p = __builtin_bswap16(p); + return __builtin_bswap16(p); + } + + constexpr uint16_t create_pen_rgb332(uint8_t r, uint8_t g, uint8_t b) { + uint16_t p = ((r & 0b11100000) << 8) | + ((g & 0b11100000) << 3) | + ((b & 0b11000000) >> 3); - for(auto i=0u; i < palette_ptr; i++) { - if(palette[i] == p) return i; + return __builtin_bswap16(p); + } + + Pen create_pen(uint8_t r, uint8_t g, uint8_t b) { + return put_palette(create_pen_rgb332(r, g, b)); + } + + void flush_palette() { + palette_entries = 0; + } + + void default_palette() { + for (auto i = 0u; i < 255; i++) { + palette[i] = i; } + palette_entries = 255; + } - if(palette_ptr < 256) { - palette[palette_ptr] = p; - palette_ptr += 1; - } - return palette_ptr - 1; - }; + uint8_t put_palette(uint16_t p); + uint16_t get_palette(uint8_t i); + void put_palette(uint16_t p, uint8_t i); void set_clip(const Rect &r); void remove_clip(); @@ -96,6 +112,7 @@ namespace pimoroni { void circle(const Point &p, int32_t r); void character(const char c, const Point &p, uint8_t scale = 2); void text(const std::string &t, const Point &p, int32_t wrap, uint8_t scale = 2); + void measure_text(const std::string &t, uint8_t scale = 2); void polygon(const std::vector &points); void triangle(Point p1, Point p2, Point p3); void line(Point p1, Point p2); diff --git a/micropython/modules/pico_display/pico_display.cpp b/micropython/modules/pico_display/pico_display.cpp index c6b7650d..985ba4a4 100644 --- a/micropython/modules/pico_display/pico_display.cpp +++ b/micropython/modules/pico_display/pico_display.cpp @@ -27,7 +27,7 @@ mp_obj_t picodisplay_init(mp_obj_t buf_obj) { } // Create a new display pointing to the newly provided buffer - display = new PicoDisplay((uint16_t *)bufinfo.buf); + display = new PicoDisplay(bufinfo.buf); display->init(); return mp_const_none; diff --git a/micropython/modules/pico_display_2/pico_display_2.cpp b/micropython/modules/pico_display_2/pico_display_2.cpp index f33eb065..831407f4 100644 --- a/micropython/modules/pico_display_2/pico_display_2.cpp +++ b/micropython/modules/pico_display_2/pico_display_2.cpp @@ -27,7 +27,7 @@ mp_obj_t picodisplay2_init(mp_obj_t buf_obj) { } // Create a new display pointing to the newly provided buffer - display2 = new PicoDisplay2((uint16_t *)bufinfo.buf); + display2 = new PicoDisplay2(bufinfo.buf); display2->init(); return mp_const_none; diff --git a/micropython/modules/st7789/st7789.c b/micropython/modules/st7789/st7789.c index fcd64a95..dd6a80ab 100644 --- a/micropython/modules/st7789/st7789.c +++ b/micropython/modules/st7789/st7789.c @@ -1,6 +1,8 @@ #include "st7789.h" MP_DEFINE_CONST_FUN_OBJ_1(GenericST7789_update_obj, GenericST7789_update); +MP_DEFINE_CONST_FUN_OBJ_1(GenericST7789_flush_palette_obj, GenericST7789_flush_palette); +MP_DEFINE_CONST_FUN_OBJ_1(GenericST7789_default_palette_obj, GenericST7789_default_palette); MP_DEFINE_CONST_FUN_OBJ_KW(GenericST7789_set_backlight_obj, 1, GenericST7789_set_backlight); MP_DEFINE_CONST_FUN_OBJ_KW(GenericST7789_set_pen_obj, 1, GenericST7789_set_pen); MP_DEFINE_CONST_FUN_OBJ_KW(GenericST7789_create_pen_obj, 1, GenericST7789_create_pen); @@ -19,13 +21,15 @@ MP_DEFINE_CONST_FUN_OBJ_KW(GenericST7789_line_obj, 1, GenericST7789_line); STATIC const mp_rom_map_elem_t GenericST7789_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&GenericST7789_update_obj) }, - { MP_ROM_QSTR(MP_QSTR_set_backlight), MP_ROM_PTR(&GenericST7789_set_backlight_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel), MP_ROM_PTR(&GenericST7789_pixel_obj) }, { MP_ROM_QSTR(MP_QSTR_set_pen), MP_ROM_PTR(&GenericST7789_set_pen_obj) }, + { MP_ROM_QSTR(MP_QSTR_flush_palette), MP_ROM_PTR(&GenericST7789_flush_palette_obj) }, + { MP_ROM_QSTR(MP_QSTR_default_palette), MP_ROM_PTR(&GenericST7789_default_palette_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_backlight), MP_ROM_PTR(&GenericST7789_set_backlight_obj) }, { MP_ROM_QSTR(MP_QSTR_create_pen), MP_ROM_PTR(&GenericST7789_create_pen_obj) }, { MP_ROM_QSTR(MP_QSTR_set_clip), MP_ROM_PTR(&GenericST7789_set_clip_obj) }, { MP_ROM_QSTR(MP_QSTR_remove_clip), MP_ROM_PTR(&GenericST7789_remove_clip_obj) }, { MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&GenericST7789_clear_obj) }, - { MP_ROM_QSTR(MP_QSTR_pixel), MP_ROM_PTR(&GenericST7789_pixel_obj) }, { MP_ROM_QSTR(MP_QSTR_pixel_span), MP_ROM_PTR(&GenericST7789_pixel_span_obj) }, { MP_ROM_QSTR(MP_QSTR_rectangle), MP_ROM_PTR(&GenericST7789_rectangle_obj) }, { MP_ROM_QSTR(MP_QSTR_circle), MP_ROM_PTR(&GenericST7789_circle_obj) }, diff --git a/micropython/modules/st7789/st7789.cpp b/micropython/modules/st7789/st7789.cpp index 891f52b0..cfd1df07 100644 --- a/micropython/modules/st7789/st7789.cpp +++ b/micropython/modules/st7789/st7789.cpp @@ -14,7 +14,7 @@ typedef struct _GenericST7789_obj_t { mp_obj_base_t base; ST7789Generic *st7789; bool parallel; - uint8_t *buffer; + void *buffer; } GenericST7789_obj_t; /***** Print *****/ @@ -85,12 +85,12 @@ mp_obj_t GenericST7789_make_new(const mp_obj_type_t *type, size_t n_args, size_t 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 = (uint8_t *)bufinfo.buf; - if(bufinfo.len < (size_t)(width * height)) { + self->buffer = bufinfo.buf; + if(bufinfo.len < (size_t)(width * height * sizeof(Pen))) { mp_raise_ValueError("Supplied buffer is too small!"); } } else { - self->buffer = m_new(uint8_t, width * height); + self->buffer = m_new(uint8_t, width * height * sizeof(Pen)); } if(args[ARG_slot].u_int != -1) { @@ -200,6 +200,20 @@ mp_obj_t GenericST7789_update(mp_obj_t self_in) { return mp_const_none; } +mp_obj_t GenericST7789_flush_palette(mp_obj_t self_in) { + GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(self_in, GenericST7789_obj_t); + self->st7789->flush_palette(); + + return mp_const_none; +} + +mp_obj_t GenericST7789_default_palette(mp_obj_t self_in) { + GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(self_in, GenericST7789_obj_t); + self->st7789->default_palette(); + + return mp_const_none; +} + mp_obj_t GenericST7789_set_backlight(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_self, ARG_brightness }; static const mp_arg_t allowed_args[] = { @@ -225,11 +239,10 @@ mp_obj_t GenericST7789_set_backlight(size_t n_args, const mp_obj_t *pos_args, mp mp_obj_t GenericST7789_set_pen(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { if(n_args <= 2) { - enum { ARG_self, ARG_pen, ARG_raw }; + enum { ARG_self, ARG_pen }; static const mp_arg_t allowed_args[] = { { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_pen, MP_ARG_REQUIRED | MP_ARG_INT }, - { MP_QSTR_raw, MP_ARG_OBJ, { .u_obj = mp_const_false } }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -239,18 +252,10 @@ mp_obj_t GenericST7789_set_pen(size_t n_args, const mp_obj_t *pos_args, mp_map_t int pen = args[ARG_pen].u_int; - if (args[ARG_raw].u_obj == mp_const_false) { - if(pen < 0 || pen > 0xff) { - mp_raise_ValueError("p is not a valid pen."); - } else { - self->st7789->set_pen(pen); - } + if(pen < 0 || pen > 0xff) { + mp_raise_ValueError("p is not a valid pen."); } else { - if(pen < 0 || pen > 0xffff) { - mp_raise_ValueError("p is not a valid pen."); - } else { - self->st7789->set_pen_raw(pen); - } + self->st7789->set_pen(pen); } } else { diff --git a/micropython/modules/st7789/st7789.h b/micropython/modules/st7789/st7789.h index c72a9e4a..1d822556 100644 --- a/micropython/modules/st7789/st7789.h +++ b/micropython/modules/st7789/st7789.h @@ -11,6 +11,8 @@ extern mp_obj_t GenericST7789_make_new(const mp_obj_type_t *type, size_t n_args, extern 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); extern mp_obj_t GenericST7789_update(mp_obj_t self_in); +extern mp_obj_t GenericST7789_flush_palette(mp_obj_t self_in); +extern mp_obj_t GenericST7789_default_palette(mp_obj_t self_in); extern mp_obj_t GenericST7789_set_backlight(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); extern mp_obj_t GenericST7789_set_pen(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);