summaryrefslogtreecommitdiff
path: root/bsp/apollo2/libraries/drivers/hal/am_hal_adc.h
blob: 554e997441b363636111600fc71e0824a6f730d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
//*****************************************************************************
//
//  am_hal_adc.h
//! @file
//!
//! @brief Functions for interfacing with the Analog to Digital Converter
//!
//! @addtogroup adc2 Analog-to-Digital Converter (ADC)
//! @ingroup apollo2hal
//! @{
//
//*****************************************************************************

//*****************************************************************************
//
// Copyright (c) 2017, Ambiq Micro
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// 
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 1.2.11 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_ADC_H
#define AM_HAL_ADC_H

//*****************************************************************************
//
//! @name Clock Selection
//! @brief These macros may be used to set the ADC module's clock source.
//! @{
//
//*****************************************************************************
#define AM_HAL_ADC_CLOCK_OFF                AM_REG_ADC_CFG_CLKSEL_OFF
#define AM_HAL_ADC_CLOCK_HFRC               AM_REG_ADC_CFG_CLKSEL_HFRC
#define AM_HAL_ADC_CLOCK_DIV2               AM_REG_ADC_CFG_CLKSEL_HFRC_DIV2
//! @}

//*****************************************************************************
//
//! @name Trigger Settings
//! @brief ADC trigger setting macros.
//!
//! These macros alter the ADC's trigger source and trigger polarity. Note that
//! the external trigger setting needs to be ORed with a POS or NEG option to
//! define the desired trigger polarity.
//! @{
//
//*****************************************************************************
#define AM_HAL_ADC_TRIGGER_SOFT             AM_REG_ADC_CFG_TRIGSEL_SWT
#define AM_HAL_ADC_TRIGGER_VCOMP            AM_REG_ADC_CFG_TRIGSEL_VCOMP
#define AM_HAL_ADC_TRIGGER_EXT0             AM_REG_ADC_CFG_TRIGSEL_EXT0
#define AM_HAL_ADC_TRIGGER_EXT1             AM_REG_ADC_CFG_TRIGSEL_EXT1
#define AM_HAL_ADC_TRIGGER_EXT2             AM_REG_ADC_CFG_TRIGSEL_EXT2
#define AM_HAL_ADC_TRIGGER_EXT3             AM_REG_ADC_CFG_TRIGSEL_EXT3
#define AM_HAL_ADC_TRIGGER_FALL             AM_REG_ADC_CFG_TRIGPOL_FALLING_EDGE
#define AM_HAL_ADC_TRIGGER_RISE             AM_REG_ADC_CFG_TRIGPOL_RISING_EDGE
//! @}

//*****************************************************************************
//
//! @name Reference Settings
//! @brief ADC reference voltage setting macros.
//!
//! These macros control the ADC reference voltage source.
//! @{
//
//*****************************************************************************
#define AM_HAL_ADC_REF_EXT_2P0              AM_REG_ADC_CFG_REFSEL_EXT2P0
#define AM_HAL_ADC_REF_EXT_1P5              AM_REG_ADC_CFG_REFSEL_EXT1P5
#define AM_HAL_ADC_REF_INT_2P0              AM_REG_ADC_CFG_REFSEL_INT2P0
#define AM_HAL_ADC_REF_INT_1P5              AM_REG_ADC_CFG_REFSEL_INT1P5
//! @}

//*****************************************************************************
//
//! @name Clock Mode
//! @brief ADC clock mode settings
//!
//! These macros determine whether the ADC shuts down its clock between
//! samples. Shutting down the clock will reduce power consumption, but
//! increase latency. This setting is only valid for LPMODE 0. For other modes,
//! it will be ignored.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_ADC_CK_LOW_POWER             AM_REG_ADC_CFG_CKMODE_LPCKMODE
#define AM_HAL_ADC_CK_LOW_LATENCY           AM_REG_ADC_CFG_CKMODE_LLCKMODE
//! @}

//*****************************************************************************
//
//! @name Low Power Mode
//! @brief ADC power conservation settings.
//!
//! These macros select the power state to enter between active scans. Each low
//! power mode has its own set of timing constraints. Please see the datasheet
//! for additional timing information on each power mode.
//! @{
//
//*****************************************************************************
#define AM_HAL_ADC_LPMODE_0                 AM_REG_ADC_CFG_LPMODE_MODE0
#define AM_HAL_ADC_LPMODE_1                 AM_REG_ADC_CFG_LPMODE_MODE1
//! @}

//*****************************************************************************
//
//! @name Repeat Mode
//! @brief Enable repeating scan mode.
//!
//! Use this macro to enable repeating scans using timer 3.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_ADC_REPEAT                   AM_REG_ADC_CFG_RPTEN(1)
#define AM_HAL_ADC_NO_REPEAT                AM_REG_ADC_CFG_RPTEN(0)
//! @}

//*****************************************************************************
//
//! @name Slot configuration
//! @brief Slot configuration macros
//!
//! These macros may be used to configure an individual ADC slot.
//! @{
//
//*****************************************************************************

// Set number of samples to average.
#define AM_HAL_ADC_SLOT_AVG_1               AM_REG_ADC_SL0CFG_ADSEL0(0)
#define AM_HAL_ADC_SLOT_AVG_2               AM_REG_ADC_SL0CFG_ADSEL0(1)
#define AM_HAL_ADC_SLOT_AVG_4               AM_REG_ADC_SL0CFG_ADSEL0(2)
#define AM_HAL_ADC_SLOT_AVG_8               AM_REG_ADC_SL0CFG_ADSEL0(3)
#define AM_HAL_ADC_SLOT_AVG_16              AM_REG_ADC_SL0CFG_ADSEL0(4)
#define AM_HAL_ADC_SLOT_AVG_32              AM_REG_ADC_SL0CFG_ADSEL0(5)
#define AM_HAL_ADC_SLOT_AVG_64              AM_REG_ADC_SL0CFG_ADSEL0(6)
#define AM_HAL_ADC_SLOT_AVG_128             AM_REG_ADC_SL0CFG_ADSEL0(7)

// Set slot precision mode.
#define AM_HAL_ADC_SLOT_14BIT               AM_REG_ADC_SL0CFG_PRMODE0_P14B
#define AM_HAL_ADC_SLOT_12BIT               AM_REG_ADC_SL0CFG_PRMODE0_P14B
#define AM_HAL_ADC_SLOT_10BIT               AM_REG_ADC_SL0CFG_PRMODE0_P14B
#define AM_HAL_ADC_SLOT_8BIT                AM_REG_ADC_SL0CFG_PRMODE0_P14B

// Select a channel by number.
#define AM_HAL_ADC_SLOT_CHANNEL(n)          AM_REG_ADC_SL0CFG_CHSEL0(n)

// Single-ended channels
#define AM_HAL_ADC_SLOT_CHSEL_SE0           AM_REG_ADC_SL0CFG_CHSEL0_SE0
#define AM_HAL_ADC_SLOT_CHSEL_SE1           AM_REG_ADC_SL0CFG_CHSEL0_SE1
#define AM_HAL_ADC_SLOT_CHSEL_SE2           AM_REG_ADC_SL0CFG_CHSEL0_SE2
#define AM_HAL_ADC_SLOT_CHSEL_SE3           AM_REG_ADC_SL0CFG_CHSEL0_SE3
#define AM_HAL_ADC_SLOT_CHSEL_SE4           AM_REG_ADC_SL0CFG_CHSEL0_SE4
#define AM_HAL_ADC_SLOT_CHSEL_SE5           AM_REG_ADC_SL0CFG_CHSEL0_SE5
#define AM_HAL_ADC_SLOT_CHSEL_SE6           AM_REG_ADC_SL0CFG_CHSEL0_SE6
#define AM_HAL_ADC_SLOT_CHSEL_SE7           AM_REG_ADC_SL0CFG_CHSEL0_SE7
#define AM_HAL_ADC_SLOT_CHSEL_SE8           AM_REG_ADC_SL0CFG_CHSEL0_SE8
#define AM_HAL_ADC_SLOT_CHSEL_SE9           AM_REG_ADC_SL0CFG_CHSEL0_SE9

// Differential channels.
#define AM_HAL_ADC_SLOT_CHSEL_DF0           AM_REG_ADC_SL0CFG_CHSEL0_DF0
#define AM_HAL_ADC_SLOT_CHSEL_DF1           AM_REG_ADC_SL0CFG_CHSEL0_DF1

// Miscellaneous other signals.
#define AM_HAL_ADC_SLOT_CHSEL_TEMP          AM_REG_ADC_SL0CFG_CHSEL0_TEMP
#define AM_HAL_ADC_SLOT_CHSEL_VSS           AM_REG_ADC_SL0CFG_CHSEL0_VSS
#define AM_HAL_ADC_SLOT_CHSEL_VBATT         AM_REG_ADC_SL0CFG_CHSEL0_BATT

// Window enable.
#define AM_HAL_ADC_SLOT_WINDOW_EN           AM_REG_ADC_SL0CFG_WCEN0(1)

// Enable the slot.
#define AM_HAL_ADC_SLOT_ENABLE              AM_REG_ADC_SL0CFG_SLEN0(1)
//! @}

//*****************************************************************************
//
//! @name Interrupt Status Bits
//! @brief Interrupt Status Bits for enable/disble use
//!
//! These macros may be used to enable an individual ADC interrupt cause.
//! @{
//
//*****************************************************************************
#define AM_HAL_ADC_INT_WCINC              AM_REG_ADC_INTEN_WCINC(1)
#define AM_HAL_ADC_INT_WCEXC              AM_REG_ADC_INTEN_WCEXC(1)
#define AM_HAL_ADC_INT_FIFOOVR2           AM_REG_ADC_INTEN_FIFOOVR2(1)
#define AM_HAL_ADC_INT_FIFOOVR1           AM_REG_ADC_INTEN_FIFOOVR1(1)
#define AM_HAL_ADC_INT_SCNCMP             AM_REG_ADC_INTEN_SCNCMP(1)
#define AM_HAL_ADC_INT_CNVCMP             AM_REG_ADC_INTEN_CNVCMP(1)
//! @}

//*****************************************************************************
//
//! @name Temperature Trim Value Locations
//! @brief Temperature calibration cofficients are stored in readable space.
//!
//! These macros are used to access the temperature trim values in readable
//! space.
//! @{
//
//*****************************************************************************
#define AM_HAL_ADC_CALIB_TEMP_ADDR          (0x50023010)
#define AM_HAL_ADC_CALIB_AMBIENT_ADDR       (0x50023014)
#define AM_HAL_ADC_CALIB_ADC_OFFSET_ADDR    (0x50023018)

//
// Default coefficients (used when trims not provided):
//  TEMP_DEFAULT    = Temperature in deg K (e.g. 299.5 - 273.15 = 26.35)
//  AMBIENT_DEFAULT = Voltage measurement at default temperature.
//  OFFSET_DEFAULT  = Default ADC offset at 1v.
//
#define AM_HAL_ADC_CALIB_TEMP_DEFAULT       (299.5F)
#define AM_HAL_ADC_CALIB_AMBIENT_DEFAULT    (1.02809F)
#define AM_HAL_ADC_CALIB_ADC_OFFSET_DEFAULT (-0.004281F)
//! @}

//*****************************************************************************
//
//! @brief Configuration structure for the ADC.
//
//*****************************************************************************
typedef struct
{
    //! Select the ADC Clock source using one of the clock source macros.
    uint32_t ui32Clock;

    //! Select the ADC trigger source using a trigger source macro.
    uint32_t ui32TriggerConfig;

    //! Use a macro to select the ADC reference voltage.
    uint32_t ui32Reference;

    //! Use a macro to decide whether to disable clocks between samples.
    uint32_t ui32ClockMode;

    //! Use a macro to select the ADC power mode.
    uint32_t ui32PowerMode;

    //! Select whether the ADC will re-trigger based on a signal from timer 3.
    uint32_t ui32Repeat;
}
am_hal_adc_config_t;

//*****************************************************************************
//
//! @brief ADC Fifo Read macros
//!
//! These are helper macros for interpreting FIFO data. Each ADC FIFO entry
//! contains information about the slot number and the FIFO depth alongside the
//! current sample. These macros perform the correct masking and shifting to
//! read those values.
//!
//! The SAMPLE and FULL_SAMPLE options refer to the fractional part of averaged
//! samples. If you are not using hardware averaging or don't need the
//! fractional part of the ADC sample, you should just use
//! AM_HAL_ADC_FIFO_SAMPLE.
//!
//! If you do need the fractional part, use AM_HAL_ADC_FIFO_FULL_SAMPLE. This
//! macro will keep six bits of precision past the decimal point. Depending on
//! the number of averaged samples, anywhere between 1 and 6 of these bits will
//! be valid. Please consult the datasheet to find out how many bits of data
//! are valid for your chosen averaging settings.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_ADC_FIFO_SAMPLE(value)                                         \
    ((((value) & AM_REG_ADC_FIFO_DATA_M) >> AM_REG_ADC_FIFO_DATA_S) >> 6)

#define AM_HAL_ADC_FIFO_FULL_SAMPLE(value)                                    \
    (((value) & AM_REG_ADC_FIFO_DATA_M) >> AM_REG_ADC_FIFO_DATA_S )

#define AM_HAL_ADC_FIFO_SLOT(value)                                           \
    (((value) & AM_REG_ADC_FIFO_SLOTNUM_M) >> AM_REG_ADC_FIFO_SLOTNUM_S)

#define AM_HAL_ADC_FIFO_COUNT(value)                                          \
    (((value) & AM_REG_ADC_FIFO_COUNT_M) >> AM_REG_ADC_FIFO_COUNT_S)
//! @}

#ifdef __cplusplus
extern "C"
{
#endif

//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void am_hal_adc_config(am_hal_adc_config_t *psConfig);
extern void am_hal_adc_window_set(uint32_t ui32Upper, uint32_t ui32Lower);
extern void am_hal_adc_slot_config(uint32_t ui32SlotNumber,
                                   uint32_t ui32SlotConfig);

extern uint32_t am_hal_adc_fifo_peek(void);
extern uint32_t am_hal_adc_fifo_pop(void);

extern void am_hal_adc_trigger(void);
extern void am_hal_adc_enable(void);
extern void am_hal_adc_disable(void);
extern void am_hal_adc_int_enable(uint32_t ui32Interrupt);
extern uint32_t am_hal_adc_int_enable_get(void);
extern void am_hal_adc_int_disable(uint32_t ui32Interrupt);
extern void am_hal_adc_int_clear(uint32_t ui32Interrupt);
extern void am_hal_adc_int_set(uint32_t ui32Interrupt);
extern uint32_t am_hal_adc_int_status_get(bool bEnabledOnly);
extern float am_hal_adc_volts_to_celsius(float fVoltage);
extern void am_hal_adc_temp_trims_get(float * pfTemp, float * pfVoltage, float * pfOffsetV);

#ifdef __cplusplus
}
#endif

#endif // AM_HAL_ADC_H

//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************