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:
Sissors
Date:
Sat Jun 28 13:01:27 2014 +0000
Revision:
8:68082fdde730
Child:
10:afc3b84dbbd6
Added LPC11uXX support

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 8:68082fdde730 1 #ifdef TARGET_LPC11UXX
Sissors 8:68082fdde730 2
Sissors 8:68082fdde730 3 #include "FastAnalogIn.h"
Sissors 8:68082fdde730 4 static inline int div_round_up(int x, int y)
Sissors 8:68082fdde730 5 {
Sissors 8:68082fdde730 6 return (x + (y - 1)) / y;
Sissors 8:68082fdde730 7 }
Sissors 8:68082fdde730 8
Sissors 8:68082fdde730 9 #define LPC_IOCON0_BASE (LPC_IOCON_BASE)
Sissors 8:68082fdde730 10 #define LPC_IOCON1_BASE (LPC_IOCON_BASE + 0x60)
Sissors 8:68082fdde730 11 #define MAX_ADC_CLK 4500000
Sissors 8:68082fdde730 12
Sissors 8:68082fdde730 13 static const PinMap PinMap_ADC[] = {
Sissors 8:68082fdde730 14 {P0_11, ADC0_0, 0x02},
Sissors 8:68082fdde730 15 {P0_12, ADC0_1, 0x02},
Sissors 8:68082fdde730 16 {P0_13, ADC0_2, 0x02},
Sissors 8:68082fdde730 17 {P0_14, ADC0_3, 0x02},
Sissors 8:68082fdde730 18 {P0_15, ADC0_4, 0x02},
Sissors 8:68082fdde730 19 {P0_16, ADC0_5, 0x01},
Sissors 8:68082fdde730 20 {P0_22, ADC0_6, 0x01},
Sissors 8:68082fdde730 21 {P0_23, ADC0_7, 0x01},
Sissors 8:68082fdde730 22 {NC , NC , 0 }
Sissors 8:68082fdde730 23 };
Sissors 8:68082fdde730 24
Sissors 8:68082fdde730 25 static int channel_usage[8] = {0,0,0,0,0,0,0,0};
Sissors 8:68082fdde730 26
Sissors 8:68082fdde730 27
Sissors 8:68082fdde730 28
Sissors 8:68082fdde730 29 FastAnalogIn::FastAnalogIn(PinName pin, bool enabled)
Sissors 8:68082fdde730 30 {
Sissors 8:68082fdde730 31 ADCnumber = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
Sissors 8:68082fdde730 32 if (ADCnumber == (uint32_t)NC)
Sissors 8:68082fdde730 33 error("ADC pin mapping failed");
Sissors 8:68082fdde730 34 datareg = (uint32_t*) (&LPC_ADC->DR0 + ADCnumber);
Sissors 8:68082fdde730 35
Sissors 8:68082fdde730 36 // Power up ADC
Sissors 8:68082fdde730 37 LPC_SYSCON->PDRUNCFG &= ~ (1 << 4);
Sissors 8:68082fdde730 38 LPC_SYSCON->SYSAHBCLKCTRL |= ((uint32_t)1 << 13);
Sissors 8:68082fdde730 39
Sissors 8:68082fdde730 40 uint32_t pin_number = (uint32_t)pin;
Sissors 8:68082fdde730 41 __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));
Sissors 8:68082fdde730 42
Sissors 8:68082fdde730 43 // set pin to ADC mode
Sissors 8:68082fdde730 44 *reg &= ~(1 << 7); // set ADMODE = 0 (analog mode)
Sissors 8:68082fdde730 45
Sissors 8:68082fdde730 46 uint32_t clkdiv = div_round_up(SystemCoreClock, MAX_ADC_CLK) - 1;
Sissors 8:68082fdde730 47
Sissors 8:68082fdde730 48 LPC_ADC->CR = (0 << 0) // no channels selected
Sissors 8:68082fdde730 49 | (clkdiv << 8) // max of 4.5MHz
Sissors 8:68082fdde730 50 | (1 << 16) // BURST = 1, hardware controlled
Sissors 8:68082fdde730 51 | ( 0 << 17 ); // CLKS = 0, we stick to 10 bit mode
Sissors 8:68082fdde730 52
Sissors 8:68082fdde730 53 pinmap_pinout(pin, PinMap_ADC);
Sissors 8:68082fdde730 54
Sissors 8:68082fdde730 55 //Enable channel
Sissors 8:68082fdde730 56 running = false;
Sissors 8:68082fdde730 57 enable(enabled);
Sissors 8:68082fdde730 58
Sissors 8:68082fdde730 59 }
Sissors 8:68082fdde730 60
Sissors 8:68082fdde730 61 void FastAnalogIn::enable(bool enabled)
Sissors 8:68082fdde730 62 {
Sissors 8:68082fdde730 63 //If currently not running
Sissors 8:68082fdde730 64 if (!running) {
Sissors 8:68082fdde730 65 if (enabled) {
Sissors 8:68082fdde730 66 //Enable the ADC channel
Sissors 8:68082fdde730 67 channel_usage[ADCnumber]++;
Sissors 8:68082fdde730 68 LPC_ADC->CR |= (1<<ADCnumber);
Sissors 8:68082fdde730 69 running = true;
Sissors 8:68082fdde730 70 } else
Sissors 8:68082fdde730 71 disable();
Sissors 8:68082fdde730 72 }
Sissors 8:68082fdde730 73 }
Sissors 8:68082fdde730 74
Sissors 8:68082fdde730 75 void FastAnalogIn::disable( void )
Sissors 8:68082fdde730 76 {
Sissors 8:68082fdde730 77 //If currently running
Sissors 8:68082fdde730 78 if (running) {
Sissors 8:68082fdde730 79 channel_usage[ADCnumber]--;
Sissors 8:68082fdde730 80
Sissors 8:68082fdde730 81 if (channel_usage[ADCnumber]==0)
Sissors 8:68082fdde730 82 LPC_ADC->CR &= ~(1<<ADCnumber);
Sissors 8:68082fdde730 83 }
Sissors 8:68082fdde730 84 running = false;
Sissors 8:68082fdde730 85 }
Sissors 8:68082fdde730 86
Sissors 8:68082fdde730 87 unsigned short FastAnalogIn::read_u16( void )
Sissors 8:68082fdde730 88 {
Sissors 8:68082fdde730 89 unsigned int retval;
Sissors 8:68082fdde730 90 //If object is enabled return current value of datareg
Sissors 8:68082fdde730 91 if (running)
Sissors 8:68082fdde730 92 retval = *datareg;
Sissors 8:68082fdde730 93
Sissors 8:68082fdde730 94 //If it isn't running, enable it and wait until new value is written to datareg
Sissors 8:68082fdde730 95 else {
Sissors 8:68082fdde730 96 //Force a read to clear done bit, enable the ADC channel
Sissors 8:68082fdde730 97 retval = *datareg;
Sissors 8:68082fdde730 98 enable();
Sissors 8:68082fdde730 99 //Wait until it is converted
Sissors 8:68082fdde730 100 while(1) {
Sissors 8:68082fdde730 101 retval = *datareg;
Sissors 8:68082fdde730 102 if ((retval>>31) == 1)
Sissors 8:68082fdde730 103 break;
Sissors 8:68082fdde730 104 }
Sissors 8:68082fdde730 105 //Disable again
Sissors 8:68082fdde730 106 disable();
Sissors 8:68082fdde730 107 }
Sissors 8:68082fdde730 108
Sissors 8:68082fdde730 109 //Do same thing as standard mbed lib, unused bit 0-3, replicate 4-7 in it
Sissors 8:68082fdde730 110 retval &= ~0xFFFF003F;
Sissors 8:68082fdde730 111 retval |= (retval >> 6) & 0x003F;
Sissors 8:68082fdde730 112 return retval;
Sissors 8:68082fdde730 113 }
Sissors 8:68082fdde730 114 #endif //defined TARGET_LPC11UXX