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@45:d591d138cdeb, 2015-01-31 (annotated)
- Committer:
- timmey9
- Date:
- Sat Jan 31 07:25:52 2015 +0000
- Revision:
- 45:d591d138cdeb
- Parent:
- 44:41c262caf898
- Child:
- 46:a015ebf4663b
Quadrature decoder is working.
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 | /* |
timmey9 | 44:41c262caf898 | 4 | TODO: remove interrupt handlers |
timmey9 | 44:41c262caf898 | 5 | add calibration |
timmey9 | 45:d591d138cdeb | 6 | change clock speed |
timmey9 | 44:41c262caf898 | 7 | |
timmey9 | 45:d591d138cdeb | 8 | Possible causes of the triggering problem: |
timmey9 | 45:d591d138cdeb | 9 | more multiplexing somehow? |
timmey9 | 45:d591d138cdeb | 10 | does the ADC interrupt need to be enabled? |
timmey9 | 45:d591d138cdeb | 11 | clock speed? |
timmey9 | 45:d591d138cdeb | 12 | hardware/software trigger |
timmey9 | 45:d591d138cdeb | 13 | channel A or B? |
timmey9 | 45:d591d138cdeb | 14 | single vs continuous mode |
timmey9 | 45:d591d138cdeb | 15 | does asynchronous clock have to do with this? |
timmey9 | 44:41c262caf898 | 16 | */ |
timmey9 | 45:d591d138cdeb | 17 | DigitalOut toggle1(PTC16); |
timmey9 | 45:d591d138cdeb | 18 | DigitalOut green(LED_GREEN); |
timmey9 | 45:d591d138cdeb | 19 | DigitalOut red(LED_RED); |
timmey9 | 45:d591d138cdeb | 20 | Serial debug(USBTX,USBRX); |
timmey9 | 39:82dc3daecf32 | 21 | |
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 | 45:d591d138cdeb | 33 | SIM_SOPT7 = SIM_SOPT7_ADC0TRGSEL(0); |
timmey9 | 39:82dc3daecf32 | 34 | |
timmey9 | 45:d591d138cdeb | 35 | // Setup Configuration Register 1 |
timmey9 | 45:d591d138cdeb | 36 | ADC0_CFG1 = 0; // clear register |
timmey9 | 45:d591d138cdeb | 37 | ADC0_CFG1 |= ADC_CFG1_ADICLK(0); // select bus clock |
timmey9 | 45:d591d138cdeb | 38 | ADC0_CFG1 |= ADC_CFG1_MODE(3); // select 16-bit 2's complement output |
timmey9 | 45:d591d138cdeb | 39 | ADC0_CFG1 |= ADC_CFG1_ADIV(0); // select short sample time |
timmey9 | 45:d591d138cdeb | 40 | ADC0_CFG1 &= ~ADC_CFG1_ADLSMP_MASK; // select short sample time |
timmey9 | 45:d591d138cdeb | 41 | ADC0_CFG1 &= ~ADC_CFG1_ADLPC_MASK; // select normal power configuration |
timmey9 | 45:d591d138cdeb | 42 | |
timmey9 | 45:d591d138cdeb | 43 | // Setup Configuration Register 2 |
timmey9 | 45:d591d138cdeb | 44 | ADC0_CFG2 = 0; // clear register |
timmey9 | 45:d591d138cdeb | 45 | ADC0_CFG2 |= ADC_CFG2_ADHSC_MASK ; // select high-speed conversion |
timmey9 | 45:d591d138cdeb | 46 | ADC0_CFG2 &= ~ADC_CFG2_MUXSEL_MASK; // select a channels |
timmey9 | 39:82dc3daecf32 | 47 | |
timmey9 | 45:d591d138cdeb | 48 | // Setup Status and Control Register 2 |
timmey9 | 45:d591d138cdeb | 49 | ADC0_SC2 = 0; // clear register |
timmey9 | 45:d591d138cdeb | 50 | ADC0_SC2 |= ADC_SC2_REFSEL(0); // select external voltage reference |
timmey9 | 45:d591d138cdeb | 51 | ADC0_SC2 |= ADC_SC2_DMAEN_MASK; // enable DMA |
timmey9 | 45:d591d138cdeb | 52 | ADC0_SC2 &= ~ADC_SC2_ADTRG_MASK; // select software trigger until calibration is complete |
timmey9 | 45:d591d138cdeb | 53 | |
timmey9 | 45:d591d138cdeb | 54 | // Setup Status and Control Register 3 |
timmey9 | 45:d591d138cdeb | 55 | ADC0_SC3 = 0; // Hardware Average set to 4 samples averaged |
timmey9 | 45:d591d138cdeb | 56 | // Hardware Average Disabled |
timmey9 | 45:d591d138cdeb | 57 | // select single conversion mode |
timmey9 | 39:82dc3daecf32 | 58 | |
timmey9 | 45:d591d138cdeb | 59 | // calibrate the ADC |
timmey9 | 45:d591d138cdeb | 60 | ADC0_SC3 |= ADC_SC3_CAL_MASK; // start calibration |
timmey9 | 45:d591d138cdeb | 61 | while(ADC0_SC3&ADC_SC3_CALF_MASK) {} // wait for calibration to complete |
timmey9 | 45:d591d138cdeb | 62 | |
timmey9 | 45:d591d138cdeb | 63 | // calculate the gains (see user manual page 864) |
timmey9 | 45:d591d138cdeb | 64 | int16_t gain = (ADC0_CLP0+ADC0_CLP1+ADC0_CLP2+ADC0_CLP3+ADC0_CLP4+ADC0_CLPS); |
timmey9 | 45:d591d138cdeb | 65 | gain = (gain>>1); // divide by 2 |
timmey9 | 45:d591d138cdeb | 66 | gain |= 0x8000; // set the MSB |
timmey9 | 45:d591d138cdeb | 67 | ADC0_PG = gain; |
timmey9 | 45:d591d138cdeb | 68 | |
timmey9 | 45:d591d138cdeb | 69 | gain = (ADC0_CLM0+ADC0_CLM1+ADC0_CLM2+ADC0_CLM3+ADC0_CLM4+ADC0_CLMS); |
timmey9 | 45:d591d138cdeb | 70 | gain = (gain>>1); // divide by 2 |
timmey9 | 45:d591d138cdeb | 71 | gain |= 0x8000; // set the MSB |
timmey9 | 45:d591d138cdeb | 72 | ADC0_MG = gain; |
timmey9 | 39:82dc3daecf32 | 73 | |
timmey9 | 45:d591d138cdeb | 74 | ADC0_SC3 &= ~ADC_SC3_CAL_MASK; // stop calibration |
timmey9 | 45:d591d138cdeb | 75 | |
timmey9 | 45:d591d138cdeb | 76 | |
timmey9 | 45:d591d138cdeb | 77 | |
timmey9 | 45:d591d138cdeb | 78 | |
timmey9 | 45:d591d138cdeb | 79 | |
timmey9 | 45:d591d138cdeb | 80 | |
timmey9 | 45:d591d138cdeb | 81 | |
timmey9 | 45:d591d138cdeb | 82 | // yellow indicating calibration complete |
timmey9 | 45:d591d138cdeb | 83 | red = 0; |
timmey9 | 45:d591d138cdeb | 84 | green = 0; |
timmey9 | 45:d591d138cdeb | 85 | |
timmey9 | 45:d591d138cdeb | 86 | ADC0_SC2 |= ADC_SC2_ADTRG_MASK; // select hardware trigger now that calibration is complete |
timmey9 | 45:d591d138cdeb | 87 | |
timmey9 | 45:d591d138cdeb | 88 | // Setup Status and Control Register 1A |
timmey9 | 45:d591d138cdeb | 89 | ADC0_SC1A = 0; // clear register |
timmey9 | 45:d591d138cdeb | 90 | ADC0_SC1A &= ~ADC_SC1_DIFF_MASK; // select single-ended mode |
timmey9 | 45:d591d138cdeb | 91 | ADC0_SC1A |= ADC_SC1_AIEN_MASK; // enable interrupt (for debugging) |
timmey9 | 45:d591d138cdeb | 92 | ADC0_SC1A |= ADC_SC1_ADCH(13); // select channel 13 |
timmey9 | 45:d591d138cdeb | 93 | |
timmey9 | 45:d591d138cdeb | 94 | // Check if ADC is finished initializing TODO: This part doesn't seem right, but I did it according to 871 |
timmey9 | 45:d591d138cdeb | 95 | while( (ADC0_SC1A&ADC_SC1_COCO_MASK)) {} |
timmey9 | 45:d591d138cdeb | 96 | gain = ADC0_RA; // read the register to clear SC1A[COCO] |
timmey9 | 45:d591d138cdeb | 97 | |
timmey9 | 45:d591d138cdeb | 98 | |
timmey9 | 45:d591d138cdeb | 99 | |
timmey9 | 45:d591d138cdeb | 100 | |
timmey9 | 45:d591d138cdeb | 101 | |
timmey9 | 45:d591d138cdeb | 102 | |
timmey9 | 45:d591d138cdeb | 103 | // green indicating calibration and initialization complete |
timmey9 | 45:d591d138cdeb | 104 | red = 1; |
timmey9 | 45:d591d138cdeb | 105 | green = 0; |
timmey9 | 45:d591d138cdeb | 106 | |
timmey9 | 45:d591d138cdeb | 107 | |
timmey9 | 45:d591d138cdeb | 108 | debug.printf("ADC0_SC1a: %08x\r\n",ADC0_SC1A); //(0x0000004d) |
timmey9 | 45:d591d138cdeb | 109 | debug.printf("ADC0_SC1b: %08x\r\n",ADC0_SC1B); //(0x0000001f) |
timmey9 | 45:d591d138cdeb | 110 | debug.printf("ADC0_CFG1: %08x\r\n",ADC0_CFG1); //(0x0000000c) |
timmey9 | 45:d591d138cdeb | 111 | debug.printf("ADC0_CFG2: %08x\r\n",ADC0_CFG2); //(0x00000004) |
timmey9 | 45:d591d138cdeb | 112 | debug.printf("ADC0_RA: %08x\r\n",ADC0_RA); //(0x00000000) |
timmey9 | 45:d591d138cdeb | 113 | debug.printf("ADC0_RB: %08x\r\n",ADC0_RB); //(0x00000000) |
timmey9 | 45:d591d138cdeb | 114 | debug.printf("ADC0_SC2: %08x\r\n",ADC0_SC2); //(0x00000044) |
timmey9 | 45:d591d138cdeb | 115 | debug.printf("ADC0_SC3: %08x\r\n\n",ADC0_SC3); //(0x00000000) |
timmey9 | 45:d591d138cdeb | 116 | |
timmey9 | 40:bd6d8c35e822 | 117 | // Enable the ISR vector |
timmey9 | 41:3e0623d81b9a | 118 | NVIC_SetVector(ADC0_IRQn, (uint32_t)&ADC0_IRQHandler); |
timmey9 | 40:bd6d8c35e822 | 119 | NVIC_EnableIRQ(ADC0_IRQn); |
timmey9 | 40:bd6d8c35e822 | 120 | } |
timmey9 | 40:bd6d8c35e822 | 121 | |
timmey9 | 41:3e0623d81b9a | 122 | void adc_start() { |
timmey9 | 40:bd6d8c35e822 | 123 | // reset DMA |
timmey9 | 45:d591d138cdeb | 124 | dma_reset(); |
timmey9 | 40:bd6d8c35e822 | 125 | |
timmey9 | 40:bd6d8c35e822 | 126 | // set ADC to continuous mode |
timmey9 | 40:bd6d8c35e822 | 127 | ADC0_SC3 |= ADC_SC3_ADCO_MASK; |
timmey9 | 45:d591d138cdeb | 128 | |
timmey9 | 45:d591d138cdeb | 129 | // set ADC to software trigger |
timmey9 | 45:d591d138cdeb | 130 | ADC0_SC2 &= ~ADC_SC2_ADTRG_MASK; |
timmey9 | 40:bd6d8c35e822 | 131 | |
timmey9 | 40:bd6d8c35e822 | 132 | // start ADC conversion (SW trigger) |
timmey9 | 45:d591d138cdeb | 133 | //ADC0_SC1A |= ADC_SC1_ADCH(13); // write to SC1A causing a trigger |
timmey9 | 45:d591d138cdeb | 134 | //BW_ADC_SC1n_ADCH(0, 0, kAdcChannel13); // trigger the ADC |
timmey9 | 40:bd6d8c35e822 | 135 | } |
timmey9 | 40:bd6d8c35e822 | 136 | |
timmey9 | 41:3e0623d81b9a | 137 | void adc_stop() { |
timmey9 | 45:d591d138cdeb | 138 | // set ADC to hardware trigger |
timmey9 | 45:d591d138cdeb | 139 | ADC0_SC2 |= ADC_SC2_ADTRG_MASK; |
timmey9 | 45:d591d138cdeb | 140 | |
timmey9 | 45:d591d138cdeb | 141 | // set to single conversion mode effectively stopping the ADC unless a timer triggers the ADC |
timmey9 | 45:d591d138cdeb | 142 | ADC0_SC3 &= ~ADC_SC3_ADCO_MASK; |
timmey9 | 45:d591d138cdeb | 143 | } |
timmey9 | 45:d591d138cdeb | 144 | |
timmey9 | 45:d591d138cdeb | 145 | void adc_single_sample() { |
timmey9 | 45:d591d138cdeb | 146 | ADC0_SC3 &= ~ADC_SC3_ADCO_MASK; // single conversion mode |
timmey9 | 45:d591d138cdeb | 147 | ADC0_SC2 &= ~ADC_SC2_ADTRG_MASK; // set ADC to software trigger |
timmey9 | 45:d591d138cdeb | 148 | ADC0_SC1A |= ADC_SC1_ADCH(13); // write to SC1A causing a trigger |
timmey9 | 40:bd6d8c35e822 | 149 | } |
timmey9 | 40:bd6d8c35e822 | 150 | |
timmey9 | 40:bd6d8c35e822 | 151 | void ADC0_IRQHandler() { |
timmey9 | 45:d591d138cdeb | 152 | toggle1 = !toggle1; |
timmey9 | 39:82dc3daecf32 | 153 | } |