-
-
Notifications
You must be signed in to change notification settings - Fork 66
/
nanovna.h
1430 lines (1264 loc) · 51.7 KB
/
nanovna.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Copyright (c) 2019-2020, Dmitry (DiSlord) [email protected]
* Based on TAKAHASHI Tomohiro (TTRFTECH) [email protected]
* All rights reserved.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* The software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#pragma once
#include "ch.h"
// Define LCD display driver and size
#if defined(NANOVNA_F303)
#define LCD_DRIVER_ST7796S
#define LCD_480x320
#else
// Used auto detect from ILI9341 or ST7789
#define LCD_DRIVER_ILI9341
#define LCD_DRIVER_ST7789
#define LCD_320x240
#endif
// Enable DMA mode for send data to LCD (Need enable HAL_USE_SPI in halconf.h)
#define __USE_DISPLAY_DMA__
// LCD or hardware allow change brightness, add menu item for this
#if defined(NANOVNA_F303)
#define __LCD_BRIGHTNESS__
#else
//#define __LCD_BRIGHTNESS__
#endif
// Use DAC (in H4 used for brightness used DAC, so need enable __LCD_BRIGHTNESS__ for it)
//#define __VNA_ENABLE_DAC__
// Allow enter to DFU from menu or command
#define __DFU_SOFTWARE_MODE__
// Add RTC clock support
#define __USE_RTC__
// Add RTC backup registers support
#define __USE_BACKUP__
// Add SD card support, req enable RTC (additional settings for file system see FatFS lib ffconf.h)
#define __USE_SD_CARD__
// Use unique serial string for USB
#define __USB_UID__
// If enabled serial in halconf.h, possible enable serial console control
#define __USE_SERIAL_CONSOLE__
// Add show y grid line values option
#define __USE_GRID_VALUES__
// Add remote desktop option
#define __REMOTE_DESKTOP__
// Add RLE8 compression capture image format
#define __CAPTURE_RLE8__
// Allow flip display
#define __FLIP_DISPLAY__
// Add shadow on text in plot area (improve readable, but little slowdown render)
#define _USE_SHADOW_TEXT_
// Faster draw line in cell algorithm (better clipping and faster)
// #define __VNA_FAST_LINES__
// Use build in table for sin/cos calculation, allow save a lot of flash space (this table also use for FFT), max sin/cos error = 4e-7
#define __VNA_USE_MATH_TABLES__
// Use custom fast/compact approximation for some math functions in calculations (vna_ ...), use it carefully
#define __USE_VNA_MATH__
// Use cache for window function used by FFT (but need FFT_SIZE*sizeof(float) RAM)
//#define USE_FFT_WINDOW_BUFFER
// Enable data smooth option
#define __USE_SMOOTH__
// Enable optional change digit separator for locales (dot or comma, need for correct work some external software)
#define __DIGIT_SEPARATOR__
// Use table for frequency list (if disabled use real time calc)
//#define __USE_FREQ_TABLE__
// Enable DSP instruction (support only by Cortex M4 and higher)
#ifdef ARM_MATH_CM4
#define __USE_DSP__
#endif
// Add measure module option (allow made some measure calculations on data)
#define __VNA_MEASURE_MODULE__
// Add Z normalization feature
//#define __VNA_Z_RENORMALIZATION__
/*
* Submodules defines
*/
// If SD card enabled
#ifdef __USE_SD_CARD__
// Allow run commands from SD card (config.ini in root)
#define __SD_CARD_LOAD__
// Allow screenshots in TIFF format
#define __SD_CARD_DUMP_TIFF__
// Allow dump firmware to SD card
#define __SD_CARD_DUMP_FIRMWARE__
// Enable SD card file browser, and allow load files from it
#define __SD_FILE_BROWSER__
#endif
// If measure module enabled, add submodules
#ifdef __VNA_MEASURE_MODULE__
// Add LC match function
#define __USE_LC_MATCHING__
// Enable Series measure option
#define __S21_MEASURE__
// Enable S11 cable measure option
#define __S11_CABLE_MEASURE__
// Enable S11 resonance search option
#define __S11_RESONANCE_MEASURE__
#endif
/*
* Hardware depends options for VNA
*/
#if defined(NANOVNA_F303)
// Define ADC sample rate in kilobyte (can be 48k, 96k, 192k, 384k)
//#define AUDIO_ADC_FREQ_K 768
//#define AUDIO_ADC_FREQ_K 384
#define AUDIO_ADC_FREQ_K 192
//#define AUDIO_ADC_FREQ_K 96
//#define AUDIO_ADC_FREQ_K 48
// Define sample count for one step measure
#define AUDIO_SAMPLES_COUNT (48)
//#define AUDIO_SAMPLES_COUNT (96)
//#define AUDIO_SAMPLES_COUNT (192)
// Frequency offset, depend from AUDIO_ADC_FREQ settings (need aligned table)
// Use real time build table (undef for use constant, see comments)
// Constant tables build only for AUDIO_SAMPLES_COUNT = 48
#define USE_VARIABLE_OFFSET
// Maximum sweep point count (limit by flash and RAM size)
#define SWEEP_POINTS_MAX 401
#define AUDIO_ADC_FREQ_K1 384
#else
//#define AUDIO_ADC_FREQ_K 768
//#define AUDIO_ADC_FREQ_K 384
#define AUDIO_ADC_FREQ_K 192
//#define AUDIO_ADC_FREQ_K 96
//#define AUDIO_ADC_FREQ_K 48
// Define sample count for one step measure
#define AUDIO_SAMPLES_COUNT (48)
//#define AUDIO_SAMPLES_COUNT (96)
//#define AUDIO_SAMPLES_COUNT (192)
// Frequency offset, depend from AUDIO_ADC_FREQ settings (need aligned table)
// Use real time build table (undef for use constant, see comments)
// Constant tables build only for AUDIO_SAMPLES_COUNT = 48
#define USE_VARIABLE_OFFSET
// Maximum sweep point count (limit by flash and RAM size)
#define SWEEP_POINTS_MAX 101
#endif
// Minimum sweep point count
#define SWEEP_POINTS_MIN 21
// Dirty hack for H4 ADC speed in version screen (Need for correct work NanoVNA-App)
#ifndef AUDIO_ADC_FREQ_K1
#define AUDIO_ADC_FREQ_K1 AUDIO_ADC_FREQ_K
#endif
/*
* main.c
*/
// Minimum frequency set
#define FREQUENCY_MIN 600
// Maximum frequency set
#define FREQUENCY_MAX 2700000000U
// Frequency threshold (max frequency for si5351, harmonic mode after)
#define FREQUENCY_THRESHOLD 300000100U
// XTAL frequency on si5351
#define XTALFREQ 26000000U
// Define i2c bus speed, add predefined for 400k, 600k, 900k
#define STM32_I2C_SPEED 900
// Define default src impedance for xtal calculations
#define MEASURE_DEFAULT_R 50.0f
// Add IF select menu in expert settings
#ifdef USE_VARIABLE_OFFSET
#define USE_VARIABLE_OFFSET_MENU
#endif
#if AUDIO_ADC_FREQ_K == 768
#define FREQUENCY_OFFSET_STEP 16000
// For 768k ADC (16k step for 48 samples)
#define FREQUENCY_IF_K 8 // only 96 samples and variable table
//#define FREQUENCY_IF_K 12 // only 192 samples and variable table
//#define FREQUENCY_IF_K 16
//#define FREQUENCY_IF_K 32
//#define FREQUENCY_IF_K 48
//#define FREQUENCY_IF_K 64
#elif AUDIO_ADC_FREQ_K == 384
#define FREQUENCY_OFFSET_STEP 4000
// For 384k ADC (8k step for 48 samples)
//#define FREQUENCY_IF_K 8
#define FREQUENCY_IF_K 12 // only 96 samples and variable table
//#define FREQUENCY_IF_K 16
//#define FREQUENCY_IF_K 20 // only 96 samples and variable table
//#define FREQUENCY_IF_K 24
//#define FREQUENCY_IF_K 32
#elif AUDIO_ADC_FREQ_K == 192
#define FREQUENCY_OFFSET_STEP 4000
// For 192k ADC (sin_cos table in dsp.c generated for 8k, 12k, 16k, 20k, 24k if change need create new table )
//#define FREQUENCY_IF_K 8
#define FREQUENCY_IF_K 12
//#define FREQUENCY_IF_K 16
//#define FREQUENCY_IF_K 20
//#define FREQUENCY_IF_K 24
//#define FREQUENCY_IF_K 28
#elif AUDIO_ADC_FREQ_K == 96
#define FREQUENCY_OFFSET_STEP 2000
// For 96k ADC (sin_cos table in dsp.c generated for 6k, 8k, 10k, 12k if change need create new table )
//#define FREQUENCY_IF_K 6
//#define FREQUENCY_IF_K 8
//#define FREQUENCY_IF_K 10
#define FREQUENCY_IF_K 12
#elif AUDIO_ADC_FREQ_K == 48
#define FREQUENCY_OFFSET_STEP 1000
// For 48k ADC (sin_cos table in dsp.c generated for 3k, 4k, 5k, 6k, if change need create new table )
//#define FREQUENCY_IF_K 3
//#define FREQUENCY_IF_K 4
//#define FREQUENCY_IF_K 5
#define FREQUENCY_IF_K 6
//#define FREQUENCY_IF_K 7
#endif
/*
* CPU Hardware depend functions declaration
*/
#include "hardware.h"
#define AUDIO_ADC_FREQ (AUDIO_ADC_FREQ_K*1000)
#define FREQUENCY_OFFSET (FREQUENCY_IF_K*1000)
// Apply calibration after made sweep, (if set 1, then calibration move out from sweep cycle)
#define APPLY_CALIBRATION_AFTER_SWEEP 0
// Speed of light const
#define SPEED_OF_LIGHT 299792458
// pi const
#define VNA_PI 3.14159265358979323846f
#define VNA_TWOPI 6.28318530717958647692f
// Define frequency range (can be unsigned)
typedef uint32_t freq_t;
// Optional sweep point (in UI menu)
#if SWEEP_POINTS_MAX >=401
#define POINTS_SET_COUNT 5
#define POINTS_SET {51, 101, 201, 301, SWEEP_POINTS_MAX}
#define POINTS_COUNT_DEFAULT SWEEP_POINTS_MAX
#elif SWEEP_POINTS_MAX >=301
#define POINTS_SET_COUNT 4
#define POINTS_SET {51, 101, 201, SWEEP_POINTS_MAX}
#define POINTS_COUNT_DEFAULT SWEEP_POINTS_MAX
#elif SWEEP_POINTS_MAX >=201
#define POINTS_SET_COUNT 3
#define POINTS_SET {51, 101, SWEEP_POINTS_MAX}
#define POINTS_COUNT_DEFAULT SWEEP_POINTS_MAX
#elif SWEEP_POINTS_MAX >=101
#define POINTS_SET_COUNT 2
#define POINTS_SET {51, SWEEP_POINTS_MAX}
#define POINTS_COUNT_DEFAULT SWEEP_POINTS_MAX
#endif
extern float measured[2][SWEEP_POINTS_MAX][2];
#define CAL_TYPE_COUNT 5
#define CAL_LOAD 0
#define CAL_OPEN 1
#define CAL_SHORT 2
#define CAL_THRU 3
#define CAL_ISOLN 4
#define CALSTAT_LOAD (1<<0)
#define CALSTAT_OPEN (1<<1)
#define CALSTAT_SHORT (1<<2)
#define CALSTAT_THRU (1<<3)
#define CALSTAT_ISOLN (1<<4)
#define CALSTAT_ES (1<<5)
#define CALSTAT_ER (1<<6)
#define CALSTAT_ET (1<<7)
#define CALSTAT_ED CALSTAT_LOAD
#define CALSTAT_EX CALSTAT_ISOLN
#define CALSTAT_APPLY (1<<8)
#define CALSTAT_INTERPOLATED (1<<9)
#define CALSTAT_ENHANCED_RESPONSE (1<<10)
#define ETERM_ED 0 /* error term directivity */
#define ETERM_ES 1 /* error term source match */
#define ETERM_ER 2 /* error term refrection tracking */
#define ETERM_ET 3 /* error term transmission tracking */
#define ETERM_EX 4 /* error term isolation */
#if SWEEP_POINTS_MAX <= 256
#define FFT_SIZE 256
#elif SWEEP_POINTS_MAX <= 512
#define FFT_SIZE 512
#endif
void cal_collect(uint16_t type);
void cal_done(void);
#define MAX_FREQ_TYPE 5
enum stimulus_type {
ST_START=0, ST_STOP, ST_CENTER, ST_CW, ST_SPAN, ST_STEP, ST_VAR
};
freq_t getFrequency(uint16_t idx);
freq_t getFrequencyStep(void);
void set_marker_index(int m, int idx);
freq_t get_marker_frequency(int marker);
void reset_sweep_frequency(void);
void set_sweep_frequency(uint16_t type, freq_t frequency);
void set_bandwidth(uint16_t bw_count);
uint32_t get_bandwidth_frequency(uint16_t bw_freq);
void set_power(uint8_t value);
void set_smooth_factor(uint8_t factor);
uint8_t get_smooth_factor(void);
int32_t my_atoi(const char *p);
uint32_t my_atoui(const char *p);
float my_atof(const char *p);
bool strcmpi(const char *t1, const char *t2);
int get_str_index(const char *v, const char *list);
int parse_line(char *line, char* args[], int max_cnt);
void swap_bytes(uint16_t *buf, int size);
int packbits(char *source, char *dest, int size);
void _delay_8t(uint32_t cycles);
inline void delayMicroseconds(uint32_t us) {_delay_8t(us*STM32_CORE_CLOCK/8);}
inline void delayMilliseconds(uint32_t ms) {_delay_8t(ms*125*STM32_CORE_CLOCK);}
void pause_sweep(void);
void toggle_sweep(void);
int load_properties(uint32_t id);
#ifdef __USE_BACKUP__
void update_backup_data(void);
#endif
void set_sweep_points(uint16_t points);
bool sd_card_load_config(void);
void VNAShell_executeCMDLine(char *line);
#ifdef __REMOTE_DESKTOP__
// State flags for remote touch state
#define REMOTE_NONE 0
#define REMOTE_PRESS 1
#define REMOTE_RELEASE 2
typedef struct {
char new_str[6];
int16_t x;
int16_t y;
int16_t w;
int16_t h;
} remote_region_t;
void remote_touch_set(uint16_t state, int16_t x, int16_t y);
void send_region(remote_region_t *rd, uint8_t * buf, uint16_t size);
#endif
#define SWEEP_ENABLE 0x01
#define SWEEP_ONCE 0x02
#define SWEEP_BINARY 0x08
#define SWEEP_REMOTE 0x40
#define SWEEP_UI_MODE 0x80
extern uint8_t sweep_mode;
extern const char *info_about[];
/*
* Measure timings for si5351 generator, after ready
*/
// Enable si5351 timing command, used for debug align times
//#define ENABLE_SI5351_TIMINGS
#if defined(NANOVNA_F303)
// Generator ready delays, values in us
#define DELAY_BAND_1_2 US2ST( 100) // Delay for bands 1-2
#define DELAY_BAND_3_4 US2ST( 120) // Delay for bands 3-4
#define DELAY_BANDCHANGE US2ST(2000) // Band changes need set additional delay after reset PLL
#define DELAY_CHANNEL_CHANGE US2ST( 100) // Switch channel delay
#define DELAY_SWEEP_START US2ST(2000) // Delay at sweep start
// Delay after set new PLL values in ms, and send reset
#define DELAY_RESET_PLL_BEFORE 0 // 0 (0 for disabled)
#define DELAY_RESET_PLL_AFTER 4000 // 4000 (0 for disabled)
#else
// Generator ready delays, values in us
#define DELAY_BAND_1_2 US2ST( 100) // 0 Delay for bands 1-2
#define DELAY_BAND_3_4 US2ST( 140) // 1 Delay for bands 3-4
#define DELAY_BANDCHANGE US2ST( 800) // 2 Band changes need set additional delay after reset PLL
#define DELAY_CHANNEL_CHANGE US2ST( 100) // 3 Switch channel delay
#define DELAY_SWEEP_START US2ST( 100) // 4 Delay at sweep start
// Delay after before/after set new PLL values in ms
#define DELAY_RESET_PLL_BEFORE 0 // 5 0 (0 for disabled)
#define DELAY_RESET_PLL_AFTER 4000 // 6 4000 (0 for disabled)
#endif
/*
* dsp.c
*/
// Define aic3204 source clock frequency (on 8MHz used fractional multiplier, and possible little phase error)
#define AUDIO_CLOCK_REF (8000000U)
// Define aic3204 source clock frequency (on 12288000U used integer multiplier)
//#define AUDIO_CLOCK_REF (12288000U)
// Disable AIC PLL clock, use input as CODEC_CLKIN (not stable on some devices, on long work)
//#define AUDIO_CLOCK_REF (98304000U)
// Buffer contain left and right channel samples (need x2)
#define AUDIO_BUFFER_LEN (AUDIO_SAMPLES_COUNT*2)
// Bandwidth depend from AUDIO_SAMPLES_COUNT and audio ADC frequency
// for AUDIO_SAMPLES_COUNT = 48 and ADC = 48kHz one measure give 48000/48=1000Hz
// for AUDIO_SAMPLES_COUNT = 48 and ADC = 96kHz one measure give 96000/48=2000Hz
// for AUDIO_SAMPLES_COUNT = 48 and ADC = 192kHz one measure give 192000/48=4000Hz
// Define additional measure count for menus
#if AUDIO_ADC_FREQ/AUDIO_SAMPLES_COUNT == 16000
#define BANDWIDTH_8000 ( 1 - 1)
#define BANDWIDTH_4000 ( 2 - 1)
#define BANDWIDTH_1000 ( 8 - 1)
#define BANDWIDTH_333 ( 24 - 1)
#define BANDWIDTH_100 ( 80 - 1)
#define BANDWIDTH_30 (256 - 1)
#elif AUDIO_ADC_FREQ/AUDIO_SAMPLES_COUNT == 8000
#define BANDWIDTH_8000 ( 1 - 1)
#define BANDWIDTH_4000 ( 2 - 1)
#define BANDWIDTH_1000 ( 8 - 1)
#define BANDWIDTH_333 ( 24 - 1)
#define BANDWIDTH_100 ( 80 - 1)
#define BANDWIDTH_30 (256 - 1)
#elif AUDIO_ADC_FREQ/AUDIO_SAMPLES_COUNT == 4000
#define BANDWIDTH_4000 ( 1 - 1)
#define BANDWIDTH_2000 ( 2 - 1)
#define BANDWIDTH_1000 ( 4 - 1)
#define BANDWIDTH_333 ( 12 - 1)
#define BANDWIDTH_100 ( 40 - 1)
#define BANDWIDTH_30 (132 - 1)
#elif AUDIO_ADC_FREQ/AUDIO_SAMPLES_COUNT == 2000
#define BANDWIDTH_2000 ( 1 - 1)
#define BANDWIDTH_1000 ( 2 - 1)
#define BANDWIDTH_333 ( 6 - 1)
#define BANDWIDTH_100 ( 20 - 1)
#define BANDWIDTH_30 ( 66 - 1)
#define BANDWIDTH_10 (200 - 1)
#elif AUDIO_ADC_FREQ/AUDIO_SAMPLES_COUNT == 1000
#define BANDWIDTH_1000 ( 1 - 1)
#define BANDWIDTH_333 ( 3 - 1)
#define BANDWIDTH_100 ( 10 - 1)
#define BANDWIDTH_30 ( 33 - 1)
#define BANDWIDTH_10 (100 - 1)
#endif
typedef int16_t audio_sample_t;
void dsp_process(audio_sample_t *src, size_t len);
void reset_dsp_accumerator(void);
void calculate_gamma(float *gamma);
void fetch_amplitude(float *gamma);
void fetch_amplitude_ref(float *gamma);
void generate_DSP_Table(int offset);
/*
* tlv320aic3204.c
*/
void tlv320aic3204_init(void);
void tlv320aic3204_set_gain(uint8_t lgain, uint8_t rgain);
void tlv320aic3204_select(uint8_t channel);
void tlv320aic3204_write_reg(uint8_t page, uint8_t reg, uint8_t data);
/*
* vna_math.c
*/
#include "vna_math.h"
/*
* plot.c
*/
// LCD display size settings
#ifdef LCD_320x240 // 320x240 display plot definitions
#define LCD_WIDTH 320
#define LCD_HEIGHT 240
// Define maximum distance in pixel for pickup marker (can be bigger for big displays)
#define MARKER_PICKUP_DISTANCE 20
// Used marker image settings
#define _USE_MARKER_SET_ 1
// Used font settings
#define _USE_FONT_ 1
#define _USE_SMALL_FONT_ 0
// Plot area size settings
// Offset of plot area (size of additional info at left side)
#define OFFSETX 10
#define OFFSETY 0
// Grid count, must divide
//#define NGRIDY 10
#define NGRIDY 8
// Plot area WIDTH better be n*(POINTS_COUNT-1)
#define WIDTH 300
// Plot area HEIGHT = NGRIDY * GRIDY
#define HEIGHT 232
// GRIDX calculated depends from frequency span
// GRIDY depend from HEIGHT and NGRIDY, must be integer
#define GRIDY (HEIGHT / NGRIDY)
// Need for reference marker draw
#define CELLOFFSETX 5
#define AREA_WIDTH_NORMAL (CELLOFFSETX + WIDTH + 1 + 4)
#define AREA_HEIGHT_NORMAL ( HEIGHT + 1)
// Smith/polar chart
#define P_CENTER_X (CELLOFFSETX + WIDTH/2)
#define P_CENTER_Y (HEIGHT/2)
#define P_RADIUS (HEIGHT/2)
// Other settings (battery/calibration/frequency text position)
// Battery icon position
#define BATTERY_ICON_POSX 1
#define BATTERY_ICON_POSY 1
// Calibration text coordinates
#define CALIBRATION_INFO_POSX 0
#define CALIBRATION_INFO_POSY 100
#define FREQUENCIES_XPOS1 OFFSETX
#define FREQUENCIES_XPOS2 (LCD_WIDTH - 23 * sFONT_WIDTH)
#define FREQUENCIES_XPOS3 (LCD_WIDTH/2 + OFFSETX - 16 * sFONT_WIDTH / 2)
#define FREQUENCIES_YPOS (AREA_HEIGHT_NORMAL)
#endif // end 320x240 display plot definitions
#ifdef LCD_480x320 // 480x320 display definitions
#define LCD_WIDTH 480
#define LCD_HEIGHT 320
// Define maximum distance in pixel for pickup marker (can be bigger for big displays)
#define MARKER_PICKUP_DISTANCE 30
// Used marker image settings
#define _USE_MARKER_SET_ 2
// Used font settings
#define _USE_FONT_ 2
#define _USE_SMALL_FONT_ 2
// Plot area size settings
// Offset of plot area (size of additional info at left side)
#define OFFSETX 15
#define OFFSETY 0
// Grid count, must divide
//#define NGRIDY 10
#define NGRIDY 8
// Plot area WIDTH better be n*(POINTS_COUNT-1)
#define WIDTH 455
// Plot area HEIGHT = NGRIDY * GRIDY
#define HEIGHT 304
// GRIDX calculated depends from frequency span
// GRIDY depend from HEIGHT and NGRIDY, must be integer
#define GRIDY (HEIGHT / NGRIDY)
// Need for reference marker draw
#define CELLOFFSETX 5
#define AREA_WIDTH_NORMAL (CELLOFFSETX + WIDTH + 1 + 4)
#define AREA_HEIGHT_NORMAL ( HEIGHT + 1)
// Smith/polar chart
#define P_CENTER_X (CELLOFFSETX + WIDTH/2)
#define P_CENTER_Y (HEIGHT/2)
#define P_RADIUS (HEIGHT/2)
// Other settings (battery/calibration/frequency text position)
// Battery icon position
#define BATTERY_ICON_POSX 3
#define BATTERY_ICON_POSY 2
// Calibration text coordinates
#define CALIBRATION_INFO_POSX 0
#define CALIBRATION_INFO_POSY 100
#define FREQUENCIES_XPOS1 OFFSETX
#define FREQUENCIES_XPOS2 (LCD_WIDTH - 22 * sFONT_WIDTH)
#define FREQUENCIES_XPOS3 (LCD_WIDTH/2 + OFFSETX - 14 * sFONT_WIDTH / 2)
#define FREQUENCIES_YPOS (AREA_HEIGHT_NORMAL + 2)
#endif // end 480x320 display plot definitions
// UI size defines
// Text offset in menu
#define MENU_TEXT_OFFSET 6
#define MENU_ICON_OFFSET 4
// Scale / ref quick touch position
#define UI_SCALE_REF_X0 (OFFSETX - 5)
#define UI_SCALE_REF_X1 (OFFSETX + CELLOFFSETX + 10)
// Leveler Marker mode select
#define UI_MARKER_Y0 30
// Maximum menu buttons count
#define MENU_BUTTON_MAX 16
#define MENU_BUTTON_MIN 8
// Menu buttons y offset
#define MENU_BUTTON_Y_OFFSET 1
// Menu buttons size = 21 for icon and 10 chars
#define MENU_BUTTON_WIDTH (7 + 12 * FONT_WIDTH)
#define MENU_BUTTON_HEIGHT(n) (AREA_HEIGHT_NORMAL/(n))
#define MENU_BUTTON_BORDER 1
#define KEYBOARD_BUTTON_BORDER 1
#define BROWSER_BUTTON_BORDER 1
// Browser window settings
#define FILES_COLUMNS (LCD_WIDTH/160) // columns in browser
#define FILES_ROWS 10 // rows in browser
#define FILES_PER_PAGE (FILES_COLUMNS*FILES_ROWS) // FILES_ROWS * FILES_COLUMNS
#define FILE_BOTTOM_HEIGHT 20 // Height of bottom buttons (< > X)
#define FILE_BUTTON_HEIGHT ((LCD_HEIGHT - FILE_BOTTOM_HEIGHT)/FILES_ROWS) // Height of file buttons
// Define message box width
#define MESSAGE_BOX_WIDTH 180
// Height of numerical input field (at bottom)
#define NUM_INPUT_HEIGHT 32
// On screen keyboard button size
#if 1 // Full screen keyboard
#define KP_WIDTH (LCD_WIDTH / 4) // numeric keypad button width
#define KP_HEIGHT ((LCD_HEIGHT - NUM_INPUT_HEIGHT) / 4) // numeric keypad button height
#define KP_X_OFFSET 0 // numeric keypad X offset
#define KP_Y_OFFSET 0 // numeric keypad Y offset
#define KPF_WIDTH (LCD_WIDTH / 10) // text keypad button width
#define KPF_HEIGHT KPF_WIDTH // text keypad button height
#define KPF_X_OFFSET 0 // text keypad X offset
#define KPF_Y_OFFSET (LCD_HEIGHT - NUM_INPUT_HEIGHT - 4 * KPF_HEIGHT) // text keypad Y offset
#else // 64 pixel size keyboard
#define KP_WIDTH 64 // numeric keypad button width
#define KP_HEIGHT 64 // numeric keypad button height
#define KP_X_OFFSET (LCD_WIDTH-MENU_BUTTON_WIDTH-16-KP_WIDTH*4) // numeric keypad X offset
#define KP_Y_OFFSET 20 // numeric keypad Y offset
#define KPF_WIDTH (LCD_WIDTH / 10) // text keypad button width
#define KPF_HEIGHT KPF_WIDTH // text keypad button height
#define KPF_X_OFFSET 0 // text keypad X offset
#define KPF_Y_OFFSET (LCD_HEIGHT - NUM_INPUT_HEIGHT - 4 * KPF_HEIGHT) // text keypad Y offset
#endif
/*
* Font size defines
*/
#define FONT_SMALL 0
#define FONT_NORMAL 1
#if _USE_FONT_ == 0
extern const uint8_t x5x7_bits[];
#define FONT_START_CHAR 0x16
#define FONT_WIDTH 5
#define FONT_GET_HEIGHT 7
#define FONT_STR_HEIGHT 8
#define FONT_GET_DATA(ch) ( &x5x7_bits[(ch-FONT_START_CHAR)*FONT_GET_HEIGHT])
#define FONT_GET_WIDTH(ch) (8-(x5x7_bits[(ch-FONT_START_CHAR)*FONT_GET_HEIGHT]&0x7))
#elif _USE_FONT_ == 1
extern const uint8_t x6x10_bits[];
#define FONT_START_CHAR 0x16
#define FONT_WIDTH 6
#define FONT_GET_HEIGHT 10
#define FONT_STR_HEIGHT 11
#define FONT_GET_DATA(ch) ( &x6x10_bits[(ch-FONT_START_CHAR)*FONT_GET_HEIGHT])
#define FONT_GET_WIDTH(ch) (8-(x6x10_bits[(ch-FONT_START_CHAR)*FONT_GET_HEIGHT]&0x7))
#elif _USE_FONT_ == 2
extern const uint8_t x7x11b_bits[];
#define FONT_START_CHAR 0x16
#define FONT_WIDTH 7
#define FONT_GET_HEIGHT 11
#define FONT_STR_HEIGHT 11
#define FONT_GET_DATA(ch) ( &x7x11b_bits[(ch-FONT_START_CHAR)*FONT_GET_HEIGHT])
#define FONT_GET_WIDTH(ch) (8-(x7x11b_bits[(ch-FONT_START_CHAR)*FONT_GET_HEIGHT]&7))
#elif _USE_FONT_ == 3
extern const uint8_t x11x14_bits[];
#define FONT_START_CHAR 0x16
#define FONT_WIDTH 11
#define FONT_GET_HEIGHT 14
#define FONT_STR_HEIGHT 16
#define FONT_GET_DATA(ch) ( &x11x14_bits[(ch-FONT_START_CHAR)*2*FONT_GET_HEIGHT ])
#define FONT_GET_WIDTH(ch) (14-(x11x14_bits[(ch-FONT_START_CHAR)*2*FONT_GET_HEIGHT+1]&0x7))
#endif
#if _USE_SMALL_FONT_ == 0
extern const uint8_t x5x7_bits[];
#define sFONT_START_CHAR 0x16
#define sFONT_WIDTH 5
#define sFONT_GET_HEIGHT 7
#define sFONT_STR_HEIGHT 8
#define sFONT_GET_DATA(ch) ( &x5x7_bits[(ch-sFONT_START_CHAR)*sFONT_GET_HEIGHT])
#define sFONT_GET_WIDTH(ch) (8-(x5x7_bits[(ch-sFONT_START_CHAR)*sFONT_GET_HEIGHT]&0x7))
#elif _USE_SMALL_FONT_ == 1
extern const uint8_t x6x10_bits[];
#define sFONT_START_CHAR 0x16
#define sFONT_WIDTH 6
#define sFONT_GET_HEIGHT 10
#define sFONT_STR_HEIGHT 11
#define sFONT_GET_DATA(ch) ( &x6x10_bits[(ch-sFONT_START_CHAR)*sFONT_GET_HEIGHT])
#define sFONT_GET_WIDTH(ch) (8-(x6x10_bits[(ch-sFONT_START_CHAR)*sFONT_GET_HEIGHT]&0x7))
#elif _USE_SMALL_FONT_ == 2
extern const uint8_t x7x11b_bits[];
#define sFONT_START_CHAR 0x16
#define sFONT_WIDTH 7
#define sFONT_GET_HEIGHT 11
#define sFONT_STR_HEIGHT 11
#define sFONT_GET_DATA(ch) ( &x7x11b_bits[(ch-sFONT_START_CHAR)*sFONT_GET_HEIGHT])
#define sFONT_GET_WIDTH(ch) (8-(x7x11b_bits[(ch-sFONT_START_CHAR)*sFONT_GET_HEIGHT]&7))
#elif _USE_SMALL_FONT_ == 3
extern const uint8_t x11x14_bits[];
#define sFONT_START_CHAR 0x16
#define sFONT_WIDTH 11
#define sFONT_GET_HEIGHT 14
#define sFONT_STR_HEIGHT 16
#define sFONT_GET_DATA(ch) ( &x11x14_bits[(ch-sFONT_START_CHAR)*2*sFONT_GET_HEIGHT ])
#define sFONT_GET_WIDTH(ch) (14-(x11x14_bits[(ch-sFONT_START_CHAR)*2*sFONT_GET_HEIGHT+1]&0x7))
#endif
#if _USE_FONT_ != _USE_SMALL_FONT_
void lcd_set_font(int type);
#else
#define lcd_set_font(type) {}
#endif
extern const uint8_t numfont16x22[];
#define NUM_FONT_GET_WIDTH 16
#define NUM_FONT_GET_HEIGHT 22
#define NUM_FONT_GET_DATA(ch) (&numfont16x22[ch*2*NUM_FONT_GET_HEIGHT])
// Glyph names from numfont16x22.c
enum {
KP_0 = 0, KP_1, KP_2, KP_3, KP_4, KP_5, KP_6, KP_7, KP_8, KP_9,
KP_PERIOD,
KP_MINUS,
KP_BS,
KP_k, KP_M, KP_G,
KP_m, KP_u, KP_n, KP_p,
KP_X1, KP_ENTER, KP_PERCENT, // Enter values
#if 0
KP_INF,
KP_DB,
KP_PLUSMINUS,
KP_KEYPAD,
KP_SPACE,
KP_PLUS,
#endif
// Special uint8_t buttons
KP_EMPTY = 255 // Empty button
};
/*
* LC match text output settings
*/
#ifdef __VNA_MEASURE_MODULE__
// X and Y offset to L/C match text
#define STR_MEASURE_X (OFFSETX + 0)
// Better be aligned by cell (cell height = 32)
#define STR_MEASURE_Y (OFFSETY + 80)
// 1/3 Width of text (use 3 column for data)
#define STR_MEASURE_WIDTH (FONT_WIDTH * 10)
// String Height (need 2 + 0..4 string)
#define STR_MEASURE_HEIGHT (FONT_STR_HEIGHT + 1)
#endif
#ifdef __USE_GRID_VALUES__
#define GRID_X_TEXT (WIDTH - 5 * sFONT_WIDTH)
#endif
// Render control chars
#define R_BGCOLOR "\001" // hex 0x01 set background color
#define R_FGCOLOR "\002" // hex 0x02 set foreground color
#define R_TEXT_COLOR "\002\001" // set 1 color index as foreground
#define R_LINK_COLOR "\002\031" // set 25 color index as foreground
// Additional chars in fonts
#define S_ENTER "\026" // hex 0x16
#define S_DELTA "\027" // hex 0x17
#define S_SARROW "\030" // hex 0x18
#define S_INFINITY "\031" // hex 0x19
#define S_LARROW "\032" // hex 0x1A
#define S_RARROW "\033" // hex 0x1B
#define S_PI "\034" // hex 0x1C
#define S_MICRO '\035' // hex 0x1D
#define S_OHM "\036" // hex 0x1E
#define S_DEGREE "\037" // hex 0x1F
#define S_SIEMENS "S" //
#define S_dB "dB" //
#define S_Hz "Hz" //
#define S_FARAD "F" //
#define S_HENRY "H" //
#define S_SECOND "s" //
#define S_METRE "m" //
#define S_VOLT "V" //
#define S_AMPER "A" //
#define S_PPM "ppm" //
// Max palette indexes in config
#define MAX_PALETTE 32
// trace
#define MAX_TRACE_TYPE 30
enum trace_type {
TRC_LOGMAG=0, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG,
TRC_R, TRC_X, TRC_Z, TRC_ZPHASE,
TRC_G, TRC_B, TRC_Y, TRC_Rp, TRC_Xp,
TRC_sC, TRC_sL,
TRC_pC, TRC_pL,
TRC_Q,
TRC_Rser, TRC_Xser, TRC_Zser,
TRC_Rsh, TRC_Xsh, TRC_Zsh,
TRC_Qs21
};
// Mask for define rectangular plot
#define RECTANGULAR_GRID_MASK ((1<<TRC_LOGMAG)|(1<<TRC_PHASE)|(1<<TRC_DELAY)|(1<<TRC_LINEAR)|(1<<TRC_SWR)|(1<<TRC_REAL)|(1<<TRC_IMAG)\
|(1<<TRC_R)|(1<<TRC_X)|(1<<TRC_Z)|(1<<TRC_ZPHASE)\
|(1<<TRC_G)|(1<<TRC_B)|(1<<TRC_Y)|(1<<TRC_Rp)|(1<<TRC_Xp)\
|(1<<TRC_sC)|(1<<TRC_sL)\
|(1<<TRC_pC)|(1<<TRC_pL)\
|(1<<TRC_Q)\
|(1<<TRC_Rser)|(1<<TRC_Xser)|(1<<TRC_Zser)\
|(1<<TRC_Rsh)|(1<<TRC_Xsh)|(1<<TRC_Zsh)\
|(1<<TRC_Qs21))
// complex graph type (polar / smith / admit)
#define ROUND_GRID_MASK ((1<<TRC_POLAR)|(1<<TRC_SMITH))
// Scale / Amplitude input in nano/pico values graph type
#define NANO_TYPE_MASK ((1<<TRC_DELAY)|(1<<TRC_sC)|(1<<TRC_sL)|(1<<TRC_pC)|(1<<TRC_pL))
// Trace info description structure
typedef float (*get_value_cb_t)(int idx, const float *v); // get value callback
typedef struct trace_info {
const char *name; // Trace name
const char *format; // trace value printf format for marker output
const char *dformat; // delta value printf format
const char *symbol; // value symbol
float refpos; // default refpos
float scale_unit; // default scale
get_value_cb_t get_value_cb; // get value callback (can be NULL, in this case need add custom calculations)
} trace_info_t;
// Trace render options in plot.c
extern const trace_info_t trace_info_list[MAX_TRACE_TYPE];
// marker smith value format
enum {MS_LIN, MS_LOG, MS_REIM, MS_RX, MS_RLC, MS_GB, MS_GLC, MS_RpXp, MS_RpLC, MS_SHUNT_RX, MS_SHUNT_RLC, MS_SERIES_RX, MS_SERIES_RLC, MS_END};
#define ADMIT_MARKER_VALUE(v) ((1<<(v))&((1<<MS_GB)|(1<<MS_GLC)|(1<<MS_RpXp)|(1<<MS_RpLC)))
#define LC_MARKER_VALUE(v) ((1<<(v))&((1<<MS_RLC)|(1<<MS_GLC)|(1<<MS_RpLC)|(1<<MS_SHUNT_RLC)|(1<<MS_SERIES_RLC)))
#define S11_SMITH_VALUE(v) ((1<<(v))&((1<<MS_LIN)|(1<<MS_LOG)|(1<<MS_REIM)|(1<<MS_RX)|(1<<MS_RLC)|(1<<MS_GB)|(1<<MS_GLC)|(1<<MS_RpXp)|(1<<MS_RpLC)))
#define S21_SMITH_VALUE(v) ((1<<(v))&((1<<MS_LIN)|(1<<MS_LOG)|(1<<MS_REIM)|(1<<MS_SHUNT_RX)|(1<<MS_SHUNT_RLC)|(1<<MS_SERIES_RX)|(1<<MS_SERIES_RLC)))
typedef struct {
const char *name; // Trace name
const char *format; // trace value printf format for marker output
get_value_cb_t get_re_cb; // get real value callback
get_value_cb_t get_im_cb; // get imag value callback (can be NULL, in this case need add custom calculations)
} marker_info_t;
extern const marker_info_t marker_info_list[MS_END];
// lever_mode
enum {LM_MARKER, LM_SEARCH, LM_FREQ_0, LM_FREQ_1, LM_EDELAY};
#define MARKER_INVALID -1
#define TRACE_INVALID -1
// properties flags
#define DOMAIN_MODE (1<<0)
#define DOMAIN_FREQ (0<<0)
#define DOMAIN_TIME (1<<0)
// Time domain function
#define TD_FUNC (0b11<<1)
#define TD_FUNC_BANDPASS (0b00<<1)
#define TD_FUNC_LOWPASS_IMPULSE (0b01<<1)
#define TD_FUNC_LOWPASS_STEP (0b10<<1)
// Time domain window
#define TD_WINDOW (0b11<<3)
#define TD_WINDOW_NORMAL (0b00<<3)
#define TD_WINDOW_MINIMUM (0b01<<3)
#define TD_WINDOW_MAXIMUM (0b10<<3)
// Sweep mode
#define TD_START_STOP (0<<0)
#define TD_CENTER_SPAN (1<<6)
// Marker track
#define TD_MARKER_TRACK (1<<7)
// Marker delta
#define TD_MARKER_DELTA (1<<8)
// Marker delta
//#define TD_MARKER_LOCK (1<<9) // reserved
//
// config.vna_mode flags (16 bit field)
//
enum {
VNA_MODE_AUTO_NAME = 0,// Auto name for files
#ifdef __USE_SMOOTH__
VNA_MODE_SMOOTH, // Smooth function (0: Geom, 1: Arith)
#endif
#ifdef __USE_SERIAL_CONSOLE__
VNA_MODE_CONNECTION, // Connection flag (0: USB, 1: SERIAL)
#endif
VNA_MODE_SEARCH, // Marker search mode (0: max, 1: min)
VNA_MODE_SHOW_GRID, // Show grid values
VNA_MODE_DOT_GRID, // Dotted grid lines
#ifdef __USE_BACKUP__
VNA_MODE_BACKUP, // Made backup settings (save some settings after power off)
#endif
#ifdef __FLIP_DISPLAY__
VNA_MODE_FLIP_DISPLAY, // Flip display
#endif
#ifdef __DIGIT_SEPARATOR__
VNA_MODE_SEPARATOR, // Comma or dot digit separator (0: dot, 1: comma)
#endif
#ifdef __SD_CARD_DUMP_TIFF__
VNA_MODE_TIFF, // Save screenshot format (0: bmp, 1: tiff)
#endif
#ifdef __USB_UID__
VNA_MODE_USB_UID // Use unique serial string for USB
#endif
};
// Update config._vna_mode flags function
typedef enum {VNA_MODE_CLR = 0, VNA_MODE_SET, VNA_MODE_TOGGLE} vna_mode_ops;
void apply_VNA_mode(uint16_t idx, vna_mode_ops operation);
#ifdef __VNA_MEASURE_MODULE__
// Measure option mode
enum {
MEASURE_NONE = 0,
#ifdef __USE_LC_MATCHING__
MEASURE_LC_MATH,
#endif
#ifdef __S21_MEASURE__
MEASURE_SHUNT_LC,
MEASURE_SERIES_LC,
MEASURE_SERIES_XTAL,
MEASURE_FILTER,
#endif
#ifdef __S11_CABLE_MEASURE__
MEASURE_S11_CABLE,
#endif
#ifdef __S11_RESONANCE_MEASURE__
MEASURE_S11_RESONANCE,
#endif
MEASURE_END
};
#endif
#define STORED_TRACES 1
#define TRACES_MAX 4
#define TRACE_INDEX_COUNT (TRACES_MAX+STORED_TRACES)
typedef struct trace {
uint8_t enabled;
uint8_t type;
uint8_t channel;
uint8_t smith_format;
float scale;
float refpos;
} trace_t;
// marker 1 to 8
#define MARKERS_MAX 8
typedef struct marker {
uint8_t enabled;
uint8_t reserved;
uint16_t index;
freq_t frequency;
} marker_t;
typedef struct config {
uint32_t magic;
uint32_t _harmonic_freq_threshold;
int32_t _IF_freq;
int16_t _touch_cal[4];
uint16_t _vna_mode;
uint16_t _dac_value;
uint16_t _vbat_offset;
uint16_t _bandwidth;
uint8_t _lever_mode;