forked from jelinj8/dso203
-
Notifications
You must be signed in to change notification settings - Fork 39
/
Copy pathProcess.c
3071 lines (2655 loc) · 118 KB
/
Process.c
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
/******************** (C) COPYRIGHT 2009 e-Design Co.,Ltd. *********************
File Name : Process.c
Version : DS203_APP Ver 2.3x Author : bure
*******************************************************************************/
#include "Interrupt.h"
#include "Function.h"
#include "Process.h"
#include "Draw.h"
#include "Menu.h"
#include "BIOS.h"
#include "File.h"
#include "Calibrat.h"
#include "stm32f10x_map.h"
// FFT ////////////////////////////////////////////////////////////////////
s32 fr[FFTSize];
s32 fi[FFTSize];
u32 NFreq;
char NFreqStr[12];
int imax;
short PeakFreq;
char BaseFreqStr[12];
char PeakFreqStr[12];
char FreqDivStr[12];
char FreqT1Str[12];
////////////////////////////////////////////////////////////////////////////
u32 Sum[4]={0,0,0,0}; //averaging accumulators
u16 NAvg[4]={0,0,0,0};
u16 VNAvg[2]={0,0};
s32 VxAvg[2]={0,0};
s32 VxSsq[2]={0,0};
u32 PxS[4]={0,0,0,0};
u32 TxS[4]={0,0,0,0};
u32 TxN[4]={0,0,0,0};
u16 TaS, TbS, TcS, TdS; // cycles accumulated
u16 PaS, PbS, PcS, PdS; // pulse width of the cumulative
u16 TaN, TbN, TcN, TdN; // Cycle Count
s16 a_Mid_H, a_Mid_L;
s16 b_Mid_H, b_Mid_L;
s32 a_Avg, b_Avg, a_Ssq, b_Ssq; // use signed integers, allows values at bottom of screen to be read
s16 a_Max, b_Max, a_Min, b_Min; // 0 levels can get pushed up by calibration, bringing bottom of screen below 0
s16 aT_Max, bT_Max, aT_Min, bT_Min; // for auto trigger, kept separate from meter data for curdeftime
s16 Posi_412,Posi_41_2, Posi_41, Posi_42, Posi_4_2, Posi_4F1, Posi_4F2, Posi_4F3, Posi_4F4;
s16 c_Max=0, d_Max=0, A_Posi, B_Posi;
u8 BailoutFlag=0;
u16 JumpCnt,CountUnread;
u8 FrameMode;
u8 HoldOnNext =0;
u16 bag_max_buf = 4096;
u8 freerun=0; //flags for auto trig mode
u8 exitflag=0;
u8 entryflag=0;
u8 ADCoffset=54; //shifts ADC/FIFO operating area away from non-linear first xx steps into previously unused linear 200-255 step area
u16 TempKp1=1024;
u8 CalFlag;
u8 CurDefTime=0;
u8 Options; //options flag
u8 HoldResetFlag=0;
s16 Xtend; //buffer size control
u8 discard=0; //pre-signal trace blanking
s16 TrigSourceEnable=1; //for alternate triggering, end of cycling, will go to chA
u32 ReverseBitMask;
u32 BitMask;
u16 AltHoldoff=0;
s8 OldShift=0;
u8 ClearMeterAreaFlag=0;
u8 ScalingOffset=40; //centers Ka3 Y-position scaling factor on a step other than 0
//25= same as calibration gain correction (Ka2) zero
//40= same as y-position alignment offset (Ka1) zero calibration point
u16 QStart[2]={0,0}; //quantization error start/stop reference positions
u16 QEnd[2]={0,0};
u8 LastA_Mid=0; //trigger level points for time meter quantization error calculations
u8 LastB_Mid=0;
u8 FirstA_Mid=0;
u8 FirstB_Mid=0;
u8 SumResetFlag=0; //resets meter summing function
u32 UTmp;
u8 EnablePaS=1; //controls update speed of PaS and PbS derived calcs (TH, TL, %duty) in large meters
u8 ClearHoldFlag=0;
u8 SlowModeSkip=0;
u8 ClearLeadingEdge=0; //WAS 0
u8 FFTflag=0;
u8 Normal=100;
u8 FrameEndFlag;
u8 FFTGain=0;
u16 BufferSize=512;
u8 EnableFFT;
u8 Filter=40;
u8 InitiateNoise;
s32 Waste;
s8 PrevSweepIndex=-1;
u8 ResetFlag=0;
u16 ARBT_ARR;
u8 M_Factor=1;
u8 WaitForTrigFlag=0;
s16 Ch1TLevel=100;
s16 Ch2TLevel=100;
u8 SerialStatus;
u8 StartUart=0;
u32 USART1_DR=((u32)(USART1_BASE + 0x04));
u8 InitiateUartGen=0;
u8 OsTransferCompleteFlag;
u8 OsFFTData[2][700];
u8 AutoTrigIni=0;
u8 RMSdata[2][700];
u8 InvertA=0;
u8 InvertB=0;
u8 ScrollFlag=2;
u8 ErrorFlag=0;
u8 ResetEnableFFT=0;
u8 FastMode=1;
u8 ChartMode=0;
u8 OsChartFlag=0;
u8 ToggleName=0;
u8 DisableCursorTimer=0;
u16 DownConvert=0;
u32 FreqIN;
u8 DownConvertInitiate=0;
u32 FFTScale=0;
u8 DCbase;
u8 DCframe;
u8 DCmode;
u8 DCmeter;
u16 DCt1=0;
u8 FreqScaleShift;
u8 DownConvertShiftEnable=0;
u32 LfreqPeriod;
u16 PrecisionLevel=0;
u8 FFTt1Mode=0;
void Beeper(u16 ms); //alarms
void AlternateChannel(void); //for A&B mode
void SetOffset(u8 channel,u8 range, s16 Ypos); //sets Ka3,Kb3 zero level reference
void BatLevelCompensation(void);
s8 InterpolateS8(u8 Ch, s8 L8,s8 H8); //for battery level comp
u16 InterpolateU16(u8 Ch, u16 L16,u16 H16);
s16 QParam(u8 Ch, u16 Position,u8 service); //for Qerror
s32 QError(u8 Ch, u16 Start, u16 End, u32 Utmp); //quantization error compensation
void Average(u8 Ch);
void RunAvg(u8 Ch);
s32 VRunAvg(u8 Ch, s32 Value, s32 Sum);
void cleardatabuf(u8 service);
s32 Log10Process(u16 i);
u8 TriggerModeLogic(void);
void SetIRQ2Priority(void);
void CalculateArbtTimer(void);
void UpdateTLevels(void);
void UpdateCursorMeter(void);
void CursorDisplaySelectLogic(void);
s16 WaveValue(u16 j);
u8 TriggerType=0;
u8 SubIndex=0;
s16 WindowPosition;
//u8 StartOffset=16; //this displayed trigger point ~2 samples to left of trigger vernier on factory FPGA, ~4 on custom FPGA
u8 StartOffset=14; //NOTE: 2 sample delay buffer now used for data aligns with trigger's 2 sample delay so need default of 16(?)
u8 OsBufferLogicFlag=0;
u8 OSAvg=0;
u8 PrevSource=0xFF,PrevKind=0xFF;
u8 InvTrig[8]={1,0,3,2,6,7,4,5};
u8 HardwareVersion;
const SubTbase TbaseSub[13]={
// .Psc .Arr .S_OS_Size .Ratio
{1-1, 2400-1, 100, 10}, //.1S
{1-1, 4800-1, 100 , 5}, //.2S
{1-1, 8000-1, 150 , 2}, //.5S
{1-1, 16000-1, 150 , 1}, //1S
{1-1, 32000-1, 150 , 2}, //2S
{1-1, 60000-1, 200 , 5}, //5S
{10-1, 12000-1, 200 , 10}, //10S
{10-1, 12000-1, 300 , 15}, //15S
{10-1, 24000-1, 300 , 30}, //30S
{10-1, 36000-1, 400 , 60}, //60S
{100-1, 7200-1, 400 , 120}, //2M
{100-1, 12000-1, 600 , 300}, //5M
{100-1, 24000-1, 600 , 600}}; //10M
const OSTbase TbaseOS[17]={
// .Psc .Arr
{200-1,1500-1}, //1S
{100-1,1500-1}, //500MS
{40-1,1500-1}, //200MS
{40-1,750-1}, //100MS
{40-1,375-1}, //50MS
{16-1,375-1}, //20MS
{8-1,375-1}, //10MS
{4-1,375-1}, //5mS
{4-1,150-1}, //2MS
{2-1,150-1}, //1MS
{1-1,150-1}, //500uS
{1-1,60-1}, //200uS
{1-1,30-1}, //100uS
{1-1,15-1}, //50uS
{1-1,6-1}, //20uS
{1-1,3-1}, //10uS
{1-1,2-1}}; //5uS
uc16 Wait[22]= {1000, 500, 200, 100, 65, 30, 20, 10, 5, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2};
uc16 shortwait[22]= {600, 250, 100, 75, 35, 15, 10, 10, 5, 3, //for auto trig mode, set time to hold before going auto
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2 };
uc16 TrigDelayLoop[10]= {2,4,10,20,40,100,200,400,1000,2000}; //for trig holdoff, sets how many time loops before allowing rest of program to function
uc16 AltDelay[21]= {1000, 500, 300, 150, 75, 30, 15, 8, 4, 2}; //for alt trig mode, sets time to wait for trigger in other ch if untriggered
uc16 TimeBase[22]= {50000,50000,20000,10000,5000,2000,1000,500,200,100,50,20,10,5,2,1,1,1,1,1,1,1};
Y_attr *Y_Attr;
X_attr *X_Attr;
G_attr *G_Attr;
T_attr *T_Attr;
u32 DataBuf[4096]; //could save 4K of RAM here, using u16 + u8 struct
u8 TrackBuff [397 * 4]; // curve track: i +0, i +1, i +2, i +3, respectively, placed one on the 4th track data
uc8 Log10Mant[100]={ 0, 0, 3, 5, 6, 7, 8, 8, 9, 10, 0, 4, 8,11,15,18,20,23,26,28,30,32,34,36,38, //0-9: scale x10, 10-99: scale x100
40,41,43,45,46,48,49,51,52,53,54,56,57,58,59,60,61,62,63,64,65,66,67,68,69,
70,71,72,72,73,74,75,76,76,77,78,79,79,80,81,81,82,83,83,84,85,85,86,86,87,
88,88,89,89,90,90,91,91,92,92,93,93,94,94,95,95,96,96,97,97,98,98,99,99,100};
uc8 Window[512]= //Hann window
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8,
9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 17, 17, 18, 18, 19,
20, 20, 21, 21, 22, 23, 23, 24, 25, 25, 26, 27, 28, 28, 29, 30, 30, 31, 32, 33,
33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 41, 42, 43, 44, 45, 46, 46, 47, 48, 49,
50, 51, 52, 53, 53, 54, 55, 56, 57, 58, 59, 60, 61, 61, 62, 63, 64, 65, 66, 67,
68, 69, 70, 71, 72, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 84, 85,
86, 87, 88, 89, 90, 91, 92, 93, 93, 94, 95, 96, 97, 98, 99,100,101,101,102,103,
104,105,106,106,107,108,109,110,111,111,112,113,114,115,115,116,117,118,118,119,
120,121,121,122,123,124,124,125,126,126,127,128,128,129,130,130,131,131,132,133,
133,134,134,135,135,136,137,137,138,138,139,139,140,140,140,141,141,142,142,143,
143,143,144,144,144,145,145,145,146,146,146,147,147,147,147,148,148,148,148,148,
149,149,149,149,149,149,149,150,150,150,150,150,150,150,150,150,150,150,150,150,
150,150,150,150,150,149,149,149,149,149,149,149,148,148,148,148,148,147,147,147,
147,146,146,146,145,145,145,144,144,144,143,143,143,142,142,141,141,140,140,140,
139,139,138,138,137,137,136,135,135,134,134,133,133,132,131,131,130,130,129,128,
128,127,126,126,125,124,124,123,122,121,121,120,119,118,118,117,116,115,115,114,
113,112,111,111,110,109,108,107,106,106,105,104,103,102,101,101,100, 99, 98, 97,
96, 95, 94, 93, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 84, 83, 82, 81, 80, 79,
78, 77, 76, 75, 74, 73, 72, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 61,
60, 59, 58, 57, 56, 55, 54, 53, 53, 52, 51, 50, 49, 48, 47, 46, 46, 45, 44, 43,
42, 41, 41, 40, 39, 38, 37, 37, 36, 35, 34, 33, 33, 32, 31, 30, 30, 29, 28, 28,
27, 26, 25, 25, 24, 23, 23, 22, 21, 21, 20, 20, 19, 18, 18, 17, 17, 16, 15, 15,
14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 8, 7, 7, 6, 6, 6,
5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
s8 Ka1[10], Kb1[10];
u16 Ka2[10], Kb2[10];
s8 Ka3[10], Kb3[10];
s8 HKa1[10], HKb1[10];
u16 HKa2[10], HKb2[10];
s8 HKa3[10], HKb3[10];
s8 LKa1[10], LKb1[10];
u16 LKa2[10], LKb2[10];
s8 LKa3[10], LKb3[10];
u16 HiBatLevel[2]={0,0}; //high battery correction reference level
u16 LoBatLevel[2]={0,0}; //low battery correction reference level
u16 PrevBatLevel=0;
u16 VDiff[2]={0,0};
D_tab D_Tab[23] ={ // pulse waveform output driver table, based on the 72MHz frequency
// PSC ARR
{ 2400-1,30000-1}, //1 0
{ 1200-1,30000-1}, //2 1
{ 480-1, 30000-1}, //5 2
{ 240-1, 30000-1}, //10 3
{ 120-1, 30000-1}, //20 4
{ 48-1, 30000-1}, //50 5
{ 24-1, 30000-1}, //100 6
{ 12-1, 30000-1}, //200 7
{ 5-1, 28800-1}, //500 8
{ 2-1, 36000-1}, //1K 9
{ 1-1, 36000-1}, //2K 10
{ 1-1, 14400-1}, //5K 11
{ 1-1, 7200-1}, //10K 12
{ 1-1, 3600-1}, //20K 13
{ 1-1, 1440-1}, //50K 14
{ 1-1, 720-1}, //100K 15
{ 1-1, 360-1}, //200K 16
{ 1-1, 144-1}, //500K 17
{ 1-1, 72-1},
{ 1-1, 36-1},
{ 1-1, 18-1},
{ 1-1, 12-1},
{ 1-1, 9-1}}; // 22
//previous versions used 1.8Mhz sampling rate for 25Khz range (@ 72samples/period)
uc32 A_Freq[18]={1,2,5,10,20,50,100,200,500,1000,2000,5000,10000,20000,50000,100000,200000,500000};
uc8 ScaleIndex[17]={1,1,1,1,1,1,1,1,1,1,1,2,4,10,20,40,80}; //for max DAC sampling rate of 1.8Mhz(DAC is only rated to 1Mhz but seems OK @ 1.8Mhz)
uc16 A_Tab[17]={
50000-1, //1Hz uses 36Mhz clock, rest 72Mhz
50000-1,
20000-1,
10000-1,
5000-1, //all except noted @ 720 samples/period (=<1.44Mhz sampling rate)
2000-1,
1000-1,
500-1,
200-1, //500Hz
100-1, //1Khz
50-1, //2Khz
40-1, //5Khz @ 360 samples/period (1.8Mhz sampling rate)
40-1, //10Khz @ 180 samples/period (1.8Mhz sampling rate)
50-1, //20Khz @ 72 samples/period (1.44Mhz sampling rate)
40-1, //50Khz @ 36 samples/period (1.8Mhz sampling rate) 14
40-1, //100Khz@ 18 samples/period (1.8Mhz sampling rate)
40-1}; //200Khz@ 9 samples/period (1.8Mhz sampling rate)
s16 ATT_DATA[720]; //could go up to 2880 to allow long arb digital streams
sc16 SIN_QUAD[181]={ 2048 , 2066 , 2084 , 2102 , 2119 , 2137 , 2155 , 2173 , 2191 , 2209 , 2226 ,
2244 , 2262 , 2280 , 2297 , 2315 , 2333 , 2351 , 2368 , 2386 , 2403 , 2421 ,
2439 , 2456 , 2474 , 2491 , 2508 , 2526 , 2543 , 2561 , 2578 , 2595 , 2612 ,
2629 , 2646 , 2664 , 2681 , 2698 , 2714 , 2731 , 2748 , 2765 , 2782 , 2798 ,
2815 , 2831 , 2848 , 2864 , 2881 , 2897 , 2913 , 2929 , 2945 , 2961 , 2977 ,
2993 , 3009 , 3025 , 3040 , 3056 , 3072 , 3087 , 3102 , 3118 , 3133 , 3148 ,
3163 , 3178 , 3193 , 3207 , 3222 , 3237 , 3251 , 3266 , 3280 , 3294 , 3308 ,
3322 , 3336 , 3350 , 3364 , 3377 , 3391 , 3404 , 3418 , 3431 , 3444 , 3457 ,
3470 , 3483 , 3495 , 3508 , 3520 , 3533 , 3545 , 3557 , 3569 , 3581 , 3593 ,
3605 , 3616 , 3628 , 3639 , 3650 , 3661 , 3672 , 3683 , 3693 , 3704 , 3714 ,
3725 , 3735 , 3745 , 3755 , 3765 , 3774 , 3784 , 3793 , 3803 , 3812 , 3821 ,
3830 , 3838 , 3847 , 3855 , 3864 , 3872 , 3880 , 3888 , 3896 , 3903 , 3911 ,
3918 , 3925 , 3932 , 3939 , 3946 , 3953 , 3959 , 3965 , 3972 , 3978 , 3983 ,
3989 , 3995 , 4000 , 4006 , 4011 , 4016 , 4021 , 4025 , 4030 , 4034 , 4038 ,
4043 , 4046 , 4050 , 4054 , 4057 , 4061 , 4064 , 4067 , 4070 , 4073 , 4075 ,
4077 , 4080 , 4082 , 4084 , 4086 , 4087 , 4089 , 4090 , 4091 , 4092 , 4093 ,
4094 , 4094 , 4095 , 4095 , 4095 };
sc16 Sine100K[18]= //
{0x9C0,0xC59,0xE68,0xFAB,
0xFFF,0xF70,0xDF5,0xBBD,0x90E,
0x63E,0x3A5,0x196,0x053,
0x000,0x08E,0x209,0x441,0x6F0};
sc16 Sine200K[9]=
{0xC59,0xFAB,
0xF70,0xBBD,
0x63E,0x196,
0x000,0x209,0x6F0};
sc16 Triangle100K[18] =
{0x8E2,0xAA9,0xC70,0xE37,
0xFFE,0xE37,0xC70,0xAA9,0x8E2,
0x71B,0x554,0x38D,0x1C6,
0x000,0x1C6,0x38D,0x554,0x71B};
sc16 Triangle200K[9] =
{0xAA9,0xE37,
0xE37,0xAA9,
0x71B,0x38D,
0x000,0x38D,0x71B};
sc16 DIGI_DATA[2] = // Square wave data //
{2047,-2048};
void BackGround_Reset(u8 clear)
{
u8 i, j;
u8 TitleLimit=13;
if ((FlagMeter==2)&&(UpdateMeter!=4))TitleLimit=11;
if(clear)__Clear_Screen(BLACK);
Delayms(100);
for(i=0; i<TitleLimit; i++) for(j=0; j<4; j++) Title[i][j].Flag |= UPDAT;
for(i=0; i<9; i++) Meter[i].Flag |= UPDAT;
if(Current != FILE) {
Title[FILE][0].Flag &= !UPDAT;
Title[FILE][1].Flag &= !UPDAT;
Title[FILE][3].Flag &= !UPDAT;
}
Update = 1; // return back the jumper settings
ClearMeterAreaFlag=1;
InitXY=1;
}
/*******************************************************************************
App_init: Displays the window waveform data initialization
*******************************************************************************/
void App_init(u8 ClearScreen)
{
__Set(ADC_CTRL, EN );
__Set(ADC_MODE, SEPARATE);
__Set(STANDBY, DN); // exit the power saving state
Delayms(20);
__Set(FIFO_CLR, W_PTR);
BackGround_Reset(ClearScreen);
PD_Cnt = 600;
}
/*******************************************************************************
Update_Range:
*******************************************************************************/
void Update_Range(void)
{
u8 Amode=Title[TRACK1][COUPLE].Value;
u8 Bmode=Title[TRACK2][COUPLE].Value;
if (Amode==2){Amode--;Det|=1;}else Det&=2; //use AC for coupling in detector mode
if (Bmode==2){Bmode--;Det|=2;}else Det&=1;
if (Amode>2)Amode=0; //DC coupling for serial decode
if (Bmode>2)Bmode=0;
__Set(CH_A_COUPLE, Amode);
__Set(CH_A_RANGE, Title[TRACK1][RANGE].Value);
SetOffset(0,_A_Range,_1_posi);
__Set(CH_B_COUPLE, Bmode);
__Set(CH_B_RANGE, Title[TRACK2][RANGE].Value);
SetOffset(1,_B_Range,_2_posi);
if(SerialStatus)UpdateTLevels();
if((Sweep)||(Det)){
Update_Output();
if(Title[TRIGG][SOURCE].Value==4) Update_Trig(0); else Update_Trig(1);
}
}
/*******************************************************************************
Update_Base:
*******************************************************************************/
void Update_Base(void)
{
u16 i,Tmp;
if(DownConvertMode)return;
__Set(ADC_CTRL, EN);
if(ChartLogic()){
__Set(T_BASE_PSC, TbaseSub[SubIndex-1].Psc);
__Set(T_BASE_ARR, TbaseSub[SubIndex-1].Arr);
__Set_Param(8,0x96);
__Set_Param(9,0x00); //normal 150 sample pre-sampling depth
}else{
i = Title[T_BASE][BASE].Value;
if(OSBufferLogic()){
if(_T_base<16) Tmp=(1208-(_X_posi.Value*8))+(StartOffset*8);
else Tmp=(908-(_X_posi.Value*6))+(StartOffset*6);
__Set_Param(8,(Tmp&0xFF)); //stabilize window position and shift trigger point to match xpos rather
__Set_Param(9,((Tmp>>8)&0xFF)); //than shifting window to keep buffer size at 512 (X8= 4096)
__Set(T_BASE_PSC,TbaseOS[i].Psc);
__Set(T_BASE_ARR,TbaseOS[i].Arr);
}else{
__Set_Param(8,0x96);
__Set_Param(9,0x00); //normal 150 sample pre-sampling depth
__Set(T_BASE_PSC, X_Attr[i].PSC);
__Set(T_BASE_ARR, X_Attr[i].ARR);
}
SubIndex=0; //reset extended time base if moving out of SCAN mode
}
Wait_Cnt = Wait[_T_base];
if(_Mode!=SCAN){
if(_Status == RUN) __Set(FIFO_CLR, W_PTR); // FIFO write pointer reset
if((_T_base>16)||(OSBufferLogic())){if(Title[TRIGG][SOURCE].Value==4) Update_Trig(0); else Update_Trig(1);}
JumpCnt=0;
}
}
void FFTdownConvert(u8 service){
static u32 Divisor,WindowShiftFactor,AdjDivisor,Base,Fsamp=0,RefFreq,AdjBase;
static u16 FFTorderADJ;
static s8 i;
s8 h;
u32 Adj,Tmp=0,Tmp2,j;
u16 AdjustedARR=0;
u32 PreScale=0;
if(((FreqIN==0)&&(FFTt1Mode==0))||(DownConvertMode==0))return;
if(service==4){
if(FreqIN>5000000)DownConvertShiftEnable=60;
else if(FreqIN>1500000)DownConvertShiftEnable=30;
else DownConvertShiftEnable=15;
service=0;
}
if(service==3)goto ReadFreqMeter; //meter reads
else if((service)||(DownConvertShiftEnable==2))goto ShiftWindow; //window shifts
while(1){
if(DownConvertInitiate){
if(FFTt1Mode){ //"T1" mode
Tmp=(NFreq/FFTBins)*_T1;
if(_T_base<12)Tmp/=1000;
_T1=128;
DownConvert=1; //reset to base magnification
}else{
Tmp=FreqIN;
for(i=0;i<(FreqScaleShift);i++)Tmp/=10; //establish proper frequency from prior scaling
}
if(Tmp<215){
DownConvertMode=0;
DownConvertRestore();
return;
}
}else Tmp=RefFreq;
RefFreq=Tmp;
WindowShiftFactor=((90000000/Tmp)+11)/22;
if(WindowShiftFactor==0)WindowShiftFactor=1;
Adj=DownConvert*125; //shift halfway up sub-order
Adj-=(Adj%100); //remove offset to obtain sub-order base
FFTorderADJ=Adj/100; //store unscaled base order
Adj+=25; //restore offset
Divisor=((7200*Adj)/RefFreq)*100; //calculate division ratio
Divisor+=(((((7200*Adj)%RefFreq)*100)+(RefFreq/2))/RefFreq); //add and round last 2 significant digits of precision
if(Divisor>429495){ //limits slowest screen refresh to approx 2 to 3 seconds
switch(DownConvert){ //and reasonably accurate <1Hz calculations
case 5:
case 50:
case 500:
DownConvert/=5;
DownConvert*=2;
break;
default:
if(DownConvert>1)DownConvert/=2;else return;
}
}else break;
}
ShiftWindow:
if(service==1)Divisor+=WindowShiftFactor;
else if(service==2)Divisor-=WindowShiftFactor;
if(Divisor<1200)_T_base=12;else _T_base=7; //allows proper selection of buffer aquisition modes
__Set_Param(8,0x96);
__Set_Param(9,0x00); //normal 150 sample pre-sampling depth
if(Divisor<61356){ //setup prescaling
PreScale=1;
AdjustedARR=Divisor;
}else{
PreScale=(Divisor/61356)+1; //try to find integral prescale
while((Divisor%PreScale)!=0){
PreScale++;
}
if(PreScale<61356){ //if integral ratios found
AdjustedARR=(Divisor/PreScale);
}else{ //if not keep prescale small and use rounded ARR
i=1;
for(j=122712;j<429496;j+=61356){
i++;
if(Divisor<j){
PreScale=i;
AdjustedARR=((Divisor+(i/2))/i);
break;
}
}
}
}
__Set(T_BASE_PSC,PreScale-1);
__Set(T_BASE_ARR,AdjustedARR-1);
__Set(FIFO_CLR, W_PTR);
JumpCnt=0;
AdjDivisor=PreScale*AdjustedARR;
if(((72000000/AdjDivisor)*FFTorderADJ)>1000000){
Fsamp=((72000000/AdjDivisor)*100); //calculate downconverted sampling base
Tmp=((((72000000%AdjDivisor)*10000)/AdjDivisor)*FFTorderADJ)/100; //x10000 correction factor
Base=(Fsamp*FFTorderADJ)+Tmp; //actual frequency at base
i=-1;
}else{
Fsamp=((72000000/AdjDivisor)*1000);
Tmp=((((72000000%AdjDivisor)*10000)/AdjDivisor)*FFTorderADJ)/10;
Base=(Fsamp*FFTorderADJ)+Tmp;
i=0;
}
AdjBase=ClockAdjust(Base); //adjust with CPU clock frequency correction
ReadFreqMeter:
if(service==3){ //offset from sub-order fold
if(i==-1)Tmp2=(((LfreqPeriod/(Power(10,(ShiftDigits+1))))+(AdjDivisor/2))/AdjDivisor)*72;
else Tmp2=(((LfreqPeriod+(AdjDivisor/2))/AdjDivisor)*72)/(Power(10,(ShiftDigits)));
if(AdjBase<1000000){Tmp=10;h=i+1;}else{Tmp=1;h=i;}
Int2Str(BaseFreqStr,(AdjBase*Tmp), F_UNITSUB , 7, UNSIGN,h);
Int2Str(PeakFreqStr,((AdjBase+Tmp2)*Tmp), F_UNITSUB , 7, UNSIGN,h);
Int2Str(NFreqStr,((AdjBase+(Fsamp>>1))*Tmp), F_UNITSUB , 7, UNSIGN,h);
if(Fsamp>10000000)j=((AdjBase+((((Fsamp>>1)+128)/FFTBins)*_T1))*Tmp);
else j=(( AdjBase+(((Fsamp*_T1)+256)/512))*Tmp);
Int2Str(FreqT1Str,j,F_UNITSUB, 7, UNSIGN,h);
if((Fsamp*15)>286331000)Tmp=(((Fsamp+(FFTBins/2))/FFTBins)*15);
else Tmp=((Fsamp*15)+(FFTBins/2))/FFTBins;
if(Tmp<1000){Tmp*=10000;j=4;}
else if(Tmp<10000){Tmp*=1000;j=3;}
else if(Tmp<100000){Tmp*=100;j=2;}
else if(Tmp<1000000){Tmp*=10;j=1;}else j=0;
Int2Str(FreqDivStr,Tmp,F_UNITSUB, 7, UNSIGN,j+i);
if(i==-1)Tmp=RefFreq*100;else Tmp=RefFreq*1000;
if((imax>20)&&(imax<215)&&(Base<Tmp)&&(Tmp<(Base+(Fsamp>>1))))Tmp=(Base+Tmp2);
if((Base>Tmp)||(Tmp>(Base+(Fsamp>>1))))
{for(j=0;j<10;j++)PeakFreqStr[j]='-';PeakFreqStr[10]=0;}
if(FFTt1Mode==0){
if(i==-1)RefFreq=Tmp/100;else RefFreq=Tmp/1000;
}
}
if(FFTt1Mode){
if(((DownConvert>PrecisionLevel)&&(service==0))
||((DownConvert>=PrecisionLevel)&&((service==1)||(service==2)))){
if(service==0)PrecisionLevel=DownConvert;
if((service==1)||(service==2))_T1=128; //reset T1 to middle of screen if shifting window
if(i==-1)RefFreq=(Base+(((Fsamp>>1)/FFTBins)*_T1))/100;
else RefFreq=(Base+(((Fsamp>>1)/FFTBins)*_T1))/1000;
}
}
}
/*******************************************************************************
Update_Output:
*******************************************************************************/
void Update_Output(void) {
u16 i,BaudDiv;
if((StartUart)&&(_Kind==8)){ //transmit uart data
DMA1_Channel4->CCR &=~DMA_CCR1_EN; //disable usart1 dma access
USART1->SR &=0xFFBF; //clear bit 6 (transmission complete bit, TC)
DMA1_Channel4->CNDTR =UartFileSize; //number of bytes to load
DMA1_Channel4->CCR |=0x00000001; //enable
StartUart=0;
return;
}else if(_Kind==8){
if(InitiateUartGen==0)InitiateUartGen=1;else goto AdjUartGen;
}else InitiateUartGen=0;
if(_Frqn==0)TIM7->PSC=1; else TIM7->PSC=0; //set DAC clock to 36Mhz for 1Hz to avoid ARR overload, 72Mhz for rest
SetIRQ2Priority();
TIM_2IRQControl();
if(Title[TRIGG][SOURCE].Value==4) Update_Trig(0); else Update_Trig(1);
M_Factor=1;
TIM4->CR1 = 0x0080; // SQR_OUT = Disable. Stops counter 0x80=auto reload preload enable
TIM4->DIER = 0x0000; // disable TIM4_INT
TIM4->CR2 = 0x0000; // disable update event as output
AFIO->MAPR =0x04000000; //reset remaped PB6 alt function
USART1->CR1 =0x0000; //disable usart1
RCC->APB2ENR &=0xFFFFBFFF; //disable usart1 clock
DMA1_Channel4->CCR &=~DMA_CCR1_EN;//disable usart1 dma access
if(ResetFlag){
TIM4->EGR=0x0001; // generate update event for full reset
TIM2->EGR=0x0001;
ResetFlag--;
}
DAC->CR = 0x00000000; // reset both channels
if(_Kind == PWM){ //(4)
if(Sweep==1){ //if in sweep mode, initialize analog as well as it uses this along with PWM
Title[OUTPUT][DUTYPWM].Value=15000;
DMA2_Channel4->CCR &= ~DMA_CCR1_EN;
for(i=0;i<720;i++)ATT_DATA[i]=2048;
ResetDMA2_Ch4Params(72);
__Set(ANALOG_ARR, 40-1);
}
__Set(DIGTAL_PSC, D_Tab[_Frqn].PSC);
__Set(DIGTAL_ARR, D_Tab[_Frqn].ARR);
i=((D_Tab[_Frqn].ARR+1)*(30000-Title[OUTPUT][DUTYPWM].Value))/30000;
if(i==0)i++;
if(i>(D_Tab[_Frqn].ARR+1))i=(D_Tab[_Frqn].ARR+1);
if((Sweep==1)||(PWAdjustMode==0)){
__Set(DIGTAL_CCR,i);
}else{
GPIOB->CRL &= 0xF0FFFFFF;
GPIOB->CRL |= 0x0B000000;
TIM4->CR1 = 0x0081;
}
TIM4->EGR=0x0001; //reset
}else if(_Kind==5){ // random noise mode
if(_Frqn>18)_Frqn=18; // DAC refresh limit, 1Mhz
InitiateNoise=1;
if(PrevSweepIndex<0)PrevSweepIndex=SweepIndex;
DMA2_Channel4->CCR &=0xFFFFFFFE; // release DMA channel from DAC
DMA1_Channel4->CCR &= ~DMA_CCR1_EN; //make sure ch is off (same as ccrX)
GPIOB->CRL = 0x34BBB438; // puts PWM port(TIM4/PB6) in input, floating mode + configures other bits
GPIOA->CRL = 0x110011BB; // puts DAC2 port (PA5) in input, analog mode
if(_Frqn<8)i=_Frqn+6; // 100x averaging filter @ <500hz
else if(_Frqn<14)i=_Frqn+3; // 10x filter for 500hz - 20Khz
else i=_Frqn; // above 20Khz no filtering
TIM4->PSC = D_Tab[i].PSC; // oversampling setup
TIM4->ARR = D_Tab[i].ARR;
if(_Frqn<16){
TIM4->DIER|=0x0001; // enable TIM4_INT, engages seeding @ <200Khz and filters for frequencies <=20Khz
}else{
TIM4->DIER=0x0000; // seeding by TIM2_INT for freq limits > 100Khz
SweepIndex=_Frqn-13;
}
TIM_2IRQControl();
TIM4->CR2 = 0x0020; // use update event as output
TIM4->CR1 = 0x0085; // turn on DAC2 clock, preload arr, update only on overflow
if(_Frqn<14){
DAC->CR = 0x0B6C002C; // set up both DACs to trigger from TIM4 update event: DAC2=generator > filter > DAC1=output
DAC->CR |= 0x00010001; // enable both channels
}else{ // above 20Khz
DAC->CR = 0x00000B6C; // set up DAC1 for generator and output
DAC->CR |= 0x00000001; // enable DAC1
}
return;
}else if(_Kind==6){ // generator turned off DAC, PWM and TIM4_INT already shut down at top of function
// shut down additional resources + set output low
DMA2_Channel4->CCR&= 0xFFFFFFFE; // release DMA channel from DAC
TIM7->CR1 = 0x0084; // shut off DAC timer
GPIOA->CRL |= 0x00040000; // disconnect DAC if connected
GPIOB->CRL &= 0xF0FFFFFF; // reset bit 6 control
GPIOB->CRL |= 0x03000000; // enable bit 6 as output
GPIOB->ODR &= 0x0000FFBF; // reset bit 6 to set gen output low
if(PrevSweepIndex<0)PrevSweepIndex=SweepIndex;
return;
}else if(_Kind==7){ //arbitrary waveforms
while((ArbtSampleNumber*A_Freq[_Frqn])>1800000)_Frqn--; //limit frequency range so sampling rate is <1.8Mhz
Title[OUTPUT][1].Flag|= UPDAT;
DMA2_Channel4->CCR &= ~DMA_CCR1_EN;
ResetDMA2_Ch4Params(ArbtSampleNumber);
CalculateArbtTimer();
}else if(_Kind==8){ //UART OUTPUT
GPIOA->CRL &=0xFFF0FFFF; //reset PA4 control
GPIOA->CRL |=0x00080000; //PA4 (DAC1 port) set to input pull up/down mode
GPIOA->ODR |=0x00000010; //pull up port so idle line stays high through external connection with PB6
TIM4->PSC = 2400-1; //Generate update event for full reset, sets disabled TIM4 output low.
__Set(DIGTAL_ARR, 3000-1); //Remapped alternate function appears to be logically or'd with default
TIM4->CCR1 = 3000-1; //alternate function, so default needs to be at 0 level or it will shut
TIM4->EGR=0x0001; //remapped off. Could not find this defined in STM32 programming reference...
AFIO->MAPR =0x04000004; //remap PB6 alt function to USART1 TX
RCC->APB2ENR |=0x00004000; //enable usart1 clock
GPIOB->CRL &=0xF0FFFFFF; //reset PB6 control
GPIOB->CRL |=0x09000000; //PB6 set to alt function, B=50Mhz 9=10Mhz push-pull output
AdjUartGen:
switch(GenUartMode){
case 1:
USART1->CR1 =0x2408; //uart1 enable, 7Pe
break;
case 2:
USART1->CR1 =0x2608; //uart1 enable, 7Po
break;
case 3:
USART1->CR1 =0x2008; //uart1 enable, 8N
break;
case 4:
USART1->CR1 =0x3408; //uart1 enable, 8Pe
break;
case 5:
USART1->CR1 =0x3608; //uart1 enable, 8Po
break;
case 6:
USART1->CR1 =0x3008; //uart1 enable, 9N
}
if(GenUartStopBits==0)
USART1->CR2 =0x0000; //1 stop bit, clock disabled
else USART1->CR2 =0x2000; //2 stop bits
USART1->CR3 =0x0088; //enable DMA for transmit, half duplex (mode allows remap of PB6 only)
if(GenBaudIndex<8485){ //below 8485 divider = index for baud rates 8485 to 4.5M
BaudDiv=GenBaudIndex;
GenBaudRate=72000000/GenBaudIndex;
}else{ //above 8485 baud rate 1:1 ratio with index, baud rate calculated for all integers down to 1099
GenBaudRate=((15871-GenBaudIndex)+1099);
BaudDiv=72000000/GenBaudRate;
}
USART1->BRR =BaudDiv;
USART1->SR &=0xFFBF; //clear bit 6 (transmission complete bit, TC)
DMA1_Channel4->CCR &=~DMA_CCR1_EN; //disable usart1 dma access
DMA1_Channel4->CPAR =(u32)USART1_DR; //usart data register address
DMA1_Channel4->CMAR =(u32)SecBuff; //file data
DMA1_Channel4->CNDTR =0; //only initialize
DMA1_Channel4->CCR =0x00003000; //priority
if(GenUartCont){
DMA1_Channel4->CCR |=0x000000B0; //setup B > circular mode
}else{
DMA1_Channel4->CCR |=0x00000090; //setup 9 > single mode
}
DMA1_Channel4->CCR |=0x00000001; //enable
return;
}else{
if(_Frqn>16)_Frqn=16;
DMA2_Channel4->CCR &= ~DMA_CCR1_EN;
WaveGen();
ResetDMA2_Ch4Params(720/ScaleIndex[_Frqn]);
__Set(ANALOG_ARR, A_Tab[_Frqn]);
}
if(PrevSweepIndex>=0){SweepIndex=PrevSweepIndex;PrevSweepIndex=-1;}
if(GenAdjustMode==0){GenFreqShift=0;PrevShift=0;}
OutputAdjust();
}
void ResetDMA2_Ch4Params(u32 Count){ //This is an attempt to fix a *very* occasional loss of this DMA function while quickly
DMA2_Channel4->CPAR=DHR12R1_DAC; //shifting some gen menu functions by holding down repeat keys, requiring reboot. All relevant parms now reset
__Set(ANALOG_PTR, (u32)ATT_DATA); //DMA ch needs to be disabled before calling
__Set(ANALOG_CNT, Count);
DMA2_Channel4->CCR =0x00003000; //priority
DMA2_Channel4->CCR|=0x000005B0; //setup
DMA2_Channel4->CCR|=0x00000002; //turn transfer complete int on
DMA2_Channel4->CCR|=0x00000001; //enable
DMA2->IFCR|=0x00002000; //clear transfer complete int flag
TIM7->DIER=0x0100; //enable DMA call
TIM7->CR2 =0x0000; //system (V1.50-1.64, others?) sets bit 3 here for DMA call on update event, no such selection on basic timers
} //TIM 7 does not have capture compare mode, so DMA call is always on update event
void CalculateArbtTimer(void){
u32 X;
u16 Y;
X=72000000/(ArbtSampleNumber*A_Freq[_Frqn]);
if(X<10000){
TIM7->PSC=0;
ARBT_ARR=X-1;
}else{
Y=X/10000;
while((X%Y)!=0)Y++; // find an integral divider
if(Y>(X/Y)){ // if divider larger than divided, use as ARR so freq shift function can work correctly
TIM7->PSC=(X/Y)-1;
ARBT_ARR=(Y-1);
}else{
TIM7->PSC=(Y-1);
ARBT_ARR=(X/Y)-1;
}
}
__Set(ANALOG_ARR,ARBT_ARR);
}
/*******************************************************************************
Update_Trig:
*******************************************************************************/
void Update_Trig(u8 service)
{
u16 a;
u16 b;
u32 UTmp;
AutoTrigIni=1;
TriggerType=_Tr_kind;
a=((TempKp1*_T1)+512)/1024; //compensate for interpolated ranges
b=((TempKp1*_T2)+512)/1024;
if(OSBufferLogic()){if(_T_base<16) {a*=8;b*=8;}else{a*=6;b*=6;}}
if(_Tr_kind==8){
if((Sweep)&&(_Kind<5)){
UTmp=((1000/((TIM2Speed[SweepIndex]*SweepStep*5)/SweepMod))*750)/TimeBase[_T_base]; //calculate optimum period to trigger on
if(UTmp>200)UTmp=200;
if(OSBufferLogic()){if(_T_base<16)UTmp*=8;else UTmp*=6;}
__Set(T_THRESHOLD,UTmp); //bits 0-15
if(service){
if(Title[TRIGG][SOURCE].Value == TRACK1){
if(_Vt1>_1_posi)TriggerType=5;else TriggerType=7;
}
if(Title[TRIGG][SOURCE].Value == TRACK2){
if(_Vt2>_2_posi)TriggerType=5;else TriggerType=7;
}
}else{
if(TrigSourceEnable == TRACK1){
if(_Vt1>_1_posi)TriggerType=5;else TriggerType=7;
}
if(TrigSourceEnable == TRACK2){
if(_Vt2>_2_posi)TriggerType=5;else TriggerType=7;
}
}
if((_Kind==PWM)&&((Sweep>1)||(Det==0)))TriggerType=5;
}else{
TriggerType=3; //trigger on positive transition of continuous wave
}
}else{
if(_T1 > _T2) __Set(T_THRESHOLD,a-b);
else __Set(T_THRESHOLD,b-a);
}
if((InvertA)&&((Title[TRIGG][SOURCE].Value==0)||((Title[TRIGG][SOURCE].Value==4)&&(TrigSourceEnable==0)))){
a=((((-(_Vt1+Ka1[_A_Range]-_1_posi))*1024)/Ka2[_A_Range])&0xFF)+ADCoffset+_1_posi;
}else{
a=((((_Vt1-Ka1[_A_Range]-_1_posi)*1024)/Ka2[_A_Range])&0xFF)+ADCoffset+_1_posi;
}
if((InvertB)&&((Title[TRIGG][SOURCE].Value==1)||((Title[TRIGG][SOURCE].Value==4)&&(TrigSourceEnable==1)))){
b=((((-(_Vt2+Kb1[_B_Range]-_2_posi))*1024)/Kb2[_B_Range])&0xFF)+ADCoffset+_2_posi;
}else{
b=((((_Vt2-Kb1[_B_Range]-_2_posi)*1024)/Kb2[_B_Range])&0xFF)+ADCoffset+_2_posi;
}
UpdateTLevels();
if(TriggerType>7)TriggerType=3;
if((_T_base>18)||(OSBufferLogic())){ //use time based triggering for OS and fastest timebases rather than edge or level trig
if((TriggerType==0)||(TriggerType==2)){ //more reliable for random, occasional triggers or noisy OS waveforms
TriggerType=7; //triggers if time exceeds threshold
__Set(T_THRESHOLD,0); //setting time to exceed at 0 turns these into an edge or level trigger
}
if((TriggerType==1)||(TriggerType==3)){
TriggerType=5;
__Set(T_THRESHOLD,0); //setting time to exceed at 0 turns these into an edge or level trigger
}
}
if(((Title[TRIGG][SOURCE].Value==0)&&(InvertA))||((Title[TRIGG][SOURCE].Value==1)&&(InvertB))||
((Title[TRIGG][SOURCE].Value==4)&&(((TrigSourceEnable==0)&&(InvertA))||((TrigSourceEnable==1)&&(InvertB)))))
TriggerType=InvTrig[TriggerType];
if(service){ //in regular trigger modes
if( (((PrevSource!=_Tr_source)||(PrevKind!=TriggerType)))||(!OSBufferLogic())||(service==2))//does not reset trig mode in OS mode except when changing
__Set(TRIGG_MODE,(_Tr_source<< 3)+TriggerType);
PrevSource=_Tr_source; PrevKind=TriggerType;
if(Title[TRIGG][SOURCE].Value == TRACK1){
__Set(V_THRESHOLD,a);
}
if(Title[TRIGG][SOURCE].Value == TRACK2){
__Set(V_THRESHOLD,b);
}
if(OSBufferLogic()){
if(_T_base<16) UTmp=(1208-(_X_posi.Value*8))+(StartOffset*8);
else UTmp=(908-(_X_posi.Value*6))+(StartOffset*6);
__Set_Param(8,(UTmp&0xFF)); //stabilize window position and shift trigger point to match xpos rather
__Set_Param(9,((UTmp>>8)&0xFF)); //than shifting window to keep buffer size at 512 (X8= 4096)
}
}else{ //in A&B trigger mode
__Set(TRIGG_MODE, (TrigSourceEnable<< 3)+TriggerType); //TRIGG_MODE =
if(TrigSourceEnable == TRACK1){
__Set(V_THRESHOLD,a);
}
if(TrigSourceEnable == TRACK2){
__Set(V_THRESHOLD,b);
}
}
if((Current==7)&&(_Det==2)&&(_Mode!=X_Y)&&(_4_source!=SPEC_A)
&&(_4_source!=SPEC_B)&&(ListOverride)){
ConfNameTimer=110;
ToggleName=1;
Update_Mark();
}
}
void UpdateTLevels(void){
Ch1TLevel=(((_Vt1-Ka1[_A_Range]-_1_posi)*1024)/Ka2[_A_Range])+_1_posi;
Ch2TLevel=(((_Vt2-Kb1[_B_Range]-_2_posi)*1024)/Kb2[_B_Range])+_2_posi;
}