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
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
Generated on Thu Jul 14 2022 10:27:31 by 1.7.2