kopia lustrzana https://github.com/pimoroni/pimoroni-pico
ST7701: Experimental driver stub.
rodzic
616b1cc8d6
commit
0eb59c4232
|
@ -6,6 +6,7 @@ add_subdirectory(ltp305)
|
|||
add_subdirectory(ltr559)
|
||||
add_subdirectory(pmw3901)
|
||||
add_subdirectory(sgp30)
|
||||
add_subdirectory(st7701)
|
||||
add_subdirectory(st7735)
|
||||
add_subdirectory(st7789)
|
||||
add_subdirectory(msa301)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
include(${CMAKE_CURRENT_LIST_DIR}/st7701.cmake)
|
|
@ -0,0 +1,56 @@
|
|||
# ST7701 Display Driver for Pimoroni LCDs <!-- omit in toc -->
|
||||
|
||||
The ST7701 driver supports both Parallel and Serial (SPI) ST7701 displays and is intended for use with:
|
||||
|
||||
* Redacted
|
||||
* Wouldn't you like to know
|
||||
* Super Sekret
|
||||
|
||||
## Setup
|
||||
|
||||
Construct an instance of the ST7701 driver with either Parallel or SPI pins.
|
||||
|
||||
Parallel:
|
||||
|
||||
```c++
|
||||
ST7701 st7701(WIDTH, HEIGHT, ROTATE_0, {
|
||||
Tufty2040::LCD_CS, // Chip-Select
|
||||
Tufty2040::LCD_DC, // Data-Command
|
||||
Tufty2040::LCD_WR, // Write
|
||||
Tufty2040::LCD_RD, // Read
|
||||
Tufty2040::LCD_D0, // Data 0 (start of a bank of 8 pins)
|
||||
Tufty2040::BACKLIGHT // Backlight
|
||||
});
|
||||
```
|
||||
|
||||
SPI:
|
||||
|
||||
```c++
|
||||
ST7701 st7701(WIDTH, HEIGHT, ROTATE_0, false, {
|
||||
PIMORONI_SPI_DEFAULT_INSTANCE, // SPI instance
|
||||
SPI_BG_FRONT_CS, // Chip-select
|
||||
SPI_DEFAULT_SCK, // SPI Clock
|
||||
SPI_DEFAULT_MOSI, // SPI Out
|
||||
PIN_UNUSED, // SPI In
|
||||
SPI_DEFAULT_DC, // SPI Data/Command
|
||||
PIN_UNUSED // Backlight
|
||||
});
|
||||
```
|
||||
|
||||
## Reference
|
||||
|
||||
### Update
|
||||
|
||||
ST7701's `update` accepts an instance of `PicoGraphics` in any colour mode:
|
||||
|
||||
```c++
|
||||
st7701.update(&graphics);
|
||||
```
|
||||
|
||||
### Set Backlight
|
||||
|
||||
If a backlight pin has been configured, you can set the backlight from 0 to 255:
|
||||
|
||||
```c++
|
||||
st7701.set_backlight(128)
|
||||
```
|
|
@ -0,0 +1,14 @@
|
|||
set(DRIVER_NAME st7701)
|
||||
add_library(${DRIVER_NAME} INTERFACE)
|
||||
|
||||
target_sources(${DRIVER_NAME} INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/${DRIVER_NAME}.cpp)
|
||||
|
||||
pico_generate_pio_header(${DRIVER_NAME} ${CMAKE_CURRENT_LIST_DIR}/st7701_parallel.pio)
|
||||
|
||||
target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
target_include_directories(st7701 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_pio hardware_dma pico_graphics)
|
|
@ -0,0 +1,246 @@
|
|||
#include "st7701.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <math.h>
|
||||
|
||||
namespace pimoroni {
|
||||
uint8_t madctl;
|
||||
|
||||
enum dcx {
|
||||
CMD = 0x00,
|
||||
DATA = 0x01
|
||||
};
|
||||
|
||||
enum reg {
|
||||
SWRESET = 0x01, // Software Reset
|
||||
SLPOUT = 0x11, // Sleep Out
|
||||
PTLON = 0x12, // Partial Display Mode On
|
||||
NORON = 0x13, // Normal Display Mode On
|
||||
INVOFF = 0x20, // Display Inversion Off
|
||||
INVON = 0x21, // Display Inversion On
|
||||
ALLPOFF = 0x22, // All Pixels Off
|
||||
ALLPON = 0x23, // All Pixels On
|
||||
GAMSET = 0x26, // Gamma Set
|
||||
DISPOFF = 0x28, // Display Off
|
||||
DISPON = 0x29, // Display On
|
||||
TEOFF = 0x34, // Tearing Effect Line Off (kinda vsync)
|
||||
TEON = 0x35, // Tearing Effect Line On (kinda vsync)
|
||||
MADCTL = 0x36, // Display data access control
|
||||
IDMOFF = 0x38, // Idle Mode Off
|
||||
IDMON = 0x39, // Idle Mode On
|
||||
COLMOD = 0x3A, // Interface Pixel Format
|
||||
GSL = 0x45, // Get Scan Line
|
||||
// Command2_BK0
|
||||
PVGAMCTRL = 0xB0, // Positive Voltage Gamma Control
|
||||
NVGAMCTRL = 0xB1, // Negative Voltage Gamma Control
|
||||
DGMEN = 0xB8, // Digital Gamma Enable
|
||||
DGMLUTR = 0xB9, // Digital Gamma LUT for Red
|
||||
DGMLUTB = 0xBA, // Digital Gamma Lut for Blue
|
||||
LNESET = 0xC0, // Display Line Setting
|
||||
PORCTRL = 0xC1, // Porch Control
|
||||
INVSET = 0xC2, // Inversion Selection & Frame Rate Control
|
||||
RGBCTRL = 0xC3, // RGB Control
|
||||
PARCTRL = 0xC5, // Partial Mode Control
|
||||
SDIR = 0xC7, // X-direction Control
|
||||
PDOSET = 0xC8, // Pseudo-Dot Inversion Diving Settign
|
||||
COLCTRL = 0xCD, // Colour Control
|
||||
SRECTRL = 0xE0, // Sunlight Readable Enhancement
|
||||
NRCTRL = 0xE1, // Noise Reduce Control
|
||||
SECTRL = 0xE2, // Sharpness Control
|
||||
CCCTRL = 0xE3, // Color Calibration Control
|
||||
SKCTRL = 0xE4, // Skin Tone Preservation Control
|
||||
// Command2_BK1
|
||||
VHRS = 0xB0, // Vop amplitude
|
||||
VCOMS = 0xB1, // VCOM amplitude
|
||||
VGHSS = 0xB2, // VGH voltage
|
||||
TESTCMD = 0xB3, // TEST command
|
||||
VGLS = 0xB5, // VGL voltage
|
||||
VRHDV = 0xB6, // VRH_DV voltage
|
||||
PWCTRL1 = 0xB7, // Power Control 1
|
||||
PWCTRL2 = 0xB8, // Power Control 2
|
||||
PCLKS1 = 0xBA, // Power pumping clock selection 1
|
||||
PCLKS2 = 0xBC, // Power pumping clock selection 2
|
||||
PDR1 = 0xC1, // Source pre_drive timing set 1
|
||||
PDR2 = 0xC2, // Source pre_drive timing set 2
|
||||
// Command2_BK3
|
||||
NVMEN = 0xC8, // NVM enable
|
||||
NVMSET = 0xCA, // NVM manual control
|
||||
PROMACT = 0xCC, // NVM program active
|
||||
// Other
|
||||
CND2BKxSEL = 0xFF,
|
||||
};
|
||||
|
||||
void ST7701::common_init() {
|
||||
// if a backlight pin is provided then set it up for
|
||||
// pwm control
|
||||
if(lcd_bl != PIN_UNUSED) {
|
||||
pwm_config cfg = pwm_get_default_config();
|
||||
pwm_set_wrap(pwm_gpio_to_slice_num(lcd_bl), 65535);
|
||||
pwm_init(pwm_gpio_to_slice_num(lcd_bl), &cfg, true);
|
||||
gpio_set_function(lcd_bl, GPIO_FUNC_PWM);
|
||||
set_backlight(0); // Turn backlight off initially to avoid nasty surprises
|
||||
}
|
||||
|
||||
command(reg::SWRESET);
|
||||
|
||||
sleep_ms(150);
|
||||
|
||||
// Commmand 2 BK0 - kinda a page select
|
||||
command(reg::CND2BKxSEL, 5, "\x77\x01\x00\x00\x10");
|
||||
|
||||
if(width == 480 && height == 480) {
|
||||
// TODO: Figure out what's actually display specific
|
||||
command(reg::MADCTL, 1, "\x00"); // Normal scan direction and RGB pixels
|
||||
command(reg::LNESET, 2, "\x3b\x00"); // (59 + 1) * 8 = 480 lines
|
||||
command(reg::PORCTRL, 2, "\x0d\x02"); // 13 VBP, 2 VFP
|
||||
command(reg::INVSET, 2, "\x32\x05");
|
||||
command(reg::COLCTRL, 1, "\x08"); // LED polarity reversed
|
||||
command(reg::PVGAMCTRL, 16, "\x00\x11\x18\x0e\x11\x06\x07\x08\x07\x22\x04\x12\x0f\xaa\x31\x18");
|
||||
command(reg::NVGAMCTRL, 16, "\x00\x11\x19\x0e\x12\x07\x08\x08\x08\x22\x04\x11\x11\xa9\x32\x18");
|
||||
}
|
||||
|
||||
// Command 2 BK1 - Voltages and power and stuff
|
||||
command(reg::CND2BKxSEL, 5, "\x77\x01\x00\x00\x11");
|
||||
command(reg::VHRS, 1, "\x60"); // 4.7375v
|
||||
command(reg::VCOMS, 1, "\x32"); // 0.725v
|
||||
command(reg::VGHSS, 1, "\x07"); // 15v
|
||||
command(reg::TESTCMD, 1, "\x80"); // y tho?
|
||||
command(reg::VGLS, 1, "\x49"); // -10.17v
|
||||
command(reg::PWCTRL1, 1, "\x85"); // Middle/Min/Min bias
|
||||
command(reg::PWCTRL2, 1, "\x21"); // 6.6 / -4.6
|
||||
command(reg::PDR1, 1, "\x78"); // 1.6uS
|
||||
command(reg::PDR2, 1, "\x78"); // 6.4uS
|
||||
|
||||
// Begin Forbidden Knowledge
|
||||
// This sequence is probably specific to TL040WVS03CT15-H1263A.
|
||||
// It is not documented in the ST7701s datasheet.
|
||||
// TODO: 👇 W H A T ! ? 👇
|
||||
command(0xE0, 3, "\x00\x1b\x02");
|
||||
command(0xE1, 11, "\x08\xa0\x00\x00\x07\xa0\x00\x00\x00\x44\x44");
|
||||
command(0xE2, 12, "\x11\x11\x44\x44\xed\xa0\x00\x00\xec\xa0\x00\x00");
|
||||
command(0xE3, 4, "\x00\x00\x11\x11");
|
||||
command(0xE4, 2, "\x44\x44");
|
||||
command(0xE5, 16, "\x0a\xe9\xd8\xa0\x0c\xeb\xd8\xa0\x0e\xed\xd8\xa0\x10\xef\xd8\xa0");
|
||||
command(0xE7, 2, "\x44\x44");
|
||||
command(0xE8, 16, "\x09\xe8\xd8\xa0\x0b\xea\xd8\xa0\x0d\xec\xd8\xa0\x0f\xee\xd8\xa0");
|
||||
command(0xEC, 2, "\x3c\x00");
|
||||
command(0xED, 16, "\xab\x89\x76\x54\x02\xff\xff\xff\xff\xff\xff\x20\x45\x67\x98\xba");
|
||||
command(0x36, 1, "\x00");
|
||||
// End Forbidden Knowledge
|
||||
|
||||
// Command 2 BK3
|
||||
command(reg::CND2BKxSEL, 5, "\x77\x01\x00\x00\x13");
|
||||
//command(reg::COLMOD, 1, "\x77"); // 24 bits per pixel...
|
||||
command(reg::COLMOD, 1, "\x66"); // 18 bits per pixel...
|
||||
//command(reg::COLMOD, 1, "\x55"); // 16 bits per pixel...
|
||||
|
||||
command(reg::SLPOUT);
|
||||
sleep_ms(120);
|
||||
command(reg::DISPON);
|
||||
sleep_ms(50);
|
||||
|
||||
// TODO: Support rotation
|
||||
// configure_display(rotation);
|
||||
|
||||
if(lcd_bl != PIN_UNUSED) {
|
||||
//update(); // Send the new buffer to the display to clear any previous content
|
||||
sleep_ms(50); // Wait for the update to apply
|
||||
set_backlight(255); // Turn backlight on now surprises have passed
|
||||
}
|
||||
}
|
||||
|
||||
void ST7701::cleanup() {
|
||||
if(dma_channel_is_claimed(st_dma)) {
|
||||
dma_channel_abort(st_dma);
|
||||
dma_channel_unclaim(st_dma);
|
||||
}
|
||||
if(spi) return; // SPI mode needs no further tear down
|
||||
|
||||
if(pio_sm_is_claimed(parallel_pio, parallel_sm)) {
|
||||
pio_sm_set_enabled(parallel_pio, parallel_sm, false);
|
||||
pio_sm_drain_tx_fifo(parallel_pio, parallel_sm);
|
||||
pio_sm_unclaim(parallel_pio, parallel_sm);
|
||||
}
|
||||
}
|
||||
|
||||
void ST7701::configure_display(Rotation rotate) {
|
||||
|
||||
if(rotate == ROTATE_90 || rotate == ROTATE_270) {
|
||||
std::swap(width, height);
|
||||
}
|
||||
|
||||
// 480x480 Square Display
|
||||
if(width == 480 && height == 480) {
|
||||
madctl = 0;
|
||||
}
|
||||
|
||||
command(reg::MADCTL, 1, (char *)&madctl);
|
||||
}
|
||||
|
||||
void ST7701::write_blocking_dma(const uint8_t *src, size_t len) {
|
||||
while (dma_channel_is_busy(st_dma))
|
||||
;
|
||||
dma_channel_set_trans_count(st_dma, len, false);
|
||||
dma_channel_set_read_addr(st_dma, src, true);
|
||||
}
|
||||
|
||||
void ST7701::write_blocking_parallel(const uint8_t *src, size_t len) {
|
||||
write_blocking_dma(src, len);
|
||||
dma_channel_wait_for_finish_blocking(st_dma);
|
||||
|
||||
// This may cause a race between PIO and the
|
||||
// subsequent chipselect deassert for the last pixel
|
||||
while(!pio_sm_is_tx_fifo_empty(parallel_pio, parallel_sm))
|
||||
;
|
||||
}
|
||||
|
||||
void ST7701::command(uint8_t command, size_t len, const char *data) {
|
||||
static uint16_t _data[20] = {0};
|
||||
gpio_put(spi_cs, 0);
|
||||
|
||||
// Add leading byte for 9th D/CX bit
|
||||
uint8_t _command[2] = {dcx::CMD, command};
|
||||
spi_write_blocking(spi, (const uint8_t*)_command, 2);
|
||||
|
||||
if(data) {
|
||||
// Add leading bytes for 9th D/CX bits
|
||||
// TODO: OOOF - I *think* this is how 9bit SPI is supposed to work!?
|
||||
// We'd probably be better off with some dedicated PIO tomfoolery
|
||||
for(auto i = 0u; i < len; i++) {
|
||||
_data[i] = (dcx::DATA << 8) | data[i];
|
||||
}
|
||||
spi_write_blocking(spi, (const uint8_t*)_data, len);
|
||||
}
|
||||
|
||||
gpio_put(spi_cs, 1);
|
||||
}
|
||||
|
||||
void ST7701::update(PicoGraphics *graphics) {
|
||||
//uint8_t cmd = reg::RAMWR;
|
||||
|
||||
// TODO: Where's my buffer at? Where's my buffer at?
|
||||
// I left it out back in the PSRAM chip, y'all
|
||||
// And now I cannot find it even though it's 60k tall
|
||||
|
||||
if(graphics->pen_type == PicoGraphics::PEN_RGB565) { // Display buffer is screen native
|
||||
// command(cmd, width * height * sizeof(uint16_t), (const char*)graphics->frame_buffer);
|
||||
} else {
|
||||
/*graphics->frame_convert(PicoGraphics::PEN_RGB565, [this](void *data, size_t length) {
|
||||
if (length > 0) {
|
||||
write_blocking_dma((const uint8_t*)data, length);
|
||||
}
|
||||
else {
|
||||
dma_channel_wait_for_finish_blocking(st_dma);
|
||||
}
|
||||
});*/
|
||||
}
|
||||
}
|
||||
|
||||
void ST7701::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(lcd_bl, value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
#pragma once
|
||||
|
||||
#include "hardware/spi.h"
|
||||
#include "hardware/dma.h"
|
||||
#include "hardware/gpio.h"
|
||||
#include "hardware/pio.h"
|
||||
#include "hardware/pwm.h"
|
||||
#include "hardware/clocks.h"
|
||||
#include "common/pimoroni_common.hpp"
|
||||
#include "common/pimoroni_bus.hpp"
|
||||
#include "libraries/pico_graphics/pico_graphics.hpp"
|
||||
|
||||
|
||||
#ifndef NO_QSTR
|
||||
#include "st7701_parallel.pio.h"
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
class ST7701 : public DisplayDriver {
|
||||
spi_inst_t *spi = PIMORONI_SPI_DEFAULT_INSTANCE;
|
||||
|
||||
//--------------------------------------------------
|
||||
// Variables
|
||||
//--------------------------------------------------
|
||||
private:
|
||||
|
||||
// interface pins with our standard defaults where appropriate
|
||||
uint spi_cs;
|
||||
uint spi_sck;
|
||||
uint spi_dat;
|
||||
uint lcd_bl;
|
||||
uint parallel_sm;
|
||||
PIO parallel_pio;
|
||||
uint parallel_offset;
|
||||
uint st_dma;
|
||||
|
||||
uint d0 = 1; // First pin of 18-bit parallel interface
|
||||
uint hsync = 19;
|
||||
uint vsync = 20;
|
||||
uint lcd_de = 21;
|
||||
uint lcd_dot_clk = 22;
|
||||
|
||||
static const uint32_t SPI_BAUD = 8'000'000;
|
||||
|
||||
public:
|
||||
// Parallel init
|
||||
ST7701(uint16_t width, uint16_t height, Rotation rotation, SPIPins control_pins,
|
||||
uint d0=1, uint hsync=19, uint vsync=20, uint lcd_de = 21, uint lcd_dot_clk = 22) :
|
||||
DisplayDriver(width, height, rotation),
|
||||
spi(control_pins.spi),
|
||||
spi_cs(control_pins.cs), spi_sck(control_pins.sck), spi_dat(control_pins.mosi), lcd_bl(control_pins.bl),
|
||||
d0(d0), hsync(hsync), vsync(vsync), lcd_de(lcd_de), lcd_dot_clk(lcd_dot_clk) {
|
||||
|
||||
parallel_pio = pio1;
|
||||
parallel_sm = pio_claim_unused_sm(parallel_pio, true);
|
||||
parallel_offset = pio_add_program(parallel_pio, &st7701_parallel_program);
|
||||
|
||||
spi_init(spi, SPI_BAUD);
|
||||
gpio_set_function(spi_cs, GPIO_FUNC_SIO);
|
||||
gpio_set_dir(spi_cs, GPIO_OUT);
|
||||
gpio_set_function(spi_dat, GPIO_FUNC_SPI);
|
||||
gpio_set_function(spi_sck, GPIO_FUNC_SPI);
|
||||
|
||||
// ST7701 3-line Serial Interface
|
||||
// 9th bit = D/CX
|
||||
// low = command
|
||||
// high = data
|
||||
spi_set_format(spi, 9, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
|
||||
|
||||
//gpio_init(wr_sck);
|
||||
//gpio_set_dir(wr_sck, GPIO_OUT);
|
||||
//gpio_set_function(wr_sck, GPIO_FUNC_SIO);
|
||||
pio_gpio_init(parallel_pio, hsync);
|
||||
pio_gpio_init(parallel_pio, vsync);
|
||||
pio_gpio_init(parallel_pio, lcd_de);
|
||||
pio_gpio_init(parallel_pio, lcd_dot_clk);
|
||||
|
||||
for(auto i = 0u; i < 18; i++) {
|
||||
//gpio_set_function(d0 + i, GPIO_FUNC_SIO);
|
||||
//gpio_set_dir(d0 + i, GPIO_OUT);
|
||||
//gpio_init(d0 + 0); gpio_set_dir(d0 + i, GPIO_OUT);
|
||||
pio_gpio_init(parallel_pio, d0 + i);
|
||||
}
|
||||
|
||||
pio_sm_set_consecutive_pindirs(parallel_pio, parallel_sm, d0, 18, true);
|
||||
pio_sm_set_consecutive_pindirs(parallel_pio, parallel_sm, hsync, 4, true);
|
||||
|
||||
pio_sm_config c = st7701_parallel_program_get_default_config(parallel_offset);
|
||||
|
||||
sm_config_set_out_pins(&c, d0, 18);
|
||||
//sm_config_set_sideset_pins(&c, wr_sck);
|
||||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
|
||||
sm_config_set_out_shift(&c, false, true, 18);
|
||||
|
||||
// Determine clock divider
|
||||
constexpr uint32_t max_pio_clk = 32 * MHZ;
|
||||
const uint32_t sys_clk_hz = clock_get_hz(clk_sys);
|
||||
const uint32_t clk_div = (sys_clk_hz + max_pio_clk - 1) / max_pio_clk;
|
||||
sm_config_set_clkdiv(&c, clk_div);
|
||||
|
||||
pio_sm_init(parallel_pio, parallel_sm, parallel_offset, &c);
|
||||
pio_sm_set_enabled(parallel_pio, parallel_sm, true);
|
||||
|
||||
|
||||
st_dma = dma_claim_unused_channel(true);
|
||||
dma_channel_config config = dma_channel_get_default_config(st_dma);
|
||||
channel_config_set_transfer_data_size(&config, DMA_SIZE_8);
|
||||
channel_config_set_bswap(&config, false);
|
||||
channel_config_set_dreq(&config, pio_get_dreq(parallel_pio, parallel_sm, true));
|
||||
dma_channel_configure(st_dma, &config, ¶llel_pio->txf[parallel_sm], NULL, 0, false);
|
||||
|
||||
common_init();
|
||||
}
|
||||
|
||||
void cleanup() override;
|
||||
void update(PicoGraphics *graphics) override;
|
||||
void set_backlight(uint8_t brightness) override;
|
||||
|
||||
private:
|
||||
void common_init();
|
||||
void configure_display(Rotation rotate);
|
||||
void write_blocking_dma(const uint8_t *src, size_t len);
|
||||
void write_blocking_parallel(const uint8_t *src, size_t len);
|
||||
void command(uint8_t command, size_t len = 0, const char *data = NULL);
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
.program st7701_parallel
|
||||
.side_set 1
|
||||
|
||||
.wrap_target
|
||||
out pins, 18 side 0
|
||||
nop side 1
|
||||
.wrap
|
|
@ -62,3 +62,5 @@ add_subdirectory(galactic_unicorn)
|
|||
add_subdirectory(gfx_pack)
|
||||
add_subdirectory(cosmic_unicorn)
|
||||
add_subdirectory(stellar_unicorn)
|
||||
|
||||
add_subdirectory(st7701)
|
|
@ -0,0 +1 @@
|
|||
include(st7701_test.cmake)
|
|
@ -0,0 +1,14 @@
|
|||
set(OUTPUT_NAME st7701_test)
|
||||
add_executable(${OUTPUT_NAME} st7701_test.cpp)
|
||||
|
||||
target_link_libraries(${OUTPUT_NAME}
|
||||
hardware_spi
|
||||
pico_graphics
|
||||
st7701
|
||||
button
|
||||
)
|
||||
|
||||
# enable usb output
|
||||
pico_enable_stdio_usb(${OUTPUT_NAME} 1)
|
||||
|
||||
pico_add_extra_outputs(${OUTPUT_NAME})
|
|
@ -0,0 +1,116 @@
|
|||
#include "pico/stdlib.h"
|
||||
#include <stdio.h>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include "pico/time.h"
|
||||
#include "pico/platform.h"
|
||||
|
||||
#include "common/pimoroni_common.hpp"
|
||||
#include "drivers/st7701/st7701.hpp"
|
||||
#include "libraries/pico_graphics/pico_graphics.hpp"
|
||||
|
||||
using namespace pimoroni;
|
||||
|
||||
static const uint BACKLIGHT = 2;
|
||||
|
||||
static const int WIDTH = 480;
|
||||
static const int HEIGHT = 480;
|
||||
static const uint LCD_CLK = 29;
|
||||
static const uint LCD_CS = 28;
|
||||
static const uint LCD_DAT = 27;
|
||||
static const uint LCD_DC = PIN_UNUSED;
|
||||
static const uint LCD_D0 = 1;
|
||||
|
||||
ST7701 st7701(
|
||||
WIDTH,
|
||||
HEIGHT,
|
||||
ROTATE_0,
|
||||
SPIPins{
|
||||
spi0,
|
||||
LCD_CS,
|
||||
LCD_CLK,
|
||||
LCD_DAT,
|
||||
PIN_UNUSED, // MISO
|
||||
LCD_DC,
|
||||
BACKLIGHT
|
||||
},
|
||||
LCD_D0
|
||||
);
|
||||
|
||||
PicoGraphics_PenRGB332 graphics(st7701.width, st7701.height, nullptr);
|
||||
|
||||
uint32_t time() {
|
||||
absolute_time_t t = get_absolute_time();
|
||||
return to_ms_since_boot(t);
|
||||
}
|
||||
|
||||
int main() {
|
||||
st7701.set_backlight(255);
|
||||
|
||||
Pen WHITE = graphics.create_pen(255, 255, 255);
|
||||
Pen BG = graphics.create_pen(120, 40, 60);
|
||||
|
||||
struct pt {
|
||||
float x;
|
||||
float y;
|
||||
uint8_t r;
|
||||
float dx;
|
||||
float dy;
|
||||
uint16_t pen;
|
||||
};
|
||||
|
||||
std::vector<pt> 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);
|
||||
|
||||
while(true) {
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
graphics.set_pen(WHITE);
|
||||
graphics.text("Hello World", text_location, 320);
|
||||
|
||||
// update screen
|
||||
st7701.update(&graphics);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Ładowanie…
Reference in New Issue