Mercurial > ~darius > hgwebdir.cgi > modulator
comparison modulator.c @ 7:4ad473648949
Copy pulse up in reverse for pulse down.
Copy first pulse for subsequent pulses.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Sun, 16 Feb 2025 10:09:05 +1030 |
parents | 5bed069f0c33 |
children | 0249d0cecac4 |
comparison
equal
deleted
inserted
replaced
6:5bed069f0c33 | 7:4ad473648949 |
---|---|
37 #pragma GCC diagnostic pop | 37 #pragma GCC diagnostic pop |
38 | 38 |
39 #include "dac.pio.h" | 39 #include "dac.pio.h" |
40 | 40 |
41 // https://github.com/howerj/q | 41 // https://github.com/howerj/q |
42 // Modified to be Q20.12 rather than Q16.16 | |
42 #include "q/q.h" | 43 #include "q/q.h" |
43 | 44 |
44 #include "shaped-trap.h" | 45 #include "shaped-trap.h" |
45 | 46 |
46 static int dma_chan; | 47 static int dma_chan; |
81 #define PACTIVE 0x08 | 82 #define PACTIVE 0x08 |
82 | 83 |
83 // Need to add pre/postgate/sense/phase counters | 84 // Need to add pre/postgate/sense/phase counters |
84 unsigned | 85 unsigned |
85 compute_pulse(uint8_t *data, uint8_t *ctrl, unsigned datalen, uint16_t plen, char *code, uint8_t ncode, const uint8_t *shape, uint8_t shapelen, uint8_t codegap, uint8_t slew1, uint8_t slew2, uint8_t dcofs) { | 86 compute_pulse(uint8_t *data, uint8_t *ctrl, unsigned datalen, uint16_t plen, char *code, uint8_t ncode, const uint8_t *shape, uint8_t shapelen, uint8_t codegap, uint8_t slew1, uint8_t slew2, uint8_t dcofs) { |
86 uint32_t shapesamples, nsamples, idx; | 87 uint32_t shapesamples, nsamples, idx, bit1startup, bit1stopup; |
87 q_t dcscale, stepsize; | 88 q_t dcscale, stepsize; |
88 char tmps[20]; | 89 char tmps[20]; |
90 interp_config cfg; | |
91 | |
92 // Setup lane 0 to generate index into shape table | |
93 // Mask start is 0 because we use 8 bit samples | |
94 cfg = interp_default_config(); | |
95 interp_config_set_shift(&cfg, QBITS); | |
96 interp_config_set_mask(&cfg, 0, 32 - QBITS); | |
97 interp_config_set_blend(&cfg, true); | |
98 interp_set_config(interp0, 0, &cfg); | |
99 | |
100 // Setup lane 1 to LERP each sample pair | |
101 cfg = interp_default_config(); | |
102 interp_config_set_shift(&cfg, QBITS - 8); | |
103 interp_config_set_signed(&cfg, false); | |
104 interp_config_set_cross_input(&cfg, true); // unsigned blending | |
105 interp_set_config(interp0, 1, &cfg); | |
106 | |
107 interp0->accum[0] = 0; // Initial offset into shape table | |
108 interp0->base[2] = (uintptr_t)shape; // Start of shape table | |
89 | 109 |
90 dcscale = qdiv(qsub(qint(255), qint(dcofs)), qint(255)); | 110 dcscale = qdiv(qsub(qint(255), qint(dcofs)), qint(255)); |
91 qsprint(dcscale, tmps, sizeof(tmps)); | 111 qsprint(dcscale, tmps, sizeof(tmps)); |
92 printf("dcscale = %s\n", tmps); | 112 printf("dcscale = %s\n", tmps); |
93 | 113 |
125 for (uint16_t i = 0; i < slew1; i++) { | 145 for (uint16_t i = 0; i < slew1; i++) { |
126 data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(i)), qint(slew1))); | 146 data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(i)), qint(slew1))); |
127 ctrl[idx] |= PACTIVE; | 147 ctrl[idx] |= PACTIVE; |
128 } | 148 } |
129 for (uint16_t c = 0; c < ncode; c++) { | 149 for (uint16_t c = 0; c < ncode; c++) { |
150 if (c == 0) | |
151 bit1startup = idx; | |
152 | |
130 uint ctrltmp = PACTIVE; | 153 uint ctrltmp = PACTIVE; |
131 if (code[c] == '0') | 154 if (code[c] == '0') |
132 ctrltmp |= PHINV; | 155 ctrltmp |= PHINV; |
133 | 156 |
134 // Pulse up | 157 // Pulse up |
135 for (uint16_t i = 0; i < shapesamples; i++) { | 158 for (uint16_t i = 0; i < shapesamples; i++) { |
136 data[idx++] = dcofs + qtoi(qmul(qint(shape[qtoi(qdiv(qint(i), stepsize))]), dcscale)); | 159 if (c == 0) |
160 data[idx++] = dcofs + qtoi(qmul(qint(shape[qtoi(qdiv(qint(i), stepsize))]), dcscale)); | |
161 else | |
162 // Already done it before, just copy the previous instance | |
163 data[idx++] = data[bit1startup + i]; | |
137 ctrl[idx] = ctrltmp; | 164 ctrl[idx] = ctrltmp; |
138 } | 165 } |
166 if (c == 0) | |
167 bit1stopup = idx - 1; | |
139 // Pulse down | 168 // Pulse down |
169 // Since the pulse is symmetrical just copy the up slope in reverse | |
140 for (uint16_t i = 0; i < shapesamples; i++) { | 170 for (uint16_t i = 0; i < shapesamples; i++) { |
141 data[idx++] = dcofs + qtoi(qmul(qint(shape[qtoi(qdiv(qint(shapesamples - i - 1), stepsize))]), dcscale)); | 171 data[idx++] = data[bit1stopup - i]; |
142 // Could replace this with a separate loop to poke it into place | 172 // Could replace this with a separate loop to poke it into place |
143 // Similarly for TR switch when implemented | 173 // Similarly for TR switch when implemented |
144 if (i == 0 && c == 0) | 174 if (i == 0 && c == 0) |
145 ctrl[idx] = ctrltmp | SENSE; | 175 ctrl[idx] = ctrltmp | SENSE; |
146 else | 176 else |
223 timer_hw->dbgpause = 0; | 253 timer_hw->dbgpause = 0; |
224 | 254 |
225 gpio_init(PICO_DEFAULT_LED_PIN); | 255 gpio_init(PICO_DEFAULT_LED_PIN); |
226 gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); | 256 gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); |
227 | 257 |
228 interp_test(pulse_data, shaped_trap); | 258 //interp_test(pulse_data, shaped_trap); |
229 | 259 |
230 uint32_t idx; | 260 uint32_t idx; |
231 uint16_t plen = 4000; | 261 uint16_t plen = 4000; |
232 char *code = "1110010"; | 262 char *code = "1110010"; |
233 //char *code = "10"; | 263 //char *code = "10"; |