]> git.sur5r.net Git - freertos/blob
ded86e7dd1cb2465f39d3a91204675d8fb844208
[freertos] /
1 /**********************************************************************\r
2 * $Id$          lpc18xx_adc.c           2011-06-02\r
3 *//**\r
4 * @file         lpc18xx_adc.c\r
5 * @brief        Contains all functions support for ADC firmware library on LPC18xx\r
6 * @version      1.0\r
7 * @date         02. June. 2011\r
8 * @author       NXP MCU SW Application Team\r
9 *\r
10 * Copyright(C) 2011, NXP Semiconductor\r
11 * All rights reserved.\r
12 *\r
13 ***********************************************************************\r
14 * Software that is described herein is for illustrative purposes only\r
15 * which provides customers with programming information regarding the\r
16 * products. This software is supplied "AS IS" without any warranties.\r
17 * NXP Semiconductors assumes no responsibility or liability for the\r
18 * use of the software, conveys no license or title under any patent,\r
19 * copyright, or mask work right to the product. NXP Semiconductors\r
20 * reserves the right to make changes in the software without\r
21 * notification. NXP Semiconductors also make no representation or\r
22 * warranty that such application will be suitable for the specified\r
23 * use without further testing or modification.\r
24 **********************************************************************/\r
25 \r
26 /* Peripheral group ----------------------------------------------------------- */\r
27 /** @addtogroup ADC\r
28  * @{\r
29  */\r
30 \r
31 /* Includes ------------------------------------------------------------------- */\r
32 #include "lpc18xx_adc.h"\r
33 #include "lpc18xx_cgu.h"\r
34 \r
35 /* If this source file built with example, the LPC18xx FW library configuration\r
36  * file in each example directory ("lpc18xx_libcfg.h") must be included,\r
37  * otherwise the default FW library configuration file must be included instead\r
38  */\r
39 #ifdef __BUILD_WITH_EXAMPLE__\r
40 #include "lpc18xx_libcfg.h"\r
41 #else\r
42 #include "lpc18xx_libcfg_default.h"\r
43 #endif /* __BUILD_WITH_EXAMPLE__ */\r
44 \r
45 \r
46 #ifdef _ADC\r
47 /* Public Functions ----------------------------------------------------------- */\r
48 /** @addtogroup ADC_Public_Functions\r
49  * @{\r
50  */\r
51 \r
52 /*********************************************************************//**\r
53  * @brief               Initial for ADC\r
54  *                                      + Set bit PCADC\r
55  *                                      + Set clock for ADC\r
56  *                                      + Set Clock Frequency\r
57  * @param[in]   ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC\r
58  * @param[in]   rate ADC conversion rate, should be <=200KHz\r
59  * @param[in]   bits_accuracy number of bits accuracy, should be <=10 bits and >=3bits\r
60  * @return              None\r
61  **********************************************************************/\r
62 void ADC_Init(LPC_ADCn_Type *ADCx, uint32_t rate, uint8_t bits_accuracy)\r
63 {\r
64         uint32_t temp, tmpreg, ADCbitrate;\r
65 \r
66         CHECK_PARAM(PARAM_ADCx(ADCx));\r
67         CHECK_PARAM(PARAM_ADC_RATE(rate));\r
68 \r
69         // Turn on power and clock\r
70         //CGU_ConfigPPWR (CGU_PCONP_PCAD, ENABLE);\r
71 \r
72         ADCx->CR = 0;\r
73 \r
74         //Enable PDN bit\r
75         tmpreg = ADC_CR_PDN;\r
76         // Set clock frequency\r
77         if(ADCx == LPC_ADC0)\r
78                 temp = CGU_GetPCLKFrequency(CGU_PERIPHERAL_ADC0);\r
79         else if(ADCx == LPC_ADC1)\r
80                 temp = CGU_GetPCLKFrequency(CGU_PERIPHERAL_ADC1);\r
81         /* The APB clock (PCLK_ADC0) is divided by (CLKDIV+1) to produce the clock for\r
82          * A/D converter, which should be less than or equal to 13MHz.\r
83          * A fully conversion requires (bits_accuracy+1) of these clocks.\r
84          * ADC clock = PCLK_ADC0 / (CLKDIV + 1);\r
85          * ADC rate = ADC clock / (bits_accuracy+1);
86          */\r
87          ADCbitrate = (rate * (bits_accuracy+1));\r
88         temp = ((temp*2 + ADCbitrate) / (ADCbitrate*2)) - 1;//get the round value by fomular: (2*A + B)/(2*B)\r
89         tmpreg |=  ADC_CR_CLKDIV(temp) | ADC_CR_BITACC(10 - bits_accuracy);\r
90 \r
91         ADCx->CR = tmpreg;\r
92 }\r
93 \r
94 \r
95 /*********************************************************************//**\r
96 * @brief                Close ADC\r
97 * @param[in]    ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC\r
98 * @return               None\r
99 **********************************************************************/\r
100 void ADC_DeInit(LPC_ADCn_Type *ADCx)\r
101 {\r
102         CHECK_PARAM(PARAM_ADCx(ADCx));\r
103 \r
104         // Clear PDN bit\r
105         ADCx->CR &= ~ADC_CR_PDN;\r
106         // Turn on power and clock\r
107         //CGU_ConfigPPWR (CGU_PCONP_PCAD, DISABLE);\r
108 }\r
109 \r
110 \r
111 ///*********************************************************************//**\r
112 //* @brief              Get Result conversion from A/D data register\r
113 //* @param[in]  channel number which want to read back the result\r
114 //* @return             Result of conversion\r
115 //*********************************************************************/\r
116 //uint32_t ADC_GetData(uint32_t channel)\r
117 //{\r
118 //      uint32_t adc_value;\r
119 //\r
120 //      CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));\r
121 //\r
122 //      adc_value = *(uint32_t *)((&LPC_ADC->DR0) + channel);\r
123 //      return ADC_GDR_RESULT(adc_value);\r
124 //}\r
125 \r
126 /*********************************************************************//**\r
127 * @brief                Set start mode for ADC\r
128 * @param[in]    ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC\r
129 * @param[in]    start_mode Start mode choose one of modes in\r
130 *                               'ADC_START_OPT' enumeration type definition, should be:\r
131 *                                       - ADC_START_CONTINUOUS\r
132 *                                       - ADC_START_NOW\r
133 *                                       - ADC_START_ON_EINT0\r
134 *                                       - ADC_START_ON_CAP01\r
135 *                                       - ADC_START_ON_MAT01\r
136 *                                       - ADC_START_ON_MAT03\r
137 *                                       - ADC_START_ON_MAT10\r
138 *                                       - ADC_START_ON_MAT11\r
139 * @return               None\r
140 *********************************************************************/\r
141 void ADC_StartCmd(LPC_ADCn_Type *ADCx, uint8_t start_mode)\r
142 {\r
143         CHECK_PARAM(PARAM_ADCx(ADCx));\r
144         CHECK_PARAM(PARAM_ADC_START_OPT(start_mode));\r
145 \r
146         ADCx->CR &= ~ADC_CR_START_MASK;\r
147         ADCx->CR |=ADC_CR_START_MODE_SEL((uint32_t)start_mode);\r
148 }\r
149 \r
150 \r
151 /*********************************************************************//**\r
152 * @brief                ADC Burst mode setting\r
153 * @param[in]    ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC\r
154 * @param[in]    NewState\r
155 *                                       - 1: Set Burst mode\r
156 *                                       - 0: reset Burst mode\r
157 * @return               None\r
158 **********************************************************************/\r
159 void ADC_BurstCmd(LPC_ADCn_Type *ADCx, FunctionalState NewState)\r
160 {\r
161         CHECK_PARAM(PARAM_ADCx(ADCx));\r
162 \r
163         ADCx->CR &= ~ADC_CR_BURST;\r
164         if (NewState){\r
165                 ADCx->CR |= ADC_CR_BURST;\r
166         }\r
167 }\r
168 \r
169 /*********************************************************************//**\r
170 * @brief                Set AD conversion in power mode\r
171 * @param[in]    ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC\r
172 * @param[in]    NewState\r
173 *                                       - 1: AD converter is optional\r
174 *                                       - 0: AD Converter is in power down mode\r
175 * @return               None\r
176 **********************************************************************/\r
177 void ADC_PowerdownCmd(LPC_ADCn_Type *ADCx, FunctionalState NewState)\r
178 {\r
179         CHECK_PARAM(PARAM_ADCx(ADCx));\r
180 \r
181         ADCx->CR &= ~ADC_CR_PDN;\r
182         if (NewState){\r
183                 ADCx->CR |= ADC_CR_PDN;\r
184         }\r
185 }\r
186 \r
187 /*********************************************************************//**\r
188 * @brief                Set Edge start configuration\r
189 * @param[in]    ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC\r
190 * @param[in]    EdgeOption is ADC_START_ON_RISING and ADC_START_ON_FALLING\r
191 *                                       - 0: ADC_START_ON_RISING\r
192 *                                       - 1: ADC_START_ON_FALLING\r
193 * @return               None\r
194 **********************************************************************/\r
195 void ADC_EdgeStartConfig(LPC_ADCn_Type *ADCx, uint8_t EdgeOption)\r
196 {\r
197         CHECK_PARAM(PARAM_ADCx(ADCx));\r
198         CHECK_PARAM(PARAM_ADC_START_ON_EDGE_OPT(EdgeOption));\r
199 \r
200         ADCx->CR &= ~ADC_CR_EDGE;\r
201         if (EdgeOption){\r
202                 ADCx->CR |= ADC_CR_EDGE;\r
203         }\r
204 }\r
205 \r
206 /*********************************************************************//**\r
207 * @brief                ADC interrupt configuration\r
208 * @param[in]    ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC\r
209 * @param[in]    IntType: type of interrupt, should be:\r
210 *                                       - ADC_ADINTEN0: Interrupt channel 0\r
211 *                                       - ADC_ADINTEN1: Interrupt channel 1\r
212 *                                       ...\r
213 *                                       - ADC_ADINTEN7: Interrupt channel 7\r
214 *                                       - ADC_ADGINTEN: Individual channel/global flag done generate an interrupt\r
215 * @param[in]    NewState:\r
216 *                                       - SET : enable ADC interrupt\r
217 *                                       - RESET: disable ADC interrupt\r
218 * @return               None\r
219 **********************************************************************/\r
220 void ADC_IntConfig (LPC_ADCn_Type *ADCx, ADC_TYPE_INT_OPT IntType, FunctionalState NewState)\r
221 {\r
222         CHECK_PARAM(PARAM_ADCx(ADCx));\r
223         CHECK_PARAM(PARAM_ADC_TYPE_INT_OPT(IntType));\r
224 \r
225         ADCx->INTEN &= ~ADC_INTEN_CH(IntType);\r
226         if (NewState){\r
227                 ADCx->INTEN |= ADC_INTEN_CH(IntType);\r
228         }\r
229 }\r
230 \r
231 /*********************************************************************//**\r
232 * @brief                Enable/Disable ADC channel number\r
233 * @param[in]    ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC\r
234 * @param[in]    Channel channel number\r
235 * @param[in]    NewState        New state, should be:\r
236 *                                       - ENABLE\r
237 *                                       - DISABLE\r
238 * @return               None\r
239 **********************************************************************/\r
240 void ADC_ChannelCmd (LPC_ADCn_Type *ADCx, uint8_t Channel, FunctionalState NewState)\r
241 {\r
242         CHECK_PARAM(PARAM_ADCx(ADCx));\r
243         CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(Channel));\r
244 \r
245         if (NewState == ENABLE) {\r
246                 ADCx->CR |= ADC_CR_CH_SEL(Channel);\r
247         } else {\r
248                 ADCx->CR &= ~ADC_CR_CH_SEL(Channel);\r
249         }\r
250 }\r
251 \r
252 /*********************************************************************//**\r
253 * @brief                Get ADC result\r
254 * @param[in]    ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC\r
255 * @param[in]    channel channel number, should be 0...7\r
256 * @return               Converted data\r
257 **********************************************************************/\r
258 uint16_t ADC_ChannelGetData(LPC_ADCn_Type *ADCx, uint8_t channel)\r
259 {\r
260         uint32_t adc_value;\r
261 \r
262         CHECK_PARAM(PARAM_ADCx(ADCx));\r
263         CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));\r
264 \r
265         adc_value = *(uint32_t *) ((&(ADCx->DR[0])) + channel);\r
266         return ADC_DR_RESULT(adc_value);\r
267 }\r
268 \r
269 /*********************************************************************//**\r
270 * @brief                Get ADC Channel status from ADC data register\r
271 * @param[in]    ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC\r
272 * @param[in]    channel: channel number, should be 0..7\r
273 * @param[in]    StatusType\r
274 *                       - 0: Burst status\r
275 *                       - 1: Done status\r
276 * @return               Channel status, could be:\r
277 *                                       - SET\r
278 *                                       - RESET\r
279 **********************************************************************/\r
280 FlagStatus ADC_ChannelGetStatus(LPC_ADCn_Type *ADCx, uint8_t channel, uint32_t StatusType)\r
281 {\r
282         uint32_t temp;\r
283 \r
284         CHECK_PARAM(PARAM_ADCx(ADCx));\r
285         CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));\r
286         CHECK_PARAM(PARAM_ADC_DATA_STATUS(StatusType));\r
287 \r
288         temp =  *(uint32_t *) ((&ADCx->DR[0]) + channel);\r
289         if (StatusType) {\r
290                 temp &= ADC_DR_DONE_FLAG;\r
291         }else{\r
292                 temp &= ADC_DR_OVERRUN_FLAG;\r
293         }\r
294         if (temp) {\r
295                 return SET;\r
296         } else {\r
297                 return RESET;\r
298         }\r
299 \r
300 }\r
301 \r
302 /*********************************************************************//**\r
303 * @brief                Get ADC Data from AD Global register\r
304 * @param[in]    ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC\r
305 * @return               Result of conversion\r
306 **********************************************************************/\r
307 uint32_t ADC_GlobalGetData(LPC_ADCn_Type *ADCx)\r
308 {\r
309         CHECK_PARAM(PARAM_ADCx(ADCx));\r
310 \r
311         return ((uint32_t)(ADCx->GDR));\r
312 }\r
313 \r
314 /*********************************************************************//**\r
315 * @brief                Get ADC Chanel status from AD global data register\r
316 * @param[in]    ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC\r
317 * @param[in]    StatusType\r
318 *                       - 0: Burst status\r
319 *                       - 1: Done status\r
320 * @return               SET / RESET\r
321 **********************************************************************/\r
322 FlagStatus      ADC_GlobalGetStatus(LPC_ADCn_Type *ADCx, uint32_t StatusType)\r
323 {\r
324         uint32_t temp;\r
325 \r
326         CHECK_PARAM(PARAM_ADCx(ADCx));\r
327         CHECK_PARAM(PARAM_ADC_DATA_STATUS(StatusType));\r
328 \r
329         temp =  ADCx->GDR;\r
330         if (StatusType){\r
331                 temp &= ADC_DR_DONE_FLAG;\r
332         }else{\r
333                 temp &= ADC_DR_OVERRUN_FLAG;\r
334         }\r
335         if (temp){\r
336                 return SET;\r
337         }else{\r
338                 return RESET;\r
339         }\r
340 }\r
341 \r
342 /**\r
343  * @}\r
344  */\r
345 \r
346 #endif /* _ADC */\r
347 \r
348 /**\r
349  * @}\r
350  */\r
351 \r
352 /* --------------------------------- End Of File ------------------------------ */\r
353 \r