From a1caa9495c3476e8d2568d3026db0d42bbc1e6a7 Mon Sep 17 00:00:00 2001 From: Mike Bell Date: Wed, 17 May 2023 20:45:26 +0100 Subject: [PATCH] Buffer sequential writes --- drivers/aps6404/aps6404.cpp | 34 +++++++++++++------------- drivers/dv_display/dv_display.cpp | 37 ++++++++++++++++------------- drivers/dv_display/dv_display.hpp | 11 ++++++--- examples/dv_stick/dv_stick_test.cpp | 16 ++++++++++++- 4 files changed, 61 insertions(+), 37 deletions(-) diff --git a/drivers/aps6404/aps6404.cpp b/drivers/aps6404/aps6404.cpp index 165612e4..5cd9aa0e 100644 --- a/drivers/aps6404/aps6404.cpp +++ b/drivers/aps6404/aps6404.cpp @@ -98,6 +98,13 @@ namespace pimoroni { } void APS6404::write(uint32_t addr, uint32_t* data, uint32_t len_in_bytes) { + dma_channel_config c = dma_channel_get_default_config(dma_channel); + channel_config_set_read_increment(&c, true); + channel_config_set_write_increment(&c, false); + channel_config_set_dreq(&c, pio_get_dreq(pio, pio_sm, true)); + channel_config_set_transfer_data_size(&c, DMA_SIZE_32); + channel_config_set_bswap(&c, true); + if (!last_cmd_was_write) { wait_for_finish_blocking(); setup_cmd_buffer_dma(true); @@ -114,13 +121,6 @@ namespace pimoroni { pio_sm_put_blocking(pio, pio_sm, 0x38000000u | addr); pio_sm_put_blocking(pio, pio_sm, pio_offset + sram_offset_do_write); - dma_channel_config c = dma_channel_get_default_config(dma_channel); - channel_config_set_read_increment(&c, true); - channel_config_set_write_increment(&c, false); - channel_config_set_dreq(&c, pio_get_dreq(pio, pio_sm, true)); - channel_config_set_transfer_data_size(&c, DMA_SIZE_32); - channel_config_set_bswap(&c, true); - dma_channel_configure( dma_channel, &c, &pio->txf[pio_sm], @@ -132,6 +132,13 @@ namespace pimoroni { } void APS6404::write_repeat(uint32_t addr, uint32_t data, uint32_t len_in_bytes) { + dma_channel_config c = dma_channel_get_default_config(dma_channel); + channel_config_set_read_increment(&c, false); + channel_config_set_write_increment(&c, false); + channel_config_set_dreq(&c, pio_get_dreq(pio, pio_sm, true)); + channel_config_set_transfer_data_size(&c, DMA_SIZE_32); + channel_config_set_bswap(&c, true); + if (!last_cmd_was_write) { wait_for_finish_blocking(); setup_cmd_buffer_dma(true); @@ -149,13 +156,6 @@ namespace pimoroni { pio_sm_put_blocking(pio, pio_sm, 0x38000000u | addr); pio_sm_put_blocking(pio, pio_sm, pio_offset + sram_offset_do_write); - dma_channel_config c = dma_channel_get_default_config(dma_channel); - channel_config_set_read_increment(&c, false); - channel_config_set_write_increment(&c, false); - channel_config_set_dreq(&c, pio_get_dreq(pio, pio_sm, true)); - channel_config_set_transfer_data_size(&c, DMA_SIZE_32); - channel_config_set_bswap(&c, true); - dma_channel_configure( dma_channel, &c, &pio->txf[pio_sm], @@ -199,9 +199,6 @@ namespace pimoroni { } void APS6404::start_read(uint32_t* read_buf, uint32_t total_len_in_words, int chain_channel) { - last_cmd_was_write = false; - wait_for_finish_blocking(); - dma_channel_config c = dma_channel_get_default_config(dma_channel); channel_config_set_read_increment(&c, false); channel_config_set_write_increment(&c, true); @@ -212,6 +209,9 @@ namespace pimoroni { channel_config_set_chain_to(&c, chain_channel); } + last_cmd_was_write = false; + wait_for_finish_blocking(); + dma_channel_configure( dma_channel, &c, read_buf, diff --git a/drivers/dv_display/dv_display.cpp b/drivers/dv_display/dv_display.cpp index 1550e21e..61be84f3 100644 --- a/drivers/dv_display/dv_display.cpp +++ b/drivers/dv_display/dv_display.cpp @@ -16,6 +16,7 @@ namespace pimoroni { gpio_init(VSYNC); gpio_set_dir(VSYNC, GPIO_IN); + sleep_ms(200); swd_load_program(section_addresses, section_data, section_data_len, sizeof(section_addresses) / sizeof(section_addresses[0]), 0x20000001, 0x15004000, true); ram.init(); @@ -27,7 +28,7 @@ namespace pimoroni { bank = 0; gpio_put(RAM_SEL, 0); - sleep_ms(500); + sleep_ms(100); printf("Start I2C\n"); //i2c_init(i2c0, 100000); @@ -41,26 +42,16 @@ namespace pimoroni { } void DVDisplay::flip() { + if (pixel_buffer_location.y != -1) { + ram.write(pointToAddress(pixel_buffer_location), pixel_buffer, pixel_buffer_x << 1); + pixel_buffer_location.y = -1; + } bank ^= 1; ram.wait_for_finish_blocking(); while (gpio_get(VSYNC) == 0); gpio_put(RAM_SEL, bank); } - void DVDisplay::write(uint32_t address, size_t len, const uint16_t *data) - { - if ((uintptr_t)data & 2) { - write(address, 1, *data); - data++; - len--; - address += 2; - } - - if (len > 0) { - ram.write(address, (uint32_t*)data, len << 1); - } - } - void DVDisplay::write(uint32_t address, size_t len, const uint16_t colour) { uint32_t val = colour | ((uint32_t)colour << 16); @@ -75,7 +66,21 @@ namespace pimoroni { void DVDisplay::write_pixel(const Point &p, uint16_t colour) { - write(pointToAddress(p), 1, colour); + if (pixel_buffer_location.y == p.y && pixel_buffer_location.x + pixel_buffer_x == p.x) { + if (pixel_buffer_x & 1) pixel_buffer[pixel_buffer_x >> 1] |= (uint32_t)colour << 16; + else pixel_buffer[pixel_buffer_x >> 1] = colour; + if (++pixel_buffer_x == PIXEL_BUFFER_LEN_IN_WORDS * 2) { + ram.write(pointToAddress(pixel_buffer_location), pixel_buffer, PIXEL_BUFFER_LEN_IN_WORDS * 4); + pixel_buffer_location.y = -1; + } + return; + } + else if (pixel_buffer_location.y != -1) { + ram.write(pointToAddress(pixel_buffer_location), pixel_buffer, pixel_buffer_x << 1); + } + pixel_buffer_location = p; + pixel_buffer_x = 1; + pixel_buffer[0] = colour; } void DVDisplay::write_pixel_span(const Point &p, uint l, uint16_t colour) diff --git a/drivers/dv_display/dv_display.hpp b/drivers/dv_display/dv_display.hpp index ea26fb7c..afd2a9c1 100644 --- a/drivers/dv_display/dv_display.hpp +++ b/drivers/dv_display/dv_display.hpp @@ -48,6 +48,7 @@ namespace pimoroni { : ram(CS, D0) , i2c(I2C_SDA, I2C_SCL) , width(width), height(height) + , pixel_buffer_location(-1, -1) {} //-------------------------------------------------- @@ -66,7 +67,7 @@ namespace pimoroni { for(uint k = 0; k < 1024*mb; k++) { sprintf(writeBuffer, "%u-%u", b, k); - write(k*1024, strlen(writeBuffer)+1, (uint16_t *)writeBuffer); + ram.write(k*1024, (uint32_t *)writeBuffer, strlen(writeBuffer)+1); } } @@ -91,8 +92,12 @@ namespace pimoroni { void flip(); private: - void write(uint32_t address, size_t len, const uint16_t *data); - void write(uint32_t address, size_t len, const uint16_t byte); + static constexpr int PIXEL_BUFFER_LEN_IN_WORDS = 16; + uint32_t pixel_buffer[PIXEL_BUFFER_LEN_IN_WORDS]; + Point pixel_buffer_location; + int32_t pixel_buffer_x; + + void write(uint32_t address, size_t len, const uint16_t colour); void read(uint32_t address, size_t len, uint16_t *data); void write_header(uint bank); diff --git a/examples/dv_stick/dv_stick_test.cpp b/examples/dv_stick/dv_stick_test.cpp index 09fac16e..862a99c5 100644 --- a/examples/dv_stick/dv_stick_test.cpp +++ b/examples/dv_stick/dv_stick_test.cpp @@ -39,7 +39,7 @@ int main() { gpio_set_dir(BUTTON_A, GPIO_IN); gpio_pull_up(BUTTON_A); - sleep_ms(5000); + //sleep_ms(5000); DVDisplay display(FRAME_WIDTH, FRAME_HEIGHT); display.init(); @@ -79,6 +79,20 @@ int main() { graphics.set_pen(0xFFFF); graphics.clear(); + for (uint i = 0; i < 128; i++) { + for (uint j = 0; j < 256; j++) { + graphics.set_pen((j << 7) | i); + graphics.pixel(Point(j, i)); + } + } + + for (uint i = 0; i < 128; i++) { + for (uint j = 0; j < 256; j++) { + graphics.set_pen((j << 7) | i); + graphics.pixel(Point(i, j+128)); + } + } + for(int i =0 ; i < NUM_CIRCLES ; i++) { graphics.set_pen(0);