FastAnalogIn

Fork of FastAnalogIn by Erik -

Committer:
Sissors
Date:
Mon Mar 21 07:41:52 2016 +0000
Revision:
12:46fbc645de4d
Parent:
7:965a2b0e477f
Fixed pinmapping of LPC1114

Who changed what in which revision?

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