Commit | Line | Data |
---|---|---|
23839b8c | 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 | ||
f7bca5c4 JH |
17 | // Simple analog to digitial conversion |
18 | ||
19 | #include <avr/io.h> | |
20 | #include <avr/pgmspace.h> | |
21 | #include <stdint.h> | |
22 | #include "analog.h" | |
23 | ||
b624f32f | 24 | static uint8_t aref = (1 << REFS0); // default to AREF = Vcc |
f7bca5c4 | 25 | |
b624f32f | 26 | void analogReference(uint8_t mode) { aref = mode & 0xC0; } |
f7bca5c4 JH |
27 | |
28 | // Arduino compatible pin input | |
b624f32f | 29 | int16_t analogRead(uint8_t pin) { |
f7bca5c4 | 30 | #if defined(__AVR_ATmega32U4__) |
b624f32f | 31 | static const uint8_t PROGMEM pin_to_mux[] = {0x00, 0x01, 0x04, 0x05, 0x06, 0x07, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20}; |
32 | if (pin >= 12) return 0; | |
33 | return adc_read(pgm_read_byte(pin_to_mux + pin)); | |
f7bca5c4 | 34 | #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) |
b624f32f | 35 | if (pin >= 8) return 0; |
36 | return adc_read(pin); | |
f7bca5c4 | 37 | #else |
b624f32f | 38 | return 0; |
f7bca5c4 JH |
39 | #endif |
40 | } | |
41 | ||
42 | // Mux input | |
b624f32f | 43 | int16_t adc_read(uint8_t mux) { |
f7bca5c4 | 44 | #if defined(__AVR_AT90USB162__) |
b624f32f | 45 | return 0; |
f7bca5c4 | 46 | #else |
b624f32f | 47 | uint8_t low; |
48 | ||
49 | ADCSRA = (1 << ADEN) | ADC_PRESCALER; // enable ADC | |
50 | ADCSRB = (1 << ADHSM) | (mux & 0x20); // high speed mode | |
51 | ADMUX = aref | (mux & 0x1F); // configure mux input | |
52 | ADCSRA = (1 << ADEN) | ADC_PRESCALER | (1 << ADSC); // start the conversion | |
53 | while (ADCSRA & (1 << ADSC)) | |
54 | ; // wait for result | |
55 | low = ADCL; // must read LSB first | |
56 | return (ADCH << 8) | low; // must read MSB only once! | |
f7bca5c4 JH |
57 | #endif |
58 | } |