blob: ba2b247b0373631d2b569c21b8e88253af881d95 [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 {
7
8#define ADC_SC2_BASE (ADC_SC2_REFSEL(0) /* Use the external reference pins. */)
9
10#define ADC_FINISH_CALIBRATION(n, PM) \
11 do { \
12 uint16_t variable = 0; \
13 variable += ADC##n##_CL##PM##0; \
14 variable += ADC##n##_CL##PM##1; \
15 variable += ADC##n##_CL##PM##2; \
16 variable += ADC##n##_CL##PM##3; \
17 variable += ADC##n##_CL##PM##4; \
18 variable += ADC##n##_CL##PM##S; \
19 variable /= 2; \
20 variable |= 0x8000; \
21 ADC##n##_##PM##G = variable; \
22 } while (0);
23
24#define ADC_INIT_SINGLE(n) \
25 do { \
26 ADC##n##_CFG1 = ADC_CFG1_ADIV(2) /* Divide clock by 4 to get 15MHz. */ | \
27 ADC_CFG1_MODE(1) /* 12 bit mode. */ | \
28 ADC_CFG1_ADICLK(0) /* Use the bus clock (60MHz). */; \
29 ADC##n##_CFG2 = ADC_CFG2_MUXSEL /* Use the b channels. */ | \
30 ADC_CFG2_ADHSC /* Support higher ADC clock speeds. */; \
31 ADC##n##_SC1A = 0; /* Clear SC1A's COCO flag. */ \
32 ADC##n##_SC2 = ADC_SC2_BASE; \
33 do { \
34 ADC##n##_SC3 = ADC_SC3_CAL | ADC_SC3_AVGE | \
35 ADC_SC3_AVGS(3) /* Average 32 samples (max). */; \
36 /* Wait for calibration to complete. */ \
37 while (!(ADC##n##_SC1A & ADC_SC1_COCO)) { \
38 } \
39 } while (ADC##n##_SC3 & ADC_SC3_CALF); \
40 ADC_FINISH_CALIBRATION(n, P); \
41 ADC_FINISH_CALIBRATION(n, M); \
42 \
43 ADC##n##_SC3 = 0 /* Disable hardware averaging. */; \
44 } while (0)
45
46void AdcInit() {
47 SIM_SCGC3 |= SIM_SCGC3_ADC1;
48 SIM_SCGC6 |= SIM_SCGC6_ADC0;
49 // TODO(Brian): Mess with SIM_SOPT7 to reconfigure ADC trigger input source?
50 ADC_INIT_SINGLE(0);
51 ADC_INIT_SINGLE(1);
52
53 // M_CH2V/M1_CH2F ADC0_SE14
54 PORTC_PCR0 = PORT_PCR_MUX(0);
55
56 // M_CH0V/M1_CH0F ADC0_SE13
57 PORTB_PCR3 = PORT_PCR_MUX(0);
58
59 // M_CH1V/M1_CH1F ADC0_SE12
60 PORTB_PCR2 = PORT_PCR_MUX(0);
61
62 // M0_CH0F/M_CH0F ADC1_SE14
63 PORTB_PCR10 = PORT_PCR_MUX(0);
64
65 // M0_CH1F/M_CH1F ADC1_SE15
66 PORTB_PCR11 = PORT_PCR_MUX(0);
67
68 // WHEEL_ABS/M_VREF ADC0_SE18
69 PORTE_PCR25 = PORT_PCR_MUX(0);
70
71 // VIN/VIN ADC1_SE5B
72 PORTC_PCR9 = PORT_PCR_MUX(0);
73
74 // M0_CH2F/M_CH2F ADC1_SE17
75 PORTA_PCR17 = PORT_PCR_MUX(0);
76}
77
78MediumAdcReadings AdcReadMedium() {
79 MediumAdcReadings r;
80
81 ADC1_SC1A = 14;
82 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
83 }
84 ADC1_SC1A = 15;
85 r.motor_currents[0][0] = ADC1_RA;
86 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
87 }
88 ADC1_SC1A = 17;
89 ADC0_SC1A = 18;
90 r.motor_currents[1][0] = ADC1_RA;
91 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
92 }
93 ADC1_SC1A = 5;
94 r.motor_currents[2][0] = ADC1_RA;
95 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
96 }
97 r.motor_current_ref = ADC0_RA;
98 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
99 }
100 ADC1_SC1A = 14;
101 r.input_voltage = ADC1_RA;
102 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
103 }
104 ADC1_SC1A = 15;
105 r.motor_currents[0][1] = ADC1_RA;
106 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
107 }
108 ADC1_SC1A = 17;
109 r.motor_currents[1][1] = ADC1_RA;
110 while (!(ADC1_SC1A & ADC_SC1_COCO)) {
111 }
112 r.motor_currents[2][1] = ADC1_RA;
113
114 return r;
115}
116
117} // namespace salsa
118} // namespace frc971