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 #include "chip.h"
33
34 /*****************************************************************************
35 * Private types/enumerations/variables
36 ****************************************************************************/
37
38 /*****************************************************************************
39 * Public types/enumerations/variables
40 ****************************************************************************/
41
42 /*****************************************************************************
43 * Private functions
44 ****************************************************************************/
45
46 /* Set ADC interrupt bits (safe) */
Chip_ADC_SetIntBits(LPC_ADC_T * pADC,uint32_t intMask)47 void Chip_ADC_SetIntBits(LPC_ADC_T *pADC, uint32_t intMask)
48 {
49 uint32_t temp;
50
51 /* Read and write values may not be the same, write 0 to
52 undefined bits */
53 temp = pADC->INTEN & 0x07FFFFFF;
54
55 pADC->INTEN = temp | intMask;
56 }
57
58 /* Clear ADC interrupt bits (safe) */
Chip_ADC_ClearIntBits(LPC_ADC_T * pADC,uint32_t intMask)59 void Chip_ADC_ClearIntBits(LPC_ADC_T *pADC, uint32_t intMask)
60 {
61 uint32_t temp;
62
63 /* Read and write values may not be the same, write 0 to
64 undefined bits */
65 temp = pADC->INTEN & 0x07FFFFFF;
66
67 pADC->INTEN = temp & ~intMask;
68 }
69
70 /* Set ADC threshold selection bits (safe) */
Chip_ADC_SetTHRSELBits(LPC_ADC_T * pADC,uint32_t mask)71 void Chip_ADC_SetTHRSELBits(LPC_ADC_T *pADC, uint32_t mask)
72 {
73 uint32_t temp;
74
75 /* Read and write values may not be the same, write 0 to
76 undefined bits */
77 temp = pADC->CHAN_THRSEL & 0x00000FFF;
78
79 pADC->CHAN_THRSEL = temp | mask;
80 }
81
82 /* Clear ADC threshold selection bits (safe) */
Chip_ADC_ClearTHRSELBits(LPC_ADC_T * pADC,uint32_t mask)83 void Chip_ADC_ClearTHRSELBits(LPC_ADC_T *pADC, uint32_t mask)
84 {
85 uint32_t temp;
86
87 /* Read and write values may not be the same, write 0 to
88 undefined bits */
89 temp = pADC->CHAN_THRSEL & 0x00000FFF;
90
91 pADC->CHAN_THRSEL = temp & ~mask;
92 }
93
94 /*****************************************************************************
95 * Public functions
96 ****************************************************************************/
97
98 /* Initialize the ADC peripheral */
Chip_ADC_Init(LPC_ADC_T * pADC,uint32_t flags)99 void Chip_ADC_Init(LPC_ADC_T *pADC, uint32_t flags)
100 {
101 /* Power up ADC and enable ADC base clock */
102 if (pADC == LPC_ADC0) {
103 Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_ADC0_PD);
104 Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_ADC0);
105 Chip_SYSCTL_PeriphReset(RESET_ADC0);
106 }
107 else {
108 Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_ADC1_PD);
109 Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_ADC1);
110 Chip_SYSCTL_PeriphReset(RESET_ADC1);
111 }
112
113 /* Disable ADC interrupts */
114 pADC->INTEN = 0;
115
116 /* Set ADC control options */
117 pADC->CTRL = flags;
118 }
119
120 /* Shutdown ADC */
Chip_ADC_DeInit(LPC_ADC_T * pADC)121 void Chip_ADC_DeInit(LPC_ADC_T *pADC)
122 {
123 pADC->INTEN = 0;
124 pADC->CTRL = 0;
125
126 /* Stop ADC clock and then power down ADC */
127 if (pADC == LPC_ADC0) {
128 Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_ADC0);
129 Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_ADC0_PD);
130 }
131 else {
132 Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_ADC1);
133 Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_ADC1_PD);
134 }
135 }
136
137 /* Set ADC clock rate */
Chip_ADC_SetClockRate(LPC_ADC_T * pADC,uint32_t rate)138 void Chip_ADC_SetClockRate(LPC_ADC_T *pADC, uint32_t rate)
139 {
140 uint32_t div;
141
142 /* Get ADC clock source to determine base ADC rate. IN sychronous mode,
143 the ADC base clock comes from the system clock. In ASYNC mode, it
144 comes from the ASYNC ADC clock and this function doesn't work. */
145 div = Chip_Clock_GetSystemClockRate() / rate;
146 if (div == 0) {
147 div = 1;
148 }
149
150 Chip_ADC_SetDivider(pADC, (uint8_t) div - 1);
151 }
152
153 /* Start ADC calibration */
Chip_ADC_StartCalibration(LPC_ADC_T * pADC)154 void Chip_ADC_StartCalibration(LPC_ADC_T *pADC)
155 {
156 /* Set calibration mode */
157 pADC->CTRL |= ADC_CR_CALMODEBIT;
158
159 /* Clear ASYNC bit */
160 pADC->CTRL &= ~ADC_CR_ASYNMODE;
161
162 /* Setup ADC for about 500KHz (per UM) */
163 Chip_ADC_SetClockRate(pADC, 500000);
164
165 /* Clearn low power bit */
166 pADC->CTRL &= ~ADC_CR_LPWRMODEBIT;
167
168 /* Calibration is only complete when ADC_CR_CALMODEBIT bit has cleared */
169 }
170
171 /* Helper function for safely setting ADC sequencer register bits */
Chip_ADC_SetSequencerBits(LPC_ADC_T * pADC,ADC_SEQ_IDX_T seqIndex,uint32_t bits)172 void Chip_ADC_SetSequencerBits(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t bits)
173 {
174 uint32_t temp;
175
176 /* Read sequencer register and mask off bits 20..25 */
177 temp = pADC->SEQ_CTRL[seqIndex] & ~(0x3F << 20);
178
179 /* OR in passed bits */
180 pADC->SEQ_CTRL[seqIndex] = temp | bits;
181 }
182
183 /* Helper function for safely clearing ADC sequencer register bits */
Chip_ADC_ClearSequencerBits(LPC_ADC_T * pADC,ADC_SEQ_IDX_T seqIndex,uint32_t bits)184 void Chip_ADC_ClearSequencerBits(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t bits)
185 {
186 uint32_t temp;
187
188 /* Read sequencer register and mask off bits 20..25 */
189 temp = pADC->SEQ_CTRL[seqIndex] & ~(0x3F << 20);
190
191 /* OR in passed bits */
192 pADC->SEQ_CTRL[seqIndex] = temp & ~bits;
193 }
194
195 /* Enable interrupts in ADC (sequencers A/B and overrun) */
Chip_ADC_EnableInt(LPC_ADC_T * pADC,uint32_t intMask)196 void Chip_ADC_EnableInt(LPC_ADC_T *pADC, uint32_t intMask)
197 {
198 Chip_ADC_SetIntBits(pADC, intMask);
199 }
200
201 /* Disable interrupts in ADC (sequencers A/B and overrun) */
Chip_ADC_DisableInt(LPC_ADC_T * pADC,uint32_t intMask)202 void Chip_ADC_DisableInt(LPC_ADC_T *pADC, uint32_t intMask)
203 {
204 Chip_ADC_ClearIntBits(pADC, intMask);
205 }
206
207 /* Enable a threshold event interrupt in ADC */
Chip_ADC_SetThresholdInt(LPC_ADC_T * pADC,uint8_t ch,ADC_INTEN_THCMP_T thInt)208 void Chip_ADC_SetThresholdInt(LPC_ADC_T *pADC, uint8_t ch, ADC_INTEN_THCMP_T thInt)
209 {
210 int shiftIndex = 3 + (ch * 2);
211
212 /* Clear current bits first */
213 Chip_ADC_ClearIntBits(pADC, (ADC_INTEN_CMP_MASK << shiftIndex));
214
215 /* Set new threshold interrupt type */
216 Chip_ADC_SetIntBits(pADC, ((uint32_t) thInt << shiftIndex));
217 }
218
219 /* Select threshold 0 values for comparison for selected channels */
Chip_ADC_SelectTH0Channels(LPC_ADC_T * pADC,uint32_t channels)220 void Chip_ADC_SelectTH0Channels(LPC_ADC_T *pADC, uint32_t channels)
221 {
222 Chip_ADC_ClearTHRSELBits(pADC, channels);
223 }
224
225 /* Select threshold 1 value for comparison for selected channels */
Chip_ADC_SelectTH1Channels(LPC_ADC_T * pADC,uint32_t channels)226 void Chip_ADC_SelectTH1Channels(LPC_ADC_T *pADC, uint32_t channels)
227 {
228 Chip_ADC_SetTHRSELBits(pADC, channels);
229 }
230