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:
Sun Apr 20 16:23:19 2014 +0000
Revision:
4:cd84739f7640
Child:
5:55274430c8df
Added support for LPC4088,; Fixed linker error (missing definition of static member)

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 //printf("ADC_ID=%u\n",ADCnumber);
humlet 4:cd84739f7640 30 datareg = (uint32_t*) (&LPC_ADC->DR[ADCnumber]);
humlet 4:cd84739f7640 31
humlet 4:cd84739f7640 32 wait_us(1000); // we need either the debug printf above or a wait before we try to initialize the ADC
humlet 4:cd84739f7640 33
humlet 4:cd84739f7640 34 // ensure power is turned on
humlet 4:cd84739f7640 35 LPC_SC->PCONP |= (1 << 12);
humlet 4:cd84739f7640 36
humlet 4:cd84739f7640 37 uint32_t PCLK = PeripheralClock;
humlet 4:cd84739f7640 38
humlet 4:cd84739f7640 39 // calculate minimum clock divider
humlet 4:cd84739f7640 40 // clkdiv = divider - 1
humlet 4:cd84739f7640 41 uint32_t MAX_ADC_CLK = 12400000;
humlet 4:cd84739f7640 42 uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1;
humlet 4:cd84739f7640 43 // Set the clkdiv
humlet 4:cd84739f7640 44 LPC_ADC->CR &= ~(255<<8);
humlet 4:cd84739f7640 45 LPC_ADC->CR |= clkdiv<<8;
humlet 4:cd84739f7640 46
humlet 4:cd84739f7640 47 //Enable ADC:
humlet 4:cd84739f7640 48 LPC_ADC->CR |= 1<<21;
humlet 4:cd84739f7640 49
humlet 4:cd84739f7640 50 //Enable burstmode, set start as zero
humlet 4:cd84739f7640 51 LPC_ADC->CR |= 1<<16;
humlet 4:cd84739f7640 52 LPC_ADC->CR &= ~(7<<24);
humlet 4:cd84739f7640 53
humlet 4:cd84739f7640 54 // must enable analog mode (ADMODE = 0) ... ??? just copied from official LPC408X analogin_api.c
humlet 4:cd84739f7640 55 __IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin);
humlet 4:cd84739f7640 56 *reg &= ~(1 << 7);
humlet 4:cd84739f7640 57
humlet 4:cd84739f7640 58 //Map pins
humlet 4:cd84739f7640 59 pinmap_pinout(pin, PinMap_ADC);
humlet 4:cd84739f7640 60
humlet 4:cd84739f7640 61 //Enable channel
humlet 4:cd84739f7640 62 running = false;
humlet 4:cd84739f7640 63 enable(enabled);
humlet 4:cd84739f7640 64
humlet 4:cd84739f7640 65 }
humlet 4:cd84739f7640 66
humlet 4:cd84739f7640 67 void FastAnalogIn::enable(bool enabled)
humlet 4:cd84739f7640 68 {
humlet 4:cd84739f7640 69 //If currently not running
humlet 4:cd84739f7640 70 if (!running) {
humlet 4:cd84739f7640 71 if (enabled) {
humlet 4:cd84739f7640 72 //Enable the ADC channel
humlet 4:cd84739f7640 73 channel_usage[ADCnumber]++;
humlet 4:cd84739f7640 74 LPC_ADC->CR |= (1<<ADCnumber);
humlet 4:cd84739f7640 75 running = true;
humlet 4:cd84739f7640 76 } else
humlet 4:cd84739f7640 77 disable();
humlet 4:cd84739f7640 78 }
humlet 4:cd84739f7640 79 }
humlet 4:cd84739f7640 80
humlet 4:cd84739f7640 81 void FastAnalogIn::disable( void )
humlet 4:cd84739f7640 82 {
humlet 4:cd84739f7640 83 //If currently running
humlet 4:cd84739f7640 84 if (running) {
humlet 4:cd84739f7640 85 channel_usage[ADCnumber]--;
humlet 4:cd84739f7640 86
humlet 4:cd84739f7640 87 if (channel_usage[ADCnumber]==0)
humlet 4:cd84739f7640 88 LPC_ADC->CR &= ~(1<<ADCnumber);
humlet 4:cd84739f7640 89 }
humlet 4:cd84739f7640 90 running = false;
humlet 4:cd84739f7640 91 }
humlet 4:cd84739f7640 92
humlet 4:cd84739f7640 93 unsigned short FastAnalogIn::read_u16( void )
humlet 4:cd84739f7640 94 {
humlet 4:cd84739f7640 95 volatile unsigned int retval;
humlet 4:cd84739f7640 96 //If object is enabled return current value of datareg
humlet 4:cd84739f7640 97 if (running ){
humlet 4:cd84739f7640 98 retval = *datareg;
humlet 4:cd84739f7640 99 //If it isn't running, enable it and wait until new value is written to datareg
humlet 4:cd84739f7640 100 }else {
humlet 4:cd84739f7640 101 //Force a read to clear done bit, enable the ADC channel
humlet 4:cd84739f7640 102 retval = *datareg;
humlet 4:cd84739f7640 103 enable();
humlet 4:cd84739f7640 104 //Wait until it is converted
humlet 4:cd84739f7640 105 while(1) {
humlet 4:cd84739f7640 106 wait_us(1);
humlet 4:cd84739f7640 107 retval = *datareg;
humlet 4:cd84739f7640 108 if ((retval>>31) == 1)
humlet 4:cd84739f7640 109 break;
humlet 4:cd84739f7640 110 }
humlet 4:cd84739f7640 111 //Do a second conversion since first one always fails for some reason
humlet 4:cd84739f7640 112 while(1) {
humlet 4:cd84739f7640 113 wait_us(1);
humlet 4:cd84739f7640 114 retval = *datareg;
humlet 4:cd84739f7640 115 if ((retval>>31) == 1)
humlet 4:cd84739f7640 116 break;
humlet 4:cd84739f7640 117 }
humlet 4:cd84739f7640 118 //Disable again
humlet 4:cd84739f7640 119 disable();
humlet 4:cd84739f7640 120 }
humlet 4:cd84739f7640 121
humlet 4:cd84739f7640 122 //Do same thing as standard mbed lib, unused bit 0-3, replicate 4-7 in it
humlet 4:cd84739f7640 123 retval &= ~0xFFFF000F;
humlet 4:cd84739f7640 124 retval |= (retval >> 8) & 0x000F;
humlet 4:cd84739f7640 125 return retval;
humlet 4:cd84739f7640 126
humlet 4:cd84739f7640 127 }
humlet 4:cd84739f7640 128 #endif //defined TARGET_LPC408X