aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-05-10 22:32:21 +0200
committerBad Diode <bd@badd10de.dev>2024-05-10 22:32:21 +0200
commitf2a20887b57ccad5286ee22d0fe6f8342df1750a (patch)
tree5b62775d096394a78cc3eff85e462f8b6f31a60a /src
parent3240295fb846dfb0cf95ceef399b3ef9f085b2bd (diff)
downloadstepper-f2a20887b57ccad5286ee22d0fe6f8342df1750a.tar.gz
stepper-f2a20887b57ccad5286ee22d0fe6f8342df1750a.zip
Add a more accurate LSDJ sync method, including SO out
Diffstat (limited to 'src')
-rw-r--r--src/sequencer.c116
-rw-r--r--src/settings.h2
2 files changed, 50 insertions, 68 deletions
diff --git a/src/sequencer.c b/src/sequencer.c
index 9e39cc7..4f57ec8 100644
--- a/src/sequencer.c
+++ b/src/sequencer.c
@@ -35,30 +35,6 @@ gate_set(u8 sc, u8 so) {
35 | SIO_SI(0); 35 | SIO_SI(0);
36} 36}
37 37
38int pulses_sent = 0;
39int gate_status = 0;
40
41void
42gate_lsdj(void) {
43 gate_status ^= 1;
44 if (pulses_sent >= 7) {
45 gate_set(0, 0);
46 return;
47 }
48 if (gate_status == 1) {
49 gate_set(0, 0);
50 } else {
51 pulses_sent++;
52 gate_set(1, 0);
53 }
54 int n_ticks = -80 / 8 / 2; // 5ms
55 irs_set(IRQ_TIMER_3, gate_lsdj);
56 TIMER_DATA_3 = n_ticks;
57 TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3;
58}
59
60// TODO: LSDJ sync pulse?
61
62//void 38//void
63//gate_on(void) { 39//gate_on(void) {
64// // SYNC24 NOTES 40// // SYNC24 NOTES
@@ -106,60 +82,56 @@ gate_lsdj(void) {
106// // } 82// // }
107//} 83//}
108 84
109bool first_pulse = true; 85int pulse_count = 0;
110int so_status = 1; 86int pulse_value = 0;
111 87int gate_status = 0;
112void
113lsdj_toggle(void) {
114 gate_status ^= 1;
115 if (pulses_sent >= 7) {
116 TIMER_CTRL_3 = 0;
117 gate_set(1, so_status);
118 return;
119 }
120 if (gate_status == 1) {
121 gate_set(1, so_status);
122 } else {
123 pulses_sent++;
124 gate_set(0, so_status);
125 }
126 TIMER_CTRL_3 = 0;
127 // int n_ticks = -80 / 8 / 2; // 5ms
128 // irs_set(IRQ_TIMER_3, lsdj_toggle);
129 // TIMER_DATA_3 = n_ticks;
130 // TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3;
131 int n_ticks = -9; // 122/2 = 61us; 61 / 3.8 = 16
132 irs_set(IRQ_TIMER_3, lsdj_toggle);
133 TIMER_DATA_3 = n_ticks;
134 TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_1;
135}
136 88
137void 89void
138lsdj_pulse(void) { 90send_pulse(void) {
139 // LSDJ expects a pulse train on the SC pin (active low?). For the song 91 // LSDJ expects a pulse train on the SC pin (active low). For the song
140 // start, the first pulse and until the start of the second one it should 92 // start, the first pulse indicates the starting row, for example, for row
141 // set SO to low as follows: 93 // 0x06:
142 // 94 //
143 // CLK (SC) --_-_-_-_-_-_-_-_----------------_-_-_-_-_-_-_-_---------------- 95 // CLK (SC) --_-_-_-_-_-_-_-_----------------_-_-_-_-_-_-_-_----------------
144 // OUT (SO) --_______________________________------------------------------- 96 // OUT (SO) --__________----_________________-------------------------------
97 //
98 // Additionally, in LSDJ sync mode, at the start of each bar, SO should send
99 // the 0x01 byte (active low).
145 // 100 //
146 // Additionally, in LSDJ sync mode, SO will go low at the start of each bar. 101 // CLK (SC) --_-_-_-_-_-_-_-_----------------_-_-_-_-_-_-_-_----------------
102 // OUT (SO) --____________--_________________-------------------------------
147 // 103 //
148 // The width of the pulse is approximately 915-916us (122us per pulse at 50% 104 // The width of the pulse is approximately 915-916us (122us per pulse at 50%
149 // duty cycle of 61us). This sync method is based on sync24, so it should 105 // duty cycle of 61us). This sync method is based on sync24, so it should
150 // receive 6 pulses each 1/16th step (96 pulses in a 16 step sequence). 106 // receive 6 pulses each 1/16th step (96 pulses in a 16 step sequence).
151 if (first_pulse) { 107 TIMER_CTRL_3 = 0;
152 first_pulse = false; 108 gate_set(gate_status, (pulse_value >> (7 - pulse_count)) & 0x1);
153 so_status = 0; 109 gate_status ^= 1;
110 if (gate_status == 0) {
111 pulse_count++;
112 }
113 if (pulse_count <= 7) {
114 int n_ticks = -9; // 122/2 = 61us; 61 / 3.8 = 16
115 irs_set(IRQ_TIMER_3, send_pulse);
116 TIMER_DATA_3 = n_ticks;
117 TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_1;
154 } else { 118 } else {
155 so_status = 1; 119 pulse_value = 0;
120 pulse_count = 0;
156 } 121 }
122}
123
124void
125send_lsdj_pulse(u8 out_byte) {
126 pulse_value = out_byte;
127
128 // Reset timer.
157 TIMER_DATA_3 = 0; 129 TIMER_DATA_3 = 0;
158 pulses_sent = 0; 130 pulse_value = out_byte;
131 pulse_count = 0;
159 gate_status = 0; 132 gate_status = 0;
160 gate_set(0, so_status);
161 int n_ticks = -9; // 122/2 = 61us; 61 / 3.8 = 16 133 int n_ticks = -9; // 122/2 = 61us; 61 / 3.8 = 16
162 irs_set(IRQ_TIMER_3, lsdj_toggle); 134 irs_set(IRQ_TIMER_3, send_pulse);
163 TIMER_DATA_3 = n_ticks; 135 TIMER_DATA_3 = n_ticks;
164 TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_1; 136 TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_1;
165} 137}
@@ -607,10 +579,19 @@ sequencer_tick(void) {
607 // case SYNC_OUT_LINK_AUDIO_2BPQ: { if (sync_ticks++ % 48 == 0) { gate_on(); audio_sync_click = true; } } break; 579 // case SYNC_OUT_LINK_AUDIO_2BPQ: { if (sync_ticks++ % 48 == 0) { gate_on(); audio_sync_click = true; } } break;
608 // default: break; 580 // default: break;
609 // } 581 // }
582 // TODO: case sync_out_lsdj
583 if (sync_ticks++ % 4 == 0) {
584 u8 val = 0xff;
585 if ((sync_ticks - 1) == 0) {
586 val = 7; // DEBUG: Depends on pattern + bank.
587 } else if ((sync_ticks - 1) % 384 == 0) {
588 val = 253;
589 }
590 send_lsdj_pulse(val);
591 }
610 if (nseq_ticks++ == 0) { 592 if (nseq_ticks++ == 0) {
611 play_step(); 593 play_step();
612 } 594 }
613 if (sync_ticks++ % 4 == 0) { lsdj_pulse(); }
614 if (nseq_ticks == 24) { 595 if (nseq_ticks == 24) {
615 nseq_ticks = 0; 596 nseq_ticks = 0;
616 } 597 }
@@ -800,10 +781,9 @@ stop_sound(void) {
800 781
801void 782void
802reset_sequencer(void) { 783reset_sequencer(void) {
803 first_pulse = true; 784 TIMER_CTRL_3 = 0;
804 so_status = 1; 785 gate_set(1, 1);
805 gate_status = 0; 786 gate_status = 0;
806 pulses_sent = 0;
807 step_counter = 0; 787 step_counter = 0;
808 nseq_ticks = 0; 788 nseq_ticks = 0;
809 sync_ticks = 0; 789 sync_ticks = 0;
diff --git a/src/settings.h b/src/settings.h
index bbfdfd2..73da88f 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -28,6 +28,7 @@ typedef enum SyncSetting {
28 SYNC_OUT_LINK_AUDIO_6BPQ, 28 SYNC_OUT_LINK_AUDIO_6BPQ,
29 SYNC_OUT_LINK_AUDIO_4BPQ, 29 SYNC_OUT_LINK_AUDIO_4BPQ,
30 SYNC_OUT_LINK_AUDIO_2BPQ, 30 SYNC_OUT_LINK_AUDIO_2BPQ,
31 SYNC_OUT_LSDJ,
31 SYNC_IN_LINK_96BPQ, 32 SYNC_IN_LINK_96BPQ,
32 SYNC_IN_LINK_48BPQ, 33 SYNC_IN_LINK_48BPQ,
33 SYNC_IN_LINK_24BPQ, 34 SYNC_IN_LINK_24BPQ,
@@ -54,6 +55,7 @@ char * sync_setting_str[] = {
54 "LINK+AUDIO OUT (6BPQ)", 55 "LINK+AUDIO OUT (6BPQ)",
55 "LINK+AUDIO OUT (4BPQ)", 56 "LINK+AUDIO OUT (4BPQ)",
56 "LINK+AUDIO OUT (2BPQ)", 57 "LINK+AUDIO OUT (2BPQ)",
58 "LSDJ OUT",
57 "LINK IN (96BPQ)", 59 "LINK IN (96BPQ)",
58 "LINK IN (48BPQ)", 60 "LINK IN (48BPQ)",
59 "LINK IN (24BPQ)", 61 "LINK IN (24BPQ)",