From 3f24b442f1590da7dac94c39f9d7b2d088bcc271 Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Thu, 29 Sep 2022 10:21:14 +0100 Subject: [PATCH 01/28] inital work needs testing --- drivers/st7567/CMakeLists.txt | 1 + drivers/st7567/st7567.cmake | 10 ++ drivers/st7567/st7567.cpp | 175 ++++++++++++++++++++++++++++++++++ drivers/st7567/st7567.hpp | 68 +++++++++++++ pimoroni-pico.code-workspace | 7 ++ 5 files changed, 261 insertions(+) create mode 100644 drivers/st7567/CMakeLists.txt create mode 100644 drivers/st7567/st7567.cmake create mode 100644 drivers/st7567/st7567.cpp create mode 100644 drivers/st7567/st7567.hpp create mode 100644 pimoroni-pico.code-workspace diff --git a/drivers/st7567/CMakeLists.txt b/drivers/st7567/CMakeLists.txt new file mode 100644 index 00000000..080cb792 --- /dev/null +++ b/drivers/st7567/CMakeLists.txt @@ -0,0 +1 @@ +include(st7735.cmake) diff --git a/drivers/st7567/st7567.cmake b/drivers/st7567/st7567.cmake new file mode 100644 index 00000000..85c8ae60 --- /dev/null +++ b/drivers/st7567/st7567.cmake @@ -0,0 +1,10 @@ +set(DRIVER_NAME st7735) +add_library(${DRIVER_NAME} INTERFACE) + +target_sources(${DRIVER_NAME} INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/${DRIVER_NAME}.cpp) + +target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) + +# Pull in pico libraries that we need +target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib pimoroni_bus hardware_spi hardware_pwm hardware_dma) diff --git a/drivers/st7567/st7567.cpp b/drivers/st7567/st7567.cpp new file mode 100644 index 00000000..f7a1a945 --- /dev/null +++ b/drivers/st7567/st7567.cpp @@ -0,0 +1,175 @@ +#include "ST7567.hpp" + +#include +#include + +#include "hardware/dma.h" +#include "hardware/pwm.h" + +namespace pimoroni { + + enum reg : uint8_t { + DISPOFF = 0xAE,// + DISPON = 0xAF,// + SETSTARTLINE = 0x40,// + STARTLINE_MASK = 0x3f,// + REG_RATIO = 0x20,// + SETPAGESTART = 0xb0,// + PAGESTART_MASK = 0x07,// + SETCOLL = 0x00, // # 0x00-0x0f: Set lower column address */ + COLL_MASK = 0x0f,// + SETCOLH = 0x10, //# 0x10-0x1f: Set higher column address */ + COLH_MASK = 0x0F,// + SEG_DIR_NORMAL = 0xa0, //# 0xa0: Column address 0 is mapped to SEG0 */ + SEG_DIR_REV = 0xa1, //# 0xa1: Column address 128 is mapped to S + DISPNORMAL = 0xa6, //# 0xa6: Normal display */ + DISPINVERSE = 0xa7, //# 0xa7: Inverse disp + DISPRAM = 0xa4, //# 0xa4: Resume to RAM content display */ + DISPENTIRE = 0xa5, //# 0xa5: Entire display + BIAS_1_9 = 0xa2, //# 0xa2: Select BIAS setting 1/9 */ + BIAS_1_7 = 0xa3, // # 0xa3: Select BIAS setting + ENTER_RMWMODE = 0xe0, //# 0xe0: Enter the Read Modify Write mode */ + EXIT_RMWMODE = 0xee, //# 0xee: Leave the Read Modify Write mode */ + EXIT_SOFTRST = 0xe2, // # 0xe2: Software RE + SETCOMNORMAL = 0xc0, //# 0xc0: Set COM output direction, normal mode */ + SETCOMREVERSE = 0xc8, // # 0xc8: Set COM output direction, reverse m + POWERCTRL_VF = 0x29, //# 0x29: Control built-in power circuit */ + POWERCTRL_VR = 0x2a, //# 0x2a: Control built-in power circuit */ + POWERCTRL_VB = 0x2c, //# 0x2c: Control built-in power circuit */ + POWERCTRL = 0x2f, // # 0x2c: Control built-in power circ + REG_RES_RR0 = 0x21, //# 0x21: Regulation Resistior ratio */ + REG_RES_RR1 = 0x22, //# 0x22: Regulation Resistior ratio */ + REG_RES_RR2 = 0x24, // # 0x24: Regulation Resistior ra + SETCONTRAST = 0x81, // # 0x81: Set contrast cont + SETBOOSTER = 0xf8, //# Set booster level */ + SETBOOSTER4X = 0x00, //# Set booster level */ + SETBOOSTER5X = 0x01 , // # Set booster le + NOP = 0xe3, //# 0xe3: NOP Command for no operation */ + STARTBYTES = 0, + }; + + void ST7567::reset() { + if(RESET == PIN_UNUSED) return; + gpio_put(RESET, 0); sleep_ms(10); + gpio_put(RESET, 1); sleep_ms(10); + sleep_ms(100); + } + + + void ST7567::init(bool auto_init_sequence) { + spi_init(spi, spi_baud); + + gpio_set_function(reset, GPIO_FUNC_SIO); + gpio_set_dir(reset, GPIO_OUT); + + gpio_set_function(dc, GPIO_FUNC_SIO); + gpio_set_dir(dc, GPIO_OUT); + + gpio_set_function(cs, GPIO_FUNC_SIO); + gpio_set_dir(cs, GPIO_OUT); + + gpio_set_function(sck, GPIO_FUNC_SPI); + gpio_set_function(mosi, GPIO_FUNC_SPI); + + // if a backlight pin is provided then set it up for + // pwm control + if(bl != PIN_UNUSED) { + pwm_config cfg = pwm_get_default_config(); + pwm_set_wrap(pwm_gpio_to_slice_num(bl), 65535); + pwm_init(pwm_gpio_to_slice_num(bl), &cfg, true); + gpio_set_function(bl, GPIO_FUNC_PWM); + set_backlight(0); // Turn backlight off initially to avoid nasty surprises + } + + //reset display + + reset(); + + + + // if auto_init_sequence then send initialisation sequence + // for our standard displays based on the width and height + if(auto_init_sequence) { + + command(reg::BIAS_1_7); + command(reg::SEG_DIR_NORMAL); + command(reg::SETCOMREVERSE); + command(reg::DISPNORMAL); + command(reg::SETSTARTLINE | 0x00); //Startline from 0x40-0x7F + command(reg::POWERCTRL); + command(reg::REG_RATIO | 3); + command(reg::DISPON); + command(reg::SETCONTRAST); + command(58); // defalut contrast level + } + + if(bl != PIN_UNUSED) { + set_backlight(255); // Turn backlight on now surprises have passed + } + } + + void ST7567::command(uint8_t command, size_t len, const char *data) { + gpio_put(cs, 0); + + gpio_put(dc, 0); // command mode + spi_write_blocking(spi, &command, 1); + + if(data) { + gpio_put(dc, 1); // data mode + spi_write_blocking(spi, (const uint8_t*)data, len); + } + + gpio_put(cs, 1); + } + + // Native 16-bit framebuffer update + void ST7567::update(PicoGraphics *graphics) { + uint8_t offset; + uint8_t *fb = (uint8_t *)graphics->frame_buffer; + + + if(graphics->pen_type == PicoGraphics::PEN_1BIT) { + command(reg::ENTER_RWMODE); + for (uint8_t page=0; page < 8 ; page++){ + command(reg::SETPAGESTART | page); + command(reg::SETCOLL); + command(reg::SETCOLH); + gpio_put(dc, 1); // data mode + gpio_put(cs, 0); + spi_write_blocking(spi, fb, PAGESIZE / 8); + fb += PAGESIZE / 8; + gpio_put(cs, 1); + + } + + } else { + command(reg::ENTER_RWMODE); + gpio_put(dc, 1); // data mode + gpio_put(cs, 0); + + graphics->frame_convert(PicoGraphics::PEN_1BIT, [this](void *data, size_t length) { + if (length > 0) { + for (uint8_t page=0; page < 8 ; page++){ + offset = page * PAGESIZE; + command(reg::SETPAGESTART | page); + command(reg::SETCOLL); + command(reg::SETCOLH); + gpio_put(dc, 1); // data mode + gpio_put(cs, 0); + spi_write_blocking(spi, (const uint8_t*)data[offset/8], PAGESIZE / 8); + gpio_put(cs, 1); + } + }); + + gpio_put(cs, 1); + } + } + + void ST7567::set_backlight(uint8_t brightness) { + // 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) * 65535.0f + 0.5f); + pwm_set_gpio_level(bl, value); + } +} \ No newline at end of file diff --git a/drivers/st7567/st7567.hpp b/drivers/st7567/st7567.hpp new file mode 100644 index 00000000..13848722 --- /dev/null +++ b/drivers/st7567/st7567.hpp @@ -0,0 +1,68 @@ +#pragma once + +#include "hardware/spi.h" +#include "hardware/gpio.h" +#include "common/pimoroni_common.hpp" +#include "common/pimoroni_bus.hpp" +#include "libraries/pico_graphics/pico_graphics.hpp" + +namespace pimoroni { + + class ST7567 : public DisplayDriver { + //-------------------------------------------------- + // Constants + //-------------------------------------------------- + private: + static const uint8_t ROWS = 128; + static const uint8_t COLS = 64; + static const uint8_t PAGESIZE = 128; + + //-------------------------------------------------- + // Variables + //-------------------------------------------------- + private: + + spi_inst_t *spi = spi0; + + uint32_t dma_channel; + + // interface pins with our standard defaults where appropriate + uint cs = SPI_BG_FRONT_CS; + uint dc = 20; + uint sck = SPI_DEFAULT_SCK ; + uint mosi = SPI_DEFAULT_MOSI; + uint bl = PIN_UNUSED; + uint reset = PIN_UNUSED; + + uint32_t spi_baud = 30 * 1024 * 1024; + + uint8_t offset_cols = 0; + uint8_t offset_rows = 0; + + //-------------------------------------------------- + // Constructors/Destructor + //-------------------------------------------------- + public: + ST7567(uint16_t width, uint16_t height, Rotation rotate) : ST7567(width, height, rotate, {PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, 20, PIN_UNUSED}) {}; + + ST7567(uint16_t width, uint16_t height, SPIPins pins, uint busy=26, uint reset=21) : + DisplayDriver(width, height, ROTATE_0), + spi(pins.spi), + CS(pins.cs), DC(pins.dc), SCK(pins.sck), MOSI(pins.mosi), BUSY(busy), RESET(reset) { + init(); + } + + + //-------------------------------------------------- + // Methods + //-------------------------------------------------- + public: + void update(PicoGraphics *graphics) override; + void set_backlight(uint8_t brightness) override; + + private: + void init(bool auto_init_sequence = true); + void command(uint8_t command, size_t len = 0, const char *data = NULL); + }; + +} diff --git a/pimoroni-pico.code-workspace b/pimoroni-pico.code-workspace new file mode 100644 index 00000000..ef9f5d27 --- /dev/null +++ b/pimoroni-pico.code-workspace @@ -0,0 +1,7 @@ +{ + "folders": [ + { + "path": "." + } + ] +} \ No newline at end of file From c48f81bc90eca2db90f95c5e0d2a2eaaaffde25e Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Thu, 29 Sep 2022 12:01:35 +0100 Subject: [PATCH 02/28] started on converting pico display demo --- drivers/CMakeLists.txt | 1 + drivers/st7567/CMakeLists.txt | 2 +- drivers/st7567/st7567.cmake | 2 +- examples/CMakeLists.txt | 1 + examples/gfx_pack/CMakeLists.txt | 12 +++ examples/gfx_pack/gfx_demo.cpp | 124 ++++++++++++++++++++++++++++++ libraries/CMakeLists.txt | 1 + libraries/gfx_pack/CMakeLists.txt | 11 +++ libraries/gfx_pack/README.md | 84 ++++++++++++++++++++ libraries/gfx_pack/gfx_pack.cmake | 10 +++ libraries/gfx_pack/gfx_pack.cpp | 1 + libraries/gfx_pack/gfx_pack.hpp | 19 +++++ 12 files changed, 266 insertions(+), 2 deletions(-) create mode 100644 examples/gfx_pack/CMakeLists.txt create mode 100644 examples/gfx_pack/gfx_demo.cpp create mode 100644 libraries/gfx_pack/CMakeLists.txt create mode 100644 libraries/gfx_pack/README.md create mode 100644 libraries/gfx_pack/gfx_pack.cmake create mode 100644 libraries/gfx_pack/gfx_pack.cpp create mode 100644 libraries/gfx_pack/gfx_pack.hpp diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index bb474e1d..5c005228 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -38,3 +38,4 @@ add_subdirectory(vl53l5cx) add_subdirectory(pcf85063a) add_subdirectory(pms5003) add_subdirectory(sh1107) +add_subdirectory(st7567) \ No newline at end of file diff --git a/drivers/st7567/CMakeLists.txt b/drivers/st7567/CMakeLists.txt index 080cb792..6a0bb2be 100644 --- a/drivers/st7567/CMakeLists.txt +++ b/drivers/st7567/CMakeLists.txt @@ -1 +1 @@ -include(st7735.cmake) +include(st7567.cmake) diff --git a/drivers/st7567/st7567.cmake b/drivers/st7567/st7567.cmake index 85c8ae60..9207751e 100644 --- a/drivers/st7567/st7567.cmake +++ b/drivers/st7567/st7567.cmake @@ -1,4 +1,4 @@ -set(DRIVER_NAME st7735) +set(DRIVER_NAME st7567) add_library(${DRIVER_NAME} INTERFACE) target_sources(${DRIVER_NAME} INTERFACE diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index c7de23d1..ee8884fb 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -55,3 +55,4 @@ add_subdirectory(servo2040) add_subdirectory(motor2040) add_subdirectory(inventor2040w) add_subdirectory(encoder) +add_subdirectory(gfx_pack) diff --git a/examples/gfx_pack/CMakeLists.txt b/examples/gfx_pack/CMakeLists.txt new file mode 100644 index 00000000..90a7b0b7 --- /dev/null +++ b/examples/gfx_pack/CMakeLists.txt @@ -0,0 +1,12 @@ +set(OUTPUT_NAME gfx_pack_demo) + +add_executable( + ${OUTPUT_NAME} + gfx_demo.cpp +) + +# Pull in pico libraries that we need +target_link_libraries(${OUTPUT_NAME} pico_stdlib hardware_spi hardware_pwm hardware_dma rgbled button pico_display_2 st7568 pico_graphics) + +# create map/bin/hex file etc. +pico_add_extra_outputs(${OUTPUT_NAME}) \ No newline at end of file diff --git a/examples/gfx_pack/gfx_demo.cpp b/examples/gfx_pack/gfx_demo.cpp new file mode 100644 index 00000000..ad9d9bdf --- /dev/null +++ b/examples/gfx_pack/gfx_demo.cpp @@ -0,0 +1,124 @@ +#include +#include +#include +#include + +#include "libraries/pico_display_2/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; + +ST7789 st7789(320, 240, ROTATE_0, false, get_spi_pins(BG_SPI_FRONT)); +PicoGraphics_PenRGB332 graphics(st7789.width, st7789.height, nullptr); + +RGBLED led(PicoDisplay2::LED_R, PicoDisplay2::LED_G, PicoDisplay2::LED_B); + +Button button_a(PicoDisplay2::A); +Button button_b(PicoDisplay2::B); +Button button_x(PicoDisplay2::X); +Button button_y(PicoDisplay2::Y); + +// HSV Conversion expects float inputs in the range of 0.00-1.00 for each channel +// Outputs are rgb in the range 0-255 for each channel +void from_hsv(float h, float s, float v, uint8_t &r, uint8_t &g, uint8_t &b) { + float i = floor(h * 6.0f); + float f = h * 6.0f - i; + v *= 255.0f; + uint8_t p = v * (1.0f - s); + uint8_t q = v * (1.0f - f * s); + uint8_t t = v * (1.0f - (1.0f - f) * s); + + switch (int(i) % 6) { + case 0: r = v; g = t; b = p; break; + case 1: r = q; g = v; b = p; break; + case 2: r = p; g = v; b = t; break; + case 3: r = p; g = q; b = v; break; + case 4: r = t; g = p; b = v; break; + case 5: r = v; g = p; b = q; break; + } +} + +int main() { + st7789.set_backlight(255); + + struct pt { + float x; + float y; + uint8_t r; + float dx; + float dy; + uint16_t pen; + }; + + std::vector shapes; + for(int i = 0; i < 100; i++) { + pt shape; + shape.x = rand() % graphics.bounds.w; + shape.y = rand() % graphics.bounds.h; + shape.r = (rand() % 10) + 3; + shape.dx = float(rand() % 255) / 64.0f; + shape.dy = float(rand() % 255) / 64.0f; + shape.pen = graphics.create_pen(rand() % 255, rand() % 255, rand() % 255); + shapes.push_back(shape); + } + + Point text_location(0, 0); + + Pen BG = graphics.create_pen(120, 40, 60); + Pen WHITE = graphics.create_pen(255, 255, 255); + + while(true) { + if(button_a.raw()) text_location.x -= 1; + if(button_b.raw()) text_location.x += 1; + + if(button_x.raw()) text_location.y -= 1; + if(button_y.raw()) text_location.y += 1; + + graphics.set_pen(BG); + graphics.clear(); + + for(auto &shape : shapes) { + shape.x += shape.dx; + shape.y += shape.dy; + if((shape.x - shape.r) < 0) { + shape.dx *= -1; + shape.x = shape.r; + } + if((shape.x + shape.r) >= graphics.bounds.w) { + shape.dx *= -1; + shape.x = graphics.bounds.w - shape.r; + } + if((shape.y - shape.r) < 0) { + shape.dy *= -1; + shape.y = shape.r; + } + if((shape.y + shape.r) >= graphics.bounds.h) { + shape.dy *= -1; + shape.y = graphics.bounds.h - shape.r; + } + + graphics.set_pen(shape.pen); + graphics.circle(Point(shape.x, shape.y), shape.r); + + } + + // Since HSV takes a float from 0.0 to 1.0 indicating hue, + // then we can divide millis by the number of milliseconds + // we want a full colour cycle to take. 5000 = 5 sec. + uint8_t r = 0, g = 0, b = 0; + from_hsv((float)millis() / 5000.0f, 1.0f, 0.5f + sinf(millis() / 100.0f / 3.14159f) * 0.5f, r, g, b); + led.set_rgb(r, g, b); + + + graphics.set_pen(WHITE); + graphics.text("Hello World", text_location, 320); + + // update screen + st7789.update(&graphics); + } + + return 0; +} diff --git a/libraries/CMakeLists.txt b/libraries/CMakeLists.txt index b7fa264f..6d69f7d0 100644 --- a/libraries/CMakeLists.txt +++ b/libraries/CMakeLists.txt @@ -35,3 +35,4 @@ add_subdirectory(inventor2040w) add_subdirectory(adcfft) add_subdirectory(jpegdec) add_subdirectory(inky_frame) +add_subdirectory(gfx_pack) diff --git a/libraries/gfx_pack/CMakeLists.txt b/libraries/gfx_pack/CMakeLists.txt new file mode 100644 index 00000000..3b2ea54e --- /dev/null +++ b/libraries/gfx_pack/CMakeLists.txt @@ -0,0 +1,11 @@ +set(LIB_NAME gfx_pack) +add_library(${LIB_NAME} INTERFACE) + +target_sources(${LIB_NAME} INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/${LIB_NAME}.cpp +) + +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 hardware_spi hardware_pwm hardware_dma st7789 pico_graphics) \ No newline at end of file diff --git a/libraries/gfx_pack/README.md b/libraries/gfx_pack/README.md new file mode 100644 index 00000000..53ad9c6d --- /dev/null +++ b/libraries/gfx_pack/README.md @@ -0,0 +1,84 @@ +# Pico Display 2.0" Pack + +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! + +- [Example Program](#example-program) +- [Function Reference](#function-reference) + - [PicoGraphics](#picographics) + - [ST7789](#st7789) + +## Example Program + +The following example sets up Pico Display, displays some basic demo text and graphics and will illuminate the RGB LED green if the A button is pressed. + +```c++ +#include "pico_display_2.hpp" +#include "drivers/st7789/st7789.hpp" +#include "libraries/pico_graphics/pico_graphics.hpp" +#include "rgbled.hpp" +#include "button.hpp" + +// Display driver +ST7789 st7789(PicoDisplay2::WIDTH, PicoDisplay2::HEIGHT, ROTATE_0, false, get_spi_pins(BG_SPI_FRONT)); + +// 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() { + + // 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. + st7789.set_backlight(100); + + while(true) { + // detect if the A button is pressed (could be A, B, X, or Y) + 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 + led.set_rgb(0, 255, 0); + } + + // set the colour of the pen + // parameters are red, green, blue all between 0 and 255 + graphics.set_pen(30, 40, 50); + + // fill the screen with the current pen colour + graphics.clear(); + + // draw a box to put some text in + graphics.set_pen(10, 20, 30); + Rect text_rect(10, 10, 150, 150); + graphics.rectangle(text_rect); + + // write some text inside the box with 10 pixels of margin + // automatically word wrapping + text_rect.deflate(10); + 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 + st7789.update(&graphics); + } +} +``` + +## Function Reference + +### PicoGraphics + +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). + +### ST7789 + +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/gfx_pack/gfx_pack.cmake b/libraries/gfx_pack/gfx_pack.cmake new file mode 100644 index 00000000..b7348688 --- /dev/null +++ b/libraries/gfx_pack/gfx_pack.cmake @@ -0,0 +1,10 @@ +add_library(pico_display_2 INTERFACE) + +target_sources(pico_display_2 INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/pico_display_2.cpp +) + +target_include_directories(pico_display_2 INTERFACE ${CMAKE_CURRENT_LIST_DIR}) + +# Pull in pico libraries that we need +target_link_libraries(pico_display_2 INTERFACE pico_stdlib) \ No newline at end of file diff --git a/libraries/gfx_pack/gfx_pack.cpp b/libraries/gfx_pack/gfx_pack.cpp new file mode 100644 index 00000000..162f2bc7 --- /dev/null +++ b/libraries/gfx_pack/gfx_pack.cpp @@ -0,0 +1 @@ +#include "gfx_pack.hpp" \ No newline at end of file diff --git a/libraries/gfx_pack/gfx_pack.hpp b/libraries/gfx_pack/gfx_pack.hpp new file mode 100644 index 00000000..8a231874 --- /dev/null +++ b/libraries/gfx_pack/gfx_pack.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "pico/stdlib.h" + +namespace pimoroni { + class gfx_pack { + public: + static const int WIDTH = 128; + static const int HEIGHT = 64; + static const uint8_t A = 12; + static const uint8_t B = 13; + static const uint8_t X = 14; + static const uint8_t Y = 15; + static const uint8_t BL_R = 6; + static const uint8_t BL_G = 7; + static const uint8_t BL_B = 8; + static const uint8_t BL_W = 9; + }; +} From 7b5946ef48a8863726d603e43d03554307924abf Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Thu, 29 Sep 2022 15:48:33 +0100 Subject: [PATCH 03/28] all complies needs testing against finished unit --- drivers/st7567/st7567.cpp | 35 ++++++++++++++++---------------- drivers/st7567/st7567.hpp | 25 ++++++++++------------- examples/gfx_pack/CMakeLists.txt | 2 +- examples/gfx_pack/gfx_demo.cpp | 33 +++++++++++++++--------------- 4 files changed, 47 insertions(+), 48 deletions(-) diff --git a/drivers/st7567/st7567.cpp b/drivers/st7567/st7567.cpp index f7a1a945..bd8e9791 100644 --- a/drivers/st7567/st7567.cpp +++ b/drivers/st7567/st7567.cpp @@ -1,4 +1,4 @@ -#include "ST7567.hpp" +#include "st7567.hpp" #include #include @@ -49,9 +49,9 @@ namespace pimoroni { }; void ST7567::reset() { - if(RESET == PIN_UNUSED) return; - gpio_put(RESET, 0); sleep_ms(10); - gpio_put(RESET, 1); sleep_ms(10); + if(reset_pin == PIN_UNUSED) return; + gpio_put(reset_pin, 0); sleep_ms(10); + gpio_put(reset_pin, 1); sleep_ms(10); sleep_ms(100); } @@ -59,8 +59,8 @@ namespace pimoroni { void ST7567::init(bool auto_init_sequence) { spi_init(spi, spi_baud); - gpio_set_function(reset, GPIO_FUNC_SIO); - gpio_set_dir(reset, GPIO_OUT); + gpio_set_function(reset_pin, GPIO_FUNC_SIO); + gpio_set_dir(reset_pin, GPIO_OUT); gpio_set_function(dc, GPIO_FUNC_SIO); gpio_set_dir(dc, GPIO_OUT); @@ -124,12 +124,12 @@ namespace pimoroni { // Native 16-bit framebuffer update void ST7567::update(PicoGraphics *graphics) { - uint8_t offset; + uint8_t *fb = (uint8_t *)graphics->frame_buffer; if(graphics->pen_type == PicoGraphics::PEN_1BIT) { - command(reg::ENTER_RWMODE); + command(reg::ENTER_RMWMODE); for (uint8_t page=0; page < 8 ; page++){ command(reg::SETPAGESTART | page); command(reg::SETCOLL); @@ -137,32 +137,33 @@ namespace pimoroni { gpio_put(dc, 1); // data mode gpio_put(cs, 0); spi_write_blocking(spi, fb, PAGESIZE / 8); - fb += PAGESIZE / 8; + fb += (PAGESIZE / 8); gpio_put(cs, 1); } - } else { - command(reg::ENTER_RWMODE); + } /*else { + command(reg::ENTER_RMWMODE); gpio_put(dc, 1); // data mode gpio_put(cs, 0); graphics->frame_convert(PicoGraphics::PEN_1BIT, [this](void *data, size_t length) { if (length > 0) { for (uint8_t page=0; page < 8 ; page++){ - offset = page * PAGESIZE; + command(reg::SETPAGESTART | page); command(reg::SETCOLL); command(reg::SETCOLH); gpio_put(dc, 1); // data mode gpio_put(cs, 0); - spi_write_blocking(spi, (const uint8_t*)data[offset/8], PAGESIZE / 8); + spi_write_blocking(spi, fb, PAGESIZE / 8); + fb += PAGESIZE / 8; gpio_put(cs, 1); } - }); - + }; +*/ gpio_put(cs, 1); - } + } void ST7567::set_backlight(uint8_t brightness) { @@ -172,4 +173,4 @@ namespace pimoroni { uint16_t value = (uint16_t)(pow((float)(brightness) / 255.0f, gamma) * 65535.0f + 0.5f); pwm_set_gpio_level(bl, value); } -} \ No newline at end of file +} diff --git a/drivers/st7567/st7567.hpp b/drivers/st7567/st7567.hpp index 13848722..ee6fc2f1 100644 --- a/drivers/st7567/st7567.hpp +++ b/drivers/st7567/st7567.hpp @@ -22,19 +22,19 @@ namespace pimoroni { //-------------------------------------------------- private: - spi_inst_t *spi = spi0; + spi_inst_t *spi = spi0; uint32_t dma_channel; // interface pins with our standard defaults where appropriate - uint cs = SPI_BG_FRONT_CS; - uint dc = 20; - uint sck = SPI_DEFAULT_SCK ; - uint mosi = SPI_DEFAULT_MOSI; - uint bl = PIN_UNUSED; - uint reset = PIN_UNUSED; + uint cs; + uint dc; + uint sck; + uint mosi; + uint bl; + uint reset_pin; - uint32_t spi_baud = 30 * 1024 * 1024; + uint32_t spi_baud = 1 * 1024 * 1024; uint8_t offset_cols = 0; uint8_t offset_rows = 0; @@ -43,22 +43,19 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - ST7567(uint16_t width, uint16_t height, Rotation rotate) : ST7567(width, height, rotate, {PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, 20, PIN_UNUSED}) {}; - - ST7567(uint16_t width, uint16_t height, SPIPins pins, uint busy=26, uint reset=21) : + ST7567(uint16_t width, uint16_t height, SPIPins pins) : DisplayDriver(width, height, ROTATE_0), - spi(pins.spi), - CS(pins.cs), DC(pins.dc), SCK(pins.sck), MOSI(pins.mosi), BUSY(busy), RESET(reset) { + spi(pins.spi), cs(pins.cs), dc(pins.dc), sck(pins.sck), mosi(pins.mosi), bl(pins.bl) { init(); } - //-------------------------------------------------- // Methods //-------------------------------------------------- public: void update(PicoGraphics *graphics) override; void set_backlight(uint8_t brightness) override; + void reset(); private: void init(bool auto_init_sequence = true); diff --git a/examples/gfx_pack/CMakeLists.txt b/examples/gfx_pack/CMakeLists.txt index 90a7b0b7..c12c2118 100644 --- a/examples/gfx_pack/CMakeLists.txt +++ b/examples/gfx_pack/CMakeLists.txt @@ -6,7 +6,7 @@ add_executable( ) # Pull in pico libraries that we need -target_link_libraries(${OUTPUT_NAME} pico_stdlib hardware_spi hardware_pwm hardware_dma rgbled button pico_display_2 st7568 pico_graphics) +target_link_libraries(${OUTPUT_NAME} pico_stdlib hardware_spi hardware_pwm hardware_dma rgbled button pico_display_2 st7567 pico_graphics) # create map/bin/hex file etc. pico_add_extra_outputs(${OUTPUT_NAME}) \ No newline at end of file diff --git a/examples/gfx_pack/gfx_demo.cpp b/examples/gfx_pack/gfx_demo.cpp index ad9d9bdf..596abf61 100644 --- a/examples/gfx_pack/gfx_demo.cpp +++ b/examples/gfx_pack/gfx_demo.cpp @@ -1,25 +1,26 @@ -#include #include -#include #include +#include +#include +#include -#include "libraries/pico_display_2/pico_display_2.hpp" -#include "drivers/st7789/st7789.hpp" +#include "pico/stdlib.h" #include "libraries/pico_graphics/pico_graphics.hpp" -#include "rgbled.hpp" -#include "button.hpp" +#include "libraries/gfx_pack/gfx_pack.hpp" +#include "drivers/st7567/st7567.hpp" +#include "drivers/button/button.hpp" using namespace pimoroni; -ST7789 st7789(320, 240, ROTATE_0, false, get_spi_pins(BG_SPI_FRONT)); -PicoGraphics_PenRGB332 graphics(st7789.width, st7789.height, nullptr); +ST7567 st7567(128, 64, get_spi_pins(BG_SPI_FRONT)); +PicoGraphics_PenRGB332 graphics(st7567.width, st7567.height, nullptr); -RGBLED led(PicoDisplay2::LED_R, PicoDisplay2::LED_G, PicoDisplay2::LED_B); -Button button_a(PicoDisplay2::A); -Button button_b(PicoDisplay2::B); -Button button_x(PicoDisplay2::X); -Button button_y(PicoDisplay2::Y); + +Button button_a(gfx_pack::A); +Button button_b(gfx_pack::B); +Button button_x(gfx_pack::X); +Button button_y(gfx_pack::Y); // HSV Conversion expects float inputs in the range of 0.00-1.00 for each channel // Outputs are rgb in the range 0-255 for each channel @@ -42,7 +43,7 @@ void from_hsv(float h, float s, float v, uint8_t &r, uint8_t &g, uint8_t &b) { } int main() { - st7789.set_backlight(255); + st7567.set_backlight(255); struct pt { float x; @@ -110,14 +111,14 @@ int main() { // we want a full colour cycle to take. 5000 = 5 sec. uint8_t r = 0, g = 0, b = 0; from_hsv((float)millis() / 5000.0f, 1.0f, 0.5f + sinf(millis() / 100.0f / 3.14159f) * 0.5f, r, g, b); - led.set_rgb(r, g, b); + graphics.set_pen(WHITE); graphics.text("Hello World", text_location, 320); // update screen - st7789.update(&graphics); + st7567.update(&graphics); } return 0; From 8f645257c32919b8e6bd0920d686c65209309c17 Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Wed, 5 Oct 2022 14:26:17 +0100 Subject: [PATCH 04/28] display running but data corrupt --- drivers/st7567/st7567.cpp | 15 ++++++++++----- drivers/st7567/st7567.hpp | 4 ++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/st7567/st7567.cpp b/drivers/st7567/st7567.cpp index bd8e9791..0b21ea32 100644 --- a/drivers/st7567/st7567.cpp +++ b/drivers/st7567/st7567.cpp @@ -97,10 +97,10 @@ namespace pimoroni { command(reg::DISPNORMAL); command(reg::SETSTARTLINE | 0x00); //Startline from 0x40-0x7F command(reg::POWERCTRL); - command(reg::REG_RATIO | 3); + command(reg::REG_RATIO | 4); command(reg::DISPON); command(reg::SETCONTRAST); - command(58); // defalut contrast level + command(30); // defalut contrast level } if(bl != PIN_UNUSED) { @@ -113,13 +113,17 @@ namespace pimoroni { gpio_put(dc, 0); // command mode spi_write_blocking(spi, &command, 1); + gpio_put(cs, 1); + sleep_us(100); if(data) { + gpio_put(cs, 0); gpio_put(dc, 1); // data mode spi_write_blocking(spi, (const uint8_t*)data, len); + gpio_put(cs, 1); } - gpio_put(cs, 1); + } // Native 16-bit framebuffer update @@ -136,9 +140,10 @@ namespace pimoroni { command(reg::SETCOLH); gpio_put(dc, 1); // data mode gpio_put(cs, 0); - spi_write_blocking(spi, fb, PAGESIZE / 8); - fb += (PAGESIZE / 8); + spi_write_blocking(spi, fb, PAGESIZE ); + fb += (PAGESIZE/8); gpio_put(cs, 1); + gpio_put(dc, 0); // Back to command mode } diff --git a/drivers/st7567/st7567.hpp b/drivers/st7567/st7567.hpp index ee6fc2f1..573d8251 100644 --- a/drivers/st7567/st7567.hpp +++ b/drivers/st7567/st7567.hpp @@ -32,9 +32,9 @@ namespace pimoroni { uint sck; uint mosi; uint bl; - uint reset_pin; + uint reset_pin=21; - uint32_t spi_baud = 1 * 1024 * 1024; + uint32_t spi_baud = 500000; uint8_t offset_cols = 0; uint8_t offset_rows = 0; From 2f7afad12d56857f9f78552dde892423b490e988 Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Thu, 6 Oct 2022 12:28:22 +0100 Subject: [PATCH 05/28] Update st7567.cpp still trying to get this working properly --- drivers/st7567/st7567.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/st7567/st7567.cpp b/drivers/st7567/st7567.cpp index 0b21ea32..90134e6a 100644 --- a/drivers/st7567/st7567.cpp +++ b/drivers/st7567/st7567.cpp @@ -140,8 +140,8 @@ namespace pimoroni { command(reg::SETCOLH); gpio_put(dc, 1); // data mode gpio_put(cs, 0); - spi_write_blocking(spi, fb, PAGESIZE ); - fb += (PAGESIZE/8); + spi_write_blocking(spi, fb, PAGESIZE/8 ); + fb += (PAGESIZE); gpio_put(cs, 1); gpio_put(dc, 0); // Back to command mode From 337cd390d4d1314a5afa8f7613e0cfecbb85534c Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Mon, 10 Oct 2022 14:12:45 +0100 Subject: [PATCH 06/28] wip --- drivers/st7567/st7567.cpp | 53 +++++++++++++++++++++++++++++++++++++-- drivers/st7567/st7567.hpp | 4 +-- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/drivers/st7567/st7567.cpp b/drivers/st7567/st7567.cpp index 90134e6a..e8dd8cdb 100644 --- a/drivers/st7567/st7567.cpp +++ b/drivers/st7567/st7567.cpp @@ -6,6 +6,17 @@ #include "hardware/dma.h" #include "hardware/pwm.h" +#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" +#define BYTE_TO_BINARY(byte) \ + (byte & 0x80 ? '1' : '0'), \ + (byte & 0x40 ? '1' : '0'), \ + (byte & 0x20 ? '1' : '0'), \ + (byte & 0x10 ? '1' : '0'), \ + (byte & 0x08 ? '1' : '0'), \ + (byte & 0x04 ? '1' : '0'), \ + (byte & 0x02 ? '1' : '0'), \ + (byte & 0x01 ? '1' : '0') + namespace pimoroni { enum reg : uint8_t { @@ -130,6 +141,42 @@ namespace pimoroni { void ST7567::update(PicoGraphics *graphics) { uint8_t *fb = (uint8_t *)graphics->frame_buffer; + uint8_t *page_p = (uint8_t *)graphics->frame_buffer; + uint8_t *byte_p = page_p; + uint8_t page_buffer[128]; + for (int i=0 ; i < 128 ; i++){ + page_buffer[i] = i; + } + uint8_t col_byte = 0; + /* + 1111111111 + 0000000000 + 1111111111 + 0000000000 + to + 1010101010 + 1010101010 + 1010101010 + 1010101010 + */ + + + //0b00000011 = 0b000000001 0b00000001 + + + /* + for (uint8_t pb_col_byte_index=0; pb_col_byte_index < 128; pb_col_byte_index++ ){ + + for (uint8_t fb_row_bit_index=0; fb_row_bit_index < 8; fb_row_bit_index++ ){ + byte_p = byte_p + ((16 * fb_row_bit_index) + (pb_col_byte_index / 8)); + page_buffer[pb_col_byte_index] = (*byte_p) & (1 << fb_row_bit_index); + + + } + + } + */ + if(graphics->pen_type == PicoGraphics::PEN_1BIT) { @@ -140,14 +187,16 @@ namespace pimoroni { command(reg::SETCOLH); gpio_put(dc, 1); // data mode gpio_put(cs, 0); - spi_write_blocking(spi, fb, PAGESIZE/8 ); + spi_write_blocking(spi, &page_buffer[0], PAGESIZE ); fb += (PAGESIZE); gpio_put(cs, 1); gpio_put(dc, 0); // Back to command mode } - } /*else { + } + + /*else { command(reg::ENTER_RMWMODE); gpio_put(dc, 1); // data mode gpio_put(cs, 0); diff --git a/drivers/st7567/st7567.hpp b/drivers/st7567/st7567.hpp index 573d8251..0aff9b36 100644 --- a/drivers/st7567/st7567.hpp +++ b/drivers/st7567/st7567.hpp @@ -13,8 +13,8 @@ namespace pimoroni { // Constants //-------------------------------------------------- private: - static const uint8_t ROWS = 128; - static const uint8_t COLS = 64; + static const uint8_t ROWS = 64; + static const uint8_t COLS = 128; static const uint8_t PAGESIZE = 128; //-------------------------------------------------- From fa04fef4f0c659242470b1f1e0691a26fb963aa6 Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Mon, 10 Oct 2022 14:33:28 +0100 Subject: [PATCH 07/28] Update st7567.cpp --- drivers/st7567/st7567.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/st7567/st7567.cpp b/drivers/st7567/st7567.cpp index e8dd8cdb..079ff6b1 100644 --- a/drivers/st7567/st7567.cpp +++ b/drivers/st7567/st7567.cpp @@ -163,19 +163,21 @@ namespace pimoroni { //0b00000011 = 0b000000001 0b00000001 + uint8_t row_offset=0 + + for (uint8_t fb_byte_index=0; fb_byte_index < 16; fb_byte_index ++ ){ + + uint8_t new_loc = fb_byte_index * 8 + - /* - for (uint8_t pb_col_byte_index=0; pb_col_byte_index < 128; pb_col_byte_index++ ){ - - for (uint8_t fb_row_bit_index=0; fb_row_bit_index < 8; fb_row_bit_index++ ){ - byte_p = byte_p + ((16 * fb_row_bit_index) + (pb_col_byte_index / 8)); - page_buffer[pb_col_byte_index] = (*byte_p) & (1 << fb_row_bit_index); - } + } - */ + + + From 0e5e7feb7d3dea75fa1126c22cfddc643de555e8 Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Wed, 12 Oct 2022 09:13:38 +0100 Subject: [PATCH 08/28] page 0 working --- drivers/st7567/st7567.cpp | 46 ++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/drivers/st7567/st7567.cpp b/drivers/st7567/st7567.cpp index 079ff6b1..c644e82f 100644 --- a/drivers/st7567/st7567.cpp +++ b/drivers/st7567/st7567.cpp @@ -141,41 +141,37 @@ namespace pimoroni { void ST7567::update(PicoGraphics *graphics) { uint8_t *fb = (uint8_t *)graphics->frame_buffer; - uint8_t *page_p = (uint8_t *)graphics->frame_buffer; - uint8_t *byte_p = page_p; uint8_t page_buffer[128]; + uint8_t page_byte_selector; + uint8_t page_bit_selector; + // clear page buffer for (int i=0 ; i < 128 ; i++){ - page_buffer[i] = i; + page_buffer[i] = 0; } - uint8_t col_byte = 0; - /* - 1111111111 - 0000000000 - 1111111111 - 0000000000 - to - 1010101010 - 1010101010 - 1010101010 - 1010101010 - */ + for (uint16_t pixel_index=0 ; pixel_index < (128 * 8) ; pixel_index++){ + page_byte_selector = ((pixel_index % 128)) ; + page_bit_selector = (pixel_index / 128); - //0b00000011 = 0b000000001 0b00000001 - - uint8_t row_offset=0 - - for (uint8_t fb_byte_index=0; fb_byte_index < 16; fb_byte_index ++ ){ + // printf ("fb byte %d fb bit %d set to %d\n", page_byte_selector, page_bit_selector, *fb & (1 << (pixel_index % 8))); + - uint8_t new_loc = fb_byte_index * 8 + if (*fb & (0b10000000 >> (pixel_index % 8))){ // check selected pixel is present + page_buffer[page_byte_selector] |= (1 << page_bit_selector); + } + else{ + page_buffer[page_byte_selector] &= ~( 1 << page_bit_selector); + } + if ((pixel_index % 8) >= 7 ){ //increment fb pointer at end of byte + + fb++; + + } - - - } - + } From d03c00383a3c7b0bd060a3b5e96f27654e503e2b Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Wed, 12 Oct 2022 11:07:17 +0100 Subject: [PATCH 09/28] driver working for PG1Bit mode --- drivers/st7567/st7567.cpp | 55 ++++++---------------------------- drivers/st7567/st7567.hpp | 2 +- examples/gfx_pack/gfx_demo.cpp | 22 ++++++-------- 3 files changed, 19 insertions(+), 60 deletions(-) diff --git a/drivers/st7567/st7567.cpp b/drivers/st7567/st7567.cpp index c644e82f..32aa8b18 100644 --- a/drivers/st7567/st7567.cpp +++ b/drivers/st7567/st7567.cpp @@ -141,19 +141,14 @@ namespace pimoroni { void ST7567::update(PicoGraphics *graphics) { uint8_t *fb = (uint8_t *)graphics->frame_buffer; - uint8_t page_buffer[128]; + uint8_t page_buffer[PAGESIZE]; uint8_t page_byte_selector; uint8_t page_bit_selector; - // clear page buffer - for (int i=0 ; i < 128 ; i++){ - page_buffer[i] = 0; - } + for (uint8_t page=0; page < 8 ; page++){ //select page - for (uint16_t pixel_index=0 ; pixel_index < (128 * 8) ; pixel_index++){ - page_byte_selector = ((pixel_index % 128)) ; + for (uint16_t pixel_index=0 ; pixel_index < (PAGESIZE * 8) ; pixel_index++){ //cycle through a page worth of bits from the fb + page_byte_selector = ((pixel_index % 128)); page_bit_selector = (pixel_index / 128); - - // printf ("fb byte %d fb bit %d set to %d\n", page_byte_selector, page_bit_selector, *fb & (1 << (pixel_index % 8))); if (*fb & (0b10000000 >> (pixel_index % 8))){ // check selected pixel is present @@ -162,58 +157,26 @@ namespace pimoroni { else{ page_buffer[page_byte_selector] &= ~( 1 << page_bit_selector); } - - - if ((pixel_index % 8) >= 7 ){ //increment fb pointer at end of byte - - - fb++; - + + if ((pixel_index % 8) >= 7 ){ //increment fb pointer at end of byte + fb++; } - } - - - if(graphics->pen_type == PicoGraphics::PEN_1BIT) { command(reg::ENTER_RMWMODE); - for (uint8_t page=0; page < 8 ; page++){ + command(reg::SETPAGESTART | page); command(reg::SETCOLL); command(reg::SETCOLH); gpio_put(dc, 1); // data mode gpio_put(cs, 0); spi_write_blocking(spi, &page_buffer[0], PAGESIZE ); - fb += (PAGESIZE); gpio_put(cs, 1); gpio_put(dc, 0); // Back to command mode - - } - } - - /*else { - command(reg::ENTER_RMWMODE); - gpio_put(dc, 1); // data mode - gpio_put(cs, 0); - - graphics->frame_convert(PicoGraphics::PEN_1BIT, [this](void *data, size_t length) { - if (length > 0) { - for (uint8_t page=0; page < 8 ; page++){ - - command(reg::SETPAGESTART | page); - command(reg::SETCOLL); - command(reg::SETCOLH); - gpio_put(dc, 1); // data mode - gpio_put(cs, 0); - spi_write_blocking(spi, fb, PAGESIZE / 8); - fb += PAGESIZE / 8; - gpio_put(cs, 1); - } - }; -*/ + } gpio_put(cs, 1); } diff --git a/drivers/st7567/st7567.hpp b/drivers/st7567/st7567.hpp index 0aff9b36..be51b4c8 100644 --- a/drivers/st7567/st7567.hpp +++ b/drivers/st7567/st7567.hpp @@ -34,7 +34,7 @@ namespace pimoroni { uint bl; uint reset_pin=21; - uint32_t spi_baud = 500000; + uint32_t spi_baud = 10000000; //10Mhz uint8_t offset_cols = 0; uint8_t offset_rows = 0; diff --git a/examples/gfx_pack/gfx_demo.cpp b/examples/gfx_pack/gfx_demo.cpp index 596abf61..6e885cd2 100644 --- a/examples/gfx_pack/gfx_demo.cpp +++ b/examples/gfx_pack/gfx_demo.cpp @@ -12,8 +12,8 @@ using namespace pimoroni; -ST7567 st7567(128, 64, get_spi_pins(BG_SPI_FRONT)); -PicoGraphics_PenRGB332 graphics(st7567.width, st7567.height, nullptr); +ST7567 st7567(128, 64, {PIMORONI_SPI_DEFAULT_INSTANCE, 17, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, 16, SPI_BG_FRONT_PWM}); +PicoGraphics_Pen1Bit graphics(st7567.width, st7567.height, nullptr); @@ -55,21 +55,21 @@ int main() { }; std::vector shapes; - for(int i = 0; i < 100; i++) { + for(int i = 0; i < 10; i++) { pt shape; shape.x = rand() % graphics.bounds.w; shape.y = rand() % graphics.bounds.h; shape.r = (rand() % 10) + 3; shape.dx = float(rand() % 255) / 64.0f; shape.dy = float(rand() % 255) / 64.0f; - shape.pen = graphics.create_pen(rand() % 255, rand() % 255, rand() % 255); + shape.pen = rand() % 14; shapes.push_back(shape); } Point text_location(0, 0); - Pen BG = graphics.create_pen(120, 40, 60); - Pen WHITE = graphics.create_pen(255, 255, 255); + //Pen BG = graphics.create_pen(120, 40, 60); + //Pen WHITE = graphics.create_pen(255, 255, 255); while(true) { if(button_a.raw()) text_location.x -= 1; @@ -78,7 +78,7 @@ int main() { if(button_x.raw()) text_location.y -= 1; if(button_y.raw()) text_location.y += 1; - graphics.set_pen(BG); + graphics.set_pen(0); graphics.clear(); for(auto &shape : shapes) { @@ -106,19 +106,15 @@ int main() { } - // Since HSV takes a float from 0.0 to 1.0 indicating hue, - // then we can divide millis by the number of milliseconds - // we want a full colour cycle to take. 5000 = 5 sec. - uint8_t r = 0, g = 0, b = 0; - from_hsv((float)millis() / 5000.0f, 1.0f, 0.5f + sinf(millis() / 100.0f / 3.14159f) * 0.5f, r, g, b); - graphics.set_pen(WHITE); + graphics.set_pen(15); graphics.text("Hello World", text_location, 320); // update screen st7567.update(&graphics); + sleep_ms(1000/15); } return 0; From 54018afde39e6de2c8c24195c7e7043f50da4ea0 Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Wed, 12 Oct 2022 13:10:12 +0100 Subject: [PATCH 10/28] small tweeks --- drivers/st7567/st7567.cpp | 4 ++++ drivers/st7567/st7567.hpp | 5 +++++ examples/gfx_pack/gfx_demo.cpp | 7 ++----- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/st7567/st7567.cpp b/drivers/st7567/st7567.cpp index 32aa8b18..06f12bd6 100644 --- a/drivers/st7567/st7567.cpp +++ b/drivers/st7567/st7567.cpp @@ -144,6 +144,7 @@ namespace pimoroni { uint8_t page_buffer[PAGESIZE]; uint8_t page_byte_selector; uint8_t page_bit_selector; + for (uint8_t page=0; page < 8 ; page++){ //select page for (uint16_t pixel_index=0 ; pixel_index < (PAGESIZE * 8) ; pixel_index++){ //cycle through a page worth of bits from the fb @@ -176,6 +177,9 @@ namespace pimoroni { gpio_put(cs, 1); gpio_put(dc, 0); // Back to command mode } + else{ //other pen types incompatable + return; + } } gpio_put(cs, 1); diff --git a/drivers/st7567/st7567.hpp b/drivers/st7567/st7567.hpp index be51b4c8..de0956b3 100644 --- a/drivers/st7567/st7567.hpp +++ b/drivers/st7567/st7567.hpp @@ -8,6 +8,8 @@ namespace pimoroni { + + class ST7567 : public DisplayDriver { //-------------------------------------------------- // Constants @@ -43,11 +45,14 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: + SPIPins gfx_pack_pins = {PIMORONI_SPI_DEFAULT_INSTANCE, 17, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, 16, SPI_BG_FRONT_PWM}; + ST7567(uint16_t width, uint16_t height, SPIPins pins) : DisplayDriver(width, height, ROTATE_0), spi(pins.spi), cs(pins.cs), dc(pins.dc), sck(pins.sck), mosi(pins.mosi), bl(pins.bl) { init(); } + //-------------------------------------------------- // Methods diff --git a/examples/gfx_pack/gfx_demo.cpp b/examples/gfx_pack/gfx_demo.cpp index 6e885cd2..5b4258b1 100644 --- a/examples/gfx_pack/gfx_demo.cpp +++ b/examples/gfx_pack/gfx_demo.cpp @@ -11,8 +11,8 @@ #include "drivers/button/button.hpp" using namespace pimoroni; - -ST7567 st7567(128, 64, {PIMORONI_SPI_DEFAULT_INSTANCE, 17, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, 16, SPI_BG_FRONT_PWM}); +SPIPins pins = {PIMORONI_SPI_DEFAULT_INSTANCE, 17, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, 16, SPI_BG_FRONT_PWM}; +ST7567 st7567(128, 64, pins); PicoGraphics_Pen1Bit graphics(st7567.width, st7567.height, nullptr); @@ -106,9 +106,6 @@ int main() { } - - - graphics.set_pen(15); graphics.text("Hello World", text_location, 320); From 9af1081e68a01f9956419c1ff741eae8c53836bc Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Fri, 28 Oct 2022 17:54:37 +0100 Subject: [PATCH 11/28] gfx c libs working --- drivers/st7567/st7567.cpp | 21 ++++++++++----------- drivers/st7567/st7567.hpp | 3 +-- examples/gfx_pack/gfx_demo.cpp | 32 +++++++++++++++++++------------- libraries/gfx_pack/gfx_pack.hpp | 12 +++++++++--- 4 files changed, 39 insertions(+), 29 deletions(-) diff --git a/drivers/st7567/st7567.cpp b/drivers/st7567/st7567.cpp index 06f12bd6..1a66de67 100644 --- a/drivers/st7567/st7567.cpp +++ b/drivers/st7567/st7567.cpp @@ -147,7 +147,7 @@ namespace pimoroni { for (uint8_t page=0; page < 8 ; page++){ //select page - for (uint16_t pixel_index=0 ; pixel_index < (PAGESIZE * 8) ; pixel_index++){ //cycle through a page worth of bits from the fb + for (uint16_t pixel_index=0 ; pixel_index < (PAGESIZE * 8) ; pixel_index++){ //cycle through a page worth of bits from the fb page_byte_selector = ((pixel_index % 128)); page_bit_selector = (pixel_index / 128); @@ -167,22 +167,21 @@ namespace pimoroni { if(graphics->pen_type == PicoGraphics::PEN_1BIT) { command(reg::ENTER_RMWMODE); - - command(reg::SETPAGESTART | page); - command(reg::SETCOLL); - command(reg::SETCOLH); - gpio_put(dc, 1); // data mode - gpio_put(cs, 0); - spi_write_blocking(spi, &page_buffer[0], PAGESIZE ); - gpio_put(cs, 1); - gpio_put(dc, 0); // Back to command mode + command(reg::SETPAGESTART | page); + command(reg::SETCOLL); + command(reg::SETCOLH); + gpio_put(dc, 1); // data mode + gpio_put(cs, 0); + spi_write_blocking(spi, &page_buffer[0], PAGESIZE ); + gpio_put(cs, 1); + gpio_put(dc, 0); // Back to command mode } else{ //other pen types incompatable return; } } gpio_put(cs, 1); - + } void ST7567::set_backlight(uint8_t brightness) { diff --git a/drivers/st7567/st7567.hpp b/drivers/st7567/st7567.hpp index de0956b3..001be289 100644 --- a/drivers/st7567/st7567.hpp +++ b/drivers/st7567/st7567.hpp @@ -34,7 +34,7 @@ namespace pimoroni { uint sck; uint mosi; uint bl; - uint reset_pin=21; + uint reset_pin; uint32_t spi_baud = 10000000; //10Mhz @@ -45,7 +45,6 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - SPIPins gfx_pack_pins = {PIMORONI_SPI_DEFAULT_INSTANCE, 17, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, 16, SPI_BG_FRONT_PWM}; ST7567(uint16_t width, uint16_t height, SPIPins pins) : DisplayDriver(width, height, ROTATE_0), diff --git a/examples/gfx_pack/gfx_demo.cpp b/examples/gfx_pack/gfx_demo.cpp index 5b4258b1..6bd2d746 100644 --- a/examples/gfx_pack/gfx_demo.cpp +++ b/examples/gfx_pack/gfx_demo.cpp @@ -9,18 +9,19 @@ #include "libraries/gfx_pack/gfx_pack.hpp" #include "drivers/st7567/st7567.hpp" #include "drivers/button/button.hpp" +#include "drivers/rgbled/rgbled.hpp" using namespace pimoroni; -SPIPins pins = {PIMORONI_SPI_DEFAULT_INSTANCE, 17, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, 16, SPI_BG_FRONT_PWM}; -ST7567 st7567(128, 64, pins); + +ST7567 st7567(128, 64, gfx_pack_pins); PicoGraphics_Pen1Bit graphics(st7567.width, st7567.height, nullptr); +RGBLED backlight_rgb(GfxPack::BL_R, GfxPack::BL_G, GfxPack::BL_B, Polarity::ACTIVE_HIGH); - - -Button button_a(gfx_pack::A); -Button button_b(gfx_pack::B); -Button button_x(gfx_pack::X); -Button button_y(gfx_pack::Y); +Button button_a(GfxPack::A); +Button button_b(GfxPack::B); +Button button_c(GfxPack::C); +Button button_d(GfxPack::D); +Button button_e(GfxPack::E); // HSV Conversion expects float inputs in the range of 0.00-1.00 for each channel // Outputs are rgb in the range 0-255 for each channel @@ -43,6 +44,7 @@ void from_hsv(float h, float s, float v, uint8_t &r, uint8_t &g, uint8_t &b) { } int main() { + st7567.set_backlight(255); struct pt { @@ -68,15 +70,17 @@ int main() { Point text_location(0, 0); - //Pen BG = graphics.create_pen(120, 40, 60); - //Pen WHITE = graphics.create_pen(255, 255, 255); - +float hue = 0.0; while(true) { if(button_a.raw()) text_location.x -= 1; if(button_b.raw()) text_location.x += 1; - if(button_x.raw()) text_location.y -= 1; - if(button_y.raw()) text_location.y += 1; + if(button_c.raw()) text_location.y -= 1; + if(button_d.raw()) text_location.y += 1; + + if(button_e.raw()){ + text_location.x = 0; + text_location.y = 0;} graphics.set_pen(0); graphics.clear(); @@ -110,6 +114,8 @@ int main() { graphics.text("Hello World", text_location, 320); // update screen + backlight_rgb.set_hsv(hue, 0.0f, 1.0f); + hue += 0.002; st7567.update(&graphics); sleep_ms(1000/15); } diff --git a/libraries/gfx_pack/gfx_pack.hpp b/libraries/gfx_pack/gfx_pack.hpp index 8a231874..9256e135 100644 --- a/libraries/gfx_pack/gfx_pack.hpp +++ b/libraries/gfx_pack/gfx_pack.hpp @@ -1,16 +1,22 @@ #pragma once #include "pico/stdlib.h" +#include "common/pimoroni_bus.hpp" namespace pimoroni { - class gfx_pack { + + SPIPins gfx_pack_pins= {PIMORONI_SPI_DEFAULT_INSTANCE, 17, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, 20, 9}; + + class GfxPack{ + public: static const int WIDTH = 128; static const int HEIGHT = 64; static const uint8_t A = 12; static const uint8_t B = 13; - static const uint8_t X = 14; - static const uint8_t Y = 15; + static const uint8_t C = 14; + static const uint8_t D = 15; + static const uint8_t E = 22; static const uint8_t BL_R = 6; static const uint8_t BL_G = 7; static const uint8_t BL_B = 8; From 982253c416aaff93706ab95a2f58ba3fe9c51512 Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Fri, 28 Oct 2022 17:57:18 +0100 Subject: [PATCH 12/28] Update gfx_demo.cpp --- examples/gfx_pack/gfx_demo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/gfx_pack/gfx_demo.cpp b/examples/gfx_pack/gfx_demo.cpp index 6bd2d746..4d7fde10 100644 --- a/examples/gfx_pack/gfx_demo.cpp +++ b/examples/gfx_pack/gfx_demo.cpp @@ -45,7 +45,7 @@ void from_hsv(float h, float s, float v, uint8_t &r, uint8_t &g, uint8_t &b) { int main() { - st7567.set_backlight(255); + st7567.set_backlight(50); struct pt { float x; @@ -114,7 +114,7 @@ float hue = 0.0; graphics.text("Hello World", text_location, 320); // update screen - backlight_rgb.set_hsv(hue, 0.0f, 1.0f); + backlight_rgb.set_hsv(hue, 1.0f, 1.0f); hue += 0.002; st7567.update(&graphics); sleep_ms(1000/15); From e85367a961720a21132075983a2800a9cc39db47 Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Mon, 31 Oct 2022 13:44:23 +0000 Subject: [PATCH 13/28] started mp --- drivers/st7567/st7567.cpp | 2 +- drivers/st7567/st7567.hpp | 2 +- examples/gfx_pack/gfx_demo.cpp | 2 +- micropython/modules/picographics/picographics.c | 1 + micropython/modules/picographics/picographics.h | 3 ++- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/st7567/st7567.cpp b/drivers/st7567/st7567.cpp index 1a66de67..00153b89 100644 --- a/drivers/st7567/st7567.cpp +++ b/drivers/st7567/st7567.cpp @@ -62,6 +62,7 @@ namespace pimoroni { void ST7567::reset() { if(reset_pin == PIN_UNUSED) return; gpio_put(reset_pin, 0); sleep_ms(10); + sleep_ms(100); gpio_put(reset_pin, 1); sleep_ms(10); sleep_ms(100); } @@ -93,7 +94,6 @@ namespace pimoroni { } //reset display - reset(); diff --git a/drivers/st7567/st7567.hpp b/drivers/st7567/st7567.hpp index 001be289..e21e99a6 100644 --- a/drivers/st7567/st7567.hpp +++ b/drivers/st7567/st7567.hpp @@ -34,7 +34,7 @@ namespace pimoroni { uint sck; uint mosi; uint bl; - uint reset_pin; + uint reset_pin=21; uint32_t spi_baud = 10000000; //10Mhz diff --git a/examples/gfx_pack/gfx_demo.cpp b/examples/gfx_pack/gfx_demo.cpp index 4d7fde10..ec015567 100644 --- a/examples/gfx_pack/gfx_demo.cpp +++ b/examples/gfx_pack/gfx_demo.cpp @@ -16,7 +16,6 @@ using namespace pimoroni; ST7567 st7567(128, 64, gfx_pack_pins); PicoGraphics_Pen1Bit graphics(st7567.width, st7567.height, nullptr); RGBLED backlight_rgb(GfxPack::BL_R, GfxPack::BL_G, GfxPack::BL_B, Polarity::ACTIVE_HIGH); - Button button_a(GfxPack::A); Button button_b(GfxPack::B); Button button_c(GfxPack::C); @@ -44,6 +43,7 @@ void from_hsv(float h, float s, float v, uint8_t &r, uint8_t &g, uint8_t &b) { } int main() { + sleep_ms(100); st7567.set_backlight(50); diff --git a/micropython/modules/picographics/picographics.c b/micropython/modules/picographics/picographics.c index 590432e1..01d98ac8 100644 --- a/micropython/modules/picographics/picographics.c +++ b/micropython/modules/picographics/picographics.c @@ -124,6 +124,7 @@ STATIC const mp_map_elem_t picographics_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_DISPLAY_I2C_OLED_128X128), MP_ROM_INT(DISPLAY_I2C_OLED_128X128) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY_INKY_PACK), MP_ROM_INT(DISPLAY_INKY_PACK) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY_INKY_FRAME), MP_ROM_INT(DISPLAY_INKY_FRAME) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_GFX_PACK), MP_ROM_INT(DISPLAY_GFX_PACK)}, { MP_ROM_QSTR(MP_QSTR_PEN_1BIT), MP_ROM_INT(PEN_1BIT) }, { MP_ROM_QSTR(MP_QSTR_PEN_P4), MP_ROM_INT(PEN_P4) }, diff --git a/micropython/modules/picographics/picographics.h b/micropython/modules/picographics/picographics.h index 55d9d765..664d712c 100644 --- a/micropython/modules/picographics/picographics.h +++ b/micropython/modules/picographics/picographics.h @@ -12,7 +12,8 @@ enum PicoGraphicsDisplay { DISPLAY_LCD_160X80, DISPLAY_I2C_OLED_128X128, DISPLAY_INKY_PACK, - DISPLAY_INKY_FRAME + DISPLAY_INKY_FRAME, + DISPLAY_GFX_PACK }; enum PicoGraphicsPenType { From 79eb998183cd4764e2bbfa86b11c6b0c8cdf7c59 Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Wed, 2 Nov 2022 20:43:07 +0000 Subject: [PATCH 14/28] adjustments prior to micropython --- drivers/st7567/st7567.cmake | 2 +- drivers/st7567/st7567.cpp | 4 +--- examples/gfx_pack/CMakeLists.txt | 2 +- examples/gfx_pack/gfx_demo.cpp | 6 +----- libraries/gfx_pack/CMakeLists.txt | 12 +----------- libraries/gfx_pack/gfx_pack.cmake | 11 ++++++----- libraries/gfx_pack/gfx_pack.cpp | 10 +++++++++- libraries/gfx_pack/gfx_pack.hpp | 13 ++++++++----- 8 files changed, 28 insertions(+), 32 deletions(-) diff --git a/drivers/st7567/st7567.cmake b/drivers/st7567/st7567.cmake index 9207751e..85c022a4 100644 --- a/drivers/st7567/st7567.cmake +++ b/drivers/st7567/st7567.cmake @@ -7,4 +7,4 @@ target_sources(${DRIVER_NAME} INTERFACE target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib pimoroni_bus hardware_spi hardware_pwm hardware_dma) +target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib pimoroni_bus hardware_spi hardware_pwm) diff --git a/drivers/st7567/st7567.cpp b/drivers/st7567/st7567.cpp index 00153b89..c03fad58 100644 --- a/drivers/st7567/st7567.cpp +++ b/drivers/st7567/st7567.cpp @@ -1,10 +1,8 @@ #include "st7567.hpp" - +#include "hardware/pwm.h" #include #include -#include "hardware/dma.h" -#include "hardware/pwm.h" #define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" #define BYTE_TO_BINARY(byte) \ diff --git a/examples/gfx_pack/CMakeLists.txt b/examples/gfx_pack/CMakeLists.txt index c12c2118..0e378638 100644 --- a/examples/gfx_pack/CMakeLists.txt +++ b/examples/gfx_pack/CMakeLists.txt @@ -6,7 +6,7 @@ add_executable( ) # Pull in pico libraries that we need -target_link_libraries(${OUTPUT_NAME} pico_stdlib hardware_spi hardware_pwm hardware_dma rgbled button pico_display_2 st7567 pico_graphics) +target_link_libraries(${OUTPUT_NAME} pico_stdlib gfx_pack pico_graphics) # create map/bin/hex file etc. pico_add_extra_outputs(${OUTPUT_NAME}) \ No newline at end of file diff --git a/examples/gfx_pack/gfx_demo.cpp b/examples/gfx_pack/gfx_demo.cpp index ec015567..1ab96c75 100644 --- a/examples/gfx_pack/gfx_demo.cpp +++ b/examples/gfx_pack/gfx_demo.cpp @@ -5,15 +5,11 @@ #include #include "pico/stdlib.h" -#include "libraries/pico_graphics/pico_graphics.hpp" #include "libraries/gfx_pack/gfx_pack.hpp" -#include "drivers/st7567/st7567.hpp" -#include "drivers/button/button.hpp" -#include "drivers/rgbled/rgbled.hpp" using namespace pimoroni; -ST7567 st7567(128, 64, gfx_pack_pins); +ST7567 st7567(128, 64, GfxPack::gfx_pack_pins); PicoGraphics_Pen1Bit graphics(st7567.width, st7567.height, nullptr); RGBLED backlight_rgb(GfxPack::BL_R, GfxPack::BL_G, GfxPack::BL_B, Polarity::ACTIVE_HIGH); Button button_a(GfxPack::A); diff --git a/libraries/gfx_pack/CMakeLists.txt b/libraries/gfx_pack/CMakeLists.txt index 3b2ea54e..69ad037b 100644 --- a/libraries/gfx_pack/CMakeLists.txt +++ b/libraries/gfx_pack/CMakeLists.txt @@ -1,11 +1 @@ -set(LIB_NAME gfx_pack) -add_library(${LIB_NAME} INTERFACE) - -target_sources(${LIB_NAME} INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/${LIB_NAME}.cpp -) - -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 hardware_spi hardware_pwm hardware_dma st7789 pico_graphics) \ No newline at end of file +include(gfx_pack.cmake) \ No newline at end of file diff --git a/libraries/gfx_pack/gfx_pack.cmake b/libraries/gfx_pack/gfx_pack.cmake index b7348688..2985f968 100644 --- a/libraries/gfx_pack/gfx_pack.cmake +++ b/libraries/gfx_pack/gfx_pack.cmake @@ -1,10 +1,11 @@ -add_library(pico_display_2 INTERFACE) +set(LIB_NAME gfx_pack) +add_library(${LIB_NAME} INTERFACE) -target_sources(pico_display_2 INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/pico_display_2.cpp +target_sources(${LIB_NAME} INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/${LIB_NAME}.cpp ) -target_include_directories(pico_display_2 INTERFACE ${CMAKE_CURRENT_LIST_DIR}) +target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(pico_display_2 INTERFACE pico_stdlib) \ No newline at end of file +target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib hardware_spi pimoroni_bus st7567 pico_graphics button rgbled) \ No newline at end of file diff --git a/libraries/gfx_pack/gfx_pack.cpp b/libraries/gfx_pack/gfx_pack.cpp index 162f2bc7..a2c8e02b 100644 --- a/libraries/gfx_pack/gfx_pack.cpp +++ b/libraries/gfx_pack/gfx_pack.cpp @@ -1 +1,9 @@ -#include "gfx_pack.hpp" \ No newline at end of file +#include "gfx_pack.hpp" + + +using namespace pimoroni; + namespace GfxPack{ + + //SPIPins gfx_pack_pins; + + } \ No newline at end of file diff --git a/libraries/gfx_pack/gfx_pack.hpp b/libraries/gfx_pack/gfx_pack.hpp index 9256e135..bb9734e5 100644 --- a/libraries/gfx_pack/gfx_pack.hpp +++ b/libraries/gfx_pack/gfx_pack.hpp @@ -2,14 +2,17 @@ #include "pico/stdlib.h" #include "common/pimoroni_bus.hpp" +#include "drivers/st7567/st7567.hpp" +#include "drivers/button/button.hpp" +#include "drivers/rgbled/rgbled.hpp" +#include "libraries/pico_graphics/pico_graphics.hpp" + + namespace pimoroni { - SPIPins gfx_pack_pins= {PIMORONI_SPI_DEFAULT_INSTANCE, 17, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, 20, 9}; - - class GfxPack{ - - public: + namespace GfxPack{ + static const SPIPins gfx_pack_pins = {PIMORONI_SPI_DEFAULT_INSTANCE, 17, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, 20, 9}; static const int WIDTH = 128; static const int HEIGHT = 64; static const uint8_t A = 12; From 7be5376abfba79100c1dd310674b97f61a398669 Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Wed, 2 Nov 2022 20:58:20 +0000 Subject: [PATCH 15/28] some small fixes for easier merging later --- drivers/st7567/st7567.hpp | 1 + examples/CMakeLists.txt | 2 ++ libraries/CMakeLists.txt | 2 ++ 3 files changed, 5 insertions(+) diff --git a/drivers/st7567/st7567.hpp b/drivers/st7567/st7567.hpp index e21e99a6..79a8c6cb 100644 --- a/drivers/st7567/st7567.hpp +++ b/drivers/st7567/st7567.hpp @@ -1,6 +1,7 @@ #pragma once #include "hardware/spi.h" +#include "hardware/pwm.h" #include "hardware/gpio.h" #include "common/pimoroni_common.hpp" #include "common/pimoroni_bus.hpp" diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ee8884fb..a6c3a4af 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -47,6 +47,7 @@ add_subdirectory(inky_pack) add_subdirectory(inky_frame) add_subdirectory(automation2040w) +add_subdirectory(plasma_stick) add_subdirectory(plasma2040) add_subdirectory(badger2040) add_subdirectory(tufty2040) @@ -55,4 +56,5 @@ add_subdirectory(servo2040) add_subdirectory(motor2040) add_subdirectory(inventor2040w) add_subdirectory(encoder) +add_subdirectory(galactic_unicorn) add_subdirectory(gfx_pack) diff --git a/libraries/CMakeLists.txt b/libraries/CMakeLists.txt index 6d69f7d0..309f25f9 100644 --- a/libraries/CMakeLists.txt +++ b/libraries/CMakeLists.txt @@ -26,6 +26,7 @@ add_subdirectory(pico_motor_shim) add_subdirectory(pico_rgb_keypad) add_subdirectory(pico_wireless) add_subdirectory(automation2040w) +add_subdirectory(plasma_stick) add_subdirectory(plasma2040) add_subdirectory(badger2040) add_subdirectory(tufty2040) @@ -35,4 +36,5 @@ add_subdirectory(inventor2040w) add_subdirectory(adcfft) add_subdirectory(jpegdec) add_subdirectory(inky_frame) +add_subdirectory(galactic_unicorn) add_subdirectory(gfx_pack) From 9085c48a620875d8040bf06d6eda81872581351b Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Thu, 3 Nov 2022 13:30:07 +0000 Subject: [PATCH 16/28] mp working --- micropython/examples/gfx_pack/balls_demo.py | 60 ++++++++++ micropython/modules/micropython-gfx.cmake | 110 ++++++++++++++++++ micropython/modules/micropython-pico.cmake | 3 +- .../modules/picographics/micropython.cmake | 1 + .../modules/picographics/picographics.c | 1 + .../modules/picographics/picographics.cpp | 19 ++- .../modules/picographics/picographics.h | 3 +- 7 files changed, 192 insertions(+), 5 deletions(-) create mode 100644 micropython/examples/gfx_pack/balls_demo.py create mode 100644 micropython/modules/micropython-gfx.cmake diff --git a/micropython/examples/gfx_pack/balls_demo.py b/micropython/examples/gfx_pack/balls_demo.py new file mode 100644 index 00000000..96d24641 --- /dev/null +++ b/micropython/examples/gfx_pack/balls_demo.py @@ -0,0 +1,60 @@ +import time +import random +from picographics import PicoGraphics, DISPLAY_GFX_PACK, PEN_P8 + +display = PicoGraphics(display=DISPLAY_GFX_PACK) +display.set_backlight(1.0) + +WIDTH, HEIGHT = display.get_bounds() + +class Ball: + def __init__(self, x, y, r, dx, dy, pen): + self.x = x + self.y = y + self.r = r + self.dx = dx + self.dy = dy + self.pen = pen + + +# initialise shapes +balls = [] +for i in range(0, 10): + r = random.randint(0, 10) + 3 + balls.append( + Ball( + random.randint(r, r + (WIDTH - 2 * r)), + random.randint(r, r + (HEIGHT - 2 * r)), + r, + (14 - r) / 2, + (14 - r) / 2, + random.randint(0, 15), + ) + ) + + + +while True: + display.set_pen(0) + display.clear() + + for ball in balls: + ball.x += ball.dx + ball.y += ball.dy + + xmax = WIDTH - ball.r + xmin = ball.r + ymax = HEIGHT - ball.r + ymin = ball.r + + if ball.x < xmin or ball.x > xmax: + ball.dx *= -1 + + if ball.y < ymin or ball.y > ymax: + ball.dy *= -1 + + display.set_pen(ball.pen) + display.circle(int(ball.x), int(ball.y), int(ball.r)) + + display.update() + time.sleep(0.05) \ No newline at end of file diff --git a/micropython/modules/micropython-gfx.cmake b/micropython/modules/micropython-gfx.cmake new file mode 100644 index 00000000..d358df4a --- /dev/null +++ b/micropython/modules/micropython-gfx.cmake @@ -0,0 +1,110 @@ +include(pimoroni_i2c/micropython) +include(pimoroni_bus/micropython) + +#include(breakout_dotmatrix/micropython) +#include(breakout_encoder/micropython) +#include(breakout_ioexpander/micropython) +#include(breakout_ltr559/micropython) +#include(breakout_as7262/micropython) +#include(breakout_rgbmatrix5x5/micropython) +#include(breakout_matrix11x7/micropython) +#include(breakout_msa301/micropython) +#include(breakout_pmw3901/micropython) +#include(breakout_mics6814/micropython) +#include(breakout_potentiometer/micropython) +#include(breakout_rtc/micropython) +#include(breakout_trackball/micropython) +#include(breakout_sgp30/micropython) +#include(breakout_bh1745/micropython) +#include(breakout_bme68x/micropython) +#include(breakout_bme280/micropython) +#include(breakout_bmp280/micropython) +#include(breakout_icp10125/micropython) +#include(breakout_scd41/micropython) +#include(breakout_vl53l5cx/micropython) + +#include(pico_scroll/micropython) +#include(pico_rgb_keypad/micropython) +#include(pico_unicorn/micropython) +#include(pico_wireless/micropython) +#include(pico_explorer/micropython) + +include(hershey_fonts/micropython) +include(bitmap_fonts/micropython) + +#include(plasma/micropython) +#include(hub75/micropython) +include(pwm/micropython) +#include(servo/micropython) +#include(encoder/micropython) +#include(motor/micropython) +#include(qrcode/micropython/micropython) +#include(adcfft/micropython) +#include(pcf85063a/micropython) + +include(picographics/micropython) +include(jpegdec/micropython) +include(galactic_unicorn/micropython) + + +include(modules_py/modules_py) + +function(enable_ulab) + include(ulab/code/micropython) + + target_compile_definitions(usermod_ulab INTERFACE + # Support for complex ndarrays + ULAB_SUPPORTS_COMPLEX=0 + + # Determines, whether scipy is defined in ulab. The sub-modules and functions + # of scipy have to be defined separately + ULAB_HAS_SCIPY=0 + + # The maximum number of dimensions the firmware should be able to support + # Possible values lie between 1, and 4, inclusive + ULAB_MAX_DIMS=2 + + # By setting this constant to 1, iteration over array dimensions will be implemented + # as a function (ndarray_rewind_array), instead of writing out the loops in macros + # This reduces firmware size at the expense of speed + ULAB_HAS_FUNCTION_ITERATOR=1 + + # If NDARRAY_IS_ITERABLE is 1, the ndarray object defines its own iterator function + # This option saves approx. 250 bytes of flash space + NDARRAY_IS_ITERABLE=1 + + # Slicing can be switched off by setting this variable to 0 + NDARRAY_IS_SLICEABLE=1 + + # The default threshold for pretty printing. These variables can be overwritten + # at run-time via the set_printoptions() function + ULAB_HAS_PRINTOPTIONS=1 + NDARRAY_PRINT_THRESHOLD=10 + NDARRAY_PRINT_EDGEITEMS=3 + + # determines, whether the dtype is an object, or simply a character + # the object implementation is numpythonic, but requires more space + ULAB_HAS_DTYPE_OBJECT=0 + + # the ndarray binary operators + NDARRAY_HAS_BINARY_OPS=0 + + # Firmware size can be reduced at the expense of speed by using function + # pointers in iterations. For each operator, the function pointer saves around + # 2 kB in the two-dimensional case, and around 4 kB in the four-dimensional case. + + NDARRAY_BINARY_USES_FUN_POINTER=1 + + NDARRAY_HAS_BINARY_OP_ADD=1 + NDARRAY_HAS_BINARY_OP_EQUAL=1 + NDARRAY_HAS_BINARY_OP_LESS=1 + NDARRAY_HAS_BINARY_OP_LESS_EQUAL=1 + NDARRAY_HAS_BINARY_OP_MORE=1 + NDARRAY_HAS_BINARY_OP_MORE_EQUAL=1 + NDARRAY_HAS_BINARY_OP_MULTIPLY=1 + NDARRAY_HAS_BINARY_OP_NOT_EQUAL=1 + NDARRAY_HAS_BINARY_OP_POWER=1 + NDARRAY_HAS_BINARY_OP_SUBTRACT=1 + NDARRAY_HAS_BINARY_OP_TRUE_DIVIDE=1 + ) +endfunction() diff --git a/micropython/modules/micropython-pico.cmake b/micropython/modules/micropython-pico.cmake index d7f7a2ca..3f72eaea 100644 --- a/micropython/modules/micropython-pico.cmake +++ b/micropython/modules/micropython-pico.cmake @@ -4,4 +4,5 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../") -include(micropython-common) +#include(micropython-common) +include(micropython-gfx) \ No newline at end of file diff --git a/micropython/modules/picographics/micropython.cmake b/micropython/modules/picographics/micropython.cmake index 31d8e764..42455790 100644 --- a/micropython/modules/picographics/micropython.cmake +++ b/micropython/modules/picographics/micropython.cmake @@ -10,6 +10,7 @@ target_sources(usermod_${MOD_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/sh1107/sh1107.cpp ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/uc8151/uc8151.cpp ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/uc8159/uc8159.cpp + ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/st7567/st7567.cpp ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_graphics/pico_graphics.cpp ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_graphics/pico_graphics_pen_1bit.cpp ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_graphics/pico_graphics_pen_1bitY.cpp diff --git a/micropython/modules/picographics/picographics.c b/micropython/modules/picographics/picographics.c index 2e0f3b8b..7341aff9 100644 --- a/micropython/modules/picographics/picographics.c +++ b/micropython/modules/picographics/picographics.c @@ -126,6 +126,7 @@ STATIC const mp_map_elem_t picographics_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_DISPLAY_INKY_FRAME), MP_ROM_INT(DISPLAY_INKY_FRAME) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY_INKY_FRAME_4), MP_ROM_INT(DISPLAY_INKY_FRAME_4) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY_GALACTIC_UNICORN), MP_ROM_INT(DISPLAY_GALACTIC_UNICORN) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_GFX_PACK), MP_ROM_INT(DISPLAY_GFX_PACK) }, { MP_ROM_QSTR(MP_QSTR_PEN_1BIT), MP_ROM_INT(PEN_1BIT) }, { MP_ROM_QSTR(MP_QSTR_PEN_P4), MP_ROM_INT(PEN_P4) }, diff --git a/micropython/modules/picographics/picographics.cpp b/micropython/modules/picographics/picographics.cpp index dbe8e052..9d3d6dc1 100644 --- a/micropython/modules/picographics/picographics.cpp +++ b/micropython/modules/picographics/picographics.cpp @@ -3,6 +3,7 @@ #include "drivers/sh1107/sh1107.hpp" #include "drivers/uc8151/uc8151.hpp" #include "drivers/uc8159/uc8159.hpp" +#include "drivers/st7567/st7567.hpp" #include "libraries/pico_graphics/pico_graphics.hpp" #include "common/pimoroni_common.hpp" #include "common/pimoroni_bus.hpp" @@ -120,6 +121,13 @@ bool get_display_settings(PicoGraphicsDisplay display, int &width, int &height, if(rotate == -1) rotate = (int)Rotation::ROTATE_0; if(pen_type == -1) pen_type = PEN_RGB888; break; + case DISPLAY_GFX_PACK: + width = 128; + height = 64; + bus_type = BUS_SPI; + if(rotate == -1) rotate = (int)Rotation::ROTATE_0; + if(pen_type == -1) pen_type = PEN_1BIT; + break; default: return false; } @@ -178,7 +186,7 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size PicoGraphicsBusType bus_type = BUS_SPI; if(!get_display_settings(display, width, height, rotate, pen_type, bus_type)) mp_raise_ValueError("Unsupported display!"); if(rotate == -1) rotate = (int)Rotation::ROTATE_0; - + pimoroni::SPIPins spi_bus = get_spi_pins(BG_SPI_FRONT); pimoroni::ParallelPins parallel_bus = {10, 11, 12, 13, 14, 2}; // Default for Tufty 2040 parallel pimoroni::I2C *i2c_bus = nullptr; @@ -208,6 +216,8 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size spi_bus = {PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, 28, PIN_UNUSED}; } else if (display == DISPLAY_INKY_PACK) { spi_bus = {PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, 20, PIN_UNUSED}; + } else if (display == DISPLAY_GFX_PACK) { + spi_bus = {PIMORONI_SPI_DEFAULT_INSTANCE, 17, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, 20, 9}; } } } @@ -235,8 +245,11 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size } else if (display == DISPLAY_GALACTIC_UNICORN) { self->display = m_new_class(DisplayDriver, width, height, (Rotation)rotate); - } - else { + + } else if (display == DISPLAY_GFX_PACK) { + self->display = m_new_class(ST7567, width, height, spi_bus); + + } else { self->display = m_new_class(ST7789, width, height, (Rotation)rotate, round, spi_bus); } diff --git a/micropython/modules/picographics/picographics.h b/micropython/modules/picographics/picographics.h index b2c1e93f..4df440e2 100644 --- a/micropython/modules/picographics/picographics.h +++ b/micropython/modules/picographics/picographics.h @@ -14,7 +14,8 @@ enum PicoGraphicsDisplay { DISPLAY_INKY_PACK, DISPLAY_INKY_FRAME, DISPLAY_INKY_FRAME_4, - DISPLAY_GALACTIC_UNICORN + DISPLAY_GALACTIC_UNICORN, + DISPLAY_GFX_PACK }; enum PicoGraphicsPenType { From 78101c47b52fb7e94a5942e8617cada05d0cfe33 Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Thu, 3 Nov 2022 17:33:58 +0000 Subject: [PATCH 17/28] linting demo --- micropython/examples/gfx_pack/balls_demo.py | 6 +- micropython/modules/micropython-gfx.cmake | 110 -------------------- micropython/modules/micropython-pico.cmake | 3 +- 3 files changed, 4 insertions(+), 115 deletions(-) delete mode 100644 micropython/modules/micropython-gfx.cmake diff --git a/micropython/examples/gfx_pack/balls_demo.py b/micropython/examples/gfx_pack/balls_demo.py index 96d24641..2d550971 100644 --- a/micropython/examples/gfx_pack/balls_demo.py +++ b/micropython/examples/gfx_pack/balls_demo.py @@ -1,12 +1,13 @@ import time import random -from picographics import PicoGraphics, DISPLAY_GFX_PACK, PEN_P8 +from picographics import PicoGraphics, DISPLAY_GFX_PACK display = PicoGraphics(display=DISPLAY_GFX_PACK) display.set_backlight(1.0) WIDTH, HEIGHT = display.get_bounds() + class Ball: def __init__(self, x, y, r, dx, dy, pen): self.x = x @@ -33,7 +34,6 @@ for i in range(0, 10): ) - while True: display.set_pen(0) display.clear() @@ -57,4 +57,4 @@ while True: display.circle(int(ball.x), int(ball.y), int(ball.r)) display.update() - time.sleep(0.05) \ No newline at end of file + time.sleep(0.05) diff --git a/micropython/modules/micropython-gfx.cmake b/micropython/modules/micropython-gfx.cmake deleted file mode 100644 index d358df4a..00000000 --- a/micropython/modules/micropython-gfx.cmake +++ /dev/null @@ -1,110 +0,0 @@ -include(pimoroni_i2c/micropython) -include(pimoroni_bus/micropython) - -#include(breakout_dotmatrix/micropython) -#include(breakout_encoder/micropython) -#include(breakout_ioexpander/micropython) -#include(breakout_ltr559/micropython) -#include(breakout_as7262/micropython) -#include(breakout_rgbmatrix5x5/micropython) -#include(breakout_matrix11x7/micropython) -#include(breakout_msa301/micropython) -#include(breakout_pmw3901/micropython) -#include(breakout_mics6814/micropython) -#include(breakout_potentiometer/micropython) -#include(breakout_rtc/micropython) -#include(breakout_trackball/micropython) -#include(breakout_sgp30/micropython) -#include(breakout_bh1745/micropython) -#include(breakout_bme68x/micropython) -#include(breakout_bme280/micropython) -#include(breakout_bmp280/micropython) -#include(breakout_icp10125/micropython) -#include(breakout_scd41/micropython) -#include(breakout_vl53l5cx/micropython) - -#include(pico_scroll/micropython) -#include(pico_rgb_keypad/micropython) -#include(pico_unicorn/micropython) -#include(pico_wireless/micropython) -#include(pico_explorer/micropython) - -include(hershey_fonts/micropython) -include(bitmap_fonts/micropython) - -#include(plasma/micropython) -#include(hub75/micropython) -include(pwm/micropython) -#include(servo/micropython) -#include(encoder/micropython) -#include(motor/micropython) -#include(qrcode/micropython/micropython) -#include(adcfft/micropython) -#include(pcf85063a/micropython) - -include(picographics/micropython) -include(jpegdec/micropython) -include(galactic_unicorn/micropython) - - -include(modules_py/modules_py) - -function(enable_ulab) - include(ulab/code/micropython) - - target_compile_definitions(usermod_ulab INTERFACE - # Support for complex ndarrays - ULAB_SUPPORTS_COMPLEX=0 - - # Determines, whether scipy is defined in ulab. The sub-modules and functions - # of scipy have to be defined separately - ULAB_HAS_SCIPY=0 - - # The maximum number of dimensions the firmware should be able to support - # Possible values lie between 1, and 4, inclusive - ULAB_MAX_DIMS=2 - - # By setting this constant to 1, iteration over array dimensions will be implemented - # as a function (ndarray_rewind_array), instead of writing out the loops in macros - # This reduces firmware size at the expense of speed - ULAB_HAS_FUNCTION_ITERATOR=1 - - # If NDARRAY_IS_ITERABLE is 1, the ndarray object defines its own iterator function - # This option saves approx. 250 bytes of flash space - NDARRAY_IS_ITERABLE=1 - - # Slicing can be switched off by setting this variable to 0 - NDARRAY_IS_SLICEABLE=1 - - # The default threshold for pretty printing. These variables can be overwritten - # at run-time via the set_printoptions() function - ULAB_HAS_PRINTOPTIONS=1 - NDARRAY_PRINT_THRESHOLD=10 - NDARRAY_PRINT_EDGEITEMS=3 - - # determines, whether the dtype is an object, or simply a character - # the object implementation is numpythonic, but requires more space - ULAB_HAS_DTYPE_OBJECT=0 - - # the ndarray binary operators - NDARRAY_HAS_BINARY_OPS=0 - - # Firmware size can be reduced at the expense of speed by using function - # pointers in iterations. For each operator, the function pointer saves around - # 2 kB in the two-dimensional case, and around 4 kB in the four-dimensional case. - - NDARRAY_BINARY_USES_FUN_POINTER=1 - - NDARRAY_HAS_BINARY_OP_ADD=1 - NDARRAY_HAS_BINARY_OP_EQUAL=1 - NDARRAY_HAS_BINARY_OP_LESS=1 - NDARRAY_HAS_BINARY_OP_LESS_EQUAL=1 - NDARRAY_HAS_BINARY_OP_MORE=1 - NDARRAY_HAS_BINARY_OP_MORE_EQUAL=1 - NDARRAY_HAS_BINARY_OP_MULTIPLY=1 - NDARRAY_HAS_BINARY_OP_NOT_EQUAL=1 - NDARRAY_HAS_BINARY_OP_POWER=1 - NDARRAY_HAS_BINARY_OP_SUBTRACT=1 - NDARRAY_HAS_BINARY_OP_TRUE_DIVIDE=1 - ) -endfunction() diff --git a/micropython/modules/micropython-pico.cmake b/micropython/modules/micropython-pico.cmake index 3f72eaea..d7f7a2ca 100644 --- a/micropython/modules/micropython-pico.cmake +++ b/micropython/modules/micropython-pico.cmake @@ -4,5 +4,4 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../") -#include(micropython-common) -include(micropython-gfx) \ No newline at end of file +include(micropython-common) From eef9334805ebfda2ebfe79d0f82bf838dd8d3645 Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Fri, 4 Nov 2022 10:21:27 +0000 Subject: [PATCH 18/28] gxf module and examples done --- micropython/examples/gfx_pack/snake.py | 140 +++++++++++++++++++ micropython/examples/gfx_pack/thermometer.py | 79 +++++++++++ micropython/modules_py/gfx_pack.py | 21 +++ 3 files changed, 240 insertions(+) create mode 100644 micropython/examples/gfx_pack/snake.py create mode 100644 micropython/examples/gfx_pack/thermometer.py create mode 100644 micropython/modules_py/gfx_pack.py diff --git a/micropython/examples/gfx_pack/snake.py b/micropython/examples/gfx_pack/snake.py new file mode 100644 index 00000000..a3329096 --- /dev/null +++ b/micropython/examples/gfx_pack/snake.py @@ -0,0 +1,140 @@ +""" +Basic Snake demo for GFX Pack +Feel free to add your own improvements :) +A = up +B = down +C = reset +D = left +E = right +""" +from picographics import PicoGraphics, DISPLAY_GFX_PACK +from gfx_pack import GfxPack +import time +import random + +MOVE_UP = 0 +MOVE_DOWN = 1 +MOVE_LEFT = 2 +MOVE_RIGHT = 3 +next_move = MOVE_RIGHT +score = 0 +head_possition = (30, 30) +segments = [head_possition] +ate_apple = False +apple_possition = None + +display = PicoGraphics(display=DISPLAY_GFX_PACK) +display.set_backlight(1.0) + +gp = GfxPack() + +WIDTH, HEIGHT = display.get_bounds() + + +def set_new_apple(): + global apple_possition + apple_possition = (random.randint(0, WIDTH), random.randint(30, HEIGHT)) + + +def game_over(): + global score, segments, head_possition, ate_apple + score = 0 + head_possition = (30, 30) + segments = [head_possition] + ate_apple = False + set_new_apple() + pass + + +def check_button(): + global next_move, ate_apple + if gp.switch_a.is_pressed: + if(next_move != MOVE_DOWN): + next_move = MOVE_UP + elif gp.switch_b.is_pressed: + if(next_move != MOVE_UP): + next_move = MOVE_DOWN + elif gp.switch_d.is_pressed: + if(next_move != MOVE_RIGHT): + next_move = MOVE_LEFT + elif gp.switch_e.is_pressed: + if(next_move != MOVE_LEFT): + next_move = MOVE_RIGHT + elif gp.switch_c.is_pressed: + game_over() + + +def check_eaten(): + global ate_apple, head_possition, apple_possition, score + if (head_possition == apple_possition): + ate_apple = True + score += 1 + set_new_apple() + + +def check_collision(): + for index in range(len(segments) - 1): + if (head_possition == segments[index]): + game_over() + return + if (head_possition[0] >= WIDTH): + game_over() + if (head_possition[0] <= 0): + game_over() + if (head_possition[1] >= HEIGHT): + game_over() + if (head_possition[1] <= 20): + game_over() + + +def move(): + global head_possition, segments, ate_apple + + head_x, head_y = head_possition + + if (next_move == MOVE_UP): + head_y -= 1 + elif(next_move == MOVE_DOWN): + head_y += 1 + elif(next_move == MOVE_LEFT): + head_x -= 1 + elif(next_move == MOVE_RIGHT): + head_x += 1 + + head_possition = (head_x, head_y) + segments.append(head_possition) + + if (ate_apple): + ate_apple = False + else: + segments.pop(0) + + +def draw(): + display.set_pen(0) + display.clear() + display.set_pen(15) + display.text("score: {0}".format(score), 0, 0) + display.line(0, 20, 127, 20) + display.line(0, 63, 127, 63) + display.line(0, 63, 0, 20) + display.line(128, 63, 127, 20) + # Draw apple + display.pixel(apple_possition[0], apple_possition[1]) + + # Drawing snake + for segment in segments: + display.pixel(segment[0], segment[1]) + + display.update() + + +game_over() + +while 1: + check_button() + check_eaten() + move() + check_collision() + draw() + time.sleep(0.2) diff --git a/micropython/examples/gfx_pack/thermometer.py b/micropython/examples/gfx_pack/thermometer.py new file mode 100644 index 00000000..5794014a --- /dev/null +++ b/micropython/examples/gfx_pack/thermometer.py @@ -0,0 +1,79 @@ +"""GFX temp DEMO +This demo uses a BME680 or BME688 attached to the QWST connector to measure Temperature pressure and humidity +and Display it on the GXF display +or +the internal temperature sensor can be used in place of the BME68x breakout +just change use_bme68x_breakout to False +""" + +import time +from breakout_bme68x import BreakoutBME68X, STATUS_HEATER_STABLE +from pimoroni_i2c import PimoroniI2C +from picographics import PicoGraphics, DISPLAY_GFX_PACK +from gfx_pack import GfxPack +import machine + +# Settings +lower_temp_bound = 15 +upper_temp_bound = 30 +use_bme68x_breakout = True + +sensor_temp = machine.ADC(4) +conversion_factor = 3.3 / (65535) # used for calculating a temperature from the raw sensor reading + +gp = GfxPack() +display = PicoGraphics(display=DISPLAY_GFX_PACK) +display.set_backlight(0.4) +gp.rgb.set_rgb(0, 0, 0) + + +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} + +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) + +bmp = BreakoutBME68X(i2c) +# If this gives an error, try the alternative address +# bmp = BreakoutBME68X(i2c, 0x77) + +display.set_pen(0) +display.clear() +display.set_font("bitmap14_outline") + +while True: + # Clear display + display.set_pen(0) + display.clear() + + display.set_pen(15) + display.text("GFXPack Temp demo", 0, 0, scale=0.1) + + if use_bme68x_breakout: + temperature, pressure, humidity, gas, status, _, _ = bmp.read() + display.text("Temp: {:0.2f}c".format(temperature), 0, 20, scale=0.2) + display.text("Press: {:0.2f}Pa".format(pressure), 0, 35, scale=0.2) + display.text("Humid: {:0.2f}%".format(humidity), 0, 50, scale=0.2) + + heater = "Stable" if status & STATUS_HEATER_STABLE else "Unstable" + print("{:0.2f}c, {:0.2f}Pa, {:0.2f}%, {:0.2f} Ohms, Heater: {}".format( + temperature, pressure, humidity, gas, heater)) + + else: + reading = sensor_temp.read_u16() * conversion_factor + temperature = 27 - (reading - 0.706) / 0.001721 + display.text("Temperature", 25, 15, scale=0.2) + display.text("{:0.2f}c".format(temperature), 25, 30, scale=2) + + if (temperature < lower_temp_bound): + r = 0 + b = 255 + elif(temperature > upper_temp_bound): + r = 255 + b = 0 + else: + r = ((temperature - lower_temp_bound) / (upper_temp_bound - lower_temp_bound) * 255) + b = 255 - ((temperature - lower_temp_bound) / (upper_temp_bound - lower_temp_bound) * 255) + + gp.rgb.set_rgb(r, 0, b) + display.update() + time.sleep(0.2) diff --git a/micropython/modules_py/gfx_pack.py b/micropython/modules_py/gfx_pack.py new file mode 100644 index 00000000..c7b232a5 --- /dev/null +++ b/micropython/modules_py/gfx_pack.py @@ -0,0 +1,21 @@ +from pimoroni import RGBLED, Button + + +class GfxPack: + + SW_A = 12 + SW_B = 13 + SW_C = 14 + SW_D = 15 + SW_E = 22 + LED_R = 6 + LED_G = 7 + LED_B = 8 + + def __init__(self): + self.rgb = RGBLED(GfxPack.LED_R, GfxPack.LED_G, GfxPack.LED_B, invert=False) + self.switch_a = Button(GfxPack.SW_A) + self.switch_b = Button(GfxPack.SW_B) + self.switch_c = Button(GfxPack.SW_C) + self.switch_d = Button(GfxPack.SW_D) + self.switch_e = Button(GfxPack.SW_E) From 61a80ce66ebeec1a86d77573a5ea5dfe7086216a Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Fri, 4 Nov 2022 10:28:26 +0000 Subject: [PATCH 19/28] fixed some linting errors --- micropython/examples/gfx_pack/snake.py | 14 +++++++------- micropython/examples/gfx_pack/thermometer.py | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/micropython/examples/gfx_pack/snake.py b/micropython/examples/gfx_pack/snake.py index a3329096..7c724175 100644 --- a/micropython/examples/gfx_pack/snake.py +++ b/micropython/examples/gfx_pack/snake.py @@ -49,16 +49,16 @@ def game_over(): def check_button(): global next_move, ate_apple if gp.switch_a.is_pressed: - if(next_move != MOVE_DOWN): + if (next_move != MOVE_DOWN): next_move = MOVE_UP elif gp.switch_b.is_pressed: - if(next_move != MOVE_UP): + if (next_move != MOVE_UP): next_move = MOVE_DOWN elif gp.switch_d.is_pressed: - if(next_move != MOVE_RIGHT): + if (next_move != MOVE_RIGHT): next_move = MOVE_LEFT elif gp.switch_e.is_pressed: - if(next_move != MOVE_LEFT): + if (next_move != MOVE_LEFT): next_move = MOVE_RIGHT elif gp.switch_c.is_pressed: game_over() @@ -94,11 +94,11 @@ def move(): if (next_move == MOVE_UP): head_y -= 1 - elif(next_move == MOVE_DOWN): + elif (next_move == MOVE_DOWN): head_y += 1 - elif(next_move == MOVE_LEFT): + elif (next_move == MOVE_LEFT): head_x -= 1 - elif(next_move == MOVE_RIGHT): + elif (next_move == MOVE_RIGHT): head_x += 1 head_possition = (head_x, head_y) diff --git a/micropython/examples/gfx_pack/thermometer.py b/micropython/examples/gfx_pack/thermometer.py index 5794014a..be67ecf8 100644 --- a/micropython/examples/gfx_pack/thermometer.py +++ b/micropython/examples/gfx_pack/thermometer.py @@ -67,7 +67,7 @@ while True: if (temperature < lower_temp_bound): r = 0 b = 255 - elif(temperature > upper_temp_bound): + elif (temperature > upper_temp_bound): r = 255 b = 0 else: From f3f260e17615293e82ad8ac1f9a4bb5f909bf2fc Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Fri, 4 Nov 2022 17:23:30 +0000 Subject: [PATCH 20/28] finish docs and cmake gfx module --- micropython/modules/picographics/README.md | 1 + micropython/modules_py/gfx_pack.md | 71 ++++++++++++++++++++++ micropython/modules_py/modules_py.cmake | 2 +- 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 micropython/modules_py/gfx_pack.md diff --git a/micropython/modules/picographics/README.md b/micropython/modules/picographics/README.md index b86b1e7d..f9bf7ada 100644 --- a/micropython/modules/picographics/README.md +++ b/micropython/modules/picographics/README.md @@ -63,6 +63,7 @@ Bear in mind that MicroPython has only 192K of RAM available- a 320x240 pixel di * 128x128 I2C OLED - `DISPLAY_I2C_OLED_128X128` * Pico Inky Pack - 296x128 mono e-ink - `DISPLAY_INKY_PACK` * Inky Frame - 600x447 7-colour e-ink - `DISPLAY_INKY_FRAME` +* Pico GFX Pack - 128x64 mono LCD Matrix - `DISPLAY_GFX_PACK` ### Supported Graphics Modes (Pen Type) diff --git a/micropython/modules_py/gfx_pack.md b/micropython/modules_py/gfx_pack.md new file mode 100644 index 00000000..6bd47ec2 --- /dev/null +++ b/micropython/modules_py/gfx_pack.md @@ -0,0 +1,71 @@ +# GFX Pack MicroPython + +This library offers convenient functions for interacting with [Pico GFX Pack](https://shop.pimoroni.com/products/gfxpack) - The Pico GFX Pack adds a 128x64 LCD Matrix display to your headered Raspberry Pi Pico or PicoW, with RGBW backlight and 5 input buttons for all your display anc control needs. + +## Table of Content +- [Table of Content](#table-of-content) +- [GFX Pack Classes](#GFX-Pack-class) + - [Switches](#switches) + - [RGB Backlight](#rgb-backlight) + + +## GFX Pack Class + +The `GfxPack` class deals with RGB backlight and buttons on the GFX Pack. To create one, import the `gfx_pack` module, then define a new `board` variable: + +```python +import gfx_pack + +board = gfx_pack.GfxPack() +``` + + +### Switches + +The GFX Pack has 5 user switchs located just under the display labeled A to E. The names of these switches in the class are: + +`.switch_a` + +`.switch_b` + +`.switch_c` + +`.switch_d` + +`.switch_e` + +These can be read with the `.is_pressed` method. + +```python + +if (board.switch_a.is_pressed): + print('You pressed Switch A') + +if (board.switch_b.is_pressed): + print('You pressed Switch B') +``` + + + +### RGB Backlight + +The GFX has an RGB backlight as well as the regular Matrix display backlight to change the colour of the backlight. This is accessed via the following method. + + +`.rgb.set_rgb(r, g, b)` + +Where r, g, b are values between 0 and 255 + + +example: + + +```python + +board.rgb.set_rgb(255, 0, 0) # Makes the Backlight Red + +board.rgb.set_rgb(0, 255, 0) # Makes the Backlight Blue + +board.rgb.set_rgb(0, 0, 255) # Makes the Backlight Green + +``` \ No newline at end of file diff --git a/micropython/modules_py/modules_py.cmake b/micropython/modules_py/modules_py.cmake index 2f45172f..d7fd2165 100644 --- a/micropython/modules_py/modules_py.cmake +++ b/micropython/modules_py/modules_py.cmake @@ -18,7 +18,7 @@ target_link_libraries(usermod INTERFACE usermod_modules_py) # .py files to copy from modules_py to ports/rp2/modules #copy_module(usermod_modules_py ${CMAKE_CURRENT_LIST_DIR}/picosystem.py picosystem) copy_module(usermod_modules_py ${CMAKE_CURRENT_LIST_DIR}/pimoroni.py pimoroni) - +copy_module(usermod_modules_py ${CMAKE_CURRENT_LIST_DIR}/gfx_pack.py gfx_pack) if(PICO_BOARD STREQUAL "pico_w") copy_module(usermod_modules_py ${CMAKE_CURRENT_LIST_DIR}/automation.py automation) copy_module(usermod_modules_py ${CMAKE_CURRENT_LIST_DIR}/inventor.py inventor) From 678b8d7cf9e17293c1767aa60d379a086fc02273 Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Mon, 7 Nov 2022 12:50:50 +0000 Subject: [PATCH 21/28] Review of GfxPack code --- drivers/st7567/st7567.cmake | 2 +- drivers/st7567/st7567.cpp | 75 ++++++++--------- drivers/st7567/st7567.hpp | 12 +-- examples/gfx_pack/CMakeLists.txt | 2 +- examples/gfx_pack/gfx_demo.cpp | 34 ++++---- libraries/gfx_pack/gfx_pack.cmake | 6 +- libraries/gfx_pack/gfx_pack.cpp | 9 -- libraries/gfx_pack/gfx_pack.hpp | 5 -- micropython/examples/gfx_pack/balls_demo.py | 11 ++- micropython/examples/gfx_pack/snake.py | 86 ++++++++++---------- micropython/examples/gfx_pack/thermometer.py | 48 +++++------ micropython/modules_py/gfx_pack.md | 4 +- micropython/modules_py/gfx_pack.py | 52 ++++++++---- 13 files changed, 171 insertions(+), 175 deletions(-) delete mode 100644 libraries/gfx_pack/gfx_pack.cpp diff --git a/drivers/st7567/st7567.cmake b/drivers/st7567/st7567.cmake index 85c022a4..f3af5a90 100644 --- a/drivers/st7567/st7567.cmake +++ b/drivers/st7567/st7567.cmake @@ -7,4 +7,4 @@ target_sources(${DRIVER_NAME} INTERFACE target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib pimoroni_bus hardware_spi hardware_pwm) +target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib pimoroni_bus hardware_spi hardware_pwm pico_graphics) diff --git a/drivers/st7567/st7567.cpp b/drivers/st7567/st7567.cpp index c03fad58..0796052b 100644 --- a/drivers/st7567/st7567.cpp +++ b/drivers/st7567/st7567.cpp @@ -1,6 +1,4 @@ #include "st7567.hpp" -#include "hardware/pwm.h" -#include #include @@ -58,7 +56,9 @@ namespace pimoroni { }; void ST7567::reset() { - if(reset_pin == PIN_UNUSED) return; + if(reset_pin == PIN_UNUSED) + return; + gpio_put(reset_pin, 0); sleep_ms(10); sleep_ms(100); gpio_put(reset_pin, 1); sleep_ms(10); @@ -95,11 +95,9 @@ namespace pimoroni { reset(); - // if auto_init_sequence then send initialisation sequence // for our standard displays based on the width and height if(auto_init_sequence) { - command(reg::BIAS_1_7); command(reg::SEG_DIR_NORMAL); command(reg::SETCOMREVERSE); @@ -130,56 +128,49 @@ namespace pimoroni { gpio_put(dc, 1); // data mode spi_write_blocking(spi, (const uint8_t*)data, len); gpio_put(cs, 1); - } - - + } } // Native 16-bit framebuffer update void ST7567::update(PicoGraphics *graphics) { - uint8_t *fb = (uint8_t *)graphics->frame_buffer; uint8_t page_buffer[PAGESIZE]; uint8_t page_byte_selector; uint8_t page_bit_selector; - for (uint8_t page=0; page < 8 ; page++){ //select page + for(uint8_t page=0; page < 8 ; page++) { //select page + for(uint16_t pixel_index=0 ; pixel_index < (PAGESIZE * 8) ; pixel_index++) { //cycle through a page worth of bits from the fb + page_byte_selector = ((pixel_index % 128)); + page_bit_selector = (pixel_index / 128); - for (uint16_t pixel_index=0 ; pixel_index < (PAGESIZE * 8) ; pixel_index++){ //cycle through a page worth of bits from the fb - page_byte_selector = ((pixel_index % 128)); - page_bit_selector = (pixel_index / 128); - - - if (*fb & (0b10000000 >> (pixel_index % 8))){ // check selected pixel is present - page_buffer[page_byte_selector] |= (1 << page_bit_selector); + if(*fb & (0b10000000 >> (pixel_index % 8))) { // check selected pixel is present + page_buffer[page_byte_selector] |= (1 << page_bit_selector); + } + else { + page_buffer[page_byte_selector] &= ~( 1 << page_bit_selector); + } + + if((pixel_index % 8) >= 7) { //increment fb pointer at end of byte + fb++; + } } - else{ - page_buffer[page_byte_selector] &= ~( 1 << page_bit_selector); - } - - if ((pixel_index % 8) >= 7 ){ //increment fb pointer at end of byte - fb++; - } - } - - if(graphics->pen_type == PicoGraphics::PEN_1BIT) { - command(reg::ENTER_RMWMODE); - command(reg::SETPAGESTART | page); - command(reg::SETCOLL); - command(reg::SETCOLH); - gpio_put(dc, 1); // data mode - gpio_put(cs, 0); - spi_write_blocking(spi, &page_buffer[0], PAGESIZE ); - gpio_put(cs, 1); - gpio_put(dc, 0); // Back to command mode - } - else{ //other pen types incompatable - return; + if(graphics->pen_type == PicoGraphics::PEN_1BIT) { + command(reg::ENTER_RMWMODE); + command(reg::SETPAGESTART | page); + command(reg::SETCOLL); + command(reg::SETCOLH); + gpio_put(dc, 1); // data mode + gpio_put(cs, 0); + spi_write_blocking(spi, &page_buffer[0], PAGESIZE ); + gpio_put(cs, 1); + gpio_put(dc, 0); // Back to command mode + } + else { //other pen types incompatable + return; + } } - } - gpio_put(cs, 1); - + gpio_put(cs, 1); } void ST7567::set_backlight(uint8_t brightness) { diff --git a/drivers/st7567/st7567.hpp b/drivers/st7567/st7567.hpp index 79a8c6cb..a4b25d2a 100644 --- a/drivers/st7567/st7567.hpp +++ b/drivers/st7567/st7567.hpp @@ -2,15 +2,10 @@ #include "hardware/spi.h" #include "hardware/pwm.h" -#include "hardware/gpio.h" -#include "common/pimoroni_common.hpp" #include "common/pimoroni_bus.hpp" #include "libraries/pico_graphics/pico_graphics.hpp" namespace pimoroni { - - - class ST7567 : public DisplayDriver { //-------------------------------------------------- // Constants @@ -24,8 +19,7 @@ namespace pimoroni { // Variables //-------------------------------------------------- private: - - spi_inst_t *spi = spi0; + spi_inst_t *spi = spi0; uint32_t dma_channel; @@ -50,8 +44,8 @@ namespace pimoroni { ST7567(uint16_t width, uint16_t height, SPIPins pins) : DisplayDriver(width, height, ROTATE_0), spi(pins.spi), cs(pins.cs), dc(pins.dc), sck(pins.sck), mosi(pins.mosi), bl(pins.bl) { - init(); - } + init(); + } //-------------------------------------------------- diff --git a/examples/gfx_pack/CMakeLists.txt b/examples/gfx_pack/CMakeLists.txt index 0e378638..131534d4 100644 --- a/examples/gfx_pack/CMakeLists.txt +++ b/examples/gfx_pack/CMakeLists.txt @@ -6,7 +6,7 @@ add_executable( ) # Pull in pico libraries that we need -target_link_libraries(${OUTPUT_NAME} pico_stdlib gfx_pack pico_graphics) +target_link_libraries(${OUTPUT_NAME} pico_stdlib gfx_pack) # create map/bin/hex file etc. pico_add_extra_outputs(${OUTPUT_NAME}) \ No newline at end of file diff --git a/examples/gfx_pack/gfx_demo.cpp b/examples/gfx_pack/gfx_demo.cpp index 1ab96c75..ca818de7 100644 --- a/examples/gfx_pack/gfx_demo.cpp +++ b/examples/gfx_pack/gfx_demo.cpp @@ -1,10 +1,5 @@ -#include -#include -#include -#include -#include - #include "pico/stdlib.h" +#include "libraries/pico_graphics/pico_graphics.hpp" #include "libraries/gfx_pack/gfx_pack.hpp" using namespace pimoroni; @@ -41,7 +36,7 @@ void from_hsv(float h, float s, float v, uint8_t &r, uint8_t &g, uint8_t &b) { int main() { sleep_ms(100); - st7567.set_backlight(50); + st7567.set_backlight(64); // 0 to 255 struct pt { float x; @@ -66,17 +61,26 @@ int main() { Point text_location(0, 0); -float hue = 0.0; + float hue = 0.0f; while(true) { - if(button_a.raw()) text_location.x -= 1; - if(button_b.raw()) text_location.x += 1; + if(button_a.raw()) { + text_location.x -= 1; + } + if(button_b.raw()) { + text_location.x += 1; + } - if(button_c.raw()) text_location.y -= 1; - if(button_d.raw()) text_location.y += 1; + if(button_c.raw()) { + text_location.y -= 1; + } + if(button_d.raw()) { + text_location.y += 1; + } - if(button_e.raw()){ + if(button_e.raw()) { text_location.x = 0; - text_location.y = 0;} + text_location.y = 0; + } graphics.set_pen(0); graphics.clear(); @@ -116,5 +120,5 @@ float hue = 0.0; sleep_ms(1000/15); } - return 0; + return 0; } diff --git a/libraries/gfx_pack/gfx_pack.cmake b/libraries/gfx_pack/gfx_pack.cmake index 2985f968..dcba5dad 100644 --- a/libraries/gfx_pack/gfx_pack.cmake +++ b/libraries/gfx_pack/gfx_pack.cmake @@ -1,11 +1,7 @@ set(LIB_NAME gfx_pack) add_library(${LIB_NAME} INTERFACE) -target_sources(${LIB_NAME} INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/${LIB_NAME}.cpp -) - 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 hardware_spi pimoroni_bus st7567 pico_graphics button rgbled) \ No newline at end of file +target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib st7567 button rgbled) \ No newline at end of file diff --git a/libraries/gfx_pack/gfx_pack.cpp b/libraries/gfx_pack/gfx_pack.cpp deleted file mode 100644 index a2c8e02b..00000000 --- a/libraries/gfx_pack/gfx_pack.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "gfx_pack.hpp" - - -using namespace pimoroni; - namespace GfxPack{ - - //SPIPins gfx_pack_pins; - - } \ No newline at end of file diff --git a/libraries/gfx_pack/gfx_pack.hpp b/libraries/gfx_pack/gfx_pack.hpp index bb9734e5..2d329115 100644 --- a/libraries/gfx_pack/gfx_pack.hpp +++ b/libraries/gfx_pack/gfx_pack.hpp @@ -1,13 +1,8 @@ #pragma once -#include "pico/stdlib.h" -#include "common/pimoroni_bus.hpp" #include "drivers/st7567/st7567.hpp" #include "drivers/button/button.hpp" #include "drivers/rgbled/rgbled.hpp" -#include "libraries/pico_graphics/pico_graphics.hpp" - - namespace pimoroni { diff --git a/micropython/examples/gfx_pack/balls_demo.py b/micropython/examples/gfx_pack/balls_demo.py index 2d550971..fb94ebfd 100644 --- a/micropython/examples/gfx_pack/balls_demo.py +++ b/micropython/examples/gfx_pack/balls_demo.py @@ -1,9 +1,14 @@ import time import random -from picographics import PicoGraphics, DISPLAY_GFX_PACK +from gfx_pack import GfxPack -display = PicoGraphics(display=DISPLAY_GFX_PACK) -display.set_backlight(1.0) +""" +Add something here Gee +""" + +gp = GfxPack() +gp.set_backlight(0, 0, 0, 255) +display = gp.display WIDTH, HEIGHT = display.get_bounds() diff --git a/micropython/examples/gfx_pack/snake.py b/micropython/examples/gfx_pack/snake.py index 7c724175..de8d544b 100644 --- a/micropython/examples/gfx_pack/snake.py +++ b/micropython/examples/gfx_pack/snake.py @@ -1,46 +1,47 @@ +import time +import random +from gfx_pack import GfxPack, SWITCH_A, SWITCH_B, SWITCH_C, SWITCH_D, SWITCH_E + """ Basic Snake demo for GFX Pack Feel free to add your own improvements :) + A = up B = down C = reset D = left E = right """ -from picographics import PicoGraphics, DISPLAY_GFX_PACK -from gfx_pack import GfxPack -import time -import random MOVE_UP = 0 MOVE_DOWN = 1 MOVE_LEFT = 2 MOVE_RIGHT = 3 + next_move = MOVE_RIGHT score = 0 -head_possition = (30, 30) -segments = [head_possition] +head_position = (30, 30) +segments = [head_position] ate_apple = False -apple_possition = None - -display = PicoGraphics(display=DISPLAY_GFX_PACK) -display.set_backlight(1.0) +apple_position = None gp = GfxPack() +gp.set_backlight(0, 0, 0, 255) +display = gp.display WIDTH, HEIGHT = display.get_bounds() def set_new_apple(): - global apple_possition - apple_possition = (random.randint(0, WIDTH), random.randint(30, HEIGHT)) + global apple_position + apple_position = random.randint(0, WIDTH), random.randint(30, HEIGHT) def game_over(): - global score, segments, head_possition, ate_apple + global score, segments, head_position, ate_apple score = 0 - head_possition = (30, 30) - segments = [head_possition] + head_position = (30, 30) + segments = [head_position] ate_apple = False set_new_apple() pass @@ -48,25 +49,25 @@ def game_over(): def check_button(): global next_move, ate_apple - if gp.switch_a.is_pressed: - if (next_move != MOVE_DOWN): + if gp.switch_pressed(SWITCH_A): + if next_move != MOVE_DOWN: next_move = MOVE_UP - elif gp.switch_b.is_pressed: - if (next_move != MOVE_UP): + elif gp.switch_pressed(SWITCH_B): + if next_move != MOVE_UP: next_move = MOVE_DOWN - elif gp.switch_d.is_pressed: - if (next_move != MOVE_RIGHT): + elif gp.switch_pressed(SWITCH_C): + if next_move != MOVE_RIGHT: next_move = MOVE_LEFT - elif gp.switch_e.is_pressed: - if (next_move != MOVE_LEFT): + elif gp.switch_pressed(SWITCH_D): + if next_move != MOVE_LEFT: next_move = MOVE_RIGHT - elif gp.switch_c.is_pressed: + elif gp.switch_pressed(SWITCH_E): game_over() def check_eaten(): - global ate_apple, head_possition, apple_possition, score - if (head_possition == apple_possition): + global ate_apple, head_position, apple_position, score + if head_position == apple_position: ate_apple = True score += 1 set_new_apple() @@ -74,37 +75,37 @@ def check_eaten(): def check_collision(): for index in range(len(segments) - 1): - if (head_possition == segments[index]): + if head_position == segments[index]: game_over() return - if (head_possition[0] >= WIDTH): + if head_position[0] >= WIDTH: game_over() - if (head_possition[0] <= 0): + if head_position[0] <= 0: game_over() - if (head_possition[1] >= HEIGHT): + if head_position[1] >= HEIGHT: game_over() - if (head_possition[1] <= 20): + if head_position[1] <= 20: game_over() def move(): - global head_possition, segments, ate_apple + global head_position, segments, ate_apple - head_x, head_y = head_possition + head_x, head_y = head_position - if (next_move == MOVE_UP): + if next_move == MOVE_UP: head_y -= 1 - elif (next_move == MOVE_DOWN): + elif next_move == MOVE_DOWN: head_y += 1 - elif (next_move == MOVE_LEFT): + elif next_move == MOVE_LEFT: head_x -= 1 - elif (next_move == MOVE_RIGHT): + elif next_move == MOVE_RIGHT: head_x += 1 - head_possition = (head_x, head_y) - segments.append(head_possition) + head_position = (head_x, head_y) + segments.append(head_position) - if (ate_apple): + if ate_apple: ate_apple = False else: segments.pop(0) @@ -120,7 +121,7 @@ def draw(): display.line(0, 63, 0, 20) display.line(128, 63, 127, 20) # Draw apple - display.pixel(apple_possition[0], apple_possition[1]) + display.pixel(apple_position[0], apple_position[1]) # Drawing snake for segment in segments: @@ -131,10 +132,11 @@ def draw(): game_over() -while 1: +while True: check_button() check_eaten() move() check_collision() draw() + time.sleep(0.2) diff --git a/micropython/examples/gfx_pack/thermometer.py b/micropython/examples/gfx_pack/thermometer.py index be67ecf8..dbd12d47 100644 --- a/micropython/examples/gfx_pack/thermometer.py +++ b/micropython/examples/gfx_pack/thermometer.py @@ -1,17 +1,16 @@ -"""GFX temp DEMO -This demo uses a BME680 or BME688 attached to the QWST connector to measure Temperature pressure and humidity -and Display it on the GXF display -or -the internal temperature sensor can be used in place of the BME68x breakout -just change use_bme68x_breakout to False -""" - import time -from breakout_bme68x import BreakoutBME68X, STATUS_HEATER_STABLE -from pimoroni_i2c import PimoroniI2C -from picographics import PicoGraphics, DISPLAY_GFX_PACK -from gfx_pack import GfxPack import machine +from gfx_pack import GfxPack +from breakout_bme68x import BreakoutBME68X, STATUS_HEATER_STABLE + +""" +GFX temp DEMO + +This demo uses a BME680 or BME688 attached to the QWST connector to +measure temperature, pressure, and humidity and display it on the GFX display, +or the internal temperature sensor can be used in place of the +BME68x breakout. Just change use_bme68x_breakout to False +""" # Settings lower_temp_bound = 15 @@ -22,19 +21,13 @@ sensor_temp = machine.ADC(4) conversion_factor = 3.3 / (65535) # used for calculating a temperature from the raw sensor reading gp = GfxPack() -display = PicoGraphics(display=DISPLAY_GFX_PACK) -display.set_backlight(0.4) -gp.rgb.set_rgb(0, 0, 0) +gp.set_backlight(0, 0, 0) # turn the RGB backlight off +display = gp.display +display.set_backlight(0.4) # set the white to a low value - -PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} -PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} - -i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) - -bmp = BreakoutBME68X(i2c) +bmp = BreakoutBME68X(gp.i2c) # If this gives an error, try the alternative address -# bmp = BreakoutBME68X(i2c, 0x77) +# bmp = BreakoutBME68X(gp.i2c, 0x77) display.set_pen(0) display.clear() @@ -64,16 +57,17 @@ while True: display.text("Temperature", 25, 15, scale=0.2) display.text("{:0.2f}c".format(temperature), 25, 30, scale=2) - if (temperature < lower_temp_bound): + if temperature < lower_temp_bound: r = 0 b = 255 - elif (temperature > upper_temp_bound): + elif temperature > upper_temp_bound: r = 255 b = 0 else: - r = ((temperature - lower_temp_bound) / (upper_temp_bound - lower_temp_bound) * 255) + r = (temperature - lower_temp_bound) / (upper_temp_bound - lower_temp_bound) * 255 b = 255 - ((temperature - lower_temp_bound) / (upper_temp_bound - lower_temp_bound) * 255) - gp.rgb.set_rgb(r, 0, b) + gp.set_backlight(r, 0, b) display.update() + time.sleep(0.2) diff --git a/micropython/modules_py/gfx_pack.md b/micropython/modules_py/gfx_pack.md index 6bd47ec2..1b4e68c1 100644 --- a/micropython/modules_py/gfx_pack.md +++ b/micropython/modules_py/gfx_pack.md @@ -1,10 +1,10 @@ -# GFX Pack MicroPython +# GFX Pack (MicroPython) This library offers convenient functions for interacting with [Pico GFX Pack](https://shop.pimoroni.com/products/gfxpack) - The Pico GFX Pack adds a 128x64 LCD Matrix display to your headered Raspberry Pi Pico or PicoW, with RGBW backlight and 5 input buttons for all your display anc control needs. ## Table of Content - [Table of Content](#table-of-content) -- [GFX Pack Classes](#GFX-Pack-class) +- [GFX Pack Class](#gfx-pack-class) - [Switches](#switches) - [RGB Backlight](#rgb-backlight) diff --git a/micropython/modules_py/gfx_pack.py b/micropython/modules_py/gfx_pack.py index c7b232a5..dad1c77e 100644 --- a/micropython/modules_py/gfx_pack.py +++ b/micropython/modules_py/gfx_pack.py @@ -1,21 +1,45 @@ from pimoroni import RGBLED, Button +from picographics import PicoGraphics, DISPLAY_GFX_PACK +from pimoroni_i2c import PimoroniI2C + +# Index Constants +SWITCH_A = 0 +SWITCH_B = 1 +SWITCH_C = 2 +SWITCH_D = 3 +SWITCH_E = 4 class GfxPack: + I2C_SDA_PIN = 4 + I2C_SCL_PIN = 5 + SWITCh_PINS = (12, 13, 14, 15, 22) + LED_R_PIN = 6 + LED_G_PIN = 7 + LED_B_PIN = 8 - SW_A = 12 - SW_B = 13 - SW_C = 14 - SW_D = 15 - SW_E = 22 - LED_R = 6 - LED_G = 7 - LED_B = 8 + # Count Constants + NUM_SWITCHES = 5 def __init__(self): - self.rgb = RGBLED(GfxPack.LED_R, GfxPack.LED_G, GfxPack.LED_B, invert=False) - self.switch_a = Button(GfxPack.SW_A) - self.switch_b = Button(GfxPack.SW_B) - self.switch_c = Button(GfxPack.SW_C) - self.switch_d = Button(GfxPack.SW_D) - self.switch_e = Button(GfxPack.SW_E) + self.display = PicoGraphics(display=DISPLAY_GFX_PACK) + + # Set up the user switches + self.__switches = [] + for i in range(self.NUM_SWITCHES): + self.__switches.append(Button(self.SWITCH_PINS[i])) + + self.__rgb = RGBLED(GfxPack.LED_R_PIN, GfxPack.LED_G_PIN, GfxPack.LED_B_PIN, invert=False) + + # Set up the i2c for Qw/st and Breakout Garden + self.i2c = PimoroniI2C(self.I2C_SDA_PIN, self.I2C_SCL_PIN, 100000) + + def switch_pressed(self, switch): + if switch < 0 or switch >= self.NUM_SWITCHES: + raise ValueError("switch out of range. Expected SWITCH_A (0), SWITCH_B (1), SWITCH_C (2), SWITCH_D (3), or SWITCH_E (4)") + return not self.__switches[switch].value() + + def set_backlight(self, r, g, b, w=None): + self.__rgb.set_rgb(r, g, b) + if w is not None: + self.display.set_backlight(w) From b3893d005237752b7304cb020a360b1773720a7b Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Mon, 7 Nov 2022 13:43:53 +0000 Subject: [PATCH 22/28] couple of minor fixes --- micropython/examples/gfx_pack/balls_demo.py | 4 +++- micropython/examples/gfx_pack/snake.py | 21 +++++++++++++++----- micropython/examples/gfx_pack/thermometer.py | 5 ++--- micropython/modules_py/gfx_pack.py | 6 +++--- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/micropython/examples/gfx_pack/balls_demo.py b/micropython/examples/gfx_pack/balls_demo.py index fb94ebfd..cb1617ea 100644 --- a/micropython/examples/gfx_pack/balls_demo.py +++ b/micropython/examples/gfx_pack/balls_demo.py @@ -3,7 +3,9 @@ import random from gfx_pack import GfxPack """ -Add something here Gee +Bouncing Ball demo +10 balls of different shades will be bouncing around your display. +Funky... """ gp = GfxPack() diff --git a/micropython/examples/gfx_pack/snake.py b/micropython/examples/gfx_pack/snake.py index de8d544b..050791e9 100644 --- a/micropython/examples/gfx_pack/snake.py +++ b/micropython/examples/gfx_pack/snake.py @@ -12,12 +12,12 @@ C = reset D = left E = right """ - +# Constants for next move state MOVE_UP = 0 MOVE_DOWN = 1 MOVE_LEFT = 2 MOVE_RIGHT = 3 - +# In-game variables next_move = MOVE_RIGHT score = 0 head_position = (30, 30) @@ -32,11 +32,13 @@ display = gp.display WIDTH, HEIGHT = display.get_bounds() +# Draw the apple in a random possition within the play field def set_new_apple(): global apple_position apple_position = random.randint(0, WIDTH), random.randint(30, HEIGHT) +# Reset game to start position and score def game_over(): global score, segments, head_position, ate_apple score = 0 @@ -47,6 +49,7 @@ def game_over(): pass +# Poll all the butttons to see if anything has been pressed and change next direction accoringly def check_button(): global next_move, ate_apple if gp.switch_pressed(SWITCH_A): @@ -55,16 +58,17 @@ def check_button(): elif gp.switch_pressed(SWITCH_B): if next_move != MOVE_UP: next_move = MOVE_DOWN - elif gp.switch_pressed(SWITCH_C): + elif gp.switch_pressed(SWITCH_D): if next_move != MOVE_RIGHT: next_move = MOVE_LEFT - elif gp.switch_pressed(SWITCH_D): + elif gp.switch_pressed(SWITCH_E): if next_move != MOVE_LEFT: next_move = MOVE_RIGHT - elif gp.switch_pressed(SWITCH_E): + elif gp.switch_pressed(SWITCH_C): game_over() +# If the snake head and apple are on the same pixel the apple has been eaten def check_eaten(): global ate_apple, head_position, apple_position, score if head_position == apple_position: @@ -74,10 +78,12 @@ def check_eaten(): def check_collision(): + # Check if the head or any of the tail segments are on the same pixel for index in range(len(segments) - 1): if head_position == segments[index]: game_over() return + # Check the snake head has not gone beyond the play area if head_position[0] >= WIDTH: game_over() if head_position[0] <= 0: @@ -103,8 +109,10 @@ def move(): head_x += 1 head_position = (head_x, head_y) + # Add head to body segments segments.append(head_position) + # I there is no apple remove end of the tail otherwise tail grows by 1 if ate_apple: ate_apple = False else: @@ -115,6 +123,7 @@ def draw(): display.set_pen(0) display.clear() display.set_pen(15) + # Draw play field including score display.text("score: {0}".format(score), 0, 0) display.line(0, 20, 127, 20) display.line(0, 63, 127, 63) @@ -130,9 +139,11 @@ def draw(): display.update() +# Make sure game is reset to begin with game_over() while True: + # Game logic check_button() check_eaten() move() diff --git a/micropython/examples/gfx_pack/thermometer.py b/micropython/examples/gfx_pack/thermometer.py index dbd12d47..6a0ed5db 100644 --- a/micropython/examples/gfx_pack/thermometer.py +++ b/micropython/examples/gfx_pack/thermometer.py @@ -25,9 +25,8 @@ gp.set_backlight(0, 0, 0) # turn the RGB backlight off display = gp.display display.set_backlight(0.4) # set the white to a low value -bmp = BreakoutBME68X(gp.i2c) -# If this gives an error, try the alternative address -# bmp = BreakoutBME68X(gp.i2c, 0x77) +if use_bme68x_breakout: + bmp = BreakoutBME68X(gp.i2c) display.set_pen(0) display.clear() diff --git a/micropython/modules_py/gfx_pack.py b/micropython/modules_py/gfx_pack.py index dad1c77e..08096864 100644 --- a/micropython/modules_py/gfx_pack.py +++ b/micropython/modules_py/gfx_pack.py @@ -13,7 +13,7 @@ SWITCH_E = 4 class GfxPack: I2C_SDA_PIN = 4 I2C_SCL_PIN = 5 - SWITCh_PINS = (12, 13, 14, 15, 22) + SWITCH_PINS = (12, 13, 14, 15, 22) LED_R_PIN = 6 LED_G_PIN = 7 LED_B_PIN = 8 @@ -37,9 +37,9 @@ class GfxPack: def switch_pressed(self, switch): if switch < 0 or switch >= self.NUM_SWITCHES: raise ValueError("switch out of range. Expected SWITCH_A (0), SWITCH_B (1), SWITCH_C (2), SWITCH_D (3), or SWITCH_E (4)") - return not self.__switches[switch].value() + return self.__switches[switch].is_pressed def set_backlight(self, r, g, b, w=None): self.__rgb.set_rgb(r, g, b) if w is not None: - self.display.set_backlight(w) + self.display.set_backlight(w / 255) From 065b55b6af681eac4a9ca721e00f57632472a5c5 Mon Sep 17 00:00:00 2001 From: Hel Gibbons Date: Mon, 7 Nov 2022 14:20:12 +0000 Subject: [PATCH 23/28] add rainbow example --- micropython/examples/gfx_pack/rainbow.py | 53 ++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 micropython/examples/gfx_pack/rainbow.py diff --git a/micropython/examples/gfx_pack/rainbow.py b/micropython/examples/gfx_pack/rainbow.py new file mode 100644 index 00000000..b921452a --- /dev/null +++ b/micropython/examples/gfx_pack/rainbow.py @@ -0,0 +1,53 @@ +# This example borrows a CircuitPython hsv_to_rgb function to cycle through some rainbows on GFX Pack's screen. +# If you're into rainbows, HSV (Hue, Saturation, Value) is very useful! + +import time +from picographics import PicoGraphics, DISPLAY_GFX_PACK +from gfx_pack import GfxPack + +display = PicoGraphics(display=DISPLAY_GFX_PACK, rotate=0) + +WIDTH, HEIGHT = display.get_bounds() + +gp = GfxPack() + + +# From CPython Lib/colorsys.py +def hsv_to_rgb(h, s, v): + if s == 0.0: + return v, v, v + i = int(h * 6.0) + f = (h * 6.0) - i + p = v * (1.0 - s) + q = v * (1.0 - s * f) + t = v * (1.0 - s * (1.0 - f)) + i = i % 6 + if i == 0: + return v, t, p + if i == 1: + return q, v, p + if i == 2: + return p, v, t + if i == 3: + return p, q, v + if i == 4: + return t, p, v + if i == 5: + return v, p, q + + +h = 0 +display.set_font("bitmap8") + +while True: + h += 1 + r, g, b = [int(255 * c) for c in hsv_to_rgb(h / 360.0, 1.0, 1.0)] # rainbow magic + gp.set_backlight(r, g, b, 0) # Set backlight to a converted HSV value + display.set_pen(15) # Set pen to black + display.clear() + display.set_pen(0) # Set pen to white + display.text("pico disco!", 18, 5, WIDTH, 2) # Add some text + display.text("\\o/ \\o/ \\o/", 14, 25, WIDTH, 2) # and some more text + display.text("\\o/ \\o/ \\o/", 14, 45, WIDTH, 2) # and a bit more text + display.update() # Update the display + time.sleep(1.0 / 60) From 7a458f32e40a3055165fe46942b62eb111eb4322 Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Mon, 7 Nov 2022 14:23:20 +0000 Subject: [PATCH 24/28] Update gfx_pack.md --- micropython/modules_py/gfx_pack.md | 68 +++++++++++++++++++----------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/micropython/modules_py/gfx_pack.md b/micropython/modules_py/gfx_pack.md index 1b4e68c1..f907fad1 100644 --- a/micropython/modules_py/gfx_pack.md +++ b/micropython/modules_py/gfx_pack.md @@ -6,7 +6,9 @@ This library offers convenient functions for interacting with [Pico GFX Pack](ht - [Table of Content](#table-of-content) - [GFX Pack Class](#gfx-pack-class) - [Switches](#switches) - - [RGB Backlight](#rgb-backlight) + - [RGBW Backlight](#rgbw-backlight) +- [Display](#display) + - [Backlight](#backlight) ## GFX Pack Class @@ -19,53 +21,71 @@ import gfx_pack board = gfx_pack.GfxPack() ``` +From here, all features can be accessed by calling functions on `board`. In addition, when using Qwiic / Stemma QT devices, the I2C channel to use can be accessed with `board.i2c`. ### Switches -The GFX Pack has 5 user switchs located just under the display labeled A to E. The names of these switches in the class are: +GFX Pack has five switches just below the display. To read one of the switches, call `.switch_pressed(switch)`, where `switch` is a value from `0` to `.NUM_SWITCHES - 1`. This returns `True` when the specified switch is pressed, and `False` otherwise. -`.switch_a` +To read a specific input, the `gfx_pack` module contains these handy constants: -`.switch_b` - -`.switch_c` - -`.switch_d` - -`.switch_e` - -These can be read with the `.is_pressed` method. +* `SWITCH_A` = `0` +* `SWITCH_B` = `1` +* `SWITCH_C` = `2` +* `SWITCH_D` = `3` +* `SWITCH_E` = `4` ```python +if board.switch_pressed(SWITCH_A): + # Do something interesting here! -if (board.switch_a.is_pressed): - print('You pressed Switch A') - -if (board.switch_b.is_pressed): - print('You pressed Switch B') +if board.switch_pressed(SWITCH_B): + # Do something else even more interesting here! ``` - -### RGB Backlight +### RGBW Backlight The GFX has an RGB backlight as well as the regular Matrix display backlight to change the colour of the backlight. This is accessed via the following method. -`.rgb.set_rgb(r, g, b)` +`.set_backlight(r, g, b, w=None)` -Where r, g, b are values between 0 and 255 +Where r, g, b and w are values between 0 and 255 example: +```python +board.set_backlight(255, 0, 0) # Makes the Backlight Red +board.set_backlight(0, 255, 0) # Makes the Backlight Blue +board.set_backlight(0, 0, 255) # Makes the Backlight Green +board.set_backlight(0, 0, 0, 255) # Makes the Backlight White +``` + +## Display + +The display is all handled by our custom picographics drivers the can be accessed via `.display`. + +example: ```python +display = board.display() +display.text("Hello World!", 0, 0) +display.line(0, 0, 128, 64) +display.update() # Update display with the above items +``` +All the picographics functions can be found [Here](../modules/picographics/README.md) -board.rgb.set_rgb(255, 0, 0) # Makes the Backlight Red +### Backlight -board.rgb.set_rgb(0, 255, 0) # Makes the Backlight Blue +Included in the picographics display drivers is a function for controling the displays white backlight only which is accessed via `.set_backlight()`. -board.rgb.set_rgb(0, 0, 255) # Makes the Backlight Green +This funstion takes a floating point value between `0.0` and `1.0` +```python +display = board.display() +display.set_backlight(0.0) # Backlight is off +display.set_backlight(0.5) # Backlight is 50% +display.set_backlight(1.0) # Backlight is 100% ``` \ No newline at end of file From 98e29e07fbced706dbbd0a8531f4ebbe733c0fa6 Mon Sep 17 00:00:00 2001 From: Hel Gibbons Date: Mon, 7 Nov 2022 15:38:44 +0000 Subject: [PATCH 25/28] add dancing --- micropython/examples/gfx_pack/rainbow.py | 38 +++++++++++++++++------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/micropython/examples/gfx_pack/rainbow.py b/micropython/examples/gfx_pack/rainbow.py index b921452a..ff93cf8e 100644 --- a/micropython/examples/gfx_pack/rainbow.py +++ b/micropython/examples/gfx_pack/rainbow.py @@ -2,14 +2,15 @@ # If you're into rainbows, HSV (Hue, Saturation, Value) is very useful! import time -from picographics import PicoGraphics, DISPLAY_GFX_PACK from gfx_pack import GfxPack -display = PicoGraphics(display=DISPLAY_GFX_PACK, rotate=0) +gp = GfxPack() +display = gp.display WIDTH, HEIGHT = display.get_bounds() +display.set_backlight(0) # turn off the white component of the backlight -gp = GfxPack() +DANCE_TIME = 1.0 # From CPython Lib/colorsys.py @@ -36,18 +37,35 @@ def hsv_to_rgb(h, s, v): return v, p, q +# some variables to keep track of rainbows and dancing h = 0 +dancing = True +last_time = time.ticks_ms() + display.set_font("bitmap8") while True: + time_ms = time.ticks_ms() + h += 1 r, g, b = [int(255 * c) for c in hsv_to_rgb(h / 360.0, 1.0, 1.0)] # rainbow magic - gp.set_backlight(r, g, b, 0) # Set backlight to a converted HSV value - display.set_pen(15) # Set pen to black - display.clear() + gp.set_backlight(r, g, b) # Set backlight to a converted HSV value display.set_pen(0) # Set pen to white - display.text("pico disco!", 18, 5, WIDTH, 2) # Add some text - display.text("\\o/ \\o/ \\o/", 14, 25, WIDTH, 2) # and some more text - display.text("\\o/ \\o/ \\o/", 14, 45, WIDTH, 2) # and a bit more text - display.update() # Update the display + display.clear() + display.set_pen(15) # Set pen to black + # draw text and mans + if dancing: + display.text("pico!", 9, 5, WIDTH, 2) + display.text("\\o\\ \\o\\ \\o\\ ", 7, 25, WIDTH, 2) + display.text("\\o\\ \\o\\ \\o\\ ", 7, 45, WIDTH, 2) + else: + display.text("disco!", 69, 5, WIDTH, 2) + display.text("/o/ /o/ /o/ ", 21, 25, WIDTH, 2) + display.text("/o/ /o/ /o/ ", 21, 45, WIDTH, 2) + # our main loop is faster than our dancing loop + # this 'if' checks when it's time to dance + if time_ms - last_time > DANCE_TIME * 1000: + dancing = not dancing + last_time = time_ms + display.update() time.sleep(1.0 / 60) From 91a2e7f5fb84f4f851ebff0b35992849cdffc3d0 Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Mon, 7 Nov 2022 16:11:05 +0000 Subject: [PATCH 26/28] Fixed typos --- micropython/modules_py/gfx_pack.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/micropython/modules_py/gfx_pack.md b/micropython/modules_py/gfx_pack.md index f907fad1..e508179d 100644 --- a/micropython/modules_py/gfx_pack.md +++ b/micropython/modules_py/gfx_pack.md @@ -1,6 +1,6 @@ # GFX Pack (MicroPython) -This library offers convenient functions for interacting with [Pico GFX Pack](https://shop.pimoroni.com/products/gfxpack) - The Pico GFX Pack adds a 128x64 LCD Matrix display to your headered Raspberry Pi Pico or PicoW, with RGBW backlight and 5 input buttons for all your display anc control needs. +This library offers convenient functions for interacting with [Pico GFX Pack](https://shop.pimoroni.com/products/gfxpack) - The Pico GFX Pack adds a 128x64 LCD Matrix display to your headered Raspberry Pi Pico or PicoW, with RGBW backlight and 5 input buttons for all your display and control needs. ## Table of Content - [Table of Content](#table-of-content) @@ -13,7 +13,7 @@ This library offers convenient functions for interacting with [Pico GFX Pack](ht ## GFX Pack Class -The `GfxPack` class deals with RGB backlight and buttons on the GFX Pack. To create one, import the `gfx_pack` module, then define a new `board` variable: +The `GfxPack` class deals with RGBW backlight and buttons on the GFX Pack. To create one, import the `gfx_pack` module, then define a new `board` variable: ```python import gfx_pack @@ -70,7 +70,7 @@ The display is all handled by our custom picographics drivers the can be accesse example: ```python -display = board.display() +display = board.display display.text("Hello World!", 0, 0) display.line(0, 0, 128, 64) display.update() # Update display with the above items @@ -81,10 +81,10 @@ All the picographics functions can be found [Here](../modules/picographics/READM Included in the picographics display drivers is a function for controling the displays white backlight only which is accessed via `.set_backlight()`. -This funstion takes a floating point value between `0.0` and `1.0` +This function takes a floating point value between `0.0` and `1.0` ```python -display = board.display() +display = board.display display.set_backlight(0.0) # Backlight is off display.set_backlight(0.5) # Backlight is 50% display.set_backlight(1.0) # Backlight is 100% From 4f4b0b277c7a5d52f5323430e2c08745138472aa Mon Sep 17 00:00:00 2001 From: Gee Bartlett Date: Mon, 7 Nov 2022 18:07:48 +0000 Subject: [PATCH 27/28] updated readme's --- drivers/st7567/README.md | 42 +++++++++++++++++++++++++++++ libraries/gfx_pack/README.md | 52 +++++++++++++++++++----------------- 2 files changed, 70 insertions(+), 24 deletions(-) create mode 100644 drivers/st7567/README.md diff --git a/drivers/st7567/README.md b/drivers/st7567/README.md new file mode 100644 index 00000000..43468b58 --- /dev/null +++ b/drivers/st7567/README.md @@ -0,0 +1,42 @@ +# ST7567 Display Driver for Pimoroni LCDs + +The ST7567 driver supports Serial (SPI) ST7567 displays and is intended for use with: + +* Pico GFX Pack + +## Setup + +Construct an instance of the ST7567 driver with SPI pins. + + +SPI: + +```c++ +ST7567 st7567(WIDTH, HEIGHT, { + 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 + +ST7567's `update` accepts an instance of `PicoGraphics` in 1 bit colour mode: + +```c++ +st7567.update(&graphics); +``` + +### Set Backlight + +If a backlight pin has been configured, you can set the backlight from 0 to 255: + +```c++ +st7567.set_backlight(128) +``` \ No newline at end of file diff --git a/libraries/gfx_pack/README.md b/libraries/gfx_pack/README.md index 53ad9c6d..42d6e533 100644 --- a/libraries/gfx_pack/README.md +++ b/libraries/gfx_pack/README.md @@ -1,6 +1,6 @@ -# Pico Display 2.0" Pack +# Pico GFX Pack -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! +Our Pico GFX Pack offers 2.15" (128x64) LCD matrix display for your Raspberry Pi Pico it also includes five switches and an RGBW Backlight! - [Example Program](#example-program) - [Function Reference](#function-reference) @@ -9,44 +9,48 @@ Our Pico Display Pack offers a vibrant 1.14" (240x135) IPS LCD screen for your R ## Example Program -The following example sets up Pico Display, displays some basic demo text and graphics and will illuminate the RGB LED green if the A button is pressed. +The following example sets up Pico Display, displays some basic demo text and graphics and will illuminate the backlight green if the A button is pressed. ```c++ -#include "pico_display_2.hpp" -#include "drivers/st7789/st7789.hpp" +#include "gxf_pack.hpp" +#include "drivers/st7567/st7576.hpp" #include "libraries/pico_graphics/pico_graphics.hpp" #include "rgbled.hpp" #include "button.hpp" // Display driver -ST7789 st7789(PicoDisplay2::WIDTH, PicoDisplay2::HEIGHT, ROTATE_0, false, get_spi_pins(BG_SPI_FRONT)); +ST7567 st7567(128, 64, GfxPack::gfx_pack_pins); + +// Graphics library - in 1 Bit mode you get 16 shades with dithering. +PicoGraphics_Pen1Bit graphics(st7567.width, st7567.height, nullptr); + +// RGB backlight elements +RGBLED backlight_rgb(GfxPack::BL_R, GfxPack::BL_G, GfxPack::BL_B, Polarity::ACTIVE_HIGH); + +// And each button +Button button_a(GfxPack::A); +Button button_b(GfxPack::B); +Button button_c(GfxPack::C); +Button button_d(GfxPack::D); +Button button_e(GfxPack::E); -// 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() { // 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. - st7789.set_backlight(100); + // This controls the white elements of the RGBW backlight + st7567.set_backlight(100); while(true) { - // detect if the A button is pressed (could be A, B, X, or Y) + // detect if the A button is pressed (could be A, B, C, D or E) if(button_a.raw(display.A)) { - // make the led glow green + // make the LCD glow green // parameters are red, green, blue all between 0 and 255 // these are also gamma corrected - led.set_rgb(0, 255, 0); + backlight_rgb.set_rgb(0, 255, 0); } // set the colour of the pen @@ -68,7 +72,7 @@ int main() { 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 - st7789.update(&graphics); + st7567.update(&graphics); } } ``` @@ -77,8 +81,8 @@ int main() { ### PicoGraphics -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). +Pico GFX Pack 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). -### ST7789 +### ST7567 -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 +Pico Display uses the ST7567 display driver to handle the LCD. For more information [read the ST7567 README.](../../drivers/st7789/README.md). \ No newline at end of file From 23f56f05e4bf01d6d3ee32b8df8aeee85e9f71ee Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Tue, 8 Nov 2022 11:10:51 +0000 Subject: [PATCH 28/28] Minor readme tweaks --- libraries/gfx_pack/README.md | 8 ++++---- micropython/modules_py/gfx_pack.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/gfx_pack/README.md b/libraries/gfx_pack/README.md index 42d6e533..4fc70775 100644 --- a/libraries/gfx_pack/README.md +++ b/libraries/gfx_pack/README.md @@ -1,6 +1,6 @@ -# Pico GFX Pack +# Pico GFX Pack (C++) -Our Pico GFX Pack offers 2.15" (128x64) LCD matrix display for your Raspberry Pi Pico it also includes five switches and an RGBW Backlight! +This library offers convenient functions for interacting with [Pico GFX Pack](https://shop.pimoroni.com/products/gfxpack) - The Pico GFX Pack adds a 128x64 LCD Matrix display to your headered Raspberry Pi Pico or PicoW, with RGBW backlight and 5 input buttons for all your display and control needs. - [Example Program](#example-program) - [Function Reference](#function-reference) @@ -12,7 +12,7 @@ Our Pico GFX Pack offers 2.15" (128x64) LCD matrix display for your Raspberry Pi The following example sets up Pico Display, displays some basic demo text and graphics and will illuminate the backlight green if the A button is pressed. ```c++ -#include "gxf_pack.hpp" +#include "gfx_pack.hpp" #include "drivers/st7567/st7576.hpp" #include "libraries/pico_graphics/pico_graphics.hpp" #include "rgbled.hpp" @@ -36,7 +36,7 @@ Button button_e(GfxPack::E); // RGB LED -RGBLED led(PicoDisplay2::LED_R, PicoDisplay2::LED_G, PicoDisplay2::LED_B); +RGBLED led(GfxPack::LED_R, GfxPack::LED_G, GfxPack::LED_B); int main() { diff --git a/micropython/modules_py/gfx_pack.md b/micropython/modules_py/gfx_pack.md index e508179d..e7e31416 100644 --- a/micropython/modules_py/gfx_pack.md +++ b/micropython/modules_py/gfx_pack.md @@ -1,4 +1,4 @@ -# GFX Pack (MicroPython) +# Pico GFX Pack (MicroPython) This library offers convenient functions for interacting with [Pico GFX Pack](https://shop.pimoroni.com/products/gfxpack) - The Pico GFX Pack adds a 128x64 LCD Matrix display to your headered Raspberry Pi Pico or PicoW, with RGBW backlight and 5 input buttons for all your display and control needs.