attemting to use dma not working
This commit is contained in:
15
src/main.c
15
src/main.c
@@ -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();
|
||||
|
||||
16
src/tft.c
16
src/tft.c
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
17
src/tft.pio
17
src/tft.pio
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user