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 -

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FastAnalogIn_LPC1768.cpp Source File

FastAnalogIn_LPC1768.cpp

00001 #ifdef TARGET_LPC1768
00002 
00003 #include "FastAnalogIn.h"
00004 static inline int div_round_up(int x, int y)
00005 {
00006     return (x + (y - 1)) / y;
00007 }
00008 
00009 static const PinMap PinMap_ADC[] = {
00010     P0_23, ADC0_0, 1,
00011     P0_24, ADC0_1, 1,
00012     P0_25, ADC0_2, 1,
00013     P0_26, ADC0_3, 1,
00014     P1_30, ADC0_4, 3,
00015     P1_31, ADC0_5, 3,
00016     P0_2,  ADC0_7, 2,
00017     P0_3,  ADC0_6, 2,
00018     NC,    NC,     0
00019 };
00020 
00021 static int channel_usage[8] = {0,0,0,0,0,0,0,0};
00022 
00023 FastAnalogIn::FastAnalogIn(PinName pin, bool enabled)
00024 {
00025     ADCnumber = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
00026     if (ADCnumber == (uint32_t)NC)
00027         error("ADC pin mapping failed");
00028     datareg = (uint32_t*) (&LPC_ADC->ADDR0 + ADCnumber);
00029 
00030     // ensure power is turned on
00031     LPC_SC->PCONP |= (1 << 12);
00032     // set PCLK of ADC to /1
00033     LPC_SC->PCLKSEL0 &= ~(0x3 << 24);
00034     LPC_SC->PCLKSEL0 |= (0x1 << 24);
00035     uint32_t PCLK = SystemCoreClock;
00036 
00037     // calculate minimum clock divider
00038     //  clkdiv = divider - 1
00039     uint32_t MAX_ADC_CLK = 13000000;
00040     uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1;
00041     // Set the clkdiv
00042     LPC_ADC->ADCR &= ~(255<<8);
00043     LPC_ADC->ADCR |= clkdiv<<8;
00044 
00045     //Enable ADC:
00046     LPC_ADC->ADCR |= 1<<21;
00047 
00048     //Enable burstmode, set start as zero
00049     LPC_ADC->ADCR |= 1<<16;
00050     LPC_ADC->ADCR &= ~(7<<24);
00051 
00052     //Map pins
00053     pinmap_pinout(pin, PinMap_ADC);
00054 
00055     //Enable channel
00056     running = false;
00057     enable(enabled);
00058 
00059 }
00060 
00061 void FastAnalogIn::enable(bool enabled)
00062 {
00063     //If currently not running
00064     if (!running) {
00065         if (enabled) {
00066             //Enable the ADC channel
00067             channel_usage[ADCnumber]++;
00068             LPC_ADC->ADCR |= (1<<ADCnumber);
00069             running = true;
00070         } else
00071             disable();
00072     }
00073 }
00074 
00075 void FastAnalogIn::disable( void )
00076 {
00077     //If currently running
00078     if (running) {
00079         channel_usage[ADCnumber]--;
00080         
00081         if (channel_usage[ADCnumber]==0)
00082             LPC_ADC->ADCR &= ~(1<<ADCnumber);
00083     }
00084     running = false;
00085 }
00086 
00087 unsigned short FastAnalogIn::read_u16( void )
00088 {
00089     volatile unsigned int retval;
00090     //If object is enabled return current value of datareg
00091     if (running)
00092         retval = *datareg;
00093  
00094     //If it isn't running, enable it and wait until new value is written to datareg
00095     else {
00096         //Force a read to clear done bit, enable the ADC channel
00097         retval = *datareg;
00098         enable();
00099         //Wait until it is converted
00100         while(1) {
00101             wait_us(1);
00102             retval = *datareg;
00103             if ((retval>>31) == 1)
00104                 break;
00105         }
00106         
00107         //Do a second conversion since first one always fails for some reason
00108         while(1) {
00109             wait_us(1);
00110             retval = *datareg;
00111             if ((retval>>31) == 1)
00112                 break;
00113         }
00114 
00115         //Disable again
00116         disable();
00117     }
00118     
00119     //Do same thing as standard mbed lib, unused bit 0-3, replicate 4-7 in it
00120     retval &= ~0xFFFF000F;
00121     retval |= (retval >> 8) & 0x000F;
00122     return retval;
00123 
00124 }
00125 #endif //defined TARGET_LPC1768