1 //*****************************************************************************
2 //
3 //  am_hal_adc.h
4 //! @file
5 //!
6 //! @brief Functions for interfacing with the Analog to Digital Converter
7 //!
8 //! @addtogroup adc2 Analog-to-Digital Converter (ADC)
9 //! @ingroup apollo2hal
10 //! @{
11 //
12 //*****************************************************************************
13 
14 //*****************************************************************************
15 //
16 // Copyright (c) 2017, Ambiq Micro
17 // All rights reserved.
18 //
19 // Redistribution and use in source and binary forms, with or without
20 // modification, are permitted provided that the following conditions are met:
21 //
22 // 1. Redistributions of source code must retain the above copyright notice,
23 // this list of conditions and the following disclaimer.
24 //
25 // 2. Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // 3. Neither the name of the copyright holder nor the names of its
30 // contributors may be used to endorse or promote products derived from this
31 // software without specific prior written permission.
32 //
33 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
34 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
37 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 // POSSIBILITY OF SUCH DAMAGE.
44 //
45 // This is part of revision 1.2.11 of the AmbiqSuite Development Package.
46 //
47 //*****************************************************************************
48 #ifndef AM_HAL_ADC_H
49 #define AM_HAL_ADC_H
50 
51 //*****************************************************************************
52 //
53 //! @name Clock Selection
54 //! @brief These macros may be used to set the ADC module's clock source.
55 //! @{
56 //
57 //*****************************************************************************
58 #define AM_HAL_ADC_CLOCK_OFF                AM_REG_ADC_CFG_CLKSEL_OFF
59 #define AM_HAL_ADC_CLOCK_HFRC               AM_REG_ADC_CFG_CLKSEL_HFRC
60 #define AM_HAL_ADC_CLOCK_DIV2               AM_REG_ADC_CFG_CLKSEL_HFRC_DIV2
61 //! @}
62 
63 //*****************************************************************************
64 //
65 //! @name Trigger Settings
66 //! @brief ADC trigger setting macros.
67 //!
68 //! These macros alter the ADC's trigger source and trigger polarity. Note that
69 //! the external trigger setting needs to be ORed with a POS or NEG option to
70 //! define the desired trigger polarity.
71 //! @{
72 //
73 //*****************************************************************************
74 #define AM_HAL_ADC_TRIGGER_SOFT             AM_REG_ADC_CFG_TRIGSEL_SWT
75 #define AM_HAL_ADC_TRIGGER_VCOMP            AM_REG_ADC_CFG_TRIGSEL_VCOMP
76 #define AM_HAL_ADC_TRIGGER_EXT0             AM_REG_ADC_CFG_TRIGSEL_EXT0
77 #define AM_HAL_ADC_TRIGGER_EXT1             AM_REG_ADC_CFG_TRIGSEL_EXT1
78 #define AM_HAL_ADC_TRIGGER_EXT2             AM_REG_ADC_CFG_TRIGSEL_EXT2
79 #define AM_HAL_ADC_TRIGGER_EXT3             AM_REG_ADC_CFG_TRIGSEL_EXT3
80 #define AM_HAL_ADC_TRIGGER_FALL             AM_REG_ADC_CFG_TRIGPOL_FALLING_EDGE
81 #define AM_HAL_ADC_TRIGGER_RISE             AM_REG_ADC_CFG_TRIGPOL_RISING_EDGE
82 //! @}
83 
84 //*****************************************************************************
85 //
86 //! @name Reference Settings
87 //! @brief ADC reference voltage setting macros.
88 //!
89 //! These macros control the ADC reference voltage source.
90 //! @{
91 //
92 //*****************************************************************************
93 #define AM_HAL_ADC_REF_EXT_2P0              AM_REG_ADC_CFG_REFSEL_EXT2P0
94 #define AM_HAL_ADC_REF_EXT_1P5              AM_REG_ADC_CFG_REFSEL_EXT1P5
95 #define AM_HAL_ADC_REF_INT_2P0              AM_REG_ADC_CFG_REFSEL_INT2P0
96 #define AM_HAL_ADC_REF_INT_1P5              AM_REG_ADC_CFG_REFSEL_INT1P5
97 //! @}
98 
99 //*****************************************************************************
100 //
101 //! @name Clock Mode
102 //! @brief ADC clock mode settings
103 //!
104 //! These macros determine whether the ADC shuts down its clock between
105 //! samples. Shutting down the clock will reduce power consumption, but
106 //! increase latency. This setting is only valid for LPMODE 0. For other modes,
107 //! it will be ignored.
108 //!
109 //! @{
110 //
111 //*****************************************************************************
112 #define AM_HAL_ADC_CK_LOW_POWER             AM_REG_ADC_CFG_CKMODE_LPCKMODE
113 #define AM_HAL_ADC_CK_LOW_LATENCY           AM_REG_ADC_CFG_CKMODE_LLCKMODE
114 //! @}
115 
116 //*****************************************************************************
117 //
118 //! @name Low Power Mode
119 //! @brief ADC power conservation settings.
120 //!
121 //! These macros select the power state to enter between active scans. Each low
122 //! power mode has its own set of timing constraints. Please see the datasheet
123 //! for additional timing information on each power mode.
124 //! @{
125 //
126 //*****************************************************************************
127 #define AM_HAL_ADC_LPMODE_0                 AM_REG_ADC_CFG_LPMODE_MODE0
128 #define AM_HAL_ADC_LPMODE_1                 AM_REG_ADC_CFG_LPMODE_MODE1
129 //! @}
130 
131 //*****************************************************************************
132 //
133 //! @name Repeat Mode
134 //! @brief Enable repeating scan mode.
135 //!
136 //! Use this macro to enable repeating scans using timer 3.
137 //!
138 //! @{
139 //
140 //*****************************************************************************
141 #define AM_HAL_ADC_REPEAT                   AM_REG_ADC_CFG_RPTEN(1)
142 #define AM_HAL_ADC_NO_REPEAT                AM_REG_ADC_CFG_RPTEN(0)
143 //! @}
144 
145 //*****************************************************************************
146 //
147 //! @name Slot configuration
148 //! @brief Slot configuration macros
149 //!
150 //! These macros may be used to configure an individual ADC slot.
151 //! @{
152 //
153 //*****************************************************************************
154 
155 // Set number of samples to average.
156 #define AM_HAL_ADC_SLOT_AVG_1               AM_REG_ADC_SL0CFG_ADSEL0(0)
157 #define AM_HAL_ADC_SLOT_AVG_2               AM_REG_ADC_SL0CFG_ADSEL0(1)
158 #define AM_HAL_ADC_SLOT_AVG_4               AM_REG_ADC_SL0CFG_ADSEL0(2)
159 #define AM_HAL_ADC_SLOT_AVG_8               AM_REG_ADC_SL0CFG_ADSEL0(3)
160 #define AM_HAL_ADC_SLOT_AVG_16              AM_REG_ADC_SL0CFG_ADSEL0(4)
161 #define AM_HAL_ADC_SLOT_AVG_32              AM_REG_ADC_SL0CFG_ADSEL0(5)
162 #define AM_HAL_ADC_SLOT_AVG_64              AM_REG_ADC_SL0CFG_ADSEL0(6)
163 #define AM_HAL_ADC_SLOT_AVG_128             AM_REG_ADC_SL0CFG_ADSEL0(7)
164 
165 // Set slot precision mode.
166 #define AM_HAL_ADC_SLOT_14BIT               AM_REG_ADC_SL0CFG_PRMODE0_P14B
167 #define AM_HAL_ADC_SLOT_12BIT               AM_REG_ADC_SL0CFG_PRMODE0_P14B
168 #define AM_HAL_ADC_SLOT_10BIT               AM_REG_ADC_SL0CFG_PRMODE0_P14B
169 #define AM_HAL_ADC_SLOT_8BIT                AM_REG_ADC_SL0CFG_PRMODE0_P14B
170 
171 // Select a channel by number.
172 #define AM_HAL_ADC_SLOT_CHANNEL(n)          AM_REG_ADC_SL0CFG_CHSEL0(n)
173 
174 // Single-ended channels
175 #define AM_HAL_ADC_SLOT_CHSEL_SE0           AM_REG_ADC_SL0CFG_CHSEL0_SE0
176 #define AM_HAL_ADC_SLOT_CHSEL_SE1           AM_REG_ADC_SL0CFG_CHSEL0_SE1
177 #define AM_HAL_ADC_SLOT_CHSEL_SE2           AM_REG_ADC_SL0CFG_CHSEL0_SE2
178 #define AM_HAL_ADC_SLOT_CHSEL_SE3           AM_REG_ADC_SL0CFG_CHSEL0_SE3
179 #define AM_HAL_ADC_SLOT_CHSEL_SE4           AM_REG_ADC_SL0CFG_CHSEL0_SE4
180 #define AM_HAL_ADC_SLOT_CHSEL_SE5           AM_REG_ADC_SL0CFG_CHSEL0_SE5
181 #define AM_HAL_ADC_SLOT_CHSEL_SE6           AM_REG_ADC_SL0CFG_CHSEL0_SE6
182 #define AM_HAL_ADC_SLOT_CHSEL_SE7           AM_REG_ADC_SL0CFG_CHSEL0_SE7
183 #define AM_HAL_ADC_SLOT_CHSEL_SE8           AM_REG_ADC_SL0CFG_CHSEL0_SE8
184 #define AM_HAL_ADC_SLOT_CHSEL_SE9           AM_REG_ADC_SL0CFG_CHSEL0_SE9
185 
186 // Differential channels.
187 #define AM_HAL_ADC_SLOT_CHSEL_DF0           AM_REG_ADC_SL0CFG_CHSEL0_DF0
188 #define AM_HAL_ADC_SLOT_CHSEL_DF1           AM_REG_ADC_SL0CFG_CHSEL0_DF1
189 
190 // Miscellaneous other signals.
191 #define AM_HAL_ADC_SLOT_CHSEL_TEMP          AM_REG_ADC_SL0CFG_CHSEL0_TEMP
192 #define AM_HAL_ADC_SLOT_CHSEL_VSS           AM_REG_ADC_SL0CFG_CHSEL0_VSS
193 #define AM_HAL_ADC_SLOT_CHSEL_VBATT         AM_REG_ADC_SL0CFG_CHSEL0_BATT
194 
195 // Window enable.
196 #define AM_HAL_ADC_SLOT_WINDOW_EN           AM_REG_ADC_SL0CFG_WCEN0(1)
197 
198 // Enable the slot.
199 #define AM_HAL_ADC_SLOT_ENABLE              AM_REG_ADC_SL0CFG_SLEN0(1)
200 //! @}
201 
202 //*****************************************************************************
203 //
204 //! @name Interrupt Status Bits
205 //! @brief Interrupt Status Bits for enable/disble use
206 //!
207 //! These macros may be used to enable an individual ADC interrupt cause.
208 //! @{
209 //
210 //*****************************************************************************
211 #define AM_HAL_ADC_INT_WCINC              AM_REG_ADC_INTEN_WCINC(1)
212 #define AM_HAL_ADC_INT_WCEXC              AM_REG_ADC_INTEN_WCEXC(1)
213 #define AM_HAL_ADC_INT_FIFOOVR2           AM_REG_ADC_INTEN_FIFOOVR2(1)
214 #define AM_HAL_ADC_INT_FIFOOVR1           AM_REG_ADC_INTEN_FIFOOVR1(1)
215 #define AM_HAL_ADC_INT_SCNCMP             AM_REG_ADC_INTEN_SCNCMP(1)
216 #define AM_HAL_ADC_INT_CNVCMP             AM_REG_ADC_INTEN_CNVCMP(1)
217 //! @}
218 
219 //*****************************************************************************
220 //
221 //! @name Temperature Trim Value Locations
222 //! @brief Temperature calibration cofficients are stored in readable space.
223 //!
224 //! These macros are used to access the temperature trim values in readable
225 //! space.
226 //! @{
227 //
228 //*****************************************************************************
229 #define AM_HAL_ADC_CALIB_TEMP_ADDR          (0x50023010)
230 #define AM_HAL_ADC_CALIB_AMBIENT_ADDR       (0x50023014)
231 #define AM_HAL_ADC_CALIB_ADC_OFFSET_ADDR    (0x50023018)
232 
233 //
234 // Default coefficients (used when trims not provided):
235 //  TEMP_DEFAULT    = Temperature in deg K (e.g. 299.5 - 273.15 = 26.35)
236 //  AMBIENT_DEFAULT = Voltage measurement at default temperature.
237 //  OFFSET_DEFAULT  = Default ADC offset at 1v.
238 //
239 #define AM_HAL_ADC_CALIB_TEMP_DEFAULT       (299.5F)
240 #define AM_HAL_ADC_CALIB_AMBIENT_DEFAULT    (1.02809F)
241 #define AM_HAL_ADC_CALIB_ADC_OFFSET_DEFAULT (-0.004281F)
242 //! @}
243 
244 //*****************************************************************************
245 //
246 //! @brief Configuration structure for the ADC.
247 //
248 //*****************************************************************************
249 typedef struct
250 {
251     //! Select the ADC Clock source using one of the clock source macros.
252     uint32_t ui32Clock;
253 
254     //! Select the ADC trigger source using a trigger source macro.
255     uint32_t ui32TriggerConfig;
256 
257     //! Use a macro to select the ADC reference voltage.
258     uint32_t ui32Reference;
259 
260     //! Use a macro to decide whether to disable clocks between samples.
261     uint32_t ui32ClockMode;
262 
263     //! Use a macro to select the ADC power mode.
264     uint32_t ui32PowerMode;
265 
266     //! Select whether the ADC will re-trigger based on a signal from timer 3.
267     uint32_t ui32Repeat;
268 }
269 am_hal_adc_config_t;
270 
271 //*****************************************************************************
272 //
273 //! @brief ADC Fifo Read macros
274 //!
275 //! These are helper macros for interpreting FIFO data. Each ADC FIFO entry
276 //! contains information about the slot number and the FIFO depth alongside the
277 //! current sample. These macros perform the correct masking and shifting to
278 //! read those values.
279 //!
280 //! The SAMPLE and FULL_SAMPLE options refer to the fractional part of averaged
281 //! samples. If you are not using hardware averaging or don't need the
282 //! fractional part of the ADC sample, you should just use
283 //! AM_HAL_ADC_FIFO_SAMPLE.
284 //!
285 //! If you do need the fractional part, use AM_HAL_ADC_FIFO_FULL_SAMPLE. This
286 //! macro will keep six bits of precision past the decimal point. Depending on
287 //! the number of averaged samples, anywhere between 1 and 6 of these bits will
288 //! be valid. Please consult the datasheet to find out how many bits of data
289 //! are valid for your chosen averaging settings.
290 //!
291 //! @{
292 //
293 //*****************************************************************************
294 #define AM_HAL_ADC_FIFO_SAMPLE(value)                                         \
295     ((((value) & AM_REG_ADC_FIFO_DATA_M) >> AM_REG_ADC_FIFO_DATA_S) >> 6)
296 
297 #define AM_HAL_ADC_FIFO_FULL_SAMPLE(value)                                    \
298     (((value) & AM_REG_ADC_FIFO_DATA_M) >> AM_REG_ADC_FIFO_DATA_S )
299 
300 #define AM_HAL_ADC_FIFO_SLOT(value)                                           \
301     (((value) & AM_REG_ADC_FIFO_SLOTNUM_M) >> AM_REG_ADC_FIFO_SLOTNUM_S)
302 
303 #define AM_HAL_ADC_FIFO_COUNT(value)                                          \
304     (((value) & AM_REG_ADC_FIFO_COUNT_M) >> AM_REG_ADC_FIFO_COUNT_S)
305 //! @}
306 
307 #ifdef __cplusplus
308 extern "C"
309 {
310 #endif
311 
312 //*****************************************************************************
313 //
314 // External function definitions
315 //
316 //*****************************************************************************
317 extern void am_hal_adc_config(am_hal_adc_config_t *psConfig);
318 extern void am_hal_adc_window_set(uint32_t ui32Upper, uint32_t ui32Lower);
319 extern void am_hal_adc_slot_config(uint32_t ui32SlotNumber,
320                                    uint32_t ui32SlotConfig);
321 
322 extern uint32_t am_hal_adc_fifo_peek(void);
323 extern uint32_t am_hal_adc_fifo_pop(void);
324 
325 extern void am_hal_adc_trigger(void);
326 extern void am_hal_adc_enable(void);
327 extern void am_hal_adc_disable(void);
328 extern void am_hal_adc_int_enable(uint32_t ui32Interrupt);
329 extern uint32_t am_hal_adc_int_enable_get(void);
330 extern void am_hal_adc_int_disable(uint32_t ui32Interrupt);
331 extern void am_hal_adc_int_clear(uint32_t ui32Interrupt);
332 extern void am_hal_adc_int_set(uint32_t ui32Interrupt);
333 extern uint32_t am_hal_adc_int_status_get(bool bEnabledOnly);
334 extern float am_hal_adc_volts_to_celsius(float fVoltage);
335 extern void am_hal_adc_temp_trims_get(float * pfTemp, float * pfVoltage, float * pfOffsetV);
336 
337 #ifdef __cplusplus
338 }
339 #endif
340 
341 #endif // AM_HAL_ADC_H
342 
343 //*****************************************************************************
344 //
345 // End Doxygen group.
346 //! @}
347 //
348 //*****************************************************************************
349