Dependencies:   mbed-dsp mbed

Fork of DSP_200kHz by Mazzeo Research Group

adc.cpp

Committer:
timmey9
Date:
2015-01-30
Revision:
43:c593a8b9688f
Parent:
42:52a92a8d2cc7
Child:
44:41c262caf898

File content as of revision 43:c593a8b9688f:

#include "adc.h"
#include "dma.h"

DigitalOut blah(LED_BLUE);
DigitalOut craw(LED_GREEN);
DigitalOut toggle(PTC16);

void adc_init(PinName pin)
{
    // Turn on the ADC0 and ADC1 clocks
    SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK;
    SIM_SCGC3 |= SIM_SCGC3_ADC1_MASK;
       
    /*
    // Configure System Integration Module for defaults as far as ADC
    SIM_SOPT7 &= ~(SIM_SOPT7_ADC1ALTTRGEN_MASK  | // selects PDB not ALT trigger
                SIM_SOPT7_ADC1PRETRGSEL_MASK |
                SIM_SOPT7_ADC0ALTTRGEN_MASK  | // selects PDB not ALT trigger
                SIM_SOPT7_ADC0ALTTRGEN_MASK) ;
    SIM_SOPT7 = SIM_SOPT7_ADC0TRGSEL(0);       // applies only in case of ALT trigger, in which case PDB external pin input trigger for ADC
    SIM_SOPT7 = SIM_SOPT7_ADC1TRGSEL(0);       // same for both ADCs
    */
    
    // enable interrupt
    ADC0_SC1A |= ADC_SC1_AIEN_MASK;
    ADC1_SC1A |= ADC_SC1_AIEN_MASK;
    
    // enable the DMA
    ADC0->SC2 |= ADC_SC2_DMAEN_MASK;
    ADC1->SC2 |= ADC_SC2_DMAEN_MASK;
    
    // 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
    
    ADC0->CFG1 |= ADC_CFG1_ADLPC_MASK; // high power mode for faster frequencies
    ADC1->CFG1 |= ADC_CFG1_ADLPC_MASK; // high power mode for faster frequencies
    
    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);
    */
    // 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();
    
    // set ADC to continuous mode
    ADC0_SC3 |= ADC_SC3_ADCO_MASK;
    ADC1_SC3 |= ADC_SC3_ADCO_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)
}

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
}

void ADC0_IRQHandler() {
    //toggle = !toggle;
    //craw = !craw;
}
void ADC1_IRQHandler() {
    //toggle = !toggle;
    //blah = !blah;
}