hadrovic oled

Dependencies:   mbed

Committer:
perodot
Date:
Wed Apr 09 13:32:39 2014 +0000
Revision:
0:b13343630d26
Hardovic Oled

Who changed what in which revision?

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