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_KLXX_K20D50M.cpp
00001 #if defined(TARGET_KLXX) || defined(TARGET_K20D50M) 00002 00003 #include "FastAnalogIn.h" 00004 #include "clk_freqs.h" 00005 00006 #define MAX_FADC 6000000 00007 #define CHANNELS_A_SHIFT 5 00008 00009 #ifdef TARGET_K20D50M 00010 static const PinMap PinMap_ADC[] = { 00011 {PTC2, ADC0_SE4b, 0}, 00012 {PTD1, ADC0_SE5b, 0}, 00013 {PTD5, ADC0_SE6b, 0}, 00014 {PTD6, ADC0_SE7b, 0}, 00015 {PTB0, ADC0_SE8, 0}, 00016 {PTB1, ADC0_SE9, 0}, 00017 {PTB2, ADC0_SE12, 0}, 00018 {PTB3, ADC0_SE13, 0}, 00019 {PTC0, ADC0_SE14, 0}, 00020 {PTC1, ADC0_SE15, 0}, 00021 {NC, NC, 0} 00022 }; 00023 #endif 00024 00025 FastAnalogIn::FastAnalogIn(PinName pin, bool enabled) 00026 { 00027 if (pin == NC) 00028 return; 00029 00030 ADCnumber = (ADCName)pinmap_peripheral(pin, PinMap_ADC); 00031 if (ADCnumber == (ADCName)NC) { 00032 error("ADC pin mapping failed"); 00033 } 00034 00035 SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK; 00036 00037 uint32_t port = (uint32_t)pin >> PORT_SHIFT; 00038 SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port); 00039 00040 uint32_t cfg2_muxsel = ADC_CFG2_MUXSEL_MASK; 00041 if (ADCnumber & (1 << CHANNELS_A_SHIFT)) { 00042 cfg2_muxsel = 0; 00043 } 00044 00045 // bus clk 00046 uint32_t PCLK = bus_frequency(); 00047 uint32_t clkdiv; 00048 for (clkdiv = 0; clkdiv < 4; clkdiv++) { 00049 if ((PCLK >> clkdiv) <= MAX_FADC) 00050 break; 00051 } 00052 if (clkdiv == 4) //Set max div 00053 clkdiv = 0x7; 00054 00055 ADC0->SC1[1] = ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT)); 00056 00057 ADC0->CFG1 = ADC_CFG1_ADIV(clkdiv & 0x3) // Clock Divide Select: (Input Clock)/8 00058 | ADC_CFG1_MODE(3) // (16)bits Resolution 00059 | ADC_CFG1_ADICLK(clkdiv >> 2); // Input Clock: (Bus Clock)/2 00060 00061 ADC0->CFG2 = cfg2_muxsel // ADxxb or ADxxa channels 00062 | ADC_CFG2_ADACKEN_MASK // Asynchronous Clock Output Enable 00063 | ADC_CFG2_ADHSC_MASK; // High-Speed Configuration 00064 00065 ADC0->SC2 = ADC_SC2_REFSEL(0); // Default Voltage Reference 00066 00067 pinmap_pinout(pin, PinMap_ADC); 00068 00069 //Enable channel 00070 running = false; 00071 enable(enabled); 00072 } 00073 00074 void FastAnalogIn::enable(bool enabled) 00075 { 00076 //If currently not running 00077 if (!running) { 00078 if (enabled) { 00079 //Enable the ADC channel 00080 ADC0->SC3 |= ADC_SC3_ADCO_MASK; // Enable continuous conversion 00081 ADC0->SC1[0] = ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT)); //Start conversion 00082 running = true; 00083 } else 00084 disable(); 00085 } 00086 } 00087 00088 void FastAnalogIn::disable( void ) 00089 { 00090 //If currently running 00091 if (running) { 00092 ADC0->SC3 &= ~ADC_SC3_ADCO_MASK; // Disable continuous conversion 00093 } 00094 running = false; 00095 } 00096 00097 uint16_t FastAnalogIn::read_u16() 00098 { 00099 if (!running) 00100 { 00101 // start conversion 00102 ADC0->SC1[0] = ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT)); 00103 // Wait Conversion Complete 00104 while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK); 00105 } 00106 if(running && ((ADC0->SC1[0]&ADC_SC1_ADCH_MASK) != (ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT))))) 00107 { 00108 running = false; 00109 enable(); 00110 while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK); 00111 } 00112 // Return value 00113 return (uint16_t)ADC0->R[0]; 00114 } 00115 00116 #endif //defined TARGET_KLXX 00117
Generated on Thu Jul 14 2022 10:27:31 by 1.7.2