Jared Baxter / Mbed 2 deprecated Impedance_Fast_Circuitry_print_V_I

Dependencies:   mbed-dsp mbed

Fork of Impedance_Fast_Circuitry by Jared Baxter

Revision:
45:d591d138cdeb
Parent:
44:41c262caf898
Child:
46:a015ebf4663b
--- a/adc.cpp	Fri Jan 30 14:56:58 2015 +0000
+++ b/adc.cpp	Sat Jan 31 07:25:52 2015 +0000
@@ -1,107 +1,153 @@
 #include "adc.h"
-#include "dma.h"
+
 /*
 TODO:   remove interrupt handlers
         add calibration
-        change clock speed (possible with PIT)
+        change clock speed
         
+Possible causes of the triggering problem:
+        more multiplexing somehow?
+        does the ADC interrupt need to be enabled?
+        clock speed?
+        hardware/software trigger
+        channel A or B?
+        single vs continuous mode
+        does asynchronous clock have to do with this?
 */
-DigitalOut blah(LED_BLUE);
-DigitalOut craw(LED_GREEN);
-DigitalOut toggle(PTC16);
+DigitalOut toggle1(PTC16);
+DigitalOut green(LED_GREEN);
+DigitalOut red(LED_RED);
+Serial debug(USBTX,USBRX);
 
-void adc_init(PinName pin)
+void adc_init()
 {
+    // red, indicating now ready
+    red = 0;
+    green = 1;
+    
     // Turn on the ADC0 and ADC1 clocks
     SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK;
     SIM_SCGC3 |= SIM_SCGC3_ADC1_MASK;
     
-    // enable interrupt
-    ADC0_SC1A |= ADC_SC1_AIEN_MASK;
-    ADC1_SC1A |= ADC_SC1_AIEN_MASK;
+    // Set ADC hardware trigger to PDB0
+    SIM_SOPT7 = SIM_SOPT7_ADC0TRGSEL(0);
     
-    // enable the DMA
-    ADC0->SC2 |= ADC_SC2_DMAEN_MASK;
-    ADC1->SC2 |= ADC_SC2_DMAEN_MASK;
+    // Setup Configuration Register 1 
+    ADC0_CFG1 = 0; // clear register
+    ADC0_CFG1 |= ADC_CFG1_ADICLK(0);    // select bus clock
+    ADC0_CFG1 |= ADC_CFG1_MODE(3);      // select 16-bit 2's complement output
+    ADC0_CFG1 |= ADC_CFG1_ADIV(0);      // select short sample time
+    ADC0_CFG1 &= ~ADC_CFG1_ADLSMP_MASK; // select short sample time
+    ADC0_CFG1 &= ~ADC_CFG1_ADLPC_MASK;  // select normal power configuration
+    
+    // Setup Configuration Register 2 
+    ADC0_CFG2 = 0; // clear register
+    ADC0_CFG2 |= ADC_CFG2_ADHSC_MASK ; // select high-speed conversion
+    ADC0_CFG2 &= ~ADC_CFG2_MUXSEL_MASK; // select a channels    
     
-    // calibrate ADC
-    ADC0->SC3 = 0; // Reset SC3
-    ADC1->SC3 = 0; // Reset SC3
-    /*do {
-        ADC0->SC3 |= (1<<7); // start calibration
-        while(ADC0->SC3&(1<<7)) {} // wait for calibration to complete
-        if((ADC0->SC3)&(1<<6)) pc.printf("Calibration Failed\r\n");
-    } while(ADC0->SC3&(1<<6));
-    */ // the calibration may be failing because ADC0_SC2 has the Vref set to external pins
+    // Setup Status and Control Register 2 
+    ADC0_SC2 = 0;                   // clear register
+    ADC0_SC2 |= ADC_SC2_REFSEL(0);  // select external voltage reference
+    ADC0_SC2 |= ADC_SC2_DMAEN_MASK; // enable DMA
+    ADC0_SC2 &= ~ADC_SC2_ADTRG_MASK; // select software trigger until calibration is complete
+    
+    // Setup Status and Control Register 3 
+    ADC0_SC3 = 0;  // Hardware Average set to 4 samples averaged
+                   // Hardware Average Disabled
+                   // select single conversion mode
     
-    ADC0->CFG1 |= ADC_CFG1_ADLPC_MASK; // high power mode for faster frequencies
-    ADC1->CFG1 |= ADC_CFG1_ADLPC_MASK; // high power mode for faster frequencies
+    // calibrate the ADC
+    ADC0_SC3 |= ADC_SC3_CAL_MASK; // start calibration
+    while(ADC0_SC3&ADC_SC3_CALF_MASK) {} // wait for calibration to complete
+    
+    // calculate the gains (see user manual page 864)
+    int16_t gain = (ADC0_CLP0+ADC0_CLP1+ADC0_CLP2+ADC0_CLP3+ADC0_CLP4+ADC0_CLPS);
+    gain = (gain>>1); // divide by 2
+    gain |= 0x8000;  // set the MSB
+    ADC0_PG = gain;
+    
+    gain = (ADC0_CLM0+ADC0_CLM1+ADC0_CLM2+ADC0_CLM3+ADC0_CLM4+ADC0_CLMS);
+    gain = (gain>>1); // divide by 2
+    gain |= 0x8000;  // set the MSB
+    ADC0_MG = gain;
     
-    ADCName adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
-    uint32_t instance = adc >> ADC_INSTANCE_SHIFT;
-    clock_manager_set_gate(kClockModuleADC, instance, true);
-    uint32_t bus_clock;
-    clock_manager_get_frequency(kBusClock, &bus_clock);
-    uint32_t clkdiv;
-    for (clkdiv = 0; clkdiv < 4; clkdiv++) {
-        if ((bus_clock >> clkdiv) <= MAX_FADC)
-            break;
-    }
-    if (clkdiv == 4) {
-        clkdiv = 0x7; //Set max div
-    }
-    // adc is enabled/triggered when reading.
-    adc_hal_set_clock_source_mode(instance, (adc_clock_source_mode_t)(clkdiv >> 2));
-    adc_hal_set_clock_divider_mode(instance, (adc_clock_divider_mode_t)(clkdiv & 0x3));
-    adc_hal_set_reference_voltage_mode(instance, kAdcVoltageVref);
-    adc_hal_set_resolution_mode(instance, kAdcSingleDiff16);
-    adc_hal_configure_continuous_conversion(instance, false); // true=continuous conversion mode, false = single conversion mode
-    adc_hal_configure_hw_trigger(instance, false); // true=hw trigger, false=sw trigger
-    adc_hal_configure_hw_average(instance, false);
-    adc_hal_set_hw_average_mode(instance, kAdcHwAverageCount4);
-    adc_hal_set_group_mux(instance, kAdcChannelMuxB); // only B channels are avail 
-
-    pinmap_pinout(pin, PinMap_ADC);
-    /*
-    pc.printf("ADC0_SC1a: %08x\r\n",ADC0_SC1A); // module disabled
-    pc.printf("ADC0_SC1b: %08x\r\n",ADC0_SC1B); // module disabled
-    pc.printf("ADC0_CFG1: %08x\r\n",ADC0_CFG1); // alternate clock2 selected, 16-bit 2's complement selected, short sample time, clock divide ration is input/8, low power mode selected
-    pc.printf("ADC0_CFG2: %08x\r\n",ADC0_CFG2); // ADxxa channels selected
-    pc.printf("ADC0_RA:   %08x\r\n",ADC0_RA);
-    pc.printf("ADC0_RB:   %08x\r\n",ADC0_RB);
-    pc.printf("ADC0_SC2:  %08x\r\n",ADC0_SC2); // hw trigger and dma enabled.  Compare function disabled and Vref set to external pin
-    pc.printf("ADC0_SC3:  %08x\r\n\n",ADC0_SC3);
-    */
+    ADC0_SC3 &= ~ADC_SC3_CAL_MASK; // stop calibration
+    
+    
+    
+    
+    
+    
+    
+    // yellow indicating calibration complete
+    red = 0;
+    green = 0;
+    
+    ADC0_SC2 |= ADC_SC2_ADTRG_MASK; // select hardware trigger now that calibration is complete
+    
+    // Setup Status and Control Register 1A 
+    ADC0_SC1A = 0; // clear register
+    ADC0_SC1A &= ~ADC_SC1_DIFF_MASK; // select single-ended mode
+    ADC0_SC1A |= ADC_SC1_AIEN_MASK;  // enable interrupt (for debugging)
+    ADC0_SC1A |= ADC_SC1_ADCH(13);   // select channel 13
+    
+    // Check if ADC is finished initializing  TODO:  This part doesn't seem right, but I did it according to 871
+    while( (ADC0_SC1A&ADC_SC1_COCO_MASK)) {}
+    gain = ADC0_RA; // read the register to clear SC1A[COCO]
+    
+    
+    
+    
+    
+    
+    // green indicating calibration and initialization complete
+    red = 1;
+    green = 0;
+    
+    
+    debug.printf("ADC0_SC1a: %08x\r\n",ADC0_SC1A);  //(0x0000004d)
+    debug.printf("ADC0_SC1b: %08x\r\n",ADC0_SC1B);  //(0x0000001f)
+    debug.printf("ADC0_CFG1: %08x\r\n",ADC0_CFG1);  //(0x0000000c)
+    debug.printf("ADC0_CFG2: %08x\r\n",ADC0_CFG2);  //(0x00000004)
+    debug.printf("ADC0_RA:   %08x\r\n",ADC0_RA);    //(0x00000000)
+    debug.printf("ADC0_RB:   %08x\r\n",ADC0_RB);    //(0x00000000)
+    debug.printf("ADC0_SC2:  %08x\r\n",ADC0_SC2);   //(0x00000044)
+    debug.printf("ADC0_SC3:  %08x\r\n\n",ADC0_SC3); //(0x00000000)
+    
     // Enable the ISR vector
     NVIC_SetVector(ADC0_IRQn, (uint32_t)&ADC0_IRQHandler);
-    NVIC_SetVector(ADC1_IRQn, (uint32_t)&ADC1_IRQHandler);
     NVIC_EnableIRQ(ADC0_IRQn);
-    NVIC_EnableIRQ(ADC1_IRQn);
 }
 
 void adc_start() {
     // reset DMA
-    dma.reset();
+    dma_reset();
     
     // set ADC to continuous mode
     ADC0_SC3 |= ADC_SC3_ADCO_MASK;
-    ADC1_SC3 |= ADC_SC3_ADCO_MASK;
+    
+    // set ADC to software trigger
+    ADC0_SC2 &= ~ADC_SC2_ADTRG_MASK;
     
     // start ADC conversion (SW trigger)
-    BW_ADC_SC1n_ADCH(0, 0, kAdcChannel13);      // This corresponds to starting an ADC conversion on channel 12 of ADC 0 - which is A0 (PTB2)
-    BW_ADC_SC1n_ADCH(1, 0, kAdcChannel14);      // This corresponds to starting an ADC conversion on channel 14 of ADC 1 - which is A2 (PTB10)
+    //ADC0_SC1A |= ADC_SC1_ADCH(13);   // write to SC1A causing a trigger
+    //BW_ADC_SC1n_ADCH(0, 0, kAdcChannel13); // trigger the ADC
 }
 
 void adc_stop() {
-    ADC0_SC3 &= ~ADC_SC3_ADCO_MASK; // set to single conversion mode effectively stopping the ADC
-    ADC1_SC3 &= ~ADC_SC3_ADCO_MASK; // set to single conversion mode effectively stopping the ADC
+    // set ADC to hardware trigger
+    ADC0_SC2 |= ADC_SC2_ADTRG_MASK;
+    
+    // set to single conversion mode effectively stopping the ADC unless a timer triggers the ADC
+    ADC0_SC3 &= ~ADC_SC3_ADCO_MASK; 
+}
+
+void adc_single_sample() {
+    ADC0_SC3 &= ~ADC_SC3_ADCO_MASK;  // single conversion mode
+    ADC0_SC2 &= ~ADC_SC2_ADTRG_MASK; // set ADC to software trigger
+    ADC0_SC1A |= ADC_SC1_ADCH(13);   // write to SC1A causing a trigger
 }
 
 void ADC0_IRQHandler() {
-    //toggle = !toggle;
-    //craw = !craw;
-}
-void ADC1_IRQHandler() {
-    //toggle = !toggle;
-    //blah = !blah;
+    toggle1 = !toggle1;
 }
\ No newline at end of file