blob: 9e84a386dbc1efd7e41cbff0a6d8501d48f800d5 [file] [log] [blame]
Luigi Santivetti2e35a2e2019-11-17 22:26:14 +00001/*
2 adc.h - Low level header for exposing ADC (Analog Digital Converter)
3 functionalities
4 Part of Grbl
5
6 Copyright (c) 2019 Luigi Santivetti
7
8 Grbl is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 Grbl is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Grbl. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#ifndef adc_h
23#define adc_h
24
25#define ADC_CHANNEL_00_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(0)) >> 0)
26#define ADC_CHANNEL_01_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(1)) >> 1)
27#define ADC_CHANNEL_02_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(2)) >> 2)
28#define ADC_CHANNEL_03_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(3)) >> 3)
29#define ADC_CHANNEL_04_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(4)) >> 4)
30#define ADC_CHANNEL_05_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(5)) >> 5)
31#define ADC_CHANNEL_06_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(6)) >> 6)
32#define ADC_CHANNEL_07_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(7)) >> 7)
33#define ADC_CHANNEL_08_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(8)) >> 8)
34#define ADC_CHANNEL_09_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(9)) >> 9)
35#define ADC_CHANNEL_10_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(10)) >> 10)
36
37#if DEFAULT_ADC_READINGS > 1
38// ADC ISR callbacks
39 #define ADC_ISR_PFN_SUM_ID 0
40 #define ADC_ISR_PFN_AVR_ID 1
41 #if DEFAULT_ADC_MODE == MODE0
42 #define ADC_ISR_PFN_RST_ID 2
43 #define ADC_ISR_APFN_COUNT 3
44 #else
45 #define ADC_ISR_APFN_COUNT 2
46 #endif
47#endif
48
49// Number of enabled channels
50#define ADC_CHANNELS_ENABLED_COUNT \
51 (ADC_CHANNEL_00_ENABLED + ADC_CHANNEL_01_ENABLED + ADC_CHANNEL_02_ENABLED + \
52 ADC_CHANNEL_03_ENABLED + ADC_CHANNEL_04_ENABLED + ADC_CHANNEL_05_ENABLED + \
53 ADC_CHANNEL_06_ENABLED + ADC_CHANNEL_07_ENABLED + ADC_CHANNEL_08_ENABLED + \
54 ADC_CHANNEL_09_ENABLED + ADC_CHANNEL_10_ENABLED)
55
56// Holding ADC readings
57#if DEFAULT_ADC_RESOLUTION == 8
58 typedef uint8_t adc_value;
59#else
60 typedef uint16_t adc_value;
61#endif
62
63typedef struct _adc_data adc_data;
64
65#ifdef ADC_CONFIG_SYSTEM_ALARM
66 #define ADC_INVALID_RANGE_CHANNEL(NUMBER) \
67 ((!defined(DEFAULT_ADC_RANGE_CHANNEL_ ## NUMBER ## _MIN) || \
68 !defined(DEFAULT_ADC_RANGE_CHANNEL_ ## NUMBER ## _MAX)) || \
69 ((DEFAULT_ADC_RANGE_CHANNEL_ ## NUMBER ## _MIN >> DEFAULT_ADC_RESOLUTION) || \
70 (DEFAULT_ADC_RANGE_CHANNEL_ ## NUMBER ## _MAX >> DEFAULT_ADC_RESOLUTION)))
71
72 #if ADC_CHANNEL_00_ENABLED && ADC_INVALID_RANGE_CHANNEL(0)
73 #error "Invalid ADC00 range"
74 #endif
75 #if ADC_CHANNEL_01_ENABLED && ADC_INVALID_RANGE_CHANNEL(1)
76 #error "Invalid ADC01 range"
77 #endif
78 #if ADC_CHANNEL_02_ENABLED && ADC_INVALID_RANGE_CHANNEL(2)
79 #error "Invalid ADC02 range"
80 #endif
81 #if ADC_CHANNEL_03_ENABLED && ADC_INVALID_RANGE_CHANNEL(3)
82 #error "Invalid ADC03 range"
83 #endif
84 #if ADC_CHANNEL_04_ENABLED && ADC_INVALID_RANGE_CHANNEL(4)
85 #error "Invalid ADC04 range"
86 #endif
87 #if ADC_CHANNEL_05_ENABLED && ADC_INVALID_RANGE_CHANNEL(5)
88 #error "Invalid ADC05 range"
89 #endif
90 #if ADC_CHANNEL_06_ENABLED && ADC_INVALID_RANGE_CHANNEL(6)
91 #error "Invalid ADC06 range"
92 #endif
93 #if ADC_CHANNEL_07_ENABLED && ADC_INVALID_RANGE_CHANNEL(7)
94 #error "Invalid ADC07 range"
95 #endif
96 #if ADC_CHANNEL_08_ENABLED && ADC_INVALID_RANGE_CHANNEL(8)
97 #error "Invalid ADC08 range"
98 #endif
99 #if ADC_CHANNEL_09_ENABLED && ADC_INVALID_RANGE_CHANNEL(9)
100 #error "Invalid ADC09 range"
101 #endif
102 #if ADC_CHANNEL_10_ENABLED && ADC_INVALID_RANGE_CHANNEL(10)
103 #error "Invalid ADC10 range"
104 #endif
105#endif
106
107typedef enum {
108 #if ADC_CHANNEL_00_ENABLED
109 ADC0,
110 #endif
111 #if ADC_CHANNEL_01_ENABLED
112 ADC1,
113 #endif
114 #if ADC_CHANNEL_02_ENABLED
115 ADC2,
116 #endif
117 #if ADC_CHANNEL_03_ENABLED
118 ADC3,
119 #endif
120 #if ADC_CHANNEL_04_ENABLED
121 ADC4,
122 #endif
123 #if ADC_CHANNEL_05_ENABLED
124 ADC5,
125 #endif
126 #if ADC_CHANNEL_06_ENABLED
127 ADC6,
128 #endif
129 #if ADC_CHANNEL_07_ENABLED
130 ADC7,
131 #endif
132 #if ADC_CHANNEL_08_ENABLED
133 ADC8, // Internal temperature
134 #endif
135 #if ADC_CHANNEL_09_ENABLED
136 ADC9, // Minimum voltage
137 #endif
138 #if ADC_CHANNEL_10_ENABLED
139 ADC10, // Bendgap voltage
140 #endif
141} adc_channel;
142
143struct _adc_data {
144 #if DEFAULT_ADC_READINGS > 1
145 // Array of function pointers called back from the ADC ISR and void if-else
146 void (* isr[ADC_ISR_APFN_COUNT])(adc_data *adc);
147
148 // Store partial updates per channel
149 uint16_t sum;
150
151 // Index tracking the current number of reading
152 uint8_t i_r;
153 #endif
154
155 // Index for the current channel to be stored in the buffer
156 volatile adc_channel i_c;
157
158 // Bitmask for the current status. The first 11 bit are reserved, where the
159 // i-bit set to 1 flags the i-th channel is drained and the buffer holds
160 // reliable data. The last 3 bits are for regular ADC ops signalling.
161 volatile uint16_t s;
162
163 // Buffer holding readings per channel
164 struct {
165 volatile adc_value avr;
166 #ifdef ADC_CONFIG_SYSTEM_ALARM
167 adc_value min;
168 adc_value max;
169 #endif
170 } __attribute__ ((packed)) b[ADC_CHANNELS_ENABLED_COUNT];
171} __attribute__ ((packed));
172
173// Setup the ADC with DEFAULTS, enable it and kick a conversion
174void adc_init(adc_data *adc);
175
176// Teardown ADC, need to reinit afterwards
177void adc_deinit(adc_data *adc);
178
179// Read unsigned ADC buffer value for channel
180adc_value adc_read_unsigned(const adc_data *adc, const adc_channel c);
181
182#endif