Merge pull request #663 from pimoroni/feature/inky73
Support for Inky Frame 7.3" (using direct pen into PSRAM framebuffer)
This commit is contained in:
commit
93ac854672
|
@ -40,3 +40,6 @@ add_subdirectory(pcf85063a)
|
|||
add_subdirectory(pms5003)
|
||||
add_subdirectory(sh1107)
|
||||
add_subdirectory(st7567)
|
||||
add_subdirectory(psram_display)
|
||||
add_subdirectory(inky73)
|
||||
add_subdirectory(shiftregister)
|
|
@ -0,0 +1 @@
|
|||
include(inky73.cmake)
|
|
@ -0,0 +1,10 @@
|
|||
set(DRIVER_NAME inky73)
|
||||
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 hardware_spi shiftregister)
|
|
@ -0,0 +1,196 @@
|
|||
#include "inky73.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
enum reg {
|
||||
PSR = 0x00,
|
||||
PWR = 0x01,
|
||||
POF = 0x02,
|
||||
PFS = 0x03,
|
||||
PON = 0x04,
|
||||
BTST1 = 0x05,
|
||||
BTST2 = 0x06,
|
||||
DSLP = 0x07,
|
||||
BTST3 = 0x08,
|
||||
DTM1 = 0x10,
|
||||
DSP = 0x11,
|
||||
DRF = 0x12,
|
||||
IPC = 0x13,
|
||||
PLL = 0x30,
|
||||
TSC = 0x40,
|
||||
TSE = 0x41,
|
||||
TSW = 0x42,
|
||||
TSR = 0x43,
|
||||
CDI = 0x50,
|
||||
LPD = 0x51,
|
||||
TCON = 0x60,
|
||||
TRES = 0x61,
|
||||
DAM = 0x65,
|
||||
REV = 0x70,
|
||||
FLG = 0x71,
|
||||
AMV = 0x80,
|
||||
VV = 0x81,
|
||||
VDCS = 0x82,
|
||||
T_VDCS = 0x84,
|
||||
AGID = 0x86,
|
||||
CMDH = 0xAA,
|
||||
CCSET =0xE0,
|
||||
PWS = 0xE3,
|
||||
TSSET = 0xE6 // E5 or E6
|
||||
};
|
||||
|
||||
bool Inky73::is_busy() {
|
||||
return !(sr.read() & 128);
|
||||
}
|
||||
|
||||
void Inky73::busy_wait() {
|
||||
while(is_busy()) {
|
||||
tight_loop_contents();
|
||||
}
|
||||
}
|
||||
|
||||
void Inky73::reset() {
|
||||
gpio_put(RESET, 0); sleep_ms(10);
|
||||
gpio_put(RESET, 1); sleep_ms(10);
|
||||
busy_wait();
|
||||
}
|
||||
|
||||
void Inky73::init() {
|
||||
// configure spi interface and pins
|
||||
spi_init(spi, 20'000'000);
|
||||
|
||||
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_put(CS, 1);
|
||||
|
||||
gpio_set_function(RESET, GPIO_FUNC_SIO);
|
||||
gpio_set_dir(RESET, GPIO_OUT);
|
||||
gpio_put(RESET, 1);
|
||||
|
||||
gpio_set_function(SCK, GPIO_FUNC_SPI);
|
||||
gpio_set_function(MOSI, GPIO_FUNC_SPI);
|
||||
};
|
||||
|
||||
void Inky73::setup() {
|
||||
reset();
|
||||
busy_wait();
|
||||
|
||||
command(CMDH, {0x49, 0x55, 0x20, 0x08, 0x09, 0x18});
|
||||
command(PWR, {0x3F, 0x00, 0x32, 0x2A, 0x0E, 0x2A});
|
||||
if (rotation == ROTATE_0) {
|
||||
command(PSR, {0x53, 0x69});
|
||||
} else {
|
||||
command(PSR, {0x5F, 0x69});
|
||||
}
|
||||
//command(PSR, {0x5F, 0x69});
|
||||
command(PFS, {0x00, 0x54, 0x00, 0x44});
|
||||
command(BTST1, {0x40, 0x1F, 0x1F, 0x2C});
|
||||
command(BTST2, {0x6F, 0x1F, 0x16, 0x25});
|
||||
command(BTST3, {0x6F, 0x1F, 0x1F, 0x22});
|
||||
command(IPC, {0x00, 0x04});
|
||||
command(PLL, {0x02});
|
||||
command(TSE, {0x00});
|
||||
command(CDI, {0x3F});
|
||||
command(TCON, {0x02, 0x00});
|
||||
command(TRES, {0x03, 0x20, 0x01, 0xE0});
|
||||
command(VDCS, {0x1E});
|
||||
command(T_VDCS, {0x00});
|
||||
command(AGID, {0x00});
|
||||
command(PWS, {0x2F});
|
||||
command(CCSET, {0x00});
|
||||
command(TSSET, {0x00});
|
||||
}
|
||||
|
||||
void Inky73::set_blocking(bool blocking) {
|
||||
this->blocking = blocking;
|
||||
}
|
||||
|
||||
void Inky73::power_off() {
|
||||
busy_wait();
|
||||
command(POF); // turn off
|
||||
}
|
||||
|
||||
void Inky73::command(uint8_t reg, size_t len, const uint8_t *data) {
|
||||
gpio_put(CS, 0);
|
||||
|
||||
gpio_put(DC, 0); // command mode
|
||||
spi_write_blocking(spi, ®, 1);
|
||||
|
||||
if(len > 0) {
|
||||
gpio_put(DC, 1); // data mode
|
||||
spi_write_blocking(spi, (const uint8_t*)data, len);
|
||||
}
|
||||
|
||||
gpio_put(CS, 1);
|
||||
}
|
||||
|
||||
void Inky73::data(size_t len, const uint8_t *data) {
|
||||
gpio_put(CS, 0);
|
||||
gpio_put(DC, 1); // data mode
|
||||
spi_write_blocking(spi, (const uint8_t*)data, len);
|
||||
gpio_put(CS, 1);
|
||||
}
|
||||
|
||||
void Inky73::command(uint8_t reg, std::initializer_list<uint8_t> values) {
|
||||
command(reg, values.size(), (uint8_t *)values.begin());
|
||||
}
|
||||
|
||||
void Inky73::update(PicoGraphics *graphics) {
|
||||
if(graphics->pen_type != PicoGraphics::PEN_INKY7) return; // Incompatible buffer
|
||||
|
||||
if(blocking) {
|
||||
busy_wait();
|
||||
}
|
||||
|
||||
setup();
|
||||
|
||||
gpio_put(CS, 0);
|
||||
|
||||
uint8_t reg = DTM1;
|
||||
gpio_put(DC, 0); // command mode
|
||||
spi_write_blocking(spi, ®, 1);
|
||||
|
||||
gpio_put(DC, 1); // data mode
|
||||
|
||||
uint totalLength = 0;
|
||||
gpio_put(CS, 1);
|
||||
graphics->frame_convert(PicoGraphics::PEN_INKY7, [this, &totalLength](void *buf, size_t length) {
|
||||
if (length > 0) {
|
||||
gpio_put(CS, 0);
|
||||
spi_write_blocking(spi, (const uint8_t*)buf, length);
|
||||
totalLength += length;
|
||||
gpio_put(CS, 1);
|
||||
}
|
||||
});
|
||||
|
||||
gpio_put(DC, 0); // data mode
|
||||
|
||||
gpio_put(CS, 1);
|
||||
|
||||
busy_wait();
|
||||
|
||||
command(PON, {0}); // turn on
|
||||
busy_wait();
|
||||
|
||||
command(DRF, {0}); // start display refresh
|
||||
busy_wait();
|
||||
|
||||
if(blocking) {
|
||||
busy_wait();
|
||||
|
||||
command(POF); // turn off
|
||||
}
|
||||
}
|
||||
|
||||
bool Inky73::is_pressed(Button button) {
|
||||
return sr.read() & button;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
#pragma once
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
#include "pico/stdlib.h"
|
||||
#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"
|
||||
#include "drivers/shiftregister/shiftregister.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
class Inky73 : public DisplayDriver {
|
||||
//--------------------------------------------------
|
||||
// Variables
|
||||
//--------------------------------------------------
|
||||
private:
|
||||
spi_inst_t *spi = PIMORONI_SPI_DEFAULT_INSTANCE;
|
||||
|
||||
// interface pins with our standard defaults where appropriate
|
||||
uint CS = SPI_BG_FRONT_CS;
|
||||
uint DC = 28; // 27;
|
||||
uint SCK = SPI_DEFAULT_SCK;
|
||||
uint MOSI = SPI_DEFAULT_MOSI;
|
||||
uint RESET = 27; //25;
|
||||
|
||||
uint SR_CLOCK = 8;
|
||||
uint SR_LATCH = 9;
|
||||
uint SR_DATA = 10;
|
||||
|
||||
bool blocking = false;
|
||||
|
||||
ShiftRegister<uint8_t> sr = ShiftRegister<uint8_t>(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,
|
||||
GREEN = 2,
|
||||
BLUE = 3,
|
||||
RED = 4,
|
||||
YELLOW = 5,
|
||||
ORANGE = 6,
|
||||
CLEAN = 7
|
||||
};
|
||||
|
||||
Inky73(uint16_t width, uint16_t height) : Inky73(width, height, ROTATE_0, {PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, 28, PIN_UNUSED}) {};
|
||||
|
||||
Inky73(uint16_t width, uint16_t height, SPIPins pins, uint reset=27) : Inky73(width, height, ROTATE_0, pins, reset) {};
|
||||
|
||||
Inky73(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), RESET(reset) {
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Methods
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
void busy_wait();
|
||||
void reset();
|
||||
void power_off();
|
||||
|
||||
bool is_busy() override;
|
||||
void update(PicoGraphics *graphics) override;
|
||||
|
||||
void set_blocking(bool blocking);
|
||||
|
||||
bool is_pressed(Button button);
|
||||
|
||||
private:
|
||||
void init();
|
||||
void setup();
|
||||
void command(uint8_t reg, size_t len, const uint8_t *data);
|
||||
void command(uint8_t reg, std::initializer_list<uint8_t> values);
|
||||
void command(uint8_t reg, const uint8_t data) {command(reg, 0, &data);};
|
||||
void command(uint8_t reg) {command(reg, 0, nullptr);};
|
||||
void data(size_t len, const uint8_t *data);
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
include(psram_display.cmake)
|
|
@ -0,0 +1,10 @@
|
|||
set(DRIVER_NAME psram_display)
|
||||
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 hardware_spi)
|
|
@ -0,0 +1,75 @@
|
|||
#include "psram_display.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
enum reg {
|
||||
WRITE = 0x02,
|
||||
READ = 0x03,
|
||||
RESET_ENABLE = 0x66,
|
||||
RESET = 0x99
|
||||
};
|
||||
|
||||
void PSRamDisplay::init() {
|
||||
uint baud = spi_init(spi, 31'250'000);
|
||||
printf("PSRam connected at %u\n", baud);
|
||||
gpio_set_function(CS, GPIO_FUNC_SIO);
|
||||
gpio_set_dir(CS, GPIO_OUT);
|
||||
gpio_put(CS, 1);
|
||||
|
||||
gpio_set_function(SCK, GPIO_FUNC_SPI);
|
||||
gpio_set_function(MOSI, GPIO_FUNC_SPI);
|
||||
gpio_set_function(MISO, GPIO_FUNC_SPI);
|
||||
|
||||
gpio_put(CS, 0);
|
||||
uint8_t command_buffer[2] = {RESET_ENABLE, RESET};
|
||||
spi_write_blocking(spi, command_buffer, 2);
|
||||
gpio_put(CS, 1);
|
||||
}
|
||||
|
||||
void PSRamDisplay::write(uint32_t address, size_t len, const uint8_t *data)
|
||||
{
|
||||
gpio_put(CS, 0);
|
||||
uint8_t command_buffer[4] = {WRITE, (uint8_t)((address >> 16) & 0xFF), (uint8_t)((address >> 8) & 0xFF), (uint8_t)(address & 0xFF)};
|
||||
spi_write_blocking(spi, command_buffer, 4);
|
||||
spi_write_blocking(spi, data, len);
|
||||
gpio_put(CS, 1);
|
||||
}
|
||||
|
||||
void PSRamDisplay::write(uint32_t address, size_t len, const uint8_t byte)
|
||||
{
|
||||
gpio_put(CS, 0);
|
||||
uint8_t command_buffer[4] = {WRITE, (uint8_t)((address >> 16) & 0xFF), (uint8_t)((address >> 8) & 0xFF), (uint8_t)(address & 0xFF)};
|
||||
spi_write_blocking(spi, command_buffer, 4);
|
||||
SpiSetBlocking(byte, len);
|
||||
gpio_put(CS, 1);
|
||||
}
|
||||
|
||||
|
||||
void PSRamDisplay::read(uint32_t address, size_t len, uint8_t *data)
|
||||
{
|
||||
gpio_put(CS, 0);
|
||||
uint8_t command_buffer[4] = {READ, (uint8_t)((address >> 16) & 0xFF), (uint8_t)((address >> 8) & 0xFF), (uint8_t)(address & 0xFF)};
|
||||
spi_write_blocking(spi, command_buffer, 4);
|
||||
spi_read_blocking(spi, 0, data, len);
|
||||
gpio_put(CS, 1);
|
||||
}
|
||||
|
||||
void PSRamDisplay::write_pixel(const Point &p, uint8_t colour)
|
||||
{
|
||||
write(pointToAddress(p), 1, colour);
|
||||
}
|
||||
|
||||
void PSRamDisplay::write_pixel_span(const Point &p, uint l, uint8_t colour)
|
||||
{
|
||||
write(pointToAddress(p), l, colour);
|
||||
}
|
||||
|
||||
void PSRamDisplay::read_pixel_span(const Point &p, uint l, uint8_t *data)
|
||||
{
|
||||
read(pointToAddress(p), l, data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "pico/stdlib.h"
|
||||
#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"
|
||||
|
||||
|
||||
// 8 MB PSRam
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
class PSRamDisplay : public IDirectDisplayDriver<uint8_t> {
|
||||
//--------------------------------------------------
|
||||
// Variables
|
||||
//--------------------------------------------------
|
||||
private:
|
||||
spi_inst_t *spi = PIMORONI_SPI_DEFAULT_INSTANCE;
|
||||
|
||||
// interface pins with our standard defaults where appropriate
|
||||
uint CS = 3;
|
||||
uint DC = PIN_UNUSED;
|
||||
uint SCK = SPI_DEFAULT_SCK;
|
||||
uint MOSI = SPI_DEFAULT_MOSI;
|
||||
uint MISO = SPI_DEFAULT_MISO;
|
||||
|
||||
uint32_t start_address = 0;
|
||||
uint16_t width = 0;
|
||||
uint16_t height = 0;
|
||||
|
||||
absolute_time_t timeout;
|
||||
|
||||
bool blocking = false;
|
||||
|
||||
public:
|
||||
enum colour : uint8_t {
|
||||
BLACK = 0,
|
||||
WHITE = 1,
|
||||
GREEN = 2,
|
||||
BLUE = 3,
|
||||
RED = 4,
|
||||
YELLOW = 5,
|
||||
ORANGE = 6,
|
||||
CLEAN = 7
|
||||
};
|
||||
|
||||
PSRamDisplay(uint16_t width, uint16_t height) : PSRamDisplay(width, height, {PIMORONI_SPI_DEFAULT_INSTANCE, 3, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, PIN_UNUSED, PIN_UNUSED, PIN_UNUSED}) {};
|
||||
|
||||
PSRamDisplay(uint16_t width, uint16_t height, SPIPins pins) :
|
||||
spi(pins.spi),
|
||||
CS(pins.cs), DC(pins.dc), SCK(pins.sck), MOSI(pins.mosi),
|
||||
width(width), height(height) {
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Methods
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
void test(void){
|
||||
|
||||
char writeBuffer[1024];
|
||||
char readBuffer[1024];
|
||||
|
||||
uint mb = 8;
|
||||
|
||||
for(uint k = 0; k < 1024*mb; k++)
|
||||
{
|
||||
sprintf(writeBuffer, "%u", k);
|
||||
|
||||
write(k*1024, strlen(writeBuffer)+1, (uint8_t *)writeBuffer);
|
||||
}
|
||||
|
||||
bool bSame = true;
|
||||
for(uint k = 0; k < 1024*mb && bSame; k++)
|
||||
{
|
||||
sprintf(writeBuffer, "%u", k);
|
||||
read(k*1024, strlen(writeBuffer)+1, (uint8_t *)readBuffer);
|
||||
bSame = strcmp(writeBuffer, readBuffer) ==0;
|
||||
printf("[%u] %s == %s ? %s\n", k, writeBuffer, readBuffer, bSame ? "Success" : "Failure");
|
||||
}
|
||||
}
|
||||
|
||||
void write_pixel(const Point &p, uint8_t colour) override;
|
||||
void write_pixel_span(const Point &p, uint l, uint8_t colour) override;
|
||||
void read_pixel_span(const Point &p, uint l, uint8_t *data) override;
|
||||
|
||||
int __not_in_flash_func(SpiSetBlocking)(const uint16_t uSrc, size_t uLen)
|
||||
{
|
||||
invalid_params_if(SPI, 0 > (int)uLen);
|
||||
// Deliberately overflow FIFO, then clean up afterward, to minimise amount
|
||||
// of APB polling required per halfword
|
||||
for (size_t i = 0; i < uLen; ++i) {
|
||||
while (!spi_is_writable(spi))
|
||||
tight_loop_contents();
|
||||
spi_get_hw(spi)->dr = uSrc;
|
||||
}
|
||||
|
||||
while (spi_is_readable(spi))
|
||||
(void)spi_get_hw(spi)->dr;
|
||||
while (spi_get_hw(spi)->sr & SPI_SSPSR_BSY_BITS)
|
||||
tight_loop_contents();
|
||||
while (spi_is_readable(spi))
|
||||
(void)spi_get_hw(spi)->dr;
|
||||
|
||||
// Don't leave overrun flag set
|
||||
spi_get_hw(spi)->icr = SPI_SSPICR_RORIC_BITS;
|
||||
|
||||
return (int)uLen;
|
||||
}
|
||||
|
||||
private:
|
||||
void init();
|
||||
void write(uint32_t address, size_t len, const uint8_t *data);
|
||||
void write(uint32_t address, size_t len, const uint8_t byte);
|
||||
void read(uint32_t address, size_t len, uint8_t *data);
|
||||
|
||||
uint32_t pointToAddress(const Point &p)
|
||||
{
|
||||
return start_address + (p.y * width) + p.x;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
include(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)
|
|
@ -0,0 +1,5 @@
|
|||
#include "shiftregister.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
#pragma once
|
||||
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/spi.h"
|
||||
#include "hardware/gpio.h"
|
||||
|
||||
namespace pimoroni {
|
||||
template<typename T> 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;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
include(inky_frame_jpeg_image.cmake)
|
||||
include(inky_frame_sleepy_head.cmake)
|
||||
include(inky_frame_day_planner.cmake)
|
||||
include(inky_frame7_test.cmake)
|
|
@ -0,0 +1,14 @@
|
|||
set(OUTPUT_NAME inky_frame7_test)
|
||||
|
||||
add_executable(
|
||||
${OUTPUT_NAME}
|
||||
inky_frame7_test.cpp
|
||||
)
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(${OUTPUT_NAME} pico_stdlib psram_display inky73 inky_frame hardware_pwm hardware_spi hardware_i2c hardware_rtc fatfs sdcard pico_graphics)
|
||||
|
||||
pico_enable_stdio_usb(${OUTPUT_NAME} 0)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(${OUTPUT_NAME})
|
|
@ -0,0 +1,49 @@
|
|||
#include <cstdio>
|
||||
#include <math.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include "drivers/psram_display/psram_display.hpp"
|
||||
#include "drivers/inky73/inky73.hpp"
|
||||
|
||||
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);
|
||||
Inky73 inky7(800,400);
|
||||
|
||||
while (true) {
|
||||
while(!inky7.is_pressed(Inky73::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;
|
||||
|
||||
graphics.set_pen(0);
|
||||
graphics.circle(Point(x, y), size);
|
||||
|
||||
graphics.set_pen(2+(i%5));
|
||||
graphics.circle(Point(x, y), size-2);
|
||||
}
|
||||
|
||||
gpio_put(LED_PIN, 1);
|
||||
inky7.update(&graphics);
|
||||
gpio_put(LED_PIN, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -9,6 +9,7 @@ add_library(pico_graphics
|
|||
${CMAKE_CURRENT_LIST_DIR}/pico_graphics_pen_rgb332.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico_graphics_pen_rgb565.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico_graphics_pen_rgb888.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico_graphics_pen_inky7.cpp
|
||||
)
|
||||
|
||||
target_include_directories(pico_graphics INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
|
|
@ -168,6 +168,7 @@ namespace pimoroni {
|
|||
PEN_RGB332,
|
||||
PEN_RGB565,
|
||||
PEN_RGB888,
|
||||
PEN_INKY7
|
||||
};
|
||||
|
||||
void *frame_buffer;
|
||||
|
@ -486,4 +487,62 @@ namespace pimoroni {
|
|||
virtual void cleanup() {};
|
||||
};
|
||||
|
||||
template<typename T> class IDirectDisplayDriver {
|
||||
public:
|
||||
virtual void write_pixel(const Point &p, T colour) = 0;
|
||||
virtual void write_pixel_span(const Point &p, uint l, T colour) = 0;
|
||||
|
||||
virtual void read_pixel(const Point &p, T &data) {};
|
||||
virtual void read_pixel_span(const Point &p, uint l, T *data) {};
|
||||
};
|
||||
|
||||
|
||||
class PicoGraphics_PenInky7 : public PicoGraphics {
|
||||
public:
|
||||
static const uint16_t palette_size = 8;
|
||||
RGB palette[8] = {
|
||||
/*
|
||||
{0x2b, 0x2a, 0x37},
|
||||
{0xdc, 0xcb, 0xba},
|
||||
{0x35, 0x56, 0x33},
|
||||
{0x33, 0x31, 0x47},
|
||||
{0x9c, 0x3b, 0x2e},
|
||||
{0xd3, 0xa9, 0x34},
|
||||
{0xab, 0x58, 0x37},
|
||||
{0xb2, 0x8e, 0x67}
|
||||
*/
|
||||
{ 0, 0, 0}, // black
|
||||
{255, 255, 255}, // white
|
||||
{ 0, 255, 0}, // green
|
||||
{ 0, 0, 255}, // blue
|
||||
{255, 0, 0}, // red
|
||||
{255, 255, 0}, // yellow
|
||||
{255, 128, 0}, // orange
|
||||
{220, 180, 200} // clean / taupe?!
|
||||
};
|
||||
|
||||
std::array<std::array<uint8_t, 16>, 512> candidate_cache;
|
||||
bool cache_built = false;
|
||||
std::array<uint8_t, 16> candidates;
|
||||
|
||||
RGB src_color;
|
||||
RGB565 color;
|
||||
IDirectDisplayDriver<uint8_t> &driver;
|
||||
|
||||
PicoGraphics_PenInky7(uint16_t width, uint16_t height, IDirectDisplayDriver<uint8_t> &direct_display_driver);
|
||||
void set_pen(uint c) override;
|
||||
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
void set_thickness(uint t) override {};
|
||||
int create_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
void set_pixel(const Point &p) override;
|
||||
void set_pixel_span(const Point &p, uint l) override;
|
||||
|
||||
void get_dither_candidates(const RGB &col, const RGB *palette, size_t len, std::array<uint8_t, 16> &candidates);
|
||||
void set_pixel_dither(const Point &p, const RGB &c) override;
|
||||
|
||||
void frame_convert(PenType type, conversion_callback_func callback) override;
|
||||
static size_t buffer_size(uint w, uint h) {
|
||||
return w * h;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
#include "pico_graphics.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
PicoGraphics_PenInky7::PicoGraphics_PenInky7(uint16_t width, uint16_t height, IDirectDisplayDriver<uint8_t> &direct_display_driver)
|
||||
: PicoGraphics(width, height, nullptr),
|
||||
driver(direct_display_driver) {
|
||||
this->pen_type = PEN_INKY7;
|
||||
}
|
||||
void PicoGraphics_PenInky7::set_pen(uint c) {
|
||||
color = c & 0x7;
|
||||
}
|
||||
void PicoGraphics_PenInky7::set_pen(uint8_t r, uint8_t g, uint8_t b) {
|
||||
}
|
||||
int PicoGraphics_PenInky7::create_pen(uint8_t r, uint8_t g, uint8_t b) {
|
||||
return 0;
|
||||
}
|
||||
void PicoGraphics_PenInky7::set_pixel(const Point &p) {
|
||||
driver.write_pixel(p, color);
|
||||
}
|
||||
void PicoGraphics_PenInky7::set_pixel_span(const Point &p, uint l) {
|
||||
driver.write_pixel_span(p, l, color);
|
||||
}
|
||||
void PicoGraphics_PenInky7::get_dither_candidates(const RGB &col, const RGB *palette, size_t len, std::array<uint8_t, 16> &candidates) {
|
||||
RGB error;
|
||||
for(size_t i = 0; i < candidates.size(); i++) {
|
||||
candidates[i] = (col + error).closest(palette, len);
|
||||
error += (col - palette[candidates[i]]);
|
||||
}
|
||||
|
||||
// sort by a rough approximation of luminance, this ensures that neighbouring
|
||||
// pixels in the dither matrix are at extreme opposites of luminence
|
||||
// giving a more balanced output
|
||||
std::sort(candidates.begin(), candidates.end(), [palette](int a, int b) {
|
||||
return palette[a].luminance() > palette[b].luminance();
|
||||
});
|
||||
}
|
||||
void PicoGraphics_PenInky7::set_pixel_dither(const Point &p, const RGB &c) {
|
||||
if(!bounds.contains(p)) return;
|
||||
|
||||
if(!cache_built) {
|
||||
for(uint i = 0; i < 512; i++) {
|
||||
uint r = (i & 0x1c0) >> 1;
|
||||
uint g = (i & 0x38) << 2;
|
||||
uint b = (i & 0x7) << 5;
|
||||
RGB cache_col(
|
||||
r | (r >> 3) | (r >> 6),
|
||||
g | (g >> 3) | (g >> 6),
|
||||
b | (b >> 3) | (b >> 6)
|
||||
);
|
||||
get_dither_candidates(cache_col, palette, palette_size, candidate_cache[i]);
|
||||
}
|
||||
cache_built = true;
|
||||
}
|
||||
|
||||
uint cache_key = ((c.r & 0xE0) << 1) | ((c.g & 0xE0) >> 2) | ((c.b & 0xE0) >> 5);
|
||||
//get_dither_candidates(c, palette, 256, candidates);
|
||||
|
||||
// find the pattern coordinate offset
|
||||
uint pattern_index = (p.x & 0b11) | ((p.y & 0b11) << 2);
|
||||
|
||||
// set the pixel
|
||||
//color = candidates[pattern[pattern_index]];
|
||||
color = candidate_cache[cache_key][dither16_pattern[pattern_index]];
|
||||
set_pixel(p);
|
||||
}
|
||||
void PicoGraphics_PenInky7::frame_convert(PenType type, conversion_callback_func callback) {
|
||||
if(type == PEN_INKY7) {
|
||||
uint byte_count = bounds.w/2;
|
||||
uint8_t buffer[bounds.w];
|
||||
|
||||
for(int32_t r = 0; r < bounds.h; r++)
|
||||
{
|
||||
driver.read_pixel_span(Point(0, r), bounds.w, buffer);
|
||||
// for(int y=0; y < 800; y++)
|
||||
// buffer[y] = rand() % 7;
|
||||
|
||||
// convert byte storage to nibble storage
|
||||
uint8_t *pDst = buffer;
|
||||
uint8_t *pSrc = buffer;
|
||||
|
||||
for(uint c = 0; c < byte_count; c++)
|
||||
{
|
||||
uint8_t nibble = ((*pSrc++) << 4);
|
||||
nibble |= ((*pSrc++) & 0xf);
|
||||
*pDst++ = nibble;
|
||||
}
|
||||
|
||||
callback(buffer, byte_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,6 @@ if [[ ! -d "$MPY_DIR/boards/$BOARD" ]] && [[ -d "$FIXUP_DIR/$NAME/$BOARD/" ]]; t
|
|||
fi
|
||||
|
||||
if [[ -f "$FIXUP_DIR/$NAME/fixup.sh" ]]; then
|
||||
echo "Running custom fixup[.sh"
|
||||
echo "Running custom fixup.sh"
|
||||
bash "$FIXUP_DIR/$NAME/fixup.sh" "$FIXUP_DIR/$NAME" "$MPY_DIR"
|
||||
fi
|
|
@ -17,9 +17,6 @@
|
|||
// Debug level (0-4) 1=warning, 2=info, 3=debug, 4=verbose
|
||||
// #define MODUSSL_MBEDTLS_DEBUG_LEVEL 1
|
||||
|
||||
#define MICROPY_HW_PIN_CYW43_COUNT CYW43_WL_GPIO_COUNT
|
||||
#ifdef CYW43_WL_GPIO_LED_PIN
|
||||
#define MICROPY_HW_PIN_CYW43_LED_PIN_NUM CYW43_WL_GPIO_LED_PIN
|
||||
#endif
|
||||
#define MICROPY_HW_PIN_EXT_COUNT CYW43_WL_GPIO_COUNT
|
||||
|
||||
#define MICROPY_HW_PIN_RESERVED(i) ((i) == CYW43_PIN_WL_HOST_WAKE || (i) == CYW43_PIN_WL_REG_ON)
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
GP0,GPIO0
|
||||
GP1,GPIO1
|
||||
GP2,GPIO2
|
||||
GP3,GPIO3
|
||||
GP4,GPIO4
|
||||
GP5,GPIO5
|
||||
GP6,GPIO6
|
||||
GP7,GPIO7
|
||||
GP8,GPIO8
|
||||
GP9,GPIO9
|
||||
GP10,GPIO10
|
||||
GP11,GPIO11
|
||||
GP12,GPIO12
|
||||
GP13,GPIO13
|
||||
GP14,GPIO14
|
||||
GP15,GPIO15
|
||||
GP16,GPIO16
|
||||
GP17,GPIO17
|
||||
GP18,GPIO18
|
||||
GP19,GPIO19
|
||||
GP20,GPIO20
|
||||
GP21,GPIO21
|
||||
GP22,GPIO22
|
||||
GP26,GPIO26
|
||||
GP27,GPIO27
|
||||
GP28,GPIO28
|
||||
WL_GPIO0,EXT_GPIO0
|
||||
WL_GPIO1,EXT_GPIO1
|
||||
WL_GPIO2,EXT_GPIO2
|
||||
LED,EXT_GPIO0
|
|
|
@ -3,4 +3,5 @@ include("../manifest.py")
|
|||
require("mip")
|
||||
require("ntptime")
|
||||
require("urequests")
|
||||
require("urllib.urequest")
|
||||
require("umqtt.simple")
|
|
@ -17,9 +17,6 @@
|
|||
// Debug level (0-4) 1=warning, 2=info, 3=debug, 4=verbose
|
||||
// #define MODUSSL_MBEDTLS_DEBUG_LEVEL 1
|
||||
|
||||
#define MICROPY_HW_PIN_CYW43_COUNT CYW43_WL_GPIO_COUNT
|
||||
#ifdef CYW43_WL_GPIO_LED_PIN
|
||||
#define MICROPY_HW_PIN_CYW43_LED_PIN_NUM CYW43_WL_GPIO_LED_PIN
|
||||
#endif
|
||||
#define MICROPY_HW_PIN_EXT_COUNT CYW43_WL_GPIO_COUNT
|
||||
|
||||
#define MICROPY_HW_PIN_RESERVED(i) ((i) == CYW43_PIN_WL_HOST_WAKE || (i) == CYW43_PIN_WL_REG_ON)
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
GP0,GPIO0
|
||||
GP1,GPIO1
|
||||
GP2,GPIO2
|
||||
GP3,GPIO3
|
||||
GP4,GPIO4
|
||||
GP5,GPIO5
|
||||
GP6,GPIO6
|
||||
GP7,GPIO7
|
||||
GP8,GPIO8
|
||||
GP9,GPIO9
|
||||
GP10,GPIO10
|
||||
GP11,GPIO11
|
||||
GP12,GPIO12
|
||||
GP13,GPIO13
|
||||
GP14,GPIO14
|
||||
GP15,GPIO15
|
||||
GP16,GPIO16
|
||||
GP17,GPIO17
|
||||
GP18,GPIO18
|
||||
GP19,GPIO19
|
||||
GP20,GPIO20
|
||||
GP21,GPIO21
|
||||
GP22,GPIO22
|
||||
GP26,GPIO26
|
||||
GP27,GPIO27
|
||||
GP28,GPIO28
|
||||
WL_GPIO0,EXT_GPIO0
|
||||
WL_GPIO1,EXT_GPIO1
|
||||
WL_GPIO2,EXT_GPIO2
|
||||
LED,EXT_GPIO0
|
|
|
@ -145,7 +145,10 @@ MICROPY_EVENT_POLL_HOOK
|
|||
} else if (current_graphics->pen_type == PicoGraphics::PEN_RGB888) {
|
||||
current_graphics->set_pen(RGB((RGB565)pDraw->pPixels[i]).to_rgb888());
|
||||
current_graphics->pixel({pDraw->x + x, pDraw->y + y});
|
||||
} else if (current_graphics->pen_type == PicoGraphics::PEN_P8 || current_graphics->pen_type == PicoGraphics::PEN_P4 || current_graphics->pen_type == PicoGraphics::PEN_3BIT) {
|
||||
} else if (current_graphics->pen_type == PicoGraphics::PEN_P8
|
||||
|| current_graphics->pen_type == PicoGraphics::PEN_P4
|
||||
|| current_graphics->pen_type == PicoGraphics::PEN_3BIT
|
||||
|| current_graphics->pen_type == PicoGraphics::PEN_INKY7) {
|
||||
current_graphics->set_pixel_dither({pDraw->x + x, pDraw->y + y}, RGB((RGB565)pDraw->pPixels[i]));
|
||||
} else {
|
||||
current_graphics->set_pen(pDraw->pPixels[i]);
|
||||
|
@ -262,6 +265,7 @@ mp_obj_t _JPEG_decode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args
|
|||
case PicoGraphics::PEN_P8:
|
||||
case PicoGraphics::PEN_P4:
|
||||
case PicoGraphics::PEN_3BIT:
|
||||
case PicoGraphics::PEN_INKY7:
|
||||
self->jpeg->setPixelType(RGB565_BIG_ENDIAN);
|
||||
break;
|
||||
// TODO 2-bit is currently unsupported
|
||||
|
|
|
@ -11,6 +11,9 @@ target_sources(usermod_${MOD_NAME} INTERFACE
|
|||
${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}/../../../drivers/inky73/inky73.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/shiftregister/shiftregister.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/psram_display/psram_display.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
|
||||
|
@ -20,6 +23,7 @@ target_sources(usermod_${MOD_NAME} INTERFACE
|
|||
${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_graphics/pico_graphics_pen_rgb332.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_graphics/pico_graphics_pen_rgb565.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_graphics/pico_graphics_pen_rgb888.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_graphics/pico_graphics_pen_inky7.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_graphics/types.cpp
|
||||
)
|
||||
|
||||
|
|
|
@ -150,6 +150,7 @@ STATIC const mp_map_elem_t picographics_globals_table[] = {
|
|||
{ MP_ROM_QSTR(MP_QSTR_DISPLAY_INTERSTATE75_128X64), MP_ROM_INT(DISPLAY_INTERSTATE75_128X64) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_DISPLAY_INTERSTATE75_192X64), MP_ROM_INT(DISPLAY_INTERSTATE75_192X64) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_DISPLAY_INTERSTATE75_256X64), MP_ROM_INT(DISPLAY_INTERSTATE75_256X64) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_DISPLAY_INKY_FRAME_7), MP_ROM_INT(DISPLAY_INKY_FRAME_7) },
|
||||
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_PEN_1BIT), MP_ROM_INT(PEN_1BIT) },
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "drivers/uc8151/uc8151.hpp"
|
||||
#include "drivers/uc8159/uc8159.hpp"
|
||||
#include "drivers/st7567/st7567.hpp"
|
||||
#include "drivers/inky73/inky73.hpp"
|
||||
#include "drivers/psram_display/psram_display.hpp"
|
||||
#include "libraries/pico_graphics/pico_graphics.hpp"
|
||||
#include "common/pimoroni_common.hpp"
|
||||
#include "common/pimoroni_bus.hpp"
|
||||
|
@ -192,6 +194,14 @@ 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_INKY_FRAME_7:
|
||||
width = 800;
|
||||
height = 480;
|
||||
bus_type = BUS_SPI;
|
||||
// Portrait to match labelling
|
||||
if(rotate == -1) rotate = (int)Rotation::ROTATE_0;
|
||||
if(pen_type == -1) pen_type = PEN_INKY7;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -214,6 +224,8 @@ size_t get_required_buffer_size(PicoGraphicsPenType pen_type, uint width, uint h
|
|||
return PicoGraphics_PenRGB565::buffer_size(width, height);
|
||||
case PEN_RGB888:
|
||||
return PicoGraphics_PenRGB888::buffer_size(width, height);
|
||||
case PEN_INKY7:
|
||||
return PicoGraphics_PenInky7::buffer_size(width, height);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -276,7 +288,7 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||
self->i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(PimoroniI2C_make_new(&PimoroniI2C_type, 0, 0, nullptr));
|
||||
i2c_bus = (pimoroni::I2C *)(self->i2c->i2c);
|
||||
} else if (bus_type == BUS_SPI) {
|
||||
if(display == DISPLAY_INKY_FRAME || display == DISPLAY_INKY_FRAME_4) {
|
||||
if(display == DISPLAY_INKY_FRAME || display == DISPLAY_INKY_FRAME_4 || display == DISPLAY_INKY_FRAME_7) {
|
||||
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};
|
||||
|
@ -292,6 +304,11 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||
// TODO grab BUSY and RESET from ARG_extra_pins
|
||||
self->display = m_new_class(UC8159, width, height, (Rotation)rotate, spi_bus);
|
||||
|
||||
} else if (display == DISPLAY_INKY_FRAME_7) {
|
||||
pen_type = PEN_INKY7;
|
||||
// TODO grab BUSY and RESET from ARG_extra_pins
|
||||
self->display = m_new_class(Inky73, width, height, (Rotation)rotate, spi_bus);
|
||||
|
||||
} else if (display == DISPLAY_TUFTY_2040) {
|
||||
self->display = m_new_class(ST7789, width, height, (Rotation)rotate, parallel_bus);
|
||||
|
||||
|
@ -324,6 +341,9 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||
size_t required_size = get_required_buffer_size((PicoGraphicsPenType)pen_type, width, height);
|
||||
if(required_size == 0) mp_raise_ValueError("Unsupported pen type!");
|
||||
|
||||
if(pen_type == PEN_INKY7) {
|
||||
self->buffer = m_new_class(PSRamDisplay, width, height);
|
||||
} else {
|
||||
if (args[ARG_buffer].u_obj != mp_const_none) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_RW);
|
||||
|
@ -334,6 +354,7 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||
} else {
|
||||
self->buffer = m_new(uint8_t, required_size);
|
||||
}
|
||||
}
|
||||
|
||||
// Create an instance of the graphics library
|
||||
// use the *driver* width/height because they may have been swapped due to rotation
|
||||
|
@ -363,6 +384,9 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||
case PEN_RGB888:
|
||||
self->graphics = m_new_class(PicoGraphics_PenRGB888, self->display->width, self->display->height, self->buffer);
|
||||
break;
|
||||
case PEN_INKY7:
|
||||
self->graphics = m_new_class(PicoGraphics_PenInky7, self->display->width, self->display->height, *(IDirectDisplayDriver<uint8_t> *)self->buffer);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -376,7 +400,7 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||
self->graphics->clear();
|
||||
|
||||
// Update the LCD from the graphics library
|
||||
if (display != DISPLAY_INKY_FRAME && display != DISPLAY_INKY_FRAME_4 && display != DISPLAY_INKY_PACK) {
|
||||
if (display != DISPLAY_INKY_FRAME && display != DISPLAY_INKY_FRAME_4 && display != DISPLAY_INKY_PACK && display != DISPLAY_INKY_FRAME_7) {
|
||||
self->display->update(self->graphics);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ enum PicoGraphicsDisplay {
|
|||
DISPLAY_INTERSTATE75_128X64,
|
||||
DISPLAY_INTERSTATE75_192X64,
|
||||
DISPLAY_INTERSTATE75_256X64,
|
||||
DISPLAY_INKY_FRAME_7,
|
||||
};
|
||||
|
||||
enum PicoGraphicsPenType {
|
||||
|
@ -34,7 +35,8 @@ enum PicoGraphicsPenType {
|
|||
PEN_P8,
|
||||
PEN_RGB332,
|
||||
PEN_RGB565,
|
||||
PEN_RGB888
|
||||
PEN_RGB888,
|
||||
PEN_INKY7,
|
||||
};
|
||||
|
||||
enum PicoGraphicsBusType {
|
||||
|
|
|
@ -14,6 +14,9 @@ LED_C = 13
|
|||
LED_D = 14
|
||||
LED_E = 15
|
||||
|
||||
LED_BUSY = 6
|
||||
LED_WIFI = 7
|
||||
|
||||
SHIFT_STATE = get_shift_state()
|
||||
|
||||
reset_shift_state()
|
||||
|
@ -66,3 +69,6 @@ button_b = Button(sr, 6, LED_B)
|
|||
button_c = Button(sr, 5, LED_C)
|
||||
button_d = Button(sr, 4, LED_D)
|
||||
button_e = Button(sr, 3, LED_E)
|
||||
|
||||
led_busy = Pin(LED_BUSY, Pin.OUT)
|
||||
led_wifi = Pin(LED_WIFI, Pin.OUT)
|
||||
|
|
Loading…
Reference in New Issue