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.

Dependents:   KL25Z_FFT_Demo test_armmath KL25Z_FFT_Demo_tony KL25Z_FFT_Demo_tony ... more

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