LPCOpen Platform for LPC112X microcontrollers  112X
LPCOpen Platform for the NXP LPC112X family of Microcontrollers
adc_112x.c
Go to the documentation of this file.
1 /*
2  * @brief LPC1125 ADC driver
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
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) */
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 & 0x001FFFE7;
54 
55  pADC->INTEN = temp | intMask;
56 }
57 
58 /* Clear ADC interrupt bits (safe) */
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 & 0x001FFFE7;
66 
67  pADC->INTEN = temp & ~intMask;
68 }
69 
70 /* Set ADC threshold selection bits (safe) */
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 & 0x000001FE;
78 
79  pADC->CHAN_THRSEL = temp | mask;
80 }
81 
82 /* Clear ADC threshold selection bits (safe) */
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 & 0x000001FE;
90 
91  pADC->CHAN_THRSEL = temp & ~mask;
92 }
93 
94 /*****************************************************************************
95  * Public functions
96  ****************************************************************************/
97 
98 /* Initialize the ADC peripheral */
99 void Chip_ADC_Init(LPC_ADC_T *pADC, uint32_t flags)
100 {
101  /* Power up ADC and enable ADC base clock */
104 
105  /* FIXME - LPC1125 UM describes ADC reset, but no ADC reset bit in SYSCON.
106  It will be easier to init if ADC reset is there. */
107 
108  /* Disable ADC interrupts */
109  pADC->INTEN = 0;
110 
111  /* Set ADC control options */
112  pADC->CTRL = flags;
113 }
114 
115 /* Shutdown ADC */
117 {
118  pADC->INTEN = 0;
119  pADC->CTRL = 0;
120 
121  /* Stop ADC clock and then power down ADC */
124 }
125 
126 /* Set ADC clock rate */
127 void Chip_ADC_SetClockRate(LPC_ADC_T *pADC, uint32_t rate)
128 {
129  uint32_t div;
130 
131  /* Get ADC clock source to determine base ADC rate. IN sychronous mode,
132  the ADC base clock comes from the system clock. In ASYNC mode, it
133  comes from the ASYNC ADC clock and this function doesn't work. */
134  div = Chip_Clock_GetSystemClockRate() / rate;
135  if (div == 0) {
136  div = 1;
137  }
138 
139  Chip_ADC_SetDivider(pADC, (uint8_t) div - 1);
140 }
141 
142 /* Start ADC calibration */
144 {
145  /* Set calibration mode */
146  pADC->CTRL |= ADC_CR_CALMODEBIT;
147 
148  /* Clear ASYNC bit */
149  pADC->CTRL &= ~ADC_CR_ASYNC_MODE;
150 
151  /* Setup ADC for about 500KHz (per UM) */
152  Chip_ADC_SetClockRate(pADC, 500000);
153 
154  /* Clearn low power bit */
155  pADC->CTRL &= ~ADC_CR_LPWRMODEBIT;
156 
157  /* Calibration is only complete when ADC_CR_CALMODEBIT bit has cleared */
158 }
159 
160 /* Helper function for safely setting ADC sequencer register bits */
161 void Chip_ADC_SetSequencerBits(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t bits)
162 {
163  uint32_t temp;
164 
165  /* Read sequencer register and mask off bits 20..25 */
166  temp = pADC->SEQ_CTRL[seqIndex] & ~(0x3F << 20);
167 
168  /* OR in passed bits */
169  pADC->SEQ_CTRL[seqIndex] = temp | bits;
170 }
171 
172 /* Helper function for safely clearing ADC sequencer register bits */
173 void Chip_ADC_ClearSequencerBits(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t bits)
174 {
175  uint32_t temp;
176 
177  /* Read sequencer register and mask off bits 20..25 */
178  temp = pADC->SEQ_CTRL[seqIndex] & ~(0x3F << 20);
179 
180  /* OR in passed bits */
181  pADC->SEQ_CTRL[seqIndex] = temp & ~bits;
182 }
183 
184 /* Enable interrupts in ADC (sequencers A/B and overrun) */
185 void Chip_ADC_EnableInt(LPC_ADC_T *pADC, uint32_t intMask)
186 {
187  Chip_ADC_SetIntBits(pADC, intMask);
188 }
189 
190 /* Disable interrupts in ADC (sequencers A/B and overrun) */
191 void Chip_ADC_DisableInt(LPC_ADC_T *pADC, uint32_t intMask)
192 {
193  Chip_ADC_ClearIntBits(pADC, intMask);
194 }
195 
196 /* Enable a threshold event interrupt in ADC */
198 {
199  int shiftIndex = 3 + (ch * 2);
200 
201  /* Clear current bits first */
202  Chip_ADC_ClearIntBits(pADC, (ADC_INTEN_CMP_MASK << shiftIndex));
203 
204  /* Set new threshold interrupt type */
205  Chip_ADC_SetIntBits(pADC, ((uint32_t) thInt << shiftIndex));
206 }
207 
208 /* Select threshold 0 values for comparison for selected channels */
209 void Chip_ADC_SelectTH0Channels(LPC_ADC_T *pADC, uint32_t channels)
210 {
211  Chip_ADC_ClearTHRSELBits(pADC, channels);
212 }
213 
214 /* Select threshold 1 value for comparison for selected channels */
215 void Chip_ADC_SelectTH1Channels(LPC_ADC_T *pADC, uint32_t channels)
216 {
217  Chip_ADC_SetTHRSELBits(pADC, channels);
218 }