Jared's DAC Code

Dependencies:   mbed

Dependents:   DCS_FINAL_CODE

Fork of Chemical_Sensor_DMA by Jared Baxter

Committer:
DeWayneDennis
Date:
Sat Dec 19 21:47:52 2015 +0000
Revision:
7:af255a90505e
Parent:
4:9fd291254686
Final Code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
baxterja 2:3771b3195c7b 1 #include "adc.h"
baxterja 2:3771b3195c7b 2
baxterja 2:3771b3195c7b 3 /*
baxterja 2:3771b3195c7b 4 TODO: calibration is done, i think
baxterja 2:3771b3195c7b 5 change clock speed and hw averaging
baxterja 2:3771b3195c7b 6 */
baxterja 2:3771b3195c7b 7
baxterja 2:3771b3195c7b 8 DigitalOut green(LED_GREEN);
baxterja 2:3771b3195c7b 9 DigitalOut red(LED_RED);
baxterja 2:3771b3195c7b 10
baxterja 2:3771b3195c7b 11
baxterja 2:3771b3195c7b 12
baxterja 2:3771b3195c7b 13 /* The ADCs are setup so that ADC0 and ADC1 are triggered by the PDB.
baxterja 2:3771b3195c7b 14 * When the conversions are complete, ADC0 and ADC1 then trigger DMA0
baxterja 2:3771b3195c7b 15 * and DMA1, respectively. ADC0 is using channel B and ADC1 is uing
baxterja 2:3771b3195c7b 16 * channel A. If they are on the same channel, then weird things
baxterja 2:3771b3195c7b 17 * happen. I think they interfere with each other so they have to be
baxterja 2:3771b3195c7b 18 * on separate channels if they're going to be triggered at the same
baxterja 2:3771b3195c7b 19 * time by the PDB. */
baxterja 2:3771b3195c7b 20 void adc_init()
baxterja 2:3771b3195c7b 21 {
baxterja 2:3771b3195c7b 22 // red, indicating not ready
baxterja 2:3771b3195c7b 23 red = 0;
baxterja 2:3771b3195c7b 24 green = 1;
baxterja 2:3771b3195c7b 25
baxterja 2:3771b3195c7b 26
baxterja 2:3771b3195c7b 27 // Turn on the ADC0 and ADC1 clocks
baxterja 2:3771b3195c7b 28 SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK;
baxterja 2:3771b3195c7b 29 SIM_SCGC3 |= SIM_SCGC3_ADC1_MASK;
baxterja 2:3771b3195c7b 30
baxterja 2:3771b3195c7b 31 // Set ADC hardware trigger to PDB0
baxterja 2:3771b3195c7b 32 SIM_SOPT7 = SIM_SOPT7_ADC0TRGSEL(0); // Select triggering by PDB and select pre-trigger A
baxterja 2:3771b3195c7b 33 SIM_SOPT7 = SIM_SOPT7_ADC1TRGSEL(0); // Select triggering by PDB and select pre-trigger A
baxterja 2:3771b3195c7b 34
baxterja 2:3771b3195c7b 35 // calibrate the ADC
DeWayneDennis 7:af255a90505e 36 //__disable_irq();
DeWayneDennis 7:af255a90505e 37 //if(adc_cal()) {red = 0; green = 0;} // if calibration fails, display yellow
DeWayneDennis 7:af255a90505e 38 //if(adc_cal1()) {red = 0; green = 0;} // if calibration fails, display yellow
DeWayneDennis 7:af255a90505e 39 //__enable_irq();
baxterja 2:3771b3195c7b 40
baxterja 2:3771b3195c7b 41
baxterja 2:3771b3195c7b 42 // Setup Configuration Register 1
baxterja 2:3771b3195c7b 43 ADC0_CFG1 = 0; // clear register
baxterja 2:3771b3195c7b 44 ADC0_CFG1 |= ADC_CFG1_ADICLK(0); // select bus clock
baxterja 2:3771b3195c7b 45 ADC0_CFG1 |= ADC_CFG1_MODE(3); // select 16-bit 2's complement output
baxterja 2:3771b3195c7b 46 ADC0_CFG1 |= ADC_CFG1_ADIV(0); // select short sample time
baxterja 2:3771b3195c7b 47 ADC0_CFG1 &= ~ADC_CFG1_ADLSMP_MASK; // select short sample time
baxterja 2:3771b3195c7b 48 ADC0_CFG1 &= ~ADC_CFG1_ADLPC_MASK; // select normal power configuration
baxterja 2:3771b3195c7b 49 ADC1_CFG1 = 0; // clear register
baxterja 2:3771b3195c7b 50 ADC1_CFG1 |= ADC_CFG1_ADICLK(0); // select bus clock
baxterja 2:3771b3195c7b 51 ADC1_CFG1 |= ADC_CFG1_MODE(3); // select 16-bit 2's complement output
baxterja 2:3771b3195c7b 52 ADC1_CFG1 |= ADC_CFG1_ADIV(0); // select short sample time
baxterja 2:3771b3195c7b 53 ADC1_CFG1 &= ~ADC_CFG1_ADLSMP_MASK; // select short sample time
baxterja 2:3771b3195c7b 54 ADC1_CFG1 &= ~ADC_CFG1_ADLPC_MASK; // select normal power configuration
baxterja 2:3771b3195c7b 55
baxterja 2:3771b3195c7b 56 // Setup Configuration Register 2
baxterja 2:3771b3195c7b 57 ADC0_CFG2 = 0; // clear register
baxterja 2:3771b3195c7b 58 //ADC0_CFG2 |= ADC_CFG2_ADHSC_MASK ; // select high-speed conversion
baxterja 2:3771b3195c7b 59 ADC0_CFG2 &= ~ADC_CFG2_MUXSEL_MASK; // select a channels
baxterja 2:3771b3195c7b 60 ADC1_CFG2 = 0; // clear register
baxterja 2:3771b3195c7b 61 //ADC1_CFG2 |= ADC_CFG2_ADHSC_MASK ; // select high-speed conversion
baxterja 2:3771b3195c7b 62 ADC1_CFG2 &= ~ADC_CFG2_MUXSEL_MASK; // select a channels
baxterja 2:3771b3195c7b 63
baxterja 2:3771b3195c7b 64 // Setup Status and Control Register 2
baxterja 2:3771b3195c7b 65 ADC0_SC2 = 0; // clear register
baxterja 2:3771b3195c7b 66 ADC0_SC2 |= ADC_SC2_REFSEL(0); // select external voltage reference
baxterja 2:3771b3195c7b 67 ADC0_SC2 |= ADC_SC2_DMAEN_MASK; // enable DMA
baxterja 2:3771b3195c7b 68 ADC0_SC2 |= ADC_SC2_ADTRG_MASK; // select hardware trigger
baxterja 2:3771b3195c7b 69 ADC1_SC2 = 0; // clear register
baxterja 2:3771b3195c7b 70 ADC1_SC2 |= ADC_SC2_REFSEL(0); // select external voltage reference
baxterja 2:3771b3195c7b 71 ADC1_SC2 |= ADC_SC2_DMAEN_MASK; // enable DMA
baxterja 2:3771b3195c7b 72 ADC1_SC2 |= ADC_SC2_ADTRG_MASK; // select hardware trigger
baxterja 2:3771b3195c7b 73
baxterja 2:3771b3195c7b 74 // Setup Status and Control Register 3 now that calibration is complete
baxterja 2:3771b3195c7b 75 ADC0_SC3 = 0; // Hardware Average set to 4 samples averaged
baxterja 2:3771b3195c7b 76 // Hardware Average Disabled
baxterja 2:3771b3195c7b 77 // select single conversion mode
baxterja 2:3771b3195c7b 78 ADC1_SC3 = 0; // Hardware Average set to 4 samples averaged
baxterja 2:3771b3195c7b 79 // Hardware Average Disabled
baxterja 2:3771b3195c7b 80 // select single conversion mode
DeWayneDennis 7:af255a90505e 81 // Setup Status and Control Register 3 now that calibration is complete
DeWayneDennis 7:af255a90505e 82 //ADC0_SC3 = ADC_SC3_AVGS(0) | ADC_SC3_AVGE_MASK; // Hardware Average set to 16 samples averaged
DeWayneDennis 7:af255a90505e 83 // select single conversion mode
DeWayneDennis 7:af255a90505e 84 //ADC1_SC3 = ADC_SC3_AVGS(0) | ADC_SC3_AVGE_MASK; // Hardware Average set to 16 samples averaged
baxterja 2:3771b3195c7b 85 // Setup Status and Control Register 1A
baxterja 2:3771b3195c7b 86 ADC0_SC1B = 0; // clear register
baxterja 2:3771b3195c7b 87 ADC0_SC1B &= ~ADC_SC1_DIFF_MASK; // select single-ended mode
baxterja 2:3771b3195c7b 88 ADC0_SC1B |= ADC_SC1_AIEN_MASK; // enable interrupt (for debugging)
DeWayneDennis 7:af255a90505e 89 ADC0_SC1B |= ADC_SC1_ADCH(12); // select channel 13
baxterja 2:3771b3195c7b 90 ADC1_SC1A = 0; // clear register
baxterja 2:3771b3195c7b 91 ADC1_SC1A &= ~ADC_SC1_DIFF_MASK; // select single-ended mode
baxterja 2:3771b3195c7b 92 ADC1_SC1A |= ADC_SC1_AIEN_MASK; // enable interrupt (for debugging)
baxterja 2:3771b3195c7b 93 ADC1_SC1A |= ADC_SC1_ADCH(14); // select channel 14
baxterja 2:3771b3195c7b 94
baxterja 2:3771b3195c7b 95
baxterja 2:3771b3195c7b 96 // Check if ADC is finished initializing TODO: This part doesn't seem right, but I did it according to 871
baxterja 2:3771b3195c7b 97 while( (ADC0_SC1B&ADC_SC1_COCO_MASK)) {}
baxterja 2:3771b3195c7b 98 int gain = ADC0_RA; // read the register to clear SC1A[COCO]
baxterja 2:3771b3195c7b 99 while( (ADC1_SC1A&ADC_SC1_COCO_MASK)) {}
baxterja 2:3771b3195c7b 100 gain = ADC1_RA; // read the register to clear SC1A[COCO]
baxterja 2:3771b3195c7b 101
baxterja 2:3771b3195c7b 102 red = 1;
baxterja 2:3771b3195c7b 103 green = 1;
baxterja 2:3771b3195c7b 104 }
baxterja 2:3771b3195c7b 105
baxterja 2:3771b3195c7b 106
baxterja 2:3771b3195c7b 107 /* adc_cal
baxterja 2:3771b3195c7b 108 * Calibrates the adc
baxterja 2:3771b3195c7b 109 * Returns 0 if successful calibration
baxterja 2:3771b3195c7b 110 * Returns 1 otherwise
baxterja 2:3771b3195c7b 111 * */
baxterja 2:3771b3195c7b 112 int adc_cal(void)
baxterja 2:3771b3195c7b 113 {
baxterja 2:3771b3195c7b 114 ADC0_CFG1 |= (ADC_CFG1_MODE(3) | // 16 bits mode
baxterja 2:3771b3195c7b 115 ADC_CFG1_ADICLK(1)| // Input Bus Clock divided by 2 (20-25 MHz out of reset (FEI mode) / 2)
baxterja 2:3771b3195c7b 116 ADC_CFG1_ADIV(2)) ; // Clock divide by 4 (2.5-3 MHz)
baxterja 2:3771b3195c7b 117
baxterja 2:3771b3195c7b 118 ADC0_SC3 |= ADC_SC3_AVGE_MASK | // Enable HW average
baxterja 2:3771b3195c7b 119 ADC_SC3_AVGS(3) | // Set HW average of 32 samples
baxterja 2:3771b3195c7b 120 ADC_SC3_CAL_MASK; // Start calibration process
baxterja 2:3771b3195c7b 121
baxterja 2:3771b3195c7b 122 while(ADC0_SC3 & ADC_SC3_CAL_MASK); // Wait for calibration to end
baxterja 2:3771b3195c7b 123
baxterja 2:3771b3195c7b 124 if(ADC0_SC3 & ADC_SC3_CALF_MASK) return 1; // Check for successful calibration
baxterja 2:3771b3195c7b 125
baxterja 2:3771b3195c7b 126 uint16_t calib = 0; // calibration variable
baxterja 2:3771b3195c7b 127 calib += ADC0->CLPS + ADC0_CLP4 + ADC0_CLP3 + ADC0_CLP2 + ADC0_CLP1 + ADC0_CLP0;
baxterja 2:3771b3195c7b 128 calib /= 2;
baxterja 2:3771b3195c7b 129 calib |= 0x8000; // Set MSB
baxterja 2:3771b3195c7b 130 ADC0_PG = calib;
baxterja 2:3771b3195c7b 131 calib = 0;
baxterja 2:3771b3195c7b 132 calib += ADC0_CLMS + ADC0_CLM4 + ADC0_CLM3 + ADC0_CLM2 + ADC0_CLM1 + ADC0_CLM0;
baxterja 2:3771b3195c7b 133 calib /= 2;
baxterja 2:3771b3195c7b 134 calib |= 0x8000; // Set MSB
baxterja 2:3771b3195c7b 135 ADC0_MG = calib;
baxterja 2:3771b3195c7b 136
baxterja 2:3771b3195c7b 137 return 0;
baxterja 2:3771b3195c7b 138 }
baxterja 2:3771b3195c7b 139
DeWayneDennis 7:af255a90505e 140 int adc_cal1(void)
DeWayneDennis 7:af255a90505e 141 {
DeWayneDennis 7:af255a90505e 142 ADC1_CFG1 |= (ADC_CFG1_MODE(3) | // 16 bits mode
DeWayneDennis 7:af255a90505e 143 ADC_CFG1_ADICLK(1)| // Input Bus Clock divided by 2 (20-25 MHz out of reset (FEI mode) / 2)
DeWayneDennis 7:af255a90505e 144 ADC_CFG1_ADIV(2)) ; // Clock divide by 4 (2.5-3 MHz)
DeWayneDennis 7:af255a90505e 145
DeWayneDennis 7:af255a90505e 146 ADC1_SC3 |= ADC_SC3_AVGE_MASK | // Enable HW average
DeWayneDennis 7:af255a90505e 147 ADC_SC3_AVGS(3) | // Set HW average of 32 samples
DeWayneDennis 7:af255a90505e 148 ADC_SC3_CAL_MASK; // Start calibration process
DeWayneDennis 7:af255a90505e 149
DeWayneDennis 7:af255a90505e 150 while(ADC1_SC3 & ADC_SC3_CAL_MASK); // Wait for calibration to end
DeWayneDennis 7:af255a90505e 151
DeWayneDennis 7:af255a90505e 152 if(ADC1_SC3 & ADC_SC3_CALF_MASK) return 1; // Check for successful calibration
DeWayneDennis 7:af255a90505e 153
DeWayneDennis 7:af255a90505e 154 uint16_t calib = 0; // calibration variable
DeWayneDennis 7:af255a90505e 155 calib += ADC1->CLPS + ADC1_CLP4 + ADC1_CLP3 + ADC1_CLP2 + ADC1_CLP1 + ADC1_CLP0;
DeWayneDennis 7:af255a90505e 156 calib /= 2;
DeWayneDennis 7:af255a90505e 157 calib |= 0x8000; // Set MSB
DeWayneDennis 7:af255a90505e 158 ADC1_PG = calib;
DeWayneDennis 7:af255a90505e 159 calib = 0;
DeWayneDennis 7:af255a90505e 160 calib += ADC1_CLMS + ADC1_CLM4 + ADC1_CLM3 + ADC1_CLM2 + ADC1_CLM1 + ADC1_CLM0;
DeWayneDennis 7:af255a90505e 161 calib /= 2;
DeWayneDennis 7:af255a90505e 162 calib |= 0x8000; // Set MSB
DeWayneDennis 7:af255a90505e 163 ADC1_MG = calib;
DeWayneDennis 7:af255a90505e 164
DeWayneDennis 7:af255a90505e 165 return 0;
DeWayneDennis 7:af255a90505e 166 }
baxterja 2:3771b3195c7b 167
baxterja 2:3771b3195c7b 168
baxterja 2:3771b3195c7b 169
baxterja 2:3771b3195c7b 170
baxterja 2:3771b3195c7b 171
baxterja 2:3771b3195c7b 172
baxterja 2:3771b3195c7b 173
baxterja 2:3771b3195c7b 174
baxterja 2:3771b3195c7b 175
baxterja 2:3771b3195c7b 176
baxterja 2:3771b3195c7b 177
baxterja 2:3771b3195c7b 178 /* * * * * * * * * * * * * * For Debugging Purposes * * * * * * * * * * * * * * * * * * * * */
baxterja 2:3771b3195c7b 179
baxterja 2:3771b3195c7b 180
baxterja 2:3771b3195c7b 181 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
baxterja 2:3771b3195c7b 182 * DEBUG: This is supposed to put the ADC in continuous *
baxterja 2:3771b3195c7b 183 * mode so it samples without the PCB. But for *
baxterja 2:3771b3195c7b 184 * some reason it isn't working. I haven't deleted *
baxterja 2:3771b3195c7b 185 * it just in case it is needed for debug purposes *
baxterja 2:3771b3195c7b 186 * in the future. *
baxterja 2:3771b3195c7b 187 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
baxterja 2:3771b3195c7b 188 void adc_start() {
baxterja 2:3771b3195c7b 189 // reset DMA
baxterja 2:3771b3195c7b 190 dma_reset();
baxterja 2:3771b3195c7b 191
baxterja 2:3771b3195c7b 192 // set ADC to continuous mode
baxterja 2:3771b3195c7b 193 ADC0_SC3 |= ADC_SC3_ADCO_MASK;
baxterja 2:3771b3195c7b 194 ADC1_SC3 |= ADC_SC3_ADCO_MASK;
baxterja 2:3771b3195c7b 195
baxterja 2:3771b3195c7b 196 // set ADC to software trigger
baxterja 2:3771b3195c7b 197 ADC0_SC2 &= ~ADC_SC2_ADTRG_MASK;
baxterja 2:3771b3195c7b 198 ADC1_SC2 &= ~ADC_SC2_ADTRG_MASK;
baxterja 2:3771b3195c7b 199
baxterja 2:3771b3195c7b 200 // start ADC conversion (SW trigger)
baxterja 2:3771b3195c7b 201 ADC0_SC1B |= ADC_SC1_ADCH(13); // write to SC1A causing a trigger
baxterja 2:3771b3195c7b 202 ADC1_SC1A |= ADC_SC1_ADCH(14); // write to SC1A causing a trigger
baxterja 2:3771b3195c7b 203 }
baxterja 2:3771b3195c7b 204
baxterja 2:3771b3195c7b 205 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
baxterja 2:3771b3195c7b 206 * DEBUG: This is supposed to revert back from adc_start() *
baxterja 2:3771b3195c7b 207 * but because adc_start() isn't working, this *
baxterja 2:3771b3195c7b 208 * function is good for nothing. I held on to *
baxterja 2:3771b3195c7b 209 * it just in case it is needed for debug purposes *
baxterja 2:3771b3195c7b 210 * in the future. *
baxterja 2:3771b3195c7b 211 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
baxterja 2:3771b3195c7b 212 void adc_stop() {
baxterja 2:3771b3195c7b 213 // set ADC to hardware trigger
baxterja 2:3771b3195c7b 214 ADC0_SC2 |= ADC_SC2_ADTRG_MASK;
baxterja 2:3771b3195c7b 215 ADC1_SC2 |= ADC_SC2_ADTRG_MASK;
baxterja 2:3771b3195c7b 216
baxterja 2:3771b3195c7b 217 // set to single conversion mode effectively stopping the ADC unless a timer triggers the ADC
baxterja 2:3771b3195c7b 218 ADC0_SC3 &= ~ADC_SC3_ADCO_MASK;
baxterja 2:3771b3195c7b 219 ADC1_SC3 &= ~ADC_SC3_ADCO_MASK;
baxterja 2:3771b3195c7b 220 }
baxterja 2:3771b3195c7b 221
baxterja 2:3771b3195c7b 222 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
baxterja 2:3771b3195c7b 223 * DEBUG: This is supposed to trigger a software conversion *
baxterja 2:3771b3195c7b 224 * and take a single sample. However, it only *
baxterja 2:3771b3195c7b 225 * worked for ADC1 for some reason. It is here for *
baxterja 2:3771b3195c7b 226 * possible debug purposes in the future. *
baxterja 2:3771b3195c7b 227 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
baxterja 2:3771b3195c7b 228 void adc_single_sample() {
baxterja 2:3771b3195c7b 229 ADC0_SC3 &= ~ADC_SC3_ADCO_MASK; // single conversion mode
baxterja 2:3771b3195c7b 230 ADC1_SC3 &= ~ADC_SC3_ADCO_MASK; // single conversion mode
baxterja 2:3771b3195c7b 231 ADC0_SC2 &= ~ADC_SC2_ADTRG_MASK; // set ADC to software trigger
baxterja 2:3771b3195c7b 232 ADC1_SC2 &= ~ADC_SC2_ADTRG_MASK; // set ADC to software trigger
baxterja 2:3771b3195c7b 233 ADC0_SC1B |= ADC_SC1_ADCH(13); // write to SC1B causing a trigger
baxterja 2:3771b3195c7b 234 ADC1_SC1A |= ADC_SC1_ADCH(14); // write to SC1A causing a trigger
baxterja 2:3771b3195c7b 235
baxterja 2:3771b3195c7b 236 // Set back to hardware trigger
baxterja 2:3771b3195c7b 237 ADC0_SC2 |= ADC_SC2_ADTRG_MASK; // set ADC to software trigger
baxterja 2:3771b3195c7b 238 ADC1_SC2 |= ADC_SC2_ADTRG_MASK; // set ADC to software trigger
baxterja 2:3771b3195c7b 239 }
baxterja 2:3771b3195c7b 240
baxterja 2:3771b3195c7b 241
baxterja 2:3771b3195c7b 242 void adc_print_registers() {
baxterja 2:3771b3195c7b 243 Serial debug(USBTX,USBRX);
baxterja 2:3771b3195c7b 244 debug.printf("ADC0_SC1a: %08x\r\n",ADC0_SC1A); //(0x0000004d)
baxterja 2:3771b3195c7b 245 debug.printf("ADC0_SC1b: %08x\r\n",ADC0_SC1B); //(0x0000001f)
baxterja 2:3771b3195c7b 246 debug.printf("ADC0_CFG1: %08x\r\n",ADC0_CFG1); //(0x0000000c)
baxterja 2:3771b3195c7b 247 debug.printf("ADC0_CFG2: %08x\r\n",ADC0_CFG2); //(0x00000004)
baxterja 2:3771b3195c7b 248 debug.printf("ADC0_RA: %08x\r\n",ADC0_RA); //(0x00000000)
baxterja 2:3771b3195c7b 249 debug.printf("ADC0_RB: %08x\r\n",ADC0_RB); //(0x00000000)
baxterja 2:3771b3195c7b 250 debug.printf("ADC0_SC2: %08x\r\n",ADC0_SC2); //(0x00000044)
baxterja 2:3771b3195c7b 251 debug.printf("ADC0_SC3: %08x\r\n\n",ADC0_SC3); //(0x00000000)
DeWayneDennis 7:af255a90505e 252 }