BA / SerialCom

Fork of OmniWheels by Gustav Atmel

Committer:
gustavatmel
Date:
Tue May 01 15:47:08 2018 +0000
Revision:
1:9c5af431a1f1
sdf

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gustavatmel 1:9c5af431a1f1 1 /* mbed Microcontroller Library
gustavatmel 1:9c5af431a1f1 2 * Copyright (c) 2006-2013 ARM Limited
gustavatmel 1:9c5af431a1f1 3 *
gustavatmel 1:9c5af431a1f1 4 * Licensed under the Apache License, Version 2.0 (the "License");
gustavatmel 1:9c5af431a1f1 5 * you may not use this file except in compliance with the License.
gustavatmel 1:9c5af431a1f1 6 * You may obtain a copy of the License at
gustavatmel 1:9c5af431a1f1 7 *
gustavatmel 1:9c5af431a1f1 8 * http://www.apache.org/licenses/LICENSE-2.0
gustavatmel 1:9c5af431a1f1 9 *
gustavatmel 1:9c5af431a1f1 10 * Unless required by applicable law or agreed to in writing, software
gustavatmel 1:9c5af431a1f1 11 * distributed under the License is distributed on an "AS IS" BASIS,
gustavatmel 1:9c5af431a1f1 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
gustavatmel 1:9c5af431a1f1 13 * See the License for the specific language governing permissions and
gustavatmel 1:9c5af431a1f1 14 * limitations under the License.
gustavatmel 1:9c5af431a1f1 15 */
gustavatmel 1:9c5af431a1f1 16 #include "mbed_assert.h"
gustavatmel 1:9c5af431a1f1 17 #include "analogin_api.h"
gustavatmel 1:9c5af431a1f1 18 #include "cmsis.h"
gustavatmel 1:9c5af431a1f1 19 #include "pinmap.h"
gustavatmel 1:9c5af431a1f1 20 #include "mbed_error.h"
gustavatmel 1:9c5af431a1f1 21 #include "PeripheralPins.h" // For the Peripheral to Pin Definitions found in the individual Target's Platform
gustavatmel 1:9c5af431a1f1 22
gustavatmel 1:9c5af431a1f1 23 #define ANALOGIN_MEDIAN_FILTER 1
gustavatmel 1:9c5af431a1f1 24
gustavatmel 1:9c5af431a1f1 25 #define ADC_10BIT_RANGE 0x3FF
gustavatmel 1:9c5af431a1f1 26 #define ADC_12BIT_RANGE 0xFFF
gustavatmel 1:9c5af431a1f1 27
gustavatmel 1:9c5af431a1f1 28 static inline int div_round_up(int x, int y) {
gustavatmel 1:9c5af431a1f1 29 return (x + (y - 1)) / y;
gustavatmel 1:9c5af431a1f1 30 }
gustavatmel 1:9c5af431a1f1 31
gustavatmel 1:9c5af431a1f1 32 #define LPC_IOCON0_BASE (LPC_IOCON_BASE)
gustavatmel 1:9c5af431a1f1 33 #define LPC_IOCON1_BASE (LPC_IOCON_BASE + 0x60)
gustavatmel 1:9c5af431a1f1 34
gustavatmel 1:9c5af431a1f1 35 #define ADC_RANGE ADC_10BIT_RANGE
gustavatmel 1:9c5af431a1f1 36
gustavatmel 1:9c5af431a1f1 37 void analogin_init(analogin_t *obj, PinName pin) {
gustavatmel 1:9c5af431a1f1 38 obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
gustavatmel 1:9c5af431a1f1 39 MBED_ASSERT(obj->adc != (ADCName)NC);
gustavatmel 1:9c5af431a1f1 40
gustavatmel 1:9c5af431a1f1 41 // Power up ADC
gustavatmel 1:9c5af431a1f1 42 LPC_SYSCON->PDRUNCFG &= ~ (1 << 4);
gustavatmel 1:9c5af431a1f1 43 LPC_SYSCON->SYSAHBCLKCTRL |= ((uint32_t)1 << 13);
gustavatmel 1:9c5af431a1f1 44
gustavatmel 1:9c5af431a1f1 45 uint32_t pin_number = (uint32_t)pin;
gustavatmel 1:9c5af431a1f1 46 __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));
gustavatmel 1:9c5af431a1f1 47
gustavatmel 1:9c5af431a1f1 48 // set pin to ADC mode
gustavatmel 1:9c5af431a1f1 49 *reg &= ~(1 << 7); // set ADMODE = 0 (analog mode)
gustavatmel 1:9c5af431a1f1 50
gustavatmel 1:9c5af431a1f1 51 uint32_t PCLK = SystemCoreClock;
gustavatmel 1:9c5af431a1f1 52 uint32_t MAX_ADC_CLK = 4500000;
gustavatmel 1:9c5af431a1f1 53 uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1;
gustavatmel 1:9c5af431a1f1 54
gustavatmel 1:9c5af431a1f1 55 LPC_ADC->CR = (0 << 0) // no channels selected
gustavatmel 1:9c5af431a1f1 56 | (clkdiv << 8) // max of 4.5MHz
gustavatmel 1:9c5af431a1f1 57 | (0 << 16) // BURST = 0, software controlled
gustavatmel 1:9c5af431a1f1 58 | ( 0 << 17 ); // CLKS = 0, not applicable
gustavatmel 1:9c5af431a1f1 59
gustavatmel 1:9c5af431a1f1 60 pinmap_pinout(pin, PinMap_ADC);
gustavatmel 1:9c5af431a1f1 61 }
gustavatmel 1:9c5af431a1f1 62
gustavatmel 1:9c5af431a1f1 63 static inline uint32_t adc_read(analogin_t *obj) {
gustavatmel 1:9c5af431a1f1 64 // Select the appropriate channel and start conversion
gustavatmel 1:9c5af431a1f1 65 LPC_ADC->CR &= ~0xFF;
gustavatmel 1:9c5af431a1f1 66 LPC_ADC->CR |= 1 << (int)obj->adc;
gustavatmel 1:9c5af431a1f1 67 LPC_ADC->CR |= 1 << 24;
gustavatmel 1:9c5af431a1f1 68
gustavatmel 1:9c5af431a1f1 69 // Repeatedly get the sample data until DONE bit
gustavatmel 1:9c5af431a1f1 70 unsigned int data;
gustavatmel 1:9c5af431a1f1 71 do {
gustavatmel 1:9c5af431a1f1 72 data = LPC_ADC->GDR;
gustavatmel 1:9c5af431a1f1 73 } while ((data & ((unsigned int)1 << 31)) == 0);
gustavatmel 1:9c5af431a1f1 74
gustavatmel 1:9c5af431a1f1 75 // Stop conversion
gustavatmel 1:9c5af431a1f1 76 LPC_ADC->CR &= ~(1 << 24);
gustavatmel 1:9c5af431a1f1 77
gustavatmel 1:9c5af431a1f1 78 return (data >> 6) & ADC_RANGE; // 10 bit
gustavatmel 1:9c5af431a1f1 79 }
gustavatmel 1:9c5af431a1f1 80
gustavatmel 1:9c5af431a1f1 81 static inline void order(uint32_t *a, uint32_t *b) {
gustavatmel 1:9c5af431a1f1 82 if (*a > *b) {
gustavatmel 1:9c5af431a1f1 83 uint32_t t = *a;
gustavatmel 1:9c5af431a1f1 84 *a = *b;
gustavatmel 1:9c5af431a1f1 85 *b = t;
gustavatmel 1:9c5af431a1f1 86 }
gustavatmel 1:9c5af431a1f1 87 }
gustavatmel 1:9c5af431a1f1 88
gustavatmel 1:9c5af431a1f1 89 static inline uint32_t adc_read_u32(analogin_t *obj) {
gustavatmel 1:9c5af431a1f1 90 uint32_t value;
gustavatmel 1:9c5af431a1f1 91 #if ANALOGIN_MEDIAN_FILTER
gustavatmel 1:9c5af431a1f1 92 uint32_t v1 = adc_read(obj);
gustavatmel 1:9c5af431a1f1 93 uint32_t v2 = adc_read(obj);
gustavatmel 1:9c5af431a1f1 94 uint32_t v3 = adc_read(obj);
gustavatmel 1:9c5af431a1f1 95 order(&v1, &v2);
gustavatmel 1:9c5af431a1f1 96 order(&v2, &v3);
gustavatmel 1:9c5af431a1f1 97 order(&v1, &v2);
gustavatmel 1:9c5af431a1f1 98 value = v2;
gustavatmel 1:9c5af431a1f1 99 #else
gustavatmel 1:9c5af431a1f1 100 value = adc_read(obj);
gustavatmel 1:9c5af431a1f1 101 #endif
gustavatmel 1:9c5af431a1f1 102 return value;
gustavatmel 1:9c5af431a1f1 103 }
gustavatmel 1:9c5af431a1f1 104
gustavatmel 1:9c5af431a1f1 105 uint16_t analogin_read_u16(analogin_t *obj) {
gustavatmel 1:9c5af431a1f1 106 uint32_t value = adc_read_u32(obj);
gustavatmel 1:9c5af431a1f1 107
gustavatmel 1:9c5af431a1f1 108 return (value << 6) | ((value >> 4) & 0x003F); // 10 bit
gustavatmel 1:9c5af431a1f1 109 }
gustavatmel 1:9c5af431a1f1 110
gustavatmel 1:9c5af431a1f1 111 float analogin_read(analogin_t *obj) {
gustavatmel 1:9c5af431a1f1 112 uint32_t value = adc_read_u32(obj);
gustavatmel 1:9c5af431a1f1 113 return (float)value * (1.0f / (float)ADC_RANGE);
gustavatmel 1:9c5af431a1f1 114 }