aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/os/hal/ports/MSP430X/hal_adc_lld.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios-contrib/os/hal/ports/MSP430X/hal_adc_lld.h')
-rw-r--r--lib/chibios-contrib/os/hal/ports/MSP430X/hal_adc_lld.h516
1 files changed, 516 insertions, 0 deletions
diff --git a/lib/chibios-contrib/os/hal/ports/MSP430X/hal_adc_lld.h b/lib/chibios-contrib/os/hal/ports/MSP430X/hal_adc_lld.h
new file mode 100644
index 000000000..21d9e17ad
--- /dev/null
+++ b/lib/chibios-contrib/os/hal/ports/MSP430X/hal_adc_lld.h
@@ -0,0 +1,516 @@
1/*
2 ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file hal_adc_lld.h
19 * @brief MSP430X ADC subsystem low level driver header.
20 *
21 * @addtogroup ADC
22 * @{
23 */
24
25#ifndef HAL_ADC_LLD_H
26#define HAL_ADC_LLD_H
27
28#if (HAL_USE_ADC == TRUE) || defined(__DOXYGEN__)
29
30/*===========================================================================*/
31/* Driver constants. */
32/*===========================================================================*/
33
34/**
35 * @name Sampling rates
36 * @{
37 */
38typedef enum {
39 MSP430X_ADC_SHT_4 = 0x0000,
40 MSP430X_ADC_SHT_8 = 0x1100,
41 MSP430X_ADC_SHT_16 = 0x2200,
42 MSP430X_ADC_SHT_32 = 0x3300,
43 MSP430X_ADC_SHT_64 = 0x4400,
44 MSP430X_ADC_SHT_96 = 0x5500,
45 MSP430X_ADC_SHT_128 = 0x6600,
46 MSP430X_ADC_SHT_192 = 0x7700,
47 MSP430X_ADC_SHT_256 = 0x8800,
48 MSP430X_ADC_SHT_384 = 0x9900,
49 MSP430X_ADC_SHT_512 = 0xAA00
50} MSP430XADCSampleRates;
51/** @} */
52
53/**
54 * @name Resolution
55 * @{
56 */
57typedef enum {
58 MSP430X_ADC_RES_8BIT = 0x0000,
59 MSP430X_ADC_RES_10BIT = 0x0010,
60 MSP430X_ADC_RES_12BIT = 0x0020
61} MSP430XADCResolution;
62/** @} */
63
64/**
65 * @name References
66 * @{
67 */
68typedef enum {
69 MSP430X_ADC_VSS_VCC = 0x0000,
70 MSP430X_ADC_VSS_VREF_BUF = 0x0100,
71 MSP430X_ADC_VSS_VEREF_N = 0x0200,
72 MSP430X_ADC_VSS_VEREF_P_BUF = 0x0300,
73 MSP430X_ADC_VSS_VEREF_P = 0x0400,
74 MSP430X_ADC_VEREF_P_BUF_VCC = 0x0500,
75 MSP430X_ADC_VEREF_P_VCC = 0x0600,
76 MSP430X_ADC_VEREF_P_VREF_BUF = 0x0700,
77 MSP430X_ADC_VREF_BUF_VCC = 0x0900,
78 MSP430X_ADC_VREF_BUF_VEREF_P = 0x0B00,
79 MSP430X_ADC_VEREF_N_VCC = 0x0C00,
80 MSP430X_ADC_VEREF_N_VREF_BUF = 0x0D00,
81 MSP430X_ADC_VEREF_N_VEREF_P = 0x0E00,
82 MSP430X_ADC_VEREF_N_VEREF_P_BUF = 0x0F00
83} MSP430XADCReferences;
84
85typedef enum {
86 MSP430X_REF_1V2 = 0x0000,
87 MSP430X_REF_2V0 = 0x0010,
88 MSP430X_REF_2V5 = 0x0020,
89 MSP430X_REF_1V2_EXT = 0x0002,
90 MSP430X_REF_2V0_EXT = 0x0012,
91 MSP430X_REF_2V5_EXT = 0x0022
92} MSP430XREFSources;
93
94#define MSP430X_REF_NONE MSP430X_REF_1V2
95
96/** @} */
97
98/*===========================================================================*/
99/* Driver pre-compile time settings. */
100/*===========================================================================*/
101
102/**
103 * @name MSP430X configuration options
104 * @{
105 */
106/**
107 * @brief Stores ADC samples in an 8 bit integer.
108 * @note 10 and 12 bit sampling modes must not be used when this option is
109 * enabled.
110 */
111#if !defined(MSP430X_ADC_COMPACT_SAMPLES) || defined(__DOXYGEN__)
112#define MSP430X_ADC_COMPACT_SAMPLES FALSE
113#endif
114
115/**
116 * @brief ADC1 driver enable switch.
117 * @details If set to @p TRUE the support for ADC1 is included.
118 * @note The default is @p TRUE.
119 */
120#if !defined(MSP430X_ADC_USE_ADC1) || defined(__DOXYGEN__)
121#define MSP430X_ADC_USE_ADC1 TRUE
122#endif
123
124/**]
125 * @brief Exclusive DMA enable switch.
126 * @details If set to @p TRUE the support for exclusive DMA is included.
127 * @note This increases the size of the compiled executable somewhat.
128 * @note The default is @p FALSE.
129 */
130#if !defined(MSP430X_ADC_EXCLUSIVE_DMA) || defined(__DOXYGEN__)
131#define MSP430X_ADC_EXCLUSIVE_DMA FALSE
132#endif
133
134#if MSP430X_ADC_USE_ADC1
135
136/**
137 * @brief ADC1 clock source configuration
138 */
139#if !defined(MSP430X_ADC1_CLK_SRC)
140#define MSP430X_ADC1_CLK_SRC MSP430X_MODCLK
141#endif
142
143#endif
144/** @} */
145
146/*===========================================================================*/
147/* Derived constants and error checks. */
148/*===========================================================================*/
149
150#if MSP430X_ADC_USE_ADC1
151
152#if !defined(__MSP430_HAS_ADC12_B__)
153#error "No ADC present or ADC version not supported"
154#endif
155
156#if (MSP430X_ADC1_CLK_SRC == MSP430X_MODCLK)
157#define MSP430X_ADC1_CLK_FREQ MSP430X_MODCLK_FREQ
158#define MSP430X_ADC1_SSEL ADC12SSEL_0
159#elif (MSP430X_ADC1_CLK_SRC == MSP430X_ACLK)
160#define MSP430X_ADC1_CLK_FREQ MSP430X_ACLK_FREQ
161#define MSP430X_ADC1_SSEL ADC12SSEL_1
162#elif (MSP430X_ADC1_CLK_SRC == MSP430X_MCLK)
163#define MSP$30X_ADC1_CLK_FREQ MSP430X_MCLK_FREQ
164#define MSP430X_ADC1_SSEL ADC12SSEL_2
165#elif (MSP430X_ADC1_CLK_SRC == MSP430SMCLK)
166#define MSP430X_ADC1_CLK_FREQ MSP430X_SMCLK_FREQ
167#define MSP430X_ADC1_SSEL ADC12SSEL_3
168#else
169#error "Invalid ADC1 clock source requested!"
170#endif
171
172#if !defined(MSP430X_ADC1_FREQ)
173#warning "ADC clock frequency not defined - assuming 1 for all dividers"
174#define MSP430X_ADC1_DIV_CALC(x) (x == 1)
175#else
176#define MSP430X_ADC1_DIV_CALC(x) \
177 ((MSP430X_ADC1_CLK_FREQ / x) == MSP430X_ADC1_FREQ)
178#endif
179
180/**
181 * @brief ADC1 prescaler calculations
182 */
183#if MSP430X_ADC1_DIV_CALC(1)
184#define MSP430X_ADC1_PDIV ADC12PDIV__1
185#define MSP430X_ADC1_DIV ADC12DIV_0
186#elif MSP430X_ADC1_DIV_CALC(2)
187#define MSP430X_ADC1_PDIV ADC12PDIV__1
188#define MSP430X_ADC1_DIV ADC12DIV_1
189#elif MSP430X_ADC1_DIV_CALC(3)
190#define MSP430X_ADC1_PDIV ADC12PDIV__1
191#define MSP430X_ADC1_DIV ADC12DIV_2
192#elif MSP430X_ADC1_DIV_CALC(4)
193#define MSP430X_ADC1_PDIV ADC12PDIV__4
194#define MSP430X_ADC1_DIV ADC12DIV_0
195#elif MSP430X_ADC1_DIV_CALC(5)
196#define MSP430X_ADC1_PDIV ADC12PDIV__1
197#define MSP430X_ADC1_DIV ADC12DIV_4
198#elif MSP430X_ADC1_DIV_CALC(6)
199#define MSP430X_ADC1_PDIV ADC12PDIV__1
200#define MSP430X_ADC1_DIV ADC12DIV_5
201#elif MSP430X_ADC1_DIV_CALC(7)
202#define MSP430X_ADC1_PDIV ADC12PDIV__1
203#define MSP430X_ADC1_DIV ADC12DIV_6
204#elif MSP430X_ADC1_DIV_CALC(8)
205#define MSP430X_ADC1_PDIV ADC12PDIV__4
206#define MSP430X_ADC1_DIV ADC12DIV_2
207#elif MSP430X_ADC1_DIV_CALC(12)
208#define MSP430X_ADC1_PDIV ADC12PDIV__4
209#define MSP430X_ADC1_DIV ADC12DIV_2
210#elif MSP430X_ADC1_DIV_CALC(16)
211#define MSP430X_ADC1_PDIV ADC12PDIV__4
212#define MSP430X_ADC1_DIV ADC12DIV_3
213#elif MSP430X_ADC1_DIV_CALC(20)
214#define MSP430X_ADC1_PDIV ADC12PDIV__4
215#define MSP430X_ADC1_DIV ADC12DIV_4
216#elif MSP430X_ADC1_DIV_CALC(24)
217#define MSP430X_ADC1_PDIV ADC12PDIV__4
218#define MSP430X_ADC1_DIV ADC12DIV_5
219#elif MSP430X_ADC1_DIV_CALC(28)
220#define MSP430X_ADC1_PDIV ADC12PDIV__4
221#define MSP430X_ADC1_DIV ADC12DIV_6
222#elif MSP430X_ADC1_DIV_CALC(32)
223#define MSP430X_ADC1_PDIV ADC12PDIV__32
224#define MSP430X_ADC1_DIV ADC12DIV_0
225#elif MSP430X_ADC1_DIV_CALC(64)
226#define MSP430X_ADC1_PDIV ADC12PDIV__64
227#define MSP430X_ADC1_DIV ADC12DIV_0
228#elif MSP430X_ADC1_DIV_CALC(96)
229#define MSP430X_ADC1_PDIV ADC12PDIV__32
230#define MSP430X_ADC1_DIV ADC12DIV_2
231#elif MSP430X_ADC1_DIV_CALC(128)
232#define MSP430X_ADC1_PDIV ADC12PDIV__64
233#define MSP430X_ADC1_DIV ADC12DIV_1
234#elif MSP430X_ADC1_DIV_CALC(160)
235#define MSP430X_ADC1_PDIV ADC12PDIV__32
236#define MSP430X_ADC1_DIV ADC12DIV_4
237#elif MSP430X_ADC1_DIV_CALC(192)
238#define MSP430X_ADC1_PDIV ADC12PDIV__64
239#define MSP430X_ADC1_DIV ADC12DIV_2
240#elif MSP430X_ADC1_DIV_CALC(224)
241#define MSP430X_ADC1_PDIV ADC12PDIV__32
242#define MSP430X_ADC1_DIV ADC12DIV_6
243#elif MSP430X_ADC1_DIV_CALC(256)
244#define MSP430X_ADC1_PDIV ADC12PDIV__64
245#define MSP430X_ADC1_DIV ADC12DIV_3
246#elif MSP430X_ADC1_DIV_CALC(320)
247#define MSP430X_ADC1_PDIV ADC12PDIV__64
248#define MSP430X_ADC1_DIV ADC12DIV_4
249#elif MSP430X_ADC1_DIV_CALC(384)
250#define MSP430X_ADC1_PDIV ADC12PDIV__64
251#define MSP430X_ADC1_DIV ADC12DIV_5
252#elif MSP430X_ADC1_DIV_CALC(448)
253#define MSP430X_ADC1_PDIV ADC12PDIV__64
254#define MSP430X_ADC1_DIV ADC12DIV_6
255#elif MSP430X_ADC1_DIV_CALC(512)
256#define MSP430X_ADC1_PDIV ADC12PDIV__64
257#define MSP430X_ADC1_DIV ADC12DIV_7
258#else
259#error "MSP430X_ADC1_FREQ not achievable with MSP430X_ADC1_CLK_SRC"
260#endif
261
262#endif /* MSP430X_ADC_USE_ADC1 */
263
264/*===========================================================================*/
265/* Driver data structures and types. */
266/*===========================================================================*/
267
268/**
269 * @brief ADC sample data type.
270 */
271#if !MSP430X_ADC_COMPACT_SAMPLES || defined(__DOXYGEN__)
272typedef uint16_t adcsample_t;
273#else
274typedef uint8_t adcsample_t;
275#endif
276
277/**
278 * @brief Channels number in a conversion group.
279 */
280typedef uint8_t adc_channels_num_t;
281
282/**
283 * @brief Possible ADC failure causes.
284 * @note Error codes are architecture dependent and should not relied
285 * upon.
286 */
287typedef enum {
288 ADC_ERR_UNKNOWN = 0, /**< Unknown error has occurred */
289 ADC_ERR_OVERFLOW = 1, /**< ADC overflow condition. */
290 ADC_ERR_AWD = 2 /**< Analog watchdog triggered. */
291} adcerror_t;
292
293/**
294 * @brief Type of a structure representing an ADC driver.
295 */
296typedef struct ADCDriver ADCDriver;
297
298/**
299 * @brief ADC notification callback type.
300 *
301 * @param[in] adcp pointer to the @p ADCDriver object triggering the
302 * callback
303 * @param[in] buffer pointer to the most recent samples data
304 * @param[in] n number of buffer rows available starting from @p buffer
305 */
306typedef void (*adccallback_t)(ADCDriver * adcp, adcsample_t * buffer, size_t n);
307
308/**
309 * @brief ADC error callback type.
310 *
311 * @param[in] adcp pointer to the @p ADCDriver object triggering the
312 * callback
313 * @param[in] err ADC error code
314 */
315typedef void (*adcerrorcallback_t)(ADCDriver * adcp, adcerror_t err);
316
317/**
318 * @brief MSP430X ADC register structure.
319 */
320typedef struct {
321 uint16_t ctl[4];
322 uint16_t lo;
323 uint16_t hi;
324 uint16_t ifgr[3];
325 uint16_t ier[3];
326 uint16_t iv;
327 uint16_t padding[3];
328 uint16_t mctl[32];
329 uint16_t mem[32];
330} msp430x_adc_reg_t;
331
332/**
333 * @brief MSP430X ADC calibration structure.
334 */
335typedef struct {
336 uint16_t CAL_ADC_GAIN_FACTOR;
337 uint16_t CAL_ADC_OFFSET;
338 uint16_t CAL_ADC_12T30;
339 uint16_t CAL_ADC_12T85;
340 uint16_t CAL_ADC_20T30;
341 uint16_t CAL_ADC_20T85;
342 uint16_t CAL_ADC_25T30;
343 uint16_t CAL_ADC_25T85;
344} msp430x_adc_cal_t;
345
346/**
347 * @brief MSP430X REF calibration structure.
348 */
349typedef struct {
350 uint16_t CAL_ADC_12VREF_FACTOR;
351 uint16_t CAL_ADC_20VREF_FACTOR;
352 uint16_t CAL_ADC_25VREF_FACTOR;
353} msp430x_ref_cal_t;
354
355/**
356 * @brief Conversion group configuration structure.
357 * @details This implementation-dependent structure describes a conversion
358 * operation.
359 * @note The use of this configuration structure requires knowledge of
360 * MSP430X ADC cell registers interface, please refer to the MSP430X
361 * reference manual for details.
362 */
363typedef struct {
364 /**
365 * @brief Enables the circular buffer mode for the group.
366 */
367 bool circular;
368 /**
369 * @brief Number of the analog channels belonging to the conversion group.
370 */
371 adc_channels_num_t num_channels;
372 /**
373 * @brief Callback function associated to the group or @p NULL.
374 */
375 adccallback_t end_cb;
376 /**
377 * @brief Error callback or @p NULL.
378 */
379 adcerrorcallback_t error_cb;
380 /* End of the mandatory fields.*/
381 /**
382 * @brief Sequence of analog channels belonging to the conversion group.
383 * @note Only the first num_channels are valid.
384 */
385 uint8_t channels[32];
386 /**
387 * @brief Sample resolution
388 */
389 MSP430XADCResolution res;
390 /**
391 * @brief Sampling time in clock cycles
392 */
393 MSP430XADCSampleRates rate;
394 /**
395 * @brief Voltage references to use
396 */
397 MSP430XADCReferences ref;
398 /**
399 * @brief VREF source
400 */
401 MSP430XREFSources vref_src;
402} ADCConversionGroup;
403
404/**
405 * @brief Driver configuration structure.
406 * @note It could be empty on some architectures.
407 */
408typedef struct {
409#if MSP430X_ADC_EXCLUSIVE_DMA == TRUE || defined(__DOXYGEN__)
410 /**
411 * @brief The index of the DMA channel.
412 * @note This may be >MSP430X_DMA_CHANNELS to indicate that exclusive DMA
413 * is not used.
414 */
415 uint8_t dma_index;
416#endif
417} ADCConfig;
418
419/**
420 * @brief Structure representing an ADC driver.
421 */
422struct ADCDriver {
423 /**
424 * @brief Driver state.
425 */
426 adcstate_t state;
427 /**
428 * @brief Current configuration data.
429 */
430 const ADCConfig * config;
431 /**
432 * @brief Current samples buffer pointer or @p NULL.
433 */
434 adcsample_t * samples;
435 /**
436 * @brief Current samples buffer depth or @p 0.
437 */
438 size_t depth;
439 /**
440 * @brief Current conversion group pointer or @p NULL.
441 */
442 const ADCConversionGroup * grpp;
443#if (ADC_USE_WAIT == TRUE) || defined(__DOXYGEN__)
444 /**
445 * @brief Waiting thread.
446 */
447 thread_reference_t thread;
448#endif
449#if (ADC_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
450 /**
451 * @brief Mutex protecting the peripheral.
452 */
453 mutex_t mutex;
454#endif
455#if defined(ADC_DRIVER_EXT_FIELDS)
456 ADC_DRIVER_EXT_FIELDS
457#endif
458 /* End of the mandatory fields.*/
459 /**
460 * @brief Base address of ADC12_B registers
461 */
462 msp430x_adc_reg_t * regs;
463 /**
464 * @brief DMA request structure
465 */
466 msp430x_dma_req_t req;
467 /**
468 * @brief ADC calibration structure from TLV
469 */
470 msp430x_adc_cal_t * adc_cal;
471 /**
472 * @brief REF calibration structure from TLV
473 */
474 msp430x_ref_cal_t * ref_cal;
475 /**
476 * @brief Count of times DMA callback has been called
477 */
478 uint8_t count;
479 /**
480 * @brief DMA stream
481 */
482 msp430x_dma_ch_t dma;
483};
484
485/*===========================================================================*/
486/* Driver macros. */
487/*===========================================================================*/
488
489/*===========================================================================*/
490/* External declarations. */
491/*===========================================================================*/
492
493#if (MSP430X_ADC_USE_ADC1 == TRUE) && !defined(__DOXYGEN__)
494extern ADCDriver ADCD1;
495#endif
496
497#ifdef __cplusplus
498extern "C" {
499#endif
500void adc_lld_init(void);
501void adc_lld_start(ADCDriver * adcp);
502void adc_lld_stop(ADCDriver * adcp);
503void adc_lld_start_conversion(ADCDriver * adcp);
504void adc_lld_stop_conversion(ADCDriver * adcp);
505adcsample_t adcMSP430XAdjustResult(ADCConversionGroup * grpp,
506 adcsample_t sample);
507adcsample_t adcMSP430XAdjustTemp(ADCConversionGroup * grpp, adcsample_t sample);
508#ifdef __cplusplus
509}
510#endif
511
512#endif /* HAL_USE_ADC == TRUE */
513
514#endif /* HAL_ADC_LLD_H */
515
516/** @} */