]> sigrok.org Git - sigrok-firmware-fx2lafw.git/blob - hw/sainsmart-dds120/fw.c
scopes: Move a code comment.
[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 /* Note: There's no PE2 as IOE is not bit-addressable (see TRM 15.2). */
34 #define TOGGLE_CALIBRATION_PIN() IOE = IOE ^ 0x04
35
36 #define LED_CLEAR() NOP
37 #define LED_GREEN() NOP
38 #define LED_RED()   NOP
39
40 #define TIMER2_VAL 1000
41
42 /* CTLx pin index (IFCLK, ADC clock input). */
43 #define CTL_BIT 2
44
45 #define OUT0 ((1 << CTL_BIT) << 4) /* OEx = 1, CTLx = 0 */
46
47 static const struct samplerate_info samplerates[] = {
48         { 48, 0x80,   0, 3, 0, 0x00, 0xea },
49         { 30, 0x80,   0, 3, 0, 0x00, 0xaa },
50         { 24,    1,   0, 2, 1, OUT0, 0xea },
51         { 16,    1,   1, 2, 0, OUT0, 0xea },
52         { 15,    1,   0, 2, 1, OUT0, 0xaa },
53         { 12,    2,   1, 2, 0, OUT0, 0xea },
54         { 11,    1,   1, 2, 0, OUT0, 0xaa },
55         {  8,    3,   2, 2, 0, OUT0, 0xea },
56         {  6,    2,   2, 2, 0, OUT0, 0xaa },
57         {  5,    3,   2, 2, 0, OUT0, 0xaa },
58         {  4,    6,   5, 2, 0, OUT0, 0xea },
59         {  3,    5,   4, 2, 0, OUT0, 0xaa },
60         {  2,   12,  11, 2, 0, OUT0, 0xea },
61         {  1,   24,  23, 2, 0, OUT0, 0xea },
62         { 50,   48,  47, 2, 0, OUT0, 0xea },
63         { 20,  120, 119, 2, 0, OUT0, 0xea },
64         { 10,  240, 239, 2, 0, OUT0, 0xea },
65 };
66
67 /**
68  * The gain stage is 2 stage approach. -6dB and -20dB on the first stage
69  * (attentuator). The second stage is then doing the gain by 3 different
70  * resistor values switched into the feedback loop.
71  *
72  * #Channel 0:
73  * PC1=1; PC2=0; PC3=0 -> Gain x0.1 = -20dB
74  * PC1=1; PC2=0; PC3=1 -> Gain x0.2 = -14dB
75  * PC1=1; PC2=1; PC3=0 -> Gain x0.4 =  -8dB
76  * PC1=0; PC2=0; PC3=0 -> Gain x0.5 =  -6dB
77  * PC1=0; PC2=0; PC3=1 -> Gain x1   =   0dB
78  * PC1=0; PC2=1; PC3=0 -> Gain x2   =  +6dB
79  *
80  * #Channel 1:
81  * PE1=1; PC4=0; PC5=0 -> Gain x0.1 = -20dB 
82  * PE1=1; PC4=0; PC5=1 -> Gain x0.2 = -14dB
83  * PE1=1; PC4=1; PC5=0 -> Gain x0.4 =  -8dB
84  * PE1=0; PC4=0; PC5=0 -> Gain x0.5 =  -6dB
85  * PE1=0; PC4=0; PC5=1 -> Gain x1   =   0dB
86  * PE1=0; PC4=1; PC5=0 -> Gain x2   =  +6dB
87  */
88 static BOOL set_voltage(BYTE channel, BYTE val)
89 {
90         BYTE bits_C, bit_E, mask_C, mask_E;
91
92         if (channel == 0) {
93                 mask_C = 0x0E;
94                 mask_E = 0x00;
95                 bit_E = 0;
96                 switch (val) {
97                 case 1:
98                         bits_C = 0x02;
99                         break;
100                 case 2:
101                         bits_C = 0x06;
102                         break;
103                 case 5:
104                         bits_C = 0x00;
105                         break;
106                 case 10:
107                         bits_C = 0x04;
108                         break;
109                 case 20:
110                         bits_C = 0x08;
111                         break;
112                 default:
113                         return FALSE;
114                 }
115         } else if (channel == 1) {
116                 mask_C = 0x30;
117                 mask_E = 0x02;
118                 switch (val) {
119                 case 1:
120                         bits_C = 0x00;
121                         bit_E = 0x02; 
122                         break;
123                 case 2:
124                         bits_C = 0x10;
125                         bit_E = 0x02; 
126                         break;
127                 case 5:
128                         bits_C = 0x00;
129                         bit_E = 0x00; 
130                         break;
131                 case 10:
132                         bits_C = 0x10;
133                         bit_E = 0x00; 
134                         break;
135                 case 20:
136                         bits_C = 0x20;
137                         bit_E = 0x00; 
138                         break;
139                 default:
140                         return FALSE;
141                 }
142         } else {
143                 return FALSE;
144         }
145         IOC = (IOC & ~mask_C) | (bits_C & mask_C);
146         IOE = (IOE & ~mask_E) | (bit_E & mask_E);
147                 
148         return TRUE;
149 }
150
151 #include <scope.inc>