diff --git a/drivers/st7789/README.md b/drivers/st7789/README.md new file mode 100644 index 00000000..b9e92b4b --- /dev/null +++ b/drivers/st7789/README.md @@ -0,0 +1,58 @@ +# ST7789 Display Driver for Pimoroni LCDs + +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) +``` \ No newline at end of file diff --git a/libraries/pico_display/README.md b/libraries/pico_display/README.md index 92400654..648df9ce 100644 --- a/libraries/pico_display/README.md +++ b/libraries/pico_display/README.md @@ -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). \ No newline at end of file diff --git a/libraries/pico_display_2/README.md b/libraries/pico_display_2/README.md index ee454773..18ad905c 100644 --- a/libraries/pico_display_2/README.md +++ b/libraries/pico_display_2/README.md @@ -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). \ No newline at end of file diff --git a/libraries/pico_explorer/README.md b/libraries/pico_explorer/README.md index 91589cdd..6c9b0a25 100644 --- a/libraries/pico_explorer/README.md +++ b/libraries/pico_explorer/README.md @@ -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(); -``` \ No newline at end of file +Pico Explorer uses the ST7789 display driver to handle the LCD. For more information [read the ST7789 README.](../../drivers/st7789/README.md). \ No newline at end of file