Class similar to AnalogIn that uses burst mode to run continious background conversions so when the input is read, the last value can immediatly be returned. This slightly modified version allows NC pins.

Dependents:   Pinscape_Controller

Fork of FastAnalogIn by Erik -

Committer:
humlet
Date:
Mon Apr 21 07:17:39 2014 +0000
Revision:
5:55274430c8df
Parent:
4:cd84739f7640
Child:
7:965a2b0e477f
* minor docu changes; * added definition of "channel_usage" also to KLXX-implementation

Who changed what in which revision?

UserRevisionLine numberNew contents of line
humlet 4:cd84739f7640 1 #ifdef TARGET_LPC408X
humlet 4:cd84739f7640 2
humlet 4:cd84739f7640 3 #include "FastAnalogIn.h"
humlet 4:cd84739f7640 4
humlet 4:cd84739f7640 5 static inline int div_round_up(int x, int y)
humlet 4:cd84739f7640 6 {
humlet 4:cd84739f7640 7 return (x + (y - 1)) / y;
humlet 4:cd84739f7640 8 }
humlet 4:cd84739f7640 9
humlet 4:cd84739f7640 10 static const PinMap PinMap_ADC[] = {
humlet 4:cd84739f7640 11 {P0_23, ADC0_0, 0x01},
humlet 4:cd84739f7640 12 {P0_24, ADC0_1, 0x01},
humlet 4:cd84739f7640 13 {P0_25, ADC0_2, 0x01},
humlet 4:cd84739f7640 14 {P0_26, ADC0_3, 0x01},
humlet 4:cd84739f7640 15 {P1_30, ADC0_4, 0x03},
humlet 4:cd84739f7640 16 {P1_31, ADC0_5, 0x03},
humlet 4:cd84739f7640 17 {P0_12, ADC0_6, 0x03},
humlet 4:cd84739f7640 18 {P0_13, ADC0_7, 0x03},
humlet 4:cd84739f7640 19 {NC , NC , 0 }
humlet 4:cd84739f7640 20 };
humlet 4:cd84739f7640 21
humlet 4:cd84739f7640 22 int FastAnalogIn::channel_usage[8] = {0,0,0,0,0,0,0,0};
humlet 4:cd84739f7640 23
humlet 4:cd84739f7640 24 FastAnalogIn::FastAnalogIn(PinName pin, bool enabled)
humlet 4:cd84739f7640 25 {
humlet 4:cd84739f7640 26 ADCnumber = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
humlet 4:cd84739f7640 27 if (ADCnumber == (uint32_t)NC)
humlet 4:cd84739f7640 28 error("ADC pin mapping failed");
humlet 4:cd84739f7640 29 datareg = (uint32_t*) (&LPC_ADC->DR[ADCnumber]);
humlet 4:cd84739f7640 30
humlet 5:55274430c8df 31 wait_us(1000); // wait for a short while before trying to initialize the ADC afer a reset (needed for those global instantiations just before main)
humlet 4:cd84739f7640 32
humlet 4:cd84739f7640 33 // ensure power is turned on
humlet 4:cd84739f7640 34 LPC_SC->PCONP |= (1 << 12);
humlet 4:cd84739f7640 35
humlet 4:cd84739f7640 36 uint32_t PCLK = PeripheralClock;
humlet 4:cd84739f7640 37
humlet 4:cd84739f7640 38 // calculate minimum clock divider
humlet 4:cd84739f7640 39 // clkdiv = divider - 1
humlet 4:cd84739f7640 40 uint32_t MAX_ADC_CLK = 12400000;
humlet 4:cd84739f7640 41 uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1;
humlet 4:cd84739f7640 42 // Set the clkdiv
humlet 4:cd84739f7640 43 LPC_ADC->CR &= ~(255<<8);
humlet 4:cd84739f7640 44 LPC_ADC->CR |= clkdiv<<8;
humlet 4:cd84739f7640 45
humlet 4:cd84739f7640 46 //Enable ADC:
humlet 4:cd84739f7640 47 LPC_ADC->CR |= 1<<21;
humlet 4:cd84739f7640 48
humlet 4:cd84739f7640 49 //Enable burstmode, set start as zero
humlet 4:cd84739f7640 50 LPC_ADC->CR |= 1<<16;
humlet 4:cd84739f7640 51 LPC_ADC->CR &= ~(7<<24);
humlet 4:cd84739f7640 52
humlet 4:cd84739f7640 53 // must enable analog mode (ADMODE = 0) ... ??? just copied from official LPC408X analogin_api.c
humlet 4:cd84739f7640 54 __IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin);
humlet 4:cd84739f7640 55 *reg &= ~(1 << 7);
humlet 4:cd84739f7640 56
humlet 4:cd84739f7640 57 //Map pins
humlet 4:cd84739f7640 58 pinmap_pinout(pin, PinMap_ADC);
humlet 4:cd84739f7640 59
humlet 4:cd84739f7640 60 //Enable channel
humlet 4:cd84739f7640 61 running = false;
humlet 4:cd84739f7640 62 enable(enabled);
humlet 4:cd84739f7640 63
humlet 4:cd84739f7640 64 }
humlet 4:cd84739f7640 65
humlet 4:cd84739f7640 66 void FastAnalogIn::enable(bool enabled)
humlet 4:cd84739f7640 67 {
humlet 4:cd84739f7640 68 //If currently not running
humlet 4:cd84739f7640 69 if (!running) {
humlet 4:cd84739f7640 70 if (enabled) {
humlet 4:cd84739f7640 71 //Enable the ADC channel
humlet 4:cd84739f7640 72 channel_usage[ADCnumber]++;
humlet 4:cd84739f7640 73 LPC_ADC->CR |= (1<<ADCnumber);
humlet 4:cd84739f7640 74 running = true;
humlet 4:cd84739f7640 75 } else
humlet 4:cd84739f7640 76 disable();
humlet 4:cd84739f7640 77 }
humlet 4:cd84739f7640 78 }
humlet 4:cd84739f7640 79
humlet 4:cd84739f7640 80 void FastAnalogIn::disable( void )
humlet 4:cd84739f7640 81 {
humlet 4:cd84739f7640 82 //If currently running
humlet 4:cd84739f7640 83 if (running) {
humlet 4:cd84739f7640 84 channel_usage[ADCnumber]--;
humlet 4:cd84739f7640 85
humlet 4:cd84739f7640 86 if (channel_usage[ADCnumber]==0)
humlet 4:cd84739f7640 87 LPC_ADC->CR &= ~(1<<ADCnumber);
humlet 4:cd84739f7640 88 }
humlet 4:cd84739f7640 89 running = false;
humlet 4:cd84739f7640 90 }
humlet 4:cd84739f7640 91
humlet 4:cd84739f7640 92 unsigned short FastAnalogIn::read_u16( void )
humlet 4:cd84739f7640 93 {
humlet 4:cd84739f7640 94 volatile unsigned int retval;
humlet 4:cd84739f7640 95 //If object is enabled return current value of datareg
humlet 4:cd84739f7640 96 if (running ){
humlet 4:cd84739f7640 97 retval = *datareg;
humlet 4:cd84739f7640 98 //If it isn't running, enable it and wait until new value is written to datareg
humlet 4:cd84739f7640 99 }else {
humlet 4:cd84739f7640 100 //Force a read to clear done bit, enable the ADC channel
humlet 4:cd84739f7640 101 retval = *datareg;
humlet 4:cd84739f7640 102 enable();
humlet 4:cd84739f7640 103 //Wait until it is converted
humlet 4:cd84739f7640 104 while(1) {
humlet 4:cd84739f7640 105 wait_us(1);
humlet 4:cd84739f7640 106 retval = *datareg;
humlet 4:cd84739f7640 107 if ((retval>>31) == 1)
humlet 4:cd84739f7640 108 break;
humlet 4:cd84739f7640 109 }
humlet 4:cd84739f7640 110 //Do a second conversion since first one always fails for some reason
humlet 4:cd84739f7640 111 while(1) {
humlet 4:cd84739f7640 112 wait_us(1);
humlet 4:cd84739f7640 113 retval = *datareg;
humlet 4:cd84739f7640 114 if ((retval>>31) == 1)
humlet 4:cd84739f7640 115 break;
humlet 4:cd84739f7640 116 }
humlet 4:cd84739f7640 117 //Disable again
humlet 4:cd84739f7640 118 disable();
humlet 4:cd84739f7640 119 }
humlet 4:cd84739f7640 120
humlet 4:cd84739f7640 121 //Do same thing as standard mbed lib, unused bit 0-3, replicate 4-7 in it
humlet 4:cd84739f7640 122 retval &= ~0xFFFF000F;
humlet 4:cd84739f7640 123 retval |= (retval >> 8) & 0x000F;
humlet 4:cd84739f7640 124 return retval;
humlet 4:cd84739f7640 125
humlet 4:cd84739f7640 126 }
humlet 4:cd84739f7640 127 #endif //defined TARGET_LPC408X