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

FastAnalogIn_LPC11UXX.cpp

00001 #ifdef TARGET_LPC11UXX
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 #define LPC_IOCON0_BASE (LPC_IOCON_BASE)
00010 #define LPC_IOCON1_BASE (LPC_IOCON_BASE + 0x60)
00011 #define MAX_ADC_CLK     4500000
00012 
00013 static const PinMap PinMap_ADC[] = {
00014     {P0_11, ADC0_0, 0x02},
00015     {P0_12, ADC0_1, 0x02},
00016     {P0_13, ADC0_2, 0x02},
00017     {P0_14, ADC0_3, 0x02},
00018     {P0_15, ADC0_4, 0x02},
00019     {P0_16, ADC0_5, 0x01},
00020     {P0_22, ADC0_6, 0x01},
00021     {P0_23, ADC0_7, 0x01},
00022     {NC   , NC    , 0   }
00023 };
00024 
00025 static int channel_usage[8] = {0,0,0,0,0,0,0,0};
00026 
00027 
00028 
00029 FastAnalogIn::FastAnalogIn(PinName pin, bool enabled)
00030 {
00031     ADCnumber = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
00032     if (ADCnumber == (uint32_t)NC)
00033         error("ADC pin mapping failed");
00034     datareg = (uint32_t*) (&LPC_ADC->DR0 + ADCnumber);
00035     
00036     // Power up ADC
00037     LPC_SYSCON->PDRUNCFG &= ~ (1 << 4);
00038     LPC_SYSCON->SYSAHBCLKCTRL |= ((uint32_t)1 << 13);
00039  
00040     uint32_t pin_number = (uint32_t)pin;
00041     __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));
00042  
00043     // set pin to ADC mode
00044     *reg &= ~(1 << 7); // set ADMODE = 0 (analog mode)
00045  
00046     uint32_t clkdiv = div_round_up(SystemCoreClock, MAX_ADC_CLK) - 1;
00047  
00048     LPC_ADC->CR = (LPC_ADC->CR & 0xFF)      // keep current channels
00049                 | (clkdiv << 8) // max of 4.5MHz
00050                 | (1 << 16)     // BURST = 1, hardware controlled
00051                 | ( 0 << 17 );  // CLKS = 0, we stick to 10 bit mode
00052     
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->CR |= (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->CR &= ~(1<<ADCnumber);
00083     }
00084     running = false;
00085 }
00086 
00087 unsigned short FastAnalogIn::read_u16( void )
00088 {
00089     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             retval = *datareg;
00102             if ((retval>>31) == 1)
00103                 break;
00104         }
00105         //Disable again
00106         disable();
00107     }
00108     
00109     //Do same thing as standard mbed lib, unused bit 0-3, replicate 4-7 in it
00110     retval &= ~0xFFFF003F;
00111     retval |= (retval >> 6) & 0x003F;
00112     return retval;
00113 }
00114 #endif //defined TARGET_LPC11UXX