From 43382ba2c04b8371dab7c216349b998acb1279b2 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Fri, 3 Feb 2023 11:13:47 +0000 Subject: [PATCH] Inky 7.3: Add ShiftRegister driver. --- drivers/CMakeLists.txt | 3 +- drivers/inky73/inky73.cmake | 2 +- drivers/inky73/inky73.cpp | 28 +++++-------- drivers/inky73/inky73.hpp | 26 +++++++++--- drivers/shiftregister/CMakeLists.txt | 1 + drivers/shiftregister/shiftregister.cmake | 10 +++++ drivers/shiftregister/shiftregister.cpp | 5 +++ drivers/shiftregister/shiftregister.hpp | 48 +++++++++++++++++++++++ examples/inky_frame/inky_frame7_test.cpp | 44 +++++++++++++-------- 9 files changed, 123 insertions(+), 44 deletions(-) create mode 100644 drivers/shiftregister/CMakeLists.txt create mode 100644 drivers/shiftregister/shiftregister.cmake create mode 100644 drivers/shiftregister/shiftregister.cpp create mode 100644 drivers/shiftregister/shiftregister.hpp diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index 309ca95c..d1978c9d 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -41,4 +41,5 @@ add_subdirectory(pms5003) add_subdirectory(sh1107) add_subdirectory(st7567) add_subdirectory(psram_display) -add_subdirectory(inky73) \ No newline at end of file +add_subdirectory(inky73) +add_subdirectory(shiftregister) \ No newline at end of file diff --git a/drivers/inky73/inky73.cmake b/drivers/inky73/inky73.cmake index 8c965f41..0489400e 100644 --- a/drivers/inky73/inky73.cmake +++ b/drivers/inky73/inky73.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 hardware_spi) +target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_spi shiftregister) diff --git a/drivers/inky73/inky73.cpp b/drivers/inky73/inky73.cpp index 2a2f442d..c802dd13 100644 --- a/drivers/inky73/inky73.cpp +++ b/drivers/inky73/inky73.cpp @@ -44,18 +44,10 @@ namespace pimoroni { }; bool UC8159Inky7::is_busy() { - if(BUSY == PIN_UNUSED) { - if(absolute_time_diff_us(get_absolute_time(), timeout) > 0) { - return true; - } else { - return false; - } - } - return !gpio_get(BUSY); + return !(sr.read() & 128); } - void UC8159Inky7::busy_wait(uint minimum_wait_ms) { - timeout = make_timeout_time_ms(minimum_wait_ms); + void UC8159Inky7::busy_wait() { while(is_busy()) { tight_loop_contents(); } @@ -82,10 +74,6 @@ namespace pimoroni { gpio_set_dir(RESET, GPIO_OUT); gpio_put(RESET, 1); - gpio_set_function(BUSY, GPIO_FUNC_SIO); - gpio_set_dir(BUSY, GPIO_IN); - gpio_set_pulls(BUSY, true, false); - gpio_set_function(SCK, GPIO_FUNC_SPI); gpio_set_function(MOSI, GPIO_FUNC_SPI); }; @@ -189,18 +177,20 @@ namespace pimoroni { busy_wait(); command(PON, {0}); // turn on - busy_wait(200); + busy_wait(); command(DRF, {0}); // start display refresh - busy_wait(200); + busy_wait(); if(blocking) { - busy_wait(32 * 1000); + busy_wait(); command(POF); // turn off - } else { - timeout = make_timeout_time_ms(32 * 1000); } } + bool UC8159Inky7::is_pressed(Button button) { + return sr.read() & button; + } + } diff --git a/drivers/inky73/inky73.hpp b/drivers/inky73/inky73.hpp index 805dff47..45bb54d4 100644 --- a/drivers/inky73/inky73.hpp +++ b/drivers/inky73/inky73.hpp @@ -8,6 +8,7 @@ #include "common/pimoroni_common.hpp" #include "common/pimoroni_bus.hpp" #include "libraries/pico_graphics/pico_graphics.hpp" +#include "drivers/shiftregister/shiftregister.hpp" namespace pimoroni { @@ -23,14 +24,25 @@ namespace pimoroni { uint DC = 28; // 27; uint SCK = SPI_DEFAULT_SCK; uint MOSI = SPI_DEFAULT_MOSI; - uint BUSY = PIN_UNUSED; uint RESET = 27; //25; - absolute_time_t timeout; + uint SR_CLOCK = 8; + uint SR_LATCH = 9; + uint SR_DATA = 10; bool blocking = false; + ShiftRegister sr = ShiftRegister(SR_CLOCK, SR_LATCH, SR_DATA); + public: + enum Button : uint8_t { + BUTTON_A = 1, + BUTTON_B = 2, + BUTTON_C = 4, + BUTTON_D = 8, + BUTTON_E = 16 + }; + enum colour : uint8_t { BLACK = 0, WHITE = 1, @@ -44,12 +56,12 @@ namespace pimoroni { UC8159Inky7(uint16_t width, uint16_t height) : UC8159Inky7(width, height, ROTATE_0, {PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, 28, PIN_UNUSED}) {}; - UC8159Inky7(uint16_t width, uint16_t height, SPIPins pins, uint busy=PIN_UNUSED, uint reset=27) : UC8159Inky7(width, height, ROTATE_0, pins, busy, reset) {}; + UC8159Inky7(uint16_t width, uint16_t height, SPIPins pins, uint reset=27) : UC8159Inky7(width, height, ROTATE_0, pins, reset) {}; - UC8159Inky7(uint16_t width, uint16_t height, Rotation rotation, SPIPins pins, uint busy=PIN_UNUSED, uint reset=27) : + UC8159Inky7(uint16_t width, uint16_t height, Rotation rotation, SPIPins pins, uint reset=27) : DisplayDriver(width, height, rotation), spi(pins.spi), - CS(pins.cs), DC(pins.dc), SCK(pins.sck), MOSI(pins.mosi), BUSY(busy), RESET(reset) { + CS(pins.cs), DC(pins.dc), SCK(pins.sck), MOSI(pins.mosi), RESET(reset) { init(); } @@ -58,7 +70,7 @@ namespace pimoroni { // Methods //-------------------------------------------------- public: - void busy_wait(uint minimum_wait_ms=0); + void busy_wait(); void reset(); void power_off(); @@ -67,6 +79,8 @@ namespace pimoroni { void set_blocking(bool blocking); + bool is_pressed(Button button); + private: void init(); void setup(); diff --git a/drivers/shiftregister/CMakeLists.txt b/drivers/shiftregister/CMakeLists.txt new file mode 100644 index 00000000..5dc6ee3b --- /dev/null +++ b/drivers/shiftregister/CMakeLists.txt @@ -0,0 +1 @@ +include(shiftregister.cmake) \ No newline at end of file diff --git a/drivers/shiftregister/shiftregister.cmake b/drivers/shiftregister/shiftregister.cmake new file mode 100644 index 00000000..3959a18c --- /dev/null +++ b/drivers/shiftregister/shiftregister.cmake @@ -0,0 +1,10 @@ +set(DRIVER_NAME shiftregister) +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) diff --git a/drivers/shiftregister/shiftregister.cpp b/drivers/shiftregister/shiftregister.cpp new file mode 100644 index 00000000..d03172d1 --- /dev/null +++ b/drivers/shiftregister/shiftregister.cpp @@ -0,0 +1,5 @@ +#include "shiftregister.hpp" + +namespace pimoroni { + +} \ No newline at end of file diff --git a/drivers/shiftregister/shiftregister.hpp b/drivers/shiftregister/shiftregister.hpp new file mode 100644 index 00000000..0002b70e --- /dev/null +++ b/drivers/shiftregister/shiftregister.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include "pico/stdlib.h" +#include "hardware/spi.h" +#include "hardware/gpio.h" + +namespace pimoroni { + template class ShiftRegister { + private: + uint CLOCK = 0; + uint LATCH = 0; + uint DATA = 0; + + public: + ShiftRegister(uint clock, uint latch, uint data) : + CLOCK(clock), + LATCH(latch), + DATA(data) { + gpio_init(CLOCK); + gpio_set_function(CLOCK, GPIO_FUNC_SIO); + gpio_set_dir(CLOCK, GPIO_OUT); + + gpio_init(LATCH); + gpio_set_function(LATCH, GPIO_FUNC_SIO); + gpio_set_dir(LATCH, GPIO_OUT); + + gpio_init(DATA); + gpio_set_function(DATA, GPIO_FUNC_SIO); + gpio_set_dir(DATA, GPIO_IN); + } + T read() { + gpio_put(LATCH, 0); + __asm("NOP;"); + gpio_put(LATCH, 1); + __asm("NOP;"); + T out = 0; + for (auto i = 0u; i < sizeof(T) * 8; i++) { + out <<= 1; + out |= gpio_get(DATA); + gpio_put(CLOCK, 1); + __asm("NOP;"); + gpio_put(CLOCK, 0); + __asm("NOP;"); + } + return out; + } + }; +} \ No newline at end of file diff --git a/examples/inky_frame/inky_frame7_test.cpp b/examples/inky_frame/inky_frame7_test.cpp index f509e0ff..1a8e8ce8 100644 --- a/examples/inky_frame/inky_frame7_test.cpp +++ b/examples/inky_frame/inky_frame7_test.cpp @@ -7,33 +7,43 @@ using namespace pimoroni; +uint LED_PIN = 8; + int main() { stdio_init_all(); + gpio_init(LED_PIN); + gpio_set_function(LED_PIN, GPIO_FUNC_SIO); + gpio_set_dir(LED_PIN, GPIO_OUT); + PSRamDisplay ramDisplay(800, 480); PicoGraphics_PenInky7 graphics(800, 480, ramDisplay); - UC8159Inky7 uc8159(800,400); + UC8159Inky7 inky7(800,400); - graphics.set_pen(1); - graphics.clear(); + while (true) { + while(!inky7.is_pressed(UC8159Inky7::BUTTON_A)) { + sleep_ms(10); + } + graphics.set_pen(1); + graphics.clear(); - for(int i =0 ; i < 100 ; i++) - { - uint size = 25 + (rand() % 50); - uint x = rand() % graphics.bounds.w; - uint y = rand() % graphics.bounds.h; + for(int i =0 ; i < 100 ; i++) + { + uint size = 25 + (rand() % 50); + uint x = rand() % graphics.bounds.w; + uint y = rand() % graphics.bounds.h; - graphics.set_pen(0); - graphics.circle(Point(x, y), size); + graphics.set_pen(0); + graphics.circle(Point(x, y), size); - graphics.set_pen(2+(i%5)); - graphics.circle(Point(x, y), size-2); - } + graphics.set_pen(2+(i%5)); + graphics.circle(Point(x, y), size-2); + } - uc8159.update(&graphics); - - while(true) - sleep_ms(1000); + gpio_put(LED_PIN, 1); + inky7.update(&graphics); + gpio_put(LED_PIN, 0); + } return 0; }