attemting to use dma not working

This commit is contained in:
matthias wagner
2023-05-13 20:27:38 +02:00
parent 29c6d4ac96
commit 2c4cfe8e27
24 changed files with 13370 additions and 11517 deletions

View File

@@ -27,7 +27,20 @@ int main()
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);
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_dreq(&c, DREQ_PIO0_TX0);
dma_channel_configure(
dma_chan,
&c,
&pio0_hw->txf[lcd_config.sm],
NULL,
4096,
false
);
tft_init(&lcd_config, dma_chan);
while (true) {
absolute_time_t start = get_absolute_time();

View File

@@ -2,6 +2,7 @@
static struct tft_config tft_cfg;
static bool tft_data_mode = false;
static int dma_chan;
void tft_set_dc_cs(bool dc, bool cs) {
sleep_us(1);
@@ -39,8 +40,9 @@ void tft_start_pixels(PIO pio, uint sm) {
tft_set_dc_cs(1, 0);
}
void tft_init(const struct tft_config* config) {
void tft_init(const struct tft_config* config, int dma_channel) {
memcpy(&tft_cfg, config, sizeof(tft_cfg));
dma_chan = dma_channel;
gpio_init(tft_cfg.gpio_cs);
gpio_init(tft_cfg.gpio_dc);
@@ -58,9 +60,13 @@ void tft_init(const struct tft_config* config) {
}
void tft_fill(uint16_t color) {
tft_start_pixels(tft_cfg.pio, tft_cfg.sm);
int num_pixels = tft_cfg.width * tft_cfg.height;
for (int i = 0; i < num_pixels; i++) {
tft_put(tft_cfg.pio, tft_cfg.sm, color >> 8);
tft_put(tft_cfg.pio, tft_cfg.sm, color & 0xff);
size_t buf_size = 4096;
uint16_t* pix_buf = malloc(buf_size * sizeof(uint16_t));
size_t i;
for(i = 0; i < buf_size; i++) {
pix_buf[i] = color;
}
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);
}

View File

@@ -4,6 +4,7 @@
#include "hardware/gpio.h"
#include "hardware/spi.h"
#include "hardware/divider.h"
#include "hardware/dma.h"
#include "tft.pio.h"
#include "pico/stdlib.h"
#include <string.h>
@@ -41,6 +42,6 @@ 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_init(const struct tft_config* config, int dma_channel);
void tft_fill(uint16_t color);
#endif // TFT_H

View File

@@ -22,6 +22,8 @@
// but we are using a threshold of 8 here (consume 1 byte from each FIFO entry
// and discard the remainder) to make things easier for software on the other side
#include <stdlib.h>
static inline void tft_program_init(PIO pio, uint sm, uint offset, uint data_pin, uint clk_pin, float clk_div) {
pio_gpio_init(pio, data_pin);
pio_gpio_init(pio, clk_pin);
@@ -32,7 +34,7 @@ static inline void tft_program_init(PIO pio, uint sm, uint offset, uint data_pin
sm_config_set_out_pins(&c, data_pin, 1);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
sm_config_set_clkdiv(&c, clk_div);
sm_config_set_out_shift(&c, false, true, 8);
sm_config_set_out_shift(&c, false, true, 32);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
@@ -46,6 +48,19 @@ 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
static inline void tft_wait_idle(PIO pio, uint sm) {