dma to pio outputting
This commit is contained in:
2
.vscode/.cortex-debug.peripherals.state.json
vendored
2
.vscode/.cortex-debug.peripherals.state.json
vendored
@@ -1 +1 @@
|
||||
[]
|
||||
[{"node":"PIO0","expanded":true,"format":0,"pinned":false}]
|
||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -18,5 +18,6 @@
|
||||
},
|
||||
"cmake.buildBeforeRun": true,
|
||||
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
|
||||
"C_Cpp.errorSquiggles": "disabled"
|
||||
"C_Cpp.errorSquiggles": "disabled",
|
||||
"cortex-debug.variableUseNaturalFormat": false
|
||||
}
|
||||
@@ -9,6 +9,8 @@ pico_generate_pio_header(clacer ${CMAKE_CURRENT_SOURCE_DIR}/src/tft.pio)
|
||||
target_sources(clacer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c)
|
||||
file(GLOB SOURCES "src/*.c")
|
||||
target_sources(clacer PRIVATE ${SOURCES})
|
||||
file(GLOB SOURCES "src/*.pio")
|
||||
target_sources(clacer PRIVATE ${SOURCES})
|
||||
target_link_libraries(clacer pico_stdlib pico_time hardware_pio hardware_dma)
|
||||
set_target_properties(clacer PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||
pico_add_extra_outputs(clacer)
|
||||
|
||||
25
src/main.c
25
src/main.c
@@ -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);
|
||||
}
|
||||
tft_fill(16000);
|
||||
dma_channel_wait_for_finish_blocking(dma_chan);
|
||||
while (true);
|
||||
return 0;
|
||||
}
|
||||
void dled_start(uint pin){
|
||||
|
||||
28
src/tft.c
28
src/tft.c
@@ -17,9 +17,10 @@ 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);
|
||||
}
|
||||
@@ -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
|
||||
13
src/tft.pio
13
src/tft.pio
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user