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 Erik -

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FastAnalogIn_KLXX.cpp Source File

FastAnalogIn_KLXX.cpp

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