tom dunigan / Mbed 2 deprecated k64f_adc_internal

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // k64f internal ADC channels 3.7.1.3.1
00002 //  temp sensor  ADC0 26  slope 1.62mv/C  716mv @25C
00003 //   bandgap ADC0 27  1.0v
00004 //   VREFout  ADC1 18  1.195v
00005 //   DAC0 ADC1 23
00006 // ADC1 SIM_SCGC3  ADC0 SIM_SCGC6
00007 // A0 PTB2   ADC0 channel 12
00008 #include "mbed.h"
00009 
00010 #define PRREG(z) printf(#z" 0x%x\n",z)
00011 //AnalogIn adc(A0);
00012 AnalogOut dac(DAC0_OUT);
00013 Timer tmr;
00014 static uint32_t t;
00015 
00016 // based on teensy3.1 firmware analog.c
00017 // 60mhz bus
00018 #define ADC_CFG1_16BIT  BF_ADC_CFG1_ADIV(2) + BF_ADC_CFG1_ADICLK(1) // 7.5 MHz
00019 #define ADC_CFG1_12BIT  BF_ADC_CFG1_ADIV(1) + BF_ADC_CFG1_ADICLK(1) // 15 MHz
00020 #define ADC_CFG1_10BIT  BF_ADC_CFG1_ADIV(1) + BF_ADC_CFG1_ADICLK(1) // 15 MHz
00021 #define ADC_CFG1_8BIT   BF_ADC_CFG1_ADIV(1) + BF_ADC_CFG1_ADICLK(1) // 15 MHz
00022 
00023 static uint8_t analog_config_bits = 12;  // 8 10 12 16 bit ADC
00024 static uint8_t analog_num_average = 4;    // 0 4 8 16 32
00025 static uint8_t analog_reference_internal = 0;
00026 
00027 static void adc_init() {
00028     SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK;  // start ADC  peripherals
00029     SIM_SCGC3 |= SIM_SCGC3_ADC1_MASK;
00030     VREF_TRM = 0x60;
00031     VREF_SC = 0xE1;     // enable 1.2 volt ref
00032     PMC_REGSC |= PMC_REGSC_BGBE_MASK;  // enable bandgap
00033     
00034     // would need to do GPIO init for external pins
00035 
00036     if (analog_config_bits == 8) {
00037         ADC0_CFG1 = ADC_CFG1_8BIT + BF_ADC_CFG1_MODE(0);
00038         ADC0_CFG2 = ADC_CFG2_MUXSEL_MASK + BF_ADC_CFG2_ADLSTS(3);
00039         ADC1_CFG1 = ADC_CFG1_8BIT + BF_ADC_CFG1_MODE(0);
00040         ADC1_CFG2 = ADC_CFG2_MUXSEL_MASK + BF_ADC_CFG2_ADLSTS(3);
00041     } else if (analog_config_bits == 10) {
00042         ADC0_CFG1 = ADC_CFG1_10BIT + BF_ADC_CFG1_MODE(2) + ADC_CFG1_ADLSMP_MASK;
00043         ADC0_CFG2 = ADC_CFG2_MUXSEL_MASK + BF_ADC_CFG2_ADLSTS(3);
00044         ADC1_CFG1 = ADC_CFG1_10BIT + BF_ADC_CFG1_MODE(2) + ADC_CFG1_ADLSMP_MASK;
00045         ADC1_CFG2 = ADC_CFG2_MUXSEL_MASK + BF_ADC_CFG2_ADLSTS(3);
00046     } else if (analog_config_bits == 12) {
00047         ADC0_CFG1 = ADC_CFG1_12BIT + BF_ADC_CFG1_MODE(1) + ADC_CFG1_ADLSMP_MASK;
00048         ADC0_CFG2 = ADC_CFG2_MUXSEL_MASK + BF_ADC_CFG2_ADLSTS(2);
00049         ADC1_CFG1 = ADC_CFG1_12BIT + BF_ADC_CFG1_MODE(1) + ADC_CFG1_ADLSMP_MASK;
00050         ADC1_CFG2 = ADC_CFG2_MUXSEL_MASK + BF_ADC_CFG2_ADLSTS(2);
00051     } else {
00052         ADC0_CFG1 = ADC_CFG1_16BIT + BF_ADC_CFG1_MODE(3) + ADC_CFG1_ADLSMP_MASK;
00053         ADC0_CFG2 = ADC_CFG2_MUXSEL_MASK + BF_ADC_CFG2_ADLSTS(2);
00054         ADC1_CFG1 = ADC_CFG1_16BIT + BF_ADC_CFG1_MODE(3) + ADC_CFG1_ADLSMP_MASK;
00055         ADC1_CFG2 = ADC_CFG2_MUXSEL_MASK + BF_ADC_CFG2_ADLSTS(2);
00056     }
00057     
00058     if (analog_reference_internal) {
00059         ADC0_SC2 = BF_ADC_SC2_REFSEL(1); // 1.2V ref
00060         ADC1_SC2 = BF_ADC_SC2_REFSEL(1); // 1.2V ref
00061     } else {
00062         ADC0_SC2 = BF_ADC_SC2_REFSEL(0); // vcc/ext ref
00063         ADC1_SC2 = BF_ADC_SC2_REFSEL(0); // vcc/ext ref
00064     }
00065     // calibrate ADCs
00066     t=tmr.read_us();
00067     if (analog_num_average <=1) {
00068         ADC0_SC3 = ADC_SC3_CAL_MASK;  // no averaging
00069         ADC1_SC3 = ADC_SC3_CAL_MASK;
00070     } else if (analog_num_average <=4) {
00071         ADC0_SC3 = ADC_SC3_CAL_MASK + ADC_SC3_AVGE_MASK + BF_ADC_SC3_AVGS(0);  // average 4
00072         ADC1_SC3 = ADC_SC3_CAL_MASK + ADC_SC3_AVGE_MASK + BF_ADC_SC3_AVGS(0);
00073     } else if (analog_num_average <=8) {
00074         ADC0_SC3 = ADC_SC3_CAL_MASK + ADC_SC3_AVGE_MASK + BF_ADC_SC3_AVGS(1); 
00075         ADC1_SC3 = ADC_SC3_CAL_MASK + ADC_SC3_AVGE_MASK + BF_ADC_SC3_AVGS(1);
00076     } else if (analog_num_average <=16) {
00077         ADC0_SC3 = ADC_SC3_CAL_MASK + ADC_SC3_AVGE_MASK + BF_ADC_SC3_AVGS(2);  
00078         ADC1_SC3 = ADC_SC3_CAL_MASK + ADC_SC3_AVGE_MASK + BF_ADC_SC3_AVGS(2);
00079     } else {
00080         ADC0_SC3 = ADC_SC3_CAL_MASK + ADC_SC3_AVGE_MASK + BF_ADC_SC3_AVGS(3);  
00081         ADC1_SC3 = ADC_SC3_CAL_MASK + ADC_SC3_AVGE_MASK + BF_ADC_SC3_AVGS(3);
00082     }
00083     uint16_t sum;
00084 
00085     while ((ADC0_SC3 & ADC_SC3_CAL_MASK) || (ADC1_SC3 & ADC_SC3_CAL_MASK)) ; // wait
00086 
00087     __disable_irq();
00088 
00089         sum = ADC0_CLPS + ADC0_CLP4 + ADC0_CLP3 + ADC0_CLP2 + ADC0_CLP1 + ADC0_CLP0;
00090         sum = (sum / 2) | 0x8000;
00091         ADC0_PG = sum;
00092         sum = ADC0_CLMS + ADC0_CLM4 + ADC0_CLM3 + ADC0_CLM2 + ADC0_CLM1 + ADC0_CLM0;
00093         sum = (sum / 2) | 0x8000;
00094         ADC0_MG = sum;
00095         sum = ADC1_CLPS + ADC1_CLP4 + ADC1_CLP3 + ADC1_CLP2 + ADC1_CLP1 + ADC1_CLP0;
00096         sum = (sum / 2) | 0x8000;
00097         ADC1_PG = sum;
00098         sum = ADC1_CLMS + ADC1_CLM4 + ADC1_CLM3 + ADC1_CLM2 + ADC1_CLM1 + ADC1_CLM0;
00099         sum = (sum / 2) | 0x8000;
00100         ADC1_MG = sum;
00101 
00102     __enable_irq();
00103     t=tmr.read_us()-t;
00104 }
00105 
00106 static uint16_t adc_read(ADC_Type * ADCx, int channel) {
00107     ADCx->SC1[0] = channel;
00108     while(!(ADCx->SC1[0] & ADC_SC1_COCO_MASK)); // wait
00109     return ADCx->R[0];
00110 }
00111 
00112 int main()
00113 {
00114     int ADCmax = 1 << analog_config_bits;
00115     int val, i;
00116     float Vcc,  tempc, slope=ADCmax*0.76/3.3, val25=ADCmax*.0025/3.3;
00117     
00118     printf("\nSystemCoreClock %d  %s %s\n",SystemCoreClock,__TIME__,__DATE__);
00119     tmr.start();
00120     adc_init();
00121     dac.write(0.5);   // 3.3/2 jumper to A0 and read internal
00122 
00123     PRREG(SIM_SCGC6);
00124     PRREG(SIM_SCGC3);
00125     PRREG(VREF->TRM);
00126     PRREG(VREF_SC);
00127     PRREG(PMC_REGSC);
00128     PRREG(ADC0->SC1[0]);      // or ADC0_SCA
00129     PRREG(ADC0->SC1[1]);
00130     PRREG(ADC0->CFG1);
00131     PRREG(ADC0_CFG2);
00132     PRREG(ADC0->SC2);
00133     PRREG(ADC0->SC3);
00134     PRREG(ADC1->SC1[0]);      // ADC1
00135     PRREG(ADC1->SC1[1]);
00136     PRREG(ADC1->CFG1);
00137     PRREG(ADC1_CFG2);
00138     PRREG(ADC1->SC2);
00139     PRREG(ADC1->SC3);
00140 
00141     printf("res %d average %d calibration %d us\n",analog_config_bits,analog_num_average,t);
00142     val = adc_read(ADC1,18);    // VREF OUT
00143     Vcc = ADCmax*1.195/val;
00144     printf("VREF val %d %.2f v\n",val,Vcc);
00145     val = adc_read(ADC0,27);     // bandgap
00146     Vcc = ADCmax*1.0/val;
00147     printf("bandgap val %d %.2f v\n",val,Vcc);
00148     val = adc_read(ADC0,12);   // didn't do GPIO init for A0
00149     printf("A0 val %d  %.2f v\n",val,3.3*val/ADCmax);  
00150     val = adc_read(ADC1,23);   // DAC to internal ADC
00151     printf("DAC val %d  %.2f v\n",val,3.3*val/ADCmax);  
00152     t=tmr.read_us();
00153     for(i=0;i<1000;i++) adc_read(ADC0,12);
00154     t=tmr.read_us()-t;
00155     printf("avrg A0 read %d us\n",t/1000);
00156     //  need internal VREF for temp sensor ??  TODO
00157     analog_reference_internal = 1;
00158     adc_init();  // re init and calibrate
00159     val = adc_read(ADC0,26);    // temp sensor
00160     tempc = ((val-val25)/slope) + 25.f;
00161     printf("temp val %d %.1f C\n",val,tempc); 
00162 }