Added outline of an mpy wrapper for pico_display

This commit is contained in:
ZodiusInfuser 2021-01-20 15:59:48 +00:00
parent 87acbfa5f8
commit 75560ea038
10 changed files with 309 additions and 20 deletions

View File

@ -140,7 +140,7 @@ namespace pimoroni {
// gamma correct the provided 0-255 brightness value onto a
// 0-65535 range for the pwm counter
float gamma = 2.8;
uint16_t value = (uint16_t)(pow((float)(brightness) / 255.0f, gamma) * 65536.0f + 0.5f);
uint16_t value = (uint16_t)(pow((float)(brightness) / 255.0f, gamma) * 65535.0f + 0.5f);
pwm_set_gpio_level(bl, value);
}

View File

@ -16,11 +16,11 @@ namespace pimoroni {
uint16_t row_stride;
// interface pins with our standard defaults where appropriate
int8_t cs = 17;
int8_t dc = 16;
int8_t sck = 18;
int8_t mosi = 19;
int8_t miso = -1; // we generally don't use this pin
int8_t cs = 17;
int8_t dc = 16;
int8_t bl = 20;
int8_t vsync = -1; // only available on some products
@ -37,9 +37,9 @@ namespace pimoroni {
ST7789(uint16_t width, uint16_t height, uint16_t *frame_buffer,
spi_inst_t *spi,
uint8_t cs, uint8_t dc, uint8_t sck, uint8_t mosi, uint8_t miso = -1) :
width(width), height(height), frame_buffer(frame_buffer),
spi(spi),
cs(cs), dc(dc), sck(sck), mosi(mosi), miso(miso) {}
width(width), height(height),
cs(cs), dc(dc), sck(sck), mosi(mosi), miso(miso), frame_buffer(frame_buffer) {}
void init(bool auto_init_sequence = true);

View File

@ -70,6 +70,7 @@ void sprite(uint8_t *p, int x, int y, bool flip, uint16_t c) {
}*/
int main() {
pico_display.init();
pico_display.set_backlight(100);
// uint16_t white = pico_display.create_pen(255, 255, 255);

View File

@ -1,4 +1,5 @@
#include <math.h>
#include <string.h>
#include "hardware/pwm.h"
@ -11,8 +12,11 @@ const uint8_t LED_B = 8;
namespace pimoroni {
PicoDisplay::PicoDisplay()
: screen(240, 135, __fb), PicoGraphics(240, 135, __fb) {
: PicoGraphics(WIDTH, HEIGHT, __fb), screen(WIDTH, HEIGHT, __fb) {
memset(__fb, 0, sizeof(__fb));
}
void PicoDisplay::init() {
// setup the rgb led for pwm control
pwm_config cfg = pwm_get_default_config();
pwm_config_set_output_polarity(&cfg, true, true);
@ -42,6 +46,14 @@ namespace pimoroni {
screen.init();
}
void PicoDisplay::update() {
screen.update();
}
void PicoDisplay::set_backlight(uint8_t brightness) {
screen.set_backlight(brightness);
}
void PicoDisplay::set_led(uint8_t r, uint8_t g, uint8_t b) {
// gamma correct the provided 0-255 brightness value onto a
// 0-65535 range for the pwm counter
@ -50,15 +62,15 @@ namespace pimoroni {
uint16_t value;
// red
value = (uint16_t)(pow((float)(r) / 255.0f, gamma) * 65536.0f + 0.5f);
value = (uint16_t)(pow((float)(r) / 255.0f, gamma) * 65535.0f + 0.5f);
pwm_set_gpio_level(LED_R, value);
// green
value = (uint16_t)(pow((float)(g) / 255.0f, gamma) * 65536.0f + 0.5f);
value = (uint16_t)(pow((float)(g) / 255.0f, gamma) * 65535.0f + 0.5f);
pwm_set_gpio_level(LED_G, value);
// blue
value = (uint16_t)(pow((float)(b) / 255.0f, gamma) * 65536.0f + 0.5f);
value = (uint16_t)(pow((float)(b) / 255.0f, gamma) * 65535.0f + 0.5f);
pwm_set_gpio_level(LED_B, value);
}

View File

@ -6,22 +6,26 @@
namespace pimoroni {
class PicoDisplay : public PicoGraphics {
uint16_t __fb[240 * 135];
public:
static const int WIDTH = 240;
static const int HEIGHT = 135;
static const uint8_t A = 12;
static const uint8_t B = 13;
static const uint8_t X = 14;
static const uint8_t Y = 15;
private:
uint16_t __fb[WIDTH * HEIGHT];
ST7789 screen;
public:
PicoDisplay();
void set_backlight(uint8_t brightness) {screen.set_backlight(brightness);}
void update() {screen.update();}
void init();
void update();
void set_backlight(uint8_t brightness);
void set_led(uint8_t r, uint8_t g, uint8_t b);
bool is_pressed(uint8_t button);
static const uint8_t A = 12;
static const uint8_t B = 13;
static const uint8_t X = 14;
static const uint8_t Y = 15;
};
}

View File

@ -1,5 +1,6 @@
#pragma once
#include <string>
#include <cstdint>
#include <algorithm>
@ -39,11 +40,11 @@ namespace pimoroni {
class PicoGraphics {
public:
uint16_t *frame_buffer;
rect bounds;
rect clip;
uint16_t *frame_buffer;
uint16_t pen;
public:

View File

@ -0,0 +1,6 @@
DISPLAY_MOD_DIR := $(USERMOD_DIR)
# Add all C files to SRC_USERMOD.
SRC_USERMOD += $(DISPLAY_MOD_DIR)/pico_display.c
# # We can add our module folder to include paths if needed
# # This is not actually needed in this example.
CFLAGS_USERMOD += -I$(DISPLAY_MOD_DIR)

View File

@ -0,0 +1,84 @@
#include "pico_display.h"
/***** Constants *****/
enum buttons
{
BUTTON_A = 0,
BUTTON_B,
BUTTON_X,
BUTTON_Y,
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// picodisplay Module
////////////////////////////////////////////////////////////////////////////////////////////////////
/***** Module Functions *****/
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_init_obj, picodisplay_init);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_get_width_obj, picodisplay_get_width);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_get_height_obj, picodisplay_get_height);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_update_obj, picodisplay_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_set_backlight_obj, picodisplay_set_backlight);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_set_led_obj, picodisplay_set_led);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_is_pressed_obj, picodisplay_is_pressed);
//From PicoGraphics parent class
STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_set_pen_rgb_obj, picodisplay_set_pen_rgb);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_set_pen_obj, picodisplay_set_pen);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_create_pen_obj, picodisplay_create_pen);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_set_clip_obj, picodisplay_set_clip);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_remove_clip_obj, picodisplay_remove_clip);
//STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_ptr_obj, picodisplay_ptr);
//STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_ptr_obj, picodisplay_ptr);
//STATIC MP_DEFINE_CONST_FUN_OBJ_2(picodisplay_ptr_obj, picodisplay_ptr);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_clear_obj, picodisplay_clear);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_pixel_obj, picodisplay_pixel);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(picodisplay_pixel_span_obj, picodisplay_pixel_span);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_rectangle_obj, picodisplay_rectangle);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(picodisplay_circle_obj, picodisplay_circle);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_text_obj, picodisplay_text);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_character_obj, picodisplay_character);
/***** Globals Table *****/
STATIC const mp_map_elem_t picodisplay_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_picodisplay) },
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&picodisplay_init_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_width), MP_ROM_PTR(&picodisplay_get_width_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_height), MP_ROM_PTR(&picodisplay_get_height_obj) },
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&picodisplay_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_backlight), MP_ROM_PTR(&picodisplay_set_backlight_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_led), MP_ROM_PTR(&picodisplay_set_led_obj) },
{ MP_ROM_QSTR(MP_QSTR_is_pressed), MP_ROM_PTR(&picodisplay_is_pressed_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_pen_rgb), MP_ROM_PTR(&picodisplay_set_pen_rgb_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_pen), MP_ROM_PTR(&picodisplay_set_pen_obj) },
{ MP_ROM_QSTR(MP_QSTR_create_pen), MP_ROM_PTR(&picodisplay_create_pen_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_clip), MP_ROM_PTR(&picodisplay_set_clip_obj) },
{ MP_ROM_QSTR(MP_QSTR_remove_clip), MP_ROM_PTR(&picodisplay_remove_clip_obj) },
//
{ MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&picodisplay_clear_obj) },
{ MP_ROM_QSTR(MP_QSTR_pixel), MP_ROM_PTR(&picodisplay_pixel_obj) },
{ MP_ROM_QSTR(MP_QSTR_pixel_span), MP_ROM_PTR(&picodisplay_pixel_span_obj) },
{ MP_ROM_QSTR(MP_QSTR_rectangle), MP_ROM_PTR(&picodisplay_rectangle_obj) },
{ MP_ROM_QSTR(MP_QSTR_circle), MP_ROM_PTR(&picodisplay_circle_obj) },
{ MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&picodisplay_text_obj) },
{ MP_ROM_QSTR(MP_QSTR_character), MP_ROM_PTR(&picodisplay_character_obj) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON_A), MP_ROM_INT(BUTTON_A) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON_B), MP_ROM_INT(BUTTON_B) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON_X), MP_ROM_INT(BUTTON_X) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON_Y), MP_ROM_INT(BUTTON_Y) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_picodisplay_globals, picodisplay_globals_table);
/***** Module Definition *****/
const mp_obj_module_t picodisplay_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_picodisplay_globals,
};
////////////////////////////////////////////////////////////////////////////////////////////////////
MP_REGISTER_MODULE(MP_QSTR_picodisplay, picodisplay_user_cmodule, MODULE_PICODISPLAY_ENABLED);
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,150 @@
#include "hardware/spi.h"
#include "hardware/sync.h"
#include "pico/binary_info.h"
#include "../../../pimoroni-pico/libraries/pico_display/pico_display.hpp"
using namespace pimoroni;
PicoDisplay display;
extern "C" {
#include "pico_display.h"
mp_obj_t picodisplay_init() {
display.init();
return mp_const_none;
}
mp_obj_t picodisplay_get_width() {
return mp_obj_new_int(PicoDisplay::WIDTH);
}
mp_obj_t picodisplay_get_height() {
return mp_obj_new_int(PicoDisplay::HEIGHT);
}
mp_obj_t picodisplay_update() {
display.update();
return mp_const_none;
}
mp_obj_t picodisplay_set_backlight(mp_obj_t brightness_obj) {
float brightness = mp_obj_get_float(brightness_obj);
if(brightness < 0 || brightness > 1.0f)
mp_raise_ValueError("brightness out of range. Expected 0.0 to 1.0");
else
display.set_backlight((uint8_t)(brightness * 255.0f));
return mp_const_none;
}
mp_obj_t picodisplay_set_led(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj) {
int r = mp_obj_get_int(r_obj);
int g = mp_obj_get_int(g_obj);
int b = mp_obj_get_int(b_obj);
if(r < 0 || r > 255)
mp_raise_ValueError("r out of range. Expected 0 to 255");
else if(g < 0 || g > 255)
mp_raise_ValueError("g out of range. Expected 0 to 255");
else if(b < 0 || b > 255)
mp_raise_ValueError("b out of range. Expected 0 to 255");
else
display.set_led(r, g, b);
return mp_const_none;
}
mp_obj_t picodisplay_is_pressed(mp_obj_t button_obj) {
int buttonID = mp_obj_get_int(button_obj);
bool buttonPressed = false;
switch(buttonID)
{
case 0:
buttonPressed = display.is_pressed(PicoDisplay::A);
break;
case 1:
buttonPressed = display.is_pressed(PicoDisplay::B);
break;
case 2:
buttonPressed = display.is_pressed(PicoDisplay::X);
break;
case 3:
buttonPressed = display.is_pressed(PicoDisplay::Y);
break;
default:
mp_raise_ValueError("button not valid. Expected 0 to 3");
break;
}
return buttonPressed ? mp_const_true : mp_const_false;
}
mp_obj_t picodisplay_set_pen_rgb(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj) {
return mp_const_none;
}
mp_obj_t picodisplay_set_pen(mp_obj_t p_obj) {
return mp_const_none;
}
mp_obj_t picodisplay_create_pen(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj) {
return mp_const_none;
}
mp_obj_t picodisplay_set_clip(mp_obj_t r_obj) {
return mp_const_none;
}
mp_obj_t picodisplay_remove_clip() {
return mp_const_none;
}
// mp_obj_t picodisplay_ptr(mp_obj_t p_obj) {
// return mp_const_none;
// }
// mp_obj_t picodisplay_ptr(mp_obj_t r_obj) {
// return mp_const_none;
// }
// mp_obj_t picodisplay_ptr(mp_obj_t x_obj, mp_obj_t y_obj) {
// return mp_const_none;
// }
mp_obj_t picodisplay_clear() {
return mp_const_none;
}
mp_obj_t picodisplay_pixel(mp_obj_t p_obj) {
return mp_const_none;
}
mp_obj_t picodisplay_pixel_span(mp_obj_t p_obj, mp_obj_t l_obj) {
return mp_const_none;
}
mp_obj_t picodisplay_rectangle(mp_obj_t r_obj) {
return mp_const_none;
}
mp_obj_t picodisplay_circle(mp_obj_t p_obj, mp_obj_t r_obj) {
return mp_const_none;
}
mp_obj_t picodisplay_text(mp_obj_t t_obj, mp_obj_t p_obj, mp_obj_t wrap_obj) {
return mp_const_none;
}
mp_obj_t picodisplay_character(mp_obj_t c_obj, mp_obj_t p_obj, mp_obj_t scale_obj) {
return mp_const_none;
}
}

View File

@ -0,0 +1,31 @@
// Include MicroPython API.
#include "py/runtime.h"
// Declare the functions we'll make available in Python
extern mp_obj_t picodisplay_init();
extern mp_obj_t picodisplay_get_width();
extern mp_obj_t picodisplay_get_height();
extern mp_obj_t picodisplay_set_backlight(mp_obj_t brightness_obj);
extern mp_obj_t picodisplay_update();
extern mp_obj_t picodisplay_set_led(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj);
extern mp_obj_t picodisplay_is_pressed(mp_obj_t button_obj);
// From PicoGraphics parent class
extern mp_obj_t picodisplay_set_pen_rgb(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj);
extern mp_obj_t picodisplay_set_pen(mp_obj_t p_obj);
extern mp_obj_t picodisplay_create_pen(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj);
extern mp_obj_t picodisplay_set_clip(mp_obj_t r_obj);
extern mp_obj_t picodisplay_remove_clip();
//extern mp_obj_t picodisplay_ptr(mp_obj_t p_obj);
//extern mp_obj_t picodisplay_ptr(mp_obj_t r_obj);
//extern mp_obj_t picodisplay_ptr(mp_obj_t x_obj, mp_obj_t y_obj);
extern mp_obj_t picodisplay_clear();
extern mp_obj_t picodisplay_pixel(mp_obj_t p_obj);
extern mp_obj_t picodisplay_pixel_span(mp_obj_t p_obj, mp_obj_t l_obj);
extern mp_obj_t picodisplay_rectangle(mp_obj_t r_obj);
extern mp_obj_t picodisplay_circle(mp_obj_t p_obj, mp_obj_t r_obj);
extern mp_obj_t picodisplay_text(mp_obj_t t_obj, mp_obj_t p_obj, mp_obj_t wrap_obj);
extern mp_obj_t picodisplay_character(mp_obj_t c_obj, mp_obj_t p_obj, mp_obj_t scale_obj);