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_LPC408X.cpp Source File

FastAnalogIn_LPC408X.cpp

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