mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Committer:
bogdanm
Date:
Wed Aug 07 16:43:59 2013 +0300
Revision:
15:4892fe388435
Child:
29:6ac4027eff2b
Added LPC4088 target and interrupt chaining code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bogdanm 15:4892fe388435 1 /* mbed Microcontroller Library
bogdanm 15:4892fe388435 2 * Copyright (c) 2006-2013 ARM Limited
bogdanm 15:4892fe388435 3 *
bogdanm 15:4892fe388435 4 * Licensed under the Apache License, Version 2.0 (the "License");
bogdanm 15:4892fe388435 5 * you may not use this file except in compliance with the License.
bogdanm 15:4892fe388435 6 * You may obtain a copy of the License at
bogdanm 15:4892fe388435 7 *
bogdanm 15:4892fe388435 8 * http://www.apache.org/licenses/LICENSE-2.0
bogdanm 15:4892fe388435 9 *
bogdanm 15:4892fe388435 10 * Unless required by applicable law or agreed to in writing, software
bogdanm 15:4892fe388435 11 * distributed under the License is distributed on an "AS IS" BASIS,
bogdanm 15:4892fe388435 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
bogdanm 15:4892fe388435 13 * See the License for the specific language governing permissions and
bogdanm 15:4892fe388435 14 * limitations under the License.
bogdanm 15:4892fe388435 15 */
bogdanm 15:4892fe388435 16 #include "analogin_api.h"
bogdanm 15:4892fe388435 17 #include "cmsis.h"
bogdanm 15:4892fe388435 18 #include "pinmap.h"
bogdanm 15:4892fe388435 19 #include "error.h"
bogdanm 15:4892fe388435 20
bogdanm 15:4892fe388435 21 #define ANALOGIN_MEDIAN_FILTER 1
bogdanm 15:4892fe388435 22
bogdanm 15:4892fe388435 23 #define ADC_10BIT_RANGE 0x3FF
bogdanm 15:4892fe388435 24 #define ADC_12BIT_RANGE 0xFFF
bogdanm 15:4892fe388435 25
bogdanm 15:4892fe388435 26 static inline int div_round_up(int x, int y) {
bogdanm 15:4892fe388435 27 return (x + (y - 1)) / y;
bogdanm 15:4892fe388435 28 }
bogdanm 15:4892fe388435 29
bogdanm 15:4892fe388435 30 static const PinMap PinMap_ADC[] = {
bogdanm 15:4892fe388435 31 {P0_23, ADC0_0, 0x01},
bogdanm 15:4892fe388435 32 {P0_24, ADC0_1, 0x01},
bogdanm 15:4892fe388435 33 {P0_25, ADC0_2, 0x01},
bogdanm 15:4892fe388435 34 {P0_26, ADC0_3, 0x01},
bogdanm 15:4892fe388435 35 {P1_30, ADC0_4, 0x03},
bogdanm 15:4892fe388435 36 {P1_31, ADC0_5, 0x03},
bogdanm 15:4892fe388435 37 {P0_12, ADC0_6, 0x03},
bogdanm 15:4892fe388435 38 {P0_13, ADC0_7, 0x03},
bogdanm 15:4892fe388435 39 {NC , NC , 0 }
bogdanm 15:4892fe388435 40 };
bogdanm 15:4892fe388435 41
bogdanm 15:4892fe388435 42 #define ADC_RANGE ADC_12BIT_RANGE
bogdanm 15:4892fe388435 43
bogdanm 15:4892fe388435 44 void analogin_init(analogin_t *obj, PinName pin) {
bogdanm 15:4892fe388435 45 obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
bogdanm 15:4892fe388435 46 if (obj->adc == (uint32_t)NC) {
bogdanm 15:4892fe388435 47 error("ADC pin mapping failed");
bogdanm 15:4892fe388435 48 }
bogdanm 15:4892fe388435 49
bogdanm 15:4892fe388435 50 // ensure power is turned on
bogdanm 15:4892fe388435 51 LPC_SC->PCONP |= (1 << 12);
bogdanm 15:4892fe388435 52
bogdanm 15:4892fe388435 53 uint32_t PCLK = PeripheralClock;
bogdanm 15:4892fe388435 54
bogdanm 15:4892fe388435 55 // calculate minimum clock divider
bogdanm 15:4892fe388435 56 // clkdiv = divider - 1
bogdanm 15:4892fe388435 57 uint32_t MAX_ADC_CLK = 12400000;
bogdanm 15:4892fe388435 58 uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1;
bogdanm 15:4892fe388435 59
bogdanm 15:4892fe388435 60 // Set the generic software-controlled ADC settings
bogdanm 15:4892fe388435 61 LPC_ADC->CR = (0 << 0) // SEL: 0 = no channels selected
bogdanm 15:4892fe388435 62 | (clkdiv << 8) // CLKDIV:
bogdanm 15:4892fe388435 63 | (0 << 16) // BURST: 0 = software control
bogdanm 15:4892fe388435 64 | (1 << 21) // PDN: 1 = operational
bogdanm 15:4892fe388435 65 | (0 << 24) // START: 0 = no start
bogdanm 15:4892fe388435 66 | (0 << 27); // EDGE: not applicable
bogdanm 15:4892fe388435 67
bogdanm 15:4892fe388435 68 // must enable analog mode (ADMODE = 0)
bogdanm 15:4892fe388435 69 __IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin);
bogdanm 15:4892fe388435 70 *reg &= ~(1 << 7);
bogdanm 15:4892fe388435 71
bogdanm 15:4892fe388435 72 pinmap_pinout(pin, PinMap_ADC);
bogdanm 15:4892fe388435 73 }
bogdanm 15:4892fe388435 74
bogdanm 15:4892fe388435 75 static inline uint32_t adc_read(analogin_t *obj) {
bogdanm 15:4892fe388435 76 // Select the appropriate channel and start conversion
bogdanm 15:4892fe388435 77 LPC_ADC->CR &= ~0xFF;
bogdanm 15:4892fe388435 78 LPC_ADC->CR |= 1 << (int)obj->adc;
bogdanm 15:4892fe388435 79 LPC_ADC->CR |= 1 << 24;
bogdanm 15:4892fe388435 80
bogdanm 15:4892fe388435 81 // Repeatedly get the sample data until DONE bit
bogdanm 15:4892fe388435 82 unsigned int data;
bogdanm 15:4892fe388435 83 do {
bogdanm 15:4892fe388435 84 data = LPC_ADC->GDR;
bogdanm 15:4892fe388435 85 } while ((data & ((unsigned int)1 << 31)) == 0);
bogdanm 15:4892fe388435 86
bogdanm 15:4892fe388435 87 // Stop conversion
bogdanm 15:4892fe388435 88 LPC_ADC->CR &= ~(1 << 24);
bogdanm 15:4892fe388435 89
bogdanm 15:4892fe388435 90 return (data >> 4) & ADC_RANGE; // 12 bit
bogdanm 15:4892fe388435 91 }
bogdanm 15:4892fe388435 92
bogdanm 15:4892fe388435 93 static inline void order(uint32_t *a, uint32_t *b) {
bogdanm 15:4892fe388435 94 if (*a > *b) {
bogdanm 15:4892fe388435 95 uint32_t t = *a;
bogdanm 15:4892fe388435 96 *a = *b;
bogdanm 15:4892fe388435 97 *b = t;
bogdanm 15:4892fe388435 98 }
bogdanm 15:4892fe388435 99 }
bogdanm 15:4892fe388435 100
bogdanm 15:4892fe388435 101 static inline uint32_t adc_read_u32(analogin_t *obj) {
bogdanm 15:4892fe388435 102 uint32_t value;
bogdanm 15:4892fe388435 103 #if ANALOGIN_MEDIAN_FILTER
bogdanm 15:4892fe388435 104 uint32_t v1 = adc_read(obj);
bogdanm 15:4892fe388435 105 uint32_t v2 = adc_read(obj);
bogdanm 15:4892fe388435 106 uint32_t v3 = adc_read(obj);
bogdanm 15:4892fe388435 107 order(&v1, &v2);
bogdanm 15:4892fe388435 108 order(&v2, &v3);
bogdanm 15:4892fe388435 109 order(&v1, &v2);
bogdanm 15:4892fe388435 110 value = v2;
bogdanm 15:4892fe388435 111 #else
bogdanm 15:4892fe388435 112 value = adc_read(obj);
bogdanm 15:4892fe388435 113 #endif
bogdanm 15:4892fe388435 114 return value;
bogdanm 15:4892fe388435 115 }
bogdanm 15:4892fe388435 116
bogdanm 15:4892fe388435 117 uint16_t analogin_read_u16(analogin_t *obj) {
bogdanm 15:4892fe388435 118 uint32_t value = adc_read_u32(obj);
bogdanm 15:4892fe388435 119
bogdanm 15:4892fe388435 120 return (value << 4) | ((value >> 8) & 0x000F); // 12 bit
bogdanm 15:4892fe388435 121 }
bogdanm 15:4892fe388435 122
bogdanm 15:4892fe388435 123 float analogin_read(analogin_t *obj) {
bogdanm 15:4892fe388435 124 uint32_t value = adc_read_u32(obj);
bogdanm 15:4892fe388435 125 return (float)value * (1.0f / (float)ADC_RANGE);
bogdanm 15:4892fe388435 126 }