FastAnalogIn

Fork of FastAnalogIn by Erik -

Committer:
Sissors
Date:
Sun Mar 20 20:18:12 2016 +0000
Revision:
11:14744c4ac884
Parent:
10:afc3b84dbbd6
Child:
12:46fbc645de4d
Added LPC1114 support

Who changed what in which revision?

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