kopia lustrzana https://github.com/pimoroni/pimoroni-pico
Inky 7.3: Direct pen & PSRAM update.
rodzic
b810ffdfdb
commit
0067b101a0
|
@ -39,4 +39,6 @@ add_subdirectory(vl53l5cx)
|
|||
add_subdirectory(pcf85063a)
|
||||
add_subdirectory(pms5003)
|
||||
add_subdirectory(sh1107)
|
||||
add_subdirectory(st7567)
|
||||
add_subdirectory(st7567)
|
||||
add_subdirectory(psram_display)
|
||||
add_subdirectory(uc8159_inky7)
|
|
@ -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(uc8159_inky7.cmake)
|
|
@ -0,0 +1,10 @@
|
|||
set(DRIVER_NAME uc8159_inky7)
|
||||
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,206 @@
|
|||
#include "uc8159_inky7.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 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);
|
||||
}
|
||||
|
||||
void UC8159Inky7::busy_wait(uint minimum_wait_ms) {
|
||||
timeout = make_timeout_time_ms(minimum_wait_ms);
|
||||
while(is_busy()) {
|
||||
tight_loop_contents();
|
||||
}
|
||||
}
|
||||
|
||||
void UC8159Inky7::reset() {
|
||||
gpio_put(RESET, 0); sleep_ms(10);
|
||||
gpio_put(RESET, 1); sleep_ms(10);
|
||||
busy_wait();
|
||||
}
|
||||
|
||||
void UC8159Inky7::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(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);
|
||||
};
|
||||
|
||||
void UC8159Inky7::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 UC8159Inky7::set_blocking(bool blocking) {
|
||||
this->blocking = blocking;
|
||||
}
|
||||
|
||||
void UC8159Inky7::power_off() {
|
||||
busy_wait();
|
||||
command(POF); // turn off
|
||||
}
|
||||
|
||||
void UC8159Inky7::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 UC8159Inky7::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 UC8159Inky7::command(uint8_t reg, std::initializer_list<uint8_t> values) {
|
||||
command(reg, values.size(), (uint8_t *)values.begin());
|
||||
}
|
||||
|
||||
void UC8159Inky7::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(200);
|
||||
|
||||
command(DRF, {0}); // start display refresh
|
||||
busy_wait(200);
|
||||
|
||||
if(blocking) {
|
||||
busy_wait(32 * 1000);
|
||||
|
||||
command(POF); // turn off
|
||||
} else {
|
||||
timeout = make_timeout_time_ms(32 * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
#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"
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
class UC8159Inky7 : 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 BUSY = PIN_UNUSED;
|
||||
uint RESET = 27; //25;
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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, Rotation rotation, SPIPins pins, uint busy=PIN_UNUSED, 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) {
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Methods
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
void busy_wait(uint minimum_wait_ms=0);
|
||||
void reset();
|
||||
void power_off();
|
||||
|
||||
bool is_busy() override;
|
||||
void update(PicoGraphics *graphics) override;
|
||||
|
||||
void set_blocking(bool blocking);
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
include(inky_frame_jpeg_image.cmake)
|
||||
include(inky_frame_sleepy_head.cmake)
|
||||
include(inky_frame_day_planner.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 uc8159_inky7 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,39 @@
|
|||
#include <cstdio>
|
||||
#include <math.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include "drivers/psram_display/psram_display.hpp"
|
||||
#include "drivers/uc8159_inky7/uc8159_inky7.hpp"
|
||||
|
||||
using namespace pimoroni;
|
||||
|
||||
int main() {
|
||||
stdio_init_all();
|
||||
|
||||
PSRamDisplay ramDisplay(800, 480);
|
||||
PicoGraphics_PenInky7 graphics(800, 480, ramDisplay);
|
||||
UC8159Inky7 uc8159(800,400);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
uc8159.update(&graphics);
|
||||
|
||||
while(true)
|
||||
sleep_ms(1000);
|
||||
|
||||
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,32 @@ 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:
|
||||
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 frame_convert(PenType type, conversion_callback_func callback) override;
|
||||
static size_t buffer_size(uint w, uint h) {
|
||||
return w * h;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
#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::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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Ładowanie…
Reference in New Issue