ST7789/PicoGraphics: Update docs.

This commit is contained in:
Phil Howard 2022-06-13 14:43:08 +01:00
parent 03dc1e9941
commit 1b68e498d4
4 changed files with 217 additions and 205 deletions

58
drivers/st7789/README.md Normal file
View File

@ -0,0 +1,58 @@
# ST7789 Display Driver for Pimoroni LCDs <!-- omit in toc -->
The ST7789 driver supports both Parallel and Serial (SPI) ST7789 displays and is intended for use with:
* Pico Display
* Pico Display 2.0
* Tufty 2040
* Pico Explorer
* 240x240 Round & Square SPI LCD Breakouts
## Setup
Construct an instance of the ST7789 driver with either Parallel or SPI pins.
Parallel:
```c++
ST7789 st7789(WIDTH, HEIGHT, ROTATE_0, {
Tufty2040::LCD_CS, // Chip-Select
Tufty2040::LCD_DC, // Data-Command
Tufty2040::LCD_WR, // Write
Tufty2040::LCD_RD, // Read
Tufty2040::LCD_D0, // Data 0 (start of a bank of 8 pins)
Tufty2040::BACKLIGHT // Backlight
});
```
SPI:
```c++
ST7789 st7789(WIDTH, HEIGHT, ROTATE_0, false, {
PIMORONI_SPI_DEFAULT_INSTANCE, // SPI instance
SPI_BG_FRONT_CS, // Chip-select
SPI_DEFAULT_SCK, // SPI Clock
SPI_DEFAULT_MOSI, // SPI Out
PIN_UNUSED, // SPI In
SPI_DEFAULT_DC, // SPI Data/Command
PIN_UNUSED // Backlight
});
```
## Reference
### Update
ST7789's `update` accepts an instance of `PicoGraphics` in any colour mode:
```c++
st7789.update(&graphics);
```
### Set Backlight
If a backlight pin has been configured, you can set the backlight from 0 to 255:
```c++
st7789.set_backlight(128)
```

View File

@ -7,11 +7,7 @@ We've included helper functions to handle every aspect of drawing to the screen
- [Example Program](#example-program)
- [Function Reference](#function-reference)
- [PicoGraphics](#picographics)
- [init](#init)
- [set_backlight](#set_backlight)
- [set_led](#set_led)
- [is_pressed](#is_pressed)
- [update](#update)
- [ST7789](#st7789)
## Example Program
@ -19,16 +15,18 @@ The following example sets up Pico Display, displays some basic demo text and gr
```c++
#include "pico_display.hpp"
#include "generic_st7789.hpp"
#include "drivers/st7789/st7789.hpp"
#include "libraries/pico_graphics/pico_graphics.hpp"
#include "rgbled.hpp"
#include "button.hpp"
uint16_t buffer[PicoDisplay::WIDTH * PicoDisplay::HEIGHT];
// Display driver
ST7789 st7789(PicoDisplay::WIDTH, PicoDisplay::HEIGHT, ROTATE_0, false, get_spi_pins(BG_SPI_FRONT));
// Swap WIDTH and HEIGHT to rotate 90 degrees
ST7789Generic display(PicoDisplay::WIDTH, PicoDisplay::HEIGHT, buffer);
// Graphics library - in RGB332 mode you get 256 colours and optional dithering for ~32K RAM.
PicoGraphics_PenRGB332 graphics(st7789.width, st7789.height, nullptr);
// Create an RGB LED
// RGB LED
RGBLED led(PicoDisplay::LED_R, PicoDisplay::LED_G, PicoDisplay::LED_B);
// And each button
@ -42,7 +40,7 @@ int main() {
// 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.
display.set_backlight(100);
st7789.set_backlight(100);
while(true) {
// detect if the A button is pressed (could be A, B, X, or Y)
@ -55,24 +53,24 @@ int main() {
// set the colour of the pen
// parameters are red, green, blue all between 0 and 255
display.set_pen(30, 40, 50);
graphics.set_pen(30, 40, 50);
// fill the screen with the current pen colour
display.clear();
graphics.clear();
// draw a box to put some text in
display.set_pen(10, 20, 30);
graphics.set_pen(10, 20, 30);
Rect text_rect(10, 10, 150, 150);
display.rectangle(text_rect);
graphics.rectangle(text_rect);
// write some text inside the box with 10 pixels of margin
// automatically word wrapping
text_rect.deflate(10);
display.set_pen(110, 120, 130);
display.text("This is a message", Point(text_rect.x, text_rect.y), text_rect.w);
graphics.set_pen(110, 120, 130);
graphics.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
display.update();
st7789.update(&graphics);
}
}
```
@ -83,32 +81,6 @@ int main() {
Pico Display uses our Pico Graphics library to draw graphics and text. For more information [read the Pico Graphics function reference.](../pico_graphics/README.md#function-reference).
### configure_display
### ST7789
Configures an ST7789 display. Done by default, but you can use this to set 180 degree rotation like so:
```c++
display.configure_display(true);
```
### flip
Deprecated: calls `configure_display(true);`
### set_backlight
Set the display backlight from 0-255.
```c++
display.set_backlight(brightness);
```
Uses hardware PWM to dim the display backlight, dimming values are gamma-corrected to provide smooth brightness transitions across the full range of intensity. This may result in some low values mapping as "off."
### update
To display your changes on Pico Display's screen you need to call `update`:
```c++
display.update();
```
Pico Display uses the ST7789 display driver to handle the LCD. For more information [read the ST7789 README.](../../drivers/st7789/README.md).

View File

@ -2,16 +2,10 @@
Our Pico Display Pack offers a vibrant 1.14" (240x135) IPS LCD screen for your Raspberry Pi Pico it also includes four switches and and an RGB LED!
We've included helper functions to handle every aspect of drawing to the screen and interfacing with the buttons and LED. See the [function reference](#function-reference) for details.
- [Example Program](#example-program)
- [Function Reference](#function-reference)
- [PicoGraphics](#picographics)
- [init](#init)
- [set_backlight](#set_backlight)
- [set_led](#set_led)
- [is_pressed](#is_pressed)
- [update](#update)
- [ST7789](#st7789)
## Example Program
@ -19,49 +13,62 @@ The following example sets up Pico Display, displays some basic demo text and gr
```c++
#include "pico_display_2.hpp"
#include "drivers/st7789/st7789.hpp"
#include "libraries/pico_graphics/pico_graphics.hpp"
#include "rgbled.hpp"
#include "button.hpp"
using namespace pimoroni;
// Display driver
ST7789 st7789(PicoDisplay2::WIDTH, PicoDisplay2::HEIGHT, ROTATE_0, false, get_spi_pins(BG_SPI_FRONT));
uint16_t buffer[PicoDisplay2::WIDTH * PicoDisplay2::HEIGHT];
PicoDisplay2 pico_display(buffer);
// Graphics library - in RGB332 mode you get 256 colours and optional dithering for 75K RAM.
PicoGraphics_PenRGB332 graphics(st7789.width, st7789.height, nullptr);
// RGB LED
RGBLED led(PicoDisplay2::LED_R, PicoDisplay2::LED_G, PicoDisplay2::LED_B);
// And each button
Button button_a(PicoDisplay2::A);
Button button_b(PicoDisplay2::B);
Button button_x(PicoDisplay2::X);
Button button_y(PicoDisplay2::Y);
int main() {
pico_display.init();
// 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);
st7789.set_backlight(100);
while(true) {
// detect if the A button is pressed (could be A, B, X, or Y)
if(pico_display.is_pressed(pico_display.A)) {
if(button_a.raw(display.A)) {
// make the led glow green
// parameters are red, green, blue all between 0 and 255
// these are also gamma corrected
pico_display.set_led(0, 255, 0);
led.set_rgb(0, 255, 0);
}
// set the colour of the pen
// parameters are red, green, blue all between 0 and 255
pico_display.set_pen(30, 40, 50);
graphics.set_pen(30, 40, 50);
// fill the screen with the current pen colour
pico_display.clear();
graphics.clear();
// draw a box to put some text in
pico_display.set_pen(10, 20, 30);
graphics.set_pen(10, 20, 30);
Rect text_rect(10, 10, 150, 150);
pico_display.rectangle(text_rect);
graphics.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.text("This is a message", Point(text_rect.x, text_rect.y), text_rect.w);
graphics.set_pen(110, 120, 130);
graphics.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
pico_display.update();
st7789.update(&graphics);
}
}
```
@ -72,52 +79,6 @@ int main() {
Pico Display uses our Pico Graphics library to draw graphics and text. For more information [read the Pico Graphics function reference.](../pico_graphics/README.md#function-reference).
### init
### ST7789
Sets up Pico Display. `init` must be called before any other functions since it configures the required PWM and GPIO:
```c++
pico_display.init();
```
### set_backlight
Set the display backlight from 0-255.
```c++
pico_display.set_backlight(brightness);
```
Uses hardware PWM to dim the display backlight, dimming values are gamma-corrected to provide smooth brightness transitions across the full range of intensity. This may result in some low values mapping as "off."
### set_led
Sets the RGB LED on Pico Display with an RGB triplet:
```c++
pico_display.set_led(r, g, b);
```
Uses hardware PWM to drive the LED. Values are automatically gamma-corrected to provide smooth brightness transitions and low values may map as "off."
### is_pressed
Reads the GPIO pin connected to one of Pico Display's buttons, returning a `bool` - `true` if it's pressed and `false` if it is released.
```c++
pico_display.is_pressed(button);
```
The button vaule should be a `uint8_t` denoting a pin, and constants `A`, `B`, `X` and `Y` are supplied to make it easier. e:
```c++
bool is_a_button_pressed = pico_display.is_pressed(PicoDisplay2::A)
```
### update
To display your changes on Pico Display's screen you need to call `update`:
```c++
pico_display.update();
```
Pico Display uses the ST7789 display driver to handle the LCD. For more information [read the ST7789 README.](../../drivers/st7789/README.md).

View File

@ -11,35 +11,59 @@ We've included helper functions to handle every aspect of drawing to the screen
- [Buttons](#buttons)
- [ADC Channels](#adc-channels)
- [GPIO](#gpio)
- [Motors](#motors)
- [Functions](#functions)
- [init](#init)
- [set_motor](#set_motor)
- [get_adc](#get_adc)
- [set_audio_pin](#set_audio_pin)
- [set_tone](#set_tone)
- [is_pressed](#is_pressed)
- [update](#update)
- [Motors](#motors-1)
- [Analog](#analog)
- [Buzzer](#buzzer)
- [Buttons](#buttons-1)
- [ST7789](#st7789)
## Example Program
The following example sets up Pico Explorer, displays some basic demo text and graphics and will illuminate the RGB LED green if the A button is pressed.
The following example shows how to set up all of Pico Explorers functions:
```c++
#include "pico_explorer.hpp"
#include "drivers/st7789/st7789.hpp"
#include "libraries/pico_graphics/pico_graphics.hpp"
#include "button.hpp"
#include "motor.hpp"
#include "analog.hpp"
using namespace pimoroni;
uint16_t buffer[PicoExplorer::WIDTH * PicoExplorer::HEIGHT];
PicoExplorer pico_explorer(buffer);
// Display driver
ST7789 st7789(PicoExplorer::WIDTH, PicoExplorer::HEIGHT, ROTATE_0, false, get_spi_pins(BG_SPI_FRONT));
// Graphics library - in RGB332 mode you get 256 colours and optional dithering for ~56K RAM.
PicoGraphics_PenRGB332 graphics(st7789.width, st7789.height, nullptr);
// Buttons
Button button_a(PicoExplorer::A);
Button button_b(PicoExplorer::B);
Button button_x(PicoExplorer::X);
Button button_y(PicoExplorer::Y);
// Motors
Motor motor1(PicoExplorer::MOTOR1_PINS);
Motor motor2(PicoExplorer::MOTOR2_PINS);
// Analog
Analog adc0(PicoExplorer::ADC0_PIN);
Analog adc1(PicoExplorer::ADC1_PIN);
Analog adc2(PicoExplorer::ADC2_PIN);
int main() {
pico_explorer.init();
motor1.init();
motor2.init();
while(true) {
// now we've done our drawing let's update the screen
pico_explorer.update();
}
while(true) {
// update screen
st7789.update(&graphics);
}
}
```
@ -55,132 +79,129 @@ Please note that the backlight on Pico Explorer is not dimmable (we needed the p
#### Buttons
The four buttons, A, B, X and Y have corresponding constants set to their respective GPIO pins. For example:
The four buttons, A, B, X and Y have corresponding constants set to their respective GPIO pins.
```c++
bool a_is_pressed = pico_explorer.is_pressed(pico_explorer.A);
PicoExplorer::A = 12;
PicoExplorer::B = 13;
PicoExplorer::X = 14;
PicoExplorer::Y = 15;
```
#### ADC Channels
The three ADC channels are defined as `ADC0`, `ADC1` and `ADC2`, and should be used with `get_adc`, eg:
The three ADC channels are defined as `ADC0_PIN`, `ADC1_PIN` and `ADC2_PIN`, and should be used with an instance of the `Analog` class:
```c++
float adc0_reading = pico_explorer.get_adc(pico_explorer.ADC0);
PicoExplorer::ADC0_PIN = 26;
PicoExplorer::ADC1_PIN = 27;
PicoExplorer::ADC2_PIN = 28;
```
#### GPIO
The 8 general purpose IO pins on the lower Pico Explorer are GP0 through GP7, we've created constants for you to identify them easily. You should use Pico SDK's `gpio_get` to read a pin, eg:
The 8 general purpose IO pins on the lower Pico Explorer are GP0 through GP7, we've created constants for you to identify them easily.
```c++
PicoExplorer::GP0 = 0;
PicoExplorer::GP1 = 1;
PicoExplorer::GP2 = 2;
PicoExplorer::GP3 = 3;
PicoExplorer::GP4 = 4;
PicoExplorer::GP5 = 5;
PicoExplorer::GP6 = 6;
PicoExplorer::GP7 = 7;
```
You should use Pico SDK's `gpio_get` to read a pin, eg:
```c++
bool pin_state = gpio_get(pico_explorer.GP0);
```
#### Motors
The two motor channels are defined as pin pairs, and should be used with an instance of the `Motor` class:
```c++
PicoExplorer::MOTOR1_PINS = {9, 8};
PicoExplorer::MOTOR2_PINS = {11, 10};
```
### Functions
#### init
#### Motors
Sets up Pico Explorer. `init` must be called before any other functions since it configures the required PWM and GPIO:
Pico Explorer uses our `Motor` library to drive motors. Motors are driven by PWM via an onboard DRV8833. Constants are provided for both motors, so setup is as easy as:
```c++
pico_explorer.init();
#include "motor.hpp"
using namespace motor;
Motor motor1(PicoExplorer::MOTOR1_PINS);
Motor motor2(PicoExplorer::MOTOR2_PINS);
```
#### set_motor
You should also init your motors to set up the required GPIO/PWM on their pins:
```c++
void PicoExplorer::set_motor(uint8_t channel, uint8_t action, float speed);
motor1.init();
motor2.init();
```
Motors are driven by PWM via an onboard DRV8833, `set_motor` will set the PWM values for the corresponding channel.
Channel should be one of `MOTOR1` or `MOTOR2`.
Action should be `FORWARD`, `REVERSE` or `STOP`.
Speed should be given as a float between `0.0` and `1.0`, eg:
Speed should be given as a float between `-1.0` and `1.0`, eg:
```c++
pico_explorer.set_motor(pico_explorer.MOTOR1, pico_explorer.FORWARD, 0.5f);
pico_explorer.set_motor(pico_explorer.MOTOR2, pico_explorer.REVERSE, 0.5f);
motor1.speed(1.0) // Full-speed forward
motor1.speed(-1.0) // Full-speed backward
```
And to stop the motor:
```c++
pico_explorer.set_motor(pico_explorer.MOTOR1, pico_explorer.STOP);
pico_explorer.set_motor(pico_explorer.MOTOR2, pico_explorer.STOP);
motor1.stop()
```
#### get_adc
#### Analog
```c++
float get_adc(uint8_t channel);
```
Pico Explorer's ADC channels are connected to Pico's ADC-capable pins 26, 27 and 28 which correspond to channels 0, 1 and 2 respectively. eg:
Pico Explorer's ADC channels are connected to Pico's ADC-capable pins 26, 27 and 28 which correspond to channels 0, 1 and 2 respectively.
Constants are supplied for these in the PicoExplorer library, so you can create an Analog instance for each:
```c++
float reading = pico_explorer.get_adc(pico_explorer.ADC0);
#include "analog.hpp"
Analog adc0(PicoExplorer::ADC0_PIN);
Analog adc1(PicoExplorer::ADC1_PIN);
Analog adc2(PicoExplorer::ADC2_PIN);
```
Will perform a 12-bit ADC read and return the result as a float scaled from `0.0f` to `1.0f`. This value can be plugged directly into a motor, eg:
And read a voltage with:
```c++
float reading = pico_explorer.get_adc(pico_explorer.ADC0);
pico_explorer.set_motor(pico_explorer.MOTOR1, pico_explorer.FORWARD, reading);
adc0.read_voltage();
```
#### set_audio_pin
#### Buzzer
Note: You must bridge the pin you use over to the `AUDIO` pin on the Pico Explorer header in order to drive the onboard Piezo.
TODO document buzzer
#### Buttons
```c++
void set_audio_pin(uint8_t p);
#include "button.hpp"
Button button_a(PicoExplorer::A);
Button button_b(PicoExplorer::B);
Button button_x(PicoExplorer::X);
Button button_y(PicoExplorer::Y);
```
`set_audio_pin` configures the PIN that Pico Explorer uses for audio output. It should be one of `GP0` through `GP7`, eg:
### ST7789
```c++
pico_explorer.set_audio_pin(pico_explorer.GP0);
```
Note: You must bridge this pin over to the `AUDIO` pin on the Pico Explorer header in order to drive the onboard Piezo, eg:
#### set_tone
```c++
void set_tone(uint16_t frequency, float duty = 0.2f);
```
`set_tone` will play an audio tone out of your chosen audio pin, if you have bridged that pin to "AUDIO" on the Pico Explorer header then it will sound the onboard Piezo.
```c++
uint16_t frequency = 440;
pico_explorer.set_tone(frequency);
```
#### is_pressed
```c++
bool is_pressed(uint8_t button);
```
Reads the GPIO pin connected to one of Pico Explorer's buttons, returning a `bool` - `true` if it's pressed and `false` if it is released.
```c++
pico_explorer.is_pressed(button);
```
The button vaule should be a `uint8_t` denoting a pin, and constants `A`, `B`, `X` and `Y` are supplied to make it easier. e:
```c++
bool is_a_button_pressed = pico_explorer.is_pressed(PicoDisplay::A)
```
#### update
To display your changes on Pico Explorer's screen you need to call `update`:
```c++
pico_explorer.update();
```
Pico Explorer uses the ST7789 display driver to handle the LCD. For more information [read the ST7789 README.](../../drivers/st7789/README.md).