Mercurial > ~darius > hgwebdir.cgi > modulator
annotate modulator.c @ 30:92fdf2ef995d default tip
Use 32 bit rather than 16 bit ints for loop vars.
No risk of overflow and is actually faster.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Thu, 27 Feb 2025 15:24:17 +1030 |
parents | babdb5376356 |
children |
rev | line source |
---|---|
0
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
1 /****************************************************************** |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
2 ******************************************************************* |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
3 ** |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
4 ** This is proprietary unpublished source code, property |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
5 ** of Genesis Software. Use or disclosure without prior |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
6 ** agreement is expressly prohibited. |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
7 ** |
16 | 8 ** Copyright (c) 2025 Genesis Software, all rights reserved. |
0
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
9 ** |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
10 ******************************************************************* |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
11 ******************************************************************/ |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
12 |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
13 /* |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
14 ** MODULATOR.C |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
15 ** |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
16 ** Create modulation shape |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
17 ** |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
18 */ |
26 | 19 |
20 // Define this to use trigger.pio otherwise | |
21 // the code manually triggers from pwm_wrap | |
22 #define WITH_TRIGGER | |
0
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
23 |
5 | 24 #include <stdio.h> |
25 #include <string.h> | |
26 | |
27 #pragma GCC diagnostic push | |
28 #pragma GCC diagnostic ignored "-Wtype-limits" | |
29 #pragma GCC diagnostic ignored "-Wsign-compare" | |
0
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
30 #include "pico/stdlib.h" |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
31 #include "hardware/clocks.h" |
3
b10097c3383d
DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents:
2
diff
changeset
|
32 #include "hardware/dma.h" |
5 | 33 #include "hardware/interp.h" |
3
b10097c3383d
DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents:
2
diff
changeset
|
34 #include "hardware/irq.h" |
5 | 35 #include "hardware/pll.h" |
0
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
36 #include "hardware/pio.h" |
5 | 37 #include "hardware/pwm.h" |
38 #include "hardware/structs/pll.h" | |
39 #include "hardware/structs/clocks.h" | |
40 #pragma GCC diagnostic pop | |
0
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
41 |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
42 #include "dac.pio.h" |
16 | 43 #include "ctrl.pio.h" |
9 | 44 #include "trigger.pio.h" |
0
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
45 |
5 | 46 // https://github.com/howerj/q |
7
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
47 // Modified to be Q20.12 rather than Q16.16 |
5 | 48 #include "q/q.h" |
0
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
49 |
5 | 50 #include "shaped-trap.h" |
3
b10097c3383d
DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents:
2
diff
changeset
|
51 |
11
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
52 // Base of DAC pins |
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
53 #define DACOUT_GPIO 7 |
16 | 54 // Base of ctrl pins |
55 #define CTRLOUT_GPIO 16 | |
11
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
56 // PWM output pin |
24
c7845db23ab2
Add sideset for trigger output.
Daniel O'Connor <darius@dons.net.au>
parents:
23
diff
changeset
|
57 #define TRIGOUT_GPIO 22 |
11
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
58 // PIO SM trigger input pin (connected to above for testing) |
24
c7845db23ab2
Add sideset for trigger output.
Daniel O'Connor <darius@dons.net.au>
parents:
23
diff
changeset
|
59 // Also outputs trigger on next pin |
11
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
60 #define TRIGIN_GPIO 27 |
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
61 |
9 | 62 // Pulse control bits |
16 | 63 #define PACTIVE 0x01 |
64 #define PHINV 0x02 | |
65 #define SENSE1 0x04 | |
66 #define SENSE2 0x08 | |
67 #define GATE 0x10 | |
68 #define TRSW 0x20 | |
69 | |
70 // Pulse shape data | |
71 uint8_t pulse_data[65536] __attribute__((aligned(4))); | |
72 // Pulse control data | |
73 uint8_t pulse_ctrl[65536] __attribute__((aligned(4))); | |
28
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
74 // DMA transfer size for above |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
75 unsigned transfercount; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
76 |
16 | 77 // PWM slice for PRF timer |
78 unsigned slice_num = 0; | |
79 | |
80 // PIO for pulse generation | |
81 PIO pulse_pio = pio0; | |
9 | 82 |
10
98880b18bcc1
Reset DAC PIO and use force trigger to do manual trigger.
Daniel O'Connor <darius@dons.net.au>
parents:
9
diff
changeset
|
83 // DMA channel to feed DAC PIO |
16 | 84 static int dac_dma_chan; |
10
98880b18bcc1
Reset DAC PIO and use force trigger to do manual trigger.
Daniel O'Connor <darius@dons.net.au>
parents:
9
diff
changeset
|
85 // DAC SM |
16 | 86 uint dac_sm; |
10
98880b18bcc1
Reset DAC PIO and use force trigger to do manual trigger.
Daniel O'Connor <darius@dons.net.au>
parents:
9
diff
changeset
|
87 // Instruction offset for DAC PIO program |
16 | 88 uint dac_pio_sm_offset; |
23
3c713073dd0c
Remove debug prints and #ifdef now the control code works.
Daniel O'Connor <darius@dons.net.au>
parents:
20
diff
changeset
|
89 |
16 | 90 // DMA channel to feed ctrl PIO |
91 static int ctrl_dma_chan; | |
92 // Ctrl SM | |
93 uint ctrl_sm; | |
94 // Instruction offset for ctrl PIO program | |
95 uint ctrl_pio_sm_offset; | |
96 | |
28
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
97 // Trigger SM |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
98 uint trigger_sm; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
99 |
9 | 100 /* |
101 * Use a DMA channel to feed PIO0 SM0 with pulse data. | |
102 * Each DMA transfer is a single pulse. | |
103 * | |
104 * The PIO state machine waits to be triggered before starting | |
105 * so we can use another state machine to look for the trigger edge. | |
106 * | |
107 * When the DMA is done the IRQ handler will configure it for the next | |
108 * pulse (or not if it should stop). ie reset the PIO state machine | |
109 * back to waiting for an edge and re-arm the DMA. | |
110 */ | |
3
b10097c3383d
DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents:
2
diff
changeset
|
111 void |
b10097c3383d
DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents:
2
diff
changeset
|
112 dma_handler(void) { |
28
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
113 uint32_t tmp; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
114 |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
115 if (!dma_channel_get_irq0_status(dac_dma_chan)) { |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
116 //printf("Mystery DMA IRQ\n"); |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
117 return; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
118 } |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
119 |
11
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
120 // Clear the interrupt request. |
16 | 121 dma_hw->ints0 = 1u << dac_dma_chan; |
28
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
122 if (((tmp = dma_channel_hw_addr(dac_dma_chan)->transfer_count)) != 0) |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
123 printf("DAC transfers %lu\n", tmp); |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
124 if (((tmp = dma_channel_hw_addr(ctrl_dma_chan)->transfer_count)) != 0) |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
125 printf("Ctrl transfers %lu\n", tmp); |
17
a249e4727b01
Move SM reset & DMA reprogramming to DMA IRQ handler, only trigger in PWM IRQ handler.
Daniel O'Connor <darius@dons.net.au>
parents:
16
diff
changeset
|
126 |
16 | 127 // Reset DAQ & ctrl PIO SMs so they are waiting for a trigger |
28
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
128 pio_sm_exec_wait_blocking(pulse_pio, dac_sm, dac_reset_instr(dac_pio_sm_offset)); |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
129 pio_sm_exec_wait_blocking(pulse_pio, ctrl_sm, ctrl_reset_instr(ctrl_pio_sm_offset)); |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
130 |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
131 // Abort any existing DMA |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
132 // Have to do a song and dance for the IRQ generating one due |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
133 // to errata RP2350-E5 |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
134 dma_channel_set_irq0_enabled(dac_dma_chan, false); |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
135 dma_channel_abort(dac_dma_chan); |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
136 dma_channel_acknowledge_irq0(dac_dma_chan); |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
137 dma_channel_set_irq0_enabled(dac_dma_chan, true); |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
138 dma_channel_abort(ctrl_dma_chan); |
11
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
139 |
16 | 140 // Setup next pulse data & ctrl DMA addresses |
28
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
141 dma_channel_set_read_addr(dac_dma_chan, pulse_data, false); |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
142 dma_channel_set_trans_count(dac_dma_chan, transfercount, true); |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
143 |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
144 // Disable and resync/enable DAQ & ctrl PIO SMs so they are waiting for a trigger |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
145 pio_set_sm_mask_enabled(pulse_pio, 1u << dac_sm | 1u << ctrl_sm, false); |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
146 pio_enable_sm_mask_in_sync(pulse_pio, 1u << dac_sm | 1u << ctrl_sm); |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
147 |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
148 // Setup next pulse data & ctrl DMA addresses |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
149 dma_channel_set_read_addr(ctrl_dma_chan, pulse_ctrl, false); |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
150 dma_channel_set_trans_count(ctrl_dma_chan, transfercount, true); |
5 | 151 } |
152 | |
153 void | |
154 pwm_wrap(void) { | |
155 pwm_clear_irq(slice_num); | |
16 | 156 |
18
f1e44afb41a3
WIP with control and DAC in sync and not hanging.
Daniel O'Connor <darius@dons.net.au>
parents:
17
diff
changeset
|
157 #ifndef WITH_TRIGGER |
25
6070d2e66b4c
Cascade IRQs from DAC to control so manual & external trigger are the same.
Daniel O'Connor <darius@dons.net.au>
parents:
24
diff
changeset
|
158 // Manually trigger DAC SM (cleared by SM) |
6070d2e66b4c
Cascade IRQs from DAC to control so manual & external trigger are the same.
Daniel O'Connor <darius@dons.net.au>
parents:
24
diff
changeset
|
159 pulse_pio->irq_force = 1; |
16 | 160 |
161 // 'scope trigger | |
162 gpio_put(2, 1); | |
163 gpio_put(2, 0); | |
23
3c713073dd0c
Remove debug prints and #ifdef now the control code works.
Daniel O'Connor <darius@dons.net.au>
parents:
20
diff
changeset
|
164 #endif |
5 | 165 } |
166 | |
167 // Calculate pulse shape data | |
8
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
168 // TODO: predistortion, proper sense, gate, phase, active, T/R switch |
5 | 169 // Could encode them as bit stream like data but more compact would be |
170 // (say) a list of counts to toggle pins at | |
171 // Need to add pre/postgate/sense/phase counters | |
172 unsigned | |
173 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) { | |
7
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
174 uint32_t shapesamples, nsamples, idx, bit1startup, bit1stopup; |
5 | 175 q_t dcscale, stepsize; |
176 char tmps[20]; | |
7
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
177 interp_config cfg; |
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
178 |
8
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
179 if (ncode == 1) { |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
180 // Number of samples for half of the pulse |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
181 // Do division first so we don't overflow Q16.16 |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
182 shapesamples = qtoi(qmul(qdiv(qint(plen), qint(100)), qint(shapelen / 2))); |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
183 // Number of samples for everything |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
184 // XXX: Need the +1 otherwise slew2 is truncated |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
185 nsamples = shapesamples * 2 + slew1 + slew2 + 1; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
186 } else { |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
187 shapesamples = plen / 2; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
188 nsamples = shapesamples * 2 * ncode + codegap * (ncode - 1) + slew1 + slew2 + 1; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
189 } |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
190 |
29
babdb5376356
Fix interpolator setup.
Daniel O'Connor <darius@dons.net.au>
parents:
28
diff
changeset
|
191 // How far to advance the shape pointer for each sample point |
babdb5376356
Fix interpolator setup.
Daniel O'Connor <darius@dons.net.au>
parents:
28
diff
changeset
|
192 // Needs to be 1 less than the shape length otherwise we overflow |
babdb5376356
Fix interpolator setup.
Daniel O'Connor <darius@dons.net.au>
parents:
28
diff
changeset
|
193 // at the end of the pulse up. |
babdb5376356
Fix interpolator setup.
Daniel O'Connor <darius@dons.net.au>
parents:
28
diff
changeset
|
194 stepsize = qdiv(qint(shapelen - 1), qint(shapesamples)); |
8
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
195 qsprint(stepsize, tmps, sizeof(tmps)); |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
196 printf("shapelen = %d shapesamples = %lu nsamples = %lu stepsize = %s\n", shapelen, shapesamples, nsamples, tmps); |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
197 |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
198 // Check the requested pulse will not overflow given data |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
199 if (nsamples > datalen) { |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
200 printf("Pulse too long (%ld > %u)\n", nsamples, datalen); |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
201 return 0; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
202 } |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
203 // Check it is not too short |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
204 if (shapesamples < 2) { |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
205 printf("Pulse too short (%lu < %d)\n", shapesamples, 2); |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
206 return 0; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
207 } |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
208 |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
209 // Setup interp 0 lane 0 to generate index into shape table |
7
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
210 // Mask start is 0 because we use 8 bit samples |
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
211 cfg = interp_default_config(); |
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
212 interp_config_set_shift(&cfg, QBITS); |
29
babdb5376356
Fix interpolator setup.
Daniel O'Connor <darius@dons.net.au>
parents:
28
diff
changeset
|
213 interp_config_set_mask(&cfg, 0, 32 - QBITS - 1); |
7
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
214 interp_config_set_blend(&cfg, true); |
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
215 interp_set_config(interp0, 0, &cfg); |
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
216 |
8
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
217 // Setup interp 0 lane 1 to LERP each sample pair |
7
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
218 cfg = interp_default_config(); |
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
219 interp_config_set_shift(&cfg, QBITS - 8); |
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
220 interp_config_set_signed(&cfg, false); |
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
221 interp_config_set_cross_input(&cfg, true); // unsigned blending |
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
222 interp_set_config(interp0, 1, &cfg); |
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
223 |
8
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
224 // Setup interp 1 lane 0 to clamp 0-255 |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
225 cfg = interp_default_config(); |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
226 interp_config_set_clamp(&cfg, true); |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
227 interp_config_set_shift(&cfg, 0); |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
228 interp_config_set_mask(&cfg, 0, 8); |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
229 interp_config_set_signed(&cfg, false); |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
230 interp_set_config(interp1, 0, &cfg); |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
231 interp1->base[0] = 0; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
232 interp1->base[1] = 255; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
233 |
7
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
234 interp0->accum[0] = 0; // Initial offset into shape table |
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
235 interp0->base[2] = (uintptr_t)shape; // Start of shape table |
5 | 236 |
8
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
237 dcscale = qdiv(qsub(qint(256), qint(dcofs)), qint(255)); |
5 | 238 qsprint(dcscale, tmps, sizeof(tmps)); |
239 printf("dcscale = %s\n", tmps); | |
240 | |
16 | 241 memset(pulse_data, 0, datalen); |
242 memset(pulse_ctrl, 0, datalen); | |
5 | 243 idx = 0; |
28
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
244 #if 0 |
30
92fdf2ef995d
Use 32 bit rather than 16 bit ints for loop vars.
Daniel O'Connor <darius@dons.net.au>
parents:
29
diff
changeset
|
245 for (uint32_t i = 0; i < 255 * 200; i++) |
28
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
246 data[idx++] = i / 200; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
247 |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
248 printf("Dummy done\n"); |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
249 return idx; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
250 #endif |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
251 #if 0 |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
252 data[idx++] = 255; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
253 data[idx++] = 0; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
254 data[idx++] = 0; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
255 data[idx++] = 0; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
256 data[idx++] = 0; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
257 data[idx++] = 128; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
258 data[idx++] = 128; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
259 data[idx++] = 0; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
260 data[idx++] = 0; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
261 data[idx++] = 0; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
262 data[idx++] = 0; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
263 data[idx++] = 0; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
264 data[idx++] = 255; |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
265 #endif |
5 | 266 |
267 // Up slew | |
30
92fdf2ef995d
Use 32 bit rather than 16 bit ints for loop vars.
Daniel O'Connor <darius@dons.net.au>
parents:
29
diff
changeset
|
268 for (uint32_t i = 0; i < slew1; i++) { |
5 | 269 data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(i)), qint(slew1))); |
270 } | |
30
92fdf2ef995d
Use 32 bit rather than 16 bit ints for loop vars.
Daniel O'Connor <darius@dons.net.au>
parents:
29
diff
changeset
|
271 for (uint32_t c = 0; c < ncode; c++) { |
7
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
272 if (c == 0) |
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
273 bit1startup = idx; |
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
274 |
5 | 275 uint ctrltmp = PACTIVE; |
276 if (code[c] == '0') | |
277 ctrltmp |= PHINV; | |
278 | |
279 // Pulse up | |
8
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
280 if (c == 0) { |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
281 interp0->accum[0] = 0; // Initial offset into shape table |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
282 interp0->base[2] = (uintptr_t)shape; // Start of shape table |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
283 } |
30
92fdf2ef995d
Use 32 bit rather than 16 bit ints for loop vars.
Daniel O'Connor <darius@dons.net.au>
parents:
29
diff
changeset
|
284 for (uint32_t i = 0; i < shapesamples; i++) { |
19
2e14ccd1338a
Set control data after shape data so it is lined up properly.
Daniel O'Connor <darius@dons.net.au>
parents:
18
diff
changeset
|
285 ctrl[idx] = ctrltmp; |
8
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
286 if (c == 0) { |
29
babdb5376356
Fix interpolator setup.
Daniel O'Connor <darius@dons.net.au>
parents:
28
diff
changeset
|
287 // First code bit |
8
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
288 // Get sample pair |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
289 uint8_t *sample_pair = (uint8_t *) interp0->peek[2]; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
290 // Ask lane 1 for a LERP, using the lane 0 accumulator |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
291 interp0->base[0] = sample_pair[0]; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
292 interp0->base[1] = sample_pair[1]; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
293 uint8_t peek = interp0->peek[1]; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
294 // Apply DC offset scaling & clamp |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
295 interp1->accum[0] = dcofs + qtoi(qmul(qint(peek), dcscale)); |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
296 data[idx++] = interp1->peek[0]; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
297 // Update interpolator for next point |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
298 interp0->add_raw[0] = stepsize; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
299 } else |
7
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
300 // Already done it before, just copy the previous instance |
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
301 data[idx++] = data[bit1startup + i]; |
5 | 302 } |
7
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
303 if (c == 0) |
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
304 bit1stopup = idx - 1; |
29
babdb5376356
Fix interpolator setup.
Daniel O'Connor <darius@dons.net.au>
parents:
28
diff
changeset
|
305 |
5 | 306 // Pulse down |
7
4ad473648949
Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents:
6
diff
changeset
|
307 // Since the pulse is symmetrical just copy the up slope in reverse |
8
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
308 // XXX: if we had asymmetrical predistortion this wouldn't be true |
30
92fdf2ef995d
Use 32 bit rather than 16 bit ints for loop vars.
Daniel O'Connor <darius@dons.net.au>
parents:
29
diff
changeset
|
309 for (uint32_t i = 0; i < shapesamples; i++) { |
5 | 310 // Could replace this with a separate loop to poke it into place |
311 // Similarly for TR switch when implemented | |
312 if (i == 0 && c == 0) | |
16 | 313 ctrl[idx] = ctrltmp | SENSE1; |
5 | 314 else |
315 ctrl[idx] = ctrltmp; | |
19
2e14ccd1338a
Set control data after shape data so it is lined up properly.
Daniel O'Connor <darius@dons.net.au>
parents:
18
diff
changeset
|
316 data[idx++] = data[bit1stopup - i]; |
5 | 317 } |
318 | |
319 // Code gap | |
320 if (c < ncode - 1) | |
30
92fdf2ef995d
Use 32 bit rather than 16 bit ints for loop vars.
Daniel O'Connor <darius@dons.net.au>
parents:
29
diff
changeset
|
321 for (uint32_t i = 0; i < codegap; i++) { |
19
2e14ccd1338a
Set control data after shape data so it is lined up properly.
Daniel O'Connor <darius@dons.net.au>
parents:
18
diff
changeset
|
322 ctrl[idx] = ctrltmp; |
5 | 323 data[idx++] = dcofs; |
324 } | |
325 } | |
326 | |
327 // Down slew | |
30
92fdf2ef995d
Use 32 bit rather than 16 bit ints for loop vars.
Daniel O'Connor <darius@dons.net.au>
parents:
29
diff
changeset
|
328 for (uint32_t i = 0; i < slew2 + 1; i++) { |
5 | 329 data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(slew2 - i)), qint(slew2))); |
330 } | |
11
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
331 |
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
332 data[idx++] = 0; |
16 | 333 ctrl[idx] = 0; |
11
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
334 |
16 | 335 return idx + 1; |
5 | 336 } |
337 | |
0
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
338 int |
3
b10097c3383d
DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents:
2
diff
changeset
|
339 main(void) { |
5 | 340 absolute_time_t then, now; |
341 | |
342 // Set sysclk to 120MHz | |
343 set_sys_clock_khz(120000, true); | |
0
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
344 |
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
345 stdio_init_all(); |
5 | 346 printf("\n\n\nIniting\n"); |
0
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
347 |
5 | 348 // Needed otherwise timer related functions hang under debugging |
349 // https://github.com/raspberrypi/pico-sdk/issues/1152#issuecomment-1418248639 | |
350 timer_hw->dbgpause = 0; | |
351 | |
352 gpio_init(PICO_DEFAULT_LED_PIN); | |
353 gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); | |
9 | 354 gpio_init(2); |
355 gpio_set_dir(2, GPIO_OUT); | |
11
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
356 |
9 | 357 #if 0 |
16 | 358 // GPIO tester to check breadboard wiring |
9 | 359 for (unsigned i = 7; i < 7 + 9; i++) { |
360 printf("GPIO %d\n", i); | |
361 gpio_init(i); | |
362 gpio_set_dir(i, GPIO_OUT); | |
363 printf("on\n"); | |
364 gpio_put(i, 1); | |
365 __breakpoint(); | |
366 printf("off\n"); | |
367 gpio_put(i, 0); | |
368 __breakpoint(); | |
369 } | |
370 #endif | |
5 | 371 |
372 uint32_t idx; | |
8
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
373 uint16_t plen; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
374 char *code; |
9 | 375 if (1) { |
8
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
376 plen = 8000; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
377 code = "1110010"; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
378 } else { |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
379 plen = 53000; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
380 code = "1"; |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
381 } |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
382 |
5 | 383 uint8_t codegap = 4; |
384 uint8_t slew1 = 10; | |
385 uint8_t slew2 = 10; | |
386 uint8_t dcofs = 110; | |
387 then = get_absolute_time(); | |
388 if ((idx = compute_pulse(pulse_data, pulse_ctrl, sizeof(pulse_data), | |
389 plen, code, strlen(code), | |
390 shaped_trap, sizeof(shaped_trap), | |
391 codegap, slew1, slew2, dcofs)) == 0) { | |
392 printf("Failed to compute pulse\n"); | |
393 while (1) | |
394 ; | |
395 } | |
396 now = get_absolute_time(); | |
8
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
397 unsigned long long diff = absolute_time_diff_us(then, now); |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
398 printf("Pulse computation took %lld usec and created %lu samples - %.1f nsec/sample\n", |
0249d0cecac4
Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents:
7
diff
changeset
|
399 diff, idx, (float)diff * 1000.0 / idx); |
28
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
400 transfercount = ((idx + 3) >> 2); |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
401 printf("Using %u transfers\n", transfercount); |
10
98880b18bcc1
Reset DAC PIO and use force trigger to do manual trigger.
Daniel O'Connor <darius@dons.net.au>
parents:
9
diff
changeset
|
402 //__breakpoint(); |
9 | 403 |
11
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
404 // Load the DAC program, and configure a free state machine |
9 | 405 // to run the program. |
16 | 406 dac_pio_sm_offset = pio_add_program(pulse_pio, &dac_program); |
407 if (dac_pio_sm_offset < 0) { | |
408 printf("Unable to load DAC program\n"); | |
409 __breakpoint(); | |
410 } | |
411 dac_sm = pio_claim_unused_sm(pulse_pio, true); | |
9 | 412 // Data is GPIO7 to GPIO14, clock is GPIO15 |
27
e1d8fe3e418a
Run PIOs at 1x with delays and sync.
Daniel O'Connor <darius@dons.net.au>
parents:
26
diff
changeset
|
413 // Clock divisor of 1 but the PIO has delays so it runs at 60MHz |
e1d8fe3e418a
Run PIOs at 1x with delays and sync.
Daniel O'Connor <darius@dons.net.au>
parents:
26
diff
changeset
|
414 // and generates a 30MHz clock |
e1d8fe3e418a
Run PIOs at 1x with delays and sync.
Daniel O'Connor <darius@dons.net.au>
parents:
26
diff
changeset
|
415 dac_program_init(pulse_pio, dac_sm, dac_pio_sm_offset, DACOUT_GPIO, 1); |
9 | 416 |
417 // Configure a channel to write 32 bits at a time to PIO0 | |
418 // SM0's TX FIFO, paced by the data request signal from that peripheral. | |
16 | 419 dac_dma_chan = dma_claim_unused_channel(true); |
420 dma_channel_config dac_dmac = dma_channel_get_default_config(dac_dma_chan); | |
421 channel_config_set_transfer_data_size(&dac_dmac, DMA_SIZE_32); | |
422 channel_config_set_read_increment(&dac_dmac, true); | |
423 channel_config_set_dreq(&dac_dmac, PIO_DREQ_NUM(pulse_pio, dac_sm, true)); | |
9 | 424 |
425 dma_channel_configure( | |
16 | 426 dac_dma_chan, |
427 &dac_dmac, | |
428 &pulse_pio->txf[dac_sm], // Write address | |
429 pulse_data, // Pulse data | |
28
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
430 transfercount, // Transfer count |
18
f1e44afb41a3
WIP with control and DAC in sync and not hanging.
Daniel O'Connor <darius@dons.net.au>
parents:
17
diff
changeset
|
431 true // Start transfer |
9 | 432 ); |
433 | |
434 // Tell the DMA to raise IRQ line 0 when the channel finishes a block | |
16 | 435 dma_channel_set_irq0_enabled(dac_dma_chan, true); |
9 | 436 |
437 // Configure the processor to run dma_handler() when DMA IRQ 0 is asserted | |
438 irq_set_exclusive_handler(DMA_IRQ_0, dma_handler); | |
439 irq_set_enabled(DMA_IRQ_0, true); | |
440 | |
16 | 441 // Load the ctrl program, and configure a free state machine |
442 // to run the program. | |
443 ctrl_pio_sm_offset = pio_add_program(pulse_pio, &ctrl_program); | |
444 if (ctrl_pio_sm_offset < 0) { | |
445 printf("Unable to load ctrl program\n"); | |
446 __breakpoint(); | |
447 } | |
448 ctrl_sm = pio_claim_unused_sm(pulse_pio, true); | |
27
e1d8fe3e418a
Run PIOs at 1x with delays and sync.
Daniel O'Connor <darius@dons.net.au>
parents:
26
diff
changeset
|
449 ctrl_program_init(pulse_pio, ctrl_sm, ctrl_pio_sm_offset, CTRLOUT_GPIO, 1); |
16 | 450 |
451 // Configure a channel to write 32 bits at a time to PIO0 | |
452 // SM0's TX FIFO, paced by the data request signal from that peripheral. | |
453 ctrl_dma_chan = dma_claim_unused_channel(true); | |
454 dma_channel_config ctrl_dmac = dma_channel_get_default_config(ctrl_dma_chan); | |
455 channel_config_set_transfer_data_size(&ctrl_dmac, DMA_SIZE_32); | |
456 channel_config_set_read_increment(&ctrl_dmac, true); | |
457 channel_config_set_dreq(&ctrl_dmac, PIO_DREQ_NUM(pulse_pio, ctrl_sm, true)); | |
458 | |
459 dma_channel_configure( | |
460 ctrl_dma_chan, | |
461 &ctrl_dmac, | |
462 &pulse_pio->txf[ctrl_sm], // Write address | |
463 pulse_ctrl, // Ctrl data | |
28
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
464 transfercount, // Transfer count |
18
f1e44afb41a3
WIP with control and DAC in sync and not hanging.
Daniel O'Connor <darius@dons.net.au>
parents:
17
diff
changeset
|
465 true // Start transfer |
16 | 466 ); |
467 // No IRQ, piggyback on the data one | |
468 | |
18
f1e44afb41a3
WIP with control and DAC in sync and not hanging.
Daniel O'Connor <darius@dons.net.au>
parents:
17
diff
changeset
|
469 #ifdef WITH_TRIGGER |
11
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
470 // Load the trigger program, and configure a free state machine |
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
471 // to run the program. |
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
472 uint trigger_pio_sm_offset = pio_add_program(pulse_pio, &trigger_program); |
16 | 473 if (trigger_pio_sm_offset < 0) { |
474 printf("Unable to load trigger program\n"); | |
475 __breakpoint(); | |
476 } | |
28
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
477 trigger_sm = pio_claim_unused_sm(pulse_pio, true); |
27
e1d8fe3e418a
Run PIOs at 1x with delays and sync.
Daniel O'Connor <darius@dons.net.au>
parents:
26
diff
changeset
|
478 trigger_program_init(pulse_pio, trigger_sm, trigger_pio_sm_offset, TRIGIN_GPIO, 1); |
16 | 479 #endif |
24
c7845db23ab2
Add sideset for trigger output.
Daniel O'Connor <darius@dons.net.au>
parents:
23
diff
changeset
|
480 |
27
e1d8fe3e418a
Run PIOs at 1x with delays and sync.
Daniel O'Connor <darius@dons.net.au>
parents:
26
diff
changeset
|
481 // Start & sync all state machines |
e1d8fe3e418a
Run PIOs at 1x with delays and sync.
Daniel O'Connor <darius@dons.net.au>
parents:
26
diff
changeset
|
482 // This is necessary to avoid any jitter and to make the |
e1d8fe3e418a
Run PIOs at 1x with delays and sync.
Daniel O'Connor <darius@dons.net.au>
parents:
26
diff
changeset
|
483 // trigger sync work correctly |
28
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
484 pio_enable_sm_mask_in_sync(pulse_pio, 0 |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
485 | 1u << dac_sm |
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
486 | 1u << ctrl_sm |
27
e1d8fe3e418a
Run PIOs at 1x with delays and sync.
Daniel O'Connor <darius@dons.net.au>
parents:
26
diff
changeset
|
487 #ifdef WITH_TRIGGER |
28
600a394629e6
Use 8 bit auto pull otherwise the PIOs jitter (due to DMA contention I guess?)
Daniel O'Connor <darius@dons.net.au>
parents:
27
diff
changeset
|
488 | 1u << trigger_sm |
27
e1d8fe3e418a
Run PIOs at 1x with delays and sync.
Daniel O'Connor <darius@dons.net.au>
parents:
26
diff
changeset
|
489 #endif |
e1d8fe3e418a
Run PIOs at 1x with delays and sync.
Daniel O'Connor <darius@dons.net.au>
parents:
26
diff
changeset
|
490 ); |
11
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
491 // |
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
492 // Setup PWM |
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
493 // Used here to output a trigger which gets fed back into the trigger SM |
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
494 // |
5 | 495 // 120MHz / 250 = 480kHz base |
496 // Maximum divisor is only 256 which limits the low end, | |
497 // could further subdivide in the IRQ handler | |
9 | 498 pwm_config c = pwm_get_default_config(); |
5 | 499 pwm_config_set_clkdiv_int(&c, 250); |
27
e1d8fe3e418a
Run PIOs at 1x with delays and sync.
Daniel O'Connor <darius@dons.net.au>
parents:
26
diff
changeset
|
500 // 80Hz |
e1d8fe3e418a
Run PIOs at 1x with delays and sync.
Daniel O'Connor <darius@dons.net.au>
parents:
26
diff
changeset
|
501 pwm_config_set_wrap(&c, 6000 - 1); |
11
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
502 |
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
503 gpio_set_function(TRIGOUT_GPIO, GPIO_FUNC_PWM); |
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
504 |
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
505 slice_num = pwm_gpio_to_slice_num(TRIGOUT_GPIO); |
5 | 506 pwm_init(slice_num, &c, true); |
507 pwm_clear_irq(slice_num); | |
11
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
508 pwm_set_chan_level(slice_num, PWM_CHAN_A, 1); |
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
509 pwm_set_enabled(slice_num, 1); |
5 | 510 pwm_set_irq_enabled(slice_num, true); |
511 irq_set_exclusive_handler(PWM_IRQ_WRAP, pwm_wrap); | |
512 irq_set_enabled(PWM_IRQ_WRAP, true); | |
11
e9d12b36cfcc
Use PWM output to feed PIO trigger
Daniel O'Connor <darius@dons.net.au>
parents:
10
diff
changeset
|
513 |
3
b10097c3383d
DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents:
2
diff
changeset
|
514 // Everything else from this point is interrupt-driven. The processor has |
b10097c3383d
DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents:
2
diff
changeset
|
515 // time to sit and think about its early retirement -- maybe open a bakery? |
0
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
516 while (true) { |
5 | 517 gpio_put(PICO_DEFAULT_LED_PIN, 1); |
518 sleep_ms(100); | |
519 gpio_put(PICO_DEFAULT_LED_PIN, 0); | |
2
0d653f60dec8
Actually get data moving out.
Daniel O'Connor <darius@dons.net.au>
parents:
0
diff
changeset
|
520 sleep_ms(100); |
0
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
521 } |
5 | 522 |
523 __breakpoint(); | |
0
a55e39064a71
First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff
changeset
|
524 } |