Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Impedance_Fast_Circuitry by
adc.cpp@40:bd6d8c35e822, 2015-01-30 (annotated)
- Committer:
- timmey9
- Date:
- Fri Jan 30 06:16:39 2015 +0000
- Revision:
- 40:bd6d8c35e822
- Parent:
- 39:82dc3daecf32
- Child:
- 41:3e0623d81b9a
ADC and DMA working. Start and stop of ADC/DMA is also working.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
timmey9 | 39:82dc3daecf32 | 1 | #include "adc.h" |
timmey9 | 40:bd6d8c35e822 | 2 | #include "dma.h" |
timmey9 | 40:bd6d8c35e822 | 3 | |
timmey9 | 40:bd6d8c35e822 | 4 | DigitalOut blah(LED_BLUE); |
timmey9 | 40:bd6d8c35e822 | 5 | DigitalOut toggle(PTC16); |
timmey9 | 39:82dc3daecf32 | 6 | |
timmey9 | 39:82dc3daecf32 | 7 | void analog_initialization(PinName pin, Serial &pc) |
timmey9 | 39:82dc3daecf32 | 8 | { |
timmey9 | 39:82dc3daecf32 | 9 | |
timmey9 | 40:bd6d8c35e822 | 10 | |
timmey9 | 39:82dc3daecf32 | 11 | // Turn on the ADC0 and ADC1 clocks |
timmey9 | 39:82dc3daecf32 | 12 | SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK; |
timmey9 | 39:82dc3daecf32 | 13 | SIM_SCGC3 |= SIM_SCGC3_ADC1_MASK; |
timmey9 | 39:82dc3daecf32 | 14 | |
timmey9 | 39:82dc3daecf32 | 15 | |
timmey9 | 40:bd6d8c35e822 | 16 | /* |
timmey9 | 39:82dc3daecf32 | 17 | // Configure System Integration Module for defaults as far as ADC |
timmey9 | 39:82dc3daecf32 | 18 | SIM_SOPT7 &= ~(SIM_SOPT7_ADC1ALTTRGEN_MASK | // selects PDB not ALT trigger |
timmey9 | 39:82dc3daecf32 | 19 | SIM_SOPT7_ADC1PRETRGSEL_MASK | |
timmey9 | 39:82dc3daecf32 | 20 | SIM_SOPT7_ADC0ALTTRGEN_MASK | // selects PDB not ALT trigger |
timmey9 | 39:82dc3daecf32 | 21 | SIM_SOPT7_ADC0ALTTRGEN_MASK) ; |
timmey9 | 39:82dc3daecf32 | 22 | SIM_SOPT7 = SIM_SOPT7_ADC0TRGSEL(0); // applies only in case of ALT trigger, in which case PDB external pin input trigger for ADC |
timmey9 | 39:82dc3daecf32 | 23 | SIM_SOPT7 = SIM_SOPT7_ADC1TRGSEL(0); // same for both ADCs |
timmey9 | 40:bd6d8c35e822 | 24 | */ |
timmey9 | 40:bd6d8c35e822 | 25 | |
timmey9 | 40:bd6d8c35e822 | 26 | // enable interrupt |
timmey9 | 40:bd6d8c35e822 | 27 | ADC0_SC1A |= ADC_SC1_AIEN_MASK; |
timmey9 | 39:82dc3daecf32 | 28 | |
timmey9 | 39:82dc3daecf32 | 29 | // enable the DMA |
timmey9 | 39:82dc3daecf32 | 30 | ADC0->SC2 |= ADC_SC2_DMAEN_MASK; |
timmey9 | 39:82dc3daecf32 | 31 | //ADC1->SC2 |= ADC_SC2_DMAEN_MASK; |
timmey9 | 39:82dc3daecf32 | 32 | |
timmey9 | 39:82dc3daecf32 | 33 | // calibrate ADC |
timmey9 | 39:82dc3daecf32 | 34 | ADC0->SC3 = 0; // Reset SC3 |
timmey9 | 39:82dc3daecf32 | 35 | //ADC1->SC3 = 0; // Reset SC3 |
timmey9 | 39:82dc3daecf32 | 36 | /*do { |
timmey9 | 39:82dc3daecf32 | 37 | ADC0->SC3 |= (1<<7); // start calibration |
timmey9 | 39:82dc3daecf32 | 38 | while(ADC0->SC3&(1<<7)) {} // wait for calibration to complete |
timmey9 | 39:82dc3daecf32 | 39 | if((ADC0->SC3)&(1<<6)) pc.printf("Calibration Failed\r\n"); |
timmey9 | 39:82dc3daecf32 | 40 | } while(ADC0->SC3&(1<<6)); |
timmey9 | 39:82dc3daecf32 | 41 | */ // the calibration may be failing because ADC0_SC2 has the Vref set to external pins |
timmey9 | 39:82dc3daecf32 | 42 | |
timmey9 | 39:82dc3daecf32 | 43 | ADC0->CFG1 |= ADC_CFG1_ADLPC_MASK; // high power mode for faster frequencies |
timmey9 | 39:82dc3daecf32 | 44 | |
timmey9 | 39:82dc3daecf32 | 45 | ADCName adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); |
timmey9 | 39:82dc3daecf32 | 46 | uint32_t instance = adc >> ADC_INSTANCE_SHIFT; |
timmey9 | 39:82dc3daecf32 | 47 | clock_manager_set_gate(kClockModuleADC, instance, true); |
timmey9 | 39:82dc3daecf32 | 48 | uint32_t bus_clock; |
timmey9 | 39:82dc3daecf32 | 49 | clock_manager_get_frequency(kBusClock, &bus_clock); |
timmey9 | 39:82dc3daecf32 | 50 | uint32_t clkdiv; |
timmey9 | 39:82dc3daecf32 | 51 | for (clkdiv = 0; clkdiv < 4; clkdiv++) { |
timmey9 | 39:82dc3daecf32 | 52 | if ((bus_clock >> clkdiv) <= MAX_FADC) |
timmey9 | 39:82dc3daecf32 | 53 | break; |
timmey9 | 39:82dc3daecf32 | 54 | } |
timmey9 | 39:82dc3daecf32 | 55 | if (clkdiv == 4) { |
timmey9 | 39:82dc3daecf32 | 56 | clkdiv = 0x7; //Set max div |
timmey9 | 39:82dc3daecf32 | 57 | } |
timmey9 | 39:82dc3daecf32 | 58 | // adc is enabled/triggered when reading. |
timmey9 | 39:82dc3daecf32 | 59 | adc_hal_set_clock_source_mode(instance, (adc_clock_source_mode_t)(clkdiv >> 2)); |
timmey9 | 39:82dc3daecf32 | 60 | adc_hal_set_clock_divider_mode(instance, (adc_clock_divider_mode_t)(clkdiv & 0x3)); |
timmey9 | 39:82dc3daecf32 | 61 | adc_hal_set_reference_voltage_mode(instance, kAdcVoltageVref); |
timmey9 | 39:82dc3daecf32 | 62 | adc_hal_set_resolution_mode(instance, kAdcSingleDiff16); |
timmey9 | 40:bd6d8c35e822 | 63 | adc_hal_configure_continuous_conversion(instance, true); // true=continuous conversion mode, false = single conversion mode |
timmey9 | 40:bd6d8c35e822 | 64 | adc_hal_configure_hw_trigger(instance, false); // true=hw trigger, false=sw trigger |
timmey9 | 39:82dc3daecf32 | 65 | adc_hal_configure_hw_average(instance, false); |
timmey9 | 39:82dc3daecf32 | 66 | adc_hal_set_hw_average_mode(instance, kAdcHwAverageCount4); |
timmey9 | 39:82dc3daecf32 | 67 | adc_hal_set_group_mux(instance, kAdcChannelMuxB); // only B channels are avail |
timmey9 | 39:82dc3daecf32 | 68 | |
timmey9 | 39:82dc3daecf32 | 69 | pinmap_pinout(pin, PinMap_ADC); |
timmey9 | 39:82dc3daecf32 | 70 | |
timmey9 | 39:82dc3daecf32 | 71 | pc.printf("ADC0_SC1a: %08x\r\n",ADC0_SC1A); // module disabled |
timmey9 | 39:82dc3daecf32 | 72 | pc.printf("ADC0_SC1b: %08x\r\n",ADC0_SC1B); // module disabled |
timmey9 | 39:82dc3daecf32 | 73 | 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 |
timmey9 | 39:82dc3daecf32 | 74 | pc.printf("ADC0_CFG2: %08x\r\n",ADC0_CFG2); // ADxxa channels selected |
timmey9 | 39:82dc3daecf32 | 75 | pc.printf("ADC0_RA: %08x\r\n",ADC0_RA); |
timmey9 | 39:82dc3daecf32 | 76 | pc.printf("ADC0_RB: %08x\r\n",ADC0_RB); |
timmey9 | 39:82dc3daecf32 | 77 | pc.printf("ADC0_SC2: %08x\r\n",ADC0_SC2); // hw trigger and dma enabled. Compare function disabled and Vref set to external pin |
timmey9 | 39:82dc3daecf32 | 78 | pc.printf("ADC0_SC3: %08x\r\n\n",ADC0_SC3); |
timmey9 | 40:bd6d8c35e822 | 79 | |
timmey9 | 40:bd6d8c35e822 | 80 | // Enable the ISR vector |
timmey9 | 40:bd6d8c35e822 | 81 | NVIC_SetVector (ADC0_IRQn, (uint32_t)&ADC0_IRQHandler); |
timmey9 | 40:bd6d8c35e822 | 82 | NVIC_EnableIRQ(ADC0_IRQn); |
timmey9 | 40:bd6d8c35e822 | 83 | } |
timmey9 | 40:bd6d8c35e822 | 84 | |
timmey9 | 40:bd6d8c35e822 | 85 | void start_adc() { |
timmey9 | 40:bd6d8c35e822 | 86 | // reset DMA |
timmey9 | 40:bd6d8c35e822 | 87 | //reset_dma(); |
timmey9 | 40:bd6d8c35e822 | 88 | dma_init(100); |
timmey9 | 40:bd6d8c35e822 | 89 | |
timmey9 | 40:bd6d8c35e822 | 90 | // set ADC to continuous mode |
timmey9 | 40:bd6d8c35e822 | 91 | ADC0_SC3 |= ADC_SC3_ADCO_MASK; |
timmey9 | 40:bd6d8c35e822 | 92 | |
timmey9 | 40:bd6d8c35e822 | 93 | // start ADC conversion (SW trigger) |
timmey9 | 40:bd6d8c35e822 | 94 | BW_ADC_SC1n_ADCH(0, 0, kAdcChannel12); // This corresponds to starting an ADC conversion on channel 12 of ADC 0 - which is A0 (PTB2) |
timmey9 | 40:bd6d8c35e822 | 95 | //BW_ADC_SC1n_ADCH(1, 0, kAdcChannel14); // This corresponds to starting an ADC conversion on channel 14 of ADC 1 - which is A2 (PTB10) |
timmey9 | 40:bd6d8c35e822 | 96 | } |
timmey9 | 40:bd6d8c35e822 | 97 | |
timmey9 | 40:bd6d8c35e822 | 98 | void stop_adc() { |
timmey9 | 40:bd6d8c35e822 | 99 | ADC0_SC3 &= ~ADC_SC3_ADCO_MASK; // set to single conversion mode effectively stopping the ADC |
timmey9 | 40:bd6d8c35e822 | 100 | } |
timmey9 | 40:bd6d8c35e822 | 101 | |
timmey9 | 40:bd6d8c35e822 | 102 | void ADC0_IRQHandler() { |
timmey9 | 40:bd6d8c35e822 | 103 | blah = !blah; |
timmey9 | 39:82dc3daecf32 | 104 | } |