blob: 90b1d0d8bd73f049eb7e80bf5bd147464462b60c [file] [log] [blame]
Brian Silverman8d3816a2017-07-03 18:52:15 -07001#include "motors/peripheral/adc.h"
2
3#include "motors/core/kinetis.h"
4
5namespace frc971 {
6namespace salsa {
Brian Silverman19ea60f2018-01-03 21:43:15 -08007namespace {
Brian Silverman8d3816a2017-07-03 18:52:15 -07008
9#define ADC_SC2_BASE (ADC_SC2_REFSEL(0) /* Use the external reference pins. */)
10
11#define ADC_FINISH_CALIBRATION(n, PM) \
12 do { \
13 uint16_t variable = 0; \
14 variable += ADC##n##_CL##PM##0; \
15 variable += ADC##n##_CL##PM##1; \
16 variable += ADC##n##_CL##PM##2; \
17 variable += ADC##n##_CL##PM##3; \
18 variable += ADC##n##_CL##PM##4; \
19 variable += ADC##n##_CL##PM##S; \
20 variable /= 2; \
21 variable |= 0x8000; \
22 ADC##n##_##PM##G = variable; \
23 } while (0);
24
25#define ADC_INIT_SINGLE(n) \
26 do { \
27 ADC##n##_CFG1 = ADC_CFG1_ADIV(2) /* Divide clock by 4 to get 15MHz. */ | \
28 ADC_CFG1_MODE(1) /* 12 bit mode. */ | \
29 ADC_CFG1_ADICLK(0) /* Use the bus clock (60MHz). */; \
30 ADC##n##_CFG2 = ADC_CFG2_MUXSEL /* Use the b channels. */ | \
31 ADC_CFG2_ADHSC /* Support higher ADC clock speeds. */; \
32 ADC##n##_SC1A = 0; /* Clear SC1A's COCO flag. */ \
33 ADC##n##_SC2 = ADC_SC2_BASE; \
34 do { \
35 ADC##n##_SC3 = ADC_SC3_CAL | ADC_SC3_AVGE | \
36 ADC_SC3_AVGS(3) /* Average 32 samples (max). */; \
37 /* Wait for calibration to complete. */ \
38 while (!(ADC##n##_SC1A & ADC_SC1_COCO)) { \
39 } \
40 } while (ADC##n##_SC3 & ADC_SC3_CALF); \
41 ADC_FINISH_CALIBRATION(n, P); \
42 ADC_FINISH_CALIBRATION(n, M); \
43 \
44 ADC##n##_SC3 = 0 /* Disable hardware averaging. */; \
45 } while (0)
46
Brian Silverman19ea60f2018-01-03 21:43:15 -080047void AdcInitCommon() {
Brian Silverman8d3816a2017-07-03 18:52:15 -070048 SIM_SCGC3 |= SIM_SCGC3_ADC1;
49 SIM_SCGC6 |= SIM_SCGC6_ADC0;
50 // TODO(Brian): Mess with SIM_SOPT7 to reconfigure ADC trigger input source?
51 ADC_INIT_SINGLE(0);
52 ADC_INIT_SINGLE(1);
Brian Silverman19ea60f2018-01-03 21:43:15 -080053}
Brian Silverman8d3816a2017-07-03 18:52:15 -070054
Brian Silverman19ea60f2018-01-03 21:43:15 -080055} // namespace
56
57void AdcInitMedium() {
58 AdcInitCommon();
59
60 // M_CH2V ADC0_SE14
Brian Silverman8d3816a2017-07-03 18:52:15 -070061 PORTC_PCR0 = PORT_PCR_MUX(0);
62
Brian Silverman19ea60f2018-01-03 21:43:15 -080063 // M_CH0V ADC0_SE13
Brian Silverman8d3816a2017-07-03 18:52:15 -070064 PORTB_PCR3 = PORT_PCR_MUX(0);
65
Brian Silverman19ea60f2018-01-03 21:43:15 -080066 // M_CH1V ADC0_SE12
Brian Silverman8d3816a2017-07-03 18:52:15 -070067 PORTB_PCR2 = PORT_PCR_MUX(0);
68
Brian Silverman19ea60f2018-01-03 21:43:15 -080069 // M_CH0F ADC1_SE14
Brian Silverman8d3816a2017-07-03 18:52:15 -070070 PORTB_PCR10 = PORT_PCR_MUX(0);
71
Brian Silverman19ea60f2018-01-03 21:43:15 -080072 // M_CH1F ADC1_SE15
Brian Silverman8d3816a2017-07-03 18:52:15 -070073 PORTB_PCR11 = PORT_PCR_MUX(0);
74
Brian Silverman19ea60f2018-01-03 21:43:15 -080075 // M_VREF ADC0_SE18
Brian Silverman8d3816a2017-07-03 18:52:15 -070076 PORTE_PCR25 = PORT_PCR_MUX(0);
77
Brian Silverman19ea60f2018-01-03 21:43:15 -080078 // VIN ADC1_SE5B
Brian Silverman8d3816a2017-07-03 18:52:15 -070079 PORTC_PCR9 = PORT_PCR_MUX(0);
80
Brian Silverman19ea60f2018-01-03 21:43:15 -080081 // M_CH2F ADC1_SE17
Brian Silverman8d3816a2017-07-03 18:52:15 -070082 PORTA_PCR17 = PORT_PCR_MUX(0);
83}
84
Brian Silverman19ea60f2018-01-03 21:43:15 -080085void AdcInitSmall() {
86 AdcInitCommon();
87
88 // M0_CH0F ADC1_SE17
89 PORTA_PCR17 = PORT_PCR_MUX(0);
90
91 // M0_CH1F ADC1_SE14
92 PORTB_PCR10 = PORT_PCR_MUX(0);
93
94 // M0_CH2F ADC1_SE15
95 PORTB_PCR11 = PORT_PCR_MUX(0);
96
97 // M0_ABS ADC0_SE5b
98 PORTD_PCR1 = PORT_PCR_MUX(0);
99
100 // M1_CH0F ADC0_SE13
101 PORTB_PCR3 = PORT_PCR_MUX(0);
102
103 // M1_CH1F ADC0_SE12
104 PORTB_PCR2 = PORT_PCR_MUX(0);
105
106 // M1_CH2F ADC0_SE14
107 PORTC_PCR0 = PORT_PCR_MUX(0);
108
109 // M1_ABS ADC0_SE17
110 PORTE_PCR24 = PORT_PCR_MUX(0);
111
112 // WHEEL_ABS ADC0_SE18
113 PORTE_PCR25 = PORT_PCR_MUX(0);
114
115 // VIN ADC1_SE5B
116 PORTC_PCR9 = PORT_PCR_MUX(0);
117}
118
Brian Silverman259c4432018-01-15 14:34:21 -0800119void AdcInitJoystick() {
120 AdcInitCommon();
121
122 // ANALOG0 ADC0_SE5b
123 PORTD_PCR1 = PORT_PCR_MUX(0);
124 // ANALOG1 ADC0_SE14
125 PORTC_PCR0 = PORT_PCR_MUX(0);
126 // ANALOG2 ADC0_SE13
127 PORTB_PCR3 = PORT_PCR_MUX(0);
128 // ANALOG3 ADC0_SE12
129 PORTB_PCR2 = PORT_PCR_MUX(0);
130}
131
Brian Silvermana3a172b2018-03-24 03:53:32 -0400132void AdcInitSimple() {
133 AdcInitCommon();
134
135 // ENC_SIN ADC0_SE23
136 // ENC_COS ADC1_SE23
137}
138
Brian Silverman19ea60f2018-01-03 21:43:15 -0800139MediumAdcReadings AdcReadMedium(const DisableInterrupts &) {
Brian Silverman8d3816a2017-07-03 18:52:15 -0700140 MediumAdcReadings r;
141
142 ADC1_SC1A = 14;
143 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
144 }
145 ADC1_SC1A = 15;
146 r.motor_currents[0][0] = ADC1_RA;
147 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
148 }
149 ADC1_SC1A = 17;
150 ADC0_SC1A = 18;
151 r.motor_currents[1][0] = ADC1_RA;
152 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
153 }
154 ADC1_SC1A = 5;
155 r.motor_currents[2][0] = ADC1_RA;
156 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
157 }
158 r.motor_current_ref = ADC0_RA;
159 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
160 }
161 ADC1_SC1A = 14;
162 r.input_voltage = ADC1_RA;
163 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
164 }
165 ADC1_SC1A = 15;
166 r.motor_currents[0][1] = ADC1_RA;
167 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
168 }
169 ADC1_SC1A = 17;
170 r.motor_currents[1][1] = ADC1_RA;
171 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
172 }
173 r.motor_currents[2][1] = ADC1_RA;
174
175 return r;
176}
177
Brian Silverman19ea60f2018-01-03 21:43:15 -0800178SmallAdcReadings AdcReadSmall0(const DisableInterrupts &) {
179 SmallAdcReadings r;
180
181 ADC1_SC1A = 17;
182 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
183 }
184 ADC1_SC1A = 14;
185 r.currents[0] = ADC1_RA;
186 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
187 }
188 ADC1_SC1A = 15;
189 r.currents[1] = ADC1_RA;
190 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
191 }
192 r.currents[2] = ADC1_RA;
193
194 return r;
195}
196
197SmallAdcReadings AdcReadSmall1(const DisableInterrupts &) {
198 SmallAdcReadings r;
199
200 ADC0_SC1A = 13;
201 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
202 }
203 ADC0_SC1A = 12;
204 r.currents[0] = ADC0_RA;
205 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
206 }
207 ADC0_SC1A = 14;
208 r.currents[1] = ADC0_RA;
209 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
210 }
211 r.currents[2] = ADC0_RA;
212
213 return r;
214}
215
216SmallInitReadings AdcReadSmallInit(const DisableInterrupts &) {
217 SmallInitReadings r;
218
219 ADC0_SC1A = 5;
220 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
221 }
222 ADC0_SC1A = 17;
223 r.motor0_abs = ADC0_RA;
224 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
225 }
226 ADC0_SC1A = 18;
227 r.motor1_abs = ADC0_RA;
228 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
229 }
230 r.wheel_abs = ADC0_RA;
231
232 return r;
233}
234
Brian Silverman259c4432018-01-15 14:34:21 -0800235JoystickAdcReadings AdcReadJoystick(const DisableInterrupts &) {
236 JoystickAdcReadings r;
237
238 ADC0_SC1A = 5;
239 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
240 }
241 ADC0_SC1A = 14;
242 r.analog0 = ADC0_RA;
243 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
244 }
245 ADC0_SC1A = 13;
246 r.analog1 = ADC0_RA;
247 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
248 }
249 ADC0_SC1A = 12;
250 r.analog2 = ADC0_RA;
251 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
252 }
253 r.analog3 = ADC0_RA;
254
255 return r;
256}
257
Brian Silvermana3a172b2018-03-24 03:53:32 -0400258SimpleAdcReadings AdcReadSimple(const DisableInterrupts &) {
259 SimpleAdcReadings r;
260
261 ADC0_SC1A = 23;
262 ADC1_SC1A = 23;
263 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
264 }
265 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
266 }
267 r.sin = ADC0_RA;
268 r.cos = ADC1_RA;
269
270 return r;
271}
272
Brian Silverman8d3816a2017-07-03 18:52:15 -0700273} // namespace salsa
274} // namespace frc971