Statistics
| Branch: | Revision:

root / arduino-1.0 / hardware / arduino / cores / arduino / wiring_analog.c @ 58d82c77

History | View | Annotate | Download (6.95 KB)

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
  Modified 28 September 2010 by Mark Sproul
23

24
  $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
25
*/
26

    
27
#include "wiring_private.h"
28
#include "pins_arduino.h"
29

    
30
uint8_t analog_reference = DEFAULT;
31

    
32
void analogReference(uint8_t mode)
33
{
34
        // can't actually set the register here because the default setting
35
        // will connect AVCC and the AREF pin, which would cause a short if
36
        // there's something connected to AREF.
37
        analog_reference = mode;
38
}
39

    
40
int analogRead(uint8_t pin)
41
{
42
        uint8_t low, high;
43

    
44
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
45
        if (pin >= 54) pin -= 54; // allow for channel or pin numbers
46
#elif defined(__AVR_ATmega32U4__)
47
        if (pin >= 18) pin -= 18; // allow for channel or pin numbers
48
#else
49
        if (pin >= 14) pin -= 14; // allow for channel or pin numbers
50
#endif
51
        
52
#if defined(__AVR_ATmega32U4__)
53
        pin = analogPinToChannel(pin);
54
        ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
55
#elif defined(ADCSRB) && defined(MUX5)
56
        // the MUX5 bit of ADCSRB selects whether we're reading from channels
57
        // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
58
        ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
59
#endif
60
  
61
        // set the analog reference (high two bits of ADMUX) and select the
62
        // channel (low 4 bits).  this also sets ADLAR (left-adjust result)
63
        // to 0 (the default).
64
#if defined(ADMUX)
65
        ADMUX = (analog_reference << 6) | (pin & 0x07);
66
#endif
67

    
68
        // without a delay, we seem to read from the wrong channel
69
        //delay(1);
70

    
71
#if defined(ADCSRA) && defined(ADCL)
72
        // start the conversion
73
        sbi(ADCSRA, ADSC);
74

    
75
        // ADSC is cleared when the conversion finishes
76
        while (bit_is_set(ADCSRA, ADSC));
77

    
78
        // we have to read ADCL first; doing so locks both ADCL
79
        // and ADCH until ADCH is read.  reading ADCL second would
80
        // cause the results of each conversion to be discarded,
81
        // as ADCL and ADCH would be locked when it completed.
82
        low  = ADCL;
83
        high = ADCH;
84
#else
85
        // we dont have an ADC, return 0
86
        low  = 0;
87
        high = 0;
88
#endif
89

    
90
        // combine the two bytes
91
        return (high << 8) | low;
92
}
93

    
94
// Right now, PWM output only works on the pins with
95
// hardware support.  These are defined in the appropriate
96
// pins_*.c file.  For the rest of the pins, we default
97
// to digital output.
98
void analogWrite(uint8_t pin, int val)
99
{
100
        // We need to make sure the PWM output is enabled for those pins
101
        // that support it, as we turn it off when digitally reading or
102
        // writing with them.  Also, make sure the pin is in output mode
103
        // for consistenty with Wiring, which doesn't require a pinMode
104
        // call for the analog output pins.
105
        pinMode(pin, OUTPUT);
106
        if (val == 0)
107
        {
108
                digitalWrite(pin, LOW);
109
        }
110
        else if (val == 255)
111
        {
112
                digitalWrite(pin, HIGH);
113
        }
114
        else
115
        {
116
                switch(digitalPinToTimer(pin))
117
                {
118
                        // XXX fix needed for atmega8
119
                        #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__)
120
                        case TIMER0A:
121
                                // connect pwm to pin on timer 0
122
                                sbi(TCCR0, COM00);
123
                                OCR0 = val; // set pwm duty
124
                                break;
125
                        #endif
126

    
127
                        #if defined(TCCR0A) && defined(COM0A1)
128
                        case TIMER0A:
129
                                // connect pwm to pin on timer 0, channel A
130
                                sbi(TCCR0A, COM0A1);
131
                                OCR0A = val; // set pwm duty
132
                                break;
133
                        #endif
134

    
135
                        #if defined(TCCR0A) && defined(COM0B1)
136
                        case TIMER0B:
137
                                // connect pwm to pin on timer 0, channel B
138
                                sbi(TCCR0A, COM0B1);
139
                                OCR0B = val; // set pwm duty
140
                                break;
141
                        #endif
142

    
143
                        #if defined(TCCR1A) && defined(COM1A1)
144
                        case TIMER1A:
145
                                // connect pwm to pin on timer 1, channel A
146
                                sbi(TCCR1A, COM1A1);
147
                                OCR1A = val; // set pwm duty
148
                                break;
149
                        #endif
150

    
151
                        #if defined(TCCR1A) && defined(COM1B1)
152
                        case TIMER1B:
153
                                // connect pwm to pin on timer 1, channel B
154
                                sbi(TCCR1A, COM1B1);
155
                                OCR1B = val; // set pwm duty
156
                                break;
157
                        #endif
158

    
159
                        #if defined(TCCR2) && defined(COM21)
160
                        case TIMER2:
161
                                // connect pwm to pin on timer 2
162
                                sbi(TCCR2, COM21);
163
                                OCR2 = val; // set pwm duty
164
                                break;
165
                        #endif
166

    
167
                        #if defined(TCCR2A) && defined(COM2A1)
168
                        case TIMER2A:
169
                                // connect pwm to pin on timer 2, channel A
170
                                sbi(TCCR2A, COM2A1);
171
                                OCR2A = val; // set pwm duty
172
                                break;
173
                        #endif
174

    
175
                        #if defined(TCCR2A) && defined(COM2B1)
176
                        case TIMER2B:
177
                                // connect pwm to pin on timer 2, channel B
178
                                sbi(TCCR2A, COM2B1);
179
                                OCR2B = val; // set pwm duty
180
                                break;
181
                        #endif
182

    
183
                        #if defined(TCCR3A) && defined(COM3A1)
184
                        case TIMER3A:
185
                                // connect pwm to pin on timer 3, channel A
186
                                sbi(TCCR3A, COM3A1);
187
                                OCR3A = val; // set pwm duty
188
                                break;
189
                        #endif
190

    
191
                        #if defined(TCCR3A) && defined(COM3B1)
192
                        case TIMER3B:
193
                                // connect pwm to pin on timer 3, channel B
194
                                sbi(TCCR3A, COM3B1);
195
                                OCR3B = val; // set pwm duty
196
                                break;
197
                        #endif
198

    
199
                        #if defined(TCCR3A) && defined(COM3C1)
200
                        case TIMER3C:
201
                                // connect pwm to pin on timer 3, channel C
202
                                sbi(TCCR3A, COM3C1);
203
                                OCR3C = val; // set pwm duty
204
                                break;
205
                        #endif
206

    
207
                        #if defined(TCCR4A) && defined(COM4A1)
208
                        case TIMER4A:
209
                                // connect pwm to pin on timer 4, channel A
210
                                sbi(TCCR4A, COM4A1);
211
                                OCR4A = val; // set pwm duty
212
                                break;
213
                        #endif
214

    
215
                        #if defined(TCCR4A) && defined(COM4B1)
216
                        case TIMER4B:
217
                                // connect pwm to pin on timer 4, channel B
218
                                sbi(TCCR4A, COM4B1);
219
                                OCR4B = val; // set pwm duty
220
                                break;
221
                        #endif
222

    
223
                        #if defined(TCCR4A) && defined(COM4C1)
224
                        case TIMER4C:
225
                                // connect pwm to pin on timer 4, channel C
226
                                sbi(TCCR4A, COM4C1);
227
                                OCR4C = val; // set pwm duty
228
                                break;
229
                        #endif
230
                                
231
                        #if defined(TCCR4A) && defined(COM4D1)
232
                        case TIMER4D:
233
                                // connect pwm to pin on timer 4, channel D
234
                                sbi(TCCR4A, COM4D1);
235
                                OCR4D = val; // set pwm duty
236
                                break;
237
                        #endif
238

    
239
                        #if defined(TCCR5A) && defined(COM5A1)
240
                        case TIMER5A:
241
                                // connect pwm to pin on timer 5, channel A
242
                                sbi(TCCR5A, COM5A1);
243
                                OCR5A = val; // set pwm duty
244
                                break;
245
                        #endif
246

    
247
                        #if defined(TCCR5A) && defined(COM5B1)
248
                        case TIMER5B:
249
                                // connect pwm to pin on timer 5, channel B
250
                                sbi(TCCR5A, COM5B1);
251
                                OCR5B = val; // set pwm duty
252
                                break;
253
                        #endif
254

    
255
                        #if defined(TCCR5A) && defined(COM5C1)
256
                        case TIMER5C:
257
                                // connect pwm to pin on timer 5, channel C
258
                                sbi(TCCR5A, COM5C1);
259
                                OCR5C = val; // set pwm duty
260
                                break;
261
                        #endif
262

    
263
                        case NOT_ON_TIMER:
264
                        default:
265
                                if (val < 128) {
266
                                        digitalWrite(pin, LOW);
267
                                } else {
268
                                        digitalWrite(pin, HIGH);
269
                                }
270
                }
271
        }
272
}