School project for big bang base code

Dependencies:   mbed

Fork of GT_Tuner3 by Mike Pollock

Committer:
mptapton
Date:
Tue Jan 03 13:46:19 2017 +0000
Revision:
0:6b0b61d411ad
Adaptation to original GT_Tuner code (by Andrew Durand), as part of a school project for Tapton school

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mptapton 0:6b0b61d411ad 1 /* mbed Library - ADC
mptapton 0:6b0b61d411ad 2 * Copyright (c) 2010, sblandford
mptapton 0:6b0b61d411ad 3 * released under MIT license http://mbed.org/licence/mit
mptapton 0:6b0b61d411ad 4 */
mptapton 0:6b0b61d411ad 5 #include "mbed.h"
mptapton 0:6b0b61d411ad 6 #include "adc.h"
mptapton 0:6b0b61d411ad 7
mptapton 0:6b0b61d411ad 8
mptapton 0:6b0b61d411ad 9 ADC *ADC::instance;
mptapton 0:6b0b61d411ad 10
mptapton 0:6b0b61d411ad 11 ADC::ADC(int sample_rate, int cclk_div)
mptapton 0:6b0b61d411ad 12 {
mptapton 0:6b0b61d411ad 13
mptapton 0:6b0b61d411ad 14 int i, adc_clk_freq, pclk, clock_div, max_div=1;
mptapton 0:6b0b61d411ad 15
mptapton 0:6b0b61d411ad 16 //Work out CCLK
mptapton 0:6b0b61d411ad 17 adc_clk_freq=CLKS_PER_SAMPLE*sample_rate;
mptapton 0:6b0b61d411ad 18 int m = (LPC_SC->PLL0CFG & 0xFFFF) + 1;
mptapton 0:6b0b61d411ad 19 int n = (LPC_SC->PLL0CFG >> 16) + 1;
mptapton 0:6b0b61d411ad 20 int cclkdiv = LPC_SC->CCLKCFG + 1;
mptapton 0:6b0b61d411ad 21 int Fcco = (2 * m * XTAL_FREQ) / n;
mptapton 0:6b0b61d411ad 22 int cclk = Fcco / cclkdiv;
mptapton 0:6b0b61d411ad 23
mptapton 0:6b0b61d411ad 24 //Power up the ADC
mptapton 0:6b0b61d411ad 25 LPC_SC->PCONP |= (1 << 12);
mptapton 0:6b0b61d411ad 26 //Set clock at cclk / 1.
mptapton 0:6b0b61d411ad 27 LPC_SC->PCLKSEL0 &= ~(0x3 << 24);
mptapton 0:6b0b61d411ad 28 switch (cclk_div) {
mptapton 0:6b0b61d411ad 29 case 1:
mptapton 0:6b0b61d411ad 30 LPC_SC->PCLKSEL0 |= 0x1 << 24;
mptapton 0:6b0b61d411ad 31 break;
mptapton 0:6b0b61d411ad 32 case 2:
mptapton 0:6b0b61d411ad 33 LPC_SC->PCLKSEL0 |= 0x2 << 24;
mptapton 0:6b0b61d411ad 34 break;
mptapton 0:6b0b61d411ad 35 case 4:
mptapton 0:6b0b61d411ad 36 LPC_SC->PCLKSEL0 |= 0x0 << 24;
mptapton 0:6b0b61d411ad 37 break;
mptapton 0:6b0b61d411ad 38 case 8:
mptapton 0:6b0b61d411ad 39 LPC_SC->PCLKSEL0 |= 0x3 << 24;
mptapton 0:6b0b61d411ad 40 break;
mptapton 0:6b0b61d411ad 41 default:
mptapton 0:6b0b61d411ad 42 fprintf(stderr, "Warning: ADC CCLK clock divider must be 1, 2, 4 or 8. %u supplied.\n",
mptapton 0:6b0b61d411ad 43 cclk_div);
mptapton 0:6b0b61d411ad 44 fprintf(stderr, "Defaulting to 1.\n");
mptapton 0:6b0b61d411ad 45 LPC_SC->PCLKSEL0 |= 0x1 << 24;
mptapton 0:6b0b61d411ad 46 break;
mptapton 0:6b0b61d411ad 47 }
mptapton 0:6b0b61d411ad 48 pclk = cclk / cclk_div;
mptapton 0:6b0b61d411ad 49 clock_div=pclk / adc_clk_freq;
mptapton 0:6b0b61d411ad 50
mptapton 0:6b0b61d411ad 51 if (clock_div > 0xFF) {
mptapton 0:6b0b61d411ad 52 fprintf(stderr, "Warning: Clock division is %u which is above 255 limit. Re-Setting at limit.\n",
mptapton 0:6b0b61d411ad 53 clock_div);
mptapton 0:6b0b61d411ad 54 clock_div=0xFF;
mptapton 0:6b0b61d411ad 55 }
mptapton 0:6b0b61d411ad 56 if (clock_div == 0) {
mptapton 0:6b0b61d411ad 57 fprintf(stderr, "Warning: Clock division is 0. Re-Setting to 1.\n");
mptapton 0:6b0b61d411ad 58 clock_div=1;
mptapton 0:6b0b61d411ad 59 }
mptapton 0:6b0b61d411ad 60
mptapton 0:6b0b61d411ad 61 _adc_clk_freq=pclk / clock_div;
mptapton 0:6b0b61d411ad 62 if (_adc_clk_freq > MAX_ADC_CLOCK) {
mptapton 0:6b0b61d411ad 63 fprintf(stderr, "Warning: Actual ADC sample rate of %u which is above %u limit\n",
mptapton 0:6b0b61d411ad 64 _adc_clk_freq / CLKS_PER_SAMPLE, MAX_ADC_CLOCK / CLKS_PER_SAMPLE);
mptapton 0:6b0b61d411ad 65 while ((pclk / max_div) > MAX_ADC_CLOCK) max_div++;
mptapton 0:6b0b61d411ad 66 fprintf(stderr, "Maximum recommended sample rate is %u\n", (pclk / max_div) / CLKS_PER_SAMPLE);
mptapton 0:6b0b61d411ad 67 }
mptapton 0:6b0b61d411ad 68
mptapton 0:6b0b61d411ad 69 LPC_ADC->ADCR =
mptapton 0:6b0b61d411ad 70 ((clock_div - 1 ) << 8 ) | //Clkdiv
mptapton 0:6b0b61d411ad 71 ( 1 << 21 ); //A/D operational
mptapton 0:6b0b61d411ad 72
mptapton 0:6b0b61d411ad 73 //Default no channels enabled
mptapton 0:6b0b61d411ad 74 LPC_ADC->ADCR &= ~0xFF;
mptapton 0:6b0b61d411ad 75 //Default NULL global custom isr
mptapton 0:6b0b61d411ad 76 _adc_g_isr = NULL;
mptapton 0:6b0b61d411ad 77 //Initialize arrays
mptapton 0:6b0b61d411ad 78 for (i=7; i>=0; i--) {
mptapton 0:6b0b61d411ad 79 _adc_data[i] = 0;
mptapton 0:6b0b61d411ad 80 _adc_isr[i] = NULL;
mptapton 0:6b0b61d411ad 81 }
mptapton 0:6b0b61d411ad 82
mptapton 0:6b0b61d411ad 83
mptapton 0:6b0b61d411ad 84 //* Attach IRQ
mptapton 0:6b0b61d411ad 85 instance = this;
mptapton 0:6b0b61d411ad 86 NVIC_SetVector(ADC_IRQn, (uint32_t)&_adcisr);
mptapton 0:6b0b61d411ad 87
mptapton 0:6b0b61d411ad 88 //Disable global interrupt
mptapton 0:6b0b61d411ad 89 LPC_ADC->ADINTEN &= ~0x100;
mptapton 0:6b0b61d411ad 90
mptapton 0:6b0b61d411ad 91 };
mptapton 0:6b0b61d411ad 92
mptapton 0:6b0b61d411ad 93 void ADC::_adcisr(void)
mptapton 0:6b0b61d411ad 94 {
mptapton 0:6b0b61d411ad 95 instance->adcisr();
mptapton 0:6b0b61d411ad 96 }
mptapton 0:6b0b61d411ad 97
mptapton 0:6b0b61d411ad 98
mptapton 0:6b0b61d411ad 99 void ADC::adcisr(void)
mptapton 0:6b0b61d411ad 100 {
mptapton 0:6b0b61d411ad 101 uint32_t stat;
mptapton 0:6b0b61d411ad 102 int chan;
mptapton 0:6b0b61d411ad 103
mptapton 0:6b0b61d411ad 104 // Read status
mptapton 0:6b0b61d411ad 105 stat = LPC_ADC->ADSTAT;
mptapton 0:6b0b61d411ad 106 //Scan channels for over-run or done and update array
mptapton 0:6b0b61d411ad 107 if (stat & 0x0101) _adc_data[0] = LPC_ADC->ADDR0;
mptapton 0:6b0b61d411ad 108 if (stat & 0x0202) _adc_data[1] = LPC_ADC->ADDR1;
mptapton 0:6b0b61d411ad 109 if (stat & 0x0404) _adc_data[2] = LPC_ADC->ADDR2;
mptapton 0:6b0b61d411ad 110 if (stat & 0x0808) _adc_data[3] = LPC_ADC->ADDR3;
mptapton 0:6b0b61d411ad 111 if (stat & 0x1010) _adc_data[4] = LPC_ADC->ADDR4;
mptapton 0:6b0b61d411ad 112 if (stat & 0x2020) _adc_data[5] = LPC_ADC->ADDR5;
mptapton 0:6b0b61d411ad 113 if (stat & 0x4040) _adc_data[6] = LPC_ADC->ADDR6;
mptapton 0:6b0b61d411ad 114 if (stat & 0x8080) _adc_data[7] = LPC_ADC->ADDR7;
mptapton 0:6b0b61d411ad 115
mptapton 0:6b0b61d411ad 116 // Channel that triggered interrupt
mptapton 0:6b0b61d411ad 117 chan = (LPC_ADC->ADGDR >> 24) & 0x07;
mptapton 0:6b0b61d411ad 118 //User defined interrupt handlers
mptapton 0:6b0b61d411ad 119 if (_adc_isr[chan] != NULL)
mptapton 0:6b0b61d411ad 120 _adc_isr[chan](_adc_data[chan]);
mptapton 0:6b0b61d411ad 121 if (_adc_g_isr != NULL)
mptapton 0:6b0b61d411ad 122 _adc_g_isr(chan, _adc_data[chan]);
mptapton 0:6b0b61d411ad 123 return;
mptapton 0:6b0b61d411ad 124 }
mptapton 0:6b0b61d411ad 125
mptapton 0:6b0b61d411ad 126 int ADC::_pin_to_channel(PinName pin) {
mptapton 0:6b0b61d411ad 127 int chan;
mptapton 0:6b0b61d411ad 128 switch (pin) {
mptapton 0:6b0b61d411ad 129 case p15://=p0.23 of LPC1768
mptapton 0:6b0b61d411ad 130 default:
mptapton 0:6b0b61d411ad 131 chan=0;
mptapton 0:6b0b61d411ad 132 break;
mptapton 0:6b0b61d411ad 133 case p16://=p0.24 of LPC1768
mptapton 0:6b0b61d411ad 134 chan=1;
mptapton 0:6b0b61d411ad 135 break;
mptapton 0:6b0b61d411ad 136 case p17://=p0.25 of LPC1768
mptapton 0:6b0b61d411ad 137 chan=2;
mptapton 0:6b0b61d411ad 138 break;
mptapton 0:6b0b61d411ad 139 case p18://=p0.26 of LPC1768
mptapton 0:6b0b61d411ad 140 chan=3;
mptapton 0:6b0b61d411ad 141 break;
mptapton 0:6b0b61d411ad 142 case p19://=p1.30 of LPC1768
mptapton 0:6b0b61d411ad 143 chan=4;
mptapton 0:6b0b61d411ad 144 break;
mptapton 0:6b0b61d411ad 145 case p20://=p1.31 of LPC1768
mptapton 0:6b0b61d411ad 146 chan=5;
mptapton 0:6b0b61d411ad 147 break;
mptapton 0:6b0b61d411ad 148 }
mptapton 0:6b0b61d411ad 149 return(chan);
mptapton 0:6b0b61d411ad 150 }
mptapton 0:6b0b61d411ad 151
mptapton 0:6b0b61d411ad 152 PinName ADC::channel_to_pin(int chan) {
mptapton 0:6b0b61d411ad 153 const PinName pin[8]={p15, p16, p17, p18, p19, p20, p15, p15};
mptapton 0:6b0b61d411ad 154
mptapton 0:6b0b61d411ad 155 if ((chan < 0) || (chan > 5))
mptapton 0:6b0b61d411ad 156 fprintf(stderr, "ADC channel %u is outside range available to MBED pins.\n", chan);
mptapton 0:6b0b61d411ad 157 return(pin[chan & 0x07]);
mptapton 0:6b0b61d411ad 158 }
mptapton 0:6b0b61d411ad 159
mptapton 0:6b0b61d411ad 160
mptapton 0:6b0b61d411ad 161 int ADC::channel_to_pin_number(int chan) {
mptapton 0:6b0b61d411ad 162 const int pin[8]={15, 16, 17, 18, 19, 20, 0, 0};
mptapton 0:6b0b61d411ad 163
mptapton 0:6b0b61d411ad 164 if ((chan < 0) || (chan > 5))
mptapton 0:6b0b61d411ad 165 fprintf(stderr, "ADC channel %u is outside range available to MBED pins.\n", chan);
mptapton 0:6b0b61d411ad 166 return(pin[chan & 0x07]);
mptapton 0:6b0b61d411ad 167 }
mptapton 0:6b0b61d411ad 168
mptapton 0:6b0b61d411ad 169
mptapton 0:6b0b61d411ad 170 uint32_t ADC::_data_of_pin(PinName pin) {
mptapton 0:6b0b61d411ad 171 //If in burst mode and at least one interrupt enabled then
mptapton 0:6b0b61d411ad 172 //take all values from _adc_data
mptapton 0:6b0b61d411ad 173 if (burst() && (LPC_ADC->ADINTEN & 0x3F)) {
mptapton 0:6b0b61d411ad 174 return(_adc_data[_pin_to_channel(pin)]);
mptapton 0:6b0b61d411ad 175 } else {
mptapton 0:6b0b61d411ad 176 //Return current register value or last value from interrupt
mptapton 0:6b0b61d411ad 177 switch (pin) {
mptapton 0:6b0b61d411ad 178 case p15://=p0.23 of LPC1768
mptapton 0:6b0b61d411ad 179 default:
mptapton 0:6b0b61d411ad 180 return(LPC_ADC->ADINTEN & 0x01?_adc_data[0]:LPC_ADC->ADDR0);
mptapton 0:6b0b61d411ad 181 case p16://=p0.24 of LPC1768
mptapton 0:6b0b61d411ad 182 return(LPC_ADC->ADINTEN & 0x02?_adc_data[1]:LPC_ADC->ADDR1);
mptapton 0:6b0b61d411ad 183 case p17://=p0.25 of LPC1768
mptapton 0:6b0b61d411ad 184 return(LPC_ADC->ADINTEN & 0x04?_adc_data[2]:LPC_ADC->ADDR2);
mptapton 0:6b0b61d411ad 185 case p18://=p0.26 of LPC1768:
mptapton 0:6b0b61d411ad 186 return(LPC_ADC->ADINTEN & 0x08?_adc_data[3]:LPC_ADC->ADDR3);
mptapton 0:6b0b61d411ad 187 case p19://=p1.30 of LPC1768
mptapton 0:6b0b61d411ad 188 return(LPC_ADC->ADINTEN & 0x10?_adc_data[4]:LPC_ADC->ADDR4);
mptapton 0:6b0b61d411ad 189 case p20://=p1.31 of LPC1768
mptapton 0:6b0b61d411ad 190 return(LPC_ADC->ADINTEN & 0x20?_adc_data[5]:LPC_ADC->ADDR5);
mptapton 0:6b0b61d411ad 191 }
mptapton 0:6b0b61d411ad 192 }
mptapton 0:6b0b61d411ad 193 }
mptapton 0:6b0b61d411ad 194
mptapton 0:6b0b61d411ad 195 //Enable or disable an ADC pin
mptapton 0:6b0b61d411ad 196 void ADC::setup(PinName pin, int state) {
mptapton 0:6b0b61d411ad 197 int chan;
mptapton 0:6b0b61d411ad 198 chan=_pin_to_channel(pin);
mptapton 0:6b0b61d411ad 199 if ((state & 1) == 1) {
mptapton 0:6b0b61d411ad 200 switch(pin) {
mptapton 0:6b0b61d411ad 201 case p15://=p0.23 of LPC1768
mptapton 0:6b0b61d411ad 202 default:
mptapton 0:6b0b61d411ad 203 LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 14);
mptapton 0:6b0b61d411ad 204 LPC_PINCON->PINSEL1 |= (unsigned int)0x1 << 14;
mptapton 0:6b0b61d411ad 205 LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 14);
mptapton 0:6b0b61d411ad 206 LPC_PINCON->PINMODE1 |= (unsigned int)0x2 << 14;
mptapton 0:6b0b61d411ad 207 break;
mptapton 0:6b0b61d411ad 208 case p16://=p0.24 of LPC1768
mptapton 0:6b0b61d411ad 209 LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 16);
mptapton 0:6b0b61d411ad 210 LPC_PINCON->PINSEL1 |= (unsigned int)0x1 << 16;
mptapton 0:6b0b61d411ad 211 LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 16);
mptapton 0:6b0b61d411ad 212 LPC_PINCON->PINMODE1 |= (unsigned int)0x2 << 16;
mptapton 0:6b0b61d411ad 213 break;
mptapton 0:6b0b61d411ad 214 case p17://=p0.25 of LPC1768
mptapton 0:6b0b61d411ad 215 LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 18);
mptapton 0:6b0b61d411ad 216 LPC_PINCON->PINSEL1 |= (unsigned int)0x1 << 18;
mptapton 0:6b0b61d411ad 217 LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 18);
mptapton 0:6b0b61d411ad 218 LPC_PINCON->PINMODE1 |= (unsigned int)0x2 << 18;
mptapton 0:6b0b61d411ad 219 break;
mptapton 0:6b0b61d411ad 220 case p18://=p0.26 of LPC1768:
mptapton 0:6b0b61d411ad 221 LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 20);
mptapton 0:6b0b61d411ad 222 LPC_PINCON->PINSEL1 |= (unsigned int)0x1 << 20;
mptapton 0:6b0b61d411ad 223 LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 20);
mptapton 0:6b0b61d411ad 224 LPC_PINCON->PINMODE1 |= (unsigned int)0x2 << 20;
mptapton 0:6b0b61d411ad 225 break;
mptapton 0:6b0b61d411ad 226 case p19://=p1.30 of LPC1768
mptapton 0:6b0b61d411ad 227 LPC_PINCON->PINSEL3 &= ~((unsigned int)0x3 << 28);
mptapton 0:6b0b61d411ad 228 LPC_PINCON->PINSEL3 |= (unsigned int)0x3 << 28;
mptapton 0:6b0b61d411ad 229 LPC_PINCON->PINMODE3 &= ~((unsigned int)0x3 << 28);
mptapton 0:6b0b61d411ad 230 LPC_PINCON->PINMODE3 |= (unsigned int)0x2 << 28;
mptapton 0:6b0b61d411ad 231 break;
mptapton 0:6b0b61d411ad 232 case p20://=p1.31 of LPC1768
mptapton 0:6b0b61d411ad 233 LPC_PINCON->PINSEL3 &= ~((unsigned int)0x3 << 30);
mptapton 0:6b0b61d411ad 234 LPC_PINCON->PINSEL3 |= (unsigned int)0x3 << 30;
mptapton 0:6b0b61d411ad 235 LPC_PINCON->PINMODE3 &= ~((unsigned int)0x3 << 30);
mptapton 0:6b0b61d411ad 236 LPC_PINCON->PINMODE3 |= (unsigned int)0x2 << 30;
mptapton 0:6b0b61d411ad 237 break;
mptapton 0:6b0b61d411ad 238 }
mptapton 0:6b0b61d411ad 239 //Only one channel can be selected at a time if not in burst mode
mptapton 0:6b0b61d411ad 240 if (!burst()) LPC_ADC->ADCR &= ~0xFF;
mptapton 0:6b0b61d411ad 241 //Select channel
mptapton 0:6b0b61d411ad 242 LPC_ADC->ADCR |= (1 << chan);
mptapton 0:6b0b61d411ad 243 }
mptapton 0:6b0b61d411ad 244 else {
mptapton 0:6b0b61d411ad 245 switch(pin) {
mptapton 0:6b0b61d411ad 246 case p15://=p0.23 of LPC1768
mptapton 0:6b0b61d411ad 247 default:
mptapton 0:6b0b61d411ad 248 LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 14);
mptapton 0:6b0b61d411ad 249 LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 14);
mptapton 0:6b0b61d411ad 250 break;
mptapton 0:6b0b61d411ad 251 case p16://=p0.24 of LPC1768
mptapton 0:6b0b61d411ad 252 LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 16);
mptapton 0:6b0b61d411ad 253 LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 16);
mptapton 0:6b0b61d411ad 254 break;
mptapton 0:6b0b61d411ad 255 case p17://=p0.25 of LPC1768
mptapton 0:6b0b61d411ad 256 LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 18);
mptapton 0:6b0b61d411ad 257 LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 18);
mptapton 0:6b0b61d411ad 258 break;
mptapton 0:6b0b61d411ad 259 case p18://=p0.26 of LPC1768:
mptapton 0:6b0b61d411ad 260 LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 20);
mptapton 0:6b0b61d411ad 261 LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 20);
mptapton 0:6b0b61d411ad 262 break;
mptapton 0:6b0b61d411ad 263 case p19://=p1.30 of LPC1768
mptapton 0:6b0b61d411ad 264 LPC_PINCON->PINSEL3 &= ~((unsigned int)0x3 << 28);
mptapton 0:6b0b61d411ad 265 LPC_PINCON->PINMODE3 &= ~((unsigned int)0x3 << 28);
mptapton 0:6b0b61d411ad 266 break;
mptapton 0:6b0b61d411ad 267 case p20://=p1.31 of LPC1768
mptapton 0:6b0b61d411ad 268 LPC_PINCON->PINSEL3 &= ~((unsigned int)0x3 << 30);
mptapton 0:6b0b61d411ad 269 LPC_PINCON->PINMODE3 &= ~((unsigned int)0x3 << 30);
mptapton 0:6b0b61d411ad 270 break;
mptapton 0:6b0b61d411ad 271 }
mptapton 0:6b0b61d411ad 272 LPC_ADC->ADCR &= ~(1 << chan);
mptapton 0:6b0b61d411ad 273 }
mptapton 0:6b0b61d411ad 274 }
mptapton 0:6b0b61d411ad 275 //Return channel enabled/disabled state
mptapton 0:6b0b61d411ad 276 int ADC::setup(PinName pin) {
mptapton 0:6b0b61d411ad 277 int chan;
mptapton 0:6b0b61d411ad 278
mptapton 0:6b0b61d411ad 279 chan = _pin_to_channel(pin);
mptapton 0:6b0b61d411ad 280 return((LPC_ADC->ADCR & (1 << chan)) >> chan);
mptapton 0:6b0b61d411ad 281 }
mptapton 0:6b0b61d411ad 282
mptapton 0:6b0b61d411ad 283 //Select channel already setup
mptapton 0:6b0b61d411ad 284 void ADC::select(PinName pin) {
mptapton 0:6b0b61d411ad 285 int chan;
mptapton 0:6b0b61d411ad 286
mptapton 0:6b0b61d411ad 287 //Only one channel can be selected at a time if not in burst mode
mptapton 0:6b0b61d411ad 288 if (!burst()) LPC_ADC->ADCR &= ~0xFF;
mptapton 0:6b0b61d411ad 289 //Select channel
mptapton 0:6b0b61d411ad 290 chan = _pin_to_channel(pin);
mptapton 0:6b0b61d411ad 291 LPC_ADC->ADCR |= (1 << chan);
mptapton 0:6b0b61d411ad 292 }
mptapton 0:6b0b61d411ad 293
mptapton 0:6b0b61d411ad 294 //Enable or disable burst mode
mptapton 0:6b0b61d411ad 295 void ADC::burst(int state) {
mptapton 0:6b0b61d411ad 296 if ((state & 1) == 1) {
mptapton 0:6b0b61d411ad 297 if (startmode(0) != 0)
mptapton 0:6b0b61d411ad 298 fprintf(stderr, "Warning. startmode is %u. Must be 0 for burst mode.\n", startmode(0));
mptapton 0:6b0b61d411ad 299 LPC_ADC->ADCR |= (1 << 16);
mptapton 0:6b0b61d411ad 300 }
mptapton 0:6b0b61d411ad 301 else
mptapton 0:6b0b61d411ad 302 LPC_ADC->ADCR &= ~(1 << 16);
mptapton 0:6b0b61d411ad 303 }
mptapton 0:6b0b61d411ad 304 //Return burst mode state
mptapton 0:6b0b61d411ad 305 int ADC::burst(void) {
mptapton 0:6b0b61d411ad 306 return((LPC_ADC->ADCR & (1 << 16)) >> 16);
mptapton 0:6b0b61d411ad 307 }
mptapton 0:6b0b61d411ad 308
mptapton 0:6b0b61d411ad 309 //Set startmode and edge
mptapton 0:6b0b61d411ad 310 void ADC::startmode(int mode, int edge) {
mptapton 0:6b0b61d411ad 311 int lpc_adc_temp;
mptapton 0:6b0b61d411ad 312
mptapton 0:6b0b61d411ad 313 //Reset start mode and edge bit,
mptapton 0:6b0b61d411ad 314 lpc_adc_temp = LPC_ADC->ADCR & ~(0x0F << 24);
mptapton 0:6b0b61d411ad 315 //Write with new values
mptapton 0:6b0b61d411ad 316 lpc_adc_temp |= ((mode & 7) << 24) | ((edge & 1) << 27);
mptapton 0:6b0b61d411ad 317 LPC_ADC->ADCR = lpc_adc_temp;
mptapton 0:6b0b61d411ad 318 }
mptapton 0:6b0b61d411ad 319
mptapton 0:6b0b61d411ad 320 //Return startmode state according to mode_edge=0: mode and mode_edge=1: edge
mptapton 0:6b0b61d411ad 321 int ADC::startmode(int mode_edge){
mptapton 0:6b0b61d411ad 322 switch (mode_edge) {
mptapton 0:6b0b61d411ad 323 case 0:
mptapton 0:6b0b61d411ad 324 default:
mptapton 0:6b0b61d411ad 325 return((LPC_ADC->ADCR >> 24) & 0x07);
mptapton 0:6b0b61d411ad 326 case 1:
mptapton 0:6b0b61d411ad 327 return((LPC_ADC->ADCR >> 27) & 0x01);
mptapton 0:6b0b61d411ad 328 }
mptapton 0:6b0b61d411ad 329 }
mptapton 0:6b0b61d411ad 330
mptapton 0:6b0b61d411ad 331 //Start ADC conversion
mptapton 0:6b0b61d411ad 332 void ADC::start(void) {
mptapton 0:6b0b61d411ad 333 startmode(1,0);
mptapton 0:6b0b61d411ad 334 }
mptapton 0:6b0b61d411ad 335
mptapton 0:6b0b61d411ad 336
mptapton 0:6b0b61d411ad 337 //Set interrupt enable/disable for pin to state
mptapton 0:6b0b61d411ad 338 void ADC::interrupt_state(PinName pin, int state) {
mptapton 0:6b0b61d411ad 339 int chan;
mptapton 0:6b0b61d411ad 340
mptapton 0:6b0b61d411ad 341 chan = _pin_to_channel(pin);
mptapton 0:6b0b61d411ad 342 if (state == 1) {
mptapton 0:6b0b61d411ad 343 LPC_ADC->ADINTEN &= ~0x100;
mptapton 0:6b0b61d411ad 344 LPC_ADC->ADINTEN |= 1 << chan;
mptapton 0:6b0b61d411ad 345 /* Enable the ADC Interrupt */
mptapton 0:6b0b61d411ad 346 NVIC_EnableIRQ(ADC_IRQn);
mptapton 0:6b0b61d411ad 347 } else {
mptapton 0:6b0b61d411ad 348 LPC_ADC->ADINTEN &= ~( 1 << chan );
mptapton 0:6b0b61d411ad 349 //Disable interrrupt if no active pins left
mptapton 0:6b0b61d411ad 350 if ((LPC_ADC->ADINTEN & 0xFF) == 0)
mptapton 0:6b0b61d411ad 351 NVIC_DisableIRQ(ADC_IRQn);
mptapton 0:6b0b61d411ad 352 }
mptapton 0:6b0b61d411ad 353 }
mptapton 0:6b0b61d411ad 354
mptapton 0:6b0b61d411ad 355 //Return enable/disable state of interrupt for pin
mptapton 0:6b0b61d411ad 356 int ADC::interrupt_state(PinName pin) {
mptapton 0:6b0b61d411ad 357 int chan;
mptapton 0:6b0b61d411ad 358
mptapton 0:6b0b61d411ad 359 chan = _pin_to_channel(pin);
mptapton 0:6b0b61d411ad 360 return((LPC_ADC->ADINTEN >> chan) & 0x01);
mptapton 0:6b0b61d411ad 361 }
mptapton 0:6b0b61d411ad 362
mptapton 0:6b0b61d411ad 363
mptapton 0:6b0b61d411ad 364 //Attach custom interrupt handler replacing default
mptapton 0:6b0b61d411ad 365 void ADC::attach(void(*fptr)(void)) {
mptapton 0:6b0b61d411ad 366 //* Attach IRQ
mptapton 0:6b0b61d411ad 367 NVIC_SetVector(ADC_IRQn, (uint32_t)fptr);
mptapton 0:6b0b61d411ad 368 }
mptapton 0:6b0b61d411ad 369
mptapton 0:6b0b61d411ad 370 //Restore default interrupt handler
mptapton 0:6b0b61d411ad 371 void ADC::detach(void) {
mptapton 0:6b0b61d411ad 372 //* Attach IRQ
mptapton 0:6b0b61d411ad 373 instance = this;
mptapton 0:6b0b61d411ad 374 NVIC_SetVector(ADC_IRQn, (uint32_t)&_adcisr);
mptapton 0:6b0b61d411ad 375 }
mptapton 0:6b0b61d411ad 376
mptapton 0:6b0b61d411ad 377
mptapton 0:6b0b61d411ad 378 //Append interrupt handler for pin to function isr
mptapton 0:6b0b61d411ad 379 void ADC::append(PinName pin, void(*fptr)(uint32_t value)) {
mptapton 0:6b0b61d411ad 380 int chan;
mptapton 0:6b0b61d411ad 381
mptapton 0:6b0b61d411ad 382 chan = _pin_to_channel(pin);
mptapton 0:6b0b61d411ad 383 _adc_isr[chan] = fptr;
mptapton 0:6b0b61d411ad 384 }
mptapton 0:6b0b61d411ad 385
mptapton 0:6b0b61d411ad 386 //Append interrupt handler for pin to function isr
mptapton 0:6b0b61d411ad 387 void ADC::unappend(PinName pin) {
mptapton 0:6b0b61d411ad 388 int chan;
mptapton 0:6b0b61d411ad 389
mptapton 0:6b0b61d411ad 390 chan = _pin_to_channel(pin);
mptapton 0:6b0b61d411ad 391 _adc_isr[chan] = NULL;
mptapton 0:6b0b61d411ad 392 }
mptapton 0:6b0b61d411ad 393
mptapton 0:6b0b61d411ad 394 //Unappend global interrupt handler to function isr
mptapton 0:6b0b61d411ad 395 void ADC::append(void(*fptr)(int chan, uint32_t value)) {
mptapton 0:6b0b61d411ad 396 _adc_g_isr = fptr;
mptapton 0:6b0b61d411ad 397 }
mptapton 0:6b0b61d411ad 398
mptapton 0:6b0b61d411ad 399 //Detach global interrupt handler to function isr
mptapton 0:6b0b61d411ad 400 void ADC::unappend() {
mptapton 0:6b0b61d411ad 401 _adc_g_isr = NULL;
mptapton 0:6b0b61d411ad 402 }
mptapton 0:6b0b61d411ad 403
mptapton 0:6b0b61d411ad 404 //Set ADC offset
mptapton 0:6b0b61d411ad 405 void offset(int offset) {
mptapton 0:6b0b61d411ad 406 LPC_ADC->ADTRM &= ~(0x07 << 4);
mptapton 0:6b0b61d411ad 407 LPC_ADC->ADTRM |= (offset & 0x07) << 4;
mptapton 0:6b0b61d411ad 408 }
mptapton 0:6b0b61d411ad 409
mptapton 0:6b0b61d411ad 410 //Return current ADC offset
mptapton 0:6b0b61d411ad 411 int offset(void) {
mptapton 0:6b0b61d411ad 412 return((LPC_ADC->ADTRM >> 4) & 0x07);
mptapton 0:6b0b61d411ad 413 }
mptapton 0:6b0b61d411ad 414
mptapton 0:6b0b61d411ad 415 //Return value of ADC on pin
mptapton 0:6b0b61d411ad 416 int ADC::read(PinName pin) {
mptapton 0:6b0b61d411ad 417 //Reset DONE and OVERRUN flags of interrupt handled ADC data
mptapton 0:6b0b61d411ad 418 _adc_data[_pin_to_channel(pin)] &= ~(((uint32_t)0x01 << 31) | ((uint32_t)0x01 << 30));
mptapton 0:6b0b61d411ad 419 //Return value
mptapton 0:6b0b61d411ad 420 return((_data_of_pin(pin) >> 4) & 0xFFF);
mptapton 0:6b0b61d411ad 421 }
mptapton 0:6b0b61d411ad 422
mptapton 0:6b0b61d411ad 423 //Return DONE flag of ADC on pin
mptapton 0:6b0b61d411ad 424 int ADC::done(PinName pin) {
mptapton 0:6b0b61d411ad 425 return((_data_of_pin(pin) >> 31) & 0x01);
mptapton 0:6b0b61d411ad 426 }
mptapton 0:6b0b61d411ad 427
mptapton 0:6b0b61d411ad 428 //Return OVERRUN flag of ADC on pin
mptapton 0:6b0b61d411ad 429 int ADC::overrun(PinName pin) {
mptapton 0:6b0b61d411ad 430 return((_data_of_pin(pin) >> 30) & 0x01);
mptapton 0:6b0b61d411ad 431 }
mptapton 0:6b0b61d411ad 432
mptapton 0:6b0b61d411ad 433 int ADC::actual_adc_clock(void) {
mptapton 0:6b0b61d411ad 434 return(_adc_clk_freq);
mptapton 0:6b0b61d411ad 435 }
mptapton 0:6b0b61d411ad 436
mptapton 0:6b0b61d411ad 437 int ADC::actual_sample_rate(void) {
mptapton 0:6b0b61d411ad 438 return(_adc_clk_freq / CLKS_PER_SAMPLE);
mptapton 0:6b0b61d411ad 439 }