lpc-field

Template project for programming NXP's LPC1768 MCUs
git clone git://git.mdnr.space/lpc-field
Log | Files | Refs | README | LICENSE

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