├── .gitignore
├── .gitmodules
├── CMSIS
├── .DS_Store
└── DSP_Lib
│ ├── Source
│ ├── CommonTables
│ │ └── arm_common_tables.c
│ ├── FilteringFunctions
│ │ └── arm_biquad_cascade_df1_q15.c
│ └── TransformFunctions
│ │ ├── arm_bitreversal.c
│ │ ├── arm_cfft_radix4_init_q31.c
│ │ └── arm_cfft_radix4_q31.c
│ └── license.txt
├── Font5x7.c
├── Makefile
├── NANOSDR_STM32_F303
├── board.c
├── board.h
└── board.mk
├── README.md
├── STM32F303xB.ld
├── build.sh
├── ccmfunc.ld
├── chconf.h
├── crt2.c
├── display.c
├── doc
├── centsdr-blockdiagram.png
├── centsdr.jpg
└── plot-waveform.png
├── dsp.c
├── ffconf.h
├── flash-openocd.gdb
├── flash-stutil.gdb
├── flash.c
├── halconf.h
├── icons.c
├── ili9341.c
├── main.c
├── mcuconf.h
├── nanosdr.h
├── numfont20x24.c
├── numfont32x24.c
├── prog.sh
├── python
├── CW-Filter-Design.ipynb
├── README.md
├── SSB-Filter-Design.ipynb
├── TLV320AIC3204-1st-IIR-HPF.ipynb
└── centsdr.py
├── rules_code.ld
├── si5351.c
├── si5351.h
├── si5351_low.c
├── tlv320aic3204.c
├── ui.c
├── usbcfg.c
└── usbcfg.h
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | .dep
3 | build
4 | TAGS
5 | *.cap
6 | .ipynb_checkpoints
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "ChibiOS"]
2 | path = ChibiOS
3 | url = https://github.com/edy555/ChibiOS.git
4 |
--------------------------------------------------------------------------------
/CMSIS/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttrftech/CentSDR/e4079566e42790497f004e16f9ebf68c83d024a0/CMSIS/.DS_Store
--------------------------------------------------------------------------------
/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_q15.c:
--------------------------------------------------------------------------------
1 | /* ----------------------------------------------------------------------
2 | * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
3 | *
4 | * $Date: 19. March 2015
5 | * $Revision: V.1.4.5
6 | *
7 | * Project: CMSIS DSP Library
8 | * Title: arm_biquad_cascade_df1_q15.c
9 | *
10 | * Description: Processing function for the
11 | * Q15 Biquad cascade DirectFormI(DF1) filter.
12 | *
13 | * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
14 | *
15 | * Redistribution and use in source and binary forms, with or without
16 | * modification, are permitted provided that the following conditions
17 | * are met:
18 | * - Redistributions of source code must retain the above copyright
19 | * notice, this list of conditions and the following disclaimer.
20 | * - Redistributions in binary form must reproduce the above copyright
21 | * notice, this list of conditions and the following disclaimer in
22 | * the documentation and/or other materials provided with the
23 | * distribution.
24 | * - Neither the name of ARM LIMITED nor the names of its contributors
25 | * may be used to endorse or promote products derived from this
26 | * software without specific prior written permission.
27 | *
28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 | * POSSIBILITY OF SUCH DAMAGE.
40 | * -------------------------------------------------------------------- */
41 |
42 | #include "arm_math.h"
43 |
44 | /**
45 | * @ingroup groupFilters
46 | */
47 |
48 | /**
49 | * @addtogroup BiquadCascadeDF1
50 | * @{
51 | */
52 |
53 | /**
54 | * @brief Processing function for the Q15 Biquad cascade filter.
55 | * @param[in] *S points to an instance of the Q15 Biquad cascade structure.
56 | * @param[in] *pSrc points to the block of input data.
57 | * @param[out] *pDst points to the location where the output result is written.
58 | * @param[in] blockSize number of samples to process per call.
59 | * @return none.
60 | *
61 | *
62 | * Scaling and Overflow Behavior:
63 | * \par
64 | * The function is implemented using a 64-bit internal accumulator.
65 | * Both coefficients and state variables are represented in 1.15 format and multiplications yield a 2.30 result.
66 | * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format.
67 | * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved.
68 | * The accumulator is then shifted by postShift
bits to truncate the result to 1.15 format by discarding the low 16 bits.
69 | * Finally, the result is saturated to 1.15 format.
70 | *
71 | * \par
72 | * Refer to the function arm_biquad_cascade_df1_fast_q15()
for a faster but less precise implementation of this filter for Cortex-M3 and Cortex-M4.
73 | */
74 |
75 | void arm_biquad_cascade_df1_q15(
76 | const arm_biquad_casd_df1_inst_q15 * S,
77 | q15_t * pSrc,
78 | q15_t * pDst,
79 | uint32_t blockSize)
80 | {
81 |
82 |
83 | #ifndef ARM_MATH_CM0_FAMILY
84 |
85 | /* Run the below code for Cortex-M4 and Cortex-M3 */
86 |
87 | q15_t *pIn = pSrc; /* Source pointer */
88 | q15_t *pOut = pDst; /* Destination pointer */
89 | q31_t in; /* Temporary variable to hold input value */
90 | q31_t out; /* Temporary variable to hold output value */
91 | q31_t b0; /* Temporary variable to hold bo value */
92 | q31_t b1, a1; /* Filter coefficients */
93 | q31_t state_in, state_out; /* Filter state variables */
94 | q31_t acc_l, acc_h;
95 | q63_t acc; /* Accumulator */
96 | int32_t lShift = (15 - (int32_t) S->postShift); /* Post shift */
97 | q15_t *pState = S->pState; /* State pointer */
98 | q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
99 | uint32_t sample, stage = (uint32_t) S->numStages; /* Stage loop counter */
100 | int32_t uShift = (32 - lShift);
101 |
102 | do
103 | {
104 | /* Read the b0 and 0 coefficients using SIMD */
105 | b0 = *__SIMD32(pCoeffs)++;
106 |
107 | /* Read the b1 and b2 coefficients using SIMD */
108 | b1 = *__SIMD32(pCoeffs)++;
109 |
110 | /* Read the a1 and a2 coefficients using SIMD */
111 | a1 = *__SIMD32(pCoeffs)++;
112 |
113 | /* Read the input state values from the state buffer: x[n-1], x[n-2] */
114 | state_in = *__SIMD32(pState)++;
115 |
116 | /* Read the output state values from the state buffer: y[n-1], y[n-2] */
117 | state_out = *__SIMD32(pState)--;
118 |
119 | /* Apply loop unrolling and compute 2 output values simultaneously. */
120 | /* The variable acc hold output values that are being computed:
121 | *
122 | * acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
123 | * acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
124 | */
125 | sample = blockSize >> 1u;
126 |
127 | /* First part of the processing with loop unrolling. Compute 2 outputs at a time.
128 | ** a second loop below computes the remaining 1 sample. */
129 | while(sample > 0u)
130 | {
131 |
132 | /* Read the input */
133 | in = *__SIMD32(pIn)++;
134 |
135 | /* out = b0 * x[n] + 0 * 0 */
136 | out = __SMUAD(b0, in);
137 |
138 | /* acc += b1 * x[n-1] + b2 * x[n-2] + out */
139 | acc = __SMLALD(b1, state_in, out);
140 | /* acc += a1 * y[n-1] + a2 * y[n-2] */
141 | acc = __SMLALD(a1, state_out, acc);
142 |
143 | /* FIX: compensate dc offset caused from bit shift operation */
144 | acc += 1 << lShift;
145 |
146 | /* The result is converted from 3.29 to 1.31 if postShift = 1, and then saturation is applied */
147 | /* Calc lower part of acc */
148 | acc_l = acc & 0xffffffff;
149 |
150 | /* Calc upper part of acc */
151 | acc_h = (acc >> 32) & 0xffffffff;
152 |
153 | /* Apply shift for lower part of acc and upper part of acc */
154 | out = (uint32_t) acc_l >> lShift | acc_h << uShift;
155 |
156 | out = __SSAT(out, 16);
157 |
158 | /* Every time after the output is computed state should be updated. */
159 | /* The states should be updated as: */
160 | /* Xn2 = Xn1 */
161 | /* Xn1 = Xn */
162 | /* Yn2 = Yn1 */
163 | /* Yn1 = acc */
164 | /* x[n-N], x[n-N-1] are packed together to make state_in of type q31 */
165 | /* y[n-N], y[n-N-1] are packed together to make state_out of type q31 */
166 |
167 | #ifndef ARM_MATH_BIG_ENDIAN
168 |
169 | state_in = __PKHBT(in, state_in, 16);
170 | state_out = __PKHBT(out, state_out, 16);
171 |
172 | #else
173 |
174 | state_in = __PKHBT(state_in >> 16, (in >> 16), 16);
175 | state_out = __PKHBT(state_out >> 16, (out), 16);
176 |
177 | #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
178 |
179 | /* out = b0 * x[n] + 0 * 0 */
180 | out = __SMUADX(b0, in);
181 | /* acc += b1 * x[n-1] + b2 * x[n-2] + out */
182 | acc = __SMLALD(b1, state_in, out);
183 | /* acc += a1 * y[n-1] + a2 * y[n-2] */
184 | acc = __SMLALD(a1, state_out, acc);
185 |
186 | /* The result is converted from 3.29 to 1.31 if postShift = 1, and then saturation is applied */
187 | /* Calc lower part of acc */
188 | acc_l = acc & 0xffffffff;
189 |
190 | /* Calc upper part of acc */
191 | acc_h = (acc >> 32) & 0xffffffff;
192 |
193 | /* Apply shift for lower part of acc and upper part of acc */
194 | out = (uint32_t) acc_l >> lShift | acc_h << uShift;
195 |
196 | out = __SSAT(out, 16);
197 |
198 | /* Store the output in the destination buffer. */
199 |
200 | #ifndef ARM_MATH_BIG_ENDIAN
201 |
202 | *__SIMD32(pOut)++ = __PKHBT(state_out, out, 16);
203 |
204 | #else
205 |
206 | *__SIMD32(pOut)++ = __PKHBT(out, state_out >> 16, 16);
207 |
208 | #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
209 |
210 | /* Every time after the output is computed state should be updated. */
211 | /* The states should be updated as: */
212 | /* Xn2 = Xn1 */
213 | /* Xn1 = Xn */
214 | /* Yn2 = Yn1 */
215 | /* Yn1 = acc */
216 | /* x[n-N], x[n-N-1] are packed together to make state_in of type q31 */
217 | /* y[n-N], y[n-N-1] are packed together to make state_out of type q31 */
218 | #ifndef ARM_MATH_BIG_ENDIAN
219 |
220 | state_in = __PKHBT(in >> 16, state_in, 16);
221 | state_out = __PKHBT(out, state_out, 16);
222 |
223 | #else
224 |
225 | state_in = __PKHBT(state_in >> 16, in, 16);
226 | state_out = __PKHBT(state_out >> 16, out, 16);
227 |
228 | #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
229 |
230 |
231 | /* Decrement the loop counter */
232 | sample--;
233 |
234 | }
235 |
236 | /* If the blockSize is not a multiple of 2, compute any remaining output samples here.
237 | ** No loop unrolling is used. */
238 |
239 | if((blockSize & 0x1u) != 0u)
240 | {
241 | /* Read the input */
242 | in = *pIn++;
243 |
244 | /* out = b0 * x[n] + 0 * 0 */
245 |
246 | #ifndef ARM_MATH_BIG_ENDIAN
247 |
248 | out = __SMUAD(b0, in);
249 |
250 | #else
251 |
252 | out = __SMUADX(b0, in);
253 |
254 | #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
255 |
256 | /* acc = b1 * x[n-1] + b2 * x[n-2] + out */
257 | acc = __SMLALD(b1, state_in, out);
258 | /* acc += a1 * y[n-1] + a2 * y[n-2] */
259 | acc = __SMLALD(a1, state_out, acc);
260 |
261 | /* The result is converted from 3.29 to 1.31 if postShift = 1, and then saturation is applied */
262 | /* Calc lower part of acc */
263 | acc_l = acc & 0xffffffff;
264 |
265 | /* Calc upper part of acc */
266 | acc_h = (acc >> 32) & 0xffffffff;
267 |
268 | /* Apply shift for lower part of acc and upper part of acc */
269 | out = (uint32_t) acc_l >> lShift | acc_h << uShift;
270 |
271 | out = __SSAT(out, 16);
272 |
273 | /* Store the output in the destination buffer. */
274 | *pOut++ = (q15_t) out;
275 |
276 | /* Every time after the output is computed state should be updated. */
277 | /* The states should be updated as: */
278 | /* Xn2 = Xn1 */
279 | /* Xn1 = Xn */
280 | /* Yn2 = Yn1 */
281 | /* Yn1 = acc */
282 | /* x[n-N], x[n-N-1] are packed together to make state_in of type q31 */
283 | /* y[n-N], y[n-N-1] are packed together to make state_out of type q31 */
284 |
285 | #ifndef ARM_MATH_BIG_ENDIAN
286 |
287 | state_in = __PKHBT(in, state_in, 16);
288 | state_out = __PKHBT(out, state_out, 16);
289 |
290 | #else
291 |
292 | state_in = __PKHBT(state_in >> 16, in, 16);
293 | state_out = __PKHBT(state_out >> 16, out, 16);
294 |
295 | #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
296 |
297 | }
298 |
299 | /* The first stage goes from the input wire to the output wire. */
300 | /* Subsequent numStages occur in-place in the output wire */
301 | pIn = pDst;
302 |
303 | /* Reset the output pointer */
304 | pOut = pDst;
305 |
306 | /* Store the updated state variables back into the state array */
307 | *__SIMD32(pState)++ = state_in;
308 | *__SIMD32(pState)++ = state_out;
309 |
310 |
311 | /* Decrement the loop counter */
312 | stage--;
313 |
314 | } while(stage > 0u);
315 |
316 | #else
317 |
318 | /* Run the below code for Cortex-M0 */
319 |
320 | q15_t *pIn = pSrc; /* Source pointer */
321 | q15_t *pOut = pDst; /* Destination pointer */
322 | q15_t b0, b1, b2, a1, a2; /* Filter coefficients */
323 | q15_t Xn1, Xn2, Yn1, Yn2; /* Filter state variables */
324 | q15_t Xn; /* temporary input */
325 | q63_t acc; /* Accumulator */
326 | int32_t shift = (15 - (int32_t) S->postShift); /* Post shift */
327 | q15_t *pState = S->pState; /* State pointer */
328 | q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
329 | uint32_t sample, stage = (uint32_t) S->numStages; /* Stage loop counter */
330 |
331 | do
332 | {
333 | /* Reading the coefficients */
334 | b0 = *pCoeffs++;
335 | pCoeffs++; // skip the 0 coefficient
336 | b1 = *pCoeffs++;
337 | b2 = *pCoeffs++;
338 | a1 = *pCoeffs++;
339 | a2 = *pCoeffs++;
340 |
341 | /* Reading the state values */
342 | Xn1 = pState[0];
343 | Xn2 = pState[1];
344 | Yn1 = pState[2];
345 | Yn2 = pState[3];
346 |
347 | /* The variables acc holds the output value that is computed:
348 | * acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
349 | */
350 |
351 | sample = blockSize;
352 |
353 | while(sample > 0u)
354 | {
355 | /* Read the input */
356 | Xn = *pIn++;
357 |
358 | /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
359 | /* acc = b0 * x[n] */
360 | acc = (q31_t) b0 *Xn;
361 |
362 | /* acc += b1 * x[n-1] */
363 | acc += (q31_t) b1 *Xn1;
364 | /* acc += b[2] * x[n-2] */
365 | acc += (q31_t) b2 *Xn2;
366 | /* acc += a1 * y[n-1] */
367 | acc += (q31_t) a1 *Yn1;
368 | /* acc += a2 * y[n-2] */
369 | acc += (q31_t) a2 *Yn2;
370 |
371 | /* The result is converted to 1.31 */
372 | acc = __SSAT((acc >> shift), 16);
373 |
374 | /* Every time after the output is computed state should be updated. */
375 | /* The states should be updated as: */
376 | /* Xn2 = Xn1 */
377 | /* Xn1 = Xn */
378 | /* Yn2 = Yn1 */
379 | /* Yn1 = acc */
380 | Xn2 = Xn1;
381 | Xn1 = Xn;
382 | Yn2 = Yn1;
383 | Yn1 = (q15_t) acc;
384 |
385 | /* Store the output in the destination buffer. */
386 | *pOut++ = (q15_t) acc;
387 |
388 | /* decrement the loop counter */
389 | sample--;
390 | }
391 |
392 | /* The first stage goes from the input buffer to the output buffer. */
393 | /* Subsequent stages occur in-place in the output buffer */
394 | pIn = pDst;
395 |
396 | /* Reset to destination pointer */
397 | pOut = pDst;
398 |
399 | /* Store the updated state variables back into the pState array */
400 | *pState++ = Xn1;
401 | *pState++ = Xn2;
402 | *pState++ = Yn1;
403 | *pState++ = Yn2;
404 |
405 | } while(--stage);
406 |
407 | #endif /* #ifndef ARM_MATH_CM0_FAMILY */
408 |
409 | }
410 |
411 |
412 | /**
413 | * @} end of BiquadCascadeDF1 group
414 | */
415 |
--------------------------------------------------------------------------------
/CMSIS/DSP_Lib/Source/TransformFunctions/arm_bitreversal.c:
--------------------------------------------------------------------------------
1 | /* ----------------------------------------------------------------------
2 | * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
3 | *
4 | * $Date: 19. March 2015
5 | * $Revision: V.1.4.5
6 | *
7 | * Project: CMSIS DSP Library
8 | * Title: arm_bitreversal.c
9 | *
10 | * Description: This file has common tables like Bitreverse, reciprocal etc which are used across different functions
11 | *
12 | * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
13 | *
14 | * Redistribution and use in source and binary forms, with or without
15 | * modification, are permitted provided that the following conditions
16 | * are met:
17 | * - Redistributions of source code must retain the above copyright
18 | * notice, this list of conditions and the following disclaimer.
19 | * - Redistributions in binary form must reproduce the above copyright
20 | * notice, this list of conditions and the following disclaimer in
21 | * the documentation and/or other materials provided with the
22 | * distribution.
23 | * - Neither the name of ARM LIMITED nor the names of its contributors
24 | * may be used to endorse or promote products derived from this
25 | * software without specific prior written permission.
26 | *
27 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 | * POSSIBILITY OF SUCH DAMAGE.
39 | * -------------------------------------------------------------------- */
40 |
41 | #include "arm_math.h"
42 | #include "arm_common_tables.h"
43 |
44 | /*
45 | * @brief In-place bit reversal function.
46 | * @param[in, out] *pSrc points to the in-place buffer of floating-point data type.
47 | * @param[in] fftSize length of the FFT.
48 | * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table.
49 | * @param[in] *pBitRevTab points to the bit reversal table.
50 | * @return none.
51 | */
52 |
53 | void arm_bitreversal_f32(
54 | float32_t * pSrc,
55 | uint16_t fftSize,
56 | uint16_t bitRevFactor,
57 | uint16_t * pBitRevTab)
58 | {
59 | uint16_t fftLenBy2, fftLenBy2p1;
60 | uint16_t i, j;
61 | float32_t in;
62 |
63 | /* Initializations */
64 | j = 0u;
65 | fftLenBy2 = fftSize >> 1u;
66 | fftLenBy2p1 = (fftSize >> 1u) + 1u;
67 |
68 | /* Bit Reversal Implementation */
69 | for (i = 0u; i <= (fftLenBy2 - 2u); i += 2u)
70 | {
71 | if(i < j)
72 | {
73 | /* pSrc[i] <-> pSrc[j]; */
74 | in = pSrc[2u * i];
75 | pSrc[2u * i] = pSrc[2u * j];
76 | pSrc[2u * j] = in;
77 |
78 | /* pSrc[i+1u] <-> pSrc[j+1u] */
79 | in = pSrc[(2u * i) + 1u];
80 | pSrc[(2u * i) + 1u] = pSrc[(2u * j) + 1u];
81 | pSrc[(2u * j) + 1u] = in;
82 |
83 | /* pSrc[i+fftLenBy2p1] <-> pSrc[j+fftLenBy2p1] */
84 | in = pSrc[2u * (i + fftLenBy2p1)];
85 | pSrc[2u * (i + fftLenBy2p1)] = pSrc[2u * (j + fftLenBy2p1)];
86 | pSrc[2u * (j + fftLenBy2p1)] = in;
87 |
88 | /* pSrc[i+fftLenBy2p1+1u] <-> pSrc[j+fftLenBy2p1+1u] */
89 | in = pSrc[(2u * (i + fftLenBy2p1)) + 1u];
90 | pSrc[(2u * (i + fftLenBy2p1)) + 1u] =
91 | pSrc[(2u * (j + fftLenBy2p1)) + 1u];
92 | pSrc[(2u * (j + fftLenBy2p1)) + 1u] = in;
93 |
94 | }
95 |
96 | /* pSrc[i+1u] <-> pSrc[j+1u] */
97 | in = pSrc[2u * (i + 1u)];
98 | pSrc[2u * (i + 1u)] = pSrc[2u * (j + fftLenBy2)];
99 | pSrc[2u * (j + fftLenBy2)] = in;
100 |
101 | /* pSrc[i+2u] <-> pSrc[j+2u] */
102 | in = pSrc[(2u * (i + 1u)) + 1u];
103 | pSrc[(2u * (i + 1u)) + 1u] = pSrc[(2u * (j + fftLenBy2)) + 1u];
104 | pSrc[(2u * (j + fftLenBy2)) + 1u] = in;
105 |
106 | /* Reading the index for the bit reversal */
107 | j = *pBitRevTab;
108 |
109 | /* Updating the bit reversal index depending on the fft length */
110 | pBitRevTab += bitRevFactor;
111 | }
112 | }
113 |
114 |
115 |
116 | /*
117 | * @brief In-place bit reversal function.
118 | * @param[in, out] *pSrc points to the in-place buffer of Q31 data type.
119 | * @param[in] fftLen length of the FFT.
120 | * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table
121 | * @param[in] *pBitRevTab points to bit reversal table.
122 | * @return none.
123 | */
124 |
125 | void arm_bitreversal_q31(
126 | q31_t * pSrc,
127 | uint32_t fftLen,
128 | uint16_t bitRevFactor,
129 | uint16_t * pBitRevTable)
130 | {
131 | uint32_t fftLenBy2, fftLenBy2p1, i, j;
132 | q31_t in;
133 |
134 | /* Initializations */
135 | j = 0u;
136 | fftLenBy2 = fftLen / 2u;
137 | fftLenBy2p1 = (fftLen / 2u) + 1u;
138 |
139 | /* Bit Reversal Implementation */
140 | for (i = 0u; i <= (fftLenBy2 - 2u); i += 2u)
141 | {
142 | if(i < j)
143 | {
144 | /* pSrc[i] <-> pSrc[j]; */
145 | in = pSrc[2u * i];
146 | pSrc[2u * i] = pSrc[2u * j];
147 | pSrc[2u * j] = in;
148 |
149 | /* pSrc[i+1u] <-> pSrc[j+1u] */
150 | in = pSrc[(2u * i) + 1u];
151 | pSrc[(2u * i) + 1u] = pSrc[(2u * j) + 1u];
152 | pSrc[(2u * j) + 1u] = in;
153 |
154 | /* pSrc[i+fftLenBy2p1] <-> pSrc[j+fftLenBy2p1] */
155 | in = pSrc[2u * (i + fftLenBy2p1)];
156 | pSrc[2u * (i + fftLenBy2p1)] = pSrc[2u * (j + fftLenBy2p1)];
157 | pSrc[2u * (j + fftLenBy2p1)] = in;
158 |
159 | /* pSrc[i+fftLenBy2p1+1u] <-> pSrc[j+fftLenBy2p1+1u] */
160 | in = pSrc[(2u * (i + fftLenBy2p1)) + 1u];
161 | pSrc[(2u * (i + fftLenBy2p1)) + 1u] =
162 | pSrc[(2u * (j + fftLenBy2p1)) + 1u];
163 | pSrc[(2u * (j + fftLenBy2p1)) + 1u] = in;
164 |
165 | }
166 |
167 | /* pSrc[i+1u] <-> pSrc[j+1u] */
168 | in = pSrc[2u * (i + 1u)];
169 | pSrc[2u * (i + 1u)] = pSrc[2u * (j + fftLenBy2)];
170 | pSrc[2u * (j + fftLenBy2)] = in;
171 |
172 | /* pSrc[i+2u] <-> pSrc[j+2u] */
173 | in = pSrc[(2u * (i + 1u)) + 1u];
174 | pSrc[(2u * (i + 1u)) + 1u] = pSrc[(2u * (j + fftLenBy2)) + 1u];
175 | pSrc[(2u * (j + fftLenBy2)) + 1u] = in;
176 |
177 | /* Reading the index for the bit reversal */
178 | j = *pBitRevTable;
179 |
180 | /* Updating the bit reversal index depending on the fft length */
181 | pBitRevTable += bitRevFactor;
182 | }
183 | }
184 |
185 |
186 |
187 | /*
188 | * @brief In-place bit reversal function.
189 | * @param[in, out] *pSrc points to the in-place buffer of Q15 data type.
190 | * @param[in] fftLen length of the FFT.
191 | * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table
192 | * @param[in] *pBitRevTab points to bit reversal table.
193 | * @return none.
194 | */
195 |
196 | void arm_bitreversal_q15(
197 | q15_t * pSrc16,
198 | uint32_t fftLen,
199 | uint16_t bitRevFactor,
200 | uint16_t * pBitRevTab)
201 | {
202 | q31_t *pSrc = (q31_t *) pSrc16;
203 | q31_t in;
204 | uint32_t fftLenBy2, fftLenBy2p1;
205 | uint32_t i, j;
206 |
207 | /* Initializations */
208 | j = 0u;
209 | fftLenBy2 = fftLen / 2u;
210 | fftLenBy2p1 = (fftLen / 2u) + 1u;
211 |
212 | /* Bit Reversal Implementation */
213 | for (i = 0u; i <= (fftLenBy2 - 2u); i += 2u)
214 | {
215 | if(i < j)
216 | {
217 | /* pSrc[i] <-> pSrc[j]; */
218 | /* pSrc[i+1u] <-> pSrc[j+1u] */
219 | in = pSrc[i];
220 | pSrc[i] = pSrc[j];
221 | pSrc[j] = in;
222 |
223 | /* pSrc[i + fftLenBy2p1] <-> pSrc[j + fftLenBy2p1]; */
224 | /* pSrc[i + fftLenBy2p1+1u] <-> pSrc[j + fftLenBy2p1+1u] */
225 | in = pSrc[i + fftLenBy2p1];
226 | pSrc[i + fftLenBy2p1] = pSrc[j + fftLenBy2p1];
227 | pSrc[j + fftLenBy2p1] = in;
228 | }
229 |
230 | /* pSrc[i+1u] <-> pSrc[j+fftLenBy2]; */
231 | /* pSrc[i+2] <-> pSrc[j+fftLenBy2+1u] */
232 | in = pSrc[i + 1u];
233 | pSrc[i + 1u] = pSrc[j + fftLenBy2];
234 | pSrc[j + fftLenBy2] = in;
235 |
236 | /* Reading the index for the bit reversal */
237 | j = *pBitRevTab;
238 |
239 | /* Updating the bit reversal index depending on the fft length */
240 | pBitRevTab += bitRevFactor;
241 | }
242 | }
243 |
--------------------------------------------------------------------------------
/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q31.c:
--------------------------------------------------------------------------------
1 | /* ----------------------------------------------------------------------
2 | * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
3 | *
4 | * $Date: 19. March 2015
5 | * $Revision: V.1.4.5
6 | *
7 | * Project: CMSIS DSP Library
8 | * Title: arm_cfft_radix4_init_q31.c
9 | *
10 | * Description: Radix-4 Decimation in Frequency Q31 FFT & IFFT initialization function
11 | *
12 | * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
13 | *
14 | * Redistribution and use in source and binary forms, with or without
15 | * modification, are permitted provided that the following conditions
16 | * are met:
17 | * - Redistributions of source code must retain the above copyright
18 | * notice, this list of conditions and the following disclaimer.
19 | * - Redistributions in binary form must reproduce the above copyright
20 | * notice, this list of conditions and the following disclaimer in
21 | * the documentation and/or other materials provided with the
22 | * distribution.
23 | * - Neither the name of ARM LIMITED nor the names of its contributors
24 | * may be used to endorse or promote products derived from this
25 | * software without specific prior written permission.
26 | *
27 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 | * POSSIBILITY OF SUCH DAMAGE.
39 | * -------------------------------------------------------------------- */
40 |
41 | #include "arm_math.h"
42 | #include "arm_common_tables.h"
43 |
44 | /**
45 | * @ingroup groupTransforms
46 | */
47 |
48 | /**
49 | * @addtogroup ComplexFFT
50 | * @{
51 | */
52 |
53 | /**
54 | *
55 | * @brief Initialization function for the Q31 CFFT/CIFFT.
56 | * @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q31 and will be removed
57 | * @param[in,out] *S points to an instance of the Q31 CFFT/CIFFT structure.
58 | * @param[in] fftLen length of the FFT.
59 | * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform.
60 | * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
61 | * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen
is not a supported value.
62 | *
63 | * \par Description:
64 | * \par
65 | * The parameter ifftFlag
controls whether a forward or inverse transform is computed.
66 | * Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated
67 | * \par
68 | * The parameter bitReverseFlag
controls whether output is in normal order or bit reversed order.
69 | * Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order.
70 | * \par
71 | * The parameter fftLen
Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024.
72 | * \par
73 | * This Function also initializes Twiddle factor table pointer and Bit reversal table pointer.
74 | */
75 |
76 | arm_status arm_cfft_radix4_init_q31(
77 | arm_cfft_radix4_instance_q31 * S,
78 | uint16_t fftLen,
79 | uint8_t ifftFlag,
80 | uint8_t bitReverseFlag)
81 | {
82 | /* Initialise the default arm status */
83 | arm_status status = ARM_MATH_SUCCESS;
84 | /* Initialise the FFT length */
85 | S->fftLen = fftLen;
86 | /* Initialise the Twiddle coefficient pointer */
87 | S->pTwiddle = (q31_t *) twiddleCoef_4096_q31;
88 | /* Initialise the Flag for selection of CFFT or CIFFT */
89 | S->ifftFlag = ifftFlag;
90 | /* Initialise the Flag for calculation Bit reversal or not */
91 | S->bitReverseFlag = bitReverseFlag;
92 |
93 | /* Initializations of Instance structure depending on the FFT length */
94 | switch (S->fftLen)
95 | {
96 | /* Initializations of structure parameters for 4096 point FFT */
97 | case 4096u:
98 | /* Initialise the twiddle coef modifier value */
99 | S->twidCoefModifier = 1u;
100 | /* Initialise the bit reversal table modifier */
101 | S->bitRevFactor = 1u;
102 | /* Initialise the bit reversal table pointer */
103 | S->pBitRevTable = (uint16_t *) armBitRevTable;
104 | break;
105 |
106 | /* Initializations of structure parameters for 1024 point FFT */
107 | case 1024u:
108 | /* Initialise the twiddle coef modifier value */
109 | S->twidCoefModifier = 4u;
110 | /* Initialise the bit reversal table modifier */
111 | S->bitRevFactor = 4u;
112 | /* Initialise the bit reversal table pointer */
113 | S->pBitRevTable = (uint16_t *) & armBitRevTable[3];
114 | break;
115 |
116 | case 256u:
117 | /* Initializations of structure parameters for 256 point FFT */
118 | S->twidCoefModifier = 16u;
119 | S->bitRevFactor = 16u;
120 | S->pBitRevTable = (uint16_t *) & armBitRevTable[15];
121 | break;
122 |
123 | case 64u:
124 | /* Initializations of structure parameters for 64 point FFT */
125 | S->twidCoefModifier = 64u;
126 | S->bitRevFactor = 64u;
127 | S->pBitRevTable = (uint16_t *) & armBitRevTable[63];
128 | break;
129 |
130 | case 16u:
131 | /* Initializations of structure parameters for 16 point FFT */
132 | S->twidCoefModifier = 256u;
133 | S->bitRevFactor = 256u;
134 | S->pBitRevTable = (uint16_t *) & armBitRevTable[255];
135 | break;
136 |
137 | default:
138 | /* Reporting argument error if fftSize is not valid value */
139 | status = ARM_MATH_ARGUMENT_ERROR;
140 | break;
141 | }
142 |
143 | return (status);
144 | }
145 |
146 | /**
147 | * @} end of ComplexFFT group
148 | */
149 |
--------------------------------------------------------------------------------
/CMSIS/DSP_Lib/license.txt:
--------------------------------------------------------------------------------
1 | All files contained in the folders "CMSIS\DSP-Lib\Source" and "CMSIS\DSP-Lib\Examples"
2 | are guided by the following license:
3 |
4 | Copyright (C) 2009-2015 ARM Limited.
5 | All rights reserved.
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 | - Redistributions of source code must retain the above copyright
10 | notice, this list of conditions and the following disclaimer.
11 | - Redistributions in binary form must reproduce the above copyright
12 | notice, this list of conditions and the following disclaimer in the
13 | documentation and/or other materials provided with the distribution.
14 | - Neither the name of ARM nor the names of its contributors may be used
15 | to endorse or promote products derived from this software without
16 | specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 | ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
22 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 | POSSIBILITY OF SUCH DAMAGE.
29 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #############################################################################
2 | # Build global options
3 | # NOTE: Can be overridden externally.
4 | #
5 |
6 | # Compiler options here.
7 | ifeq ($(USE_OPT),)
8 | USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16
9 | endif
10 |
11 | # C specific options here (added to USE_OPT).
12 | ifeq ($(USE_COPT),)
13 | USE_COPT =
14 | endif
15 |
16 | # C++ specific options here (added to USE_OPT).
17 | ifeq ($(USE_CPPOPT),)
18 | USE_CPPOPT = -fno-rtti
19 | endif
20 |
21 | # Enable this if you want the linker to remove unused code and data
22 | ifeq ($(USE_LINK_GC),)
23 | USE_LINK_GC = yes
24 | endif
25 |
26 | # Linker extra options here.
27 | ifeq ($(USE_LDOPT),)
28 | USE_LDOPT =
29 | endif
30 |
31 | # Enable this if you want link time optimizations (LTO)
32 | ifeq ($(USE_LTO),)
33 | USE_LTO = no
34 | endif
35 |
36 | # If enabled, this option allows to compile the application in THUMB mode.
37 | ifeq ($(USE_THUMB),)
38 | USE_THUMB = yes
39 | endif
40 |
41 | # Enable this if you want to see the full log while compiling.
42 | ifeq ($(USE_VERBOSE_COMPILE),)
43 | USE_VERBOSE_COMPILE = no
44 | endif
45 |
46 | # If enabled, this option makes the build process faster by not compiling
47 | # modules not used in the current configuration.
48 | ifeq ($(USE_SMART_BUILD),)
49 | USE_SMART_BUILD = yes
50 | endif
51 |
52 | #
53 | # Build global options
54 | ##############################################################################
55 |
56 | ##############################################################################
57 | # Architecture or project specific options
58 | #
59 |
60 | # Enables the use of FPU on Cortex-M4 (no, softfp, hard).
61 | ifeq ($(USE_FPU),)
62 | USE_FPU = hard
63 | endif
64 |
65 | # Stack size to be allocated to the Cortex-M process stack. This stack is
66 | # the stack used by the main() thread.
67 | ifeq ($(USE_PROCESS_STACKSIZE),)
68 | USE_PROCESS_STACKSIZE = 0x400
69 | endif
70 |
71 | # Stack size to the allocated to the Cortex-M main/exceptions stack. This
72 | # stack is used for processing interrupts and exceptions.
73 | ifeq ($(USE_EXCEPTIONS_STACKSIZE),)
74 | USE_EXCEPTIONS_STACKSIZE = 0x400
75 | endif
76 |
77 | #
78 | # Architecture or project specific options
79 | ##############################################################################
80 |
81 | ##############################################################################
82 | # Project, sources and paths
83 | #
84 |
85 | # Define project name here
86 | PROJECT = ch
87 |
88 | # Imported source files and paths
89 | CHIBIOS = ChibiOS
90 | PROJ = .
91 | # Startup files.
92 | include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f3xx.mk
93 | # HAL-OSAL files (optional).
94 | include $(CHIBIOS)/os/hal/hal.mk
95 | include $(CHIBIOS)/os/hal/ports/STM32/STM32F3xx/platform.mk
96 | #include $(CHIBIOS)/os/hal/boards/NANOSDR_STM32_F303/board.mk
97 | include NANOSDR_STM32_F303/board.mk
98 | include $(CHIBIOS)/os/hal/osal/rt/osal.mk
99 | # RTOS files (optional).
100 | include $(CHIBIOS)/os/rt/rt.mk
101 | include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk
102 | # Other files (optional).
103 | #include $(CHIBIOS)/test/rt/test.mk
104 | include $(CHIBIOS)/os/hal/lib/streams/streams.mk
105 | include $(CHIBIOS)/os/various/shell/shell.mk
106 |
107 | # Define linker script file here
108 | #LDSCRIPT= $(STARTUPLD)/STM32F303xC.ld
109 | LDSCRIPT= STM32F303xB.ld
110 |
111 | CMSIS = CMSIS
112 | DSPLIBINC = ${CMSIS}/Include
113 | DSPLIBSRC = ${CMSIS}/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_q15.c \
114 | ${CMSIS}/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q31.c \
115 | ${CMSIS}/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_q31.c \
116 | ${CMSIS}/DSP_Lib/Source/TransformFunctions/arm_bitreversal.c \
117 | ${CMSIS}/DSP_Lib/Source/CommonTables/arm_common_tables.c
118 |
119 | # C sources that can be compiled in ARM or THUMB mode depending on the global
120 | # setting.
121 | CSRC = $(STARTUPSRC) \
122 | $(KERNSRC) \
123 | $(PORTSRC) \
124 | $(OSALSRC) \
125 | $(HALSRC) \
126 | $(PLATFORMSRC) \
127 | $(BOARDSRC) \
128 | $(STREAMSSRC) \
129 | $(SHELLSRC) \
130 | $(DSPLIBSRC) \
131 | usbcfg.c \
132 | si5351.c si5351_low.c tlv320aic3204.c ui.c \
133 | display.c ili9341.c numfont20x24.c numfont32x24.c Font5x7.c icons.c \
134 | dsp.c main.c flash.c crt2.c
135 |
136 | # C++ sources that can be compiled in ARM or THUMB mode depending on the global
137 | # setting.
138 | CPPSRC =
139 |
140 | # C sources to be compiled in ARM mode regardless of the global setting.
141 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
142 | # option that results in lower performance and larger code size.
143 | ACSRC =
144 |
145 | # C++ sources to be compiled in ARM mode regardless of the global setting.
146 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
147 | # option that results in lower performance and larger code size.
148 | ACPPSRC =
149 |
150 | # C sources to be compiled in THUMB mode regardless of the global setting.
151 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
152 | # option that results in lower performance and larger code size.
153 | TCSRC =
154 |
155 | # C sources to be compiled in THUMB mode regardless of the global setting.
156 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
157 | # option that results in lower performance and larger code size.
158 | TCPPSRC =
159 |
160 | # List ASM source files here
161 | ASMSRC = $(STARTUPASM) $(PORTASM) $(OSALASM)
162 |
163 | INCDIR = $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \
164 | $(HALINC) $(PLATFORMINC) $(BOARDINC) \
165 | $(DSPLIBINC) \
166 | $(STREAMSINC) $(SHELLINC)
167 |
168 | #
169 | # Project, sources and paths
170 | ##############################################################################
171 |
172 | ##############################################################################
173 | # Compiler settings
174 | #
175 |
176 | MCU = cortex-m4
177 |
178 | #TRGT = arm-elf-
179 | TRGT = arm-none-eabi-
180 | CC = $(TRGT)gcc
181 | CPPC = $(TRGT)g++
182 | # Enable loading with g++ only if you need C++ runtime support.
183 | # NOTE: You can use C++ even without C++ support if you are careful. C++
184 | # runtime support makes code size explode.
185 | LD = $(TRGT)gcc
186 | #LD = $(TRGT)g++
187 | CP = $(TRGT)objcopy
188 | AS = $(TRGT)gcc -x assembler-with-cpp
189 | AR = $(TRGT)ar
190 | OD = $(TRGT)objdump
191 | SZ = $(TRGT)size
192 | HEX = $(CP) -O ihex
193 | BIN = $(CP) -O binary
194 |
195 | # ARM-specific options here
196 | AOPT =
197 |
198 | # THUMB-specific options here
199 | TOPT = -mthumb -DTHUMB
200 |
201 | # Define C warning options here
202 | CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes
203 |
204 | # Define C++ warning options here
205 | CPPWARN = -Wall -Wextra -Wundef
206 |
207 | #
208 | # Compiler settings
209 | ##############################################################################
210 |
211 | ##############################################################################
212 | # Start of user section
213 | #
214 |
215 | # List all user C define here, like -D_DEBUG=1
216 | UDEFS = -DSHELL_CMD_TEST_ENABLED=0 -DARM_MATH_CM4 -D__FPU_PRESENT -D__FPU_USED
217 |
218 | # Define ASM defines here
219 | UADEFS =
220 |
221 | # List all user directories here
222 | UINCDIR =
223 |
224 | # List the user directory to look for the libraries here
225 | ULIBDIR =
226 |
227 | # List all user libraries here
228 | ULIBS = -lm
229 |
230 | #
231 | # End of user defines
232 | ##############################################################################
233 |
234 | RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC
235 | include $(RULESPATH)/rules.mk
236 |
237 | OS_SRCS=$(shell find ChibiOS/os/hal/ports/STM32/STM32F3xx ChibiOS/os -name \*.\[ch\] -print)
238 |
239 | TAGS: Makefile
240 | @etags *.[ch] NANOSDR_STM32_F303/*.[ch] $(OS_SRCS)
241 | @ls -l TAGS
242 |
243 | .PHONY: flash
244 |
245 | flash: all
246 | arm-none-eabi-gdb -x flash-stutil.gdb --silent
247 | @#arm-none-eabi-gdb -x flash-openocd.gdb --silent
248 |
249 | RELEASE=$(shell date +%Y%m%d)
250 | DIST_FILES= build/ch.bin build/ch.hex build/ch.elf
251 |
252 | release: all
253 | zip centsdr-${RELEASE}.zip ${DIST_FILES}
254 |
--------------------------------------------------------------------------------
/NANOSDR_STM32_F303/board.c:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include "hal.h"
18 |
19 | #if HAL_USE_PAL || defined(__DOXYGEN__)
20 | /**
21 | * @brief PAL setup.
22 | * @details Digital I/O ports static configuration as defined in @p board.h.
23 | * This variable is used by the HAL when initializing the PAL driver.
24 | */
25 | const PALConfig pal_default_config = {
26 | #if STM32_HAS_GPIOA
27 | {VAL_GPIOA_MODER, VAL_GPIOA_OTYPER, VAL_GPIOA_OSPEEDR, VAL_GPIOA_PUPDR,
28 | VAL_GPIOA_ODR, VAL_GPIOA_AFRL, VAL_GPIOA_AFRH},
29 | #endif
30 | #if STM32_HAS_GPIOB
31 | {VAL_GPIOB_MODER, VAL_GPIOB_OTYPER, VAL_GPIOB_OSPEEDR, VAL_GPIOB_PUPDR,
32 | VAL_GPIOB_ODR, VAL_GPIOB_AFRL, VAL_GPIOB_AFRH},
33 | #endif
34 | #if STM32_HAS_GPIOC
35 | {VAL_GPIOC_MODER, VAL_GPIOC_OTYPER, VAL_GPIOC_OSPEEDR, VAL_GPIOC_PUPDR,
36 | VAL_GPIOC_ODR, VAL_GPIOC_AFRL, VAL_GPIOC_AFRH},
37 | #endif
38 | #if STM32_HAS_GPIOD
39 | {VAL_GPIOD_MODER, VAL_GPIOD_OTYPER, VAL_GPIOD_OSPEEDR, VAL_GPIOD_PUPDR,
40 | VAL_GPIOD_ODR, VAL_GPIOD_AFRL, VAL_GPIOD_AFRH},
41 | #endif
42 | #if STM32_HAS_GPIOE
43 | {VAL_GPIOE_MODER, VAL_GPIOE_OTYPER, VAL_GPIOE_OSPEEDR, VAL_GPIOE_PUPDR,
44 | VAL_GPIOE_ODR, VAL_GPIOE_AFRL, VAL_GPIOE_AFRH},
45 | #endif
46 | #if STM32_HAS_GPIOF
47 | {VAL_GPIOF_MODER, VAL_GPIOF_OTYPER, VAL_GPIOF_OSPEEDR, VAL_GPIOF_PUPDR,
48 | VAL_GPIOF_ODR, VAL_GPIOF_AFRL, VAL_GPIOF_AFRH},
49 | #endif
50 | #if STM32_HAS_GPIOG
51 | {VAL_GPIOG_MODER, VAL_GPIOG_OTYPER, VAL_GPIOG_OSPEEDR, VAL_GPIOG_PUPDR,
52 | VAL_GPIOG_ODR, VAL_GPIOG_AFRL, VAL_GPIOG_AFRH},
53 | #endif
54 | #if STM32_HAS_GPIOH
55 | {VAL_GPIOH_MODER, VAL_GPIOH_OTYPER, VAL_GPIOH_OSPEEDR, VAL_GPIOH_PUPDR,
56 | VAL_GPIOH_ODR, VAL_GPIOH_AFRL, VAL_GPIOH_AFRH},
57 | #endif
58 | #if STM32_HAS_GPIOI
59 | {VAL_GPIOI_MODER, VAL_GPIOI_OTYPER, VAL_GPIOI_OSPEEDR, VAL_GPIOI_PUPDR,
60 | VAL_GPIOI_ODR, VAL_GPIOI_AFRL, VAL_GPIOI_AFRH}
61 | #endif
62 | };
63 | #endif
64 |
65 | extern void si5351_setup(void);
66 |
67 | /*
68 | * Early initialization code.
69 | * This initialization must be performed just after stack setup and before
70 | * any other initialization.
71 | */
72 | void __early_init(void) {
73 | si5351_setup();
74 | stm32_clock_init();
75 | }
76 |
77 | /*
78 | * Board-specific initialization code.
79 | */
80 | void boardInit(void) {
81 | }
82 |
--------------------------------------------------------------------------------
/NANOSDR_STM32_F303/board.mk:
--------------------------------------------------------------------------------
1 | # List of all the board related files.
2 | #BOARDSRC = ${CHIBIOS}/os/hal/boards/NANOSDR_STM32_F303/board.c
3 | BOARDSRC = ${PROJ}/NANOSDR_STM32_F303/board.c
4 |
5 | # Required include directories
6 | #BOARDINC = ${CHIBIOS}/os/hal/boards/NANOSDR_STM32_F303
7 | BOARDINC = ${PROJ}/NANOSDR_STM32_F303
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | CentSDR - Tiny Standalone Software Defined Receiver
2 | ==========================================================
3 |
4 |
5 |

6 |
7 |
8 | # About
9 |
10 | CentSDR is tiny handheld standalone software defined receiver with LCD display,
11 | that is simple, low budget, but has reasonable perfomance.
12 | This project is aimed at contributing to studies, experiments and educations around
13 | RF technology.
14 |
15 | # Block Diagram
16 |
17 |
18 |

19 |
20 |
21 | # Build Firmware
22 |
23 | ## Prepare ARM Cross Tools
24 |
25 | Install cross tools and firmware updating tool.
26 |
27 | $ brew cask install gcc-arm-embedded
28 |
29 | ## Fetch Source
30 |
31 | Clone source code from github.
32 |
33 | $ git clone https://github.com/ttrftech/CentSDR centsdr
34 |
35 | Then fetch ChibiOS submodule into tree.
36 |
37 | $ cd centsdr
38 | $ git submodule update --init --recursive
39 |
40 | Just make in the top directory.
41 |
42 | $ make
43 |
44 | ## Flash firmware
45 |
46 | ### Using OpenOCD and gdb
47 |
48 | Prepare openocd.
49 |
50 | $ brew install openocd
51 |
52 | Connect ST-Link2 to target board, then launch openocd as follows.
53 |
54 | $ openocd -f board/stm32f3discovery.cfg
55 |
56 | Flash firmware using gdb.
57 |
58 | $ arm-none-eabi-gdb
59 | > target extended-remote :4242
60 | > exec build/ch.elf
61 | > load
62 | > quit
63 |
64 | Or use gdb script to flash.
65 |
66 | $ arm-none-eabi-gdb -x flash-openocd.gdb --silent
67 |
68 | ### Using st-util and gdb
69 |
70 | Prepare stlink utilities.
71 |
72 | $ brew install stlink
73 |
74 | Connect target board via SWD with ST-Link2, In other terminal, launch st-util
75 |
76 | $ st-util
77 |
78 | Then, flash the firmware.
79 |
80 | $ arm-none-eabi-gdb -x flash-stutil.gdb --silent
81 |
82 | ## Flash firmware using Nucleo st-link v2.1
83 |
84 | Or you can flash the firmware using Nucleo. First, mount as usb mass storage device, then copy 'build/ch.bin' file into mounted volume.
85 |
86 | ## Attention
87 |
88 | This repository contains only source of CentSDR firmware, but NO hardware design resources.
89 |
90 | ## Reference
91 |
92 | * Kit available from http://ttrftech.tumblr.com/kit/centsdr
93 | * Credit: @edy555
94 |
95 | [EOF]
96 |
--------------------------------------------------------------------------------
/STM32F303xB.ld:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | /*
18 | * STM32F303xB memory setup.
19 | */
20 | MEMORY
21 | {
22 | flash0 : org = 0x08000000, len = 128k
23 | flash1 : org = 0x00000000, len = 0
24 | flash2 : org = 0x00000000, len = 0
25 | flash3 : org = 0x00000000, len = 0
26 | flash4 : org = 0x00000000, len = 0
27 | flash5 : org = 0x00000000, len = 0
28 | flash6 : org = 0x00000000, len = 0
29 | flash7 : org = 0x00000000, len = 0
30 | ram0 : org = 0x20000000, len = 40k
31 | ram1 : org = 0x00000000, len = 0
32 | ram2 : org = 0x00000000, len = 0
33 | ram3 : org = 0x00000000, len = 0
34 | ram4 : org = 0x10000000, len = 8k
35 | ram5 : org = 0x00000000, len = 0
36 | ram6 : org = 0x00000000, len = 0
37 | ram7 : org = 0x00000000, len = 0
38 | }
39 |
40 | /* For each data/text section two region are defined, a virtual region
41 | and a load region (_LMA suffix).*/
42 |
43 | /* Flash region to be used for exception vectors.*/
44 | REGION_ALIAS("VECTORS_FLASH", flash0);
45 | REGION_ALIAS("VECTORS_FLASH_LMA", flash0);
46 |
47 | /* Flash region to be used for constructors and destructors.*/
48 | REGION_ALIAS("XTORS_FLASH", flash0);
49 | REGION_ALIAS("XTORS_FLASH_LMA", flash0);
50 |
51 | /* Flash region to be used for code text.*/
52 | REGION_ALIAS("TEXT_FLASH", flash0);
53 | REGION_ALIAS("TEXT_FLASH_LMA", flash0);
54 |
55 | /* Flash region to be used for read only data.*/
56 | REGION_ALIAS("RODATA_FLASH", flash0);
57 | REGION_ALIAS("RODATA_FLASH_LMA", flash0);
58 |
59 | /* Flash region to be used for various.*/
60 | REGION_ALIAS("VARIOUS_FLASH", flash0);
61 | REGION_ALIAS("VARIOUS_FLASH_LMA", flash0);
62 |
63 | /* Flash region to be used for RAM(n) initialization data.*/
64 | REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0);
65 |
66 | /* RAM region to be used for Main stack. This stack accommodates the processing
67 | of all exceptions and interrupts.*/
68 | REGION_ALIAS("MAIN_STACK_RAM", ram0);
69 |
70 | /* RAM region to be used for the process stack. This is the stack used by
71 | the main() function.*/
72 | REGION_ALIAS("PROCESS_STACK_RAM", ram0);
73 |
74 | /* RAM region to be used for data segment.*/
75 | REGION_ALIAS("DATA_RAM", ram0);
76 | REGION_ALIAS("DATA_RAM_LMA", flash0);
77 |
78 | /* RAM region to be used for BSS segment.*/
79 | REGION_ALIAS("BSS_RAM", ram0);
80 |
81 | /* RAM region to be used for the default heap.*/
82 | REGION_ALIAS("HEAP_RAM", ram0);
83 |
84 | /* Generic rules inclusion.*/
85 | INCLUDE rules.ld
86 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 | set -e
3 | set -x
4 |
5 | make
6 |
--------------------------------------------------------------------------------
/ccmfunc.ld:
--------------------------------------------------------------------------------
1 | .ccmfunc : ALIGN(4)
2 | {
3 | . = ALIGN(4);
4 | __ccmfunc_init_text__ = LOADADDR(.ccmfunc);
5 | __ccmfunc_init__ = .;
6 | *dsp.o(.text.*)
7 | *dsp.o(.rodata.arctantbl)
8 | *arm_biquad_cascade_df1_q15.o(.text.*)
9 | *arm_cfft_radix4_q31.o(.text.*)
10 | *arm_bitreversal.o(.text.*)
11 | *display.o(.text.draw_waveform)
12 | *display.o(.text.draw_waterfall)
13 | *display.o(.text.draw_spectrogram)
14 | *display.o(.text.disp_fetch_samples)
15 | __ccmfunc_end__ = .;
16 | . = ALIGN(4);
17 | } > ram4 AT > RAM_INIT_FLASH_LMA
18 |
--------------------------------------------------------------------------------
/chconf.h:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | /**
18 | * @file templates/chconf.h
19 | * @brief Configuration file template.
20 | * @details A copy of this file must be placed in each project directory, it
21 | * contains the application specific kernel settings.
22 | *
23 | * @addtogroup config
24 | * @details Kernel related settings and hooks.
25 | * @{
26 | */
27 |
28 | #ifndef _CHCONF_H_
29 | #define _CHCONF_H_
30 |
31 | #define _CHIBIOS_RT_CONF_
32 |
33 | /*===========================================================================*/
34 | /**
35 | * @name System timers settings
36 | * @{
37 | */
38 | /*===========================================================================*/
39 |
40 | /**
41 | * @brief System time counter resolution.
42 | * @note Allowed values are 16 or 32 bits.
43 | */
44 | #define CH_CFG_ST_RESOLUTION 32
45 |
46 | /**
47 | * @brief System tick frequency.
48 | * @details Frequency of the system timer that drives the system ticks. This
49 | * setting also defines the system tick time unit.
50 | */
51 | #define CH_CFG_ST_FREQUENCY 10000
52 |
53 | /**
54 | * @brief Time delta constant for the tick-less mode.
55 | * @note If this value is zero then the system uses the classic
56 | * periodic tick. This value represents the minimum number
57 | * of ticks that is safe to specify in a timeout directive.
58 | * The value one is not valid, timeouts are rounded up to
59 | * this value.
60 | */
61 | #define CH_CFG_ST_TIMEDELTA 2
62 |
63 | /** @} */
64 |
65 | /*===========================================================================*/
66 | /**
67 | * @name Kernel parameters and options
68 | * @{
69 | */
70 | /*===========================================================================*/
71 |
72 | /**
73 | * @brief Round robin interval.
74 | * @details This constant is the number of system ticks allowed for the
75 | * threads before preemption occurs. Setting this value to zero
76 | * disables the preemption for threads with equal priority and the
77 | * round robin becomes cooperative. Note that higher priority
78 | * threads can still preempt, the kernel is always preemptive.
79 | * @note Disabling the round robin preemption makes the kernel more compact
80 | * and generally faster.
81 | * @note The round robin preemption is not supported in tickless mode and
82 | * must be set to zero in that case.
83 | */
84 | #define CH_CFG_TIME_QUANTUM 0
85 |
86 | /**
87 | * @brief Managed RAM size.
88 | * @details Size of the RAM area to be managed by the OS. If set to zero
89 | * then the whole available RAM is used. The core memory is made
90 | * available to the heap allocator and/or can be used directly through
91 | * the simplified core memory allocator.
92 | *
93 | * @note In order to let the OS manage the whole RAM the linker script must
94 | * provide the @p __heap_base__ and @p __heap_end__ symbols.
95 | * @note Requires @p CH_CFG_USE_MEMCORE.
96 | */
97 | #define CH_CFG_MEMCORE_SIZE 0
98 |
99 | /**
100 | * @brief Idle thread automatic spawn suppression.
101 | * @details When this option is activated the function @p chSysInit()
102 | * does not spawn the idle thread. The application @p main()
103 | * function becomes the idle thread and must implement an
104 | * infinite loop. */
105 | #define CH_CFG_NO_IDLE_THREAD FALSE
106 |
107 | /** @} */
108 |
109 | /*===========================================================================*/
110 | /**
111 | * @name Performance options
112 | * @{
113 | */
114 | /*===========================================================================*/
115 |
116 | /**
117 | * @brief OS optimization.
118 | * @details If enabled then time efficient rather than space efficient code
119 | * is used when two possible implementations exist.
120 | *
121 | * @note This is not related to the compiler optimization options.
122 | * @note The default is @p TRUE.
123 | */
124 | #define CH_CFG_OPTIMIZE_SPEED TRUE
125 |
126 | /** @} */
127 |
128 | /*===========================================================================*/
129 | /**
130 | * @name Subsystem options
131 | * @{
132 | */
133 | /*===========================================================================*/
134 |
135 | /**
136 | * @brief Time Measurement APIs.
137 | * @details If enabled then the time measurement APIs are included in
138 | * the kernel.
139 | *
140 | * @note The default is @p TRUE.
141 | */
142 | #define CH_CFG_USE_TM FALSE
143 |
144 | /**
145 | * @brief Threads registry APIs.
146 | * @details If enabled then the registry APIs are included in the kernel.
147 | *
148 | * @note The default is @p TRUE.
149 | */
150 | #define CH_CFG_USE_REGISTRY TRUE
151 |
152 | /**
153 | * @brief Threads synchronization APIs.
154 | * @details If enabled then the @p chThdWait() function is included in
155 | * the kernel.
156 | *
157 | * @note The default is @p TRUE.
158 | */
159 | #define CH_CFG_USE_WAITEXIT TRUE
160 |
161 | /**
162 | * @brief Semaphores APIs.
163 | * @details If enabled then the Semaphores APIs are included in the kernel.
164 | *
165 | * @note The default is @p TRUE.
166 | */
167 | #define CH_CFG_USE_SEMAPHORES TRUE
168 |
169 | /**
170 | * @brief Semaphores queuing mode.
171 | * @details If enabled then the threads are enqueued on semaphores by
172 | * priority rather than in FIFO order.
173 | *
174 | * @note The default is @p FALSE. Enable this if you have special
175 | * requirements.
176 | * @note Requires @p CH_CFG_USE_SEMAPHORES.
177 | */
178 | #define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE
179 |
180 | /**
181 | * @brief Mutexes APIs.
182 | * @details If enabled then the mutexes APIs are included in the kernel.
183 | *
184 | * @note The default is @p TRUE.
185 | */
186 | #define CH_CFG_USE_MUTEXES TRUE
187 |
188 | /**
189 | * @brief Enables recursive behavior on mutexes.
190 | * @note Recursive mutexes are heavier and have an increased
191 | * memory footprint.
192 | *
193 | * @note The default is @p FALSE.
194 | * @note Requires @p CH_CFG_USE_MUTEXES.
195 | */
196 | #define CH_CFG_USE_MUTEXES_RECURSIVE FALSE
197 |
198 | /**
199 | * @brief Conditional Variables APIs.
200 | * @details If enabled then the conditional variables APIs are included
201 | * in the kernel.
202 | *
203 | * @note The default is @p TRUE.
204 | * @note Requires @p CH_CFG_USE_MUTEXES.
205 | */
206 | #define CH_CFG_USE_CONDVARS TRUE
207 |
208 | /**
209 | * @brief Conditional Variables APIs with timeout.
210 | * @details If enabled then the conditional variables APIs with timeout
211 | * specification are included in the kernel.
212 | *
213 | * @note The default is @p TRUE.
214 | * @note Requires @p CH_CFG_USE_CONDVARS.
215 | */
216 | #define CH_CFG_USE_CONDVARS_TIMEOUT TRUE
217 |
218 | /**
219 | * @brief Events Flags APIs.
220 | * @details If enabled then the event flags APIs are included in the kernel.
221 | *
222 | * @note The default is @p TRUE.
223 | */
224 | #define CH_CFG_USE_EVENTS TRUE
225 |
226 | /**
227 | * @brief Events Flags APIs with timeout.
228 | * @details If enabled then the events APIs with timeout specification
229 | * are included in the kernel.
230 | *
231 | * @note The default is @p TRUE.
232 | * @note Requires @p CH_CFG_USE_EVENTS.
233 | */
234 | #define CH_CFG_USE_EVENTS_TIMEOUT TRUE
235 |
236 | /**
237 | * @brief Synchronous Messages APIs.
238 | * @details If enabled then the synchronous messages APIs are included
239 | * in the kernel.
240 | *
241 | * @note The default is @p TRUE.
242 | */
243 | #define CH_CFG_USE_MESSAGES TRUE
244 |
245 | /**
246 | * @brief Synchronous Messages queuing mode.
247 | * @details If enabled then messages are served by priority rather than in
248 | * FIFO order.
249 | *
250 | * @note The default is @p FALSE. Enable this if you have special
251 | * requirements.
252 | * @note Requires @p CH_CFG_USE_MESSAGES.
253 | */
254 | #define CH_CFG_USE_MESSAGES_PRIORITY FALSE
255 |
256 | /**
257 | * @brief Mailboxes APIs.
258 | * @details If enabled then the asynchronous messages (mailboxes) APIs are
259 | * included in the kernel.
260 | *
261 | * @note The default is @p TRUE.
262 | * @note Requires @p CH_CFG_USE_SEMAPHORES.
263 | */
264 | #define CH_CFG_USE_MAILBOXES TRUE
265 |
266 | /**
267 | * @brief I/O Queues APIs.
268 | * @details If enabled then the I/O queues APIs are included in the kernel.
269 | *
270 | * @note The default is @p TRUE.
271 | */
272 | #define CH_CFG_USE_QUEUES TRUE
273 |
274 | /**
275 | * @brief Core Memory Manager APIs.
276 | * @details If enabled then the core memory manager APIs are included
277 | * in the kernel.
278 | *
279 | * @note The default is @p TRUE.
280 | */
281 | #define CH_CFG_USE_MEMCORE TRUE
282 |
283 | /**
284 | * @brief Heap Allocator APIs.
285 | * @details If enabled then the memory heap allocator APIs are included
286 | * in the kernel.
287 | *
288 | * @note The default is @p TRUE.
289 | * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or
290 | * @p CH_CFG_USE_SEMAPHORES.
291 | * @note Mutexes are recommended.
292 | */
293 | #define CH_CFG_USE_HEAP TRUE
294 |
295 | /**
296 | * @brief Memory Pools Allocator APIs.
297 | * @details If enabled then the memory pools allocator APIs are included
298 | * in the kernel.
299 | *
300 | * @note The default is @p TRUE.
301 | */
302 | #define CH_CFG_USE_MEMPOOLS TRUE
303 |
304 | /**
305 | * @brief Dynamic Threads APIs.
306 | * @details If enabled then the dynamic threads creation APIs are included
307 | * in the kernel.
308 | *
309 | * @note The default is @p TRUE.
310 | * @note Requires @p CH_CFG_USE_WAITEXIT.
311 | * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS.
312 | */
313 | #define CH_CFG_USE_DYNAMIC TRUE
314 |
315 | /** @} */
316 |
317 | /*===========================================================================*/
318 | /**
319 | * @name Debug options
320 | * @{
321 | */
322 | /*===========================================================================*/
323 |
324 | /**
325 | * @brief Debug option, kernel statistics.
326 | *
327 | * @note The default is @p FALSE.
328 | */
329 | #define CH_DBG_STATISTICS FALSE
330 |
331 | /**
332 | * @brief Debug option, system state check.
333 | * @details If enabled the correct call protocol for system APIs is checked
334 | * at runtime.
335 | *
336 | * @note The default is @p FALSE.
337 | */
338 | #define CH_DBG_SYSTEM_STATE_CHECK TRUE
339 |
340 | /**
341 | * @brief Debug option, parameters checks.
342 | * @details If enabled then the checks on the API functions input
343 | * parameters are activated.
344 | *
345 | * @note The default is @p FALSE.
346 | */
347 | #define CH_DBG_ENABLE_CHECKS TRUE
348 |
349 | /**
350 | * @brief Debug option, consistency checks.
351 | * @details If enabled then all the assertions in the kernel code are
352 | * activated. This includes consistency checks inside the kernel,
353 | * runtime anomalies and port-defined checks.
354 | *
355 | * @note The default is @p FALSE.
356 | */
357 | #define CH_DBG_ENABLE_ASSERTS TRUE
358 |
359 | /**
360 | * @brief Debug option, trace buffer.
361 | * @details If enabled then the trace buffer is activated.
362 | *
363 | * @note The default is @p CH_DBG_TRACE_MASK_DISABLED.
364 | */
365 | #define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED
366 |
367 | /**
368 | * @brief Trace buffer entries.
369 | * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is
370 | * different from @p CH_DBG_TRACE_MASK_DISABLED.
371 | */
372 | #define CH_DBG_TRACE_BUFFER_SIZE 128
373 |
374 | /**
375 | * @brief Debug option, stack checks.
376 | * @details If enabled then a runtime stack check is performed.
377 | *
378 | * @note The default is @p FALSE.
379 | * @note The stack check is performed in a architecture/port dependent way.
380 | * It may not be implemented or some ports.
381 | * @note The default failure mode is to halt the system with the global
382 | * @p panic_msg variable set to @p NULL.
383 | */
384 | #define CH_DBG_ENABLE_STACK_CHECK TRUE
385 |
386 | /**
387 | * @brief Debug option, stacks initialization.
388 | * @details If enabled then the threads working area is filled with a byte
389 | * value when a thread is created. This can be useful for the
390 | * runtime measurement of the used stack.
391 | *
392 | * @note The default is @p FALSE.
393 | */
394 | #define CH_DBG_FILL_THREADS TRUE
395 |
396 | /**
397 | * @brief Debug option, threads profiling.
398 | * @details If enabled then a field is added to the @p thread_t structure that
399 | * counts the system ticks occurred while executing the thread.
400 | *
401 | * @note The default is @p FALSE.
402 | * @note This debug option is not currently compatible with the
403 | * tickless mode.
404 | */
405 | #define CH_DBG_THREADS_PROFILING FALSE
406 |
407 | /** @} */
408 |
409 | /*===========================================================================*/
410 | /**
411 | * @name Kernel hooks
412 | * @{
413 | */
414 | /*===========================================================================*/
415 |
416 | /**
417 | * @brief Threads descriptor structure extension.
418 | * @details User fields added to the end of the @p thread_t structure.
419 | */
420 | #define CH_CFG_THREAD_EXTRA_FIELDS \
421 | /* Add threads custom fields here.*/
422 |
423 | /**
424 | * @brief Threads initialization hook.
425 | * @details User initialization code added to the @p chThdInit() API.
426 | *
427 | * @note It is invoked from within @p chThdInit() and implicitly from all
428 | * the threads creation APIs.
429 | */
430 | #define CH_CFG_THREAD_INIT_HOOK(tp) { \
431 | /* Add threads initialization code here.*/ \
432 | }
433 |
434 | /**
435 | * @brief Threads finalization hook.
436 | * @details User finalization code added to the @p chThdExit() API.
437 | *
438 | * @note It is inserted into lock zone.
439 | * @note It is also invoked when the threads simply return in order to
440 | * terminate.
441 | */
442 | #define CH_CFG_THREAD_EXIT_HOOK(tp) { \
443 | /* Add threads finalization code here.*/ \
444 | }
445 |
446 | /**
447 | * @brief Context switch hook.
448 | * @details This hook is invoked just before switching between threads.
449 | */
450 | #define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \
451 | /* System halt code here.*/ \
452 | }
453 |
454 | /**
455 | * @brief ISR enter hook.
456 | */
457 | #define CH_CFG_IRQ_PROLOGUE_HOOK() { \
458 | /* IRQ prologue code here.*/ \
459 | }
460 |
461 | /**
462 | * @brief ISR exit hook.
463 | */
464 | #define CH_CFG_IRQ_EPILOGUE_HOOK() { \
465 | /* IRQ epilogue code here.*/ \
466 | }
467 |
468 | /**
469 | * @brief Idle thread enter hook.
470 | * @note This hook is invoked within a critical zone, no OS functions
471 | * should be invoked from here.
472 | * @note This macro can be used to activate a power saving mode.
473 | */
474 | #define CH_CFG_IDLE_ENTER_HOOK() { \
475 | }
476 |
477 | /**
478 | * @brief Idle thread leave hook.
479 | * @note This hook is invoked within a critical zone, no OS functions
480 | * should be invoked from here.
481 | * @note This macro can be used to deactivate a power saving mode.
482 | */
483 | #define CH_CFG_IDLE_LEAVE_HOOK() { \
484 | }
485 |
486 | /**
487 | * @brief Idle Loop hook.
488 | * @details This hook is continuously invoked by the idle thread loop.
489 | */
490 | #define CH_CFG_IDLE_LOOP_HOOK() { \
491 | /* Idle loop code here.*/ \
492 | }
493 |
494 | /**
495 | * @brief System tick event hook.
496 | * @details This hook is invoked in the system tick handler immediately
497 | * after processing the virtual timers queue.
498 | */
499 | #define CH_CFG_SYSTEM_TICK_HOOK() { \
500 | /* System tick event code here.*/ \
501 | }
502 |
503 | /**
504 | * @brief System halt hook.
505 | * @details This hook is invoked in case to a system halting error before
506 | * the system is halted.
507 | */
508 | #define CH_CFG_SYSTEM_HALT_HOOK(reason) { \
509 | /* System halt code here.*/ \
510 | }
511 |
512 | /**
513 | * @brief Trace hook.
514 | * @details This hook is invoked each time a new record is written in the
515 | * trace buffer.
516 | */
517 | #define CH_CFG_TRACE_HOOK(tep) { \
518 | /* Trace code here.*/ \
519 | }
520 |
521 | /** @} */
522 |
523 | /*===========================================================================*/
524 | /* Port-specific settings (override port settings defaulted in chcore.h). */
525 | /*===========================================================================*/
526 |
527 | #endif /* _CHCONF_H_ */
528 |
529 | /** @} */
530 |
--------------------------------------------------------------------------------
/crt2.c:
--------------------------------------------------------------------------------
1 | #include "ch.h"
2 | #include "hal.h"
3 |
4 | extern uint32_t __ccmfunc_init_text__, __ccmfunc_init__, __ccmfunc_end__;
5 |
6 | /*
7 | * Late initialization code.
8 | */
9 | void __late_init(void) {
10 | // CCM RAM protection register
11 | SYSCFG->RCR = 0x0000;
12 |
13 | /* Copying CCM initialization code. */
14 | uint32_t *tp = &__ccmfunc_init_text__;
15 | uint32_t *p = &__ccmfunc_init__;
16 |
17 | while (p < &__ccmfunc_end__) {
18 | *p = *tp;
19 | p++;
20 | tp++;
21 | }
22 |
23 | // CCM RAM protection register
24 | SYSCFG->RCR = 0x00ff;
25 | }
26 |
--------------------------------------------------------------------------------
/doc/centsdr-blockdiagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttrftech/CentSDR/e4079566e42790497f004e16f9ebf68c83d024a0/doc/centsdr-blockdiagram.png
--------------------------------------------------------------------------------
/doc/centsdr.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttrftech/CentSDR/e4079566e42790497f004e16f9ebf68c83d024a0/doc/centsdr.jpg
--------------------------------------------------------------------------------
/doc/plot-waveform.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttrftech/CentSDR/e4079566e42790497f004e16f9ebf68c83d024a0/doc/plot-waveform.png
--------------------------------------------------------------------------------
/ffconf.h:
--------------------------------------------------------------------------------
1 | /* CHIBIOS FIX */
2 | #include "ch.h"
3 |
4 | /*---------------------------------------------------------------------------/
5 | / FatFs - FAT file system module configuration file R0.09 (C)ChaN, 2011
6 | /----------------------------------------------------------------------------/
7 | /
8 | / CAUTION! Do not forget to make clean the project after any changes to
9 | / the configuration options.
10 | /
11 | /----------------------------------------------------------------------------*/
12 | #ifndef _FFCONF
13 | #define _FFCONF 6502 /* Revision ID */
14 |
15 |
16 | /*---------------------------------------------------------------------------/
17 | / Functions and Buffer Configurations
18 | /----------------------------------------------------------------------------*/
19 |
20 | #define _FS_TINY 0 /* 0:Normal or 1:Tiny */
21 | /* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
22 | / object instead of the sector buffer in the individual file object for file
23 | / data transfer. This reduces memory consumption 512 bytes each file object. */
24 |
25 |
26 | #define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */
27 | /* Setting _FS_READONLY to 1 defines read only configuration. This removes
28 | / writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
29 | / f_truncate and useless f_getfree. */
30 |
31 |
32 | #define _FS_MINIMIZE 0 /* 0 to 3 */
33 | /* The _FS_MINIMIZE option defines minimization level to remove some functions.
34 | /
35 | / 0: Full function.
36 | / 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
37 | / are removed.
38 | / 2: f_opendir and f_readdir are removed in addition to 1.
39 | / 3: f_lseek is removed in addition to 2. */
40 |
41 |
42 | #define _USE_STRFUNC 0 /* 0:Disable or 1-2:Enable */
43 | /* To enable string functions, set _USE_STRFUNC to 1 or 2. */
44 |
45 |
46 | #define _USE_MKFS 1 /* 0:Disable or 1:Enable */
47 | /* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
48 |
49 |
50 | #define _USE_FORWARD 0 /* 0:Disable or 1:Enable */
51 | /* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
52 |
53 |
54 | #define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */
55 | /* To enable fast seek feature, set _USE_FASTSEEK to 1. */
56 |
57 |
58 |
59 | /*---------------------------------------------------------------------------/
60 | / Locale and Namespace Configurations
61 | /----------------------------------------------------------------------------*/
62 |
63 | #define _CODE_PAGE 1251
64 | /* The _CODE_PAGE specifies the OEM code page to be used on the target system.
65 | / Incorrect setting of the code page can cause a file open failure.
66 | /
67 | / 932 - Japanese Shift-JIS (DBCS, OEM, Windows)
68 | / 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
69 | / 949 - Korean (DBCS, OEM, Windows)
70 | / 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
71 | / 1250 - Central Europe (Windows)
72 | / 1251 - Cyrillic (Windows)
73 | / 1252 - Latin 1 (Windows)
74 | / 1253 - Greek (Windows)
75 | / 1254 - Turkish (Windows)
76 | / 1255 - Hebrew (Windows)
77 | / 1256 - Arabic (Windows)
78 | / 1257 - Baltic (Windows)
79 | / 1258 - Vietnam (OEM, Windows)
80 | / 437 - U.S. (OEM)
81 | / 720 - Arabic (OEM)
82 | / 737 - Greek (OEM)
83 | / 775 - Baltic (OEM)
84 | / 850 - Multilingual Latin 1 (OEM)
85 | / 858 - Multilingual Latin 1 + Euro (OEM)
86 | / 852 - Latin 2 (OEM)
87 | / 855 - Cyrillic (OEM)
88 | / 866 - Russian (OEM)
89 | / 857 - Turkish (OEM)
90 | / 862 - Hebrew (OEM)
91 | / 874 - Thai (OEM, Windows)
92 | / 1 - ASCII only (Valid for non LFN cfg.)
93 | */
94 |
95 |
96 | #define _USE_LFN 1 /* 0 to 3 */
97 | #define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
98 | /* The _USE_LFN option switches the LFN support.
99 | /
100 | / 0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect.
101 | / 1: Enable LFN with static working buffer on the BSS. Always NOT reentrant.
102 | / 2: Enable LFN with dynamic working buffer on the STACK.
103 | / 3: Enable LFN with dynamic working buffer on the HEAP.
104 | /
105 | / The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. To enable LFN,
106 | / Unicode handling functions ff_convert() and ff_wtoupper() must be added
107 | / to the project. When enable to use heap, memory control functions
108 | / ff_memalloc() and ff_memfree() must be added to the project. */
109 |
110 |
111 | #define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
112 | /* To switch the character code set on FatFs API to Unicode,
113 | / enable LFN feature and set _LFN_UNICODE to 1. */
114 |
115 |
116 | #define _FS_RPATH 0 /* 0 to 2 */
117 | /* The _FS_RPATH option configures relative path feature.
118 | /
119 | / 0: Disable relative path feature and remove related functions.
120 | / 1: Enable relative path. f_chdrive() and f_chdir() are available.
121 | / 2: f_getcwd() is available in addition to 1.
122 | /
123 | / Note that output of the f_readdir fnction is affected by this option. */
124 |
125 |
126 |
127 | /*---------------------------------------------------------------------------/
128 | / Physical Drive Configurations
129 | /----------------------------------------------------------------------------*/
130 |
131 | #define _VOLUMES 1
132 | /* Number of volumes (logical drives) to be used. */
133 |
134 |
135 | #define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
136 | /* Maximum sector size to be handled.
137 | / Always set 512 for memory card and hard disk but a larger value may be
138 | / required for on-board flash memory, floppy disk and optical disk.
139 | / When _MAX_SS is larger than 512, it configures FatFs to variable sector size
140 | / and GET_SECTOR_SIZE command must be implememted to the disk_ioctl function. */
141 |
142 |
143 | #define _MULTI_PARTITION 0 /* 0:Single partition, 1/2:Enable multiple partition */
144 | /* When set to 0, each volume is bound to the same physical drive number and
145 | / it can mount only first primaly partition. When it is set to 1, each volume
146 | / is tied to the partitions listed in VolToPart[]. */
147 |
148 |
149 | #define _USE_ERASE 1 /* 0:Disable or 1:Enable */
150 | /* To enable sector erase feature, set _USE_ERASE to 1. CTRL_ERASE_SECTOR command
151 | / should be added to the disk_ioctl functio. */
152 |
153 |
154 |
155 | /*---------------------------------------------------------------------------/
156 | / System Configurations
157 | /----------------------------------------------------------------------------*/
158 |
159 | #define _WORD_ACCESS 1 /* 0 or 1 */
160 | /* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS
161 | / option defines which access method is used to the word data on the FAT volume.
162 | /
163 | / 0: Byte-by-byte access.
164 | / 1: Word access. Do not choose this unless following condition is met.
165 | /
166 | / When the byte order on the memory is big-endian or address miss-aligned word
167 | / access results incorrect behavior, the _WORD_ACCESS must be set to 0.
168 | / If it is not the case, the value can also be set to 1 to improve the
169 | / performance and code size.
170 | */
171 |
172 |
173 | /* A header file that defines sync object types on the O/S, such as
174 | / windows.h, ucos_ii.h and semphr.h, must be included prior to ff.h. */
175 |
176 | #define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
177 | #define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
178 | #define _SYNC_t Semaphore * /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
179 |
180 | /* The _FS_REENTRANT option switches the reentrancy (thread safe) of the FatFs module.
181 | /
182 | / 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect.
183 | / 1: Enable reentrancy. Also user provided synchronization handlers,
184 | / ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj
185 | / function must be added to the project. */
186 |
187 |
188 | #define _FS_SHARE 0 /* 0:Disable or >=1:Enable */
189 | /* To enable file shareing feature, set _FS_SHARE to 1 or greater. The value
190 | defines how many files can be opened simultaneously. */
191 |
192 |
193 | #endif /* _FFCONFIG */
194 |
--------------------------------------------------------------------------------
/flash-openocd.gdb:
--------------------------------------------------------------------------------
1 | # 1) start openocd in other terminal
2 | # $ openocd -f board/stm32f3discovery.cfg
3 | # 2) arm-none-eabi-gdb -x flash-openocd.gdb
4 |
5 | target extended-remote :3333
6 | exec build/ch.elf
7 | load
8 | continue
9 | quit
10 |
--------------------------------------------------------------------------------
/flash-stutil.gdb:
--------------------------------------------------------------------------------
1 | # 1) start st-util in background
2 | # 2) arm-none-eabi-gdb -x flash-stutil.gdb
3 |
4 | target extended-remote :4242
5 | exec build/ch.elf
6 | load
7 | quit
8 |
--------------------------------------------------------------------------------
/flash.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com
3 | * All rights reserved.
4 | *
5 | * This is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3, or (at your option)
8 | * any later version.
9 | *
10 | * The software is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with GNU Radio; see the file COPYING. If not, write to
17 | * the Free Software Foundation, Inc., 51 Franklin Street,
18 | * Boston, MA 02110-1301, USA.
19 | */
20 | #include "ch.h"
21 | #include "hal.h"
22 | #include "nanosdr.h"
23 | #include
24 |
25 | static int flash_wait_for_last_operation(void)
26 | {
27 | while (FLASH->SR == FLASH_SR_BSY) {
28 | //WWDG->CR = WWDG_CR_T;
29 | }
30 | return FLASH->SR;
31 | }
32 |
33 | static void flash_erase_page0(uint32_t page_address)
34 | {
35 | flash_wait_for_last_operation();
36 | FLASH->CR |= FLASH_CR_PER;
37 | FLASH->AR = page_address;
38 | FLASH->CR |= FLASH_CR_STRT;
39 | flash_wait_for_last_operation();
40 | FLASH->CR &= ~FLASH_CR_PER;
41 | }
42 |
43 | int flash_erase_page(uint32_t page_address)
44 | {
45 | chSysLock();
46 | flash_erase_page0(page_address);
47 | chSysUnlock();
48 | return 0;
49 | }
50 |
51 | void flash_program_half_word(uint32_t address, uint16_t data)
52 | {
53 | flash_wait_for_last_operation();
54 | FLASH->CR |= FLASH_CR_PG;
55 | *(__IO uint16_t*)address = data;
56 | flash_wait_for_last_operation();
57 | FLASH->CR &= ~FLASH_CR_PG;
58 | }
59 |
60 | void flash_unlock(void)
61 | {
62 | // unlock sequence
63 | FLASH->KEYR = 0x45670123;
64 | FLASH->KEYR = 0xCDEF89AB;
65 | }
66 |
67 |
68 | static uint32_t
69 | checksum(const void *start, size_t len)
70 | {
71 | uint32_t *p = (uint32_t*)start;
72 | uint32_t *tail = (uint32_t*)(start + len);
73 | uint32_t value = len;
74 | while (p < tail)
75 | value ^= *p++;
76 | return value;
77 | }
78 |
79 |
80 | #define FLASH_PAGESIZE 0x800
81 |
82 | // last page of flash memory. assume STM32F303CBT6 flash 128k Device
83 | const uint32_t save_config_area = 0x0801f800;
84 | const uint32_t save_config_prop_area_size = 0x800;
85 |
86 | int
87 | config_save(void)
88 | {
89 | uint16_t *src = (uint16_t*)&config;
90 | uint16_t *dst = (uint16_t*)save_config_area;
91 | int count = sizeof(config_t) / sizeof(uint16_t);
92 |
93 | config.magic = CONFIG_MAGIC;
94 | config.checksum = 0;
95 | config.checksum = checksum(&config, sizeof config);
96 |
97 | flash_unlock();
98 |
99 | /* erase flash pages */
100 | flash_erase_page((uint32_t)dst);
101 |
102 | /* write to flahs */
103 | while(count-- > 0) {
104 | flash_program_half_word((uint32_t)dst, *src++);
105 | dst++;
106 | }
107 |
108 | return 0;
109 | }
110 |
111 | int
112 | config_recall(void)
113 | {
114 | const config_t *src = (const config_t*)save_config_area;
115 | void *dst = &config;
116 |
117 | if (src->magic != CONFIG_MAGIC)
118 | return -1;
119 | if (checksum(src, sizeof(config_t)) != 0)
120 | return -1;
121 |
122 | /* duplicated saved data onto sram to be able to modify marker/trace */
123 | memcpy(dst, src, sizeof(config_t));
124 | return 0;
125 | }
126 |
127 | void
128 | clear_all_config_prop_data(void)
129 | {
130 | flash_unlock();
131 |
132 | /* erase flash pages */
133 | void *p = (void*)save_config_area;
134 | void *tail = p + save_config_prop_area_size;
135 | while (p < tail) {
136 | flash_erase_page((uint32_t)p);
137 | p += FLASH_PAGESIZE;
138 | }
139 | }
140 |
141 |
--------------------------------------------------------------------------------
/halconf.h:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | /**
18 | * @file templates/halconf.h
19 | * @brief HAL configuration header.
20 | * @details HAL configuration file, this file allows to enable or disable the
21 | * various device drivers from your application. You may also use
22 | * this file in order to override the device drivers default settings.
23 | *
24 | * @addtogroup HAL_CONF
25 | * @{
26 | */
27 |
28 | #ifndef _HALCONF_H_
29 | #define _HALCONF_H_
30 |
31 | #include "mcuconf.h"
32 |
33 | /**
34 | * @brief Enables the PAL subsystem.
35 | */
36 | #if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
37 | #define HAL_USE_PAL TRUE
38 | #endif
39 |
40 | /**
41 | * @brief Enables the ADC subsystem.
42 | */
43 | #if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
44 | #define HAL_USE_ADC TRUE
45 | #endif
46 |
47 | /**
48 | * @brief Enables the CAN subsystem.
49 | */
50 | #if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
51 | #define HAL_USE_CAN FALSE
52 | #endif
53 |
54 | /**
55 | * @brief Enables the DAC subsystem.
56 | */
57 | #if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
58 | #define HAL_USE_DAC TRUE
59 | #endif
60 |
61 | /**
62 | * @brief Enables the EXT subsystem.
63 | */
64 | #if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
65 | #define HAL_USE_EXT TRUE
66 | #endif
67 |
68 | /**
69 | * @brief Enables the GPT subsystem.
70 | */
71 | #if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
72 | #define HAL_USE_GPT FALSE
73 | #endif
74 |
75 | /**
76 | * @brief Enables the I2C subsystem.
77 | */
78 | #if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
79 | #define HAL_USE_I2C TRUE
80 | #endif
81 |
82 | /**
83 | * @brief Enables the I2S subsystem.
84 | */
85 | #if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
86 | #define HAL_USE_I2S TRUE
87 | #endif
88 |
89 | /**
90 | * @brief Enables the ICU subsystem.
91 | */
92 | #if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
93 | #define HAL_USE_ICU FALSE
94 | #endif
95 |
96 | /**
97 | * @brief Enables the MAC subsystem.
98 | */
99 | #if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
100 | #define HAL_USE_MAC FALSE
101 | #endif
102 |
103 | /**
104 | * @brief Enables the MMC_SPI subsystem.
105 | */
106 | #if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
107 | #define HAL_USE_MMC_SPI FALSE
108 | #endif
109 |
110 | /**
111 | * @brief Enables the PWM subsystem.
112 | */
113 | #if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
114 | #define HAL_USE_PWM FALSE
115 | #endif
116 |
117 | /**
118 | * @brief Enables the RTC subsystem.
119 | */
120 | #if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
121 | #define HAL_USE_RTC FALSE
122 | #endif
123 |
124 | /**
125 | * @brief Enables the SDC subsystem.
126 | */
127 | #if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
128 | #define HAL_USE_SDC FALSE
129 | #endif
130 |
131 | /**
132 | * @brief Enables the SERIAL subsystem.
133 | */
134 | #if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
135 | #define HAL_USE_SERIAL TRUE
136 | #endif
137 |
138 | /**
139 | * @brief Enables the SERIAL over USB subsystem.
140 | */
141 | #if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
142 | #define HAL_USE_SERIAL_USB TRUE
143 | #endif
144 |
145 | /**
146 | * @brief Enables the SPI subsystem.
147 | */
148 | #if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
149 | #define HAL_USE_SPI TRUE
150 | #endif
151 |
152 | /**
153 | * @brief Enables the UART subsystem.
154 | */
155 | #if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
156 | #define HAL_USE_UART FALSE
157 | #endif
158 |
159 | /**
160 | * @brief Enables the USB subsystem.
161 | */
162 | #if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
163 | #define HAL_USE_USB TRUE
164 | #endif
165 |
166 | /**
167 | * @brief Enables the WDG subsystem.
168 | */
169 | #if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
170 | #define HAL_USE_WDG FALSE
171 | #endif
172 |
173 | /*===========================================================================*/
174 | /* ADC driver related settings. */
175 | /*===========================================================================*/
176 |
177 | /**
178 | * @brief Enables synchronous APIs.
179 | * @note Disabling this option saves both code and data space.
180 | */
181 | #if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
182 | #define ADC_USE_WAIT TRUE
183 | #endif
184 |
185 | /**
186 | * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
187 | * @note Disabling this option saves both code and data space.
188 | */
189 | #if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
190 | #define ADC_USE_MUTUAL_EXCLUSION TRUE
191 | #endif
192 |
193 | /*===========================================================================*/
194 | /* CAN driver related settings. */
195 | /*===========================================================================*/
196 |
197 | /**
198 | * @brief Sleep mode related APIs inclusion switch.
199 | */
200 | #if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
201 | #define CAN_USE_SLEEP_MODE TRUE
202 | #endif
203 |
204 | /*===========================================================================*/
205 | /* I2C driver related settings. */
206 | /*===========================================================================*/
207 |
208 | /**
209 | * @brief Enables the mutual exclusion APIs on the I2C bus.
210 | */
211 | #if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
212 | #define I2C_USE_MUTUAL_EXCLUSION TRUE
213 | #endif
214 |
215 | /*===========================================================================*/
216 | /* MAC driver related settings. */
217 | /*===========================================================================*/
218 |
219 | /**
220 | * @brief Enables an event sources for incoming packets.
221 | */
222 | #if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
223 | #define MAC_USE_ZERO_COPY FALSE
224 | #endif
225 |
226 | /**
227 | * @brief Enables an event sources for incoming packets.
228 | */
229 | #if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
230 | #define MAC_USE_EVENTS TRUE
231 | #endif
232 |
233 | /*===========================================================================*/
234 | /* MMC_SPI driver related settings. */
235 | /*===========================================================================*/
236 |
237 | /**
238 | * @brief Delays insertions.
239 | * @details If enabled this options inserts delays into the MMC waiting
240 | * routines releasing some extra CPU time for the threads with
241 | * lower priority, this may slow down the driver a bit however.
242 | * This option is recommended also if the SPI driver does not
243 | * use a DMA channel and heavily loads the CPU.
244 | */
245 | #if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
246 | #define MMC_NICE_WAITING TRUE
247 | #endif
248 |
249 | /*===========================================================================*/
250 | /* SDC driver related settings. */
251 | /*===========================================================================*/
252 |
253 | /**
254 | * @brief Number of initialization attempts before rejecting the card.
255 | * @note Attempts are performed at 10mS intervals.
256 | */
257 | #if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
258 | #define SDC_INIT_RETRY 100
259 | #endif
260 |
261 | /**
262 | * @brief Include support for MMC cards.
263 | * @note MMC support is not yet implemented so this option must be kept
264 | * at @p FALSE.
265 | */
266 | #if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
267 | #define SDC_MMC_SUPPORT FALSE
268 | #endif
269 |
270 | /**
271 | * @brief Delays insertions.
272 | * @details If enabled this options inserts delays into the MMC waiting
273 | * routines releasing some extra CPU time for the threads with
274 | * lower priority, this may slow down the driver a bit however.
275 | */
276 | #if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
277 | #define SDC_NICE_WAITING TRUE
278 | #endif
279 |
280 | /*===========================================================================*/
281 | /* SERIAL driver related settings. */
282 | /*===========================================================================*/
283 |
284 | /**
285 | * @brief Default bit rate.
286 | * @details Configuration parameter, this is the baud rate selected for the
287 | * default configuration.
288 | */
289 | #if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
290 | #define SERIAL_DEFAULT_BITRATE 38400
291 | #endif
292 |
293 | /**
294 | * @brief Serial buffers size.
295 | * @details Configuration parameter, you can change the depth of the queue
296 | * buffers depending on the requirements of your application.
297 | * @note The default is 64 bytes for both the transmission and receive
298 | * buffers.
299 | */
300 | #if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
301 | #define SERIAL_BUFFERS_SIZE 16
302 | #endif
303 |
304 | /*===========================================================================*/
305 | /* SERIAL_USB driver related setting. */
306 | /*===========================================================================*/
307 |
308 | /**
309 | * @brief Serial over USB buffers size.
310 | * @details Configuration parameter, the buffer size must be a multiple of
311 | * the USB data endpoint maximum packet size.
312 | * @note The default is 64 bytes for both the transmission and receive
313 | * buffers.
314 | */
315 | #if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
316 | #define SERIAL_USB_BUFFERS_SIZE 256
317 | #endif
318 |
319 | /*===========================================================================*/
320 | /* SPI driver related settings. */
321 | /*===========================================================================*/
322 |
323 | /**
324 | * @brief Enables synchronous APIs.
325 | * @note Disabling this option saves both code and data space.
326 | */
327 | #if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
328 | #define SPI_USE_WAIT TRUE
329 | #endif
330 |
331 | /**
332 | * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
333 | * @note Disabling this option saves both code and data space.
334 | */
335 | #if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
336 | #define SPI_USE_MUTUAL_EXCLUSION TRUE
337 | #endif
338 |
339 | /*===========================================================================*/
340 | /* UART driver related settings. */
341 | /*===========================================================================*/
342 |
343 | /**
344 | * @brief Enables synchronous APIs.
345 | * @note Disabling this option saves both code and data space.
346 | */
347 | #if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
348 | #define UART_USE_WAIT FALSE
349 | #endif
350 |
351 | /**
352 | * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
353 | * @note Disabling this option saves both code and data space.
354 | */
355 | #if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
356 | #define UART_USE_MUTUAL_EXCLUSION FALSE
357 | #endif
358 |
359 | /*===========================================================================*/
360 | /* USB driver related settings. */
361 | /*===========================================================================*/
362 |
363 | /**
364 | * @brief Enables synchronous APIs.
365 | * @note Disabling this option saves both code and data space.
366 | */
367 | #if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
368 | #define USB_USE_WAIT FALSE
369 | #endif
370 |
371 | #endif /* _HALCONF_H_ */
372 |
373 | /** @} */
374 |
--------------------------------------------------------------------------------
/icons.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com
3 | * All rights reserved.
4 | *
5 | * This is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3, or (at your option)
8 | * any later version.
9 | *
10 | * The software is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with GNU Radio; see the file COPYING. If not, write to
17 | * the Free Software Foundation, Inc., 51 Franklin Street,
18 | * Boston, MA 02110-1301, USA.
19 | */
20 |
21 | #include
22 |
23 | const uint32_t icons48x20[][2*20] = {
24 | { // CW
25 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
26 | 0b00111111111111111111111111111111, 0b11111111111111000000000000000000,
27 | 0b01111111111000000001111110000111, 0b10111100001111100000000000000000,
28 | 0b01111111100000000000011110000111, 0b00011100001111100000000000000000,
29 | 0b11111111000000000000001110000111, 0b00011100001111110000000000000000,
30 | 0b11111110000000000000001110000110, 0b00001100001111110000000000000000,
31 | 0b11111110000001111000000110000110, 0b00001100001111110000000000000000,
32 | 0b11111100000111111100000110000100, 0b00000100001111110000000000000000,
33 |
34 | 0b11111100001111111111111110000000, 0b00000000001111110000000000000000,
35 | 0b11111100001111111111111110000000, 0b00000000001111110000000000000000,
36 | 0b11111100001111111111111110000000, 0b00000000001111110000000000000000,
37 | 0b11111100001111111111111111000000, 0b01000000011111110000000000000000,
38 | 0b11111100000111111100000111000000, 0b11100000011111110000000000000000,
39 | 0b11111110000001111000000111000000, 0b11100000011111110000000000000000,
40 | 0b11111110000000000000001111000001, 0b11110000011111110000000000000000,
41 | 0b11111111000000000000001111000001, 0b11110000011111110000000000000000,
42 |
43 | 0b01111111100000000000111111000011, 0b11111000011111100000000000000000,
44 | 0b01111111111000000011111111000011, 0b11111000011111100000000000000000,
45 | 0b00111111111111111111111111111111, 0b11111111111111000000000000000000,
46 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
47 | },
48 | { // LSB
49 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
50 | 0b00111111111111111111111101111111, 0b11111111111111000000000000000000,
51 | 0b01111100001111111111110000011110, 0b00000001111111100000000000000000,
52 | 0b01111100001111111111000000000110, 0b00000000011111100000000000000000,
53 | 0b11111100001111111110000000000010, 0b00000000001111110000000000000000,
54 | 0b11111100001111111100000110000010, 0b00000000000111110000000000000000,
55 | 0b11111100001111111100001111000010, 0b00011100000111110000000000000000,
56 | 0b11111100001111111100000111111110, 0b00011110000111110000000000000000,
57 |
58 | 0b11111100001111111110000001111110, 0b00011100001111110000000000000000,
59 | 0b11111100001111111111000000011110, 0b00000000011111110000000000000000,
60 | 0b11111100001111111111110000001110, 0b00000000011111110000000000000000,
61 | 0b11111100001111111111111100000110, 0b00011100001111110000000000000000,
62 | 0b11111100001111111111111110000010, 0b00011110000111110000000000000000,
63 | 0b11111100001111111100001111000010, 0b00011100000111110000000000000000,
64 | 0b11111100000000000100000110000010, 0b00000000000111110000000000000000,
65 | 0b11111100000000000110000000000110, 0b00000000001111110000000000000000,
66 |
67 | 0b01111100000000000111000000001110, 0b00000000011111100000000000000000,
68 | 0b01111100000000000111100000011110, 0b00000001111111100000000000000000,
69 | 0b00111111111111111111111101111111, 0b11111111111111000000000000000000,
70 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
71 | },
72 | { // USB
73 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
74 | 0b00111111111111111111111101111111, 0b11111111111111000000000000000000,
75 | 0b01111000011110000111100000001110, 0b00000001111111100000000000000000,
76 | 0b01111000011110000111000000000110, 0b00000000011111100000000000000000,
77 | 0b11111000011110000110000000000010, 0b00000000001111110000000000000000,
78 | 0b11111000011110000100000110000010, 0b00000000000111110000000000000000,
79 | 0b11111000011110000100001111000010, 0b00011100000111110000000000000000,
80 | 0b11111000011110000100000111111110, 0b00011110000111110000000000000000,
81 |
82 | 0b11111000011110000110000011111110, 0b00011100001111110000000000000000,
83 | 0b11111000011110000111000000111110, 0b00000000011111110000000000000000,
84 | 0b11111000011110000111100000001110, 0b00000000011111110000000000000000,
85 | 0b11111000011110000111111000000110, 0b00011100001111110000000000000000,
86 | 0b11111000011110000111111110000010, 0b00011110000111110000000000000000,
87 | 0b11111000001100000100001111000010, 0b00011100000111110000000000000000,
88 | 0b11111000000000000100000110000010, 0b00000000000111110000000000000000,
89 | 0b11111100000000001110000000000010, 0b00000000001111110000000000000000,
90 |
91 | 0b01111110000000011111000000000110, 0b00000000011111100000000000000000,
92 | 0b01111111000000111111100000001110, 0b00000001111111100000000000000000,
93 | 0b00111111111111111111111101111111, 0b11111111111111000000000000000000,
94 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
95 | },
96 | { // AM
97 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
98 | 0b00111111111111111111111111111111, 0b11111111111111000000000000000000,
99 | 0b01111111111100000111111110000111, 0b11111100001111100000000000000000,
100 | 0b01111111111100000111111110000011, 0b11111000001111100000000000000000,
101 | 0b11111111111000000011111110000011, 0b11111000001111110000000000000000,
102 | 0b11111111111000000011111110000001, 0b11110000001111110000000000000000,
103 | 0b11111111110000000001111110000000, 0b11100000001111110000000000000000,
104 | 0b11111111110000000001111110000000, 0b11100000001111110000000000000000,
105 |
106 | 0b11111111100000100000111110000000, 0b01000000001111110000000000000000,
107 | 0b11111111100000100000111110000000, 0b00000000001111110000000000000000,
108 | 0b11111111000001110000011110000000, 0b00000000001111110000000000000000,
109 | 0b11111111000001110000011110000100, 0b00000100001111110000000000000000,
110 | 0b11111110000011111000001110000100, 0b00000100001111110000000000000000,
111 | 0b11111110000000000000001110000110, 0b00001100001111110000000000000000,
112 | 0b11111110000000000000001110000110, 0b00001100001111110000000000000000,
113 | 0b11111100000000000000000110000111, 0b00011100001111110000000000000000,
114 |
115 | 0b01111100000111111100000110000111, 0b00011100001111100000000000000000,
116 | 0b01111100000111111100000110000111, 0b10111100001111100000000000000000,
117 | 0b00111111111111111111111111111111, 0b11111111111111000000000000000000,
118 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
119 | },
120 | { // FM
121 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
122 | 0b00111111111111111111111111111111, 0b11111111111111000000000000000000,
123 | 0b01111110000000000000001110000111, 0b11111100001111100000000000000000,
124 | 0b01111110000000000000001110000011, 0b11111000001111100000000000000000,
125 | 0b11111110000000000000001110000011, 0b11111000001111110000000000000000,
126 | 0b11111110000000000000001110000001, 0b11110000001111110000000000000000,
127 | 0b11111110000011111111111110000000, 0b11100000001111110000000000000000,
128 | 0b11111110000011111111111110000000, 0b11100000001111110000000000000000,
129 |
130 | 0b11111110000011111111111110000000, 0b01000000001111110000000000000000,
131 | 0b11111110000000000000011110000000, 0b00000000001111110000000000000000,
132 | 0b11111110000000000000011110000000, 0b00000000001111110000000000000000,
133 | 0b11111110000000000000011110000100, 0b00000100001111110000000000000000,
134 | 0b11111110000000000000011110000100, 0b00000100001111110000000000000000,
135 | 0b11111110000011111111111110000110, 0b00001100001111110000000000000000,
136 | 0b11111110000011111111111110000110, 0b00001100001111110000000000000000,
137 | 0b11111110000011111111111110000111, 0b00011100001111110000000000000000,
138 |
139 | 0b01111110000011111111111110000111, 0b00011100001111100000000000000000,
140 | 0b01111110000011111111111110000111, 0b10111100001111100000000000000000,
141 | 0b00111111111111111111111111111111, 0b11111111111111000000000000000000,
142 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
143 | },
144 | { // STEREO
145 | 0b00001111111111111111111111111111, 0b11111111111110001000000000000000,
146 | 0b00111111111111111111111111111111, 0b11111111111111100000000000000000,
147 | 0b01111100011100000010000010000011, 0b00000110000111100000000000000000,
148 | 0b01111000001100000010000010000001, 0b00000100000011100000000000000000,
149 | 0b11110000000100000010000010000001, 0b00000100000011110000000000000000,
150 | 0b11110001000100000010000010000001, 0b00000100000011110000000000000000,
151 | 0b11110001100111001110011110011001, 0b00111100110011110000000000000000,
152 | 0b11110001100111001110011110011001, 0b00111100110011110000000000000000,
153 |
154 | 0b11111001111111001110000010011001, 0b00000100110011110000000000000000,
155 | 0b11111000111111001110000010000001, 0b00000100110011110000000000000000,
156 | 0b11111100011111001110000010000001, 0b00000100110011110000000000000000,
157 | 0b11111110001111001110000010000011, 0b00000100110011110000000000000000,
158 | 0b11110011001111001110011110010011, 0b00111100110011110000000000000000,
159 | 0b11110011000111001110011110010001, 0b00111100110011110000000000000000,
160 | 0b11110001000111001110000010010001, 0b00000100000011110000000000000000,
161 | 0b11110000000111001110000010011001, 0b00000100000011110000000000000000,
162 |
163 | 0b01111000001111001110000010011001, 0b00000100000011100000000000000000,
164 | 0b01111100011111001110000010011001, 0b00000110000111100000000000000000,
165 | 0b00111111111111111111111111111111, 0b11111111111111000000000000000000,
166 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
167 | },
168 | { // OFF
169 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
170 | 0b00100000000000000000000000000000, 0b00000000000011000000000000000000,
171 | 0b01000000011111000001111111111101, 0b11111111110000100000000000000000,
172 | 0b10000001111111110001111111111101, 0b11111111110000100000000000000000,
173 | 0b10000011111111111001111111111101, 0b11111111110000010000000000000000,
174 | 0b10000111110001111101111111111101, 0b11111111110000010000000000000000,
175 | 0b10000111100000111101111000000001, 0b11100000000000010000000000000000,
176 | 0b10000111100000111101111000000001, 0b11100000000000010000000000000000,
177 |
178 | 0b10000111100000111101111000000001, 0b11100000000000010000000000000000,
179 | 0b10000111100000111101111111111001, 0b11111111100000010000000000000000,
180 | 0b10000111100000111101111111111001, 0b11111111100000010000000000000000,
181 | 0b10000111100000111101111111111001, 0b11111111100000010000000000000000,
182 | 0b10000111100000111101111111111001, 0b11111111100000010000000000000000,
183 | 0b10000111100000111101111000000001, 0b11100000000000010000000000000000,
184 | 0b10000111110001111101111000000001, 0b11100000000000010000000000000000,
185 | 0b10000011111111111001111000000001, 0b11100000000000010000000000000000,
186 |
187 | 0b01000001111111110001111000000001, 0b11100000000000100000000000000000,
188 | 0b01000000011111000001111000000001, 0b11100000000000100000000000000000,
189 | 0b00110000000000000000000000000000, 0b00000000000011000000000000000000,
190 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
191 | },
192 | { // SLOW
193 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
194 | 0b00100000000000000000000000000000, 0b00000000000011000000000000000000,
195 | 0b01000001111000011100000000111110, 0b00111000001110100000000000000000,
196 | 0b10000111111110011100000001111111, 0b00111000001110100000000000000000,
197 | 0b10001111111111011100000011111111, 0b10111000001110010000000000000000,
198 | 0b10001111111111011100000011111111, 0b10111011101110010000000000000000,
199 | 0b10001110001111011100000011100011, 0b10111011101110010000000000000000,
200 | 0b10001111000111011100000011100011, 0b10111011101110010000000000000000,
201 |
202 | 0b10000111110000011100000011100011, 0b10111011101110010000000000000000,
203 | 0b10000011111100011100000011100011, 0b10111011101110010000000000000000,
204 | 0b10000001111100011100000011100011, 0b10111011101110010000000000000000,
205 | 0b10000000111110011100000011100011, 0b10111111111110010000000000000000,
206 | 0b10001110001111011100000011100011, 0b10111111111110010000000000000000,
207 | 0b10001111000111011100000011100011, 0b10011111111100010000000000000000,
208 | 0b10001111111111011111111011111111, 0b10011111111100010000000000000000,
209 | 0b10001111111111011111111011111111, 0b10011110111100010000000000000000,
210 |
211 | 0b01000111111110011111111001111111, 0b00011100011100100000000000000000,
212 | 0b01000001111000011111111000111110, 0b00011100011100100000000000000000,
213 | 0b00110000000000000000000000000000, 0b00000000000011000000000000000000,
214 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
215 | },
216 | { // MID
217 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
218 | 0b00100000000000000000000000000000, 0b00000000000011000000000000000000,
219 | 0b01000111100000001111011111111011, 0b11111100000000100000000000000000,
220 | 0b10000111110000011111011111111011, 0b11111111000000100000000000000000,
221 | 0b10000111110000011111011111111011, 0b11111111110000010000000000000000,
222 | 0b10000111111000111111000111100011, 0b11111111110000010000000000000000,
223 | 0b10000111111000111111000111100011, 0b11000111111000010000000000000000,
224 | 0b10000111111101111111000111100011, 0b11000011111000010000000000000000,
225 |
226 | 0b10000111111111111111000111100011, 0b11000001111000010000000000000000,
227 | 0b10000111111111111111000111100011, 0b11000001111000010000000000000000,
228 | 0b10000111101111101111000111100011, 0b11000001111000010000000000000000,
229 | 0b10000111101111101111000111100011, 0b11000001111000010000000000000000,
230 | 0b10000111100111001111000111100011, 0b11000011111000010000000000000000,
231 | 0b10000111100111001111000111100011, 0b11000111111000010000000000000000,
232 | 0b10000111100111001111000111100011, 0b11111111110000010000000000000000,
233 | 0b10000111100000001111011111111011, 0b11111111110000010000000000000000,
234 |
235 | 0b01000111100000001111011111111011, 0b11111111000000100000000000000000,
236 | 0b01000111100000001111011111111011, 0b11111100000000100000000000000000,
237 | 0b00110000000000000000000000000000, 0b00000000000011000000000000000000,
238 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
239 | },
240 | { // FAST
241 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
242 | 0b00100000000000000000000000000000, 0b00000000000011000000000000000000,
243 | 0b01001111111110001111000000011110, 0b00011111111100100000000000000000,
244 | 0b10001111111110001111000001111111, 0b10011111111100100000000000000000,
245 | 0b10001111111110011111100011111111, 0b11011111111100010000000000000000,
246 | 0b10001111111110011111100011111111, 0b11011111111100010000000000000000,
247 | 0b10001110000000011111100011100011, 0b11000011100000010000000000000000,
248 | 0b10001110000000111001110011110001, 0b11000011100000010000000000000000,
249 |
250 | 0b10001110000000111001110001111100, 0b00000011100000010000000000000000,
251 | 0b10001111111100111001110000111111, 0b00000011100000010000000000000000,
252 | 0b10001111111100111001110000011111, 0b00000011100000010000000000000000,
253 | 0b10001111111100111001110000001111, 0b10000011100000010000000000000000,
254 | 0b10001111111101111111111011100011, 0b11000011100000010000000000000000,
255 | 0b10001110000001111111111011110001, 0b11000011100000010000000000000000,
256 | 0b10001110000001111111111011111111, 0b11000011100000010000000000000000,
257 | 0b10001110000001110000111011111111, 0b11000011100000010000000000000000,
258 |
259 | 0b01001110000001110000111001111111, 0b10000011100000100000000000000000,
260 | 0b01001110000001110000111000011110, 0b00000011100000100000000000000000,
261 | 0b00110000000000000000000000000000, 0b00000000000011000000000000000000,
262 | 0b00001111111111111111111111111111, 0b11111111111100001000000000000000,
263 | },
264 | };
265 |
266 | #if 0
267 | const uint32_t icons64x24[][2*24] = {
268 | { // LSB
269 | 0b00001111111111111111111111111111, 0b11111111111111111111111111110000,
270 | 0b00111111111111111111111111111111, 0b11111111111111111111111111111100,
271 | 0b00111111111111111111111111111111, 0b11111111111111111111111111111100,
272 | 0b01111111100001111111111111110000, 0b01111111000000000011111111111110,
273 | 0b01111111100001111111111110000000, 0b00001111000000000000011111111110,
274 | 0b11111111100001111111111100000000, 0b00000111000000000000001111111111,
275 | 0b11111111100001111111111000000000, 0b00000011000000000000000111111111,
276 | 0b11111111100001111111111000001111, 0b10000011000011111100000111111111,
277 |
278 | 0b11111111100001111111111000000111, 0b11000011000011111110000111111111,
279 | 0b11111111100001111111111000000001, 0b11111111000011111000000111111111,
280 | 0b11111111100001111111111110000000, 0b11111111000000000000011111111111,
281 | 0b11111111100001111111111111100000, 0b00111111000000000000111111111111,
282 | 0b11111111100001111111111111111000, 0b00011111000000000000011111111111,
283 | 0b11111111100001111111111111111110, 0b00000111000011111000001111111111,
284 | 0b11111111100001111111111000011111, 0b00000011000011111110000111111111,
285 | 0b11111111100001111111111000001111, 0b10000011000011111100000111111111,
286 |
287 | 0b11111111100000000000001000000000, 0b00000011000000000000000111111111,
288 | 0b11111111100000000000001100000000, 0b00000111000000000000001111111111,
289 | 0b01111111100000000000001111000000, 0b00001111000000000000011111111110,
290 | 0b01111111100000000000001111111000, 0b01111111000000000011111111111110,
291 | 0b00111111111111111111111111111111, 0b11111111111111111111111111111100,
292 | 0b00111111111111111111111111111111, 0b11111111111111111111111111111100,
293 | 0b00001111111111111111111111111111, 0b11111111111111111111111111110000,
294 | 0b00000000000000000000000000000000, 0b00000000000000000000000000000000,
295 | },
296 | };
297 | const uint32_t icons64x16[][2*16] = {
298 | { // LSB
299 | 0b00001111111111111111111111111111, 0b11111111111111111111111111110000,
300 | 0b00111111111111111111111111111111, 0b11111111111111111111111111111100,
301 | 0b01110001111111111111111111100000, 0b00000111111000000000000001111110,
302 | 0b01110001111111111111111100000000, 0b00000000111000000000000000011110,
303 | 0b11110001111111111111110000000000, 0b00000000011000000000000000001111,
304 | 0b11110001111111111111110000011111, 0b11111000011000111111111110001111,
305 | 0b11110001111111111111111000000111, 0b11111100011000111111111100001111,
306 | 0b11110001111111111111111110000000, 0b00011111111000000000000000011111,
307 |
308 | 0b11110001111111111111111111110000, 0b00000011111000000000000000011111,
309 | 0b11110001111111111111110001111111, 0b10000000111000111111111100001111,
310 | 0b11110001111111111111110000111111, 0b11110000011000111111111110001111,
311 | 0b11110000000000000000111000000000, 0b00000000011000000000000000001111,
312 | 0b01110000000000000000111100000000, 0b00000000111000000000000000011110,
313 | 0b01110000000000000000111111100000, 0b00000111111000000000000001111110,
314 | 0b00111111111111111111111111111111, 0b11111111111111111111111111111100,
315 | 0b00001111111111111111111111111111, 0b11111111111111111111111111110000,
316 | }
317 | };
318 |
319 | const uint32_t icons32x12[][12] = {
320 | { // LSB
321 | 0b00111111111111111111111111111000,
322 | 0b01100111111110000111100000111100,
323 | 0b11100111111100000011100000011110,
324 | 0b11100111111000110001100111001110,
325 | 0b11100111111001111001100111001110,
326 | 0b11100111111000111111100000011110,
327 | 0b11100111111100000111100000011110,
328 | 0b11100111111111110000100111001110,
329 |
330 | 0b11100111111001111000100111001110,
331 | 0b11100000001000000000100000001110,
332 | 0b01100000001110000011100000111100,
333 | 0b00111111111111111111111111111000,
334 | },
335 | };
336 | #endif
337 |
--------------------------------------------------------------------------------
/ili9341.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com
3 | * All rights reserved.
4 | *
5 | * This is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3, or (at your option)
8 | * any later version.
9 | *
10 | * The software is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with GNU Radio; see the file COPYING. If not, write to
17 | * the Free Software Foundation, Inc., 51 Franklin Street,
18 | * Boston, MA 02110-1301, USA.
19 | */
20 | #include "ch.h"
21 | #include "hal.h"
22 | #include "nanosdr.h"
23 |
24 | #define RESET_ASSERT palClearPad(GPIOA, 15)
25 | #define RESET_NEGATE palSetPad(GPIOA, 15)
26 | #define CS_LOW palClearPad(GPIOB, 6)
27 | #define CS_HIGH palSetPad(GPIOB, 6)
28 | #define DC_CMD palClearPad(GPIOB, 7)
29 | #define DC_DATA palSetPad(GPIOB, 7)
30 |
31 | uint16_t spi_buffer[4096];
32 |
33 | void
34 | ssp_wait(void)
35 | {
36 | while (SPI1->SR & SPI_SR_BSY)
37 | ;
38 | }
39 |
40 | void
41 | ssp_wait_slot(void)
42 | {
43 | while ((SPI1->SR & 0x1800) == 0x1800)
44 | ;
45 | }
46 |
47 | void
48 | ssp_senddata(uint8_t x)
49 | {
50 | *(uint8_t*)(&SPI1->DR) = x;
51 | while (SPI1->SR & SPI_SR_BSY)
52 | ;
53 | }
54 |
55 | void
56 | ssp_senddata16(uint16_t x)
57 | {
58 | ssp_wait_slot();
59 | SPI1->DR = x;
60 | //while (SPI1->SR & SPI_SR_BSY)
61 | // ;
62 | }
63 |
64 | void
65 | ssp_databit8(void)
66 | {
67 | SPI1->CR2 = (SPI1->CR2 & 0xf0ff) | 0x0700;
68 | //LPC_SSP1->CR0 = (LPC_SSP1->CR0 & 0xf0) | SSP_DATABIT_8;
69 | }
70 |
71 | void
72 | ssp_databit16(void)
73 | {
74 | SPI1->CR2 = (SPI1->CR2 & 0xf0ff) | 0x0f00;
75 | //LPC_SSP1->CR0 = (LPC_SSP1->CR0 & 0xf0) | SSP_DATABIT_16;
76 | }
77 |
78 |
79 | const stm32_dma_stream_t *dmatx;
80 | uint32_t txdmamode;
81 |
82 | static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) {
83 | (void)spip;
84 | (void)flags;
85 | }
86 |
87 | void
88 | spi_init(void)
89 | {
90 | rccEnableSPI1(FALSE);
91 |
92 | dmatx = STM32_DMA_STREAM(STM32_SPI_SPI1_TX_DMA_STREAM);
93 | txdmamode = STM32_DMA_CR_CHSEL(SPI1_TX_DMA_CHANNEL) |
94 | STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) |
95 | STM32_DMA_CR_DIR_M2P |
96 | STM32_DMA_CR_DMEIE |
97 | STM32_DMA_CR_TEIE |
98 | STM32_DMA_CR_PSIZE_HWORD |
99 | STM32_DMA_CR_MSIZE_HWORD;
100 | dmaStreamAllocate(dmatx,
101 | STM32_SPI_SPI1_IRQ_PRIORITY,
102 | (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
103 | NULL);
104 | dmaStreamSetPeripheral(dmatx, &SPI1->DR);
105 |
106 | SPI1->CR1 = 0;
107 | SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI;// | SPI_CR1_BR_1;
108 | SPI1->CR2 = 0x0700 | SPI_CR2_TXDMAEN;
109 | SPI1->CR1 |= SPI_CR1_SPE;
110 | }
111 |
112 | void
113 | send_command(uint8_t cmd, int len, const uint8_t *data)
114 | {
115 | CS_LOW;
116 | DC_CMD;
117 | ssp_databit8();
118 | ssp_senddata(cmd);
119 | DC_DATA;
120 | while (len-- > 0) {
121 | ssp_senddata(*data++);
122 | }
123 | //CS_HIGH;
124 | }
125 |
126 | const uint8_t ili9341_init_seq[] = {
127 | // cmd, len, data...,
128 | // Power control B
129 | 0xCF, 3, 0x00, 0x83, 0x30,
130 | // Power on sequence control
131 | 0xED, 4, 0x64, 0x03, 0x12, 0x81,
132 | //0xED, 4, 0x55, 0x01, 0x23, 0x01,
133 | // Driver timing control A
134 | 0xE8, 3, 0x85, 0x01, 0x79,
135 | //0xE8, 3, 0x84, 0x11, 0x7a,
136 | // Power control A
137 | 0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
138 | // Pump ratio control
139 | 0xF7, 1, 0x20,
140 | // Driver timing control B
141 | 0xEA, 2, 0x00, 0x00,
142 | // POWER_CONTROL_1
143 | 0xC0, 1, 0x26,
144 | // POWER_CONTROL_2
145 | 0xC1, 1, 0x11,
146 | // VCOM_CONTROL_1
147 | 0xC5, 2, 0x35, 0x3E,
148 | // VCOM_CONTROL_2
149 | 0xC7, 1, 0xBE,
150 | // MEMORY_ACCESS_CONTROL
151 | //0x36, 1, 0x48, // portlait
152 | 0x36, 1, 0x28, // landscape
153 | // COLMOD_PIXEL_FORMAT_SET : 16 bit pixel
154 | 0x3A, 1, 0x55,
155 | // Frame Rate
156 | 0xB1, 2, 0x00, 0x1B,
157 | // Gamma Function Disable
158 | 0xF2, 1, 0x08,
159 | // gamma set for curve 01/2/04/08
160 | 0x26, 1, 0x01,
161 | // positive gamma correction
162 | 0xE0, 15, 0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0x87, 0x32, 0x0A, 0x07, 0x02, 0x07, 0x05, 0x00,
163 | // negativ gamma correction
164 | 0xE1, 15, 0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05, 0x18, 0x0D, 0x38, 0x3A, 0x1F,
165 |
166 | // Column Address Set
167 | 0x2A, 4, 0x00, 0x00, 0x01, 0x3f, // width 320
168 | // Page Address Set
169 | 0x2B, 4, 0x00, 0x00, 0x00, 0xef, // height 240
170 |
171 | // entry mode
172 | 0xB7, 1, 0x06,
173 | // display function control
174 | 0xB6, 4, 0x0A, 0x82, 0x27, 0x00,
175 |
176 | // control display
177 | //0x53, 1, 0x0c,
178 | // diaplay brightness
179 | //0x51, 1, 0xff,
180 |
181 | // sleep out
182 | 0x11, 0,
183 | 0 // sentinel
184 | };
185 |
186 | void
187 | ili9341_init(void)
188 | {
189 | spi_init();
190 | #if 1
191 | DC_DATA;
192 | RESET_ASSERT;
193 | chThdSleepMilliseconds(10);
194 | RESET_NEGATE;
195 |
196 | send_command(0x01, 0, NULL); // SW reset
197 | chThdSleepMilliseconds(5);
198 | send_command(0x28, 0, NULL); // display off
199 |
200 | const uint8_t *p;
201 | for (p = ili9341_init_seq; *p; ) {
202 | send_command(p[0], p[1], &p[2]);
203 | p += 2 + p[1];
204 | chThdSleepMilliseconds(5);
205 | }
206 |
207 | chThdSleepMilliseconds(100);
208 | send_command(0x29, 0, NULL); // display on
209 | #endif
210 | }
211 |
212 | void ili9341_pixel(int x, int y, int color)
213 | {
214 | uint8_t xx[4] = { x >> 8, x, (x+1) >> 8, (x+1) };
215 | uint8_t yy[4] = { y >> 8, y, (y+1) >> 8, (y+1) };
216 | uint8_t cc[2] = { color >> 8, color };
217 | send_command(0x2A, 4, xx);
218 | send_command(0x2B, 4, yy);
219 | send_command(0x2C, 2, cc);
220 | //send_command16(0x2C, color);
221 | }
222 |
223 |
224 |
225 | void ili9341_fill(int x, int y, int w, int h, int color)
226 | {
227 | uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) };
228 | uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) };
229 | int len = w * h;
230 | send_command(0x2A, 4, xx);
231 | send_command(0x2B, 4, yy);
232 | send_command(0x2C, 0, NULL);
233 | while (len-- > 0)
234 | ssp_senddata16(color);
235 | }
236 |
237 | void ili9341_draw_bitmap(int x, int y, int w, int h, uint16_t *buf)
238 | {
239 | uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) };
240 | uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) };
241 | int len = w * h;
242 |
243 | send_command(0x2A, 4, xx);
244 | send_command(0x2B, 4, yy);
245 | send_command(0x2C, 0, NULL);
246 |
247 | dmaStreamSetMemory0(dmatx, buf);
248 | dmaStreamSetTransactionSize(dmatx, len);
249 | dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_MINC);
250 | dmaStreamEnable(dmatx);
251 | dmaWaitCompletion(dmatx);
252 | }
253 |
254 | void
255 | ili9341_drawchar_5x7(uint8_t ch, int x, int y, uint16_t fg, uint16_t bg)
256 | {
257 | uint16_t *buf = spi_buffer;
258 | uint16_t bits;
259 | int c, r;
260 | for(c = 0; c < 7; c++) {
261 | bits = x5x7_bits[(ch * 7) + c];
262 | for (r = 0; r < 5; r++) {
263 | *buf++ = (0x8000 & bits) ? fg : bg;
264 | bits <<= 1;
265 | }
266 | }
267 | ili9341_draw_bitmap(x, y, 5, 7, spi_buffer);
268 | }
269 |
270 | void
271 | ili9341_drawstring_5x7(const char *str, int x, int y, uint16_t fg, uint16_t bg)
272 | {
273 | while (*str) {
274 | ili9341_drawchar_5x7(*str, x, y, fg, bg);
275 | x += 5;
276 | str++;
277 | }
278 | }
279 |
280 | #define SWAP(x,y) do { int z=x; x = y; y = z; } while(0)
281 |
282 | const font_t NF20x24 = { 20, 24, 1, 24, 1, (const uint32_t *)numfont20x24 };
283 | const font_t NF32x24 = { 32, 24, 1, 24, 1, (const uint32_t *)numfont32x24 };
284 | const font_t NF32x48 = { 32, 48, 2, 24, 1, (const uint32_t *)numfont32x24 };
285 | const font_t ICON48x20 = { 48, 20, 1, 40, 2, (const uint32_t *)icons48x20 };
286 |
287 | void
288 | ili9341_drawfont(uint8_t ch, const font_t *font, int x, int y, uint16_t fg, uint16_t bg)
289 | {
290 | uint16_t *buf = spi_buffer;
291 | uint32_t bits;
292 | const uint32_t *bitmap = &font->bitmap[font->slide * ch];
293 | int c, r, j, b;
294 |
295 | for (c = 0; c < font->slide; c += font->stride) {
296 | for (j = 0; j < font->scaley; j++) {
297 | int cc = c;
298 | for (r = 0; r < font->width;) {
299 | bits = bitmap[cc++];
300 | for (b = 0; b < 32 && r < font->width; b++,r++) {
301 | *buf++ = (0x80000000UL & bits) ? fg : bg;
302 | bits <<= 1;
303 | }
304 | }
305 | }
306 | }
307 | ili9341_draw_bitmap(x, y, font->width, font->height, spi_buffer);
308 | }
309 |
310 | void
311 | ili9341_drawfont_string(const char *str, const font_t *font, int x, int y, uint16_t fg, uint16_t bg)
312 | {
313 | while (*str) {
314 | char c = *str++;
315 | if (c >= '0' && c <= '9')
316 | ili9341_drawfont(c - '0', font, x, y, fg, bg);
317 | else if (c > 0 && c < 7)
318 | ili9341_drawfont(c + 9, font, x, y, fg, bg);
319 | else if (c == '.')
320 | ili9341_drawfont(10, font, x, y, fg, bg);
321 | else if (c == '-')
322 | ili9341_drawfont(11, font, x, y, fg, bg);
323 | else
324 | ili9341_fill(x, y, font->width, font->height, bg);
325 | x += font->width;
326 | }
327 | }
328 |
329 | void
330 | ili9341_set_direction(int rot180)
331 | {
332 | char value = 0x28; // landscape
333 | if (rot180) {
334 | value |= 0xc0; // reverse X and Y axis
335 | }
336 |
337 | send_command(0x36, 1, &value);
338 | }
339 |
--------------------------------------------------------------------------------
/mcuconf.h:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #ifndef MCUCONF_H
18 | #define MCUCONF_H
19 |
20 | /*
21 | * STM32F3xx drivers configuration.
22 | * The following settings override the default settings present in
23 | * the various device driver implementation headers.
24 | * Note that the settings for each driver only have effect if the whole
25 | * driver is enabled in halconf.h.
26 | *
27 | * IRQ priorities:
28 | * 15...0 Lowest...Highest.
29 | *
30 | * DMA priorities:
31 | * 0...3 Lowest...Highest.
32 | */
33 |
34 | #define STM32F3xx_MCUCONF
35 |
36 | /*
37 | * HAL driver system settings.
38 | */
39 | #define STM32_NO_INIT FALSE
40 | //#define STM32_NO_INIT TRUE
41 | #define STM32_PVD_ENABLE FALSE
42 | #define STM32_PLS STM32_PLS_LEV0
43 | #define STM32_HSI_ENABLED TRUE
44 | #define STM32_LSI_ENABLED TRUE
45 | #define STM32_HSE_ENABLED TRUE
46 | #define STM32_LSE_ENABLED FALSE
47 | #define STM32_SW STM32_SW_PLL
48 | //#define STM32_SW STM32_SW_HSI
49 | #define STM32_PLLSRC STM32_PLLSRC_HSE
50 | #define STM32_PREDIV_VALUE 1
51 | #define STM32_PLLMUL_VALUE 9
52 | #define STM32_HPRE STM32_HPRE_DIV1
53 | #define STM32_PPRE1 STM32_PPRE1_DIV2
54 | #define STM32_PPRE2 STM32_PPRE2_DIV1
55 | #define STM32_MCOSEL STM32_MCOSEL_PLLDIV2
56 | #define STM32_ADC12PRES STM32_ADC12PRES_DIV64
57 | #define STM32_ADC34PRES STM32_ADC34PRES_DIV1
58 | #define STM32_USART1SW STM32_USART1SW_PCLK
59 | #define STM32_USART2SW STM32_USART2SW_PCLK
60 | #define STM32_USART3SW STM32_USART3SW_PCLK
61 | #define STM32_UART4SW STM32_UART4SW_PCLK
62 | #define STM32_UART5SW STM32_UART5SW_PCLK
63 | #define STM32_I2C1SW STM32_I2C1SW_SYSCLK
64 | #define STM32_I2C2SW STM32_I2C2SW_SYSCLK
65 | #define STM32_TIM1SW STM32_TIM1SW_PCLK2
66 | #define STM32_TIM8SW STM32_TIM8SW_PCLK2
67 | #define STM32_RTCSEL STM32_RTCSEL_LSI
68 | #define STM32_USB_CLOCK_REQUIRED TRUE
69 | #define STM32_USBPRE STM32_USBPRE_DIV1P5
70 |
71 | /*
72 | * ADC driver system settings.
73 | */
74 | #define STM32_ADC_USE_ADC1 TRUE
75 | #define STM32_ADC_USE_ADC3 FALSE
76 | #define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(1, 1)
77 | #define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
78 | #define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
79 | #define STM32_ADC_ADC4_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
80 | #define STM32_ADC_ADC12_DMA_PRIORITY 2
81 | #define STM32_ADC_ADC34_DMA_PRIORITY 2
82 | #define STM32_ADC_ADC12_IRQ_PRIORITY 5
83 | #define STM32_ADC_ADC34_IRQ_PRIORITY 5
84 | #define STM32_ADC_ADC12_DMA_IRQ_PRIORITY 5
85 | #define STM32_ADC_ADC34_DMA_IRQ_PRIORITY 5
86 | #define STM32_ADC_ADC12_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV4
87 | #define STM32_ADC_ADC34_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1
88 | #define STM32_ADC_DUAL_MODE FALSE
89 |
90 | /*
91 | * CAN driver system settings.
92 | */
93 | #define STM32_CAN_USE_CAN1 FALSE
94 | #define STM32_CAN_CAN1_IRQ_PRIORITY 11
95 |
96 | /*
97 | * DAC driver system settings.
98 | */
99 | #define STM32_DAC_DUAL_MODE FALSE
100 | #define STM32_DAC_USE_DAC1_CH1 TRUE
101 | #define STM32_DAC_USE_DAC1_CH2 FALSE
102 | #define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10
103 | #define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10
104 | #define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2
105 | #define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2
106 |
107 | /*
108 | * EXT driver system settings.
109 | */
110 | #define STM32_EXT_EXTI0_IRQ_PRIORITY 6
111 | #define STM32_EXT_EXTI1_IRQ_PRIORITY 6
112 | #define STM32_EXT_EXTI2_IRQ_PRIORITY 6
113 | #define STM32_EXT_EXTI3_IRQ_PRIORITY 6
114 | #define STM32_EXT_EXTI4_IRQ_PRIORITY 6
115 | #define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6
116 | #define STM32_EXT_EXTI10_15_IRQ_PRIORITY 6
117 | #define STM32_EXT_EXTI16_IRQ_PRIORITY 6
118 | #define STM32_EXT_EXTI17_IRQ_PRIORITY 6
119 | #define STM32_EXT_EXTI18_IRQ_PRIORITY 6
120 | #define STM32_EXT_EXTI19_IRQ_PRIORITY 6
121 | #define STM32_EXT_EXTI20_IRQ_PRIORITY 6
122 | #define STM32_EXT_EXTI21_22_29_IRQ_PRIORITY 6
123 | #define STM32_EXT_EXTI30_32_IRQ_PRIORITY 6
124 | #define STM32_EXT_EXTI33_IRQ_PRIORITY 6
125 |
126 | /*
127 | * GPT driver system settings.
128 | */
129 | #define STM32_GPT_USE_TIM1 FALSE
130 | #define STM32_GPT_USE_TIM2 FALSE
131 | #define STM32_GPT_USE_TIM3 FALSE
132 | #define STM32_GPT_USE_TIM4 FALSE
133 | #define STM32_GPT_USE_TIM6 FALSE
134 | #define STM32_GPT_USE_TIM7 FALSE
135 | #define STM32_GPT_USE_TIM8 FALSE
136 | #define STM32_GPT_TIM1_IRQ_PRIORITY 7
137 | #define STM32_GPT_TIM2_IRQ_PRIORITY 7
138 | #define STM32_GPT_TIM3_IRQ_PRIORITY 7
139 | #define STM32_GPT_TIM4_IRQ_PRIORITY 7
140 | #define STM32_GPT_TIM6_IRQ_PRIORITY 7
141 | #define STM32_GPT_TIM7_IRQ_PRIORITY 7
142 | #define STM32_GPT_TIM8_IRQ_PRIORITY 7
143 |
144 | /*
145 | * I2C driver system settings.
146 | */
147 | #define STM32_I2C_USE_I2C1 TRUE
148 | #define STM32_I2C_USE_I2C2 FALSE
149 | #define STM32_I2C_BUSY_TIMEOUT 50
150 | #define STM32_I2C_I2C1_IRQ_PRIORITY 10
151 | #define STM32_I2C_I2C2_IRQ_PRIORITY 10
152 | #define STM32_I2C_USE_DMA TRUE
153 | #define STM32_I2C_I2C1_DMA_PRIORITY 1
154 | #define STM32_I2C_I2C2_DMA_PRIORITY 1
155 | #define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
156 |
157 | /*
158 | * I2S driver system settings.
159 | */
160 | #define STM32_I2S_USE_SPI1 FALSE
161 | #define STM32_I2S_USE_SPI2 TRUE
162 | #define STM32_I2S_SPI1_MODE (STM32_I2S_MODE_MASTER | \
163 | STM32_I2S_MODE_RX)
164 | #define STM32_I2S_SPI2_MODE (STM32_I2S_MODE_SLAVE | \
165 | STM32_I2S_MODE_TX | \
166 | STM32_I2S_MODE_FULLDUPLEX)
167 | #define STM32_I2S_SPI1_IRQ_PRIORITY 2
168 | #define STM32_I2S_SPI2_IRQ_PRIORITY 2
169 | #define STM32_I2S_SPI1_DMA_PRIORITY 1
170 | #define STM32_I2S_SPI2_DMA_PRIORITY 1
171 | #define STM32_I2S_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
172 | #define STM32_I2S_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
173 | #define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
174 | #define STM32_I2S_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
175 | #define STM32_I2S_DMA_ERROR_HOOK(i2sp) osalSysHalt("DMA failure")
176 |
177 | /*
178 | * ICU driver system settings.
179 | */
180 | #define STM32_ICU_USE_TIM1 FALSE
181 | #define STM32_ICU_USE_TIM2 FALSE
182 | #define STM32_ICU_USE_TIM3 FALSE
183 | #define STM32_ICU_USE_TIM4 FALSE
184 | #define STM32_ICU_USE_TIM8 FALSE
185 | #define STM32_ICU_TIM1_IRQ_PRIORITY 7
186 | #define STM32_ICU_TIM2_IRQ_PRIORITY 7
187 | #define STM32_ICU_TIM3_IRQ_PRIORITY 7
188 | #define STM32_ICU_TIM4_IRQ_PRIORITY 7
189 | #define STM32_ICU_TIM8_IRQ_PRIORITY 7
190 |
191 | /*
192 | * PWM driver system settings.
193 | */
194 | #define STM32_PWM_USE_ADVANCED FALSE
195 | #define STM32_PWM_USE_TIM1 FALSE
196 | #define STM32_PWM_USE_TIM2 FALSE
197 | #define STM32_PWM_USE_TIM3 FALSE
198 | #define STM32_PWM_USE_TIM4 FALSE
199 | #define STM32_PWM_USE_TIM8 FALSE
200 | #define STM32_PWM_TIM1_IRQ_PRIORITY 7
201 | #define STM32_PWM_TIM2_IRQ_PRIORITY 7
202 | #define STM32_PWM_TIM3_IRQ_PRIORITY 7
203 | #define STM32_PWM_TIM4_IRQ_PRIORITY 7
204 | #define STM32_PWM_TIM8_IRQ_PRIORITY 7
205 |
206 | /*
207 | * SERIAL driver system settings.
208 | */
209 | #define STM32_SERIAL_USE_USART1 TRUE
210 | #define STM32_SERIAL_USE_USART2 FALSE
211 | #define STM32_SERIAL_USE_USART3 FALSE
212 | #define STM32_SERIAL_USE_UART4 FALSE
213 | #define STM32_SERIAL_USE_UART5 FALSE
214 | #define STM32_SERIAL_USART1_PRIORITY 12
215 | #define STM32_SERIAL_USART2_PRIORITY 12
216 | #define STM32_SERIAL_USART3_PRIORITY 12
217 | #define STM32_SERIAL_UART4_PRIORITY 12
218 | #define STM32_SERIAL_UART5_PRIORITY 12
219 |
220 | /*
221 | * SPI driver system settings.
222 | */
223 | #define STM32_SPI_USE_SPI1 TRUE
224 | #define STM32_SPI_USE_SPI2 FALSE
225 | #define STM32_SPI_USE_SPI3 FALSE
226 | #define STM32_SPI_SPI1_DMA_PRIORITY 1
227 | #define STM32_SPI_SPI2_DMA_PRIORITY 1
228 | #define STM32_SPI_SPI3_DMA_PRIORITY 1
229 | #define STM32_SPI_SPI1_IRQ_PRIORITY 10
230 | #define STM32_SPI_SPI2_IRQ_PRIORITY 10
231 | #define STM32_SPI_SPI3_IRQ_PRIORITY 10
232 | #define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
233 |
234 | /*
235 | * ST driver system settings.
236 | */
237 | #define STM32_ST_IRQ_PRIORITY 8
238 | #define STM32_ST_USE_TIMER 2
239 |
240 | /*
241 | * UART driver system settings.
242 | */
243 | #define STM32_UART_USE_USART1 FALSE
244 | #define STM32_UART_USE_USART2 FALSE
245 | #define STM32_UART_USE_USART3 FALSE
246 | #define STM32_UART_USART1_IRQ_PRIORITY 12
247 | #define STM32_UART_USART2_IRQ_PRIORITY 12
248 | #define STM32_UART_USART3_IRQ_PRIORITY 12
249 | #define STM32_UART_USART1_DMA_PRIORITY 0
250 | #define STM32_UART_USART2_DMA_PRIORITY 0
251 | #define STM32_UART_USART3_DMA_PRIORITY 0
252 | #define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
253 |
254 | /*
255 | * USB driver system settings.
256 | */
257 | #define STM32_USB_USE_USB1 TRUE
258 | #define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
259 | #define STM32_USB_USB1_HP_IRQ_PRIORITY 13
260 | #define STM32_USB_USB1_LP_IRQ_PRIORITY 14
261 |
262 | /*
263 | * WDG driver system settings.
264 | */
265 | #define STM32_WDG_USE_IWDG FALSE
266 |
267 | #endif /* MCUCONF_H */
268 |
--------------------------------------------------------------------------------
/nanosdr.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016-2017, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com
3 | * All rights reserved.
4 | *
5 | * This is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3, or (at your option)
8 | * any later version.
9 | *
10 | * The software is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with GNU Radio; see the file COPYING. If not, write to
17 | * the Free Software Foundation, Inc., 51 Franklin Street,
18 | * Boston, MA 02110-1301, USA.
19 | */
20 |
21 | /*
22 | * main.c
23 | */
24 |
25 |
26 | typedef struct {
27 | int32_t rms[2];
28 | int16_t ave[2];
29 | int16_t min[2];
30 | int16_t max[2];
31 |
32 | uint32_t callback_count;
33 | int32_t last_counter_value;
34 | int32_t interval_cycles;
35 | int32_t busy_cycles;
36 |
37 | uint16_t fps_count;
38 | uint16_t fps;
39 | uint16_t overflow_count;
40 | uint16_t overflow;
41 |
42 | uint16_t vref;
43 | uint16_t temperature;
44 | uint16_t battery;
45 | } stat_t;
46 |
47 | extern int16_t measured_power_dbm;
48 | extern stat_t stat;
49 |
50 | void set_agc_mode(int agcmode);
51 |
52 | /*
53 | * tlv320aic3204.c
54 | */
55 |
56 | typedef struct {
57 | int target_level;
58 | int gain_hysteresis;
59 | int attack;
60 | int attack_scale;
61 | int decay;
62 | int decay_scale;
63 | int maximum_gain;
64 | } tlv320aic3204_agc_config_t;
65 |
66 | extern void tlv320aic3204_init(void);
67 | extern void tlv320aic3204_set_gain(int g1, int g2);
68 | extern void tlv320aic3204_set_digital_gain(int g1, int g2);
69 | extern void tlv320aic3204_set_volume(int gain);
70 | extern void tlv320aic3204_agc_config(tlv320aic3204_agc_config_t *conf);
71 | extern void tlv320aic3204_set_fs(int fs);
72 | extern void tlv320aic3204_stop(void);
73 |
74 | extern void tlv320aic3204_config_adc_filter(int enable);
75 | extern void tlv320aic3204_config_adc_filter2(double iqbal);
76 | extern void tlv320aic3204_set_impedance(int imp);
77 |
78 | extern int tlv320aic3204_get_sticky_flag_register(void);
79 | extern int8_t tlv320aic3204_get_left_agc_gain(void);
80 | extern int8_t tlv320aic3204_get_right_agc_gain(void);
81 | extern void tlv320aic3204_set_adc_phase_adjust(int8_t adjust);
82 | extern void tlv320aic3204_set_adc_fine_gain_adjust(int8_t g1, int8_t g2);
83 |
84 | extern void tlv320aic3204_beep(void);
85 |
86 | #define AIC3204_STICKY_ADC_OVERFLOW 0x0c
87 |
88 | /*
89 | * dsp.c
90 | */
91 |
92 | // 5ms @ 48kHz
93 | #define AUDIO_BUFFER_LEN 480
94 |
95 | extern int16_t rx_buffer[AUDIO_BUFFER_LEN * 2];
96 | extern int16_t tx_buffer[AUDIO_BUFFER_LEN * 2];
97 | extern int16_t buffer[2][AUDIO_BUFFER_LEN];
98 | extern int16_t buffer2[2][AUDIO_BUFFER_LEN];
99 |
100 | typedef enum { B_CAPTURE, B_IF1, B_IF2, B_PLAYBACK, BUFFERS_MAX } buffer_t;
101 |
102 | typedef struct {
103 | enum { BT_C_INTERLEAVE, BT_IQ, BT_R_INTERLEAVE, BT_REAL } type;
104 | int16_t length;
105 | int16_t *buf0;
106 | int16_t *buf1;
107 | } buffer_ref_t;
108 |
109 | extern const buffer_ref_t buffers_table[BUFFERS_MAX];
110 |
111 |
112 | typedef void (*signal_process_func_t)(int16_t *src, int16_t *dst, size_t len);
113 |
114 | extern signal_process_func_t signal_process;
115 |
116 | void am_demod(int16_t *src, int16_t *dst, size_t len);
117 | void cw_demod(int16_t *src, int16_t *dst, size_t len);
118 | void lsb_demod(int16_t *src, int16_t *dst, size_t len);
119 | void usb_demod(int16_t *src, int16_t *dst, size_t len);
120 | void fm_demod(int16_t *src, int16_t *dst, size_t len);
121 | void fm_demod_stereo(int16_t *src, int16_t *dst, size_t len);
122 |
123 | void dsp_init(void);
124 |
125 | #define FS 48000
126 | #define AM_FREQ_OFFSET 10000
127 | #define SSB_FREQ_OFFSET 1300
128 | #define PHASESTEP(freq) (65536L * freq / FS)
129 |
130 | extern int32_t center_frequency;
131 | extern int16_t mode_freq_offset;
132 | extern int16_t mode_freqoffset_phasestep;
133 | extern int16_t cw_tone_phasestep;
134 |
135 | typedef struct {
136 | int16_t *buffer;
137 | int16_t stride;
138 | int16_t count;
139 | int16_t coeff;
140 |
141 | int32_t accumlate;
142 | int16_t offset;
143 | } dcrejection_t;
144 |
145 |
146 | // state variables for stereo separation
147 |
148 | typedef struct {
149 | uint32_t phase_step_default;
150 | uint32_t phase_step;
151 | uint32_t phase_accum;
152 |
153 | // average of correlation vector angle
154 | int32_t sdi;
155 | int32_t sdq;
156 |
157 | int32_t corr;
158 | int32_t corr_ave;
159 | int32_t corr_std;
160 | int16_t integrator;
161 |
162 | } stereo_separate_state_t;
163 |
164 | extern stereo_separate_state_t stereo_separate_state;
165 |
166 |
167 | /*
168 | * font: Font5x7.c numfont32x24.c numfont20x24.c icons.c
169 | */
170 |
171 | extern const uint16_t x5x7_bits [];
172 | extern const uint32_t numfont20x24[][24];
173 | extern const uint32_t numfont32x24[][24];
174 | extern const uint32_t icons48x20[][20*2];
175 |
176 | #define S_PI "\034"
177 | #define S_MICRO "\035"
178 | #define S_OHM "\036"
179 | #define S_DEGREE "\037"
180 | #define S_RARROW "\033"
181 |
182 | #define ICON_AGC_OFF 6
183 |
184 |
185 | /*
186 | * ili9341.c
187 | */
188 |
189 | #define RGB565(b,g,r) ( (((r)<<8)&0xf800) | (((g)<<3)&0x07e0) | (((b)>>3)&0x001f) )
190 |
191 | typedef struct {
192 | uint16_t width;
193 | uint16_t height;
194 | uint16_t scaley;
195 | uint16_t slide;
196 | uint16_t stride;
197 | const uint32_t *bitmap;
198 | } font_t;
199 |
200 | extern const font_t NF20x24;
201 | extern const font_t NF32x24;
202 | extern const font_t NF32x48;
203 | extern const font_t ICON48x20;
204 |
205 | extern uint16_t spi_buffer[];
206 |
207 | void ili9341_init(void);
208 | void ili9341_test(int mode);
209 | void ili9341_bulk(int x, int y, int w, int h);
210 | void ili9341_fill(int x, int y, int w, int h, int color);
211 | void ili9341_draw_bitmap(int x, int y, int w, int h, uint16_t *bitmap);
212 | void ili9341_drawchar_5x7(uint8_t ch, int x, int y, uint16_t fg, uint16_t bg);
213 | void ili9341_drawstring_5x7(const char *str, int x, int y, uint16_t fg, uint16_t bg);
214 | void ili9341_drawfont(uint8_t ch, const font_t *font, int x, int y, uint16_t fg, uint16_t bg);
215 | void ili9341_drawfont_string(const char *str, const font_t *font, int x, int y, uint16_t fg, uint16_t bg);
216 | void ili9341_set_direction(int rot180);
217 |
218 |
219 | /*
220 | * display.c
221 | */
222 |
223 | void disp_init(void);
224 | void disp_process(void);
225 | void disp_fetch_samples(int bufid, int type, int16_t *buf0, int16_t *buf1, size_t len);
226 | void disp_update(void);
227 | void disp_update_power(void);
228 | void disp_clear_aux(void);
229 |
230 | void set_window_function(int wf_type);
231 |
232 |
233 | /*
234 | * ui.c
235 | */
236 |
237 | extern void ui_init(void);
238 | extern void ui_process(void);
239 |
240 | typedef enum {
241 | MOD_CW,
242 | MOD_LSB,
243 | MOD_USB,
244 | MOD_AM,
245 | MOD_FM,
246 | MOD_FM_STEREO,
247 | MOD_MAX
248 | } modulation_t;
249 |
250 | extern void set_tune(int hz);
251 | extern void set_modulation(modulation_t mod);
252 | extern void recall_channel(unsigned int channel);
253 | extern void set_fs(int fs);
254 |
255 |
256 | typedef struct {
257 | enum { CHANNEL, FREQ, VOLUME, MOD, AGC, RFGAIN, AGC_MAXGAIN, CWTONE, IQBAL,
258 | SPDISP, WFDISP, MODE_MAX } mode;
259 | int8_t volume;
260 | uint8_t channel;
261 |
262 | uint32_t freq;
263 | modulation_t modulation;
264 | int16_t rfgain;
265 | uint8_t fs; /* 48, 96, 192 */
266 |
267 | enum { AGC_MANUAL, AGC_SLOW, AGC_MID, AGC_FAST, AGC_MAX } agcmode;
268 | int8_t digit; /* 0~5 */
269 | int freq_offset;
270 | enum { SPDISP_CAP, SPDISP_CAP2, SPDISP_IF, SPDISP_AUD, SPDISP_MODE_MAX } spdispmode;
271 | enum { WATERFALL, WAVEFORM, WAVEFORM_MAG, WAVEFORM_MAG2, WFDISP_MODE_MAX } wfdispmode;
272 | int16_t cw_tone_freq;
273 | int16_t iqbal;
274 | } uistat_t;
275 |
276 | extern uistat_t uistat;
277 |
278 | /*
279 | * flash.c
280 | */
281 |
282 | #define CHANNEL_MAX 100
283 |
284 | typedef struct {
285 | uint32_t freq;
286 | modulation_t modulation;
287 | } channel_t;
288 |
289 | typedef struct {
290 | int32_t magic;
291 | uint16_t dac_value;
292 | tlv320aic3204_agc_config_t agc;
293 | channel_t channels[CHANNEL_MAX];
294 | uistat_t uistat;
295 | int8_t freq_inverse;
296 | uint8_t button_polarity;
297 | int8_t lcd_rotation;
298 | int32_t checksum;
299 | } config_t;
300 |
301 | extern config_t config;
302 |
303 | #define CONFIG_MAGIC 0x434f4e45 /* 'CONF' */
304 |
305 | int config_save(void);
306 | int config_recall(void);
307 |
308 | void clear_all_config_prop_data(void);
309 |
310 | /*EOF*/
311 |
--------------------------------------------------------------------------------
/numfont32x24.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com
3 | * All rights reserved.
4 | *
5 | * This is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3, or (at your option)
8 | * any later version.
9 | *
10 | * The software is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with GNU Radio; see the file COPYING. If not, write to
17 | * the Free Software Foundation, Inc., 51 Franklin Street,
18 | * Boston, MA 02110-1301, USA.
19 | */
20 |
21 | #include
22 |
23 | const uint32_t numfont32x24[][24] = {
24 | { // 0
25 | 0b00000000001111111111000000000000,
26 | 0b00000001111111111111111000000000,
27 | 0b00000111111111111111111110000000,
28 | 0b00011111111111111111111111100000,
29 | 0b00111111111000000001111111110000,
30 | 0b01111111100000000000011111111000,
31 | 0b01111111000000000000001111111000,
32 | 0b11111111000000000000001111111100,
33 |
34 | 0b11111110000000000000000111111100,
35 | 0b11111110000000000000000111111100,
36 | 0b11111110000000000000000111111100,
37 | 0b11111110000000000000000111111100,
38 | 0b11111110000000000000000111111100,
39 | 0b11111110000000000000000111111100,
40 | 0b11111111000000000000001111111100,
41 | 0b01111111000000000000001111111000,
42 |
43 | 0b01111111100000000000011111111000,
44 | 0b00111111111000000001111111110000,
45 | 0b00011111111111111111111111100000,
46 | 0b00000111111111111111111110000000,
47 | 0b00000001111111111111111000000000,
48 | 0b00000000001111111111000000000000,
49 | 0b00000000000000000000000000000000,
50 | 0b00000000000000000000000000000000
51 | },
52 | { // 1
53 | 0b00000000000001111111000000000000,
54 | 0b00000000000011111111000000000000,
55 | 0b00000000000011111111000000000000,
56 | 0b00000000001111111111000000000000,
57 | 0b00000000011111111111000000000000,
58 | 0b00000001111111111111000000000000,
59 | 0b00000111111111111111000000000000,
60 | 0b00000111111111111111000000000000,
61 |
62 | 0b00000111111111111111000000000000,
63 | 0b00000111111011111111000000000000,
64 | 0b00000000000011111111000000000000,
65 | 0b00000000000011111111000000000000,
66 | 0b00000000000011111111000000000000,
67 | 0b00000000000011111111000000000000,
68 | 0b00000000000011111111000000000000,
69 | 0b00000000000011111111000000000000,
70 |
71 | 0b00000000000011111111000000000000,
72 | 0b00000000000011111111000000000000,
73 | 0b00000000000011111111000000000000,
74 | 0b00000000000011111111000000000000,
75 | 0b00000000000011111111000000000000,
76 | 0b00000000000011111111000000000000,
77 | 0b00000000000000000000000000000000,
78 | 0b00000000000000000000000000000000
79 | },
80 | { // 2
81 | 0b00000000001111111111000000000000,
82 | 0b00000001111111111111111000000000,
83 | 0b00000111111111111111111110000000,
84 | 0b00011111111111111111111111100000,
85 | 0b00111111111000000001111111110000,
86 | 0b01111111100000000000011111111000,
87 | 0b11111111000000000000011111111000,
88 | 0b11111111000000000000111111111000,
89 |
90 | 0b00000000000000000011111111110000,
91 | 0b00000000000000011111111111000000,
92 | 0b00000000000011111111111100000000,
93 | 0b00000000111111111111100000000000,
94 | 0b00000011111111111100000000000000,
95 | 0b00001111111111100000000000000000,
96 | 0b00111111111100000000000000000000,
97 | 0b01111111110000000000000000000000,
98 |
99 | 0b11111111100000000000000000000000,
100 | 0b11111111000000000000000000000000,
101 | 0b11111111111111111111111111111100,
102 | 0b11111111111111111111111111111100,
103 | 0b11111111111111111111111111111100,
104 | 0b11111111111111111111111111111100,
105 | 0b00000000000000000000000000000000,
106 | 0b00000000000000000000000000000000
107 | },
108 | { // 3
109 | 0b00000000001111111111000000000000,
110 | 0b00000001111111111111111000000000,
111 | 0b00000111111111111111111110000000,
112 | 0b00011111111111111111111111100000,
113 | 0b00111111111000000001111111110000,
114 | 0b01111111100000000000011111111000,
115 | 0b11111111000000000000001111111000,
116 | 0b11111111000000000000001111111000,
117 |
118 | 0b00000000000000000000111111110000,
119 | 0b00000000000000111111111111000000,
120 | 0b00000000000000111111111100000000,
121 | 0b00000000000000111111111100000000,
122 | 0b00000000000000111111111111000000,
123 | 0b00000000000000000000111111110000,
124 | 0b11111111000000000000001111111000,
125 | 0b11111111000000000000001111111000,
126 |
127 | 0b01111111100000000000011111111000,
128 | 0b00111111111000000001111111110000,
129 | 0b00011111111111111111111111100000,
130 | 0b00000111111111111111111110000000,
131 | 0b00000001111111111111111000000000,
132 | 0b00000000001111111111000000000000,
133 | 0b00000000000000000000000000000000,
134 | 0b00000000000000000000000000000000
135 | },
136 | { // 4
137 | 0b00000000000000000011111110000000,
138 | 0b00000000000000000111111110000000,
139 | 0b00000000000000011111111110000000,
140 | 0b00000000000000111111111110000000,
141 | 0b00000000000011111111111110000000,
142 | 0b00000000000111111111111110000000,
143 | 0b00000000011111111001111110000000,
144 | 0b00000000111111110001111110000000,
145 |
146 | 0b00000011111111000001111110000000,
147 | 0b00000111111110000001111110000000,
148 | 0b00011111111000000001111110000000,
149 | 0b00111111110000000001111110000000,
150 | 0b11111111000000000001111110000000,
151 | 0b11111110000000000001111110000000,
152 | 0b11111111111111111111111111111000,
153 | 0b11111111111111111111111111111000,
154 |
155 | 0b11111111111111111111111111111000,
156 | 0b11111111111111111111111111111000,
157 | 0b00000000000000000001111110000000,
158 | 0b00000000000000000001111110000000,
159 | 0b00000000000000000001111110000000,
160 | 0b00000000000000000001111110000000,
161 | 0b00000000000000000000000000000000,
162 | 0b00000000000000000000000000000000
163 | },
164 | { // 5
165 | 0b11111111111111111111111111111000,
166 | 0b11111111111111111111111111111000,
167 | 0b11111111111111111111111111111000,
168 | 0b11111111111111111111111111111000,
169 | 0b11111110000000000000000000000000,
170 | 0b11111110000000000000000000000000,
171 | 0b11111110000000000000000000000000,
172 | 0b11111110011111111111000000000000,
173 |
174 | 0b11111111111111111111111100000000,
175 | 0b11111111111111111111111111000000,
176 | 0b11111111111111111111111111100000,
177 | 0b11111111100000000011111111110000,
178 | 0b00000000000000000000111111111000,
179 | 0b00000000000000000000011111111000,
180 | 0b00000000000000000000001111111000,
181 | 0b11111111000000000000001111111000,
182 |
183 | 0b01111111100000000000011111111000,
184 | 0b00111111111000000001111111110000,
185 | 0b00011111111111111111111111100000,
186 | 0b00000111111111111111111110000000,
187 | 0b00000001111111111111111000000000,
188 | 0b00000000001111111111000000000000,
189 | 0b00000000000000000000000000000000,
190 | 0b00000000000000000000000000000000
191 | },
192 | { // 6
193 | 0b00000000001111111111000000000000,
194 | 0b00000001111111111111111000000000,
195 | 0b00001111111111111111111110000000,
196 | 0b00111111111111111111111111100000,
197 | 0b01111111111000000001111111110000,
198 | 0b11111111100000000000000000000000,
199 | 0b11111111000000000000000000000000,
200 | 0b11111110000000000000000000000000,
201 |
202 | 0b11111110011111111111110000000000,
203 | 0b11111111111111111111111110000000,
204 | 0b11111111111111111111111111100000,
205 | 0b11111111111111111111111111110000,
206 | 0b11111111110000000001111111111000,
207 | 0b11111111000000000000011111111000,
208 | 0b11111111000000000000001111111000,
209 | 0b11111111000000000000001111111000,
210 |
211 | 0b01111111100000000000011111111000,
212 | 0b00111111111000000001111111110000,
213 | 0b00011111111111111111111111100000,
214 | 0b00000111111111111111111110000000,
215 | 0b00000001111111111111111000000000,
216 | 0b00000000001111111111000000000000,
217 | 0b00000000000000000000000000000000,
218 | 0b00000000000000000000000000000000
219 | },
220 | { // 7
221 | 0b11111111111111111111111111111100,
222 | 0b11111111111111111111111111111100,
223 | 0b11111111111111111111111111111100,
224 | 0b11111111111111111111111111111100,
225 | 0b00000000000000000000011111111100,
226 | 0b00000000000000000001111111111100,
227 | 0b00000000000000000111111111100000,
228 | 0b00000000000000011111111110000000,
229 |
230 | 0b00000000000000111111111000000000,
231 | 0b00000000000001111111100000000000,
232 | 0b00000000000011111111000000000000,
233 | 0b00000000000111111110000000000000,
234 | 0b00000000000111111110000000000000,
235 | 0b00000000001111111100000000000000,
236 | 0b00000000001111111100000000000000,
237 | 0b00000000001111111100000000000000,
238 |
239 | 0b00000000011111111000000000000000,
240 | 0b00000000011111111000000000000000,
241 | 0b00000000011111111000000000000000,
242 | 0b00000000011111111000000000000000,
243 | 0b00000000011111111000000000000000,
244 | 0b00000000011111111000000000000000,
245 | 0b00000000000000000000000000000000,
246 | 0b00000000000000000000000000000000
247 | },
248 | { // 8
249 | 0b00000000001111111111000000000000,
250 | 0b00000001111111111111111000000000,
251 | 0b00000111111111111111111110000000,
252 | 0b00011111111111111111111111100000,
253 | 0b00111111111000000001111111110000,
254 | 0b01111111100000000000011111111000,
255 | 0b01111111000000000000001111111000,
256 | 0b01111111100000000000011111111000,
257 |
258 | 0b00111111111000000001111111110000,
259 | 0b00011111111111111111111111100000,
260 | 0b00000111111111111111111110000000,
261 | 0b00000111111111111111111110000000,
262 | 0b00011111111111111111111111100000,
263 | 0b01111111111000000001111111111000,
264 | 0b11111111100000000000011111111100,
265 | 0b11111111000000000000001111111100,
266 |
267 | 0b11111111100000000000011111111100,
268 | 0b11111111111000000001111111111100,
269 | 0b01111111111111111111111111111000,
270 | 0b00111111111111111111111111110000,
271 | 0b00001111111111111111111111000000,
272 | 0b00000001111111111111111000000000,
273 | 0b00000000000000000000000000000000,
274 | 0b00000000000000000000000000000000
275 | },
276 | { // 9
277 | 0b00000000011111111111110000000000,
278 | 0b00000011111111111111111110000000,
279 | 0b00001111111111111111111111100000,
280 | 0b00111111111111111111111111110000,
281 | 0b01111111111000000001111111111000,
282 | 0b01111111100000000000011111111000,
283 | 0b11111111000000000000001111111100,
284 | 0b11111111000000000000001111111100,
285 |
286 | 0b11111111100000000000011111111100,
287 | 0b11111111111000000001111111111100,
288 | 0b01111111111111111111111111111100,
289 | 0b00111111111111111111111111111100,
290 | 0b00001111111111111111111111111100,
291 | 0b00000000111111111111111111111100,
292 | 0b00000000000000000000000111111100,
293 | 0b00000000000000000000001111111000,
294 |
295 | 0b01111111100000000000011111111000,
296 | 0b00111111111000000001111111110000,
297 | 0b00011111111111111111111111100000,
298 | 0b00000111111111111111111110000000,
299 | 0b00000001111111111111111000000000,
300 | 0b00000000001111111111000000000000,
301 | 0b00000000000000000000000000000000,
302 | 0b00000000000000000000000000000000
303 | },
304 | { // Hz = \001
305 | 0b00000000000000000000000000000000,
306 | 0b00000000000000000000000000000000,
307 | 0b00000000000000000000000000000000,
308 | 0b00000000000000000000000000000000,
309 | 0b00000000000000000000000000000000,
310 | 0b00000000000000000000000000000000,
311 | 0b00000000000000000000000000000000,
312 | 0b11111000000111110000000000000000,
313 |
314 | 0b11111000000111110000000000000000,
315 | 0b11111000000111110111111111111110,
316 | 0b11111000000111110111111111111110,
317 | 0b11111000000111110111111111111110,
318 | 0b11111000000111110000000011111100,
319 | 0b11111111111111110000000111111000,
320 | 0b11111111111111110000001111110000,
321 | 0b11111111111111110000011111100000,
322 |
323 | 0b11111000000111110000111111000000,
324 | 0b11111000000111110001111110000000,
325 | 0b11111000000111110011111100000000,
326 | 0b11111000000111110111111111111110,
327 | 0b11111000000111110111111111111110,
328 | 0b11111000000111110111111111111110,
329 | 0b00000000000000000000000000000000,
330 | 0b00000000000000000000000000000000
331 | },
332 | { // k
333 | 0b00000000000000000000000000000000,
334 | 0b00000000000000000000000000000000,
335 | 0b00000000000000000000000000000000,
336 | 0b00000000000000000000000000000000,
337 | 0b00000000000000000000000000000000,
338 | 0b00000000000000000000000000000000,
339 | 0b00000000000000000000000000000000,
340 | 0b01111100000000000000000000000000,
341 |
342 | 0b01111100000000000000000000000000,
343 | 0b01111100000111111000000000000000,
344 | 0b01111100001111110000000000000000,
345 | 0b01111100011111100000000000000000,
346 | 0b01111100111111000000000000000000,
347 | 0b01111101111110000000000000000000,
348 | 0b01111111111100000000000000000000,
349 | 0b01111111111000000000000000000000,
350 |
351 | 0b01111111111100000000000000000000,
352 | 0b01111101111110000000000000000000,
353 | 0b01111100111111000000000000000000,
354 | 0b01111100011111100000000000000000,
355 | 0b01111100001111110000000000000000,
356 | 0b01111100000111111000100000000000,
357 | 0b00000000000000000000000000000000,
358 | 0b00000000000000000000000000000000
359 | },
360 | };
361 |
362 |
--------------------------------------------------------------------------------
/prog.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 | DFU_UTIL=../dfu-util/src/dfu-util
3 | $DFU_UTIL -d 0483:df11 -a 0 -s 0x08000000:leave -D build/ch.bin
4 |
--------------------------------------------------------------------------------
/python/README.md:
--------------------------------------------------------------------------------
1 | # Python materials for CentSDR
2 |
3 | python関連のファイルです。
4 |
5 | ## DSPデザインファイル
6 |
7 | フィルタ係数の設計に使用したJupyter notebookです。
8 |
9 | - [SSB-Filter-Design.ipynb](SSB-Filter-Design.ipynb) : SSBモード用の1300Hz LPF IIRフィルタ設計
10 | - [CW-Filter-Design.ipynb](CW-Filter-Design.ipynb) : CWモード用の150Hz LPF IIRフィルタ設計
11 | - [TLV320AIC3204-1st-IIR-HPF.ipynb](TLV320AIC3204-1st-IIR-HPF.ipynb) : Codec DSP用DCリジェクトHPFフィルタ
12 |
13 | ## centsdr.py
14 |
15 | CentSDRをスクリプトやコマンドラインから制御するための、モジュール兼コマンドです。
16 | シリアル(USB-CDC)のコマンドを、Pythonスクリプトで行うものです。内部バッファの波形をプロットすることもできます。
17 |
18 | ## Requirement
19 |
20 | - python 2.7
21 | - pyserial
22 |
23 | 波形表示をするにはオプションで下記が必要です
24 |
25 | - numpy
26 | - matplotlib
27 |
28 | ## デバイスの指定
29 |
30 | シリアルポートを指定する必要があります。環境変数`CENTSDR_DEVICE`、または`-d`オプションで指定します。スクリプトの冒頭の`DEFAULT_DEVICE`を修正してもOKです。
31 |
32 | - `$ export CENTSDR_DEVICE=/dev/ttyACM1`
33 | - `$ ./centsdr.py -d /dev/cu.usbmodem401 -p 0`
34 | - `$ CENTSDR_DEVICE=/dev/cu.usbmodem401 ./centsdr.py -p 0`
35 |
36 | ## Usage
37 |
38 | ```
39 | $ ./centsdr.py -h
40 | Usage: centsdr.py [options]
41 |
42 | Options:
43 | -h, --help show this help message and exit
44 | -d DEV, --dev=DEV device node (default from env var CENTSDR_DEVICE)
45 | -F FREQ, --freqeucy=FREQ
46 | set tuning frequency
47 | -G GAIN, --gain=GAIN gain (0-95)
48 | -V VOLUME, --volume=VOLUME
49 | set volume
50 | -A AGC, --agc=AGC set agc
51 | -M MODE, --mode=MODE set modulation
52 | -C MODE, --channel=MODE
53 | set channel
54 | -P, --power show power
55 | -s, --show show current setting
56 | -S SHOWARG, --show-arg=SHOWARG
57 | show specific setting
58 | -p BUFFER, --plot=BUFFER
59 | plot buffer
60 | -l, --loop loop continuously
61 | ```
62 |
63 | ## コマンドラインから制御する
64 |
65 | コマンドラインからの制御例を示します。オプションは複数同時に指定できます。
66 |
67 | ### 周波数を設定する
68 |
69 | ```
70 | $ ./centsdr.py -F 27500000
71 | ```
72 |
73 | ### 復調モードを設定する
74 |
75 | ```
76 | $ ./centsdr.py -M fm
77 | ```
78 |
79 | ### ボリュームを設定する
80 |
81 | ```
82 | $ ./centsdr.py -V 10
83 | ```
84 |
85 | ### AGCを設定する
86 |
87 | ```
88 | $ ./centsdr.py -A mid
89 | ```
90 |
91 | ### RFゲインを設定する
92 |
93 | ```
94 | $ ./centsdr.py -G 40
95 | ```
96 |
97 | ## データ取得
98 |
99 | ### 現在状態を取得する
100 |
101 | ```
102 | $ ./centsdr.py -s
103 | tune: 27500300
104 | volume: 10
105 | mode: fm
106 | gain: 60
107 | channel: 8
108 | agc: manual
109 | ```
110 |
111 | ### 電力を取得する
112 |
113 | ```
114 | $ ./centsdr.py -P
115 | -73.1
116 | ```
117 |
118 | ### 波形を表示する
119 |
120 | 波形データが保存されているバッファ番号を指定します。
121 |
122 | - 0: Capture buffer
123 | - 1: Audio play buffer
124 | - 2: intermediate buffer 1
125 | - 3: intermediate buffer 2
126 |
127 | ```
128 | $ ./centsdr.py -p 0
129 | ```
130 |
131 | クローズは、ウィンドウのクローズボタンです。Ctrl-Cでは消えません。
132 |
133 | `-l`を指定すると連続して表示を行います。
134 |
135 | ```
136 | $ ./centsdr.py -p 0 -l
137 | ```
138 |
139 | こちらの停止はCtrl-Cです。クローズボタンでは消えません。
140 |
141 |
142 |

143 |
144 |
145 | ## スクリプトからの使用
146 |
147 | モジュールとしてimportしてスクリプトで使用することができます。
148 |
149 | ```
150 | from centsdr import CentSDR
151 | sdr = CentSDR()
152 | sdr.set_tune(27500000)
153 | sdr.set_mode('fm')
154 | sdr.set_volume(20)
155 | ```
156 |
--------------------------------------------------------------------------------
/python/centsdr.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import numpy as np
3 | import serial
4 | import struct
5 | import os
6 | import re
7 |
8 | DEFAULT_DEVICE='/dev/cu.usbmodem401'
9 |
10 | class CentSDR():
11 | def __init__(self, dev = None):
12 | self.dev = dev or os.getenv('CENTSDR_DEVICE') or DEFAULT_DEVICE
13 | self.serial = None
14 |
15 | def __enter__(self):
16 | self.open()
17 | return self
18 |
19 | def __exit__(self, exc_type, exc_value, traceback):
20 | self.close()
21 |
22 | def open(self):
23 | if self.serial is None:
24 | self.serial = serial.Serial(self.dev)
25 |
26 | def close(self):
27 | if self.serial:
28 | self.serial.close()
29 | self.serial = None
30 |
31 | def send_command(self, cmd):
32 | self.open()
33 | self.serial.write(cmd)
34 | self.serial.readline() # discard empty line
35 |
36 | def set_frequency(self, freq):
37 | self.send_command("freq %d\r" % freq)
38 |
39 | def set_tune(self, freq):
40 | self.send_command("tune %d\r" % freq)
41 |
42 | def set_gain(self, gain):
43 | self.send_command("gain %d\r" % gain)
44 |
45 | def set_volume(self, gain):
46 | self.send_command("volume %d\r" % gain)
47 |
48 | def set_fs(self, fs):
49 | self.send_command("fs %d\r" % fs)
50 |
51 | def set_mode(self, mode):
52 | self.send_command("mode %s\r" % mode)
53 |
54 | def set_channel(self, chan):
55 | self.send_command("channel %d\r" % chan)
56 |
57 | def set_agc(self, agc):
58 | self.send_command("agc %s\r" % agc)
59 |
60 | def fetch_data(self):
61 | result = ''
62 | line = ''
63 | while True:
64 | c = self.serial.read()
65 | if c == chr(13):
66 | next # ignore CR
67 | line += c
68 | if c == chr(10):
69 | result += line
70 | line = ''
71 | next
72 | if line.endswith('ch>'):
73 | # stop on prompt
74 | break
75 | return result
76 |
77 | def fetch_array(self, sel):
78 | def hex16(h):
79 | return struct.unpack('>h', h.decode('hex'))[0]
80 | self.send_command("data %d\r" % sel)
81 | data = self.fetch_data()
82 | x = []
83 | for line in data.split('\n'):
84 | if line:
85 | x.extend([hex16(d) for d in line.strip().split(' ')])
86 | return np.array(x)
87 |
88 | def data(self, sel = 0):
89 | self.send_command("data %d\r" % sel)
90 | data = self.fetch_data()
91 | x = []
92 | for line in data.split('\n'):
93 | if line:
94 | d = line.strip().split(' ')
95 | x.append(float(d[0])+float(d[1])*1.j)
96 | return np.array(x)
97 |
98 | def read_power(self):
99 | self.send_command("power\r")
100 | resp = self.fetch_data()
101 | m = re.match(r"power: ([\d.-]+)dBm", resp)
102 | return float(m.group(1))
103 |
104 | def read_status(self, arg = ''):
105 | self.send_command("show %s\r" % arg)
106 | return self.fetch_data()
107 |
108 | def flush_data(self):
109 | self.send_command("\r")
110 | self.fetch_data()
111 |
112 | def run_as_command():
113 | from optparse import OptionParser
114 | parser = OptionParser(usage="%prog [options]")
115 | parser.add_option("-d", "--dev", dest="device",
116 | help="device node (default from env var CENTSDR_DEVICE)", metavar="DEV")
117 | parser.add_option("-F", "--freqeucy", type="int", dest="freq",
118 | help="set tuning frequency", metavar="FREQ")
119 | parser.add_option("-G", "--gain", type="int", dest="gain",
120 | help="gain (0-95)", metavar="GAIN")
121 | parser.add_option("-V", "--volume", type="string", dest="volume",
122 | help="set volume", metavar="VOLUME")
123 | parser.add_option("-A", "--agc", type="string", dest="agc",
124 | help="set agc", metavar="AGC")
125 | parser.add_option("-M", "--mode", type="string", dest="mode",
126 | help="set modulation", metavar="MODE")
127 | parser.add_option("-C", "--channel", type="string", dest="channel",
128 | help="set channel", metavar="MODE")
129 | parser.add_option("-P", "--power", action="store_true", dest="power",
130 | help="show power")
131 | parser.add_option("-s", "--show", action="store_true", dest="show",
132 | help="show current setting")
133 | parser.add_option("-S", "--show-arg", type='string', dest="showarg", default='',
134 | help="show specific setting")
135 | parser.add_option("-p", "--plot", dest="buffer",
136 | help="plot buffer", metavar="BUFFER")
137 | parser.add_option("-l", "--loop", action="store_true", dest="loop", default=False,
138 | help="loop continuously")
139 | (opt, args) = parser.parse_args()
140 | sdr = CentSDR(opt.device)
141 | if opt.freq:
142 | sdr.set_tune(opt.freq)
143 | if opt.gain:
144 | sdr.set_gain(opt.gain)
145 | if opt.mode:
146 | sdr.set_mode(opt.mode)
147 | if opt.volume:
148 | sdr.set_volume(int(opt.volume))
149 | if opt.channel:
150 | sdr.set_channel(int(opt.channel))
151 | if opt.agc:
152 | sdr.set_agc(opt.agc)
153 | if opt.show:
154 | print sdr.read_status(opt.showarg)
155 | if opt.buffer:
156 | import pylab as pl
157 | sdr.flush_data()
158 | opt.buffer = int(opt.buffer)
159 | samp = sdr.fetch_array(opt.buffer)
160 | if opt.buffer == 0:
161 | samp = np.array(samp[0::2]) + np.array(samp[1::2])*1j
162 | x = range(len(samp))
163 | if opt.loop:
164 | from signal import signal, SIGINT
165 | def sigint_handler(signum, frame):
166 | opt.loop = False
167 | signal(SIGINT, sigint_handler)
168 | pl.ion()
169 | g1 = pl.plot(x, np.real(samp))
170 | g2 = pl.plot(x, np.imag(samp))
171 | pl.ylim(-10000,10000)
172 | pl.xlim(0, len(samp))
173 | while opt.loop:
174 | samp = sdr.fetch_array(opt.buffer)
175 | if opt.buffer == 0:
176 | samp = np.array(samp[0::2]) + np.array(samp[1::2])*1j
177 | x = range(len(samp))
178 | g1[0].set_data(x, np.real(samp))
179 | g2[0].set_data(x, np.imag(samp))
180 | pl.draw()
181 | pl.pause(0.01)
182 | pl.show()
183 | exit(0)
184 | if opt.power:
185 | print sdr.read_power()
186 | exit(0)
187 |
188 | if __name__ == '__main__':
189 | run_as_command()
190 |
--------------------------------------------------------------------------------
/rules_code.ld:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | ENTRY(Reset_Handler)
18 |
19 | SECTIONS
20 | {
21 | vectors : ALIGN(16) SUBALIGN(16)
22 | {
23 | KEEP(*(.vectors))
24 | } > VECTORS_FLASH AT > VECTORS_FLASH_LMA
25 |
26 | xtors : ALIGN(4) SUBALIGN(4)
27 | {
28 | __init_array_start = .;
29 | KEEP(*(SORT(.init_array.*)))
30 | KEEP(*(.init_array))
31 | __init_array_end = .;
32 | __fini_array_start = .;
33 | KEEP(*(.fini_array))
34 | KEEP(*(SORT(.fini_array.*)))
35 | __fini_array_end = .;
36 | } > XTORS_FLASH AT > XTORS_FLASH_LMA
37 |
38 | INCLUDE ccmfunc.ld
39 |
40 | .text : ALIGN(16) SUBALIGN(16)
41 | {
42 | *(.text)
43 | *(.text.*)
44 | *(.glue_7t)
45 | *(.glue_7)
46 | *(.gcc*)
47 | } > TEXT_FLASH AT > TEXT_FLASH_LMA
48 |
49 | .rodata : ALIGN(4)
50 | {
51 | . = ALIGN(4);
52 | __rodata_base__ = .;
53 | *(.rodata)
54 | *(.rodata.*)
55 | . = ALIGN(4);
56 | __rodata_end__ = .;
57 | } > RODATA_FLASH AT > RODATA_FLASH_LMA
58 |
59 | .ARM.extab :
60 | {
61 | *(.ARM.extab* .gnu.linkonce.armextab.*)
62 | } > VARIOUS_FLASH AT > VARIOUS_FLASH_LMA
63 |
64 | .ARM.exidx : {
65 | __exidx_start = .;
66 | *(.ARM.exidx* .gnu.linkonce.armexidx.*)
67 | __exidx_end = .;
68 | } > VARIOUS_FLASH AT > VARIOUS_FLASH_LMA
69 |
70 | .eh_frame_hdr :
71 | {
72 | *(.eh_frame_hdr)
73 | } > VARIOUS_FLASH AT > VARIOUS_FLASH_LMA
74 |
75 | .eh_frame : ONLY_IF_RO
76 | {
77 | *(.eh_frame)
78 | } > VARIOUS_FLASH AT > VARIOUS_FLASH_LMA
79 | }
80 |
--------------------------------------------------------------------------------
/si5351.c:
--------------------------------------------------------------------------------
1 | #include "hal.h"
2 | #include "si5351.h"
3 |
4 | #define SI5351_I2C_ADDR (0x60<<1)
5 |
6 | static void
7 | si5351_write(uint8_t reg, uint8_t dat)
8 | {
9 | int addr = SI5351_I2C_ADDR>>1;
10 | uint8_t buf[] = { reg, dat };
11 | i2cAcquireBus(&I2CD1);
12 | (void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, 2, NULL, 0, 1000);
13 | i2cReleaseBus(&I2CD1);
14 | }
15 |
16 | static void
17 | si5351_bulk_write(const uint8_t *buf, int len)
18 | {
19 | int addr = SI5351_I2C_ADDR>>1;
20 | i2cAcquireBus(&I2CD1);
21 | (void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, len, NULL, 0, 1000);
22 | i2cReleaseBus(&I2CD1);
23 | }
24 |
25 | void si5351_disable_output(void)
26 | {
27 | uint8_t reg[4];
28 | si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xff);
29 | reg[0] = SI5351_REG_16_CLK0_CONTROL;
30 | reg[1] = SI5351_CLK_POWERDOWN;
31 | reg[2] = SI5351_CLK_POWERDOWN;
32 | reg[3] = SI5351_CLK_POWERDOWN;
33 | si5351_bulk_write(reg, 4);
34 | }
35 |
36 | void si5351_enable_output(void)
37 | {
38 | si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0x00);
39 | }
40 |
41 | void si5351_reset_pll(void)
42 | {
43 | //si5351_write(SI5351_REG_177_PLL_RESET, SI5351_PLL_RESET_A | SI5351_PLL_RESET_B);
44 | si5351_write(SI5351_REG_177_PLL_RESET, 0xAC);
45 | }
46 |
47 | void si5351_setupPLL(uint8_t pll, /* SI5351_PLL_A or SI5351_PLL_B */
48 | uint8_t mult,
49 | uint32_t num,
50 | uint32_t denom)
51 | {
52 | /* Get the appropriate starting point for the PLL registers */
53 | const uint8_t pllreg_base[] = {
54 | SI5351_REG_26_PLL_A,
55 | SI5351_REG_34_PLL_B
56 | };
57 | uint32_t P1;
58 | uint32_t P2;
59 | uint32_t P3;
60 |
61 | /* Feedback Multisynth Divider Equation
62 | * where: a = mult, b = num and c = denom
63 | * P1 register is an 18-bit value using following formula:
64 | * P1[17:0] = 128 * mult + floor(128*(num/denom)) - 512
65 | * P2 register is a 20-bit value using the following formula:
66 | * P2[19:0] = 128 * num - denom * floor(128*(num/denom))
67 | * P3 register is a 20-bit value using the following formula:
68 | * P3[19:0] = denom
69 | */
70 |
71 | /* Set the main PLL config registers */
72 | if (num == 0)
73 | {
74 | /* Integer mode */
75 | P1 = 128 * mult - 512;
76 | P2 = 0;
77 | P3 = 1;
78 | }
79 | else
80 | {
81 | /* Fractional mode */
82 | //P1 = (uint32_t)(128 * mult + floor(128 * ((float)num/(float)denom)) - 512);
83 | P1 = 128 * mult + ((128 * num) / denom) - 512;
84 | //P2 = (uint32_t)(128 * num - denom * floor(128 * ((float)num/(float)denom)));
85 | P2 = 128 * num - denom * ((128 * num) / denom);
86 | P3 = denom;
87 | }
88 |
89 | /* The datasheet is a nightmare of typos and inconsistencies here! */
90 | uint8_t reg[9];
91 | reg[0] = pllreg_base[pll];
92 | reg[1] = (P3 & 0x0000FF00) >> 8;
93 | reg[2] = (P3 & 0x000000FF);
94 | reg[3] = (P1 & 0x00030000) >> 16;
95 | reg[4] = (P1 & 0x0000FF00) >> 8;
96 | reg[5] = (P1 & 0x000000FF);
97 | reg[6] = ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16);
98 | reg[7] = (P2 & 0x0000FF00) >> 8;
99 | reg[8] = (P2 & 0x000000FF);
100 | si5351_bulk_write(reg, 9);
101 | }
102 |
103 | void
104 | si5351_setupMultisynth(uint8_t output,
105 | uint8_t pllSource,
106 | uint32_t div, // 4,6,8, 8+ ~ 900
107 | uint32_t num,
108 | uint32_t denom,
109 | uint32_t rdiv, // SI5351_R_DIV_1~128
110 | uint8_t drive_strength)
111 | {
112 | /* Get the appropriate starting point for the PLL registers */
113 | const uint8_t msreg_base[] = {
114 | SI5351_REG_42_MULTISYNTH0,
115 | SI5351_REG_50_MULTISYNTH1,
116 | SI5351_REG_58_MULTISYNTH2,
117 | };
118 | const uint8_t clkctrl[] = {
119 | SI5351_REG_16_CLK0_CONTROL,
120 | SI5351_REG_17_CLK1_CONTROL,
121 | SI5351_REG_18_CLK2_CONTROL
122 | };
123 | uint8_t dat;
124 |
125 | uint32_t P1;
126 | uint32_t P2;
127 | uint32_t P3;
128 | uint32_t div4 = 0;
129 |
130 | /* Output Multisynth Divider Equations
131 | * where: a = div, b = num and c = denom
132 | * P1 register is an 18-bit value using following formula:
133 | * P1[17:0] = 128 * a + floor(128*(b/c)) - 512
134 | * P2 register is a 20-bit value using the following formula:
135 | * P2[19:0] = 128 * b - c * floor(128*(b/c))
136 | * P3 register is a 20-bit value using the following formula:
137 | * P3[19:0] = c
138 | */
139 | /* Set the main PLL config registers */
140 | if (div == 4) {
141 | div4 = SI5351_DIVBY4;
142 | P1 = P2 = 0;
143 | P3 = 1;
144 | } else if (num == 0) {
145 | /* Integer mode */
146 | P1 = 128 * div - 512;
147 | P2 = 0;
148 | P3 = 1;
149 | } else {
150 | /* Fractional mode */
151 | P1 = 128 * div + ((128 * num) / denom) - 512;
152 | P2 = 128 * num - denom * ((128 * num) / denom);
153 | P3 = denom;
154 | }
155 |
156 | /* Set the MSx config registers */
157 | uint8_t reg[9];
158 | reg[0] = msreg_base[output];
159 | reg[1] = (P3 & 0x0000FF00) >> 8;
160 | reg[2] = (P3 & 0x000000FF);
161 | reg[3] = ((P1 & 0x00030000) >> 16) | div4 | rdiv;
162 | reg[4] = (P1 & 0x0000FF00) >> 8;
163 | reg[5] = (P1 & 0x000000FF);
164 | reg[6] = ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16);
165 | reg[7] = (P2 & 0x0000FF00) >> 8;
166 | reg[8] = (P2 & 0x000000FF);
167 | si5351_bulk_write(reg, 9);
168 |
169 | /* Configure the clk control and enable the output */
170 | dat = drive_strength | SI5351_CLK_INPUT_MULTISYNTH_N;
171 | if (pllSource == SI5351_PLL_B)
172 | dat |= SI5351_CLK_PLL_SELECT_B;
173 | if (num == 0)
174 | dat |= SI5351_CLK_INTEGER_MODE;
175 | si5351_write(clkctrl[output], dat);
176 | }
177 |
178 | static uint32_t
179 | gcd(uint32_t x, uint32_t y)
180 | {
181 | uint32_t z;
182 | while (y != 0) {
183 | z = x % y;
184 | x = y;
185 | y = z;
186 | }
187 | return x;
188 | }
189 |
190 | #define XTALFREQ 26000000L
191 | #define PLL_N 32
192 | #define PLLFREQ (XTALFREQ * PLL_N)
193 |
194 | void
195 | si5351_set_frequency_fixedpll(int channel, int pll, int pllfreq, int freq,
196 | uint32_t rdiv, uint8_t drive_strength)
197 | {
198 | int32_t div = pllfreq / freq; // range: 8 ~ 1800
199 | int32_t num = pllfreq - freq * div;
200 | int32_t denom = freq;
201 | //int32_t k = freq / (1<<20) + 1;
202 | int32_t k = gcd(num, denom);
203 | num /= k;
204 | denom /= k;
205 | while (denom >= (1<<20)) {
206 | num >>= 1;
207 | denom >>= 1;
208 | }
209 | si5351_setupMultisynth(channel, pll, div, num, denom, rdiv, drive_strength);
210 | }
211 |
212 | void
213 | si5351_set_frequency_fixeddiv(int channel, int pll, int freq, int div,
214 | uint8_t drive_strength)
215 | {
216 | int32_t pllfreq = freq * div;
217 | int32_t multi = pllfreq / XTALFREQ;
218 | int32_t num = pllfreq - multi * XTALFREQ;
219 | int32_t denom = XTALFREQ;
220 | int32_t k = gcd(num, denom);
221 | num /= k;
222 | denom /= k;
223 | while (denom >= (1<<20)) {
224 | num >>= 1;
225 | denom >>= 1;
226 | }
227 | si5351_setupPLL(pll, multi, num, denom);
228 | si5351_setupMultisynth(channel, pll, div, 0, 1, SI5351_R_DIV_1, drive_strength);
229 | }
230 |
231 | //#define drive_strength SI5351_CLK_DRIVE_STRENGTH_2MA
232 | #define drive_strength SI5351_CLK_DRIVE_STRENGTH_8MA
233 | int current_band = -1;
234 |
235 | void
236 | si5351_set_frequency(int freq)
237 | {
238 | int band;
239 | uint32_t rdiv = SI5351_R_DIV_1;
240 | if (freq <= 100000000) {
241 | band = 0;
242 | } else if (freq < 150000000) {
243 | band = 1;
244 | } else {
245 | band = 2;
246 | }
247 | if (freq <= 500000) {
248 | rdiv = SI5351_R_DIV_64;
249 | } else if (freq <= 4000000) {
250 | rdiv = SI5351_R_DIV_8;
251 | }
252 |
253 | #if 0
254 | if (current_band != band)
255 | si5351_disable_output();
256 | #endif
257 |
258 | switch (band) {
259 | case 0:
260 | if (rdiv == SI5351_R_DIV_8) {
261 | freq *= 8;
262 | } else if (rdiv == SI5351_R_DIV_64) {
263 | freq *= 64;
264 | }
265 |
266 | si5351_set_frequency_fixedpll(1, SI5351_PLL_A, PLLFREQ, freq,
267 | rdiv, drive_strength);
268 | break;
269 |
270 | case 1:
271 | // Set PLL twice on changing from band 2
272 | if (current_band == 2) {
273 | si5351_set_frequency_fixeddiv(1, SI5351_PLL_B, freq, 6, drive_strength);
274 | }
275 |
276 | // div by 6 mode. both PLL A and B are dedicated for CLK0, CLK1
277 | si5351_set_frequency_fixeddiv(1, SI5351_PLL_B, freq, 6, drive_strength);
278 | break;
279 |
280 | case 2:
281 | // div by 4 mode. both PLL A and B are dedicated for CLK0, CLK1
282 | si5351_set_frequency_fixeddiv(1, SI5351_PLL_B, freq, 4, drive_strength);
283 | break;
284 | }
285 |
286 | if (current_band != band) {
287 | si5351_reset_pll();
288 | //si5351_enable_output();
289 | }
290 |
291 | current_band = band;
292 | }
293 |
294 |
295 |
--------------------------------------------------------------------------------
/si5351.h:
--------------------------------------------------------------------------------
1 | #define SI5351_PLL_A 0
2 | #define SI5351_PLL_B 1
3 |
4 | #define SI5351_MULTISYNTH_DIV_4 4
5 | #define SI5351_MULTISYNTH_DIV_6 6
6 | #define SI5351_MULTISYNTH_DIV_8 8
7 | #define SI5351_R_DIV_1 (0<<4)
8 | #define SI5351_R_DIV_2 (1<<4)
9 | #define SI5351_R_DIV_4 (2<<4)
10 | #define SI5351_R_DIV_8 (3<<4)
11 | #define SI5351_R_DIV_16 (4<<4)
12 | #define SI5351_R_DIV_32 (5<<4)
13 | #define SI5351_R_DIV_64 (6<<4)
14 | #define SI5351_R_DIV_128 (7<<4)
15 | #define SI5351_DIVBY4 (3<<2)
16 |
17 | #define SI5351_REG_3_OUTPUT_ENABLE_CONTROL 3
18 | #define SI5351_REG_16_CLK0_CONTROL 16
19 | #define SI5351_REG_17_CLK1_CONTROL 17
20 | #define SI5351_REG_18_CLK2_CONTROL 18
21 | #define SI5351_REG_26_PLL_A 26
22 | #define SI5351_REG_34_PLL_B 34
23 | #define SI5351_REG_42_MULTISYNTH0 42
24 | #define SI5351_REG_50_MULTISYNTH1 50
25 | #define SI5351_REG_58_MULTISYNTH2 58
26 |
27 | #define SI5351_CLK_POWERDOWN (1<<7)
28 | #define SI5351_CLK_INTEGER_MODE (1<<6)
29 | #define SI5351_CLK_PLL_SELECT_B (1<<5)
30 | #define SI5351_CLK_INVERT (1<<4)
31 |
32 | #define SI5351_CLK_INPUT_MASK (3<<2)
33 | #define SI5351_CLK_INPUT_XTAL (0<<2)
34 | #define SI5351_CLK_INPUT_CLKIN (1<<2)
35 | #define SI5351_CLK_INPUT_MULTISYNTH_0_4 (2<<2)
36 | #define SI5351_CLK_INPUT_MULTISYNTH_N (3<<2)
37 |
38 | #define SI5351_CLK_DRIVE_STRENGTH_MASK (3<<0)
39 | #define SI5351_CLK_DRIVE_STRENGTH_2MA (0<<0)
40 | #define SI5351_CLK_DRIVE_STRENGTH_4MA (1<<0)
41 | #define SI5351_CLK_DRIVE_STRENGTH_6MA (2<<0)
42 | #define SI5351_CLK_DRIVE_STRENGTH_8MA (3<<0)
43 |
44 |
45 | #define SI5351_REG_177_PLL_RESET 177
46 | #define SI5351_PLL_RESET_B (1<<7)
47 | #define SI5351_PLL_RESET_A (1<<5)
48 |
49 | #define SI5351_REG_183_CRYSTAL_LOAD 183
50 | #define SI5351_CRYSTAL_LOAD_6PF (1<<6)
51 | #define SI5351_CRYSTAL_LOAD_8PF (2<<6)
52 | #define SI5351_CRYSTAL_LOAD_10PF (3<<6)
53 |
54 | #define SI5351_CRYSTAL_FREQ_25MHZ 25000000
55 |
56 | void si5351_init(void);
57 |
58 | void si5351_setupPLL(uint8_t pll, /* SI5351_PLL_A or SI5351_PLL_B */
59 | uint8_t mult,
60 | uint32_t num,
61 | uint32_t denom);
62 | void si5351_setupMultisynth(uint8_t output,
63 | uint8_t pllSource,
64 | uint32_t div,
65 | uint32_t num,
66 | uint32_t denom,
67 | uint32_t rdiv,
68 | uint8_t drive_strength);
69 |
70 | void si5351_set_frequency(int freq);
71 |
72 |
--------------------------------------------------------------------------------
/si5351_low.c:
--------------------------------------------------------------------------------
1 | #include "hal.h"
2 | #include "si5351.h"
3 |
4 | #define SI5351_I2C_ADDR (0x60<<1)
5 |
6 | static void
7 | rcc_gpio_init(void)
8 | {
9 | // Reset AHB,APB1,APB2
10 | RCC->AHBRSTR |= 0xffffffff;
11 | RCC->AHBRSTR = 0;
12 | RCC->APB1RSTR |= 0xffffffff;
13 | RCC->APB1RSTR = 0;
14 | RCC->APB2RSTR |= 0xffffffff;
15 | RCC->APB2RSTR = 0;
16 |
17 | RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_I2C1EN;
18 | RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
19 | RCC->CFGR3 |= RCC_CFGR3_I2C1SW_HSI;
20 |
21 | GPIOB->AFRH = 0x55550044; // PB8,PB9 Alternate Function 4
22 | GPIOB->OTYPER |= 0x0300; // PB8,PB9 Open drain
23 | GPIOB->MODER |= 0x000A0000;//
24 | GPIOB->OSPEEDR |= 0x00050000;//
25 | }
26 |
27 | static void
28 | i2c_init(I2C_TypeDef* i2c)
29 | {
30 | // Disable the I2Cx peripheral
31 | i2c->CR1 &= ~I2C_CR1_PE;
32 | while (i2c->CR1 & I2C_CR1_PE);
33 |
34 | // 100kHz @ 8MHz
35 | i2c->TIMINGR = 0x10420F13;
36 |
37 | // Use 7-bit addresses
38 | i2c->CR2 &=~ I2C_CR2_ADD10;
39 |
40 | // Enable the analog filter
41 | i2c->CR1 &= ~I2C_CR1_ANFOFF;
42 |
43 | // Disable NOSTRETCH
44 | i2c->CR1 |= I2C_CR1_NOSTRETCH;
45 |
46 | // Enable I2Cx peripheral clock.
47 | // Select APB1 as clock source
48 | if (i2c == I2C1) {
49 | RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
50 | } else if (i2c == I2C2) {
51 | RCC->APB1ENR |= RCC_APB1ENR_I2C2EN;
52 | }
53 |
54 | // Enable the I2Cx peripheral
55 | i2c->CR1 |= I2C_CR1_PE;
56 | }
57 |
58 | static void
59 | i2cSendByte(I2C_TypeDef* i2c, uint8_t addr, const uint8_t *buf, uint8_t len)
60 | {
61 | i2c->CR2 = (I2C_CR2_SADD & addr) // Set the slave address
62 | | (I2C_CR2_NBYTES & (len << 16)) // Send one byte
63 | | I2C_CR2_START // Generate start condition
64 | | I2C_CR2_AUTOEND; // Generate stop condition after sent
65 |
66 | // Send the data
67 | while (len-- > 0) {
68 | while (!(i2c->ISR & I2C_ISR_TXIS));
69 | i2c->TXDR = (I2C_TXDR_TXDATA & *buf++);
70 | }
71 | }
72 |
73 | // register addr, length, data, ...
74 | const uint8_t si5351_configs[] = {
75 | 2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xff,
76 | 4, SI5351_REG_16_CLK0_CONTROL, SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN,
77 | 2, SI5351_REG_183_CRYSTAL_LOAD, SI5351_CRYSTAL_LOAD_8PF,
78 | // setup PLL
79 | // setup PLL (26MHz * 32 = 832MHz : 32/2-2=14)
80 | 9, SI5351_REG_26_PLL_A, /*P3*/0, 1, /*P1*/0, 14, 0, /*P3/P2*/0, 0, 0,
81 | // RESET PLL
82 | 2, SI5351_REG_177_PLL_RESET, SI5351_PLL_RESET_A | SI5351_PLL_RESET_B,
83 | // setup multisynth (832MHz/8MHz=104,104/2-2=50)
84 | 9, SI5351_REG_58_MULTISYNTH2, /*P3*/0, 1, /*P1*/0, 50, 0, /*P2|P3*/0, 0, 0,
85 | 2, SI5351_REG_18_CLK2_CONTROL, SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_INPUT_MULTISYNTH_N | SI5351_CLK_INTEGER_MODE,
86 | 2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0,
87 | 0 // sentinel
88 | };
89 |
90 | void
91 | si5351_init_bulk(void)
92 | {
93 | const uint8_t *p = si5351_configs;
94 | while (*p) {
95 | uint8_t len = *p++;
96 | i2cSendByte(I2C1, SI5351_I2C_ADDR, p, len);
97 | p += len;
98 | }
99 | }
100 |
101 | void
102 | si5351_setup(void)
103 | {
104 | rcc_gpio_init();
105 | i2c_init(I2C1);
106 | si5351_init_bulk();
107 | }
108 |
--------------------------------------------------------------------------------
/tlv320aic3204.c:
--------------------------------------------------------------------------------
1 | #include "hal.h"
2 | #include "nanosdr.h"
3 |
4 | #define REFCLK_8000KHZ
5 | #define AIC3204_ADDR 0x18
6 |
7 | #define wait_ms(ms) chThdSleepMilliseconds(ms)
8 |
9 | static void
10 | tlv320aic3204_write(uint8_t reg, uint8_t dat)
11 | {
12 | int addr = AIC3204_ADDR;
13 | uint8_t buf[] = { reg, dat };
14 | i2cAcquireBus(&I2CD1);
15 | (void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, 2, NULL, 0, 1000);
16 | i2cReleaseBus(&I2CD1);
17 | }
18 |
19 | static void
20 | tlv320aic3204_bulk_write(const uint8_t *buf, int len)
21 | {
22 | int addr = AIC3204_ADDR;
23 | i2cAcquireBus(&I2CD1);
24 | (void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, len, NULL, 0, 1000);
25 | i2cReleaseBus(&I2CD1);
26 | }
27 |
28 | static int
29 | tlv320aic3204_read(uint8_t d0)
30 | {
31 | int addr = AIC3204_ADDR;
32 | uint8_t buf[] = { d0 };
33 | i2cAcquireBus(&I2CD1);
34 | i2cMasterTransmitTimeout(&I2CD1, addr, buf, 1, buf, 1, 1000);
35 | i2cReleaseBus(&I2CD1);
36 | return buf[0];
37 | }
38 |
39 |
40 | static void
41 | tlv320aic3204_config(const uint8_t *data)
42 | {
43 | const uint8_t *p = data;
44 | while (*p) {
45 | uint8_t len = *p++;
46 | tlv320aic3204_bulk_write(p, len);
47 | p += len;
48 | }
49 | }
50 |
51 | static const uint8_t conf_data_pll[] = {
52 | // len, ( reg, data ),
53 | 2, 0x00, 0x00, /* Initialize to Page 0 */
54 | 2, 0x01, 0x01, /* Initialize the device through software reset */
55 | 2, 0x04, 0x43, /* PLL Clock High, MCLK, PLL */
56 | #ifdef REFCLK_8000KHZ
57 | /* 8.000MHz*10.7520 = 86.016MHz, 86.016MHz/(2*7*128) = 48kHz */
58 | 2, 0x05, 0x91, /* Power up PLL, P=1,R=1 */
59 | 2, 0x06, 0x0a, /* J=10 */
60 | 2, 0x07, 29, /* D=7520 = (29<<8) + 96 */
61 | 2, 0x08, 96,
62 | #endif
63 | #ifdef REFCLK_12000KHZ
64 | /* 12.000MHz*7.1680 = 86.016MHz, 86.016MHz/(2*7*128) = 48kHz */
65 | 2, 0x05, 0x91, /* Power up PLL, P=1,R=1 */
66 | 2, 0x06, 0x07, /* J=7 */
67 | 2, 0x07, 6, /* D=1680 = (6<<8) + 144 */
68 | 2, 0x08, 144,
69 | #endif
70 | #ifdef REFCLK_19200KHZ
71 | /* 19.200MHz*4.48 = 86.016MHz, 86.016MHz/(2*7*128) = 48kHz */
72 | 2, 0x05, 0x91, /* Power up PLL, P=1,R=1 */
73 | 2, 0x06, 0x04, /* J=4 */
74 | 2, 0x07, 18, /* D=4800 = (18<<8) + 192 */
75 | 2, 0x08, 192,
76 | #endif
77 | 0 // sentinel
78 | };
79 |
80 | // default fs=48kHz
81 | static const uint8_t conf_data_clk[] = {
82 | 2, 0x0b, 0x82, /* Power up the NDAC divider with value 2 */
83 | 2, 0x0c, 0x87, /* Power up the MDAC divider with value 7 */
84 | 2, 0x0d, 0x00, /* Program the OSR of DAC to 128 */
85 | 2, 0x0e, 0x80,
86 | //2, 0x3c, 0x08, /* Set the DAC Mode to PRB_P8 */
87 | 2, 0x3c, 25, /* Set the DAC Mode to PRB_P25 */
88 | 2, 0x1b, 0x0c, /* Set the BCLK,WCLK as output */
89 | 2, 0x1e, 0x80 + 28, /* Enable the BCLKN divider with value 28 */
90 | 2, 0x25, 0xee, /* DAC power up */
91 |
92 | 2, 0x12, 0x82, /* Power up the NADC divider with value 2 */
93 | 2, 0x13, 0x87, /* Power up the MADC divider with value 7 */
94 | 2, 0x14, 0x80, /* Program the OSR of ADC to 128 */
95 | 2, 0x3d, 0x01, /* Select ADC PRB_R1 */
96 | 0 // sentinel
97 | };
98 |
99 | static const uint8_t conf_data_clk_96kHz[] = {
100 | 2, 0x0b, 0x82, /* Power up the NDAC divider with value 2 */
101 | 2, 0x0c, 0x87, /* Power up the MDAC divider with value 7 */
102 | 2, 0x0d, 0x00, /* Program the OSR of DAC to 64 */
103 | 2, 0x0e, 0x40,
104 | 2, 0x3c, 0x08, /* Set the DAC Mode to PRB_P8 */
105 | 2, 0x1b, 0x0c, /* Set the BCLK,WCLK as output */
106 | 2, 0x1e, 0x80 + 14, /* Enable the BCLKN divider with value 14 */
107 | 2, 0x25, 0xee, /* DAC power up */
108 |
109 | 2, 0x12, 0x82, /* Power up the NADC divider with value 7 */
110 | 2, 0x13, 0x87, /* Power up the MADC divider with value 2 */
111 | 2, 0x14, 0x40, /* Program the OSR of ADC to 64 */
112 | 2, 0x3d, 0x01, /* Select ADC PRB_R1 */
113 | 0 // sentinel
114 | };
115 |
116 | static const uint8_t conf_data_clk_192kHz[] = {
117 | 2, 0x0b, 0x82, /* Power up the NDAC divider with value 2 */
118 | 2, 0x0c, 0x87, /* Power up the MDAC divider with value 7 */
119 | 2, 0x0d, 0x00, /* Program the OSR of DAC to 32 */
120 | 2, 0x0e, 0x20,
121 | 2, 0x3c, 17, //0x08, /* Set the DAC Mode to PRB_P17 (reduce resource) */
122 | //2, 0x3c, 25, /* Set the DAC Mode to PRB_P25 */
123 | 2, 0x1b, 0x0c, /* Set the BCLK,WCLK as output */
124 | 2, 0x1e, 0x80 + 7, /* Enable the BCLKN divider with value 7 */
125 | 2, 0x25, 0xee, /* DAC power up */
126 |
127 | 2, 0x12, 0x81, /* Power up the NADC divider with value 1 */
128 | 2, 0x13, 0x87, /* Power up the MADC divider with value 7 */
129 | 2, 0x14, 0x40, /* Program the OSR of ADC to 64 */
130 | 2, 0x3d, 0x01, /* Select ADC PRB_R1 */
131 | 0 // sentinel
132 | };
133 |
134 | static const uint8_t conf_data_routing[] = {
135 | 2, 0x00, 0x01, /* Select Page 1 */
136 | 2, 0x01, 0x08, /* Disable Internal Crude AVdd in presence of external AVdd supply or before powering up internal AVdd LDO*/
137 | 2, 0x02, 0x01, /* Enable Master Analog Power Control */
138 | 2, 0x7b, 0x01, /* Set the REF charging time to 40ms */
139 | 2, 0x14, 0x25, /* HP soft stepping settings for optimal pop performance at power up Rpop used is 6k with N = 6 and soft step = 20usec. This should work with 47uF coupling capacitor. Can try N=5,6 or 7 time constants as well. Trade-off delay vs “pop” sound. */
140 | 2, 0x0a, 0x33, /* Set the Input Common Mode to 0.9V and Output Common Mode for Headphone to 1.65V */
141 | 2, 0x0c, 0x08, /* Route Left DAC to HPL */
142 | 2, 0x0d, 0x08, /* Route Right DAC to HPR */
143 | 2, 0x03, 0x00, /* Set the DAC PTM mode to PTM_P3/4 */
144 | 2, 0x04, 0x00,
145 | 2, 0x10, 0x0a, /* Set the HPL gain to 0dB */
146 | 2, 0x11, 0x0a, /* Set the HPR gain to 0dB */
147 | 2, 0x09, 0x30, /* Power up HPL and HPR drivers */
148 |
149 | 2, 0x3d, 0x00, /* Select ADC PTM_R4 */
150 | 2, 0x47, 0x32, /* Set MicPGA startup delay to 3.1ms */
151 | 2, 0x7b, 0x01, /* Set the REF charging time to 40ms */
152 | 2, 0x34, 0x10, /* Route IN2L to LEFT_P with 10K */
153 | 2, 0x36, 0x10, /* Route IN2R to LEFT_N with 10K */
154 | 2, 0x37, 0x04, /* Route IN3R to RIGHT_P with 10K */
155 | 2, 0x39, 0x04, /* Route IN3L to RIGHT_N with 10K */
156 | 2, 0x3b, 72, /* Unmute Left MICPGA, Gain selection of 32dB to make channel gain 0dB */
157 | 2, 0x3c, 72, /* Unmute Right MICPGA, Gain selection of 32dB to make channel gain 0dB */
158 | 2, 0x33, 0x60, /* Enable MIC bias, 2.5V */
159 | 2, 0x00, 0x08, /* Select Page 8 */
160 | 2, 0x01, 0x04, /* Enable Adaptive Filter mode */
161 | 0 // sentinel
162 | };
163 |
164 | const uint8_t conf_data_unmute[] = {
165 | 2, 0x00, 0x00, /* Select Page 0 */
166 | 2, 0x3f, 0xd6, /* Power up the Left and Right DAC Channels with route the Left Audio digital data to Left Channel DAC and Right Audio digital data to Right Channel DAC */
167 | 2, 0x40, 0x00, /* Unmute the DAC digital volume control */
168 | 2, 0x51, 0xc0, /* Power up Left and Right ADC Channels */
169 | 2, 0x52, 0x00, /* Unmute Left and Right ADC Digital Volume Control */
170 | 2, 0x43, 0x93, /* Enable Headphone detection, Debounce 256ms, Button Debounce 32ms */
171 | 0 // sentinel
172 | };
173 |
174 | static const uint8_t conf_data_divoff[] = {
175 | 2, 0x51, 0x00, /* Power down Left and Right ADC Channels */
176 | 2, 0x0b, 0x00, /* Power down NDAC divider */
177 | 2, 0x0c, 0x00, /* Power down MDAC divider */
178 | 2, 0x12, 0x00, /* Power down NADC divider */
179 | 2, 0x13, 0x00, /* Power down MADC divider */
180 | 0 // sentinel
181 | };
182 |
183 | void tlv320aic3204_init(void)
184 | {
185 | tlv320aic3204_config(conf_data_pll);
186 | tlv320aic3204_config(conf_data_clk);
187 | tlv320aic3204_config(conf_data_routing);
188 | wait_ms(40);
189 | tlv320aic3204_config(conf_data_unmute);
190 | }
191 |
192 | void tlv320aic3204_stop(void)
193 | {
194 | tlv320aic3204_config(conf_data_divoff);
195 | }
196 |
197 | void tlv320aic3204_set_fs(int fs)
198 | {
199 | if (fs != 48 && fs != 96 && fs != 192)
200 | return;
201 |
202 | if (fs == 48)
203 | tlv320aic3204_config(conf_data_clk);
204 | else if (fs == 96)
205 | tlv320aic3204_config(conf_data_clk_96kHz);
206 | else if (fs == 192)
207 | tlv320aic3204_config(conf_data_clk_192kHz);
208 |
209 | wait_ms(10);
210 | tlv320aic3204_config(conf_data_unmute);
211 | }
212 |
213 | void tlv320aic3204_set_impedance(int imp)
214 | {
215 | imp &= 3; /* 1, 2, 3 */
216 | tlv320aic3204_write(0x00, 0x01); /* Select Page 1 */
217 | tlv320aic3204_write(0x34, (imp << 4)); /* Route IN2L to LEFT_P */
218 | tlv320aic3204_write(0x36, (imp << 4)); /* Route IN2R to LEFT_N */
219 | tlv320aic3204_write(0x37, (imp << 2)); /* Route IN3R to RIGHT_P */
220 | tlv320aic3204_write(0x39, (imp << 2)); /* Route IN3L to RIGHT_N */
221 | tlv320aic3204_write(0x00, 0x00); /* Select Page 0 */
222 | }
223 |
224 |
225 | void tlv320aic3204_set_gain(int g1, int g2)
226 | {
227 | if (g1 < 0) g1 = 0;
228 | if (g2 < 0) g2 = 0;
229 | if (g1 > 95) g1 = 95;
230 | if (g2 > 95) g2 = 95;
231 |
232 | tlv320aic3204_write(0x00, 0x01); /* Select Page 1 */
233 | tlv320aic3204_write(0x3b, g1); /* Unmute Left MICPGA, set gain */
234 | tlv320aic3204_write(0x3c, g2); /* Unmute Right MICPGA, set gain */
235 | tlv320aic3204_write(0x00, 0x00); /* Select Page 0 */
236 | }
237 |
238 | void tlv320aic3204_set_digital_gain(int g1, int g2)
239 | {
240 | if (g1 < -24) g1 = -24;
241 | if (g1 > 40) g1 = 40;
242 | if (g2 < -24) g2 = -24;
243 | if (g2 > 40) g2 = 40;
244 |
245 | tlv320aic3204_write(0x00, 0x00); /* Select Page 0 */
246 | tlv320aic3204_write(0x53, g1 & 0x7f); /* Left ADC Channel Volume */
247 | tlv320aic3204_write(0x54, g2 & 0x7f); /* Right ADC Channel Volume */
248 | }
249 |
250 | void tlv320aic3204_set_volume(int gain)
251 | {
252 | if (gain > 29)
253 | gain = 29;
254 | else if (gain < -6)
255 | gain = 0x40;
256 | else
257 | gain &= 0x3f;
258 |
259 | tlv320aic3204_write(0x00, 0x01); /* Select Page 1 */
260 | tlv320aic3204_write(0x10, gain); /* Unmute Left MICPGA, set gain */
261 | tlv320aic3204_write(0x11, gain); /* Unmute Right MICPGA, set gain */
262 | tlv320aic3204_write(0x00, 0x00); /* Select Page 0 */
263 | }
264 |
265 | void tlv320aic3204_agc_config(tlv320aic3204_agc_config_t *conf)
266 | {
267 | int ctrl = 0;
268 | if (conf == NULL) {
269 | ctrl = 0;
270 | } else {
271 | ctrl = 0x80
272 | | ((conf->target_level & 0x7) << 4)
273 | | (conf->gain_hysteresis & 0x3);
274 | }
275 | tlv320aic3204_write(0x00, 0x00); /* Select Page 0 */
276 | tlv320aic3204_write(0x56, ctrl); /* Left AGC Control Register */
277 | tlv320aic3204_write(0x5e, ctrl); /* Right AGC Control Register */
278 | if (ctrl == 0)
279 | return;
280 |
281 | ctrl = ((conf->attack & 0x1f) << 3) | (conf->attack_scale & 0x7);
282 | tlv320aic3204_write(0x59, ctrl); /* Left AGC Attack Time */
283 | tlv320aic3204_write(0x61, ctrl); /* Right AGC Attack Time */
284 |
285 | ctrl = ((conf->decay & 0x1f) << 3) | (conf->decay_scale & 0x7);
286 | tlv320aic3204_write(0x5a, ctrl); /* Left AGC Decay Time */
287 | tlv320aic3204_write(0x62, ctrl); /* Right AGC Decay Time */
288 |
289 | ctrl = conf->maximum_gain;
290 | tlv320aic3204_write(0x58, ctrl); /* Left AGC Maximum Gain */
291 | tlv320aic3204_write(0x60, ctrl); /* Right AGC Maximum Gain */
292 | }
293 |
294 | // implement HPF of first order IIR
295 | const uint8_t adc_iir_filter_dcreject[] = {
296 | /* len, page, reg, data.... */
297 | /* left channel C4 - C6 */
298 | 12, 8, 24,
299 | /* Pg8 Reg24-35 */
300 | 0x7f, 0xfa, 0xda, 0x00,
301 | 0x80, 0x05, 0x26, 0x00,
302 | 0x7f, 0xf5, 0xb5, 0x00,
303 |
304 | /* right channel C36 - C38 */
305 | 12, 9, 32,
306 | /* Pg9 Reg 32-43 */
307 | 0x7f, 0xfa, 0xda, 0x00,
308 | 0x80, 0x05, 0x26, 0x00,
309 | 0x7f, 0xf5, 0xb5, 0x00,
310 | 0 /* sentinel */
311 | };
312 |
313 | // implement HPF of first order IIR
314 | const uint8_t adc_iir_filter_dcreject2[] = {
315 | /* len, page, reg, data.... */
316 | /* left channel C4 - C6 */
317 | 12, 8, 24,
318 | /* Pg8 Reg24-35 */
319 | 0x7f, 0xfa, 0xda, 0x00,
320 | 0x80, 0x05, 0x26, 0x00,
321 | 0x7f, 0xf5, 0xb5, 0x00,
322 |
323 | /* right channel C36 - C38 */
324 | 12, 9, 32,
325 | /* Pg9 Reg 32-43 */
326 | 0x80, 0x06, 0x37, 0x00,
327 | 0x7f, 0xfa, 0xeb, 0x00,
328 | 0x7f, 0xf5, 0xb5, 0x00,
329 | 0 /* sentinel */
330 | };
331 |
332 | const uint8_t adc_iir_filter_default[] = {
333 | /* len, page, reg, data.... */
334 | /* left channel C4 - C6 */
335 | 12, 8, 24,
336 | /* Pg8 Reg24-35 */
337 | 0x7f, 0xff, 0xff, 0x00,
338 | 0x00, 0x00, 0x00, 0x00,
339 | 0x00, 0x00, 0x00, 0x00,
340 |
341 | /* right channel C36 - C38 */
342 | 12, 9, 32,
343 | /* Pg9 Reg 32-43 */
344 | 0x7f, 0xff, 0xff, 0x00,
345 | 0x00, 0x00, 0x00, 0x00,
346 | 0x00, 0x00, 0x00, 0x00,
347 | 0 /* sentinel */
348 | };
349 |
350 | void tlv320aic3204_config_adc_filter(int enable)
351 | {
352 | const uint8_t *p = adc_iir_filter_default;
353 | if (enable)
354 | p = adc_iir_filter_dcreject2;
355 |
356 | while (*p != 0) {
357 | uint8_t len = *p++;
358 | uint8_t page = *p++;
359 | uint8_t reg = *p++;
360 | tlv320aic3204_write(0x00, page);
361 | while (len-- > 0)
362 | tlv320aic3204_write(reg++, *p++);
363 | }
364 | tlv320aic3204_write(0x00, 0x08); /* Select Page 8 */
365 | tlv320aic3204_write(0x01, 0x05); /* ADC Coefficient Buffers will be switched at next frame boundary */
366 | tlv320aic3204_write(0x00, 0x00); /* Back to page 0 */
367 | }
368 |
369 | void tlv320aic3204_config_adc_filter2(double adj)
370 | {
371 | int reg;
372 | int32_t b0 = 0x7ffada00;
373 | int32_t b1 = 0x80052600;
374 | int32_t a1 = 0x7ff5b500;
375 |
376 | tlv320aic3204_write(0x00, 0x08);
377 | reg = 24;
378 | tlv320aic3204_write(reg++, b0 >> 24);
379 | tlv320aic3204_write(reg++, b0 >> 16);
380 | tlv320aic3204_write(reg++, b0 >> 8);
381 | tlv320aic3204_write(reg++, 0);
382 | tlv320aic3204_write(reg++, b1 >> 24);
383 | tlv320aic3204_write(reg++, b1 >> 16);
384 | tlv320aic3204_write(reg++, b1 >> 8);
385 | tlv320aic3204_write(reg++, 0);
386 | tlv320aic3204_write(reg++, a1 >> 24);
387 | tlv320aic3204_write(reg++, a1 >> 16);
388 | tlv320aic3204_write(reg++, a1 >> 8);
389 | tlv320aic3204_write(reg++, 0);
390 |
391 | b0 = (int32_t)(b0 * adj);
392 | b1 = (int32_t)(b1 * adj);
393 | tlv320aic3204_write(0x00, 0x09);
394 | reg = 32;
395 | tlv320aic3204_write(reg++, b0 >> 24);
396 | tlv320aic3204_write(reg++, b0 >> 16);
397 | tlv320aic3204_write(reg++, b0 >> 8);
398 | tlv320aic3204_write(reg++, 0);
399 | tlv320aic3204_write(reg++, b1 >> 24);
400 | tlv320aic3204_write(reg++, b1 >> 16);
401 | tlv320aic3204_write(reg++, b1 >> 8);
402 | tlv320aic3204_write(reg++, 0);
403 | tlv320aic3204_write(reg++, a1 >> 24);
404 | tlv320aic3204_write(reg++, a1 >> 16);
405 | tlv320aic3204_write(reg++, a1 >> 8);
406 | tlv320aic3204_write(reg++, 0);
407 |
408 | tlv320aic3204_write(0x00, 0x08); /* Select Page 8 */
409 | tlv320aic3204_write(0x01, 0x05); /* ADC Coefficient Buffers will be switched at next frame boundary */
410 | tlv320aic3204_write(0x00, 0x00); /* Back to page 0 */
411 | }
412 |
413 | int tlv320aic3204_get_sticky_flag_register(void)
414 | {
415 | return tlv320aic3204_read(0x2a); /* Sticky Flag Register */
416 | }
417 |
418 | int8_t tlv320aic3204_get_left_agc_gain(void)
419 | {
420 | return tlv320aic3204_read(0x5d); /* Left Channel AGC Gain Flag */
421 | }
422 |
423 | int8_t tlv320aic3204_get_right_agc_gain(void)
424 | {
425 | return tlv320aic3204_read(0x65); /* Right Channel AGC Gain Flag */
426 | }
427 |
428 | void tlv320aic3204_set_adc_phase_adjust(int8_t adjust)
429 | {
430 | tlv320aic3204_write(0x55, adjust);
431 | }
432 |
433 | void tlv320aic3204_set_adc_fine_gain_adjust(int8_t g1, int8_t g2)
434 | {
435 | tlv320aic3204_write(0x52, (g1 & 0x7) << 4 | (g2 & 0x7));
436 | }
437 |
438 | void tlv320aic3204_beep(void)
439 | {
440 | /*
441 | tlv320aic3204_write(0x25, 00); // power off dac
442 | wait_ms(10);
443 | tlv320aic3204_write(0x3c, 25); // select PRB_P25 to beep
444 | tlv320aic3204_write(0x25, 0xee); // DAC power on
445 | */
446 |
447 | // set duration
448 | tlv320aic3204_write(0x4a, 0x10);
449 | tlv320aic3204_write(0x4b, 0x00);
450 | // beep
451 | tlv320aic3204_write(0x47, 0x80);
452 |
453 | /*
454 | tlv320aic3204_write(0x3c, 17); // restore to PRB_P17
455 | */
456 | }
457 |
--------------------------------------------------------------------------------
/ui.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com
3 | * All rights reserved.
4 | *
5 | * This is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3, or (at your option)
8 | * any later version.
9 | *
10 | * The software is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with GNU Radio; see the file COPYING. If not, write to
17 | * the Free Software Foundation, Inc., 51 Franklin Street,
18 | * Boston, MA 02110-1301, USA.
19 | */
20 |
21 | #include "ch.h"
22 | #include "hal.h"
23 | #include "nanosdr.h"
24 | #include "si5351.h"
25 | #include
26 | #include
27 |
28 | #define set_volume(gain) tlv320aic3204_set_volume(gain)
29 |
30 | int fetch_encoder_tick(void);
31 |
32 | #define NO_EVENT 0
33 | #define EVT_BUTTON_SINGLE_CLICK 0x01
34 | #define EVT_BUTTON_DOUBLE_CLICK 0x02
35 | #define EVT_BUTTON_DOWN_LONG 0x04
36 | #define EVT_UP 0x10
37 | #define EVT_DOWN 0x20
38 | #define EVT_PUSH_UP 0x30
39 | #define EVT_PUSH_DOWN 0x40
40 |
41 | #define BUTTON_DOWN_LONG_TICKS 16000
42 | #define BUTTON_DOUBLE_TICKS 500
43 | #define BUTTON_DEBOUNCE_TICKS 10
44 | #define BUTTON_NO_ACTION 0
45 |
46 | #define BIT_PUSH 0
47 | #define BIT_ENCODER0 1
48 | #define BIT_ENCODER1 2
49 |
50 | static uint16_t last_button = 0;
51 | static uint16_t button_event_inhibited = 0;
52 | static uint32_t last_button_down_ticks;
53 | //static uint8_t dragged = 0; // encoder changed while button pressed
54 |
55 |
56 | int
57 | read_buttons(void)
58 | {
59 | return (palReadPort(GPIOA) & 0x1) ^ config.button_polarity;
60 | }
61 |
62 | void
63 | inhibit_button_event(void)
64 | {
65 | button_event_inhibited = 1;
66 | }
67 |
68 | int btn_check(void)
69 | {
70 | int cur_button = read_buttons();
71 | int changed = last_button ^ cur_button;
72 | int status = 0;
73 | uint32_t ticks = chVTGetSystemTime();
74 | if (changed & (1<= last_button_down_ticks + BUTTON_DEBOUNCE_TICKS) {
76 | if (!(cur_button & (1<= last_button_down_ticks + BUTTON_DOWN_LONG_TICKS) {
97 | status |= EVT_BUTTON_DOWN_LONG;
98 | button_event_inhibited = 1;
99 | }
100 | }
101 |
102 | last_button = cur_button;
103 |
104 | return status;
105 | }
106 |
107 | #define VOLUME_MAX 29
108 | #define VOLUME_MIN -7
109 | #define RFGAIN_MAX 95
110 |
111 | static void
112 | set_gain(int gain)
113 | {
114 | int dgain = 0;
115 | if (gain > RFGAIN_MAX) {
116 | dgain = gain - RFGAIN_MAX;
117 | gain = RFGAIN_MAX;
118 | }
119 | if (gain < 0) {
120 | dgain = gain;
121 | gain = 0;
122 | }
123 |
124 | tlv320aic3204_set_gain(gain, gain);
125 | tlv320aic3204_set_digital_gain(dgain, dgain);
126 | }
127 |
128 |
129 | void
130 | update_frequency(void)
131 | {
132 | set_tune(uistat.freq);
133 | }
134 |
135 |
136 | int enc_status = 0;
137 | int enc_count = 0;
138 |
139 |
140 | int
141 | fetch_encoder_tick(void)
142 | {
143 | int n = enc_count;
144 | enc_count = 0;
145 | return n;
146 | }
147 |
148 | void ext_callback(EXTDriver *extp, expchannel_t channel)
149 | {
150 | (void)extp;
151 | int cur = palReadPort(GPIOB);
152 | const int trans_tbl[4][4] = {
153 | /*falling A */ /*rising A */ /*falling B */ /*rising B */
154 | { 0, 0, 3, 3 }, { 1, 1, 2, 2 }, { 0, 1, 1, 0 }, { 3, 2, 2, 3 }
155 | };
156 | int s = (channel - 1) * 2; // A: 0, B: 2
157 | if (cur & (1 << channel))
158 | s |= 1; // rising
159 | if (enc_status == 0 && s == 3) // rising B
160 | enc_count--;
161 | if (enc_status == 3 && s == 2) // falling B
162 | enc_count++;
163 | enc_status = trans_tbl[s][enc_status];
164 | #if 0
165 | if (channel == 0) {
166 | enc_count = 0;
167 | }
168 | #endif
169 | }
170 |
171 | static const EXTConfig extconf = {
172 | {
173 | { 0, NULL }, //{ EXT_MODE_GPIOA | EXT_CH_MODE_RISING_EDGE | EXT_CH_MODE_AUTOSTART, ext_callback },
174 | { EXT_MODE_GPIOB | EXT_CH_MODE_BOTH_EDGES | EXT_CH_MODE_AUTOSTART, ext_callback },
175 | { EXT_MODE_GPIOB | EXT_CH_MODE_BOTH_EDGES | EXT_CH_MODE_AUTOSTART, ext_callback },
176 | { 0, NULL },
177 | { 0, NULL },
178 | { 0, NULL },
179 | { 0, NULL },
180 | { 0, NULL },
181 | { 0, NULL },
182 | { 0, NULL },
183 | { 0, NULL },
184 | { 0, NULL },
185 | { 0, NULL },
186 | { 0, NULL },
187 | { 0, NULL },
188 | { 0, NULL },
189 | { 0, NULL },
190 | { 0, NULL },
191 | { 0, NULL },
192 | { 0, NULL },
193 | { 0, NULL },
194 | { 0, NULL },
195 | { 0, NULL },
196 | { 0, NULL },
197 | { 0, NULL },
198 | { 0, NULL },
199 | { 0, NULL },
200 | { 0, NULL },
201 | { 0, NULL },
202 | { 0, NULL },
203 | { 0, NULL },
204 | { 0, NULL }
205 | }
206 | };
207 |
208 | void
209 | recall_channel(unsigned int channel)
210 | {
211 | // apply settings at channel
212 | uistat.freq = config.channels[channel].freq;
213 | //uistat.rfgain = config.channels[channel].rfgain;
214 | uistat.modulation = config.channels[channel].modulation;
215 |
216 | //set_gain(uistat.rfgain);
217 | set_modulation(uistat.modulation);
218 | update_frequency();
219 | }
220 |
221 | void
222 | ui_init(void)
223 | {
224 | #if 1
225 | extStart(&EXTD1, &extconf);
226 | //chCondObjectInit(&condvar_button);
227 | #endif
228 |
229 | set_volume(uistat.volume);
230 | set_gain(uistat.rfgain);
231 | set_agc_mode(uistat.agcmode);
232 | set_modulation(uistat.modulation);
233 | //recall_channel(uistat.channel);
234 | update_frequency();
235 | }
236 |
237 | static int minmax(int x, int min, int max)
238 | {
239 | if (x >= max)
240 | return max - 1;
241 | if (x < min)
242 | return min;
243 | return x;
244 | }
245 |
246 | void
247 | ui_process(void)
248 | {
249 | int status = btn_check();
250 | int tick = fetch_encoder_tick();
251 | int n;
252 | if (status & EVT_BUTTON_SINGLE_CLICK) {
253 | uistat.mode++;
254 | if (uistat.agcmode != 0 && uistat.mode == RFGAIN)
255 | uistat.mode++;
256 | // skip CWTONE, IQBAL on click
257 | if (uistat.mode == AGC_MAXGAIN)
258 | uistat.mode = SPDISP;
259 | uistat.mode %= MODE_MAX;
260 | disp_update();
261 | } else if (status & EVT_BUTTON_DOWN_LONG) {
262 | tlv320aic3204_beep();
263 | save_config_current_channel();
264 | }
265 | if (tick != 0) {
266 | if (read_buttons() != 0) {
267 | // button pressed
268 |
269 | if (uistat.mode == FREQ) {
270 | if (tick < 0) {
271 | if (uistat.digit < 7)
272 | uistat.digit++;
273 | else
274 | uistat.mode--;
275 | }
276 | if (tick > 0) {
277 | if (uistat.digit > 0)
278 | uistat.digit--;
279 | else
280 | uistat.mode++;
281 | }
282 | } else {
283 | if (tick < 0) {
284 | uistat.mode--;
285 |
286 | if (uistat.mode == IQBAL || uistat.mode == RFGAIN)
287 | disp_clear_aux();
288 |
289 | // skip rfgain if agc is enabled
290 | if (uistat.agcmode != 0 && uistat.mode == RFGAIN)
291 | uistat.mode--;
292 | }
293 | if (tick > 0) {
294 | uistat.mode++;
295 |
296 | // skip rfgain if agc is enabled
297 | if (uistat.agcmode != 0 && uistat.mode == RFGAIN)
298 | uistat.mode++;
299 |
300 | if (uistat.mode == AGC_MAXGAIN || uistat.mode == SPDISP)
301 | disp_clear_aux();
302 | }
303 | uistat.mode = uistat.mode % MODE_MAX;
304 | }
305 | disp_update();
306 | inhibit_button_event();
307 | } else {
308 | if (uistat.mode == CHANNEL) {
309 | uistat.channel = minmax(uistat.channel + tick, 0, CHANNEL_MAX);
310 | recall_channel(uistat.channel);
311 | } else if (uistat.mode == VOLUME) {
312 | uistat.volume = minmax(uistat.volume + tick, VOLUME_MIN, VOLUME_MAX+1);
313 | set_volume(uistat.volume);
314 | } else if (uistat.mode == FREQ) {
315 | int32_t step = 1;
316 | for (n = uistat.digit; n > 0; n--)
317 | step *= 10;
318 | int32_t freq = uistat.freq + step * tick;
319 | if (freq > 0)
320 | uistat.freq = freq;
321 | update_frequency();
322 | } else if (uistat.mode == RFGAIN) {
323 | uistat.rfgain = minmax((int)uistat.rfgain + tick, -24, RFGAIN_MAX + 40+1);
324 | set_gain(uistat.rfgain);
325 | } else if (uistat.mode == AGC) {
326 | uistat.agcmode = minmax(uistat.agcmode + tick, 0, AGC_MAX);
327 | set_agc_mode(uistat.agcmode);
328 | } else if (uistat.mode == MOD) {
329 | if (tick > 0 && uistat.modulation < MOD_MAX-1) {
330 | uistat.modulation++;
331 | }
332 | if (tick < 0 && uistat.modulation > 0) {
333 | uistat.modulation--;
334 | }
335 | set_modulation(uistat.modulation);
336 | update_frequency();
337 | } else if (uistat.mode == CWTONE) {
338 | uistat.cw_tone_freq = minmax(uistat.cw_tone_freq + tick, -2000, 2000);
339 | update_cwtone();
340 | } else if (uistat.mode == IQBAL) {
341 | uistat.iqbal = minmax(uistat.iqbal + tick * 10, -4000, 4000);
342 | update_iqbal();
343 | } else if (uistat.mode == AGC_MAXGAIN) {
344 | config.agc.maximum_gain = minmax(config.agc.maximum_gain + tick, 0, 128);
345 | update_agc();
346 | } else if (uistat.mode == SPDISP) {
347 | uistat.spdispmode = minmax(uistat.spdispmode + tick, 0, SPDISP_MODE_MAX);
348 | } else if (uistat.mode == WFDISP) {
349 | uistat.wfdispmode = minmax(uistat.wfdispmode + tick, 0, WFDISP_MODE_MAX);
350 | }
351 | }
352 |
353 | disp_update();
354 | }
355 | }
356 |
357 |
--------------------------------------------------------------------------------
/usbcfg.c:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include "ch.h"
18 | #include "hal.h"
19 |
20 | /* Virtual serial port over USB.*/
21 | SerialUSBDriver SDU1;
22 |
23 | /*
24 | * Endpoints to be used for USBD1.
25 | */
26 | #define USBD1_DATA_REQUEST_EP 1
27 | #define USBD1_DATA_AVAILABLE_EP 1
28 | #define USBD1_INTERRUPT_REQUEST_EP 2
29 |
30 | /*
31 | * USB Device Descriptor.
32 | */
33 | static const uint8_t vcom_device_descriptor_data[18] = {
34 | USB_DESC_DEVICE (0x0110, /* bcdUSB (1.1). */
35 | 0x02, /* bDeviceClass (CDC). */
36 | 0x00, /* bDeviceSubClass. */
37 | 0x00, /* bDeviceProtocol. */
38 | 0x40, /* bMaxPacketSize. */
39 | 0x0483, /* idVendor (ST). */
40 | 0x5740, /* idProduct. */
41 | 0x0200, /* bcdDevice. */
42 | 1, /* iManufacturer. */
43 | 2, /* iProduct. */
44 | 3, /* iSerialNumber. */
45 | 1) /* bNumConfigurations. */
46 | };
47 |
48 | /*
49 | * Device Descriptor wrapper.
50 | */
51 | static const USBDescriptor vcom_device_descriptor = {
52 | sizeof vcom_device_descriptor_data,
53 | vcom_device_descriptor_data
54 | };
55 |
56 | /* Configuration Descriptor tree for a CDC.*/
57 | static const uint8_t vcom_configuration_descriptor_data[67] = {
58 | /* Configuration Descriptor.*/
59 | USB_DESC_CONFIGURATION(67, /* wTotalLength. */
60 | 0x02, /* bNumInterfaces. */
61 | 0x01, /* bConfigurationValue. */
62 | 0, /* iConfiguration. */
63 | 0xC0, /* bmAttributes (self powered). */
64 | 50), /* bMaxPower (100mA). */
65 | /* Interface Descriptor.*/
66 | USB_DESC_INTERFACE (0x00, /* bInterfaceNumber. */
67 | 0x00, /* bAlternateSetting. */
68 | 0x01, /* bNumEndpoints. */
69 | 0x02, /* bInterfaceClass (Communications
70 | Interface Class, CDC section
71 | 4.2). */
72 | 0x02, /* bInterfaceSubClass (Abstract
73 | Control Model, CDC section 4.3). */
74 | 0x01, /* bInterfaceProtocol (AT commands,
75 | CDC section 4.4). */
76 | 0), /* iInterface. */
77 | /* Header Functional Descriptor (CDC section 5.2.3).*/
78 | USB_DESC_BYTE (5), /* bLength. */
79 | USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
80 | USB_DESC_BYTE (0x00), /* bDescriptorSubtype (Header
81 | Functional Descriptor. */
82 | USB_DESC_BCD (0x0110), /* bcdCDC. */
83 | /* Call Management Functional Descriptor. */
84 | USB_DESC_BYTE (5), /* bFunctionLength. */
85 | USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
86 | USB_DESC_BYTE (0x01), /* bDescriptorSubtype (Call Management
87 | Functional Descriptor). */
88 | USB_DESC_BYTE (0x00), /* bmCapabilities (D0+D1). */
89 | USB_DESC_BYTE (0x01), /* bDataInterface. */
90 | /* ACM Functional Descriptor.*/
91 | USB_DESC_BYTE (4), /* bFunctionLength. */
92 | USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
93 | USB_DESC_BYTE (0x02), /* bDescriptorSubtype (Abstract
94 | Control Management Descriptor). */
95 | USB_DESC_BYTE (0x02), /* bmCapabilities. */
96 | /* Union Functional Descriptor.*/
97 | USB_DESC_BYTE (5), /* bFunctionLength. */
98 | USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
99 | USB_DESC_BYTE (0x06), /* bDescriptorSubtype (Union
100 | Functional Descriptor). */
101 | USB_DESC_BYTE (0x00), /* bMasterInterface (Communication
102 | Class Interface). */
103 | USB_DESC_BYTE (0x01), /* bSlaveInterface0 (Data Class
104 | Interface). */
105 | /* Endpoint 2 Descriptor.*/
106 | USB_DESC_ENDPOINT (USBD1_INTERRUPT_REQUEST_EP|0x80,
107 | 0x03, /* bmAttributes (Interrupt). */
108 | 0x0008, /* wMaxPacketSize. */
109 | 0xFF), /* bInterval. */
110 | /* Interface Descriptor.*/
111 | USB_DESC_INTERFACE (0x01, /* bInterfaceNumber. */
112 | 0x00, /* bAlternateSetting. */
113 | 0x02, /* bNumEndpoints. */
114 | 0x0A, /* bInterfaceClass (Data Class
115 | Interface, CDC section 4.5). */
116 | 0x00, /* bInterfaceSubClass (CDC section
117 | 4.6). */
118 | 0x00, /* bInterfaceProtocol (CDC section
119 | 4.7). */
120 | 0x00), /* iInterface. */
121 | /* Endpoint 3 Descriptor.*/
122 | USB_DESC_ENDPOINT (USBD1_DATA_AVAILABLE_EP, /* bEndpointAddress.*/
123 | 0x02, /* bmAttributes (Bulk). */
124 | 0x0040, /* wMaxPacketSize. */
125 | 0x00), /* bInterval. */
126 | /* Endpoint 1 Descriptor.*/
127 | USB_DESC_ENDPOINT (USBD1_DATA_REQUEST_EP|0x80, /* bEndpointAddress.*/
128 | 0x02, /* bmAttributes (Bulk). */
129 | 0x0040, /* wMaxPacketSize. */
130 | 0x00) /* bInterval. */
131 | };
132 |
133 | /*
134 | * Configuration Descriptor wrapper.
135 | */
136 | static const USBDescriptor vcom_configuration_descriptor = {
137 | sizeof vcom_configuration_descriptor_data,
138 | vcom_configuration_descriptor_data
139 | };
140 |
141 | /*
142 | * U.S. English language identifier.
143 | */
144 | static const uint8_t vcom_string0[] = {
145 | USB_DESC_BYTE(4), /* bLength. */
146 | USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
147 | USB_DESC_WORD(0x0409) /* wLANGID (U.S. English). */
148 | };
149 |
150 | /*
151 | * Vendor string.
152 | */
153 | static const uint8_t vcom_string1[] = {
154 | USB_DESC_BYTE(38), /* bLength. */
155 | USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
156 | 'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
157 | 'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
158 | 'c', 0, 's', 0
159 | };
160 |
161 | /*
162 | * Device Description string.
163 | */
164 | static const uint8_t vcom_string2[] = {
165 | USB_DESC_BYTE(56), /* bLength. */
166 | USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
167 | 'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0,
168 | 'R', 0, 'T', 0, ' ', 0, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0,
169 | 'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0,
170 | 'o', 0, 'r', 0, 't', 0
171 | };
172 |
173 | /*
174 | * Serial Number string.
175 | */
176 | static const uint8_t vcom_string3[] = {
177 | USB_DESC_BYTE(8), /* bLength. */
178 | USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
179 | '0' + CH_KERNEL_MAJOR, 0,
180 | '0' + CH_KERNEL_MINOR, 0,
181 | '0' + CH_KERNEL_PATCH, 0
182 | };
183 |
184 | /*
185 | * Strings wrappers array.
186 | */
187 | static const USBDescriptor vcom_strings[] = {
188 | {sizeof vcom_string0, vcom_string0},
189 | {sizeof vcom_string1, vcom_string1},
190 | {sizeof vcom_string2, vcom_string2},
191 | {sizeof vcom_string3, vcom_string3}
192 | };
193 |
194 | /*
195 | * Handles the GET_DESCRIPTOR callback. All required descriptors must be
196 | * handled here.
197 | */
198 | static const USBDescriptor *get_descriptor(USBDriver *usbp,
199 | uint8_t dtype,
200 | uint8_t dindex,
201 | uint16_t lang) {
202 |
203 | (void)usbp;
204 | (void)lang;
205 | switch (dtype) {
206 | case USB_DESCRIPTOR_DEVICE:
207 | return &vcom_device_descriptor;
208 | case USB_DESCRIPTOR_CONFIGURATION:
209 | return &vcom_configuration_descriptor;
210 | case USB_DESCRIPTOR_STRING:
211 | if (dindex < 4)
212 | return &vcom_strings[dindex];
213 | }
214 | return NULL;
215 | }
216 |
217 | /**
218 | * @brief IN EP1 state.
219 | */
220 | static USBInEndpointState ep1instate;
221 |
222 | /**
223 | * @brief OUT EP1 state.
224 | */
225 | static USBOutEndpointState ep1outstate;
226 |
227 | /**
228 | * @brief EP1 initialization structure (both IN and OUT).
229 | */
230 | static const USBEndpointConfig ep1config = {
231 | USB_EP_MODE_TYPE_BULK,
232 | NULL,
233 | sduDataTransmitted,
234 | sduDataReceived,
235 | 0x0040,
236 | 0x0040,
237 | &ep1instate,
238 | &ep1outstate,
239 | 2,
240 | NULL
241 | };
242 |
243 | /**
244 | * @brief IN EP2 state.
245 | */
246 | static USBInEndpointState ep2instate;
247 |
248 | /**
249 | * @brief EP2 initialization structure (IN only).
250 | */
251 | static const USBEndpointConfig ep2config = {
252 | USB_EP_MODE_TYPE_INTR,
253 | NULL,
254 | sduInterruptTransmitted,
255 | NULL,
256 | 0x0010,
257 | 0x0000,
258 | &ep2instate,
259 | NULL,
260 | 1,
261 | NULL
262 | };
263 |
264 | /*
265 | * Handles the USB driver global events.
266 | */
267 | static void usb_event(USBDriver *usbp, usbevent_t event) {
268 | extern SerialUSBDriver SDU1;
269 |
270 | switch (event) {
271 | case USB_EVENT_RESET:
272 | return;
273 | case USB_EVENT_ADDRESS:
274 | return;
275 | case USB_EVENT_CONFIGURED:
276 | chSysLockFromISR();
277 |
278 | /* Enables the endpoints specified into the configuration.
279 | Note, this callback is invoked from an ISR so I-Class functions
280 | must be used.*/
281 | usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config);
282 | usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP, &ep2config);
283 |
284 | /* Resetting the state of the CDC subsystem.*/
285 | sduConfigureHookI(&SDU1);
286 |
287 | chSysUnlockFromISR();
288 | return;
289 | case USB_EVENT_SUSPEND:
290 | chSysLockFromISR();
291 |
292 | /* Disconnection event on suspend.*/
293 | sduDisconnectI(&SDU1);
294 |
295 | chSysUnlockFromISR();
296 | return;
297 | case USB_EVENT_WAKEUP:
298 | return;
299 | case USB_EVENT_STALLED:
300 | return;
301 | }
302 | return;
303 | }
304 |
305 | /*
306 | * Handles the USB driver global events.
307 | */
308 | static void sof_handler(USBDriver *usbp) {
309 |
310 | (void)usbp;
311 |
312 | osalSysLockFromISR();
313 | sduSOFHookI(&SDU1);
314 | osalSysUnlockFromISR();
315 | }
316 |
317 | /*
318 | * USB driver configuration.
319 | */
320 | const USBConfig usbcfg = {
321 | usb_event,
322 | get_descriptor,
323 | sduRequestsHook,
324 | sof_handler
325 | };
326 |
327 | /*
328 | * Serial over USB driver configuration.
329 | */
330 | const SerialUSBConfig serusbcfg = {
331 | &USBD1,
332 | USBD1_DATA_REQUEST_EP,
333 | USBD1_DATA_AVAILABLE_EP,
334 | USBD1_INTERRUPT_REQUEST_EP
335 | };
336 |
--------------------------------------------------------------------------------
/usbcfg.h:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | */
15 |
16 | #ifndef USBCFG_H
17 | #define USBCFG_H
18 |
19 | extern const USBConfig usbcfg;
20 | extern SerialUSBConfig serusbcfg;
21 | extern SerialUSBDriver SDU1;
22 |
23 | #endif /* USBCFG_H */
24 |
25 | /** @} */
26 |
--------------------------------------------------------------------------------