annotate modulator.c @ 8:0249d0cecac4

Use interpolator to compute pulse up. Use interpolator to clamp values. Calculate speed. Do memory clear in routine to be more honest about the speed.
author Daniel O'Connor <darius@dons.net.au>
date Sun, 16 Feb 2025 14:36:33 +1030
parents 4ad473648949
children 3acdebd7eec7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 **
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
8 ** Copyright (c) 2021 Genesis Software, all rights reserved.
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 */
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
19
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
20 #include <stdio.h>
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
21 #include <string.h>
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
22 #include "bitstring.h"
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
23
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
24 #pragma GCC diagnostic push
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
25 #pragma GCC diagnostic ignored "-Wtype-limits"
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
26 #pragma GCC diagnostic ignored "-Wsign-compare"
0
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
27 #include "pico/stdlib.h"
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
28 #include "hardware/clocks.h"
3
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
29 #include "hardware/dma.h"
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
30 #include "hardware/interp.h"
3
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
31 #include "hardware/irq.h"
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
32 #include "hardware/pll.h"
0
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
33 #include "hardware/pio.h"
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
34 #include "hardware/pwm.h"
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
35 #include "hardware/structs/pll.h"
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
36 #include "hardware/structs/clocks.h"
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
37 #pragma GCC diagnostic pop
0
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
38
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
39 #include "dac.pio.h"
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
40
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
41 // 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
42 // Modified to be Q20.12 rather than Q16.16
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
43 #include "q/q.h"
0
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
44
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
45 #include "shaped-trap.h"
3
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
46
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
47 static int dma_chan;
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
48 uint8_t pulse_data[65536];
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
49 uint8_t pulse_ctrl[65536];
3
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
50
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
51 void
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
52 dma_handler(void) {
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
53 // Clear the interrupt request.
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
54 dma_hw->ints0 = 1u << dma_chan;
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
55 // Give the channel a new wave table entry to read from, and re-trigger it
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
56 //dma_channel_set_read_addr(dma_chan, shaped_trap_dat_start, true);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
57 }
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
58
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
59 unsigned slice_num = 0;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
60
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
61 void
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
62 pwm_wrap(void) {
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
63 pwm_clear_irq(slice_num);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
64 #if 0
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
65 static unsigned state = 0;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
66
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
67 gpio_put(PICO_DEFAULT_LED_PIN, state);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
68 state = !state;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
69 #endif
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
70
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
71 // Trigger another pulse read out
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
72 dma_channel_set_read_addr(dma_chan, pulse_data, true);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
73 }
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
74
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
75 // Calculate pulse shape data
8
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
76 // TODO: predistortion, proper sense, gate, phase, active, T/R switch
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
77 // Could encode them as bit stream like data but more compact would be
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
78 // (say) a list of counts to toggle pins at
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
79 #define SENSE 0x01
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
80 #define GATE 0x02
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
81 #define PHINV 0x04
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
82 #define PACTIVE 0x08
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
83
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
84 // Need to add pre/postgate/sense/phase counters
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
85 unsigned
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
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) {
7
4ad473648949 Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents: 6
diff changeset
87 uint32_t shapesamples, nsamples, idx, bit1startup, bit1stopup;
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
88 q_t dcscale, stepsize;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
89 char tmps[20];
7
4ad473648949 Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents: 6
diff changeset
90 interp_config cfg;
4ad473648949 Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents: 6
diff changeset
91
8
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
92 if (ncode == 1) {
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
93 // 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
94 // 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
95 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
96 // Number of samples for everything
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
97 // 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
98 nsamples = shapesamples * 2 + slew1 + slew2 + 1;
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
99 } else {
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
100 shapesamples = plen / 2;
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
101 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
102 }
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
103
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
104 // Number of steps per samples in the pulse shape
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
105 stepsize = qdiv(qint(shapelen), qint(shapesamples));
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
106 qsprint(stepsize, tmps, sizeof(tmps));
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
107 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
108
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
109 // 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
110 if (nsamples > datalen) {
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
111 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
112 return 0;
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
113 }
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
114 // Check it is not too short
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
115 if (shapesamples < 2) {
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
116 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
117 return 0;
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
118 }
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
119 // Or too long (will overflow for loop variable)
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
120 if (qtoi(shapesamples) > 65535) {
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
121 printf("Shape too long (%u > %d)\n", qtoi(shapesamples), 65535);
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
122 return 0;
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
123 }
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
124
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
125 // 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
126 // 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
127 cfg = interp_default_config();
4ad473648949 Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents: 6
diff changeset
128 interp_config_set_shift(&cfg, QBITS);
4ad473648949 Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents: 6
diff changeset
129 interp_config_set_mask(&cfg, 0, 32 - QBITS);
4ad473648949 Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents: 6
diff changeset
130 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
131 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
132
8
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
133 // 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
134 cfg = interp_default_config();
4ad473648949 Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents: 6
diff changeset
135 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
136 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
137 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
138 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
139
8
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
140 // 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
141 cfg = interp_default_config();
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
142 interp_config_set_clamp(&cfg, true);
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
143 interp_config_set_shift(&cfg, 0);
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
144 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
145 interp_config_set_signed(&cfg, false);
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
146 interp_set_config(interp1, 0, &cfg);
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
147 interp1->base[0] = 0;
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
148 interp1->base[1] = 255;
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
149
7
4ad473648949 Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents: 6
diff changeset
150 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
151 interp0->base[2] = (uintptr_t)shape; // Start of shape table
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
152
8
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
153 dcscale = qdiv(qsub(qint(256), qint(dcofs)), qint(255));
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
154 qsprint(dcscale, tmps, sizeof(tmps));
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
155 printf("dcscale = %s\n", tmps);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
156
8
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
157 memset(pulse_data, 0, sizeof(pulse_data));
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
158 memset(pulse_ctrl, 0, sizeof(pulse_ctrl));
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
159 idx = 0;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
160
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
161 // Up slew
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
162 for (uint16_t i = 0; i < slew1; i++) {
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
163 data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(i)), qint(slew1)));
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
164 ctrl[idx] |= PACTIVE;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
165 }
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
166 for (uint16_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
167 if (c == 0)
4ad473648949 Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents: 6
diff changeset
168 bit1startup = idx;
4ad473648949 Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents: 6
diff changeset
169
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
170 uint ctrltmp = PACTIVE;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
171 if (code[c] == '0')
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
172 ctrltmp |= PHINV;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
173
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
174 // Pulse up
8
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
175 if (c == 0) {
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
176 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
177 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
178 }
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
179 for (uint16_t i = 0; i < shapesamples; i++) {
8
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
180 if (c == 0) {
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
181 // Get sample pair
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
182 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
183 // 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
184 interp0->base[0] = sample_pair[0];
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
185 interp0->base[1] = sample_pair[1];
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
186 uint8_t peek = interp0->peek[1];
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
187 // Apply DC offset scaling & clamp
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
188 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
189 data[idx++] = interp1->peek[0];
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
190 // Update interpolator for next point
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
191 interp0->add_raw[0] = stepsize;
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
192 } else
7
4ad473648949 Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents: 6
diff changeset
193 // 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
194 data[idx++] = data[bit1startup + i];
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
195 ctrl[idx] = ctrltmp;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
196 }
7
4ad473648949 Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents: 6
diff changeset
197 if (c == 0)
4ad473648949 Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents: 6
diff changeset
198 bit1stopup = idx - 1;
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
199 // Pulse down
7
4ad473648949 Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents: 6
diff changeset
200 // 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
201 // XXX: if we had asymmetrical predistortion this wouldn't be true
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
202 // In that case probably best to do a single pulse up/down, then
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
203 // add predistortion and copy it to other bits
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
204 for (uint16_t i = 0; i < shapesamples; i++) {
7
4ad473648949 Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents: 6
diff changeset
205 data[idx++] = data[bit1stopup - i];
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
206 // Could replace this with a separate loop to poke it into place
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
207 // Similarly for TR switch when implemented
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
208 if (i == 0 && c == 0)
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
209 ctrl[idx] = ctrltmp | SENSE;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
210 else
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
211 ctrl[idx] = ctrltmp;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
212 }
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
213
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
214 // Code gap
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
215 if (c < ncode - 1)
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
216 for (uint16_t i = 0; i < codegap; i++) {
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
217 data[idx++] = dcofs;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
218 ctrl[idx] = ctrltmp;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
219 }
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
220 }
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
221
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
222 // Down slew
8
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
223 for (uint16_t i = 0; i < slew2 + 1; i++) {
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
224 data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(slew2 - i)), qint(slew2)));
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
225 ctrl[idx] |= PACTIVE;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
226 }
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
227 return idx - 1;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
228 }
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
229
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
230 // As per hello_interp.c
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
231 void interp_test(uint8_t *data, const uint8_t *shape) {
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
232 interp_config cfg;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
233 const int uv_fractional_bits = 12;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
234
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
235 // Step size is 0.25 (ie stretching by 4x)
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
236 unsigned step = (1 << uv_fractional_bits) / 4;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
237
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
238 puts("interp_test\n");
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
239 // Setup lane 0 to generate index into shape table
6
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
240 // Mask start is 0 because we use 8 bit samples
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
241 cfg = interp_default_config();
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
242 interp_config_set_shift(&cfg, uv_fractional_bits);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
243 interp_config_set_mask(&cfg, 0, 32 - uv_fractional_bits);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
244 interp_config_set_blend(&cfg, true);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
245 interp_set_config(interp0, 0, &cfg);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
246
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
247 // Setup lane 1 to LERP each sample pair
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
248 cfg = interp_default_config();
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
249 interp_config_set_shift(&cfg, uv_fractional_bits - 8);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
250 interp_config_set_signed(&cfg, false);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
251 interp_config_set_cross_input(&cfg, true); // unsigned blending
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
252 interp_set_config(interp0, 1, &cfg);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
253
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
254 interp0->accum[0] = 0; // Initial offset into shape table
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
255 interp0->base[2] = (uintptr_t)shape; // Start of shape table
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
256 for (unsigned i = 0; i < 122 * 4; i++) {
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
257 // Get sample pair
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
258 uint8_t *sample_pair = (uint8_t *) interp0->peek[2];
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
259 // Ask lane 1 for a LERP, using the lane 0 accumulator
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
260 interp0->base[0] = sample_pair[0];
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
261 interp0->base[1] = sample_pair[1];
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
262 uint32_t peek1 = interp0->peek[1];
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
263 uint32_t add_raw1 = interp0->add_raw[1];
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
264 data[i] = peek1;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
265 printf("%d\t(%lu%% between %d and %d) %lu\n",
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
266 (int)peek1,
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
267 100 * (add_raw1 & 0xff) / 0xff,
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
268 sample_pair[0], sample_pair[1],
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
269 interp_get_accumulator(interp0, 0));
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
270 interp0->add_raw[0] = step;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
271 }
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
272 puts("done");
3
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
273 }
0
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
274
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
275 int
3
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
276 main(void) {
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
277 absolute_time_t then, now;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
278
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
279 // Set sysclk to 120MHz
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
280 set_sys_clock_khz(120000, true);
0
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
281
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
282 stdio_init_all();
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
283 printf("\n\n\nIniting\n");
0
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
284
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
285 // Needed otherwise timer related functions hang under debugging
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
286 // https://github.com/raspberrypi/pico-sdk/issues/1152#issuecomment-1418248639
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
287 timer_hw->dbgpause = 0;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
288
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
289 gpio_init(PICO_DEFAULT_LED_PIN);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
290 gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
291
7
4ad473648949 Copy pulse up in reverse for pulse down.
Daniel O'Connor <darius@dons.net.au>
parents: 6
diff changeset
292 //interp_test(pulse_data, shaped_trap);
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
293
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
294 uint32_t idx;
8
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
295 uint16_t plen;
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
296 char *code;
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
297 if (0) {
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
298 plen = 8000;
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
299 code = "1110010";
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
300 } else {
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
301 plen = 53000;
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
302 code = "1";
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
303 }
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
304
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
305 uint8_t codegap = 4;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
306 uint8_t slew1 = 10;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
307 uint8_t slew2 = 10;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
308 uint8_t dcofs = 110;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
309 then = get_absolute_time();
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
310 if ((idx = compute_pulse(pulse_data, pulse_ctrl, sizeof(pulse_data),
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
311 plen, code, strlen(code),
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
312 shaped_trap, sizeof(shaped_trap),
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
313 codegap, slew1, slew2, dcofs)) == 0) {
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
314 printf("Failed to compute pulse\n");
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
315 while (1)
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
316 ;
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
317 }
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
318 now = get_absolute_time();
8
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
319 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
320 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
321 diff, idx, (float)diff * 1000.0 / idx);
0249d0cecac4 Use interpolator to compute pulse up.
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
322 __breakpoint();
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
323 pwm_config c = pwm_get_default_config();
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
324 // 120MHz / 250 = 480kHz base
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
325 // Maximum divisor is only 256 which limits the low end,
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
326 // could further subdivide in the IRQ handler
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
327 pwm_config_set_clkdiv_int(&c, 250);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
328 // 8Hz
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
329 pwm_config_set_wrap(&c, 60000 - 1);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
330 pwm_init(slice_num, &c, true);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
331 pwm_clear_irq(slice_num);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
332 pwm_set_irq_enabled(slice_num, true);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
333 irq_set_exclusive_handler(PWM_IRQ_WRAP, pwm_wrap);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
334 irq_set_enabled(PWM_IRQ_WRAP, true);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
335 pwm_init(slice_num, &c, true);
0
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
336
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
337 // Load the clocked_input program, and configure a free state machine
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
338 // to run the program.
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
339 PIO pio = pio0;
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
340 uint offset = pio_add_program(pio, &dac_program);
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
341 uint sm = pio_claim_unused_sm(pio, true);
2
0d653f60dec8 Actually get data moving out.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
342 // XXX: I would prefer starting at GPIO16 but in that case the top 2
0d653f60dec8 Actually get data moving out.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
343 // bits don't seem to work
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
344 // Clock divisor of 2 so it runs at 60MHz and
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
345 // generates a 30MHz clock
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
346 dac_program_init(pio, sm, offset, 14, 2);
0
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
347
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
348 // Configure a channel to write the same word (8 bits) repeatedly to PIO0
3
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
349 // SM0's TX FIFO, paced by the data request signal from that peripheral.
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
350 dma_chan = dma_claim_unused_channel(true);
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
351 dma_channel_config dmac = dma_channel_get_default_config(dma_chan);
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
352 // XXX: need to get pulse generator to pad to 32 bits
3
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
353 channel_config_set_transfer_data_size(&dmac, DMA_SIZE_32);
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
354 channel_config_set_read_increment(&dmac, true);
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
355 channel_config_set_dreq(&dmac, DREQ_PIO0_TX0);
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
356
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
357 dma_channel_configure(
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
358 dma_chan,
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
359 &dmac,
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
360 &pio0_hw->txf[0], // Write address (only need to set this once)
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
361 NULL, // Don't provide a read address yet
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
362 idx >> 2, // Transfer count
3
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
363 false // Don't start yet
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
364 );
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
365
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
366 // Tell the DMA to raise IRQ line 0 when the channel finishes a block
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
367 dma_channel_set_irq0_enabled(dma_chan, true);
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
368
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
369 // Configure the processor to run dma_handler() when DMA IRQ 0 is asserted
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
370 irq_set_exclusive_handler(DMA_IRQ_0, dma_handler);
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
371 irq_set_enabled(DMA_IRQ_0, true);
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
372
b10097c3383d DMA test data repeatedly into PIO FIFO
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
373 // 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
374 // 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
375 while (true) {
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
376 dma_channel_wait_for_finish_blocking(dma_chan);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
377 gpio_put(PICO_DEFAULT_LED_PIN, 1);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
378 sleep_ms(100);
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
379 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
380 sleep_ms(100);
0
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
381 }
5
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
382
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
383 __breakpoint();
0
a55e39064a71 First commit of code that compiles.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
384 }