4
|
1 #include <sys/errno.h>
|
|
2 #include <stdio.h>
|
|
3 #include <stdint.h>
|
|
4 #include <stdlib.h>
|
|
5 #include <string.h>
|
|
6
|
5
|
7 #if 1
|
4
|
8 #include <q.h>
|
5
|
9 #else
|
|
10 // We want Q24.8 - Q16.16 is too small for sample calculations
|
|
11 #define FPT_WBITS 24
|
|
12 #include "fptc-lib/src/fptc.h"
|
|
13 #define q_t fpt
|
|
14 #define qmul fpt_mul
|
|
15 #define qdiv fpt_div
|
|
16 #define qtoi fpt2i
|
|
17 #define qint i2fpt
|
|
18 #define qsub(x, y) ((x) - (y))
|
|
19 #define qsprint(n, s, len) fpt_str(n, s, 3)
|
|
20 #endif
|
4
|
21
|
|
22 #include "shaped-trap.h"
|
|
23
|
5
|
24 unsigned
|
|
25 compute_pulse(uint8_t *data, unsigned datalen, uint16_t plen, char *code, uint8_t ncode, uint8_t shapelen, const uint8_t *shape, uint8_t codegap, uint8_t slew1, uint8_t slew2, uint8_t dcofs) {
|
4
|
26 uint32_t shapesamples, nsamples, idx;
|
|
27 q_t dcscale, stepsize;
|
5
|
28 char tmps[20];
|
4
|
29
|
|
30 dcscale = qdiv(qsub(qint(255), qint(dcofs)), qint(255));
|
|
31 qsprint(dcscale, tmps, sizeof(tmps));
|
|
32 printf("dcscale = %s\n", tmps);
|
|
33
|
|
34 if (ncode == 1) {
|
|
35 // Number of samples for half of the pulse
|
5
|
36 // Do division first so we don't overflow Q16.16
|
|
37 shapesamples = qtoi(qmul(qdiv(qint(plen), qint(100)), qint(shapelen)));
|
4
|
38 // Number of samples for everything
|
|
39 nsamples = shapesamples * 2 + slew1 + slew2;
|
|
40 } else {
|
|
41 shapesamples = plen;
|
|
42 nsamples = shapesamples * 2 * ncode + codegap * (ncode - 1) + slew1 + slew2;
|
|
43 }
|
|
44
|
|
45 // Number of samples per step in the pulse shape
|
|
46 stepsize = qdiv(qint(shapesamples), qint(shapelen));
|
|
47 qsprint(stepsize, tmps, sizeof(tmps));
|
|
48 printf("shapelen = %d shapesamples = %u nsamples = %u stepsize = %s\n", shapelen, shapesamples, nsamples, tmps);
|
|
49
|
5
|
50 if (nsamples > datalen) {
|
|
51 printf("Pulse too long (%d > %u)\n", nsamples, datalen);
|
|
52 return 0;
|
|
53 }
|
4
|
54 if (shapesamples < 2) {
|
|
55 printf("Pulse too short (%u < %d)\n", shapesamples, 2);
|
5
|
56 return 0;
|
4
|
57 }
|
5
|
58 if (qtoi(shapesamples) > 65535) {
|
|
59 printf("Shape too long (%u > %d)\n", qtoi(shapesamples), 65535);
|
|
60 return 0;
|
|
61 }
|
4
|
62 idx = 0;
|
|
63
|
|
64 // Up slew
|
|
65 for (uint16_t i = 0; i < slew1; i++)
|
|
66 data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(i)), qint(slew1)));
|
|
67
|
|
68 for (uint16_t c = 0; c < ncode; c++) {
|
|
69 // Pulse up
|
|
70 for (uint16_t i = 0; i < shapesamples; i++)
|
5
|
71 data[idx++] = dcofs + qtoi(qmul(qint(shape[qtoi(qdiv(qint(i), stepsize))]), dcscale));
|
4
|
72
|
|
73 // Pulse down
|
|
74 for (uint16_t i = 0; i < shapesamples; i++)
|
5
|
75 data[idx++] = dcofs + qtoi(qmul(qint(shape[qtoi(qdiv(qint(shapesamples - i - 1), stepsize))]), dcscale));
|
4
|
76
|
|
77 // Code gap
|
|
78 if (c < ncode - 1)
|
|
79 for (uint16_t i = 0; i < codegap; i++)
|
|
80 data[idx++] = dcofs;
|
|
81 }
|
|
82
|
|
83 // Down slew
|
|
84 for (uint16_t i = 0; i < slew2; i++)
|
|
85 data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(slew2 - i)), qint(slew2)));
|
|
86
|
5
|
87 return idx - 1;
|
|
88 }
|
|
89
|
|
90 int
|
|
91 main(int argc, char **argv) {
|
|
92 uint8_t data[65536], codegap, slew1, slew2, dcofs;
|
|
93 uint16_t plen;
|
|
94 uint32_t idx;
|
|
95 char *code;
|
|
96
|
|
97 if (argc != 7) {
|
|
98 printf("Bad usage\n");
|
|
99 exit(1);
|
|
100 }
|
|
101 plen = atoi(argv[1]);
|
|
102 code = argv[2];
|
|
103 codegap = atoi(argv[3]);
|
|
104 slew1 = atoi(argv[4]);
|
|
105 slew2 = atoi(argv[5]);
|
|
106 dcofs = atoi(argv[6]);
|
|
107
|
|
108 if ((idx = compute_pulse(data, sizeof(data), plen, code, strlen(code), sizeof(shaped_trap), shaped_trap, codegap, slew1, slew2, dcofs)) == 0) {
|
|
109 printf("Failed to build pulse\n");
|
|
110 exit(1);
|
|
111 }
|
|
112
|
4
|
113 FILE *fh;
|
|
114 if ((fh = fopen("/tmp/out.bin", "w")) == NULL) {
|
|
115 printf("Unable to open file: %s\n", strerror(errno));
|
|
116 exit(1);
|
|
117 }
|
|
118 fwrite(data, idx, 1, fh);
|
|
119 fclose(fh);
|
|
120
|
|
121 exit(0);
|
|
122 }
|