-
Notifications
You must be signed in to change notification settings - Fork 0
Data East / Sega support #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5f3739c
4d5164f
98e8464
96cc003
7b72902
25953e9
4820b44
34becda
2a95c7f
0a63d67
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| .define DE 7 | ||
| .define RDATA 6 | ||
| .define RCLK 5 | ||
| .define COLLAT 4 | ||
| .define DOTCLK 3 | ||
| .define SDATA 2 | ||
|
|
||
|
|
||
| .program dmd_reader_desega | ||
|
|
||
| ; Send using an external clock on the SPI interface | ||
|
|
||
| ; initialize y with 4096 = number of pixels (128x32) | ||
| set x, 1 | ||
| in x, 1 | ||
| in null, 13 | ||
| mov y, isr | ||
|
|
||
| .wrap_target | ||
|
|
||
| mov x, y ; load number of pixels | ||
| mov isr, null ; reset shift counter | ||
|
|
||
| irq clear 4 | ||
| wait irq 4 | ||
|
|
||
|
|
||
| ; this is the loop for the most significant bit | ||
| dotloop1: | ||
| wait 0 gpio DOTCLK ; falling edge | ||
| wait 1 gpio DOTCLK ; raising edge | ||
| in null 2 ; padding | ||
| in pins 1 ; read pin data | ||
| in null 1 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment "right padding" |
||
| jmp x-- dotloop1 | ||
|
|
||
| mov x, y ; load number of pixels | ||
| mov isr, null ; reset shift counter | ||
|
|
||
| ; There's an empty line between LSB and HSB plane | ||
| wait 0 gpio RCLK | ||
| wait 1 gpio RCLK | ||
|
|
||
| ; this is the loop for the least significant bit | ||
| ; in this loop, the bit value is multipled by 2 by shifting it one bit | ||
| dotloop2: | ||
| wait 0 gpio DOTCLK ; falling edge | ||
| wait 1 gpio DOTCLK ; raising edge | ||
| in null 3 ; padding | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| in pins 1 ; read pin data | ||
| jmp x-- dotloop2 | ||
|
|
||
|
|
||
| .wrap | ||
|
|
||
|
|
||
| .program dmd_framedetect_desega | ||
|
|
||
| .wrap_target | ||
|
|
||
| ; Data East/Sega frame start detection | ||
| ; ~7.86µs is the longest state in which DE can be low without it being a new frame | ||
| ; Each nop [31] = 32 cycles = 256 ns @125 MHz | ||
| ; We go with 10 µs to be safe and confirm the start of a new frame, which is 256ns * 39 = 9.98 µs | ||
| wait_low: | ||
| wait 0 gpio DE ; Wait for DE to go low | ||
|
|
||
| set x, 20 ; Use x as storage for 20 iterations | ||
|
|
||
| delay_loop: | ||
| nop [31] | ||
| nop [31] | ||
| 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 | ||
| irq 4 ; Pin remained low long enough → trigger IRQ | ||
|
|
||
| wait 1 gpio DE ; Wait again for it to go high before restarting cycle | ||
| jmp wait_low ; went high, time to go back to wait_low | ||
|
|
||
| .wrap | ||
|
|
||
|
|
||
| % c-sdk { | ||
| static inline void dmd_reader_desega_program_init(PIO pio, uint sm, uint offset) { | ||
| pio_sm_config c = dmd_reader_desega_program_get_default_config(offset); | ||
|
|
||
| // Set the IN pin, we don't use any other | ||
| sm_config_set_in_pins(&c, 2); // SDATA | ||
|
|
||
| // Set the pin direction at the PIO | ||
| pio_sm_set_consecutive_pindirs(pio, sm, 5, 1, false); // RCLK | ||
| pio_sm_set_consecutive_pindirs(pio, sm, 2, 2, false); // SDATA, DOTCLK | ||
|
|
||
| // Connect these GPIOs to this PIO block | ||
| pio_gpio_init(pio, 5); // RCLK | ||
| pio_gpio_init(pio, 3); // DOTCLK | ||
| pio_gpio_init(pio, 2); // SDATA | ||
|
|
||
| // Shifting to left matches the customary MSB-first ordering of SPI. | ||
| sm_config_set_in_shift( | ||
| &c, | ||
| false, // Shift-to-right = false | ||
| true, // Autopull enabled | ||
| 32 // Autopull threshold | ||
| ); | ||
|
|
||
| // We only send, so disable the TX FIFO to make the RX FIFO deeper. | ||
| sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX); | ||
|
|
||
| // Load our configuration, do not yet start the program | ||
| pio_sm_init(pio, sm, offset, &c); | ||
| } | ||
| %} | ||
|
|
||
| % c-sdk { | ||
| static inline void dmd_framedetect_desega_program_init(PIO pio, uint sm, uint offset) { | ||
| pio_sm_config c = dmd_framedetect_desega_program_get_default_config(offset); | ||
|
|
||
| // Set the pin direction at the PIO | ||
| pio_sm_set_consecutive_pindirs(pio, sm, 7, 1, false); // DE | ||
|
|
||
| // Connect this GPIO to this PIO block | ||
| pio_gpio_init(pio, 7); // DE | ||
|
|
||
| // Load our configuration, do not yet start the program | ||
| pio_sm_init(pio, sm, offset, &c); | ||
| } | ||
| %} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,7 @@ | |
| #include "dmd_interface_whitestar.pio.h" | ||
| #include "dmd_interface_spike.pio.h" | ||
| #include "dmd_interface_sam.pio.h" | ||
| #include "dmd_interface_desega.pio.h" | ||
|
|
||
| // should CRC32 checksum be caculated and sent with each frame | ||
| #define USE_CRC | ||
|
|
@@ -93,6 +94,7 @@ typedef struct __attribute__((__packed__)) block_pix_crc_header_t | |
| #define DMD_WHITESTAR 2 | ||
| #define DMD_SPIKE1 3 | ||
| #define DMD_SAM 4 | ||
| #define DMD_DESEGA 5 | ||
|
|
||
| // Line oversampling | ||
| #define LINEOVERSAMPLING_NONE 1 | ||
|
|
@@ -363,30 +365,38 @@ int detect_dmd() | |
|
|
||
| if ((dotclk > 450000) && (dotclk < 550000) && | ||
| (de > 3800) && (de < 4000) && | ||
| (rdata > 115) && (rdata < 130)) | ||
| { | ||
| (rdata > 115) && (rdata < 130)) { | ||
| printf("WPC detected\n"); | ||
| spi_notify_onoff(DMD_WPC); | ||
| return DMD_WPC; | ||
|
|
||
| } else if ((dotclk > 640000) && (dotclk < 700000) && | ||
| (de > 5000) && (de < 5300) && | ||
| (rdata > 70) && (rdata < 85)) | ||
| { | ||
| (rdata > 70) && (rdata < 85)) { | ||
| printf("Stern Whitestar detected\n"); | ||
| spi_notify_onoff(DMD_WHITESTAR); | ||
| return DMD_WHITESTAR; | ||
|
|
||
| } else if ((dotclk > 1000000) && (dotclk < 1100000) && | ||
| (de > 8000) && (de < 8400) && | ||
| (rdata > 240) && (rdata < 270)) { | ||
| printf("Stern Spike1 detected\n"); | ||
| spi_notify_onoff(DMD_SPIKE1); | ||
| return DMD_SPIKE1; | ||
|
|
||
| } else if ((dotclk > 1000000) && (dotclk < 1100000) && | ||
| (de > 8000) && (de < 8400) && | ||
| (rdata > 60) && (rdata < 70)) { | ||
| printf("Stern SAM detected\n"); | ||
| spi_notify_onoff(DMD_SAM); | ||
| return DMD_SAM; | ||
|
|
||
| } else if ((dotclk > 640000) && (dotclk < 700000) && | ||
| (de > 5000) && (de < 5300) && | ||
| (rdata > 3800) && (rdata < 4000)) { | ||
| printf("Data East/Sega detected\n"); | ||
| spi_notify_onoff(DMD_DESEGA); | ||
| return DMD_DESEGA; | ||
| } | ||
|
|
||
| spi_notify_onoff(1); | ||
|
|
@@ -584,11 +594,11 @@ bool init() | |
|
|
||
| lcd_width = 128; | ||
| lcd_height = 32; | ||
| lcd_bitsperpixel = 2; | ||
| lcd_bitsperpixel = 2; // Whitestar is 2bpp | ||
| lcd_pixelsperbyte = 8 / lcd_bitsperpixel; | ||
| lcd_planesperframe = 2; // in Whitestar, there's a MSB and a LSB plane | ||
| lcd_lineoversampling = LINEOVERSAMPLING_WHITESTAR; // in Whitestar each line is sent twice | ||
| lcd_mergeplanes = MERGEPLANES_ADDSHIFT; // required for correct 2bpp merge | ||
| //lcd_mergeplanes = MERGEPLANES_ADDSHIFT; // required for correct 2bpp merge | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is that removed? |
||
| } else if (dmd_type == DMD_SPIKE1) { | ||
| dmd_pio = pio0; | ||
| offset = pio_add_program(dmd_pio, &dmd_reader_spike_program); | ||
|
|
@@ -634,6 +644,28 @@ bool init() | |
| lcd_planesperframe = 1; // in SAM there is one planes | ||
| lcd_lineoversampling = LINEOVERSAMPLING_SAM; // with 4x line oversampling | ||
| lcd_mergeplanes = MERGEPLANES_ADD; | ||
| } else if (dmd_type == DMD_DESEGA) { | ||
| dmd_pio = pio0; | ||
| offset = pio_add_program(dmd_pio, &dmd_reader_desega_program); | ||
| dmd_sm = pio_claim_unused_sm(dmd_pio, true); | ||
| dmd_reader_desega_program_init(dmd_pio, dmd_sm, offset); | ||
| printf("Data East/Sega DMD reader initialized\n"); | ||
|
|
||
| // The framedetect program just runs and detects the beginning of a new frame | ||
| frame_pio = pio0; | ||
| offset = pio_add_program(frame_pio, &dmd_framedetect_desega_program); | ||
| frame_sm = pio_claim_unused_sm(frame_pio, true); | ||
| dmd_framedetect_desega_program_init(frame_pio, frame_sm, offset); | ||
| pio_sm_set_enabled(frame_pio, frame_sm, true); | ||
| printf("Data East/Sega frame detection initialized\n"); | ||
|
|
||
| lcd_width = 128; | ||
| lcd_height = 32; | ||
| lcd_bitsperpixel = 2; // Data East/ Sega is 2bpp | ||
| lcd_pixelsperbyte = 8 / lcd_bitsperpixel; | ||
| lcd_planesperframe = 2; // in DE/Sega, there's a MSB and a LSB plane | ||
| lcd_lineoversampling = LINEOVERSAMPLING_WHITESTAR; // in DE/Sega each line is sent twice | ||
| lcd_mergeplanes = MERGEPLANES_ADDSHIFT; // required for correct 2bpp merge | ||
| } else { | ||
| printf("Unknown DMD type, aborting\n"); | ||
| return false; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this line