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