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.
Fork of FastAnalogIn by
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 int FastAnalogIn::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
Generated on Sun Jul 17 2022 00:25:27 by 1.7.2