diff --git a/drivers/hub75/hub75.cpp b/drivers/hub75/hub75.cpp index c56f5e0ce..d4b41bdb4 100644 --- a/drivers/hub75/hub75.cpp +++ b/drivers/hub75/hub75.cpp @@ -2,6 +2,8 @@ #include #include +#include "hardware/clocks.h" + #include "hub75.hpp" namespace pimoroni { @@ -145,6 +147,8 @@ void Hub75::start(irq_handler_t handler) { FM6126A_setup(); } + uint latch_cycles = clock_get_hz(clk_sys) / 4000000; + // Claim the PIO so we can clean it upon soft restart pio_sm_claim(pio, sm_data); pio_sm_claim(pio, sm_row); @@ -156,7 +160,7 @@ void Hub75::start(irq_handler_t handler) { row_prog_offs = pio_add_program(pio, &hub75_row_program); } hub75_data_rgb888_program_init(pio, sm_data, data_prog_offs, DATA_BASE_PIN, pin_clk); - hub75_row_program_init(pio, sm_row, row_prog_offs, ROWSEL_BASE_PIN, ROWSEL_N_PINS, pin_stb); + hub75_row_program_init(pio, sm_row, row_prog_offs, ROWSEL_BASE_PIN, ROWSEL_N_PINS, pin_stb, latch_cycles); // Prevent flicker in Python caused by the smaller dataset just blasting through the PIO too quickly pio_sm_set_clkdiv(pio, sm_data, width <= 32 ? 2.0f : 1.0f); diff --git a/drivers/hub75/hub75.pio b/drivers/hub75/hub75.pio index facfdafa9..1b7ee29e6 100644 --- a/drivers/hub75/hub75.pio +++ b/drivers/hub75/hub75.pio @@ -21,7 +21,10 @@ .wrap_target out pins, 5 [1] side 0x2 ; Deassert OEn, output row select - out x, 27 [7] side 0x3 ; Pulse LATCH, get OEn pulse width + mov x, y [3] side 0x3 ; Pulse LATCH +wait_loop: + jmp x-- wait_loop side 0x2 ; Wait for row to latch + out x, 27 side 0x2 ; Get OEn pulse width pulse_loop: jmp x-- pulse_loop side 0x0 ; Assert OEn for x+1 cycles .wrap @@ -43,13 +46,16 @@ pulse_loop: .wrap_target out pins, 5 [1] side 0x3 ; Deassert OEn, output row select - out x, 27 [7] side 0x2 ; Pulse LATCH, get OEn pulse width + mov x, y [3] side 0x2 ; Pulse LATCH +wait_loop: + jmp x-- wait_loop side 0x3 ; Wait for row to latch + out x, 27 side 0x3 ; Get OEn pulse width pulse_loop: jmp x-- pulse_loop side 0x1 ; Assert OEn for x+1 cycles .wrap % c-sdk { -static inline void hub75_row_program_init(PIO pio, uint sm, uint offset, uint row_base_pin, uint n_row_pins, uint latch_base_pin) { +static inline void hub75_row_program_init(PIO pio, uint sm, uint offset, uint row_base_pin, uint n_row_pins, uint latch_base_pin, uint latch_cycles) { pio_sm_set_consecutive_pindirs(pio, sm, row_base_pin, n_row_pins, true); pio_sm_set_consecutive_pindirs(pio, sm, latch_base_pin, 2, true); for (uint i = row_base_pin; i < row_base_pin + n_row_pins; ++i) @@ -62,6 +68,8 @@ static inline void hub75_row_program_init(PIO pio, uint sm, uint offset, uint ro sm_config_set_sideset_pins(&c, latch_base_pin); sm_config_set_out_shift(&c, true, true, 32); pio_sm_init(pio, sm, offset, &c); + pio_sm_exec(pio, sm, pio_encode_out(pio_y, 32)); + pio_sm_put(pio, sm, latch_cycles); pio_sm_set_enabled(pio, sm, true); }