Jared Baxter
/
Impedance_Fast_Circuitry
Fork of DSP_200kHz by
DMA_sampling/adc.cpp@53:83a90a47c1fd, 2016-02-09 (annotated)
- Committer:
- bmazzeo
- Date:
- Tue Feb 09 15:11:08 2016 +0000
- Revision:
- 53:83a90a47c1fd
- Parent:
- Sample/adc.cpp@52:5a40cc58c4c2
- Child:
- 54:1697dc574b96
ADC initialization and calibration up and running.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
timmey9 | 39:82dc3daecf32 | 1 | #include "adc.h" |
timmey9 | 45:d591d138cdeb | 2 | |
timmey9 | 44:41c262caf898 | 3 | /* |
bmazzeo | 53:83a90a47c1fd | 4 | From page 869 of the user manual: |
bmazzeo | 53:83a90a47c1fd | 5 | |
bmazzeo | 53:83a90a47c1fd | 6 | Before the ADC module can be used to complete conversions, an initialization procedure |
bmazzeo | 53:83a90a47c1fd | 7 | must be performed. A typical sequence is: |
bmazzeo | 53:83a90a47c1fd | 8 | 1. Calibrate the ADC by following the calibration instructions in Calibration function. |
bmazzeo | 53:83a90a47c1fd | 9 | 2. Update CFG to select the input clock source and the divide ratio used to generate |
bmazzeo | 53:83a90a47c1fd | 10 | ADCK. This register is also used for selecting sample time and low-power |
bmazzeo | 53:83a90a47c1fd | 11 | configuration. |
bmazzeo | 53:83a90a47c1fd | 12 | 3. Update SC2 to select the conversion trigger, hardware or software, and compare |
bmazzeo | 53:83a90a47c1fd | 13 | function options, if enabled. |
bmazzeo | 53:83a90a47c1fd | 14 | 4. Update SC3 to select whether conversions will be continuous or completed only once |
bmazzeo | 53:83a90a47c1fd | 15 | (ADCO) and whether to perform hardware averaging. |
bmazzeo | 53:83a90a47c1fd | 16 | 5. Update SC1:SC1n registers to select whether conversions will be single-ended or |
bmazzeo | 53:83a90a47c1fd | 17 | differential and to enable or disable conversion complete interrupts. Also, select the |
bmazzeo | 53:83a90a47c1fd | 18 | input channel which can be used to perform conversions. |
timmey9 | 44:41c262caf898 | 19 | */ |
timmey9 | 45:d591d138cdeb | 20 | DigitalOut green(LED_GREEN); |
timmey9 | 45:d591d138cdeb | 21 | DigitalOut red(LED_RED); |
timmey9 | 51:43143a3fc2d7 | 22 | |
bmazzeo | 53:83a90a47c1fd | 23 | //Serial debug(USBTX, USBRX); |
timmey9 | 51:43143a3fc2d7 | 24 | |
timmey9 | 39:82dc3daecf32 | 25 | |
timmey9 | 45:d591d138cdeb | 26 | void adc_init() |
bmazzeo | 53:83a90a47c1fd | 27 | { |
bmazzeo | 53:83a90a47c1fd | 28 | |
timmey9 | 39:82dc3daecf32 | 29 | // Turn on the ADC0 and ADC1 clocks |
timmey9 | 39:82dc3daecf32 | 30 | SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK; |
timmey9 | 39:82dc3daecf32 | 31 | SIM_SCGC3 |= SIM_SCGC3_ADC1_MASK; |
timmey9 | 40:bd6d8c35e822 | 32 | |
timmey9 | 45:d591d138cdeb | 33 | // Set ADC hardware trigger to PDB0 |
timmey9 | 48:29f14bc30ba6 | 34 | SIM_SOPT7 = SIM_SOPT7_ADC0TRGSEL(0); // Select triggering by PDB and select pre-trigger A |
timmey9 | 48:29f14bc30ba6 | 35 | SIM_SOPT7 = SIM_SOPT7_ADC1TRGSEL(0); // Select triggering by PDB and select pre-trigger A |
bmazzeo | 53:83a90a47c1fd | 36 | |
bmazzeo | 53:83a90a47c1fd | 37 | // turn on the clock to the PDB |
bmazzeo | 53:83a90a47c1fd | 38 | // SIM->SCGC6 |= SIM_SCGC6_PDB_MASK; |
timmey9 | 39:82dc3daecf32 | 39 | |
bmazzeo | 53:83a90a47c1fd | 40 | // set ADC trigger to PDB0 |
bmazzeo | 53:83a90a47c1fd | 41 | // SIM_SOPT7 = SIM_SOPT7_ADC0TRGSEL(0); |
bmazzeo | 53:83a90a47c1fd | 42 | |
bmazzeo | 53:83a90a47c1fd | 43 | // This lets the clocks go to the ADC |
bmazzeo | 53:83a90a47c1fd | 44 | // SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK; |
bmazzeo | 53:83a90a47c1fd | 45 | // SIM_SCGC3 |= SIM_SCGC3_ADC1_MASK; |
timmey9 | 45:d591d138cdeb | 46 | |
bmazzeo | 53:83a90a47c1fd | 47 | /* // This lets the clocks go to the PDB |
bmazzeo | 53:83a90a47c1fd | 48 | SIM_SCGC6 |= SIM_SCGC6_PDB_MASK; |
bmazzeo | 53:83a90a47c1fd | 49 | |
bmazzeo | 53:83a90a47c1fd | 50 | // Set PDB to be enabled and have continous triggers |
bmazzeo | 53:83a90a47c1fd | 51 | PDB0_SC = PDB_SC_DMAEN_MASK // DMA Enable |
bmazzeo | 53:83a90a47c1fd | 52 | | PDB_SC_TRGSEL(0xf) // Software trigger |
bmazzeo | 53:83a90a47c1fd | 53 | | PDB_SC_PDBEN_MASK // Set to continuous mode |
bmazzeo | 53:83a90a47c1fd | 54 | | PDB_SC_LDOK_MASK; // Loading mask |
bmazzeo | 53:83a90a47c1fd | 55 | |
bmazzeo | 53:83a90a47c1fd | 56 | PDB0_SC |= PDB_SC_SWTRIG_MASK; // enable software trigger (start the PDB) |
timmey9 | 50:33524a27e08c | 57 | |
timmey9 | 39:82dc3daecf32 | 58 | |
bmazzeo | 53:83a90a47c1fd | 59 | // This now routes the triggers |
bmazzeo | 53:83a90a47c1fd | 60 | SIM_SOPT7 = SIM_SOPT7_ADC0TRGSEL(0); |
bmazzeo | 53:83a90a47c1fd | 61 | SIM_SOPT7 = SIM_SOPT7_ADC1TRGSEL(0); |
bmazzeo | 53:83a90a47c1fd | 62 | */ |
bmazzeo | 53:83a90a47c1fd | 63 | |
bmazzeo | 53:83a90a47c1fd | 64 | /* From page 853 of the user manual |
bmazzeo | 53:83a90a47c1fd | 65 | Prior to calibration, the user must configure the ADC's clock source and frequency, low |
bmazzeo | 53:83a90a47c1fd | 66 | power configuration, voltage reference selection, sample time, and high speed |
bmazzeo | 53:83a90a47c1fd | 67 | configuration according to the application's clock source availability and needs. |
bmazzeo | 53:83a90a47c1fd | 68 | */ |
bmazzeo | 53:83a90a47c1fd | 69 | ADC0_SC1A = 0x0C; //AIEN = 0, DIFF = 0, Channel = AD12 (PTB2) |
bmazzeo | 53:83a90a47c1fd | 70 | ADC1_SC1A = 0x0E; //AIEN = 0, DIFF = 0, Channel = AD14 (PTB10) |
bmazzeo | 53:83a90a47c1fd | 71 | |
bmazzeo | 53:83a90a47c1fd | 72 | ADC0_CFG1 = 0x0C; //ADLPC = 0, ADIV = 0, ADLSMP = 0, MODE = 0b11, ADICLK = 00 (16-bit single-ended) |
bmazzeo | 53:83a90a47c1fd | 73 | ADC1_CFG1 = 0x0C; //ADLPC = 0, ADIV = 0, ADLSMP = 0, MODE = 0b11, ADICLK = 00 (16-bit single-ended) |
timmey9 | 45:d591d138cdeb | 74 | |
bmazzeo | 53:83a90a47c1fd | 75 | // It is necessary not to have hardware trigger for calbiration |
bmazzeo | 53:83a90a47c1fd | 76 | ADC0_CFG2 = 0x00; // MUXSEL = 0, ADACKEN = 0, ADHSC = 0, ADLSTS = 0 (does not matter - short sample time) |
bmazzeo | 53:83a90a47c1fd | 77 | ADC1_CFG2 = 0x00; // MUXSEL = 0, ADACKEN = 0, ADHSC = 0, ADLSTS = 0 (does not matter - short sample time) |
bmazzeo | 53:83a90a47c1fd | 78 | |
bmazzeo | 53:83a90a47c1fd | 79 | // Use averaging to make calibration better |
bmazzeo | 53:83a90a47c1fd | 80 | ADC0_SC3 = 0x0F; // CAL = 0, CALF = 0, res[5:4], ADCO = 1 (continuous conversion), AVGE = 1, AVGS = 11 |
bmazzeo | 53:83a90a47c1fd | 81 | ADC1_SC3 = 0x0F; // CAL = 0, CALF = 0, res[5:4], ADCO = 1 (continuous conversion), AVGE = 1, AVGS = 11 |
timmey9 | 39:82dc3daecf32 | 82 | |
bmazzeo | 53:83a90a47c1fd | 83 | |
bmazzeo | 53:83a90a47c1fd | 84 | // calibrate the ADC (following Joey's code example) |
timmey9 | 45:d591d138cdeb | 85 | ADC0_SC3 |= ADC_SC3_CAL_MASK; // start calibration |
timmey9 | 45:d591d138cdeb | 86 | while(ADC0_SC3&ADC_SC3_CALF_MASK) {} // wait for calibration to complete |
timmey9 | 46:a015ebf4663b | 87 | ADC1_SC3 |= ADC_SC3_CAL_MASK; // start calibration |
timmey9 | 46:a015ebf4663b | 88 | while(ADC1_SC3&ADC_SC3_CALF_MASK) {} // wait for calibration to complete |
bmazzeo | 53:83a90a47c1fd | 89 | |
timmey9 | 45:d591d138cdeb | 90 | // calculate the gains (see user manual page 864) |
timmey9 | 45:d591d138cdeb | 91 | int16_t gain = (ADC0_CLP0+ADC0_CLP1+ADC0_CLP2+ADC0_CLP3+ADC0_CLP4+ADC0_CLPS); |
bmazzeo | 53:83a90a47c1fd | 92 | gain = gain / 2; // divide by 2 |
timmey9 | 45:d591d138cdeb | 93 | gain |= 0x8000; // set the MSB |
timmey9 | 45:d591d138cdeb | 94 | ADC0_PG = gain; |
timmey9 | 45:d591d138cdeb | 95 | |
timmey9 | 46:a015ebf4663b | 96 | gain = (ADC1_CLP0+ADC1_CLP1+ADC1_CLP2+ADC1_CLP3+ADC1_CLP4+ADC1_CLPS); |
bmazzeo | 53:83a90a47c1fd | 97 | gain = gain / 2; // divide by 2 |
timmey9 | 46:a015ebf4663b | 98 | gain |= 0x8000; // set the MSB |
timmey9 | 46:a015ebf4663b | 99 | ADC1_PG = gain; |
timmey9 | 46:a015ebf4663b | 100 | |
timmey9 | 45:d591d138cdeb | 101 | gain = (ADC0_CLM0+ADC0_CLM1+ADC0_CLM2+ADC0_CLM3+ADC0_CLM4+ADC0_CLMS); |
bmazzeo | 53:83a90a47c1fd | 102 | gain = gain / 2; // divide by 2 |
timmey9 | 45:d591d138cdeb | 103 | gain |= 0x8000; // set the MSB |
timmey9 | 45:d591d138cdeb | 104 | ADC0_MG = gain; |
timmey9 | 39:82dc3daecf32 | 105 | |
timmey9 | 46:a015ebf4663b | 106 | gain = (ADC1_CLM0+ADC1_CLM1+ADC1_CLM2+ADC1_CLM3+ADC1_CLM4+ADC1_CLMS); |
bmazzeo | 53:83a90a47c1fd | 107 | gain = gain / 2; // divide by 2 |
timmey9 | 46:a015ebf4663b | 108 | gain |= 0x8000; // set the MSB |
timmey9 | 46:a015ebf4663b | 109 | ADC1_MG = gain; |
timmey9 | 46:a015ebf4663b | 110 | |
bmazzeo | 53:83a90a47c1fd | 111 | |
bmazzeo | 53:83a90a47c1fd | 112 | // Now set up for use in the rest of the program. |
bmazzeo | 53:83a90a47c1fd | 113 | ADC0_SC2 = 0x44; // ADACT = 0, ADTRG = 1 (HW trigger), ACFE = 0, ACFGT = 0, ACREN = 0, DMAEN = 1, REFSEL = 00 (DMAEN needs to be asserted) |
bmazzeo | 53:83a90a47c1fd | 114 | ADC1_SC2 = 0x44; // ADACT = 0, ADTRG = 1 (HW trigger), ACFE = 0, ACFGT = 0, ACREN = 0, DMAEN = 1, REFSEL = 00 (DMAEN needs to be asserted) |
timmey9 | 51:43143a3fc2d7 | 115 | |
bmazzeo | 53:83a90a47c1fd | 116 | ADC0_SC3 = 0x08; // CAL = 0, CALF = 0, res[5:4], ADCO = 1 (continuous conversion), AVGE = 0, AVGS = 00 |
bmazzeo | 53:83a90a47c1fd | 117 | ADC1_SC3 = 0x08; // CAL = 0, CALF = 0, res[5:4], ADCO = 1 (continuous conversion), AVGE = 0, AVGS = 00 |
timmey9 | 45:d591d138cdeb | 118 | |
bmazzeo | 53:83a90a47c1fd | 119 | // debug.printf("Calbiration complete. Hardware continuous conversion running.\r\n"); |
bmazzeo | 53:83a90a47c1fd | 120 | // The ADCs are now just continuously converting and generating DMA signals after each conversion |
timmey9 | 51:43143a3fc2d7 | 121 | } |
timmey9 | 51:43143a3fc2d7 | 122 |