kopia lustrzana https://github.com/pimoroni/pimoroni-pico
ST7789: Experimental 8bit framebuffer.
rodzic
446db105f9
commit
7abe4aae7f
|
@ -88,7 +88,7 @@ namespace pimoroni {
|
|||
configure_display(false);
|
||||
|
||||
if(bl != PIN_UNUSED) {
|
||||
update(); // Send the new buffer to the display to clear any previous content
|
||||
//update(); // Send the new buffer to the display to clear any previous content
|
||||
sleep_ms(50); // Wait for the update to apply
|
||||
set_backlight(255); // Turn backlight on now surprises have passed
|
||||
}
|
||||
|
@ -219,8 +219,24 @@ namespace pimoroni {
|
|||
gpio_put(cs, 1);
|
||||
}
|
||||
|
||||
void ST7789::update() {
|
||||
command(reg::RAMWR, width * height * sizeof(uint16_t), (const char*)frame_buffer);
|
||||
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
|
||||
gpio_put(cs, 0);
|
||||
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]];
|
||||
}
|
||||
if(spi) {
|
||||
spi_write_blocking(spi, (const uint8_t*)row, width * sizeof(uint16_t));
|
||||
} else {
|
||||
write_blocking_parallel((const uint8_t*)row, width * sizeof(uint16_t));
|
||||
}
|
||||
}
|
||||
gpio_put(cs, 1);
|
||||
}
|
||||
|
||||
void ST7789::set_backlight(uint8_t brightness) {
|
||||
|
|
|
@ -36,10 +36,10 @@ namespace pimoroni {
|
|||
|
||||
public:
|
||||
// frame buffer where pixel data is stored
|
||||
uint16_t *frame_buffer;
|
||||
uint8_t *frame_buffer;
|
||||
|
||||
// Parallel init
|
||||
ST7789(uint16_t width, uint16_t height, uint16_t *frame_buffer,
|
||||
ST7789(uint16_t width, uint16_t height, uint8_t *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, uint16_t *frame_buffer,
|
||||
ST7789(uint16_t width, uint16_t height, bool round, uint8_t *frame_buffer,
|
||||
spi_inst_t *spi,
|
||||
uint cs, uint dc, uint sck, uint mosi, uint bl = PIN_UNUSED) :
|
||||
spi(spi),
|
||||
|
@ -101,7 +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();
|
||||
|
||||
|
@ -133,7 +133,7 @@ namespace pimoroni {
|
|||
void write_blocking_parallel(const uint8_t *src, size_t len);
|
||||
void common_init() {
|
||||
if(!this->frame_buffer) {
|
||||
this->frame_buffer = new uint16_t[width * height];
|
||||
this->frame_buffer = new uint8_t[width * height];
|
||||
}
|
||||
|
||||
// if a backlight pin is provided then set it up for
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace pimoroni {
|
|||
}
|
||||
|
||||
void ST7789Generic::update() {
|
||||
st7789.update();
|
||||
st7789.update(palette);
|
||||
}
|
||||
|
||||
void ST7789Generic::flip() {
|
||||
|
|
|
@ -10,34 +10,34 @@ namespace pimoroni {
|
|||
ST7789 st7789;
|
||||
|
||||
public:
|
||||
ST7789Generic(uint16_t width, uint16_t height, bool round=false, uint16_t *frame_buffer=nullptr) :
|
||||
ST7789Generic(uint16_t width, uint16_t height, bool round=false, uint8_t *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 = st7789.frame_buffer;
|
||||
this->frame_buffer = (Pen *)st7789.frame_buffer;
|
||||
this->st7789.init();
|
||||
};
|
||||
|
||||
ST7789Generic(uint16_t width, uint16_t height, bool round, uint16_t *frame_buffer, BG_SPI_SLOT slot) :
|
||||
ST7789Generic(uint16_t width, uint16_t height, bool round, uint8_t *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 = st7789.frame_buffer;
|
||||
this->frame_buffer = (Pen *)st7789.frame_buffer;
|
||||
this->st7789.init();
|
||||
};
|
||||
|
||||
ST7789Generic(uint16_t width, uint16_t height, bool round, uint16_t *frame_buffer,
|
||||
ST7789Generic(uint16_t width, uint16_t height, bool round, uint8_t *frame_buffer,
|
||||
spi_inst_t *spi,
|
||||
uint cs, uint dc, uint sck, uint mosi, uint bl = PIN_UNUSED) :
|
||||
PicoGraphics(width, height, frame_buffer),
|
||||
st7789(width, height, round, frame_buffer, spi, cs, dc, sck, mosi, bl) {
|
||||
this->frame_buffer = st7789.frame_buffer;
|
||||
this->frame_buffer = (Pen *)st7789.frame_buffer;
|
||||
this->st7789.init();
|
||||
};
|
||||
|
||||
ST7789Generic(uint16_t width, uint16_t height, uint16_t *frame_buffer,
|
||||
ST7789Generic(uint16_t width, uint16_t height, uint8_t *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) {
|
||||
this->frame_buffer = st7789.frame_buffer;
|
||||
this->frame_buffer = (Pen *)st7789.frame_buffer;
|
||||
this->st7789.init();
|
||||
};
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ const uint8_t MOTOR2P = 11;
|
|||
|
||||
namespace pimoroni {
|
||||
|
||||
PicoExplorer::PicoExplorer(uint16_t *buf)
|
||||
PicoExplorer::PicoExplorer(uint8_t *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;
|
||||
|
@ -52,7 +52,7 @@ namespace pimoroni {
|
|||
}
|
||||
|
||||
void PicoExplorer::update() {
|
||||
screen.update();
|
||||
screen.update(palette);
|
||||
}
|
||||
|
||||
bool PicoExplorer::is_pressed(uint8_t button) {
|
||||
|
|
|
@ -34,13 +34,13 @@ namespace pimoroni {
|
|||
static const uint GP6 = 6;
|
||||
static const uint GP7 = 7;
|
||||
|
||||
uint16_t *__fb;
|
||||
uint8_t *__fb;
|
||||
private:
|
||||
ST7789 screen;
|
||||
int8_t audio_pin = -1;
|
||||
|
||||
public:
|
||||
PicoExplorer(uint16_t *buf);
|
||||
PicoExplorer(uint8_t *buf);
|
||||
|
||||
void init();
|
||||
void update();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "pico_graphics.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
PicoGraphics::PicoGraphics(uint16_t width, uint16_t height, uint16_t *frame_buffer)
|
||||
: frame_buffer(frame_buffer), bounds(0, 0, width, height), clip(0, 0, width, height) {
|
||||
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);
|
||||
};
|
||||
|
||||
|
@ -18,6 +18,21 @@ namespace pimoroni {
|
|||
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;
|
||||
};
|
||||
}
|
||||
|
||||
if(palette_ptr < 256) {
|
||||
palette[palette_ptr] = p;
|
||||
pen = palette_ptr;
|
||||
palette_ptr += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void PicoGraphics::set_clip(const Rect &r) {
|
||||
clip = bounds.intersection(r);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
// supports only 16-bit (565) RGB framebuffers
|
||||
namespace pimoroni {
|
||||
|
||||
typedef uint16_t Pen;
|
||||
typedef uint8_t Pen;
|
||||
|
||||
struct Rect;
|
||||
|
||||
|
@ -45,7 +45,7 @@ namespace pimoroni {
|
|||
|
||||
class PicoGraphics {
|
||||
public:
|
||||
uint16_t *frame_buffer;
|
||||
Pen *frame_buffer;
|
||||
|
||||
Rect bounds;
|
||||
Rect clip;
|
||||
|
@ -54,18 +54,32 @@ namespace pimoroni {
|
|||
|
||||
const bitmap::font_t *font;
|
||||
|
||||
uint16_t palette[256];
|
||||
uint16_t palette_ptr = 0;
|
||||
|
||||
public:
|
||||
PicoGraphics(uint16_t width, uint16_t height, uint16_t *frame_buffer);
|
||||
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) {
|
||||
uint16_t p = ((r & 0b11111000) << 8) |
|
||||
((g & 0b11111100) << 3) |
|
||||
((b & 0b11111000) >> 3);
|
||||
|
||||
return __builtin_bswap16(p);
|
||||
p = __builtin_bswap16(p);
|
||||
|
||||
for(auto i=0u; i < palette_ptr; i++) {
|
||||
if(palette[i] == p) return i;
|
||||
}
|
||||
|
||||
if(palette_ptr < 256) {
|
||||
palette[palette_ptr] = p;
|
||||
palette_ptr += 1;
|
||||
}
|
||||
return palette_ptr - 1;
|
||||
};
|
||||
|
||||
void set_clip(const Rect &r);
|
||||
|
|
|
@ -27,7 +27,7 @@ mp_obj_t picoexplorer_init(mp_obj_t buf_obj) {
|
|||
}
|
||||
|
||||
// Create a new display pointing to the newly provided buffer
|
||||
explorer = new PicoExplorer((uint16_t *)bufinfo.buf);
|
||||
explorer = new PicoExplorer((uint8_t *)bufinfo.buf);
|
||||
explorer->init();
|
||||
|
||||
return mp_const_none;
|
||||
|
|
|
@ -14,7 +14,7 @@ typedef struct _GenericST7789_obj_t {
|
|||
mp_obj_base_t base;
|
||||
ST7789Generic *st7789;
|
||||
bool parallel;
|
||||
uint16_t *buffer;
|
||||
uint8_t *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 = (uint16_t *)bufinfo.buf;
|
||||
if(bufinfo.len < (size_t)(width * height * 2)) {
|
||||
self->buffer = (uint8_t *)bufinfo.buf;
|
||||
if(bufinfo.len < (size_t)(width * height)) {
|
||||
mp_raise_ValueError("Supplied buffer is too small!");
|
||||
}
|
||||
} else {
|
||||
self->buffer = m_new(uint16_t, width * height);
|
||||
self->buffer = m_new(uint8_t, width * height);
|
||||
}
|
||||
|
||||
if(args[ARG_slot].u_int != -1) {
|
||||
|
@ -166,12 +166,12 @@ mp_obj_t GenericST7789Parallel_make_new(const mp_obj_type_t *type, size_t n_args
|
|||
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 = (uint16_t *)bufinfo.buf;
|
||||
if(bufinfo.len < (size_t)(width * height * 2)) {
|
||||
self->buffer = (uint8_t *)bufinfo.buf;
|
||||
if(bufinfo.len < (size_t)(width * height)) {
|
||||
mp_raise_ValueError("Supplied buffer is too small!");
|
||||
}
|
||||
} else {
|
||||
self->buffer = m_new(uint16_t, width * height);
|
||||
self->buffer = m_new(uint8_t, width * height);
|
||||
}
|
||||
|
||||
int cs = args[ARG_cs].u_int;
|
||||
|
@ -187,6 +187,8 @@ mp_obj_t GenericST7789Parallel_make_new(const mp_obj_type_t *type, size_t n_args
|
|||
self->st7789->configure_display(true);
|
||||
}
|
||||
|
||||
mp_printf(&mp_plat_print, "ST7789Generic - %lu\n", sizeof(ST7789Generic));
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
|
@ -223,10 +225,11 @@ 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 };
|
||||
enum { ARG_self, ARG_pen, ARG_raw };
|
||||
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)];
|
||||
|
@ -236,10 +239,19 @@ 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(pen < 0 || pen > 0xffff)
|
||||
mp_raise_ValueError("p is not a valid pen.");
|
||||
else
|
||||
self->st7789->set_pen(pen);
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
if(pen < 0 || pen > 0xffff) {
|
||||
mp_raise_ValueError("p is not a valid pen.");
|
||||
} else {
|
||||
self->st7789->set_pen_raw(pen);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
enum { ARG_self, ARG_r, ARG_g, ARG_b };
|
||||
|
|
Ładowanie…
Reference in New Issue