]> sigrok.org Git - sigrok-firmware-fx2lafw.git/blob - hw/sainsmart-dds120/fw.c
scopes: Unify code-base, remove duplicate code/files.
[sigrok-firmware-fx2lafw.git] / hw / sainsmart-dds120 / fw.c
1 /*
2  * This file is part of the sigrok-firmware-fx2lafw project.
3  *
4  * Copyright (C) 2009 Ubixum, Inc.
5  * Copyright (C) 2015 Jochen Hoenicke
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <fx2macros.h>
22 #include <fx2ints.h>
23 #include <autovector.h>
24 #include <delay.h>
25 #include <setupdat.h>
26
27 #define SET_ANALOG_MODE() PA7 = 1
28
29 #define SET_COUPLING(x) set_coupling(x)
30
31 #define SET_CALIBRATION_PULSE(x) set_calibration_pulse(x)
32
33 /* Toggle the 1kHz calibration pin, only accurate up to ca. 8MHz. */
34 /* Note: There's no PE2 as IOE is not bit-addressable (see TRM 15.2). */
35 #define TOGGLE_CALIBRATION_PIN() IOE = IOE ^ 0x04
36
37 #define LED_CLEAR() NOP
38 #define LED_GREEN() NOP
39 #define LED_RED()   NOP
40
41 #define TIMER2_VAL 1000
42
43 /* CTLx pin index (IFCLK, ADC clock input). */
44 #define CTL_BIT 2
45
46 #define OUT0 ((1 << CTL_BIT) << 4) /* OEx = 1, CTLx = 0 */
47
48 static const struct samplerate_info samplerates[] = {
49         { 48, 0x80,   0, 3, 0, 0x00, 0xea },
50         { 30, 0x80,   0, 3, 0, 0x00, 0xaa },
51         { 24,    1,   0, 2, 1, OUT0, 0xea },
52         { 16,    1,   1, 2, 0, OUT0, 0xea },
53         { 15,    1,   0, 2, 1, OUT0, 0xaa },
54         { 12,    2,   1, 2, 0, OUT0, 0xea },
55         { 11,    1,   1, 2, 0, OUT0, 0xaa },
56         {  8,    3,   2, 2, 0, OUT0, 0xea },
57         {  6,    2,   2, 2, 0, OUT0, 0xaa },
58         {  5,    3,   2, 2, 0, OUT0, 0xaa },
59         {  4,    6,   5, 2, 0, OUT0, 0xea },
60         {  3,    5,   4, 2, 0, OUT0, 0xaa },
61         {  2,   12,  11, 2, 0, OUT0, 0xea },
62         {  1,   24,  23, 2, 0, OUT0, 0xea },
63         { 50,   48,  47, 2, 0, OUT0, 0xea },
64         { 20,  120, 119, 2, 0, OUT0, 0xea },
65         { 10,  240, 239, 2, 0, OUT0, 0xea },
66 };
67
68 /**
69  * The gain stage is 2 stage approach. -6dB and -20dB on the first stage
70  * (attentuator). The second stage is then doing the gain by 3 different
71  * resistor values switched into the feedback loop.
72  *
73  * #Channel 0:
74  * PC1=1; PC2=0; PC3=0 -> Gain x0.1 = -20dB
75  * PC1=1; PC2=0; PC3=1 -> Gain x0.2 = -14dB
76  * PC1=1; PC2=1; PC3=0 -> Gain x0.4 =  -8dB
77  * PC1=0; PC2=0; PC3=0 -> Gain x0.5 =  -6dB
78  * PC1=0; PC2=0; PC3=1 -> Gain x1   =   0dB
79  * PC1=0; PC2=1; PC3=0 -> Gain x2   =  +6dB
80  *
81  * #Channel 1:
82  * PE1=1; PC4=0; PC5=0 -> Gain x0.1 = -20dB 
83  * PE1=1; PC4=0; PC5=1 -> Gain x0.2 = -14dB
84  * PE1=1; PC4=1; PC5=0 -> Gain x0.4 =  -8dB
85  * PE1=0; PC4=0; PC5=0 -> Gain x0.5 =  -6dB
86  * PE1=0; PC4=0; PC5=1 -> Gain x1   =   0dB
87  * PE1=0; PC4=1; PC5=0 -> Gain x2   =  +6dB
88  */
89 static BOOL set_voltage(BYTE channel, BYTE val)
90 {
91         BYTE bits_C, bit_E, mask_C, mask_E;
92
93         if (channel == 0) {
94                 mask_C = 0x0E;
95                 mask_E = 0x00;
96                 bit_E = 0;
97                 switch (val) {
98                 case 1:
99                         bits_C = 0x02;
100                         break;
101                 case 2:
102                         bits_C = 0x06;
103                         break;
104                 case 5:
105                         bits_C = 0x00;
106                         break;
107                 case 10:
108                         bits_C = 0x04;
109                         break;
110                 case 20:
111                         bits_C = 0x08;
112                         break;
113                 default:
114                         return FALSE;
115                 }
116         } else if (channel == 1) {
117                 mask_C = 0x30;
118                 mask_E = 0x02;
119                 switch (val) {
120                 case 1:
121                         bits_C = 0x00;
122                         bit_E = 0x02; 
123                         break;
124                 case 2:
125                         bits_C = 0x10;
126                         bit_E = 0x02; 
127                         break;
128                 case 5:
129                         bits_C = 0x00;
130                         bit_E = 0x00; 
131                         break;
132                 case 10:
133                         bits_C = 0x10;
134                         bit_E = 0x00; 
135                         break;
136                 case 20:
137                         bits_C = 0x20;
138                         bit_E = 0x00; 
139                         break;
140                 default:
141                         return FALSE;
142                 }
143         } else {
144                 return FALSE;
145         }
146         IOC = (IOC & ~mask_C) | (bits_C & mask_C);
147         IOE = (IOE & ~mask_E) | (bit_E & mask_E);
148                 
149         return TRUE;
150 }
151
152 #include <scope.inc>