ST7789/PicoGraphics: Update C++ libs and examples.

driver/sh1107
Phil Howard 2022-05-28 21:26:17 +01:00
rodzic 0264dddc2c
commit 9b8d215cd3
13 zmienionych plików z 117 dodań i 59 usunięć

Wyświetl plik

@ -8,7 +8,7 @@ using namespace pimoroni;
const int WIDTH = 240;
const int HEIGHT = 240;
ST7789Generic lcd(WIDTH, HEIGHT, false, nullptr, BG_SPI_FRONT);
ST7789Generic display(WIDTH, HEIGHT, ROTATE_0, false, nullptr, get_spi_pins(BG_SPI_FRONT));
int main() {
//lcd.configure_display(false);

Wyświetl plik

@ -14,7 +14,7 @@ using namespace pimoroni;
const int WIDTH = 240;
const int HEIGHT = 240;
ST7789Generic display(WIDTH, HEIGHT, true, nullptr, BG_SPI_FRONT);
ST7789Generic display(WIDTH, HEIGHT, ROTATE_0, true, nullptr, get_spi_pins(BG_SPI_FRONT));
constexpr float RADIUS = WIDTH / 2;

Wyświetl plik

@ -9,16 +9,12 @@
using namespace pimoroni;
const bool ROTATE_180 = false;
// Swap WIDTH and HEIGHT to rotate 90 degrees
ST7789Generic pico_display(PicoDisplay::WIDTH, PicoDisplay::HEIGHT);
ST7789Generic pico_display(PicoDisplay::WIDTH, PicoDisplay::HEIGHT, ROTATE_0);
RGBLED led(PicoDisplay::LED_R, PicoDisplay::LED_G, PicoDisplay::LED_B);
int main() {
pico_display.configure_display(ROTATE_180);
pico_display.set_backlight(100);
struct pt {

Wyświetl plik

@ -10,10 +10,7 @@
using namespace pimoroni;
const bool ROTATE_180 = false;
// Swap WIDTH and HEIGHT to rotate 90 degrees
ST7789Generic pico_display(240, 240);
ST7789Generic pico_display(240, 240, ROTATE_0);
RGBLED led(PicoDisplay2::LED_R, PicoDisplay2::LED_G, PicoDisplay2::LED_B);
@ -43,7 +40,6 @@ void from_hsv(float h, float s, float v, uint8_t &r, uint8_t &g, uint8_t &b) {
}
int main() {
pico_display.configure_display(ROTATE_180);
pico_display.set_backlight(255);
struct pt {

Wyświetl plik

@ -15,22 +15,17 @@ using namespace pimoroni;
Tufty2040 tufty;
uint16_t buffer[Tufty2040::WIDTH * Tufty2040::HEIGHT];
static const uint8_t LCD_CS = 10;
static const uint8_t LCD_DC = 11;
static const uint8_t LCD_WR = 12;
static const uint8_t LCD_RD = 13;
static const uint8_t LCD_D0 = 14;
// Swap WIDTH and HEIGHT to rotate 90 degrees
ST7789Generic pico_display(
Tufty2040::WIDTH, Tufty2040::HEIGHT,
buffer,
Tufty2040::LCD_CS, Tufty2040::LCD_DC, Tufty2040::LCD_WR, Tufty2040::LCD_RD, Tufty2040::LCD_D0,
Tufty2040::BACKLIGHT
Tufty2040::WIDTH, Tufty2040::HEIGHT, ROTATE_0, nullptr,
ParallelPins{
Tufty2040::LCD_CS,
Tufty2040::LCD_DC,
Tufty2040::LCD_WR,
Tufty2040::LCD_RD,
Tufty2040::LCD_D0,
Tufty2040::BACKLIGHT
}
);
Button button_a(Tufty2040::A);

Wyświetl plik

@ -11,4 +11,4 @@ target_sources(${LIB_NAME} INTERFACE
target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
# Pull in pico libraries that we need
target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib st7789 pico_graphics)
target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib st7789 pimoroni_bus pico_graphics)

Wyświetl plik

@ -3,20 +3,21 @@
namespace pimoroni {
BreakoutRoundLCD::BreakoutRoundLCD(uint16_t *buf)
: PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, true, buf,
PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_MISO, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, SPI_BG_FRONT_PWM) {
: PicoGraphics(WIDTH, HEIGHT, buf),
screen(WIDTH, HEIGHT, ROTATE_0, true, buf, get_spi_pins(BG_SPI_FRONT)) {
__fb = buf;
}
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, true, buf, spi, cs, dc, sck, mosi, bl) {
: PicoGraphics(WIDTH, HEIGHT, buf),
screen(WIDTH, HEIGHT, ROTATE_0, true, buf, SPIPins{spi, cs sck, mosi, dc, bl}) {
__fb = buf;
}
BreakoutRoundLCD::BreakoutRoundLCD(uint16_t *buf, BG_SPI_SLOT slot)
: PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, true, buf,
PIMORONI_SPI_DEFAULT_INSTANCE, screen.get_slot_cs(slot), SPI_DEFAULT_MISO, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, screen.get_slot_bl(slot)) {
: PicoGraphics(WIDTH, HEIGHT, buf),
screen(WIDTH, HEIGHT, ROTATE_0, true, buf, get_spi_pins(slot)) { {
__fb = buf;
}

Wyświetl plik

@ -22,12 +22,8 @@ The following example sets up Pico Display, displays some basic demo text and gr
using namespace pimoroni;
const bool ROTATE_180 = false;
uint16_t buffer[PicoDisplay::WIDTH * PicoDisplay::HEIGHT];
// Swap WIDTH and HEIGHT to rotate 90 degrees
ST7789Generic pico_display(PicoDisplay::WIDTH, PicoDisplay::HEIGHT, buffer);
ST7789Generic pico_display(PicoDisplay::WIDTH, PicoDisplay::HEIGHT, ROTATE_0);
// RGB LED controller
RGBLED led(PicoDisplay::LED_R, PicoDisplay::LED_G, PicoDisplay::LED_B);
@ -39,12 +35,17 @@ Button button_x(PicoDisplay::X);
Button button_y(PicoDisplay::Y);
int main() {
pico_display.configure_display(ROTATE_180);
// set the backlight to a value between 0 and 255
// the backlight is driven via PWM and is gamma corrected by our
// library to give a gorgeous linear brightness range.
pico_display.set_backlight(100);
// Create pens for the colours we want to use
// parameters are red, green, blue all between 0 and 255
// By default these are crushed to RGB332 so only the upper bits of each are used!
int BG_COLOR = pico_display.create_pen(30, 40, 50);
int BOX_COLOR = pico_display.create_pen(10, 20, 30);
int TEXT_COLOR = pico_display.create_pen(110, 120, 130);
while(true) {
// detect if the A button is pressed (could be A, B, X, or Y)
@ -56,21 +57,20 @@ int main() {
}
// set the colour of the pen
// parameters are red, green, blue all between 0 and 255
pico_display.set_pen(30, 40, 50);
pico_display.set_pen(BG_COLOR);
// fill the screen with the current pen colour
pico_display.clear();
// draw a box to put some text in
pico_display.set_pen(10, 20, 30);
pico_display.set_pen(BOX_COLOR);
Rect text_rect(10, 10, 150, 150);
pico_display.rectangle(text_rect);
// write some text inside the box with 10 pixels of margin
// automatically word wrapping
text_rect.deflate(10);
pico_display.set_pen(110, 120, 130);
pico_display.set_pen(TEXT_COLOR);
pico_display.text("This is a message", Point(text_rect.x, text_rect.y), text_rect.w);
// now we've done our drawing let's update the screen

Wyświetl plik

@ -9,14 +9,14 @@
namespace pimoroni {
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) {
: PicoGraphics(WIDTH, HEIGHT, buf),
screen(WIDTH, HEIGHT, ROTATE_0, false, buf, get_spi_pins(BG_SPI_FRONT)) {
__fb = buf;
}
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) {
: PicoGraphics(width, height, buf),
screen(width, height, ROTATE_0, false, buf, get_spi_pins(BG_SPI_FRONT)) {
__fb = buf;
}

Wyświetl plik

@ -15,8 +15,8 @@ const uint8_t MOTOR2P = 11;
namespace pimoroni {
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)) {
: PicoGraphics(WIDTH, HEIGHT, buf),
screen(WIDTH, HEIGHT, ROTATE_0, false, buf, get_spi_pins(PICO_EXPLORER_ONBOARD)) {
__fb = buf;
}
@ -55,10 +55,12 @@ namespace pimoroni {
screen.update(palette);
}
[[deprecated("Use Button(uint pin).")]]
bool PicoExplorer::is_pressed(uint8_t button) {
return !gpio_get(button);
}
[[deprecated("Use Analog(uint pin).")]]
float PicoExplorer::get_adc(uint8_t channel) {
adc_select_input(channel);
// scale raw 12-bit adc value to 0 .. 1 float
@ -68,6 +70,7 @@ namespace pimoroni {
return result;
}
[[deprecated("Use Motor(pin_pair pins).")]]
void PicoExplorer::set_motor(uint8_t channel, uint8_t action, float speed) {
uint8_t p = channel == MOTOR1 ? MOTOR1P : MOTOR2P;
uint8_t n = channel == MOTOR1 ? MOTOR1N : MOTOR2N;
@ -93,6 +96,7 @@ namespace pimoroni {
}
}
[[deprecated("Use Buzzer(uint pin).")]]
void PicoExplorer::set_audio_pin(uint pin) {
pwm_config tone_pwm_cfg = pwm_get_default_config();
@ -105,6 +109,7 @@ namespace pimoroni {
audio_pin = pin;
}
[[deprecated("Use Buzzer(uint pin).set_tone().")]]
void PicoExplorer::set_tone(uint16_t frequency, float duty) {
// output a square wave, so 50% duty cycle
if(audio_pin != -1) {

Wyświetl plik

@ -19,6 +19,11 @@ It supports drawing text, primitive and individual pixels and includes basic typ
- [set_pen](#set_pen)
- [create_pen](#create_pen)
- [set_clip & remove_clip](#set_clip--remove_clip)
- [Palette](#palette)
- [set_palette_mode](#set_palette_mode)
- [reserve_palette](#reserve_palette)
- [set_palette](#set_palette)
- [RGB565 and RGB332](#rgb565-and-rgb332)
- [Pixels](#pixels)
- [pixel](#pixel)
- [pixel_span](#pixel_span)
@ -123,9 +128,10 @@ Would deflate our `box` to start at `11,11` and be 8x8 pixels in size.
Since `rectangle` *always* draws a filled rectangle, this can be useful to add an outline of your desired thickness:
```c++
WHITE = screen.create_pen(255, 255, 255);
rect box(10, 10, 100, 100);
box.inflate(1); // Inflate our box by 1px on all sides
screen.set_pen(255, 255, 255); // White outline
screen.set_pen(WHITE); // White outline
screen.rectangle(box);
box.deflate(1); // Return to our original box size
screen.set_pen(0, 0, 0); /// Black fill
@ -157,26 +163,24 @@ TODO
#### set_pen
In order to draw anything with Pico Graphics you must first set the pen to your desired colour, there are two ways to do this:
In order to draw anything with Pico Graphics you must first set the pen to your desired palette colour:
```c++
void PicoGraphics::set_pen(uint8_t r, uint8_t g, uint8_t b);
void PicoGraphics::set_pen(uint16_t p);
void PicoGraphics::set_pen(uint8_t p);
```
The former uses 8-bit R, G and B values which are clipped to 5, 6 and 5 bits respectively to form a 16-bit colour. Internally it uses `create_pen`.
This value represents an index into the internal colour palette, which has 256 entries and defaults to RGB332 giving an approximation of all RGB888 colours.
The latter takes a 16-bit colour directly and is a great way to save a few cycles if you're working with a constant palette of colours.
#### create_pen
```c++
uint16_t PicoGraphics::create_pen(uint8_t r, uint8_t g, uint8_t b);
int PicoGraphics::create_pen(uint8_t r, uint8_t g, uint8_t b);
```
Create pen takes R, G and B values, clamps them to 5, 6 and 5 bits respectively and joins them into a `uint16_t` pen that represents a single 16-bit colour.
By default create pen takes R, G and B values, clamps them to 3, 3 and 2 bits respectively and returns an index in the RGB332 palette.
Creating your pens up front and storing them as `uint16_t` can speed up switching colours.
You must create pens before using them with `set_pen()` which accepts only a palette index.
#### set_clip & remove_clip
@ -189,6 +193,59 @@ void PicoGraphics::remove_clip();
`remove_clip` sets the surface clipping rectangle back to the surface `bounds`.
### Palette
By default Pico Graphics uses an `RGB332` palette and clamps all pens to their `RGB332` values so it can give you an approximate colour for every `RGB888` value you request. If you don't want to think about colours and palettes you can leave it as is.
Alternatively `set_palette_mode()` lets you switch into an RGB565 `USER` palette which gives you up to 256 16-bit colours of your choice.
#### set_palette_mode
```c++
void PicoGraphics::set_palette_mode(PALETTE_USER);
```
Clears the default `RGB332` palette and switches into `USER` mode.
Pens created with `create_pen()` will use 16-bit `RGB565` resolution and you have up to 256 palette entries to use.
```c++
void PicoGraphics::set_palette_mode(PALETTE_RGB332);
```
Clears any `USER` assigned palettes and returns to `RGB332` mode.
#### reserve_palette
```c++
int PicoGraphics::reserve_palette();
```
Marks the first empty palette entry as reserved and return its index.
#### set_palette
```c++
void PicoGraphics::set_palette(uint8_t index, RGB565 color);
```
#### RGB565 and RGB332
```c++
int RGB565(uint8_t r, uint8_t g, uint8_t b);
```
Creates and returns an RGB565 colour, using the five/six/five most significant bits of each channel in turn.
```c++
int RGB332(uint8_t, uint8_t g, uint8_t b);
```
Creates and returns an RGB565 colour, using the three/three/two most significant bits of each channel in turn.
IE: This clips the colour to RGB332.
### Pixels
#### pixel

Wyświetl plik

@ -35,6 +35,11 @@ namespace pimoroni {
return result;
}
void PicoGraphics::set_pen(uint8_t r, uint8_t g, uint8_t b) {
int result = create_pen(r, g, b);
(void)result;
}
int PicoGraphics::search_palette(RGB565 c) {
for(auto i = 0u; i < 256; i++) {
if((palette_status[i] & PaletteStatusUsed) && palette[i] == c) return i;
@ -53,7 +58,7 @@ namespace pimoroni {
return -1;
}
void PicoGraphics::set_palette(uint8_t i, uint16_t c) {
void PicoGraphics::set_palette(uint8_t i, RGB565 c) {
palette[i] = c;
palette_status[i] |= PaletteStatusUsed;
}

Wyświetl plik

@ -76,6 +76,9 @@ namespace pimoroni {
void set_pen(Pen p);
void set_palette_mode(PaletteMode mode);
[[deprecated("Use uint8_t create_pen(uint8_t, uint8_t, uint8_t).")]]
void set_pen(uint8_t r, uint8_t g, uint8_t b);
static constexpr RGB565 create_pen_rgb565(uint8_t r, uint8_t g, uint8_t b) {
uint16_t p = ((r & 0b11111000) << 8) |
((g & 0b11111100) << 3) |