Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-src by
analogin_api.c
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "analogin_api.h" 00017 #include "cmsis.h" 00018 #include "pinmap.h" 00019 #include "error.h" 00020 00021 #define ANALOGIN_MEDIAN_FILTER 1 00022 00023 #define ADC_10BIT_RANGE 0x3FF 00024 #define ADC_12BIT_RANGE 0xFFF 00025 00026 static inline int div_round_up(int x, int y) { 00027 return (x + (y - 1)) / y; 00028 } 00029 00030 static const PinMap PinMap_ADC[] = { 00031 {P0_23, ADC0_0, 1}, 00032 {P0_24, ADC0_1, 1}, 00033 {P0_25, ADC0_2, 1}, 00034 {P0_26, ADC0_3, 1}, 00035 {P1_30, ADC0_4, 3}, 00036 {P1_31, ADC0_5, 3}, 00037 {NC, NC, 0} 00038 }; 00039 00040 #define ADC_RANGE ADC_10BIT_RANGE 00041 00042 00043 void analogin_init(analogin_t *obj, PinName pin) { 00044 obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); 00045 if (obj->adc == (uint32_t)NC) { 00046 error("ADC pin mapping failed"); 00047 } 00048 00049 // ensure power is turned on 00050 LPC_SC->PCONP |= (1 << 12); 00051 00052 // set PCLK of ADC to /1 00053 LPC_SC->PCLKSEL0 &= ~(0x3 << 24); 00054 LPC_SC->PCLKSEL0 |= (0x1 << 24); 00055 uint32_t PCLK = SystemCoreClock; 00056 00057 // calculate minimum clock divider 00058 // clkdiv = divider - 1 00059 uint32_t MAX_ADC_CLK = 13000000; 00060 uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1; 00061 00062 // Set the generic software-controlled ADC settings 00063 LPC_ADC->ADCR = (0 << 0) // SEL: 0 = no channels selected 00064 | (clkdiv << 8) // CLKDIV: PCLK max ~= 25MHz, /25 to give safe 1MHz at fastest 00065 | (0 << 16) // BURST: 0 = software control 00066 | (0 << 17) // CLKS: not applicable 00067 | (1 << 21) // PDN: 1 = operational 00068 | (0 << 24) // START: 0 = no start 00069 | (0 << 27); // EDGE: not applicable 00070 00071 pinmap_pinout(pin, PinMap_ADC); 00072 } 00073 00074 static inline uint32_t adc_read(analogin_t *obj) { 00075 // Select the appropriate channel and start conversion 00076 LPC_ADC->ADCR &= ~0xFF; 00077 LPC_ADC->ADCR |= 1 << (int)obj->adc; 00078 LPC_ADC->ADCR |= 1 << 24; 00079 00080 // Repeatedly get the sample data until DONE bit 00081 unsigned int data; 00082 do { 00083 data = LPC_ADC->ADGDR; 00084 } while ((data & ((unsigned int)1 << 31)) == 0); 00085 00086 // Stop conversion 00087 LPC_ADC->ADCR &= ~(1 << 24); 00088 00089 return (data >> 6) & ADC_RANGE; // 10 bit 00090 } 00091 00092 static inline void order(uint32_t *a, uint32_t *b) { 00093 if (*a > *b) { 00094 uint32_t t = *a; 00095 *a = *b; 00096 *b = t; 00097 } 00098 } 00099 00100 static inline uint32_t adc_read_u32(analogin_t *obj) { 00101 uint32_t value; 00102 #if ANALOGIN_MEDIAN_FILTER 00103 uint32_t v1 = adc_read(obj); 00104 uint32_t v2 = adc_read(obj); 00105 uint32_t v3 = adc_read(obj); 00106 order(&v1, &v2); 00107 order(&v2, &v3); 00108 order(&v1, &v2); 00109 value = v2; 00110 #else 00111 value = adc_read(obj); 00112 #endif 00113 return value; 00114 } 00115 00116 uint16_t analogin_read_u16(analogin_t *obj) { 00117 uint32_t value = adc_read_u32(obj); 00118 00119 return (value << 6) | ((value >> 4) & 0x003F); // 10 bit 00120 } 00121 00122 float analogin_read(analogin_t *obj) { 00123 uint32_t value = adc_read_u32(obj); 00124 return (float)value * (1.0f / (float)ADC_RANGE); 00125 }
Generated on Tue Jul 12 2022 13:47:00 by
1.7.2
