1 /*
2  * @brief  LPC15xx ADC driver
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2013
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products.  This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights.  NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers.  This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #ifndef __ADC_15XX_H_
33 #define __ADC_15XX_H_
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 /** @defgroup ADC_15XX CHIP:  LPC15xx A/D conversion driver
40  * @ingroup CHIP_15XX_Drivers
41  * @{
42  */
43 
44 /** Sequence index enumerations, used in various parts of the code for
45     register indexing and sequencer selection */
46 typedef enum {
47 	ADC_SEQA_IDX,
48 	ADC_SEQB_IDX
49 } ADC_SEQ_IDX_T;
50 
51 /**
52  * @brief ADC register block structure
53  */
54 typedef struct {								/*!< ADCn Structure */
55 	__IO uint32_t CTRL;							/*!< A/D Control Register. The AD0CR register must be written to select the operating mode before A/D conversion can occur. */
56 	__IO uint32_t INSEL;						/*!< A/D Input Select Register. This field selects the input source for channel 0. */
57 	__IO uint32_t SEQ_CTRL[ADC_SEQB_IDX + 1];	/*!< A/D Sequence A & B Control Register. Controls triggering and channel selection for sonversion sequence. */
58 	__IO uint32_t SEQ_GDAT[ADC_SEQB_IDX + 1];	/*!< A/D Sequence A & B Global Data Register. Contains the result of the most recent A/D conversion for sequence. */
59 	__I  uint32_t RESERVED1[2];
60 	__I  uint32_t DR[12];						/*!< A/D Channel Data Register. This register contains the result of the most recent conversion completed on channel n. */
61 	__IO uint32_t THR_LOW[2];					/*!< A/D Low Compare Threshold Register 0 & 1. Contains the lower threshold level for automatic threshold comparison. */
62 	__IO uint32_t THR_HIGH[2];					/*!< A/D High Compare Threshold Register 0 & 1. Contains the higher threshold level for automatic threshold comparison. */
63 	__IO uint32_t CHAN_THRSEL;					/*!< A/D Channel Threshold Select Register. Specifies which set of threshold compare registers to use. */
64 	__IO uint32_t INTEN;						/*!< A/D Interrupt Enable Register. This register contains enable bits that enable sequence-A, sequence-B, threshold compare and overrun interrupts. */
65 	__IO uint32_t FLAGS;						/*!< A/D Flags Register. This register contains interrupt flags. - To be checked */
66 	__IO uint32_t TRM;							/*!< A/D Trim Register. */
67 } LPC_ADC_T;
68 
69 /** Maximum sample rate in Hz (12-bit conversions) */
70 #define ADC_MAX_SAMPLE_RATE 50000000
71 
72 /**
73  * @brief ADC register support bitfields and mask
74  */
75 /** ADC Control register bit fields */
76 #define ADC_CR_CLKDIV_MASK      (0xFF << 0)				/*!< Mask for Clock divider value */
77 #define ADC_CR_CLKDIV_BITPOS    (0)						/*!< Bit position for Clock divider value */
78 #define ADC_CR_ASYNMODE         (1 << 8)				/*!< Asynchronous mode enable bit */
79 #define ADC_CR_MODE10BIT        (1 << 9)				/*!< 10-bit mode enable bit */
80 #define ADC_CR_LPWRMODEBIT      (1 << 10)				/*!< Low power mode enable bit */
81 #define ADC_CR_CALMODEBIT       (1 << 30)				/*!< Self calibration cycle enable bit */
82 #define ADC_CR_BITACC(n)        ((((n) & 0x1) << 9))	/*!< 12-bit or 10-bit ADC accuracy */
83 #define ADC_CR_CLKDIV(n)        ((((n) & 0xFF) << 0))	/*!< The APB clock (PCLK) is divided by (this value plus one) to produce the clock for the A/D */
84 #define ADC_SAMPLE_RATE_CONFIG_MASK (ADC_CR_CLKDIV(0xFF) | ADC_CR_BITACC(0x01))
85 
86 /** ADC input select register */
87 #define ADC_INSEL_ADC0          (0x0 << 0)				/*!< Select ADCn_0 for channel 0 */
88 #define ADC_INSEL_CRVO          (0x1 << 0)				/*!< Selects the Core voltage regulator output for channel 0 */
89 #define ADC_INSEL_IVR           (0x2 << 0)				/*!< Selects the Internal voltage reference for channel 0 */
90 #define ADC_INSEL_TS            (0x3 << 0)				/*!< Selects the Temperature Sensor for channel 0 */
91 #define ADC_INSEL_VDDA_DIV      (0x4 << 0)				/*!< Selects VDDA/2 for channel 0 */
92 
93 /** ADC Sequence Control register bit fields */
94 #define ADC_SEQ_CTRL_CHANSEL(n)   (1 << (n))			/*!< Channel select macro */
95 #define ADC_SEQ_CTRL_CHANSEL_MASK (0xFFF)				/*!< Channel select mask */
96 
97 /** ADC hardware trigger sources in SEQ_CTRL for ADC0 only. These sources should
98  * only be used when selecting trigger sources for ADC0. */
99 #define ADC0_SEQ_CTRL_HWTRIG_ADC0_PIN_TRIG0 (0 << 12)	/*!< HW trigger input - ADC0_PIN_TRIG0 */
100 #define ADC0_SEQ_CTRL_HWTRIG_ADC0_PIN_TRIG1 (1 << 12)	/*!< HW trigger input - ADC0_PIN_TRIG1 */
101 #define ADC0_SEQ_CTRL_HWTRIG_SCT0_OUT7    (2 << 12)		/*!< HW trigger input - SCT0_OUT7 */
102 #define ADC0_SEQ_CTRL_HWTRIG_SCT0_OUT9    (3 << 12)		/*!< HW trigger input - SCT0_OUT9 */
103 #define ADC0_SEQ_CTRL_HWTRIG_SCT1_OUT7    (4 << 12)		/*!< HW trigger input - SCT1_OUT7 */
104 #define ADC0_SEQ_CTRL_HWTRIG_SCT1_OUT9    (5 << 12)		/*!< HW trigger input - SCT1_OUT9 */
105 #define ADC0_SEQ_CTRL_HWTRIG_SCT2_OUT3    (6 << 12)		/*!< HW trigger input - SCT2_OUT3 */
106 #define ADC0_SEQ_CTRL_HWTRIG_SCT2_OUT4    (7 << 12)		/*!< HW trigger input - SCT2_OUT4 */
107 #define ADC0_SEQ_CTRL_HWTRIG_SCT3_OUT3    (8 << 12)		/*!< HW trigger input - SCT3_OUT3 */
108 #define ADC0_SEQ_CTRL_HWTRIG_SCT3_OUT4    (9 << 12)		/*!< HW trigger input - SCT3_OUT4 */
109 #define ADC0_SEQ_CTRL_HWTRIG_ACMP0_O      (10 << 12)	/*!< HW trigger input - ACMP0_O */
110 #define ADC0_SEQ_CTRL_HWTRIG_ACMP1_O      (11 << 12)	/*!< HW trigger input - ACMP1_O */
111 #define ADC0_SEQ_CTRL_HWTRIG_ACMP2_O      (12 << 12)	/*!< HW trigger input - ACMP2_O */
112 #define ADC0_SEQ_CTRL_HWTRIG_ACMP3_O      (13 << 12)	/*!< HW trigger input - ACMP3_O */
113 #define ADC0_SEQ_CTRL_HWTRIG_MASK         (0x3F << 12)	/*!< HW trigger input bitfield mask */
114 
115 /** ADC hardware trigger sources in SEQ_CTRL for ADC1 only. These sources should
116  * only be used when selecting trigger sources for ADC1. */
117 #define ADC1_SEQ_CTRL_HWTRIG_ADC1_PIN_TRIG0 (0 << 12)	/*!< HW trigger input - ADC1_PIN_TRIG0 */
118 #define ADC1_SEQ_CTRL_HWTRIG_ADC1_PIN_TRIG1 (1 << 12)	/*!< HW trigger input - ADC1_PIN_TRIG1 */
119 #define ADC1_SEQ_CTRL_HWTRIG_SCT0_OUT6    (2 << 12)		/*!< HW trigger input - SCT0_OUT6 */
120 #define ADC1_SEQ_CTRL_HWTRIG_SCT0_OUT9    (3 << 12)		/*!< HW trigger input - SCT0_OUT9 */
121 #define ADC1_SEQ_CTRL_HWTRIG_SCT1_OUT8    (4 << 12)		/*!< HW trigger input - SCT1_OUT8 */
122 #define ADC1_SEQ_CTRL_HWTRIG_SCT1_OUT9    (5 << 12)		/*!< HW trigger input - SCT1_OUT9 */
123 #define ADC1_SEQ_CTRL_HWTRIG_SCT2_OUT2    (6 << 12)		/*!< HW trigger input - SCT2_OUT2 */
124 #define ADC1_SEQ_CTRL_HWTRIG_SCT2_OUT5    (7 << 12)		/*!< HW trigger input - SCT2_OUT5 */
125 #define ADC1_SEQ_CTRL_HWTRIG_SCT3_OUT2    (8 << 12)		/*!< HW trigger input - SCT3_OUT2 */
126 #define ADC1_SEQ_CTRL_HWTRIG_SCT3_OUT5    (9 << 12)		/*!< HW trigger input - SCT3_OUT5 */
127 #define ADC1_SEQ_CTRL_HWTRIG_ACMP0_O      (10 << 12)	/*!< HW trigger input - ACMP0_O */
128 #define ADC1_SEQ_CTRL_HWTRIG_ACMP1_O      (11 << 12)	/*!< HW trigger input - ACMP1_O */
129 #define ADC1_SEQ_CTRL_HWTRIG_ACMP2_O      (12 << 12)	/*!< HW trigger input - ACMP2_O */
130 #define ADC1_SEQ_CTRL_HWTRIG_ACMP3_O      (13 << 12)	/*!< HW trigger input - ACMP3_O */
131 #define ADC1_SEQ_CTRL_HWTRIG_MASK         (0x3F << 12)	/*!< HW trigger input bitfield mask */
132 
133 /** SEQ_CTRL register bit fields */
134 #define ADC_SEQ_CTRL_HWTRIG_POLPOS       (1 << 18)		/*!< HW trigger polarity - positive edge */
135 #define ADC_SEQ_CTRL_HWTRIG_SYNCBYPASS   (1 << 19)		/*!< HW trigger bypass synchronisation */
136 #define ADC_SEQ_CTRL_START               (1 << 26)		/*!< Start conversion enable bit */
137 #define ADC_SEQ_CTRL_BURST               (1 << 27)		/*!< Repeated conversion enable bit */
138 #define ADC_SEQ_CTRL_SINGLESTEP          (1 << 28)		/*!< Single step enable bit */
139 #define ADC_SEQ_CTRL_LOWPRIO             (1 << 29)		/*!< High priority enable bit (regardless of name) */
140 #define ADC_SEQ_CTRL_MODE_EOS            (1 << 30)		/*!< Mode End of sequence enable bit */
141 #define ADC_SEQ_CTRL_SEQ_ENA             (1UL << 31)	/*!< Sequence enable bit */
142 
143 /** ADC global data register bit fields */
144 #define ADC_SEQ_GDAT_RESULT_MASK         (0xFFF << 4)	/*!< Result value mask */
145 #define ADC_SEQ_GDAT_RESULT_BITPOS       (4)			/*!< Result start bit position */
146 #define ADC_SEQ_GDAT_THCMPRANGE_MASK     (0x3 << 16)	/*!< Comparion range mask */
147 #define ADC_SEQ_GDAT_THCMPRANGE_BITPOS   (16)			/*!< Comparison range bit position */
148 #define ADC_SEQ_GDAT_THCMPCROSS_MASK     (0x3 << 18)	/*!< Comparion cross mask */
149 #define ADC_SEQ_GDAT_THCMPCROSS_BITPOS   (18)			/*!< Comparison cross bit position */
150 #define ADC_SEQ_GDAT_CHAN_MASK           (0xF << 26)	/*!< Channel number mask */
151 #define ADC_SEQ_GDAT_CHAN_BITPOS         (26)			/*!< Channel number bit position */
152 #define ADC_SEQ_GDAT_OVERRUN             (1 << 30)		/*!< Overrun bit */
153 #define ADC_SEQ_GDAT_DATAVALID           (1UL << 31)	/*!< Data valid bit */
154 
155 /** ADC Data register bit fields */
156 #define ADC_DR_RESULT(n)           ((((n) >> 4) & 0xFFF))	/*!< Macro for getting the ADC data value */
157 #define ADC_DR_THCMPRANGE_MASK     (0x3 << 16)			/*!< Comparion range mask */
158 #define ADC_DR_THCMPRANGE_BITPOS   (16)					/*!< Comparison range bit position */
159 #define ADC_DR_THCMPRANGE(n)       (((n) >> ADC_DR_THCMPRANGE_BITPOS) & 0x3)
160 #define ADC_DR_THCMPCROSS_MASK     (0x3 << 18)			/*!< Comparion cross mask */
161 #define ADC_DR_THCMPCROSS_BITPOS   (18)					/*!< Comparison cross bit position */
162 #define ADC_DR_THCMPCROSS(n)       (((n) >> ADC_DR_THCMPCROSS_BITPOS) & 0x3)
163 #define ADC_DR_CHAN_MASK           (0xF << 26)			/*!< Channel number mask */
164 #define ADC_DR_CHAN_BITPOS         (26)					/*!< Channel number bit position */
165 #define ADC_DR_CHANNEL(n)          (((n) >> ADC_DR_CHAN_BITPOS) & 0xF)	/*!< Channel number bit position */
166 #define ADC_DR_OVERRUN             (1 << 30)			/*!< Overrun bit */
167 #define ADC_DR_DATAVALID           (1UL << 31)			/*!< Data valid bit */
168 #define ADC_DR_DONE(n)             (((n) >> 31))
169 
170 /** ADC low/high Threshold register bit fields */
171 #define ADC_THR_VAL_MASK            (0xFFF << 4)		/*!< Threshold value bit mask */
172 #define ADC_THR_VAL_POS             (4)					/*!< Threshold value bit position */
173 
174 /** ADC Threshold select register bit fields */
175 #define ADC_THRSEL_CHAN_SEL_THR1(n) (1 << (n))			/*!< Select THR1 register for channel n */
176 
177 /** ADC Interrupt Enable register bit fields */
178 #define ADC_INTEN_SEQA_ENABLE       (1 << 0)			/*!< Sequence A Interrupt enable bit */
179 #define ADC_INTEN_SEQB_ENABLE       (1 << 1)			/*!< Sequence B Interrupt enable bit */
180 #define ADC_INTEN_SEQN_ENABLE(seq)  (1 << (seq))		/*!< Sequence A/B Interrupt enable bit */
181 #define ADC_INTEN_OVRRUN_ENABLE     (1 << 2)			/*!< Overrun Interrupt enable bit */
182 #define ADC_INTEN_CMP_DISBALE       (0)					/*!< Disable comparison interrupt value */
183 #define ADC_INTEN_CMP_OUTSIDETH     (1)					/*!< Outside threshold interrupt value */
184 #define ADC_INTEN_CMP_CROSSTH       (2)					/*!< Crossing threshold interrupt value */
185 #define ADC_INTEN_CMP_MASK          (3)					/*!< Comparison interrupt value mask */
186 #define ADC_INTEN_CMP_ENABLE(isel, ch) (((isel) & ADC_INTEN_CMP_MASK) << ((2 * (ch)) + 3))	/*!< Interrupt selection for channel */
187 
188 /** ADC Flags register bit fields */
189 #define ADC_FLAGS_THCMP_MASK(ch)    (1 << (ch))		/*!< Threshold comparison status for channel */
190 #define ADC_FLAGS_OVRRUN_MASK(ch)   (1 << (12 + (ch)))	/*!< Overrun status for channel */
191 #define ADC_FLAGS_SEQA_OVRRUN_MASK  (1 << 24)			/*!< Seq A Overrun status */
192 #define ADC_FLAGS_SEQB_OVRRUN_MASK  (1 << 25)			/*!< Seq B Overrun status */
193 #define ADC_FLAGS_SEQN_OVRRUN_MASK(seq) (1 << (24 + (seq)))	/*!< Seq A/B Overrun status */
194 #define ADC_FLAGS_SEQA_INT_MASK     (1 << 28)			/*!< Seq A Interrupt status */
195 #define ADC_FLAGS_SEQB_INT_MASK     (1 << 29)			/*!< Seq B Interrupt status */
196 #define ADC_FLAGS_SEQN_INT_MASK(seq) (1 << (28 + (seq)))/*!< Seq A/B Interrupt status */
197 #define ADC_FLAGS_THCMP_INT_MASK    (1 << 30)			/*!< Threshold comparison Interrupt status */
198 #define ADC_FLAGS_OVRRUN_INT_MASK   (1UL << 31)			/*!< Overrun Interrupt status */
199 
200 /** ADC Trim register bit fields */
201 #define ADC_TRIM_VRANGE_HIGHV       (0 << 5)			/*!< Voltage range bit - High volatge (2.7V to 3.6V) */
202 #define ADC_TRIM_VRANGE_LOWV        (1 << 5)			/*!< Voltage range bit - Low volatge (1.8V to 2.7V) */
203 
204 /**
205  * @brief	Initialize the ADC peripheral
206  * @param	pADC	: The base of ADC peripheral on the chip
207  * @param	flags	: ADC flags for init (ADC_CR_MODE10BIT and/or ADC_CR_LPWRMODEBIT)
208  * @return	Nothing
209  * @note	To select low-power ADC mode, enable the ADC_CR_LPWRMODEBIT flag.
210  * To select 10-bit conversion mode, enable the ADC_CR_MODE10BIT flag. You ca
211  * also enable asychronous clock mode by using the ADC_CR_ASYNMODE.
212  * Example: Chip_ADC_Init(LPC_ADC, (ADC_CR_MODE10BIT | ADC_CR_LPWRMODEBIT));
213  */
214 void Chip_ADC_Init(LPC_ADC_T *pADC, uint32_t flags);
215 
216 /**
217  * @brief	Shutdown ADC
218  * @param	pADC	: The base of ADC peripheral on the chip
219  * @return	Nothing
220  * @note	Disables the ADC clocks and ADC power
221  */
222 void Chip_ADC_DeInit(LPC_ADC_T *pADC);
223 
224 /**
225  * @brief	Set ADC divider
226  * @param	pADC	: The base of ADC peripheral on the chip
227  * @param	div		: ADC divider value to set minus 1
228  * @return	Nothing
229  * @note	The value is used as a divider to generate the ADC
230  * clock rate from the ADC input clock. The ADC input clock is based
231  * on the system clock. Valid values for this function are from 0 to 255
232  * with 0=divide by 1, 1=divide by 2, 2=divide by 3, etc.<br>
233  * Do not decrement this value by 1.<br>
234  * To set the ADC clock rate to 1MHz, use the following function:<br>
235  * Chip_ADC_SetDivider(LPC_ADC, (Chip_Clock_GetSystemClockRate() / 1000000) - 1);
236  */
Chip_ADC_SetDivider(LPC_ADC_T * pADC,uint8_t div)237 STATIC INLINE void Chip_ADC_SetDivider(LPC_ADC_T *pADC, uint8_t div)
238 {
239 	uint32_t temp;
240 
241 	temp = pADC->CTRL & ~(ADC_CR_CLKDIV_MASK);
242 	pADC->CTRL = temp | (uint32_t) div;
243 }
244 
245 /**
246  * @brief	Set ADC clock rate
247  * @param	pADC	: The base of ADC peripheral on the chip
248  * @param	rate	: rate in Hz to set ADC clock to (maximum ADC_MAX_SAMPLE_RATE)
249  * @return	Nothing
250  * @note	This function will not work if the ADC is used with the ASYNC
251  * ADC clock (set when the ADC_CR_ASYNMODE bit is on in the ADC CTRL register).
252  */
253 void Chip_ADC_SetClockRate(LPC_ADC_T *pADC, uint32_t rate);
254 
255 /**
256  * @brief	Get ADC divider
257  * @param	pADC	: The base of ADC peripheral on the chip
258  * @return	the current ADC divider
259  * @note	This function returns the divider that is used to generate the
260  * ADC frequency. The returned value must be incremented by 1. The
261  * frequency can be determined with the following function:<br>
262  * adc_freq = Chip_Clock_GetSystemClockRate() / (Chip_ADC_GetDivider(LPC_ADC) + 1);
263  */
Chip_ADC_GetDivider(LPC_ADC_T * pADC)264 STATIC INLINE uint8_t Chip_ADC_GetDivider(LPC_ADC_T *pADC)
265 {
266 	return pADC->CTRL & ADC_CR_CLKDIV_MASK;
267 }
268 
269 /**
270  * @brief	Start ADC calibration
271  * @param	pADC	: The base of ADC peripheral on the chip
272  * @return	Nothing
273  * @note	Calibration is not done as part of Chip_ADC_Init(), but
274  * is required after the call to Chip_ADC_Init() or after returning
275  * from a power-down state. Calibration may alter the ADC_CR_ASYNMODE
276  * and ADC_CR_LPWRMODEBIT flags ni the CTRL register.
277  */
278 void Chip_ADC_StartCalibration(LPC_ADC_T *pADC);
279 
280 /**
281  * @brief	Start ADC calibration
282  * @param	pADC	: The base of ADC peripheral on the chip
283  * @return	TRUE if calibration is complete, otherwise FALSE.
284  */
Chip_ADC_IsCalibrationDone(LPC_ADC_T * pADC)285 STATIC INLINE bool Chip_ADC_IsCalibrationDone(LPC_ADC_T *pADC)
286 {
287 	return (bool) ((pADC->CTRL & ADC_CR_CALMODEBIT) == 0);
288 }
289 
290 /**
291  * @brief	Select input select for ADC channel 0
292  * @param	pADC	: The base of ADC peripheral on the chip
293  * @param	inp		: Select an ADC_INSEL_* value for ADC0 input selection
294  * @return	Nothing
295  */
Chip_ADC_SetADC0Input(LPC_ADC_T * pADC,uint32_t inp)296 STATIC INLINE void Chip_ADC_SetADC0Input(LPC_ADC_T *pADC, uint32_t inp)
297 {
298 	pADC->INSEL = inp;
299 }
300 
301 /**
302  * @brief	Helper function for safely setting ADC sequencer register bits
303  * @param	pADC		: The base of ADC peripheral on the chip
304  * @param	seqIndex	: Sequencer to set bits for
305  * @param	bits		: Or'ed bits of a sequencer register to set
306  * @return	Nothing
307  * @note	This function will safely set the ADC sequencer register bits
308  * while maintaining bits 20..25 as 0, regardless of the read state of those bits.
309  */
310 void Chip_ADC_SetSequencerBits(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t bits);
311 
312 /**
313  * @brief	Helper function for safely clearing ADC sequencer register bits
314  * @param	pADC		: The base of ADC peripheral on the chip
315  * @param	seqIndex	: Sequencer to clear bits for
316  * @param	bits		: Or'ed bits of a sequencer register to clear
317  * @return	Nothing
318  * @note	This function will safely clear the ADC sequencer register bits
319  * while maintaining bits 20..25 as 0, regardless of the read state of those bits.
320  */
321 void Chip_ADC_ClearSequencerBits(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t bits);
322 
323 /**
324  * @brief	Sets up ADC conversion sequencer A or B
325  * @param	pADC		: The base of ADC peripheral on the chip
326  * @param	seqIndex	: Sequencer to setup
327  * @param	options		: OR'ed Sequencer options to setup (see notes)
328  * @return	Nothing
329  * @note	Sets up sequencer options for a conversion sequence. This function
330  * should be used to setup the selected channels for the sequence, the sequencer
331  * trigger, the trigger polarity, synchronization bypass, priority, and mode. All
332  * options are passed to the functions as a OR'ed list of values. This function will
333  * disable/clear the sequencer start/burst/single step/enable if they are enabled.<br>
334  * Select the channels by OR'ing in one or more ADC_SEQ_CTRL_CHANSEL(ch) values.<br>
335  * Select the hardware trigger by OR'ing in one ADC_SEQ_CTRL_HWTRIG_* value.<br>
336  * Select a positive edge hardware trigger by OR'ing in ADC_SEQ_CTRL_HWTRIG_POLPOS.<br>
337  * Select trigger bypass synchronisation by OR'ing in ADC_SEQ_CTRL_HWTRIG_SYNCBYPASS.<br>
338  * Select ADC single step on trigger/start by OR'ing in ADC_SEQ_CTRL_SINGLESTEP.<br>
339  * Select higher priority conversion on the other sequencer by OR'ing in ADC_SEQ_CTRL_LOWPRIO.<br>
340  * Select end of seqeuence instead of end of conversion interrupt by OR'ing in ADC_SEQ_CTRL_MODE_EOS.<br>
341  * Example for setting up sequencer A (channels 0-2, trigger on high edge of PIO0_2, interrupt on end of sequence):<br>
342  * Chip_ADC_SetupSequencer(LPC_ADC, ADC_SEQA_IDX, (
343  *     ADC_SEQ_CTRL_CHANSEL(0) | ADC_SEQ_CTRL_CHANSEL(1) | ADC_SEQ_CTRL_CHANSEL(2) |
344  *     ADC_SEQ_CTRL_HWTRIG_PIO0_2 | ADC_SEQ_CTRL_HWTRIG_POLPOS | ADC_SEQ_CTRL_MODE_EOS));
345  */
Chip_ADC_SetupSequencer(LPC_ADC_T * pADC,ADC_SEQ_IDX_T seqIndex,uint32_t options)346 STATIC INLINE void Chip_ADC_SetupSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t options)
347 {
348 	pADC->SEQ_CTRL[seqIndex] = options;
349 }
350 
351 /**
352  * @brief	Enables a sequencer
353  * @param	pADC		: The base of ADC peripheral on the chip
354  * @param	seqIndex	: Sequencer to enable
355  * @return	Nothing
356  */
Chip_ADC_EnableSequencer(LPC_ADC_T * pADC,ADC_SEQ_IDX_T seqIndex)357 STATIC INLINE void Chip_ADC_EnableSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
358 {
359 	Chip_ADC_SetSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_SEQ_ENA);
360 }
361 
362 /**
363  * @brief	Disables a sequencer
364  * @param	pADC		: The base of ADC peripheral on the chip
365  * @param	seqIndex	: Sequencer to disable
366  * @return	Nothing
367  */
Chip_ADC_DisableSequencer(LPC_ADC_T * pADC,ADC_SEQ_IDX_T seqIndex)368 STATIC INLINE void Chip_ADC_DisableSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
369 {
370 	Chip_ADC_ClearSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_SEQ_ENA);
371 }
372 
373 /**
374  * @brief	Forces a sequencer trigger event (software trigger of ADC)
375  * @param	pADC		: The base of ADC peripheral on the chip
376  * @param	seqIndex	: Sequencer to start
377  * @return	Nothing
378  * @note	This function sets the START bit for the sequencer to force a
379  * single conversion sequence or a single step conversion.
380  */
Chip_ADC_StartSequencer(LPC_ADC_T * pADC,ADC_SEQ_IDX_T seqIndex)381 STATIC INLINE void Chip_ADC_StartSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
382 {
383 	Chip_ADC_SetSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_START);
384 }
385 
386 /**
387  * @brief	Starts sequencer burst mode
388  * @param	pADC		: The base of ADC peripheral on the chip
389  * @param	seqIndex	: Sequencer to start burst on
390  * @return	Nothing
391  * @note	This function sets the BURST bit for the sequencer to force
392  * continuous conversion. Use Chip_ADC_StopBurstSequencer() to stop the
393  * ADC burst sequence.
394  */
Chip_ADC_StartBurstSequencer(LPC_ADC_T * pADC,ADC_SEQ_IDX_T seqIndex)395 STATIC INLINE void Chip_ADC_StartBurstSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
396 {
397 	Chip_ADC_SetSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_BURST);
398 }
399 
400 /**
401  * @brief	Stops sequencer burst mode
402  * @param	pADC		: The base of ADC peripheral on the chip
403  * @param	seqIndex	: Sequencer to stop burst on
404  * @return	Nothing
405  */
Chip_ADC_StopBurstSequencer(LPC_ADC_T * pADC,ADC_SEQ_IDX_T seqIndex)406 STATIC INLINE void Chip_ADC_StopBurstSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
407 {
408 	Chip_ADC_ClearSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_BURST);
409 }
410 
411 /** ADC sequence global data register threshold comparison range enumerations */
412 typedef enum {
413 	ADC_DR_THCMPRANGE_INRANGE,
414 	ADC_DR_THCMPRANGE_RESERVED,
415 	ADC_DR_THCMPRANGE_BELOW,
416 	ADC_DR_THCMPRANGE_ABOVE
417 } ADC_DR_THCMPRANGE_T;
418 
419 /** ADC sequence global data register threshold comparison cross enumerations */
420 typedef enum {
421 	ADC_DR_THCMPCROSS_NOCROSS,
422 	ADC_DR_THCMPCROSS_RESERVED,
423 	ADC_DR_THCMPCROSS_DOWNWARD,
424 	ADC_DR_THCMPCROSS_UPWARD
425 } ADC_DR_THCMPCROSS_T;
426 
427 /**
428  * @brief	Read a ADC sequence global data register
429  * @param	pADC		: The base of ADC peripheral on the chip
430  * @param	seqIndex	: Sequencer to read
431  * @return	Current raw value of the ADC sequence A or B global data register
432  * @note	This function returns the raw value of the data register and clears
433  * the overrun and datavalid status for the register. Once this register is read,
434  * the following functions can be used to parse the raw value:<br>
435  * uint32_t adcDataRawValue = Chip_ADC_ReadSequencerDataReg(LPC_ADC, ADC_SEQA_IDX); // Get raw value
436  * uint32_t adcDataValue = ADC_DR_RESULT(adcDataRawValue); // Aligned and masked ADC data value
437  * ADC_DR_THCMPRANGE_T adcRange = (ADC_DR_THCMPRANGE_T) ADC_DR_THCMPRANGE(adcDataRawValue); // Sample range compared to threshold low/high
438  * ADC_DR_THCMPCROSS_T adcRange = (ADC_DR_THCMPCROSS_T) ADC_DR_THCMPCROSS(adcDataRawValue); // Sample cross compared to threshold low
439  * uint32_t channel = ADC_DR_CHANNEL(adcDataRawValue); // ADC channel for this sample/data
440  * bool adcDataOverrun = (bool) ((adcDataRawValue & ADC_DR_OVERRUN) != 0); // Data overrun flag
441  * bool adcDataValid = (bool) ((adcDataRawValue & ADC_SEQ_GDAT_DATAVALID) != 0); // Data valid flag
442  */
Chip_ADC_GetSequencerDataReg(LPC_ADC_T * pADC,ADC_SEQ_IDX_T seqIndex)443 STATIC INLINE uint32_t Chip_ADC_GetSequencerDataReg(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
444 {
445 	return pADC->SEQ_GDAT[seqIndex];
446 }
447 
448 /**
449  * @brief	Read a ADC data register
450  * @param	pADC	: The base of ADC peripheral on the chip
451  * @param	index	: Data register to read, 1-8
452  * @return	Current raw value of the ADC data register
453  * @note	This function returns the raw value of the data register and clears
454  * the overrun and datavalid status for the register. Once this register is read,
455  * the following functions can be used to parse the raw value:<br>
456  * uint32_t adcDataRawValue = Chip_ADC_ReadSequencerDataReg(LPC_ADC, ADC_SEQA_IDX); // Get raw value
457  * uint32_t adcDataValue = ADC_DR_RESULT(adcDataRawValue); // Aligned and masked ADC data value
458  * ADC_DR_THCMPRANGE_T adcRange = (ADC_DR_THCMPRANGE_T) ADC_DR_THCMPRANGE(adcDataRawValue); // Sample range compared to threshold low/high
459  * ADC_DR_THCMPCROSS_T adcRange = (ADC_DR_THCMPCROSS_T) ADC_DR_THCMPCROSS(adcDataRawValue); // Sample cross compared to threshold low
460  * uint32_t channel = ADC_DR_CHANNEL(adcDataRawValue); // ADC channel for this sample/data
461  * bool adcDataOverrun = (bool) ((adcDataRawValue & ADC_DR_OVERRUN) != 0); // Data overrun flag
462  * bool adcDataValid = (bool) ((adcDataRawValue & ADC_SEQ_GDAT_DATAVALID) != 0); // Data valid flag
463  */
Chip_ADC_GetDataReg(LPC_ADC_T * pADC,uint8_t index)464 STATIC INLINE uint32_t Chip_ADC_GetDataReg(LPC_ADC_T *pADC, uint8_t index)
465 {
466 	return pADC->DR[index];
467 }
468 
469 /**
470  * @brief	Set Threshold low value in ADC
471  * @param	pADC		: The base of ADC peripheral on the chip
472  * @param   thrnum      : Threshold register value (1 for threshold register 1, 0 for threshold register 0)
473  * @param   value       : Threshold low data value (should be 12-bit value)
474  * @return	None
475  */
Chip_ADC_SetThrLowValue(LPC_ADC_T * pADC,uint8_t thrnum,uint16_t value)476 STATIC INLINE void Chip_ADC_SetThrLowValue(LPC_ADC_T *pADC, uint8_t thrnum, uint16_t value)
477 {
478 	pADC->THR_LOW[thrnum] = (((uint32_t) value) << ADC_THR_VAL_POS);
479 }
480 
481 /**
482  * @brief	Set Threshold high value in ADC
483  * @param	pADC	: The base of ADC peripheral on the chip
484  * @param   thrnum	: Threshold register value (1 for threshold register 1, 0 for threshold register 0)
485  * @param   value	: Threshold high data value (should be 12-bit value)
486  * @return	None
487  */
Chip_ADC_SetThrHighValue(LPC_ADC_T * pADC,uint8_t thrnum,uint16_t value)488 STATIC INLINE void Chip_ADC_SetThrHighValue(LPC_ADC_T *pADC, uint8_t thrnum, uint16_t value)
489 {
490 	pADC->THR_HIGH[thrnum] = (((uint32_t) value) << ADC_THR_VAL_POS);
491 }
492 
493 /**
494  * @brief	Select threshold 0 values for comparison for selected channels
495  * @param	pADC		: The base of ADC peripheral on the chip
496  * @param   channels	: An OR'ed value of one or more ADC_THRSEL_CHAN_SEL_THR1(ch) values
497  * @return	None
498  * @note	Select multiple channels to use the threshold 0 comparison.<br>
499  * Example:<br>
500  * Chip_ADC_SelectTH0Channels(LPC_ADC, (ADC_THRSEL_CHAN_SEL_THR1(1) | ADC_THRSEL_CHAN_SEL_THR1(2))); // Selects channels 1 and 2 for threshold 0
501  */
502 void Chip_ADC_SelectTH0Channels(LPC_ADC_T *pADC, uint32_t channels);
503 
504 /**
505  * @brief	Select threshold 1 value for comparison for selected channels
506  * @param	pADC		: The base of ADC peripheral on the chip
507  * @param   channels	: An OR'ed value of one or more ADC_THRSEL_CHAN_SEL_THR1(ch) values
508  * @return	None
509  * @note	Select multiple channels to use the 1 threshold comparison.<br>
510  * Example:<br>
511  * Chip_ADC_SelectTH1Channels(LPC_ADC, (ADC_THRSEL_CHAN_SEL_THR1(4) | ADC_THRSEL_CHAN_SEL_THR1(5))); // Selects channels 4 and 5 for 1 threshold
512  */
513 void Chip_ADC_SelectTH1Channels(LPC_ADC_T *pADC, uint32_t channels);
514 
515 /**
516  * @brief	Enable interrupts in ADC (sequencers A/B and overrun)
517  * @param	pADC	: The base of ADC peripheral on the chip
518  * @param	intMask	: Interrupt values to be enabled (see notes)
519  * @return	None
520  * @note	Select one or more OR'ed values of ADC_INTEN_SEQA_ENABLE,
521  * ADC_INTEN_SEQB_ENABLE, and ADC_INTEN_OVRRUN_ENABLE to enable the
522  * specific ADC interrupts.
523  */
524 void Chip_ADC_EnableInt(LPC_ADC_T *pADC, uint32_t intMask);
525 
526 /**
527  * @brief	Disable interrupts in ADC (sequencers A/B and overrun)
528  * @param	pADC	: The base of ADC peripheral on the chip
529  * @param	intMask	: Interrupt values to be disabled (see notes)
530  * @return	None
531  * @note	Select one or more OR'ed values of ADC_INTEN_SEQA_ENABLE,
532  * ADC_INTEN_SEQB_ENABLE, and ADC_INTEN_OVRRUN_ENABLE to disable the
533  * specific ADC interrupts.
534  */
535 void Chip_ADC_DisableInt(LPC_ADC_T *pADC, uint32_t intMask);
536 
537 /** Threshold interrupt event options */
538 typedef enum {
539 	ADC_INTEN_THCMP_DISABLE,
540 	ADC_INTEN_THCMP_OUTSIDE,
541 	ADC_INTEN_THCMP_CROSSING,
542 } ADC_INTEN_THCMP_T;
543 
544 /**
545  * @brief	Enable a threshold event interrupt in ADC
546  * @param	pADC	: The base of ADC peripheral on the chip
547  * @param	ch		: ADC channel to set threshold inetrrupt for, 1-8
548  * @param	thInt	: Selected threshold interrupt type
549  * @return	None
550  */
551 void Chip_ADC_SetThresholdInt(LPC_ADC_T *pADC, uint8_t ch, ADC_INTEN_THCMP_T thInt);
552 
553 /**
554  * @brief	Get flags register in ADC
555  * @param	pADC	: The base of ADC peripheral on the chip
556  * @return  Flags register value (ORed ADC_FLAG* values)
557  * @note	Mask the return value of this function with the ADC_FLAGS_*
558  * definitions to determine the overall ADC interrupt events.<br>
559  * Example:<br>
560  * if (Chip_ADC_GetFlags(LPC_ADC) & ADC_FLAGS_THCMP_MASK(3) // Check of threshold comp status for ADC channel 3
561  */
Chip_ADC_GetFlags(LPC_ADC_T * pADC)562 STATIC INLINE uint32_t Chip_ADC_GetFlags(LPC_ADC_T *pADC)
563 {
564 	return pADC->FLAGS;
565 }
566 
567 /**
568  * @brief	Clear flags register in ADC
569  * @param	pADC	: The base of ADC peripheral on the chip
570  * @param	flags	: An Or'ed values of ADC_FLAGS_* values to clear
571  * @return  Flags register value (ORed ADC_FLAG* values)
572  */
Chip_ADC_ClearFlags(LPC_ADC_T * pADC,uint32_t flags)573 STATIC INLINE void Chip_ADC_ClearFlags(LPC_ADC_T *pADC, uint32_t flags)
574 {
575 	pADC->FLAGS = flags;
576 }
577 
578 /**
579  * @brief	Set Trim register in ADC
580  * @param	pADC	: The base of ADC peripheral on the chip
581  * @param	trim	: Trim value (ADC_TRIM_VRANGE_HIGHV or ADC_TRIM_VRANGE_LOWV)
582  * @return	None
583  */
Chip_ADC_SetTrim(LPC_ADC_T * pADC,uint32_t trim)584 STATIC INLINE void Chip_ADC_SetTrim(LPC_ADC_T *pADC, uint32_t trim)
585 {
586 	pADC->TRM = trim;
587 }
588 
589 /**
590  * @}
591  */
592 
593 #ifdef __cplusplus
594 }
595 #endif
596 
597 #endif /* __ADC_15XX_H_ */
598