![]() |
Mozzi
alpha 0.01.1t
sound synthesis library for Arduino
|
00001 /* 00002 This code is from 00003 http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=789581 00004 discussion between jRaskell, bobgardner, theusch, Koshchi, code by jRaskell. 00005 00006 Another approach discussed on the same page is to use free running mode on one channel only, 00007 with (eg. 4) two resistor voltage dividers to define each input pseudo-channel. 00008 The drawback there is lower resolution for each input because the 10-bit input 00009 range has to be divided between them. 00010 00011 */ 00012 #include "mozzi_analog.h" 00013 00014 00015 #define NUM_ANALOG_INPUTS 6 00016 00017 00018 static volatile int sensors[NUM_ANALOG_INPUTS]; 00019 static volatile byte current_adc = 0; 00020 static volatile boolean readComplete = false; 00021 00022 00034 void initADC(){ 00035 // The only difference between this and vanilla arduino is ADIE, enable ADC interrupt. 00036 // Enable a2d conversions | Enable ADC Interrupt | Set a2d prescale factor to 128 00037 ADCSRA = (1 << ADEN) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); 00038 } 00039 00040 00041 00056 void startRead(){ 00057 current_adc = 0; 00058 00059 //Set MUX channel 00060 ADMUX = (1 << REFS0) | current_adc; 00061 //Start A2D Conversions 00062 ADCSRA |= (1 << ADSC); 00063 } 00064 00065 00066 00067 ISR(ADC_vect){ 00068 static boolean secondRead = false; 00069 00070 //Only record the second read on each channel 00071 if(secondRead){ 00072 sensors[current_adc] = ADCL | (ADCH << 8); 00073 //bobgardner: ..The compiler is clever enough to read the 10 bit value like this: val=ADC; 00074 //sensors[current_adc] = ADC; 00075 current_adc++; 00076 if(current_adc > NUM_ANALOG_INPUTS){ 00077 //Sequence complete. Stop A2D conversions 00078 readComplete = true; 00079 } 00080 else{ 00081 //Switch to next channel 00082 ADMUX = (1 << REFS0) | current_adc; 00083 ADCSRA |= (1 << ADSC); 00084 00085 } 00086 secondRead = false; 00087 } 00088 else{ 00089 secondRead = true; 00090 ADCSRA |= (1 << ADSC); 00091 } 00092 00093 } 00094 00095 00096 00108 int getSensor(unsigned char channel_num){ 00109 return sensors[channel_num]; 00110 } 00111 00112 00113 00114 00123 void setupFastAnalogRead() 00124 { 00125 // fastest predivided rate (divide by 16, giving 1Mhz) for which behaviour is defined (~16us per sample) 00126 sbi(ADCSRA,ADPS2); 00127 cbi(ADCSRA,ADPS1); 00128 cbi(ADCSRA,ADPS0); 00129 } 00130 00131 00132 00148 void disconnectDigitalIn(byte channel_num){ 00149 DIDR0 |= 1<<channel_num; 00150 } 00151 00152 00153 00159 void reconnectDigitalIn(byte channel_num){ 00160 DIDR0 &= ~(1<<channel_num); 00161 } 00162 00163 00164 static unsigned char analog_reference = DEFAULT; 00165 00181 // basically analogRead() chopped in half so the ADC conversion 00182 // can be started in one function and received in another. 00183 void startAnalogRead(unsigned char pin) 00184 { 00185 00186 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 00187 if (pin >= 54) 00188 pin -= 54; // allow for channel or pin numbers 00189 #elif defined(__AVR_ATmega32U4__) 00190 00191 if (pin >= 18) 00192 pin -= 18; // allow for channel or pin numbers 00193 #elif defined(__AVR_ATmega1284__) 00194 00195 if (pin >= 24) 00196 pin -= 24; // allow for channel or pin numbers 00197 #else 00198 00199 if (pin >= 14) 00200 pin -= 14; // allow for channel or pin numbers 00201 #endif 00202 00203 #if defined(__AVR_ATmega32U4__) 00204 00205 pin = analogPinToChannel(pin); 00206 ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); 00207 #elif defined(ADCSRB) && defined(MUX5) 00208 // the MUX5 bit of ADCSRB selects whether we're reading from channels 00209 // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high). 00210 ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); 00211 #endif 00212 00213 // set the analog reference (high two bits of ADMUX) and select the 00214 // channel (low 4 bits). this also sets ADLAR (left-adjust result) 00215 // to 0 (the default). 00216 #if defined(ADMUX) 00217 00218 ADMUX = (analog_reference << 6) | (pin & 0x07); 00219 #endif 00220 00221 // without a delay, we seem to read from the wrong channel 00222 //delay(1); 00223 00224 #if defined(ADCSRA) && defined(ADCL) 00225 // start the conversion 00226 sbi(ADCSRA, ADSC); 00227 #endif 00228 } 00229 00241 int receiveAnalogRead() 00242 { 00243 unsigned char low, high; 00244 #if defined(ADCSRA) && defined(ADCL) 00245 // ADSC is cleared when the conversion finishes 00246 while (bit_is_set(ADCSRA, ADSC)) 00247 ; 00248 00249 // we have to read ADCL first; doing so locks both ADCL 00250 // and ADCH until ADCH is read. reading ADCL second would 00251 // cause the results of each conversion to be discarded, 00252 // as ADCL and ADCH would be locked when it completed. 00253 low = ADCL; 00254 high = ADCH; 00255 #else 00256 // we dont have an ADC, return 0 00257 low = 0; 00258 high = 0; 00259 #endif 00260 00261 // combine the two bytes 00262 return (high << 8) | low; 00263 } 00264 00265