analog.c (4473B)
1 /* Copyright 2015 Jack Humbert 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 2 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17 #include "analog.h" 18 19 static uint8_t aref = ADC_REF_POWER; 20 21 void analogReference(uint8_t mode) { 22 aref = mode & (_BV(REFS1) | _BV(REFS0)); 23 } 24 25 int16_t analogReadPin(pin_t pin) { 26 return adc_read(pinToMux(pin)); 27 } 28 29 uint8_t pinToMux(pin_t pin) { 30 switch (pin) { 31 // clang-format off 32 #if defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) 33 case F0: return 0; // ADC0 34 case F1: return _BV(MUX0); // ADC1 35 case F2: return _BV(MUX1); // ADC2 36 case F3: return _BV(MUX1) | _BV(MUX0); // ADC3 37 case F4: return _BV(MUX2); // ADC4 38 case F5: return _BV(MUX2) | _BV(MUX0); // ADC5 39 case F6: return _BV(MUX2) | _BV(MUX1); // ADC6 40 case F7: return _BV(MUX2) | _BV(MUX1) | _BV(MUX0); // ADC7 41 default: return _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0); // 0V 42 #elif defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) 43 case F0: return 0; // ADC0 44 case F1: return _BV(MUX0); // ADC1 45 case F4: return _BV(MUX2); // ADC4 46 case F5: return _BV(MUX2) | _BV(MUX0); // ADC5 47 case F6: return _BV(MUX2) | _BV(MUX1); // ADC6 48 case F7: return _BV(MUX2) | _BV(MUX1) | _BV(MUX0); // ADC7 49 case D4: return _BV(MUX5); // ADC8 50 case D6: return _BV(MUX5) | _BV(MUX0); // ADC9 51 case D7: return _BV(MUX5) | _BV(MUX1); // ADC10 52 case B4: return _BV(MUX5) | _BV(MUX1) | _BV(MUX0); // ADC11 53 case B5: return _BV(MUX5) | _BV(MUX2); // ADC12 54 case B6: return _BV(MUX5) | _BV(MUX2) | _BV(MUX0); // ADC13 55 default: return _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0); // 0V 56 #elif defined(__AVR_ATmega32A__) 57 case A0: return 0; // ADC0 58 case A1: return _BV(MUX0); // ADC1 59 case A2: return _BV(MUX1); // ADC2 60 case A3: return _BV(MUX1) | _BV(MUX0); // ADC3 61 case A4: return _BV(MUX2); // ADC4 62 case A5: return _BV(MUX2) | _BV(MUX0); // ADC5 63 case A6: return _BV(MUX2) | _BV(MUX1); // ADC6 64 case A7: return _BV(MUX2) | _BV(MUX1) | _BV(MUX0); // ADC7 65 default: return _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0); // 0V 66 #elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) 67 case C0: return 0; // ADC0 68 case C1: return _BV(MUX0); // ADC1 69 case C2: return _BV(MUX1); // ADC2 70 case C3: return _BV(MUX1) | _BV(MUX0); // ADC3 71 case C4: return _BV(MUX2); // ADC4 72 case C5: return _BV(MUX2) | _BV(MUX0); // ADC5 73 // ADC7:6 not present in DIP package and not shared by GPIO pins 74 default: return _BV(MUX3) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0); // 0V 75 #endif 76 // clang-format on 77 } 78 return 0; 79 } 80 81 int16_t adc_read(uint8_t mux) { 82 uint16_t low; 83 84 // Enable ADC and configure prescaler 85 ADCSRA = _BV(ADEN) | ADC_PRESCALER; 86 87 #if defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) 88 // High speed mode and ADC8-13 89 ADCSRB = _BV(ADHSM) | (mux & _BV(MUX5)); 90 #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) 91 // High speed mode only 92 ADCSRB = _BV(ADHSM); 93 #endif 94 95 // Configure mux input 96 #if defined(MUX4) 97 ADMUX = aref | (mux & (_BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0))); 98 #else 99 ADMUX = aref | (mux & (_BV(MUX3) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0))); 100 #endif 101 102 // Start the conversion 103 ADCSRA |= _BV(ADSC); 104 // Wait for result 105 while (ADCSRA & _BV(ADSC)) 106 ; 107 // Must read LSB first 108 low = ADCL; 109 // Must read MSB only once! 110 low |= (ADCH << 8); 111 112 // turn off the ADC 113 ADCSRA &= ~(1 << ADEN); 114 115 return low; 116 }