~ubuntu-branches/ubuntu/precise/arduino/precise

« back to all changes in this revision

Viewing changes to hardware/arduino/cores/arduino/wiring_analog.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott Howard
  • Date: 2010-04-13 22:32:24 UTC
  • Revision ID: james.westby@ubuntu.com-20100413223224-jduxnd0xxnkkda02
Tags: upstream-0018+dfsg
ImportĀ upstreamĀ versionĀ 0018+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  wiring_analog.c - analog input and output
 
3
  Part of Arduino - http://www.arduino.cc/
 
4
 
 
5
  Copyright (c) 2005-2006 David A. Mellis
 
6
 
 
7
  This library is free software; you can redistribute it and/or
 
8
  modify it under the terms of the GNU Lesser General Public
 
9
  License as published by the Free Software Foundation; either
 
10
  version 2.1 of the License, or (at your option) any later version.
 
11
 
 
12
  This library is distributed in the hope that it will be useful,
 
13
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
  Lesser General Public License for more details.
 
16
 
 
17
  You should have received a copy of the GNU Lesser General
 
18
  Public License along with this library; if not, write to the
 
19
  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 
20
  Boston, MA  02111-1307  USA
 
21
 
 
22
  $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
 
23
*/
 
24
 
 
25
#include "wiring_private.h"
 
26
#include "pins_arduino.h"
 
27
 
 
28
uint8_t analog_reference = DEFAULT;
 
29
 
 
30
void analogReference(uint8_t mode)
 
31
{
 
32
        // can't actually set the register here because the default setting
 
33
        // will connect AVCC and the AREF pin, which would cause a short if
 
34
        // there's something connected to AREF.
 
35
        analog_reference = mode;
 
36
}
 
37
 
 
38
int analogRead(uint8_t pin)
 
39
{
 
40
        uint8_t low, high;
 
41
 
 
42
        // set the analog reference (high two bits of ADMUX) and select the
 
43
        // channel (low 4 bits).  this also sets ADLAR (left-adjust result)
 
44
        // to 0 (the default).
 
45
        ADMUX = (analog_reference << 6) | (pin & 0x07);
 
46
  
 
47
#if defined(__AVR_ATmega1280__)
 
48
        // the MUX5 bit of ADCSRB selects whether we're reading from channels
 
49
        // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
 
50
        ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
 
51
#endif
 
52
 
 
53
        // without a delay, we seem to read from the wrong channel
 
54
        //delay(1);
 
55
 
 
56
        // start the conversion
 
57
        sbi(ADCSRA, ADSC);
 
58
 
 
59
        // ADSC is cleared when the conversion finishes
 
60
        while (bit_is_set(ADCSRA, ADSC));
 
61
 
 
62
        // we have to read ADCL first; doing so locks both ADCL
 
63
        // and ADCH until ADCH is read.  reading ADCL second would
 
64
        // cause the results of each conversion to be discarded,
 
65
        // as ADCL and ADCH would be locked when it completed.
 
66
        low = ADCL;
 
67
        high = ADCH;
 
68
 
 
69
        // combine the two bytes
 
70
        return (high << 8) | low;
 
71
}
 
72
 
 
73
// Right now, PWM output only works on the pins with
 
74
// hardware support.  These are defined in the appropriate
 
75
// pins_*.c file.  For the rest of the pins, we default
 
76
// to digital output.
 
77
void analogWrite(uint8_t pin, int val)
 
78
{
 
79
        // We need to make sure the PWM output is enabled for those pins
 
80
        // that support it, as we turn it off when digitally reading or
 
81
        // writing with them.  Also, make sure the pin is in output mode
 
82
        // for consistenty with Wiring, which doesn't require a pinMode
 
83
        // call for the analog output pins.
 
84
        pinMode(pin, OUTPUT);
 
85
        
 
86
        if (digitalPinToTimer(pin) == TIMER1A) {
 
87
                // connect pwm to pin on timer 1, channel A
 
88
                sbi(TCCR1A, COM1A1);
 
89
                // set pwm duty
 
90
                OCR1A = val;
 
91
        } else if (digitalPinToTimer(pin) == TIMER1B) {
 
92
                // connect pwm to pin on timer 1, channel B
 
93
                sbi(TCCR1A, COM1B1);
 
94
                // set pwm duty
 
95
                OCR1B = val;
 
96
#if defined(__AVR_ATmega8__)
 
97
        } else if (digitalPinToTimer(pin) == TIMER2) {
 
98
                // connect pwm to pin on timer 2, channel B
 
99
                sbi(TCCR2, COM21);
 
100
                // set pwm duty
 
101
                OCR2 = val;
 
102
#else
 
103
        } else if (digitalPinToTimer(pin) == TIMER0A) {
 
104
                if (val == 0) {
 
105
                        digitalWrite(pin, LOW);
 
106
                } else {
 
107
                        // connect pwm to pin on timer 0, channel A
 
108
                        sbi(TCCR0A, COM0A1);
 
109
                        // set pwm duty
 
110
                        OCR0A = val;      
 
111
                }
 
112
        } else if (digitalPinToTimer(pin) == TIMER0B) {
 
113
                if (val == 0) {
 
114
                        digitalWrite(pin, LOW);
 
115
                } else {
 
116
                        // connect pwm to pin on timer 0, channel B
 
117
                        sbi(TCCR0A, COM0B1);
 
118
                        // set pwm duty
 
119
                        OCR0B = val;
 
120
                }
 
121
        } else if (digitalPinToTimer(pin) == TIMER2A) {
 
122
                // connect pwm to pin on timer 2, channel A
 
123
                sbi(TCCR2A, COM2A1);
 
124
                // set pwm duty
 
125
                OCR2A = val;    
 
126
        } else if (digitalPinToTimer(pin) == TIMER2B) {
 
127
                // connect pwm to pin on timer 2, channel B
 
128
                sbi(TCCR2A, COM2B1);
 
129
                // set pwm duty
 
130
                OCR2B = val;
 
131
#endif
 
132
#if defined(__AVR_ATmega1280__)
 
133
        // XXX: need to handle other timers here
 
134
        } else if (digitalPinToTimer(pin) == TIMER3A) {
 
135
                // connect pwm to pin on timer 3, channel A
 
136
                sbi(TCCR3A, COM3A1);
 
137
                // set pwm duty
 
138
                OCR3A = val;
 
139
        } else if (digitalPinToTimer(pin) == TIMER3B) {
 
140
                // connect pwm to pin on timer 3, channel B
 
141
                sbi(TCCR3A, COM3B1);
 
142
                // set pwm duty
 
143
                OCR3B = val;
 
144
        } else if (digitalPinToTimer(pin) == TIMER3C) {
 
145
                // connect pwm to pin on timer 3, channel C
 
146
                sbi(TCCR3A, COM3C1);
 
147
                // set pwm duty
 
148
                OCR3C = val;
 
149
        } else if (digitalPinToTimer(pin) == TIMER4A) {
 
150
                // connect pwm to pin on timer 4, channel A
 
151
                sbi(TCCR4A, COM4A1);
 
152
                // set pwm duty
 
153
                OCR4A = val;
 
154
        } else if (digitalPinToTimer(pin) == TIMER4B) {
 
155
                // connect pwm to pin on timer 4, channel B
 
156
                sbi(TCCR4A, COM4B1);
 
157
                // set pwm duty
 
158
                OCR4B = val;
 
159
        } else if (digitalPinToTimer(pin) == TIMER4C) {
 
160
                // connect pwm to pin on timer 4, channel C
 
161
                sbi(TCCR4A, COM4C1);
 
162
                // set pwm duty
 
163
                OCR4C = val;
 
164
        } else if (digitalPinToTimer(pin) == TIMER5A) {
 
165
                // connect pwm to pin on timer 5, channel A
 
166
                sbi(TCCR5A, COM5A1);
 
167
                // set pwm duty
 
168
                OCR5A = val;
 
169
        } else if (digitalPinToTimer(pin) == TIMER5B) {
 
170
                // connect pwm to pin on timer 5, channel B
 
171
                sbi(TCCR5A, COM5B1);
 
172
                // set pwm duty
 
173
                OCR5B = val;
 
174
#endif
 
175
        } else if (val < 128)
 
176
                digitalWrite(pin, LOW);
 
177
        else
 
178
                digitalWrite(pin, HIGH);
 
179
}