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";