fix for mbed lib issue 3 (i2c problem) see also https://mbed.org/users/mbed_official/code/mbed/issues/3 affected implementations: LPC812, LPC11U24, LPC1768, LPC2368, LPC4088
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, 0x01}, 00032 {P0_24, ADC0_1, 0x01}, 00033 {P0_25, ADC0_2, 0x01}, 00034 {P0_26, ADC0_3, 0x01}, 00035 {P1_30, ADC0_4, 0x03}, 00036 {P1_31, ADC0_5, 0x03}, 00037 {P0_12, ADC0_6, 0x03}, 00038 {P0_13, ADC0_7, 0x03}, 00039 {NC , NC , 0 } 00040 }; 00041 00042 #define ADC_RANGE ADC_12BIT_RANGE 00043 00044 void analogin_init(analogin_t *obj, PinName pin) { 00045 obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); 00046 if (obj->adc == (uint32_t)NC) { 00047 error("ADC pin mapping failed"); 00048 } 00049 00050 // ensure power is turned on 00051 LPC_SC->PCONP |= (1 << 12); 00052 00053 uint32_t PCLK = PeripheralClock ; 00054 00055 // calculate minimum clock divider 00056 // clkdiv = divider - 1 00057 uint32_t MAX_ADC_CLK = 12400000; 00058 uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1; 00059 00060 // Set the generic software-controlled ADC settings 00061 LPC_ADC->CR = (0 << 0) // SEL: 0 = no channels selected 00062 | (clkdiv << 8) // CLKDIV: 00063 | (0 << 16) // BURST: 0 = software control 00064 | (1 << 21) // PDN: 1 = operational 00065 | (0 << 24) // START: 0 = no start 00066 | (0 << 27); // EDGE: not applicable 00067 00068 // must enable analog mode (ADMODE = 0) 00069 __IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin); 00070 *reg &= ~(1 << 7); 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 >> 4) & ADC_RANGE; // 12 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 << 4) | ((value >> 8) & 0x000F); // 12 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