Dependencies:   mbed-dsp mbed

Fork of DSP_200kHz by Mazzeo Research Group

Committer:
timmey9
Date:
Sat Jan 31 20:56:04 2015 +0000
Revision:
52:5a40cc58c4c2
Parent:
adc.cpp@51:43143a3fc2d7
Made minor cosmetic and comment changes.

Who changed what in which revision?

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