switched to pio refresh time: 250ms -> 25ms

This commit is contained in:
matthias wagner
2023-05-13 16:08:15 +02:00
parent af5a1611d5
commit 87ddaa6383
28 changed files with 12151 additions and 11425 deletions

View File

@@ -6,7 +6,8 @@
// lcd configuration
const struct tft_config lcd_config = {
.spi = PICO_DEFAULT_SPI_INSTANCE,
.pio = pio0,
.sm = 0,
.gpio_din = PICO_DEFAULT_SPI_TX_PIN,
.gpio_clk = PICO_DEFAULT_SPI_SCK_PIN,
.gpio_cs = PICO_DEFAULT_SPI_CSN_PIN,
@@ -21,19 +22,18 @@ int main()
{
stdio_init_all();
// gpio_init(DLED_PIN);
// gpio_set_dir(DLED_PIN, GPIO_OUT);
set_sys_clock_khz(200 * 1000, true);
uint offset = pio_add_program(lcd_config.pio, &tft_program);
tft_program_init(lcd_config.pio, lcd_config.sm, offset, lcd_config.gpio_din, lcd_config.gpio_clk, 1.f);
tft_init(&lcd_config);
while (true) {
// gpio_put(DLED_PIN, 0);
// sleep_ms(250);
// gpio_put(DLED_PIN, 1);
// sleep_ms(1000);
absolute_time_t start = get_absolute_time();
tft_fill(0b0000000000000000);
tft_fill(0b1111111111111111);
tft_fill(0b0000000000000000);
absolute_time_t end = get_absolute_time();
volatile int64_t diff = absolute_time_diff_us(start, end);
printf("test");

207
src/tft.c
View File

@@ -3,171 +3,64 @@
static struct tft_config tft_cfg;
static bool tft_data_mode = false;
void tft_cmd(uint8_t cmd, const uint8_t* data, size_t len)
{
spi_set_format(tft_cfg.spi, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
tft_data_mode = false;
gpio_put(tft_cfg.gpio_cs, 0);
gpio_put(tft_cfg.gpio_dc, 0);
spi_write_blocking(tft_cfg.spi, &cmd, sizeof(cmd));
if (len) {
gpio_put(tft_cfg.gpio_dc, 1);
spi_write_blocking(tft_cfg.spi, data, len);
}
gpio_put(tft_cfg.gpio_cs, 1);
gpio_put(tft_cfg.gpio_dc, 1);
}
void tft_caset(uint16_t xs, uint16_t xe)
{
uint8_t data[] = {
xs >> 8,
xs & 0xff,
xe >> 8,
xe & 0xff,
};
// CASET (2Ah): Column Address Set
tft_cmd(0x2a, data, sizeof(data));
void tft_set_dc_cs(bool dc, bool cs) {
sleep_us(1);
gpio_put_masked((1u << tft_cfg.gpio_dc) | (1u << tft_cfg.gpio_cs), !!dc << tft_cfg.gpio_dc | !!cs << tft_cfg.gpio_cs);
sleep_us(1);
}
void tft_raset(uint16_t ys, uint16_t ye)
{
uint8_t data[] = {
ys >> 8,
ys & 0xff,
ye >> 8,
ye & 0xff,
};
// RASET (2Bh): Row Address Set
tft_cmd(0x2b, data, sizeof(data));
void tft_write_cmd(PIO pio, uint sm, const uint8_t *cmd, size_t count) {
tft_wait_idle(pio, sm);
tft_set_dc_cs(0, 0);
tft_put(pio, sm, *cmd++);
if (count >= 2) {
tft_wait_idle(pio, sm);
tft_set_dc_cs(1, 0);
for (size_t i = 0; i < count - 1; ++i)
tft_put(pio, sm, *cmd++);
}
tft_wait_idle(pio, sm);
tft_set_dc_cs(1, 1);
}
void tft_init(const struct tft_config* config)
{
void lcd_init(PIO pio, uint sm, const uint8_t *init_seq) {
const uint8_t *cmd = init_seq;
while (*cmd) {
tft_write_cmd(pio, sm, cmd + 2, *cmd);
//sleep_ms(*(cmd + 1) * 5);
sleep_ms(200);
cmd += *cmd + 2;
}
}
void tft_start_pixels(PIO pio, uint sm) {
uint8_t cmd = 0x2c; // RAMWR
tft_write_cmd(pio, sm, &cmd, 1);
tft_set_dc_cs(1, 0);
}
void tft_init(const struct tft_config* config) {
memcpy(&tft_cfg, config, sizeof(tft_cfg));
set_sys_clock_khz(250 * 1000, true);
gpio_init(tft_cfg.gpio_cs);
gpio_init(tft_cfg.gpio_dc);
gpio_init(tft_cfg.gpio_rst);
gpio_init(tft_cfg.gpio_bl);
gpio_set_dir(tft_cfg.gpio_cs, GPIO_OUT);
gpio_set_dir(tft_cfg.gpio_dc, GPIO_OUT);
gpio_set_dir(tft_cfg.gpio_rst, GPIO_OUT);
gpio_set_dir(tft_cfg.gpio_bl, GPIO_OUT);
volatile uint ach = spi_init(tft_cfg.spi, 67 * 1000 * 1000); // original 125 * 1000 * 1000
spi_set_format(tft_cfg.spi, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
gpio_set_function(tft_cfg.gpio_din, GPIO_FUNC_SPI);
gpio_set_function(tft_cfg.gpio_clk, GPIO_FUNC_SPI);
gpio_init(tft_cfg.gpio_cs);
gpio_init(tft_cfg.gpio_dc);
gpio_init(tft_cfg.gpio_rst);
gpio_init(tft_cfg.gpio_bl);
gpio_set_dir(tft_cfg.gpio_cs, GPIO_OUT);
gpio_set_dir(tft_cfg.gpio_dc, GPIO_OUT);
gpio_set_dir(tft_cfg.gpio_rst, GPIO_OUT);
gpio_set_dir(tft_cfg.gpio_bl, GPIO_OUT);
gpio_put(tft_cfg.gpio_cs, 1);
gpio_put(tft_cfg.gpio_dc, 1);
gpio_put(tft_cfg.gpio_rst, 1);
sleep_ms(100);
// SWRESET (01h): Software Reset
tft_cmd(0x01, NULL, 0);
sleep_ms(150);
// SLPOUT (11h): Sleep Out
tft_cmd(0x11, NULL, 0);
sleep_ms(50);
// COLMOD (3Ah): Interface Pixel Format
// - RGB interface color format = 65K of RGB interface
// - Control interface color format = 16bit/pixel
tft_cmd(0x3a, (uint8_t[]) { 0x55 }, 1);
sleep_ms(10);
// MADCTL (36h): Memory Data Access Control
// - Page Address Order = Top to Bottom
// - Column Address Order = Left to Right
// - Page/Column Order = Normal Mode
// - Line Address Order = LCD Refresh Top to Bottom
// - RGB/BGR Order = RGB
// - Display Data Latch Data Order = LCD Refresh Left to Right
tft_cmd(0x36, (uint8_t[]) { 0x00 }, 1);
tft_caset(0, tft_cfg.width);
tft_raset(0, tft_cfg.height);
// INVON (21h): Display Inversion On
// tft_cmd(0x21, NULL, 0);
// sleep_ms(10);
// NORON (13h): Normal Display Mode On
tft_cmd(0x13, NULL, 0);
sleep_ms(10);
// DISPON (29h): Display On
tft_cmd(0x29, NULL, 0);
sleep_ms(10);
gpio_put(tft_cfg.gpio_bl, 1);
gpio_put(tft_cfg.gpio_cs, 1);
gpio_put(tft_cfg.gpio_rst, 1);
lcd_init(tft_cfg.pio, tft_cfg.sm, st7789_init_seq);
gpio_put(tft_cfg.gpio_bl, 1);
}
void tft_ramwr()
{
gpio_put(tft_cfg.gpio_cs, 0);
gpio_put(tft_cfg.gpio_dc, 0);
// RAMWR (2Ch): Memory Write
uint8_t cmd = 0x2c;
spi_write_blocking(tft_cfg.spi, &cmd, sizeof(cmd));
gpio_put(tft_cfg.gpio_cs, 0);
gpio_put(tft_cfg.gpio_dc, 1);
}
void tft_write(const void* data, size_t len)
{
spi_write16_blocking(tft_cfg.spi, data, len / 2);
}
void tft_put(uint16_t pixel)
{
tft_write(&pixel, sizeof(pixel));
}
void tft_fill(uint16_t pixel)
{
void tft_fill(uint16_t color) {
tft_start_pixels(tft_cfg.pio, tft_cfg.sm);
int num_pixels = tft_cfg.width * tft_cfg.height;
tft_set_cursor(0, 0);
if (!tft_data_mode) {
tft_ramwr();
spi_set_format(tft_cfg.spi, 16, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
tft_data_mode = true;
}
printf("test");
for (int i = 0; i < num_pixels; i++) {
tft_put(pixel);
tft_put(tft_cfg.pio, tft_cfg.sm, color >> 8);
tft_put(tft_cfg.pio, tft_cfg.sm, color & 0xff);
}
printf("test");
}
void tft_set_cursor(uint16_t x, uint16_t y)
{
tft_caset(x, tft_cfg.width);
tft_raset(y, tft_cfg.height);
}
void tft_vertical_scroll(uint16_t row)
{
uint8_t data[] = {
(row >> 8) & 0xff,
row & 0x00ff
};
// VSCSAD (37h): Vertical Scroll Start Address of RAM
tft_cmd(0x37, data, sizeof(data));
}

View File

@@ -4,11 +4,14 @@
#include "hardware/gpio.h"
#include "hardware/spi.h"
#include "hardware/divider.h"
#include "tft.pio.h"
#include "pico/stdlib.h"
#include <string.h>
#include <stdio.h>
struct tft_config {
spi_inst_t* spi;
PIO pio;
uint sm;
uint gpio_din;
uint gpio_clk;
int gpio_cs;
@@ -19,15 +22,25 @@ struct tft_config {
uint16_t height;
};
void tft_cmd(uint8_t cmd, const uint8_t* data, size_t len);
void tft_caset(uint16_t xs, uint16_t xe);
void tft_raset(uint16_t ys, uint16_t ye);
void tft_init(const struct tft_config* config);
void tft_ramwr();
void tft_write(const void* data, size_t len);
void tft_put(uint16_t pixel);
void tft_fill(uint16_t pixel);
void tft_set_cursor(uint16_t x, uint16_t y);
void tft_vertical_scroll(uint16_t row);
// Note the delays have been shortened a little
static const uint8_t st7789_init_seq[] = {
1, 20, 0x01, // Software reset
1, 10, 0x11, // Exit sleep mode
2, 2, 0x3a, 0x55, // Set colour mode to 16 bit
2, 0, 0x36, 0x00, // Set MADCTL: row then column, refresh is bottom to top ????
5, 0, 0x2a, 0x00, 0x00, 320 >> 8, 320 & 0xff, // CASET: column addresses
5, 0, 0x2b, 0x00, 0x00, 480 >> 8, 480 & 0xff, // RASET: row addresses
1, 2, 0x13, // Normal display on, then 10 ms delay
1, 2, 0x29, // Main screen turn on, then wait 500 ms
0 // Terminate list
};
void tft_set_dc_cs(bool dc, bool cs);
void tft_write_cmd(PIO pio, uint sm, const uint8_t *cmd, size_t count);
void lcd_init(PIO pio, uint sm, const uint8_t *init_seq);
void tft_start_pixels(PIO pio, uint sm);
void tft_init(const struct tft_config* config);
void tft_fill(uint16_t color);
#endif // TFT_H

View File

@@ -27,7 +27,7 @@ static inline void tft_program_init(PIO pio, uint sm, uint offset, uint data_pin
pio_gpio_init(pio, clk_pin);
pio_sm_set_consecutive_pindirs(pio, sm, data_pin, 1, true);
pio_sm_set_consecutive_pindirs(pio, sm, clk_pin, 1, true);
pio_sm_config c = st7789_lcd_program_get_default_config(offset);
pio_sm_config c = tft_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, clk_pin);
sm_config_set_out_pins(&c, data_pin, 1);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);