diff --git a/drivers/hub75/hub75.cpp b/drivers/hub75/hub75.cpp index d804ae96..0d4ac48a 100644 --- a/drivers/hub75/hub75.cpp +++ b/drivers/hub75/hub75.cpp @@ -68,6 +68,13 @@ Hub75::Hub75(uint width, uint height, Pixel *buffer, PanelType panel_type, bool back_buffer = buffer + width * height; managed_buffer = false; } + + if (brightness == 0) { + if (width >= 64) brightness = 6; + if (width >= 96) brightness = 3; + if (width >= 128) brightness = 2; + if (width >= 160) brightness = 1; + } } void Hub75::set_rgb(uint x, uint y, uint8_t r, uint8_t g, uint8_t b) { @@ -203,7 +210,7 @@ void Hub75::stop(irq_handler_t handler) { irq_remove_handler(DMA_IRQ_0, handler); //dma_channel_wait_for_finish_blocking(dma_channel); dma_channel_abort(dma_channel); - dma_channel_acknowledge_irq1(dma_channel); + dma_channel_acknowledge_irq0(dma_channel); dma_channel_unclaim(dma_channel); } @@ -270,14 +277,18 @@ void Hub75::dma_complete() { if(dma_channel_get_irq0_status(dma_channel)) { dma_channel_acknowledge_irq0(dma_channel); - // SM is finished when it stalls on empty TX FIFO (or, y'know, DMA callback) + // Push out a dummy pixel for each row + pio_sm_put_blocking(pio, sm_data, 0); + pio_sm_put_blocking(pio, sm_data, 0); + + // SM is finished when it stalls on empty TX FIFO hub75_wait_tx_stall(pio, sm_data); // Check that previous OEn pulse is finished, else things WILL get out of sequence hub75_wait_tx_stall(pio, sm_row); // Latch row data, pulse output enable for new row. - pio_sm_put_blocking(pio, sm_row, row | (6u << 5 << bit)); + pio_sm_put_blocking(pio, sm_row, row | (brightness << 5 << bit)); if (do_flip && bit == 0 && row == 0) { // Literally flip the front and back buffers by swapping their addresses diff --git a/drivers/hub75/hub75.hpp b/drivers/hub75/hub75.hpp index f906f7a3..f747c83b 100644 --- a/drivers/hub75/hub75.hpp +++ b/drivers/hub75/hub75.hpp @@ -70,6 +70,8 @@ class Hub75 { uint data_prog_offs = 0; uint row_prog_offs = 0; + uint brightness = 6; + // Top half of display - 16 rows on a 32x32 panel unsigned int pin_r0 = 0; diff --git a/drivers/hub75/hub75.pio b/drivers/hub75/hub75.pio index a43863e2..facfdafa 100644 --- a/drivers/hub75/hub75.pio +++ b/drivers/hub75/hub75.pio @@ -20,7 +20,7 @@ .side_set 2 .wrap_target - out pins, 5 [7] side 0x2 ; Deassert OEn, output row select + out pins, 5 [1] side 0x2 ; Deassert OEn, output row select out x, 27 [7] side 0x3 ; Pulse LATCH, get OEn pulse width pulse_loop: jmp x-- pulse_loop side 0x0 ; Assert OEn for x+1 cycles @@ -42,7 +42,7 @@ pulse_loop: .side_set 2 .wrap_target - out pins, 5 [7] side 0x3 ; Deassert OEn, output row select + out pins, 5 [1] side 0x3 ; Deassert OEn, output row select out x, 27 [7] side 0x2 ; Pulse LATCH, get OEn pulse width pulse_loop: jmp x-- pulse_loop side 0x1 ; Assert OEn for x+1 cycles @@ -107,17 +107,18 @@ public shift0: ; R0 G0 B0 (Top half of 64x64 displays) public shift1: ; R1 G1 B1 (Bottom half of 64x64 displays) pull side 0 ; gets patched to `out null, n` if n nonzero (otherwise the PULL is required for fencing) - in osr, 1 side 0 ; Red1 N - out null, 10 side 0 ; Red1 discard + in osr, 1 side 1 ; Red1 N + out null, 10 side 1 ; Red1 discard - in osr, 1 side 0 ; Green1 N - out null, 10 side 0 ; Green1 discard + in osr, 1 side 1 ; Green1 N + out null, 10 side 1 ; Green1 discard - in osr, 1 side 0 ; Blue1 N - out null, 32 side 0 ; Remainder discard + in osr, 1 side 1 ; Blue1 N + out null, 32 side 1 ; Remainder discard + + in null, 26 side 1 ; Note we are just doing this little manoeuvre here to get GPIOs in the order + mov pins, ::isr side 1 ; R0, G0, B0, R1, G1, B1. Can go 1 cycle faster if reversed - in null, 26 side 0 ; Note we are just doing this little manoeuvre here to get GPIOs in the order - mov pins, ::isr [7] side 1 ; R0, G0, B0, R1, G1, B1. Can go 1 cycle faster if reversed .wrap ; Note that because the clock edge for pixel n is in the middle of pixel n + ; 1, a dummy pixel at the end is required to clock the last piece of genuine