Solo project mbed 2

Dependencies:   PololuLedStrip mbed

Fork of SX10_BigBangFinal_A by Tapton Eesarm

Committer:
mptapton
Date:
Mon Feb 06 09:42:24 2017 +0000
Revision:
2:bc7345c92188
Parent:
0:5ddd4b0f64f8
Tapton School project guitar tuner mbed2 code

Who changed what in which revision?

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