]>
git.gir.st - tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/analogin_api.c
1 /* mbed Microcontroller Library
2 * Copyright (c) 2006-2013 ARM Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 * Ported to NXP LPC43XX by Micromint USA <support@micromint.com>
18 #include "mbed_assert.h"
19 #include "analogin_api.h"
22 #include "mbed_error.h"
25 #define ANALOGIN_MEDIAN_FILTER 1
27 static inline int div_round_up(int x
, int y
) {
28 return (x
+ (y
- 1)) / y
;
31 static const PinMap PinMap_ADC
[] = {
50 void analogin_init(analogin_t
*obj
, PinName pin
) {
53 name
= (ADCName
)pinmap_peripheral(pin
, PinMap_ADC
);
54 MBED_ASSERT(obj
->adc
!= (LPC_ADC_T
*)NC
);
56 // Set ADC register, number and channel
57 obj
->num
= (name
>> ADC0_7
) ? 1 : 0;
58 obj
->ch
= name
% (ADC0_7
+ 1);
59 obj
->adc
= (LPC_ADC_T
*) (obj
->num
> 0) ? LPC_ADC1
: LPC_ADC0
;
61 // Reset pin function to GPIO
63 // Select ADC on analog function select register in SCU
64 LPC_SCU
->ENAIO
[obj
->num
] |= (1 << obj
->ch
);
66 // Calculate minimum clock divider
67 // clkdiv = divider - 1
68 uint32_t PCLK
= SystemCoreClock
;
69 uint32_t adcRate
= 400000;
70 uint32_t clkdiv
= div_round_up(PCLK
, adcRate
) - 1;
72 // Set the generic software-controlled ADC settings
73 obj
->adc
->CR
= (0 << 0) // SEL: 0 = no channels selected
74 | (clkdiv
<< 8) // CLKDIV:
75 | (0 << 16) // BURST: 0 = software control
76 | (1 << 21) // PDN: 1 = operational
77 | (0 << 24) // START: 0 = no start
78 | (0 << 27); // EDGE: not applicable
81 static inline uint32_t adc_read(analogin_t
*obj
) {
83 uint8_t channel
= obj
->ch
;
84 LPC_ADC_T
*pADC
= obj
->adc
;
86 // Select the appropriate channel and start conversion
87 pADC
->CR
|= ADC_CR_CH_SEL(channel
);
88 temp
= pADC
->CR
& ~ADC_CR_START_MASK
;
89 pADC
->CR
= temp
| (ADC_CR_START_MODE_SEL(ADC_START_NOW
));
91 // Wait for DONE bit and read data
92 while (!(pADC
->STAT
& ADC_CR_CH_SEL(channel
)));
93 temp
= pADC
->DR
[channel
];
95 // Deselect channel and return result
96 pADC
->CR
&= ~ADC_CR_START_MASK
;
97 pADC
->CR
&= ~ADC_CR_CH_SEL(channel
);
98 return ADC_DR_RESULT(temp
);
101 static inline void order(uint32_t *a
, uint32_t *b
) {
109 static inline uint32_t adc_read_u32(analogin_t
*obj
) {
111 #if ANALOGIN_MEDIAN_FILTER
112 uint32_t v1
= adc_read(obj
);
113 uint32_t v2
= adc_read(obj
);
114 uint32_t v3
= adc_read(obj
);
120 value
= adc_read(obj
);
125 uint16_t analogin_read_u16(analogin_t
*obj
) {
126 uint32_t value
= adc_read_u32(obj
);
128 return (value
<< 6) | ((value
>> 4) & 0x003F); // 10 bit
131 float analogin_read(analogin_t
*obj
) {
132 uint32_t value
= adc_read_u32(obj
);
133 return (float)value
* (1.0f
/ (float)ADC_RANGE
);