blob: 11a91ffc5064c0bc587fa0a9058de06e41d0cb4d [file] [log] [blame]
Brian Silverman8d3816a2017-07-03 18:52:15 -07001#include "motors/peripheral/adc.h"
2
3#include "motors/core/kinetis.h"
4
Stephan Pleinesf63bde82024-01-13 15:59:33 -08005namespace frc971::motors {
Brian Silverman19ea60f2018-01-03 21:43:15 -08006namespace {
Brian Silverman8d3816a2017-07-03 18:52:15 -07007
Philipp Schrader790cb542023-07-05 21:06:52 -07008#define ADC_SC2_BASE \
9 (ADC_SC2_REFSEL(0) /* Use the external reference pins. \
10 */)
Brian Silverman8d3816a2017-07-03 18:52:15 -070011
12#define ADC_FINISH_CALIBRATION(n, PM) \
13 do { \
14 uint16_t variable = 0; \
15 variable += ADC##n##_CL##PM##0; \
16 variable += ADC##n##_CL##PM##1; \
17 variable += ADC##n##_CL##PM##2; \
18 variable += ADC##n##_CL##PM##3; \
19 variable += ADC##n##_CL##PM##4; \
20 variable += ADC##n##_CL##PM##S; \
21 variable /= 2; \
22 variable |= 0x8000; \
23 ADC##n##_##PM##G = variable; \
24 } while (0);
25
Brian Silverman45564a82018-09-02 16:35:22 -070026#define ADC_INIT_SINGLE(n, maybe_muxsel) \
Brian Silverman8d3816a2017-07-03 18:52:15 -070027 do { \
Brian Silverman45564a82018-09-02 16:35:22 -070028 ADC##n##_CFG1 = \
29 ADC_CFG1_ADIV(2) /* Divide clock by 4 to get 15MHz. */ | \
30 0 /* !ADLSMP to sample faster */ | \
31 ADC_CFG1_MODE(1) /* 12 bit single-ended or 13-bit differential. */ | \
32 ADC_CFG1_ADICLK(0) /* Use the bus clock (60MHz). */; \
33 ADC##n##_CFG2 = (maybe_muxsel) | \
Brian Silverman8d3816a2017-07-03 18:52:15 -070034 ADC_CFG2_ADHSC /* Support higher ADC clock speeds. */; \
35 ADC##n##_SC1A = 0; /* Clear SC1A's COCO flag. */ \
36 ADC##n##_SC2 = ADC_SC2_BASE; \
37 do { \
38 ADC##n##_SC3 = ADC_SC3_CAL | ADC_SC3_AVGE | \
39 ADC_SC3_AVGS(3) /* Average 32 samples (max). */; \
40 /* Wait for calibration to complete. */ \
41 while (!(ADC##n##_SC1A & ADC_SC1_COCO)) { \
42 } \
43 } while (ADC##n##_SC3 & ADC_SC3_CALF); \
44 ADC_FINISH_CALIBRATION(n, P); \
45 ADC_FINISH_CALIBRATION(n, M); \
46 \
47 ADC##n##_SC3 = 0 /* Disable hardware averaging. */; \
48 } while (0)
49
Brian Silverman9ed2cf12018-05-12 13:06:38 -070050} // namespace
51
Brian Silverman45564a82018-09-02 16:35:22 -070052void AdcInitCommon(AdcChannels adc0_channels, AdcChannels adc1_channels) {
Brian Silverman8d3816a2017-07-03 18:52:15 -070053 SIM_SCGC3 |= SIM_SCGC3_ADC1;
54 SIM_SCGC6 |= SIM_SCGC6_ADC0;
55 // TODO(Brian): Mess with SIM_SOPT7 to reconfigure ADC trigger input source?
Brian Silverman45564a82018-09-02 16:35:22 -070056 ADC_INIT_SINGLE(0, (adc0_channels == AdcChannels::kB) ? ADC_CFG2_MUXSEL : 0);
57 ADC_INIT_SINGLE(1, (adc1_channels == AdcChannels::kB) ? ADC_CFG2_MUXSEL : 0);
Brian Silverman19ea60f2018-01-03 21:43:15 -080058}
Brian Silverman8d3816a2017-07-03 18:52:15 -070059
Stephan Pleinesf63bde82024-01-13 15:59:33 -080060} // namespace frc971::motors