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_11, ADC0_0, 0x02}, 00032 {P0_12, ADC0_1, 0x02}, 00033 {P0_13, ADC0_2, 0x02}, 00034 {P0_14, ADC0_3, 0x02}, 00035 {P0_15, ADC0_4, 0x02}, 00036 {P0_16, ADC0_5, 0x01}, 00037 {P0_22, ADC0_6, 0x01}, 00038 {P0_23, ADC0_7, 0x01}, 00039 {NC , NC , 0 } 00040 }; 00041 00042 #define LPC_IOCON0_BASE (LPC_IOCON_BASE) 00043 #define LPC_IOCON1_BASE (LPC_IOCON_BASE + 0x60) 00044 00045 #define ADC_RANGE ADC_10BIT_RANGE 00046 00047 void analogin_init(analogin_t *obj, PinName pin) { 00048 obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); 00049 if (obj->adc == (uint32_t)NC) { 00050 error("ADC pin mapping failed"); 00051 } 00052 00053 // Power up ADC 00054 LPC_SYSCON->PDRUNCFG &= ~ (1 << 4); 00055 LPC_SYSCON->SYSAHBCLKCTRL |= ((uint32_t)1 << 13); 00056 00057 uint32_t pin_number = (uint32_t)pin; 00058 __IO uint32_t *reg = (pin_number < 32) ? (__IO uint32_t*)(LPC_IOCON0_BASE + 4 * pin_number) : (__IO uint32_t*)(LPC_IOCON1_BASE + 4 * (pin_number - 32)); 00059 00060 // set pin to ADC mode 00061 *reg &= ~(1 << 7); // set ADMODE = 0 (analog mode) 00062 00063 uint32_t PCLK = SystemCoreClock; 00064 uint32_t MAX_ADC_CLK = 4500000; 00065 uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1; 00066 00067 LPC_ADC->CR = (0 << 0) // no channels selected 00068 | (clkdiv << 8) // max of 4.5MHz 00069 | (0 << 16) // BURST = 0, software controlled 00070 | ( 0 << 17 ); // CLKS = 0, not applicable 00071 00072 pinmap_pinout(pin, PinMap_ADC); 00073 } 00074 00075 static inline uint32_t adc_read(analogin_t *obj) { 00076 // Select the appropriate channel and start conversion 00077 LPC_ADC->CR &= ~0xFF; 00078 LPC_ADC->CR |= 1 << (int)obj->adc; 00079 LPC_ADC->CR |= 1 << 24; 00080 00081 // Repeatedly get the sample data until DONE bit 00082 unsigned int data; 00083 do { 00084 data = LPC_ADC->GDR; 00085 } while ((data & ((unsigned int)1 << 31)) == 0); 00086 00087 // Stop conversion 00088 LPC_ADC->CR &= ~(1 << 24); 00089 00090 return (data >> 6) & ADC_RANGE; // 10 bit 00091 } 00092 00093 static inline void order(uint32_t *a, uint32_t *b) { 00094 if (*a > *b) { 00095 uint32_t t = *a; 00096 *a = *b; 00097 *b = t; 00098 } 00099 } 00100 00101 static inline uint32_t adc_read_u32(analogin_t *obj) { 00102 uint32_t value; 00103 #if ANALOGIN_MEDIAN_FILTER 00104 uint32_t v1 = adc_read(obj); 00105 uint32_t v2 = adc_read(obj); 00106 uint32_t v3 = adc_read(obj); 00107 order(&v1, &v2); 00108 order(&v2, &v3); 00109 order(&v1, &v2); 00110 value = v2; 00111 #else 00112 value = adc_read(obj); 00113 #endif 00114 return value; 00115 } 00116 00117 uint16_t analogin_read_u16(analogin_t *obj) { 00118 uint32_t value = adc_read_u32(obj); 00119 00120 return (value << 6) | ((value >> 4) & 0x003F); // 10 bit 00121 } 00122 00123 float analogin_read(analogin_t *obj) { 00124 uint32_t value = adc_read_u32(obj); 00125 return (float)value * (1.0f / (float)ADC_RANGE); 00126 }
Generated on Tue Jul 12 2022 13:47:00 by
1.7.2
