From fe4794247d4ed4b9b9583079b3a7f626d815a0c2 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Fri, 19 Jun 2026 13:08:51 +0200 Subject: [PATCH 1/7] first attempt --- src/dmdreader.cpp | 52 +++++++++++++++++++++++++++++++++-------------- src/dmdreader.h | 2 ++ src/main.cpp | 1 + 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index 58311f2e..520ef583 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -284,26 +284,48 @@ void spi_dma_handler() { * * @return uint32_t Number of clocks per second */ -uint32_t count_clock(uint pin) { - uint pio_offset; - pio_claim_free_sm_and_add_program_for_gpio_range( - &dmd_count_signal_program, &dmd_pio, &dmd_sm, &pio_offset, pin, 1, true); - dmd_counter_program_init(dmd_pio, dmd_sm, pio_offset, pin); - pio_sm_set_enabled(dmd_pio, dmd_sm, true); +uint64_t count_clock() { + const uint pins[3] = {DOTCLK, RCLK, RDATA}; + uint sms[3]; + uint offsets[3]; + uint32_t counts[3]; + + for (int i = 0; i < 3; i++) { + pio_claim_free_sm_and_add_program_for_gpio_range( + &dmd_count_signal_program, &dmd_pio, &sms[i], &offsets[i], pins[i], 1, true); + dmd_counter_program_init(dmd_pio, sms[i], offsets[i], pins[i]); + pio_sm_set_enabled(dmd_pio, sms[i], true); + } + delay(250); - pio_sm_exec(dmd_pio, dmd_sm, pio_encode_in(pio_x, 32)); - uint32_t count = ~pio_sm_get(dmd_pio, dmd_sm); - pio_sm_set_enabled(dmd_pio, dmd_sm, false); - pio_remove_program_and_unclaim_sm(&dmd_count_signal_program, dmd_pio, dmd_sm, - pio_offset); - return count * 4; + for (int i = 0; i < 3; i++) { + pio_sm_exec(dmd_pio, sms[i], pio_encode_in(pio_x, 32)); + counts[i] = (~pio_sm_get(dmd_pio, sms[i])) * 4; + } + + for (int i = 0; i < 3; i++) { + pio_sm_set_enabled(dmd_pio, sms[i], false); + pio_remove_program_and_unclaim_sm(&dmd_count_signal_program, dmd_pio, sms[i], offsets[i]); + } + + counts[0] = 1230000; + counts[1] = 60000; + counts[2] = 41000; + + return (uint64_t)counts[0] << 32 | (uint64_t)counts[1] << 16 | (uint64_t)counts[2]; } DmdType detect_dmd() { - uint32_t dotclk = count_clock(DOTCLK); - uint32_t rclk = count_clock(RCLK); - uint32_t rdata = count_clock(RDATA); + + uint64_t signals = count_clock(); + uint32_t dotclk = signals >> 32; + uint16_t rclk = signals >> 16; // never exceeds 25000 + uint16_t rdata = signals; // never exceeds 600 + Serial.printf("dotclk: %u\n", dotclk); + Serial.printf("rclk: %u\n", rclk); + Serial.printf("rdata: %u\n", rdata); + return; // By checking DOTCLK, RCLK and RDATA we can identify system types // All values are based on a 1000ms sample of data diff --git a/src/dmdreader.h b/src/dmdreader.h index b17944e8..a23c8c2e 100644 --- a/src/dmdreader.h +++ b/src/dmdreader.h @@ -50,6 +50,8 @@ uint8_t *dmdreader_loopback_render(); void dmdreader_error_blink(bool no_error); +DmdType detect_dmd(); + uint16_t dmdreader_get_source_width(); uint16_t dmdreader_get_source_height(); diff --git a/src/main.cpp b/src/main.cpp index c550b49d..15f4edd7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,6 +28,7 @@ void setup() { void loop() { // Everything is triggered by interrupts, so nothing to do here delay(5000); + detect_dmd(); // digitalWrite(LED_BUILTIN, HIGH); delay(500); // digitalWrite(LED_BUILTIN, LOW); From 7569ab3af86447a93ca4e01420d412a645806519 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Fri, 19 Jun 2026 13:12:18 +0200 Subject: [PATCH 2/7] remove return --- src/dmdreader.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index 520ef583..00655713 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -325,7 +325,6 @@ DmdType detect_dmd() { Serial.printf("dotclk: %u\n", dotclk); Serial.printf("rclk: %u\n", rclk); Serial.printf("rdata: %u\n", rdata); - return; // By checking DOTCLK, RCLK and RDATA we can identify system types // All values are based on a 1000ms sample of data From f59ee363d67aa65f467448a12b8966e6bb6c47cd Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Fri, 19 Jun 2026 16:11:49 +0200 Subject: [PATCH 3/7] test in game --- src/dmdreader.cpp | 10 +++------- src/dmdreader.h | 2 -- src/main.cpp | 1 - 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index 00655713..658e6127 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -309,10 +309,6 @@ uint64_t count_clock() { pio_remove_program_and_unclaim_sm(&dmd_count_signal_program, dmd_pio, sms[i], offsets[i]); } - counts[0] = 1230000; - counts[1] = 60000; - counts[2] = 41000; - return (uint64_t)counts[0] << 32 | (uint64_t)counts[1] << 16 | (uint64_t)counts[2]; } @@ -322,9 +318,9 @@ DmdType detect_dmd() { uint32_t dotclk = signals >> 32; uint16_t rclk = signals >> 16; // never exceeds 25000 uint16_t rdata = signals; // never exceeds 600 - Serial.printf("dotclk: %u\n", dotclk); - Serial.printf("rclk: %u\n", rclk); - Serial.printf("rdata: %u\n", rdata); + //Serial.printf("dotclk: %u\n", dotclk); + //Serial.printf("rclk: %u\n", rclk); + //Serial.printf("rdata: %u\n", rdata); // By checking DOTCLK, RCLK and RDATA we can identify system types // All values are based on a 1000ms sample of data diff --git a/src/dmdreader.h b/src/dmdreader.h index a23c8c2e..b17944e8 100644 --- a/src/dmdreader.h +++ b/src/dmdreader.h @@ -50,8 +50,6 @@ uint8_t *dmdreader_loopback_render(); void dmdreader_error_blink(bool no_error); -DmdType detect_dmd(); - uint16_t dmdreader_get_source_width(); uint16_t dmdreader_get_source_height(); diff --git a/src/main.cpp b/src/main.cpp index 15f4edd7..c550b49d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,7 +28,6 @@ void setup() { void loop() { // Everything is triggered by interrupts, so nothing to do here delay(5000); - detect_dmd(); // digitalWrite(LED_BUILTIN, HIGH); delay(500); // digitalWrite(LED_BUILTIN, LOW); From b4eb231a1ad27166b81647804e9c673e8f73d305 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Fri, 19 Jun 2026 20:04:49 +0200 Subject: [PATCH 4/7] quick test --- src/dmdreader.cpp | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index 658e6127..23732eb1 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -130,6 +130,7 @@ bool loopback = false; // SPI PIO PIO spi_pio; uint spi_sm; +uint spi_offset; // DMD reader PIO PIO dmd_pio; @@ -286,30 +287,35 @@ void spi_dma_handler() { */ uint64_t count_clock() { const uint pins[3] = {DOTCLK, RCLK, RDATA}; - uint sms[3]; - uint offsets[3]; - uint32_t counts[3]; + // why not make use of the already existing sms/offsets + uint *sms[3] = {&spi_sm, &dmd_sm, &frame_sm}; + uint *offsets[3] = {&spi_offset, &dmd_offset, &frame_offset}; for (int i = 0; i < 3; i++) { pio_claim_free_sm_and_add_program_for_gpio_range( - &dmd_count_signal_program, &dmd_pio, &sms[i], &offsets[i], pins[i], 1, true); - dmd_counter_program_init(dmd_pio, sms[i], offsets[i], pins[i]); - pio_sm_set_enabled(dmd_pio, sms[i], true); + &dmd_count_signal_program, &dmd_pio, sms[i], offsets[i], pins[i], 1, + true); + dmd_counter_program_init(dmd_pio, *sms[i], *offsets[i], pins[i]); + pio_sm_set_enabled(dmd_pio, *sms[i], true); } - +//} delay(250); +//uint64_t read_clock_count() { + uint32_t counts[3]; + // why not make use of the already existing sms/offsets + //uint *sms[3] = {&spi_sm, &dmd_sm, &frame_sm}; + //uint *offsets[3] = {&spi_offset, &dmd_offset, &frame_offset}; for (int i = 0; i < 3; i++) { - pio_sm_exec(dmd_pio, sms[i], pio_encode_in(pio_x, 32)); - counts[i] = (~pio_sm_get(dmd_pio, sms[i])) * 4; - } - - for (int i = 0; i < 3; i++) { - pio_sm_set_enabled(dmd_pio, sms[i], false); - pio_remove_program_and_unclaim_sm(&dmd_count_signal_program, dmd_pio, sms[i], offsets[i]); + pio_sm_exec(dmd_pio, *sms[i], pio_encode_in(pio_x, 32)); + counts[i] = (~pio_sm_get(dmd_pio, *sms[i])) * 4; + pio_sm_set_enabled(dmd_pio, *sms[i], false); + pio_remove_program_and_unclaim_sm(&dmd_count_signal_program, dmd_pio, + *sms[i], *offsets[i]); } - return (uint64_t)counts[0] << 32 | (uint64_t)counts[1] << 16 | (uint64_t)counts[2]; + return (uint64_t)counts[0] << 32 | (uint64_t)counts[1] << 16 | + (uint64_t)counts[2]; } DmdType detect_dmd() { @@ -941,6 +947,7 @@ bool dmdreader_init(bool return_on_no_detection) { // Loop until the DMD is detected as it might need some time to be available // on power-on do { + //uint64_t signals = count_clock(); dmd_type = detect_dmd(); if (dmd_type == DMD_UNKNOWN && return_on_no_detection) { return false; @@ -1503,11 +1510,10 @@ void dmdreader_spi_init() { digitalWrite(SPI0_CS, LOW); // initialize SPI slave PIO - uint pio_offset; dmdreader_error_blink(pio_claim_free_sm_and_add_program_for_gpio_range( - &clocked_output_program, &spi_pio, &spi_sm, &pio_offset, SPI_BASE, 4, + &clocked_output_program, &spi_pio, &spi_sm, &spi_offset, SPI_BASE, 4, true)); - clocked_output_program_init(spi_pio, spi_sm, pio_offset, SPI_BASE); + clocked_output_program_init(spi_pio, spi_sm, spi_offset, SPI_BASE); // DMA for SPI spi_dma_channel = dma_claim_unused_channel(true); From 61d6c844e78bb8dbe31f9fd9c6a71074cce2c85e Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Fri, 19 Jun 2026 22:01:46 +0200 Subject: [PATCH 5/7] non blocking handling for return on no detect --- src/dmdreader.cpp | 49 ++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index 23732eb1..237ed3c2 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -285,9 +285,10 @@ void spi_dma_handler() { * * @return uint32_t Number of clocks per second */ -uint64_t count_clock() { + +void count_clock() { const uint pins[3] = {DOTCLK, RCLK, RDATA}; - // why not make use of the already existing sms/offsets + // just make use of the already defined sms/offsets uint *sms[3] = {&spi_sm, &dmd_sm, &frame_sm}; uint *offsets[3] = {&spi_offset, &dmd_offset, &frame_offset}; @@ -298,13 +299,13 @@ uint64_t count_clock() { dmd_counter_program_init(dmd_pio, *sms[i], *offsets[i], pins[i]); pio_sm_set_enabled(dmd_pio, *sms[i], true); } -//} - delay(250); -//uint64_t read_clock_count() { +} + +uint64_t read_clock_count() { uint32_t counts[3]; - // why not make use of the already existing sms/offsets - //uint *sms[3] = {&spi_sm, &dmd_sm, &frame_sm}; - //uint *offsets[3] = {&spi_offset, &dmd_offset, &frame_offset}; + // just make use of the already defined sms/offsets + uint *sms[3] = {&spi_sm, &dmd_sm, &frame_sm}; + uint *offsets[3] = {&spi_offset, &dmd_offset, &frame_offset}; for (int i = 0; i < 3; i++) { pio_sm_exec(dmd_pio, *sms[i], pio_encode_in(pio_x, 32)); @@ -320,13 +321,10 @@ uint64_t count_clock() { DmdType detect_dmd() { - uint64_t signals = count_clock(); + uint64_t signals = read_clock_count(); uint32_t dotclk = signals >> 32; uint16_t rclk = signals >> 16; // never exceeds 25000 uint16_t rdata = signals; // never exceeds 600 - //Serial.printf("dotclk: %u\n", dotclk); - //Serial.printf("rclk: %u\n", rclk); - //Serial.printf("rdata: %u\n", rdata); // By checking DOTCLK, RCLK and RDATA we can identify system types // All values are based on a 1000ms sample of data @@ -945,17 +943,28 @@ void dmdreader_programs_init(const pio_program_t *dmd_reader_program, bool dmdreader_init(bool return_on_no_detection) { dmd_type = DMD_UNKNOWN; // Loop until the DMD is detected as it might need some time to be available - // on power-on + // on power-on - non blocking if return_on_no_detection is true do { - //uint64_t signals = count_clock(); - dmd_type = detect_dmd(); - if (dmd_type == DMD_UNKNOWN && return_on_no_detection) { - return false; + if (!locked_in) { + digitalWrite(LED_BUILTIN, HIGH); + locked_in = true; + count_clock(); + if (return_on_no_detection) return true; + delay(250); } - digitalWrite(LED_BUILTIN, HIGH); - delay(300); + + dmd_type = detect_dmd(); digitalWrite(LED_BUILTIN, LOW); - delay(200); + locked_in = false; + + if (dmd_type == DMD_UNKNOWN) { + if (return_on_no_detection) { + return false; + } else { + delay(750); + } + } + } while (dmd_type == DMD_UNKNOWN); // Delay is still needed when blink gets removed above. From 94810baa1758f6077781ccc47b8a35f97a5ed5b0 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Fri, 19 Jun 2026 22:51:53 +0200 Subject: [PATCH 6/7] should be false --- src/dmdreader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index 237ed3c2..e04bbd08 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -949,14 +949,14 @@ bool dmdreader_init(bool return_on_no_detection) { digitalWrite(LED_BUILTIN, HIGH); locked_in = true; count_clock(); - if (return_on_no_detection) return true; + if (return_on_no_detection) return false; delay(250); } dmd_type = detect_dmd(); digitalWrite(LED_BUILTIN, LOW); locked_in = false; - + if (dmd_type == DMD_UNKNOWN) { if (return_on_no_detection) { return false; From 99e2d0cbb4b367183bf4adffc1ad36fbf3c16ab3 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Fri, 19 Jun 2026 23:56:53 +0200 Subject: [PATCH 7/7] fix the delay and use defines --- src/dmdreader.cpp | 8 +++++--- src/dmdreader.h | 4 ++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index e04bbd08..f46f9529 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -309,7 +309,7 @@ uint64_t read_clock_count() { for (int i = 0; i < 3; i++) { pio_sm_exec(dmd_pio, *sms[i], pio_encode_in(pio_x, 32)); - counts[i] = (~pio_sm_get(dmd_pio, *sms[i])) * 4; + counts[i] = (~pio_sm_get(dmd_pio, *sms[i])) * COUNT_MULTIPLIER; pio_sm_set_enabled(dmd_pio, *sms[i], false); pio_remove_program_and_unclaim_sm(&dmd_count_signal_program, dmd_pio, *sms[i], *offsets[i]); @@ -950,7 +950,7 @@ bool dmdreader_init(bool return_on_no_detection) { locked_in = true; count_clock(); if (return_on_no_detection) return false; - delay(250); + delay(COUNT_CLOCK_DELAY); } dmd_type = detect_dmd(); @@ -961,10 +961,12 @@ bool dmdreader_init(bool return_on_no_detection) { if (return_on_no_detection) { return false; } else { - delay(750); + delay(RETRIGGER_DELAY / 2); } } + delay(RETRIGGER_DELAY / 2); + } while (dmd_type == DMD_UNKNOWN); // Delay is still needed when blink gets removed above. diff --git a/src/dmdreader.h b/src/dmdreader.h index b17944e8..8acb6b5f 100644 --- a/src/dmdreader.h +++ b/src/dmdreader.h @@ -4,6 +4,10 @@ #include +#define COUNT_CLOCK_DELAY 250 +#define RETRIGGER_DELAY 750 +#define COUNT_MULTIPLIER 1000 / COUNT_CLOCK_DELAY + enum class Color : uint8_t { DMD_ORANGE, DMD_RED,