Jared Baxter
/
Impedance_Fast_Circuitry
Impedance Fast Circuitry Software
Fork of DSP_200kHz by
DMA_sampling/adc.cpp@87:80c9169acb85, 2018-06-27 (annotated)
- Committer:
- baxterja
- Date:
- Wed Jun 27 19:23:32 2018 +0000
- Revision:
- 87:80c9169acb85
- Parent:
- 74:ebc9f09fda11
Changed frequencies for different probe number. I also ordered frequencies from smallest to largest (I don't know if this is a good idea or not)
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 | 54:1697dc574b96 | 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 |
baxterja | 74:ebc9f09fda11 | 30 | SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK; |
baxterja | 74:ebc9f09fda11 | 31 | SIM->SCGC3 |= SIM_SCGC3_ADC1_MASK; |
timmey9 | 40:bd6d8c35e822 | 32 | |
timmey9 | 45:d591d138cdeb | 33 | // Set ADC hardware trigger to PDB0 |
baxterja | 74:ebc9f09fda11 | 34 | SIM->SOPT7 = SIM_SOPT7_ADC0TRGSEL(0); // Select triggering by PDB and select pre-trigger A |
baxterja | 74:ebc9f09fda11 | 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 | */ |
baxterja | 74:ebc9f09fda11 | 69 | ADC0->SC1[0] = 0x0C; //AIEN = 0, DIFF = 0, Channel = AD12 (PTB2) |
baxterja | 74:ebc9f09fda11 | 70 | ADC1->SC1[0] = 0x0E; //AIEN = 0, DIFF = 0, Channel = AD14 (PTB10) |
bmazzeo | 53:83a90a47c1fd | 71 | |
baxterja | 74:ebc9f09fda11 | 72 | ADC0->CFG1 = 0x0C; //ADLPC = 0, ADIV = 0, ADLSMP = 0, MODE = 0b11, ADICLK = 00 (16-bit single-ended) |
baxterja | 74:ebc9f09fda11 | 73 | ADC1->CFG1 = 0x0C; //ADLPC = 0, ADIV = 0, ADLSMP = 0, MODE = 0b11, ADICLK = 00 (16-bit single-ended) |
bmazzeo | 54:1697dc574b96 | 74 | |
bmazzeo | 54:1697dc574b96 | 75 | // ADC0_CFG1 = 0x00; //ADLPC = 0, ADIV = 0, ADLSMP = 0, MODE = 0b00, ADICLK = 00 (16-bit single-ended) |
bmazzeo | 54:1697dc574b96 | 76 | // ADC1_CFG1 = 0x00; //ADLPC = 0, ADIV = 0, ADLSMP = 0, MODE = 0b00, ADICLK = 00 (16-bit single-ended) |
bmazzeo | 54:1697dc574b96 | 77 | |
timmey9 | 45:d591d138cdeb | 78 | |
bmazzeo | 53:83a90a47c1fd | 79 | // It is necessary not to have hardware trigger for calbiration |
baxterja | 74:ebc9f09fda11 | 80 | ADC0->CFG2 = 0x00; // MUXSEL = 0, ADACKEN = 0, ADHSC = 0, ADLSTS = 0 (does not matter - short sample time) |
baxterja | 74:ebc9f09fda11 | 81 | ADC1->CFG2 = 0x00; // MUXSEL = 0, ADACKEN = 0, ADHSC = 0, ADLSTS = 0 (does not matter - short sample time) |
bmazzeo | 53:83a90a47c1fd | 82 | |
bmazzeo | 53:83a90a47c1fd | 83 | // Use averaging to make calibration better |
baxterja | 74:ebc9f09fda11 | 84 | ADC0->SC3 = 0x07; // CAL = 0, CALF = 0, res[5:4], ADCO = 0 (continuous conversion), AVGE = 1, AVGS = 11 |
baxterja | 74:ebc9f09fda11 | 85 | ADC1->SC3 = 0x07; // CAL = 0, CALF = 0, res[5:4], ADCO = 0 (continuous conversion), AVGE = 1, AVGS = 11 |
timmey9 | 39:82dc3daecf32 | 86 | |
bmazzeo | 53:83a90a47c1fd | 87 | |
bmazzeo | 53:83a90a47c1fd | 88 | // calibrate the ADC (following Joey's code example) |
baxterja | 74:ebc9f09fda11 | 89 | ADC0->SC3 |= ADC_SC3_CAL_MASK; // start calibration |
baxterja | 74:ebc9f09fda11 | 90 | while(ADC0->SC3&ADC_SC3_CALF_MASK) {} // wait for calibration to complete |
baxterja | 74:ebc9f09fda11 | 91 | ADC1->SC3 |= ADC_SC3_CAL_MASK; // start calibration |
baxterja | 74:ebc9f09fda11 | 92 | while(ADC1->SC3&ADC_SC3_CALF_MASK) {} // wait for calibration to complete |
bmazzeo | 54:1697dc574b96 | 93 | |
baxterja | 74:ebc9f09fda11 | 94 | debug.printf("ADC0_CLP0:%d\r\n", ADC0->CLP0); |
baxterja | 74:ebc9f09fda11 | 95 | debug.printf("ADC0_CLP1:%d\r\n", ADC0->CLP1); |
baxterja | 74:ebc9f09fda11 | 96 | debug.printf("ADC0_CLP2:%d\r\n", ADC0->CLP2); |
baxterja | 74:ebc9f09fda11 | 97 | debug.printf("ADC0_CLP3:%d\r\n", ADC0->CLP3); |
baxterja | 74:ebc9f09fda11 | 98 | debug.printf("ADC0_CLPS:%d\r\n", ADC0->CLPS); |
bmazzeo | 53:83a90a47c1fd | 99 | |
timmey9 | 45:d591d138cdeb | 100 | // calculate the gains (see user manual page 864) |
baxterja | 74:ebc9f09fda11 | 101 | int16_t gain = (ADC0->CLP0+ADC0->CLP1+ADC0->CLP2+ADC0->CLP3+ADC0->CLP4+ADC0->CLPS); |
bmazzeo | 53:83a90a47c1fd | 102 | gain = gain / 2; // divide by 2 |
timmey9 | 45:d591d138cdeb | 103 | gain |= 0x8000; // set the MSB |
baxterja | 74:ebc9f09fda11 | 104 | ADC0->PG = gain; |
timmey9 | 45:d591d138cdeb | 105 | |
baxterja | 74:ebc9f09fda11 | 106 | gain = (ADC1->CLP0+ADC1->CLP1+ADC1->CLP2+ADC1->CLP3+ADC1->CLP4+ADC1->CLPS); |
bmazzeo | 53:83a90a47c1fd | 107 | gain = gain / 2; // divide by 2 |
timmey9 | 46:a015ebf4663b | 108 | gain |= 0x8000; // set the MSB |
baxterja | 74:ebc9f09fda11 | 109 | ADC1->PG = gain; |
timmey9 | 46:a015ebf4663b | 110 | |
baxterja | 74:ebc9f09fda11 | 111 | gain = (ADC0->CLM0+ADC0->CLM1+ADC0->CLM2+ADC0->CLM3+ADC0->CLM4+ADC0->CLMS); |
bmazzeo | 53:83a90a47c1fd | 112 | gain = gain / 2; // divide by 2 |
timmey9 | 45:d591d138cdeb | 113 | gain |= 0x8000; // set the MSB |
baxterja | 74:ebc9f09fda11 | 114 | ADC0->MG = gain; |
timmey9 | 39:82dc3daecf32 | 115 | |
baxterja | 74:ebc9f09fda11 | 116 | gain = (ADC1->CLM0+ADC1->CLM1+ADC1->CLM2+ADC1->CLM3+ADC1->CLM4+ADC1->CLMS); |
bmazzeo | 53:83a90a47c1fd | 117 | gain = gain / 2; // divide by 2 |
timmey9 | 46:a015ebf4663b | 118 | gain |= 0x8000; // set the MSB |
baxterja | 74:ebc9f09fda11 | 119 | ADC1->MG = gain; |
timmey9 | 46:a015ebf4663b | 120 | |
bmazzeo | 54:1697dc574b96 | 121 | // ADC0_SC3 &= ~ADC_SC3_CAL_MASK; // stop calibration |
bmazzeo | 54:1697dc574b96 | 122 | // ADC1_SC3 &= ~ADC_SC3_CAL_MASK; // stop calibration |
bmazzeo | 54:1697dc574b96 | 123 | |
bmazzeo | 53:83a90a47c1fd | 124 | |
bmazzeo | 54:1697dc574b96 | 125 | // Now set up for use in the rest of the program - software trigger |
baxterja | 74:ebc9f09fda11 | 126 | ADC0->SC2 = 0x04; // ADACT = 0, ADTRG = 0 (HW trigger), ACFE = 0, ACFGT = 0, ACREN = 0, DMAEN = 1, REFSEL = 00 (DMAEN needs to be asserted) |
baxterja | 74:ebc9f09fda11 | 127 | ADC1->SC2 = 0x04; // ADACT = 0, ADTRG = 0 (HW trigger), ACFE = 0, ACFGT = 0, ACREN = 0, DMAEN = 1, REFSEL = 00 (DMAEN needs to be asserted) |
bmazzeo | 54:1697dc574b96 | 128 | |
bmazzeo | 54:1697dc574b96 | 129 | |
bmazzeo | 55:2526b3317bc8 | 130 | // ADC0_SC3 = 0x08; // CAL = 0, CALF = 0, res[5:4], ADCO = 1 (continuous conversion), AVGE = 0, AVGS = 00 |
bmazzeo | 55:2526b3317bc8 | 131 | // ADC1_SC3 = 0x08; // CAL = 0, CALF = 0, res[5:4], ADCO = 1 (continuous conversion), AVGE = 0, AVGS = 00 |
bmazzeo | 54:1697dc574b96 | 132 | |
baxterja | 74:ebc9f09fda11 | 133 | ADC0->SC3 = 0x00; // CAL = 0, CALF = 0, res[5:4], ADCO = 0 (continuous conversion), AVGE = 0, AVGS = 00 |
baxterja | 74:ebc9f09fda11 | 134 | ADC1->SC3 = 0x00; // CAL = 0, CALF = 0, res[5:4], ADCO = 0 (continuous conversion), AVGE = 0, AVGS = 00 |
bmazzeo | 54:1697dc574b96 | 135 | |
bmazzeo | 54:1697dc574b96 | 136 | |
timmey9 | 45:d591d138cdeb | 137 | |
baxterja | 74:ebc9f09fda11 | 138 | // A write to SC1[0] is necessary as a software trigger |
baxterja | 74:ebc9f09fda11 | 139 | ADC0->SC1[0] = 0x0C; //AIEN = 0, DIFF = 0, Channel = AD12 (PTB2) |
baxterja | 74:ebc9f09fda11 | 140 | ADC1->SC1[0] = 0x0E; //AIEN = 0, DIFF = 0, Channel = AD14 (PTB10) |
bmazzeo | 54:1697dc574b96 | 141 | |
baxterja | 74:ebc9f09fda11 | 142 | while( (ADC1->SC1[0]&ADC_SC1_COCO_MASK)) {} |
baxterja | 74:ebc9f09fda11 | 143 | //gain = ADC0_R[0]; // read the register to clear SC1[0][COCO] |
baxterja | 74:ebc9f09fda11 | 144 | debug.printf("ADC0_R[0]:%i\r\n", ADC0->R[0]); |
baxterja | 74:ebc9f09fda11 | 145 | debug.printf("ADC0_R[1]:%i\r\n", ADC0->R[1]); |
baxterja | 74:ebc9f09fda11 | 146 | debug.printf("ADC1_R[0]:%i\r\n", ADC1->R[0]); |
baxterja | 74:ebc9f09fda11 | 147 | debug.printf("ADC1_R[1]:%i\r\n", ADC1->R[1]); |
bmazzeo | 54:1697dc574b96 | 148 | |
bmazzeo | 54:1697dc574b96 | 149 | /* |
bmazzeo | 54:1697dc574b96 | 150 | |
baxterja | 74:ebc9f09fda11 | 151 | ADC0_SC1[0] = 0x0C; //AIEN = 0, DIFF = 0, Channel = AD12 (PTB2) |
baxterja | 74:ebc9f09fda11 | 152 | ADC1_SC1[0] = 0x0E; //AIEN = 0, DIFF = 0, Channel = AD14 (PTB10) |
bmazzeo | 54:1697dc574b96 | 153 | |
baxterja | 74:ebc9f09fda11 | 154 | while( (ADC1_SC1[0]&ADC_SC1_COCO_MASK)) {} |
baxterja | 74:ebc9f09fda11 | 155 | debug.printf("ADC1_R[0]:%i\r\n", ADC1_R[0]); |
bmazzeo | 54:1697dc574b96 | 156 | |
baxterja | 74:ebc9f09fda11 | 157 | ADC0_SC1[0] = 0x0C; //AIEN = 0, DIFF = 0, Channel = AD12 (PTB2) |
baxterja | 74:ebc9f09fda11 | 158 | ADC1_SC1[0] = 0x0E; //AIEN = 0, DIFF = 0, Channel = AD14 (PTB10) |
bmazzeo | 54:1697dc574b96 | 159 | |
bmazzeo | 54:1697dc574b96 | 160 | |
baxterja | 74:ebc9f09fda11 | 161 | while( (ADC1_SC1[0]&ADC_SC1_COCO_MASK)) {} |
baxterja | 74:ebc9f09fda11 | 162 | debug.printf("ADC1_R[0]:%i\r\n", ADC1_R[0]); |
bmazzeo | 54:1697dc574b96 | 163 | */ |
bmazzeo | 55:2526b3317bc8 | 164 | |
bmazzeo | 55:2526b3317bc8 | 165 | // Now set up for use in the rest of the program - HARDWARE trigger |
baxterja | 74:ebc9f09fda11 | 166 | ADC0->SC2 = 0x44; // ADACT = 0, ADTRG = 1 (HW trigger), ACFE = 0, ACFGT = 0, ACREN = 0, DMAEN = 1, REFSEL = 00 (DMAEN needs to be asserted) |
baxterja | 74:ebc9f09fda11 | 167 | ADC1->SC2 = 0x44; // ADACT = 0, ADTRG = 1 (HW trigger), ACFE = 0, ACFGT = 0, ACREN = 0, DMAEN = 1, REFSEL = 00 (DMAEN needs to be asserted) |
bmazzeo | 55:2526b3317bc8 | 168 | |
bmazzeo | 54:1697dc574b96 | 169 | |
bmazzeo | 54:1697dc574b96 | 170 | // adebug.printf("Calbiration complete. Hardware continuous conversion running.\r\n"); |
bmazzeo | 53:83a90a47c1fd | 171 | // The ADCs are now just continuously converting and generating DMA signals after each conversion |
timmey9 | 51:43143a3fc2d7 | 172 | } |
timmey9 | 51:43143a3fc2d7 | 173 |