diff --git a/src/dmd_interface.h b/src/dmd_interface.h index ef35eef..67ce0bb 100644 --- a/src/dmd_interface.h +++ b/src/dmd_interface.h @@ -23,12 +23,8 @@ #include "hardware/gpio.h" #include "hardware/pio.h" -// Derive divider from current clock so PIO runs at ~125 MHz reference -float dmd_interface_125mhz_clk_divider = - (float)(clock_get_hz(clk_sys)) / 125000000.0f; // scales automatically - // Init the DMD reader (dots) PIO program, common for all DMD types. -void dmd_reader_program_init(PIO pio, uint sm, uint offset, pio_sm_config c, +void dmd_reader_program_init(float dmd_clkdiv, PIO pio, uint sm, uint offset, pio_sm_config c, uint in_base_pin) { sm_config_set_in_pins(&c, in_base_pin); @@ -48,7 +44,7 @@ void dmd_reader_program_init(PIO pio, uint sm, uint offset, pio_sm_config c, pio_sm_set_consecutive_pindirs(pio, sm, SDATA_X16_PADDING, 1, false); // Make sure we run this sm with a 125MHz clk - sm_config_set_clkdiv(&c, dmd_interface_125mhz_clk_divider); + sm_config_set_clkdiv(&c, dmd_clkdiv); } // Connect these GPIOs to this PIO block pio_gpio_init(pio, SDATA); @@ -71,7 +67,7 @@ void dmd_reader_program_init(PIO pio, uint sm, uint offset, pio_sm_config c, } // Init the framedetect PIO program. -void dmd_framedetect_program_init(PIO pio, uint sm, uint offset, +void dmd_framedetect_program_init(float dmd_clkdiv, PIO pio, uint sm, uint offset, pio_sm_config c, const uint* input_pins, uint num_input_pins, uint jump_pin) { if (jump_pin > 0) { @@ -92,7 +88,7 @@ void dmd_framedetect_program_init(PIO pio, uint sm, uint offset, 0); // Make sure we run this sm with a 125MHz clk - sm_config_set_clkdiv(&c, dmd_interface_125mhz_clk_divider); + sm_config_set_clkdiv(&c, dmd_clkdiv); // Load our configuration, do not yet start the program pio_sm_init(pio, sm, offset, &c); diff --git a/src/dmd_interface_capcom_hd.pio b/src/dmd_interface_capcom_hd.pio index 33d8bc3..433d10d 100644 --- a/src/dmd_interface_capcom_hd.pio +++ b/src/dmd_interface_capcom_hd.pio @@ -48,6 +48,6 @@ rclk_loop: wait 1 gpio RCLK wait 0 gpio RCLK jmp x-- rclk_loop - nop [3] irq PLANE_START_IRQ + wait 1 gpio RDATA .wrap \ No newline at end of file diff --git a/src/dmd_interface_de_x16_v2.pio b/src/dmd_interface_de_x16_v2.pio index 86f80cc..6a7e394 100644 --- a/src/dmd_interface_de_x16_v2.pio +++ b/src/dmd_interface_de_x16_v2.pio @@ -32,7 +32,7 @@ dotloop: jmp y-- start skip: - mov x, osr ; copy 8192 to x + mov x, osr ; copy 4096 to x lsb_msb_check: jmp pin reload_dotloop_y ; if DOTCLK is high, it means we will have a valid LSB + MSB row jmp x-- lsb_msb_check ; loop for ~65.5 µs (based on 125MHz clkdiv) @@ -62,7 +62,7 @@ reload_dotloop_y: wait_low: wait 0 gpio DE ; Wait for DE to go low - mov x, osr ; Use x as storage for 3000 iterations + mov x, osr ; Use x as storage for 2500 iterations delay_loop: jmp x-- delay_loop ; Decrement x and repeat until zero diff --git a/src/dmd_interface_desega.pio b/src/dmd_interface_desega.pio index 062ff81..f35b5de 100644 --- a/src/dmd_interface_desega.pio +++ b/src/dmd_interface_desega.pio @@ -41,12 +41,12 @@ dotloop: wait_low: wait 0 gpio DE ; Wait for DE to go low - set x, 31 ; Use x as storage for 32 iterations + set x, 20 ; Use x as storage for 20 iterations delay_loop: nop [31] nop [31] - jmp x-- delay_loop [31] ; Decrement x and repeat until zero + jmp x-- delay_loop ; Decrement x and repeat until zero ; After ~10 µs, check if still low jmp pin, wait_low ; If pin went high early → back to wait_low diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index a144ab0..3399380 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -650,7 +650,7 @@ void dmd_dma_handler() { // It seems to be sufficient to check every 8th pixel for these patterns to // detect sync. So we could avoid bitschifiting of the uint32_t value to // check every single pixel. - if (dmd_type >= DMD_CAPCOM && !locked_in && !plane0_shifted) { + if (dmd_type == DMD_CAPCOM && !locked_in && !plane0_shifted) { digitalWrite(LED_BUILTIN, HIGH); uint8_t value = pixval & 0x0F; if (value == 2 && (planebuf[px] & 0x0F) != 1 && @@ -724,7 +724,7 @@ void dmd_dma_handler() { } } - if (DMD_CAPCOM >= dmd_type && !locked_in && !plane0_shifted && + if (dmd_type == DMD_CAPCOM && !locked_in && !plane0_shifted && detected_0_1_0_1 && detected_1_0_0_0) { locked_in = true; } @@ -865,11 +865,16 @@ void dmdreader_programs_init(const pio_program_t *dmd_reader_program, DmdConfigGetter framedetect_get_default_config, uint *input_pins, uint8_t num_input_pins, uint8_t jump_pin, uint8_t in_base_pin) { + uint32_t sys_hz = clock_get_hz(clk_sys); // e.g. 125/200/266 MHz + float target_hz = 125000000.0f; // PIO code designed for 125 MHz + float dmd_clkdiv = (float)sys_hz / target_hz; // scales automatically + dmdreader_error_blink(pio_claim_free_sm_and_add_program_for_gpio_range( dmd_reader_program, &dmd_pio, &dmd_sm, &dmd_offset, (DE < SDATA_X16) ? DE : SDATA_X16, 8, true)); pio_sm_config dmd_config = reader_get_default_config(dmd_offset); - dmd_reader_program_init(dmd_pio, dmd_sm, dmd_offset, dmd_config, in_base_pin); + dmd_reader_program_init(dmd_clkdiv, dmd_pio, dmd_sm, dmd_offset, dmd_config, + in_base_pin); // The framedetect program just runs and detects the beginning of a new // frame @@ -877,8 +882,9 @@ void dmdreader_programs_init(const pio_program_t *dmd_reader_program, dmd_framedetect_program, &frame_pio, &frame_sm, &frame_offset, (DE < SDATA_X16) ? DE : SDATA_X16, 8, true)); pio_sm_config frame_config = framedetect_get_default_config(frame_offset); - dmd_framedetect_program_init(frame_pio, frame_sm, frame_offset, frame_config, - input_pins, num_input_pins, jump_pin); + dmd_framedetect_program_init(dmd_clkdiv, frame_pio, frame_sm, frame_offset, + frame_config, input_pins, num_input_pins, + jump_pin); pio_sm_set_enabled(frame_pio, frame_sm, true); } @@ -1032,13 +1038,13 @@ bool dmdreader_init(bool return_on_no_detection) { pio_sm_exec_wait_blocking(dmd_pio, dmd_sm, pio_encode_mov(pio_y, pio_null)); - // load 8192 directly to TX fifo - pio_sm_put(dmd_pio, dmd_sm, 8192); + // load 4096 directly to TX fifo (32uS) + pio_sm_put(dmd_pio, dmd_sm, 4096); // pull 32 bits from the TX fifo into osr pio_sm_exec(dmd_pio, dmd_sm, pio_encode_pull(false, false)); - // load 3000 directly to TX fifo - pio_sm_put(frame_pio, frame_sm, 3000); + // load 2500 directly to TX fifo (20uS) + pio_sm_put(frame_pio, frame_sm, 2500); // pull 32 bits from the TX fifo into osr pio_sm_exec(frame_pio, frame_sm, pio_encode_pull(false, false));