diff --git a/drivers/aps6404/aps6404.cpp b/drivers/aps6404/aps6404.cpp index 53b5665a..13750746 100644 --- a/drivers/aps6404/aps6404.cpp +++ b/drivers/aps6404/aps6404.cpp @@ -192,9 +192,9 @@ namespace pimoroni { void APS6404::read(uint32_t addr, uint32_t* read_buf, uint32_t len_in_words) { start_read(read_buf, len_in_words); - uint32_t first_page_len = (PAGE_SIZE - (addr & (PAGE_SIZE - 1))) >> 2; + uint32_t first_page_len = (PAGE_SIZE - (addr & (PAGE_SIZE - 1))); - if (first_page_len >= len_in_words) { + if (first_page_len >= len_in_words << 2) { pio_sm_put_blocking(pio, pio_sm, (len_in_words * 8) - 4); pio_sm_put_blocking(pio, pio_sm, 0xeb000000u | addr); pio_sm_put_blocking(pio, pio_sm, pio_offset + sram_offset_do_read); @@ -261,19 +261,33 @@ namespace pimoroni { } uint32_t* APS6404::add_read_to_cmd_buffer(uint32_t* cmd_buf, uint32_t addr, uint32_t len_in_words) { - uint32_t len = (PAGE_SIZE - (addr & (PAGE_SIZE - 1))) >> 2; + int32_t len_remaining = len_in_words << 2; + uint32_t len = std::min((PAGE_SIZE - (addr & (PAGE_SIZE - 1))), (uint32_t)len_remaining); + bool clear_isr = false; while (true) { - *cmd_buf++ = (len * 8) - 4; + if (len < 2) { + // This is guaranteed to leave at least one byte in the ISR, + // which we then clear with an additional command + len = 2; + clear_isr = true; + } + *cmd_buf++ = (len * 2) - 4; *cmd_buf++ = 0xeb000000u | addr; *cmd_buf++ = pio_offset + sram_offset_do_read; - len_in_words -= len; - addr += len << 2; + len_remaining -= len; + addr += len; - if (len_in_words == 0) break; + if (len_remaining <= 0) break; - len = len_in_words; - if (len > (PAGE_SIZE >> 2)) len = PAGE_SIZE >> 2; + len = len_remaining; + if (len > PAGE_SIZE) len = PAGE_SIZE; + } + + if (clear_isr) { + *cmd_buf++ = 0; + *cmd_buf++ = 0xeb000000u | addr; + *cmd_buf++ = pio_offset + sram_offset_do_clear; } return cmd_buf; diff --git a/drivers/aps6404/aps6404.pio b/drivers/aps6404/aps6404.pio index 02069e09..30f1c0a7 100644 --- a/drivers/aps6404/aps6404.pio +++ b/drivers/aps6404/aps6404.pio @@ -34,6 +34,8 @@ PUBLIC do_write: jmp y--, do_write side 0b10 set pindirs, 0 side 0b00 out null, 32 side 0b01 +PUBLIC do_clear: + mov isr, null side 0b01 jmp top side 0b01 ; Read command @@ -76,6 +78,8 @@ PUBLIC do_write: jmp y--, do_write side 0b10 set pindirs, 0 side 0b00 out null, 32 side 0b01 +PUBLIC do_clear: + mov isr, null side 0b01 jmp top side 0b01 ; Read command @@ -121,6 +125,8 @@ PUBLIC do_write: jmp y--, do_write [1] side 0b10 set pindirs, 0 side 0b00 out null, 32 side 0b01 +PUBLIC do_clear: + mov isr, null side 0b01 jmp top side 0b01 ; Read command diff --git a/drivers/dv_display/dv_display.cpp b/drivers/dv_display/dv_display.cpp index 37bebbb6..1199272c 100644 --- a/drivers/dv_display/dv_display.cpp +++ b/drivers/dv_display/dv_display.cpp @@ -378,6 +378,7 @@ namespace pimoroni { ram.write(point_to_address_palette(p), &val, 1); --l; offset++; + ram.wait_for_finish_blocking(); } if (l > 0) { ram.write(point_to_address_palette(p) + offset, (uint32_t*)data, l);