dma to pio outputting

This commit is contained in:
matthias wagner
2023-07-30 16:15:45 +02:00
parent 70b67e297b
commit c01e73aa75
7 changed files with 33 additions and 43 deletions

View File

@@ -15,40 +15,35 @@ const struct tft_config lcd_config = {
.gpio_rst = 20,
.gpio_bl = 16,
.width = 320,
.height = 480,
.height = 480
};
int main()
{
set_sys_clock_khz(200 * 1000, true);
set_sys_clock_khz(100 * 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_program_init(lcd_config.pio, lcd_config.sm, offset, lcd_config.gpio_din, lcd_config.gpio_clk, 10.f);
int dma_chan = dma_claim_unused_channel(true);
dma_channel_config c = dma_channel_get_default_config(dma_chan);
channel_config_set_transfer_data_size(&c, DMA_SIZE_32);
channel_config_set_read_increment(&c, true);
channel_config_set_dreq(&c, DREQ_PIO0_TX0);
dma_channel_configure(
dma_chan,
&c,
&pio0_hw->txf[lcd_config.sm],
&pio0->txf[lcd_config.sm],
NULL,
4096,
320*480/12,
false
);
dled_start(25);
tft_init(&lcd_config, dma_chan);
while (true) {
sleep_ms(100);
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);
}
sleep_ms(100);
tft_fill(16000);
dma_channel_wait_for_finish_blocking(dma_chan);
while (true);
return 0;
}
void dled_start(uint pin){

View File

@@ -17,8 +17,9 @@ void tft_write_cmd(PIO pio, uint sm, const uint8_t *cmd, size_t count) {
if (count >= 2) {
tft_wait_idle(pio, sm);
tft_set_dc_cs(1, 0);
for (size_t i = 0; i < count - 1; ++i)
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);
@@ -28,14 +29,14 @@ 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);
sleep_ms(*(cmd + 1) * 5);
// sleep_ms(200);
cmd += *cmd + 2;
}
}
void tft_start_pixels(PIO pio, uint sm) {
uint8_t cmd = 0x2c; // RAMWR
const uint8_t cmd = 0x2c; // RAMWR
tft_write_cmd(pio, sm, &cmd, 1);
tft_set_dc_cs(1, 0);
}
@@ -55,18 +56,19 @@ void tft_init(const struct tft_config* config, int dma_channel) {
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);
//lcd_init(tft_cfg.pio, tft_cfg.sm, st7789_init_seq);
gpio_put(tft_cfg.gpio_bl, 1);
}
void tft_fill(uint16_t color) {
tft_start_pixels(tft_cfg.pio, tft_cfg.sm);
size_t buf_size = 4096;
uint16_t* pix_buf = malloc(buf_size * sizeof(uint16_t));
uint32_t color_left = ((uint32_t)color) << 16;
uint32_t two = 0;
two |= color_left;
two |= color;
//tft_start_pixels(tft_cfg.pio, tft_cfg.sm);
uint32_t pix_buf[320*480/12];
size_t i;
for(i = 0; i < buf_size; i++) {
pix_buf[i] = color;
for(i = 0; i < 320*480/12; i++) {
pix_buf[i] = two;
}
tft_push(tft_cfg.pio, tft_cfg.sm, dma_chan, pix_buf, buf_size);
tft_push(tft_cfg.pio, tft_cfg.sm, dma_chan, pix_buf, buf_size);
free(pix_buf);
dma_channel_set_read_addr(dma_chan, pix_buf, true);
}

View File

@@ -42,4 +42,5 @@ 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, int dma_channel);
void tft_fill(uint16_t color);
void tft_push(PIO pio, uint sm, int dma_chan, uint32_t pixels[]);
#endif // TFT_H

View File

@@ -41,6 +41,7 @@ static inline void tft_program_init(PIO pio, uint sm, uint offset, uint data_pin
// Making use of the narrow store replication behaviour on RP2040 to get the
// data left-justified (as we are using shift-to-left to get MSB-first serial)
// => command gets sent 4 times
static inline void tft_put(PIO pio, uint sm, uint8_t x) {
while (pio_sm_is_tx_fifo_full(pio, sm))
@@ -48,18 +49,6 @@ static inline void tft_put(PIO pio, uint sm, uint8_t x) {
*(volatile uint8_t*)&pio->txf[sm] = x;
}
static inline void tft_push(PIO pio, uint sm, int dma_chan, uint16_t* pixels, size_t size) {
size_t new_size = size / 2;
uint32_t* x = malloc(new_size * sizeof(uint32_t));
for (size_t i = 0, j = 0; i < size; i += 2, j++) {
uint32_t combinedValue = ((uint32_t)pixels[i] << 16) | pixels[i + 1];
x[j] = combinedValue;
}
dma_channel_set_read_addr(dma_chan, x, true);
sleep_ms(100);
free(x);
}
// SM is done when it stalls on an empty FIFO