Fork of Smoothie to port to mbed non-LPC targets.

Dependencies:   mbed

Fork of Smoothie by Stéphane Cachat

Committer:
Michael J. Spencer
Date:
Fri Feb 28 18:52:52 2014 -0800
Revision:
2:1df0b61d3b5a
Update to latest Smoothie.

Who changed what in which revision?

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