diff --git a/.vscode/.cortex-debug.peripherals.state.json b/.vscode/.cortex-debug.peripherals.state.json index 0637a08..462db0e 100644 --- a/.vscode/.cortex-debug.peripherals.state.json +++ b/.vscode/.cortex-debug.peripherals.state.json @@ -1 +1 @@ -[] \ No newline at end of file +[{"node":"PIO0","expanded":true,"format":0,"pinned":false}] \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 6e3a574..62d4392 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -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 } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f0e1f48..0d7dd67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/src/main.c b/src/main.c index 614ca33..70fa9ff 100644 --- a/src/main.c +++ b/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); - } + sleep_ms(100); + tft_fill(16000); + dma_channel_wait_for_finish_blocking(dma_chan); + while (true); return 0; } void dled_start(uint pin){ diff --git a/src/tft.c b/src/tft.c index b1a8dcc..be9b10a 100644 --- a/src/tft.c +++ b/src/tft.c @@ -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); } \ No newline at end of file diff --git a/src/tft.h b/src/tft.h index 33275c3..5507965 100644 --- a/src/tft.h +++ b/src/tft.h @@ -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 \ No newline at end of file diff --git a/src/tft.pio b/src/tft.pio index e9f13cf..6a8a534 100644 --- a/src/tft.pio +++ b/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