1
0
mirror of https://github.com/whowechina/aic_pico.git synced 2024-11-24 14:00:09 +01:00

st7789 vram dma operations

This commit is contained in:
whowechina 2024-05-19 14:34:39 +08:00
parent e25a709cfb
commit 0bff5877ce
2 changed files with 70 additions and 19 deletions

View File

@ -6,6 +6,7 @@
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
@ -28,12 +29,17 @@ static struct {
uint8_t dc;
uint8_t rst;
uint8_t ledk;
int dma_tx;
dma_channel_config dma_cfg;
int spi_dma;
dma_channel_config spi_dma_cfg;
int mem_dma;
dma_channel_config mem_dma_cfg;
} ctx;
static struct {
uint16_t x;
uint16_t y;
uint16_t vx;
uint16_t vy;
uint16_t w;
uint16_t h;
} crop = { 0, 0, WIDTH, HEIGHT };
@ -92,10 +98,15 @@ static void init_pwm()
static void init_dma()
{
ctx.dma_tx = dma_claim_unused_channel(true);
ctx.dma_cfg = dma_channel_get_default_config(ctx.dma_tx);
channel_config_set_transfer_data_size(&ctx.dma_cfg, DMA_SIZE_16);
channel_config_set_dreq(&ctx.dma_cfg, spi_get_dreq(ctx.spi, true));
ctx.spi_dma = dma_claim_unused_channel(true);
ctx.spi_dma_cfg = dma_channel_get_default_config(ctx.spi_dma);
channel_config_set_transfer_data_size(&ctx.spi_dma_cfg, DMA_SIZE_16);
channel_config_set_dreq(&ctx.spi_dma_cfg, spi_get_dreq(ctx.spi, true));
ctx.mem_dma = dma_claim_unused_channel(true);
ctx.mem_dma_cfg = dma_channel_get_default_config(ctx.mem_dma);
channel_config_set_transfer_data_size(&ctx.mem_dma_cfg, DMA_SIZE_32);
channel_config_set_write_increment(&ctx.mem_dma_cfg, true);
}
void st7789_init(spi_inst_t *port, uint8_t dc, uint8_t rst, uint8_t ledk)
@ -114,12 +125,14 @@ void st7789_init(spi_inst_t *port, uint8_t dc, uint8_t rst, uint8_t ledk)
static void update_addr()
{
uint16_t xe = crop.x + crop.w - 1;
uint8_t ca[] = { crop.x >> 8, crop.x & 0xff, xe >> 8, xe & 0xff };
uint16_t xs = crop.x + crop.vx;
uint16_t xe = xs + crop.w - 1;
uint8_t ca[] = { xs >> 8, xs & 0xff, xe >> 8, xe & 0xff };
send_cmd(0x2a, ca, sizeof(ca));
uint16_t ye = crop.y + crop.h - 1;
uint8_t ra[] = { crop.y >> 8, crop.y & 0xff, ye >> 8, ye & 0xff };
uint16_t ys = crop.y + crop.vy;
uint16_t ye = ys + crop.h - 1;
uint8_t ra[] = { ys >> 8, ys & 0xff, ye >> 8, ye & 0xff };
send_cmd(0x2b, ra, sizeof(ra));
}
@ -145,10 +158,17 @@ void st7789_reset()
update_addr();
}
void st7789_crop(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
void st7789_crop(uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool absolute)
{
if (absolute) {
crop.x = x;
crop.y = y;
crop.vx = 0;
crop.vy = 0;
} else {
crop.vx = x;
crop.vy = y;
}
crop.w = w;
crop.h = h;
update_addr();
@ -161,15 +181,19 @@ void st7789_dimmer(uint8_t level)
void st7789_vsync()
{
dma_channel_wait_for_finish_blocking(ctx.dma_tx);
dma_channel_wait_for_finish_blocking(ctx.spi_dma);
}
void st7789_render(bool vsync)
{
if (dma_channel_is_busy(ctx.spi_dma)) {
return;
}
send_cmd(0x2c, NULL, 0);
spi_set_format(ctx.spi, 16, SPI_CPOL_1, SPI_CPHA_1, SPI_MSB_FIRST);
dma_channel_configure(ctx.dma_tx, &ctx.dma_cfg,
dma_channel_configure(ctx.spi_dma, &ctx.spi_dma_cfg,
&spi_get_hw(ctx.spi)->dr, // write to
vram, // read from
crop.w * crop.h, // element count
@ -179,14 +203,33 @@ void st7789_render(bool vsync)
}
}
uint16_t st7789_rgb32(uint8_t r, uint8_t g, uint8_t b)
{
return (r << 16) | (g << 8) | b;
}
uint16_t st7789_rgb565(uint32_t rgb32)
{
return ((rgb32 >> 8) & 0xf800) | ((rgb32 >> 5) & 0x07e0) | ((rgb32 >> 3) & 0x001f);
}
void st7789_clear()
static void vram_dma(uint16_t x, uint16_t y, const void *src, bool inc, size_t pixels)
{
memset(vram, 0, sizeof(vram));
channel_config_set_read_increment(&ctx.mem_dma_cfg, inc);
dma_channel_configure(ctx.mem_dma, &ctx.mem_dma_cfg,
&vram[y * crop.w + x], src, pixels / 2, true);
dma_channel_wait_for_finish_blocking(ctx.mem_dma);
}
void st7789_clear(uint16_t color)
{
uint32_t c32 = (color << 16) | color;
vram_dma(0, 0, &c32, false, crop.w * crop.h);
}
void st7789_vramcpy(uint16_t x, uint16_t y, const void *src, size_t pixels)
{
vram_dma(x, y, src, true, pixels);
}
void static inline put_pixel(uint16_t x, uint16_t y, uint16_t color)
@ -262,3 +305,8 @@ void st7789_line(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t co
}
}
}
uint16_t *st7789_vram(uint16_t x, uint16_t y)
{
return &vram[y * crop.w + x];
}

View File

@ -13,13 +13,16 @@
void st7789_reset();
void st7789_init_spi(spi_inst_t *port, uint8_t sck, uint8_t tx, uint8_t csn);
void st7789_init(spi_inst_t *port, uint8_t dc, uint8_t rst, uint8_t ledk);
void st7789_crop(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
void st7789_crop(uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool absolute);
void st7789_dimmer(uint8_t level);
void st7789_vsync();
void st7789_render(bool vsync);
uint16_t st7789_rgb32(uint8_t r, uint8_t g, uint8_t b);
uint16_t st7789_rgb565(uint32_t rgb32);
void st7789_clear();
void st7789_clear(uint16_t color);
uint16_t *st7789_vram(uint16_t x, uint16_t y);
void st7789_vramcpy(uint16_t x, uint16_t y, const void *src, size_t count);
void st7789_pixel(uint16_t x, uint16_t y, uint16_t color);
void st7789_hline(uint16_t x, uint16_t y, uint16_t w, uint16_t color);
void st7789_vline(uint16_t x, uint16_t y, uint16_t h, uint16_t color);