root / arduino-1.0 / hardware / arduino / cores / arduino / wiring_digital.c @ 58d82c77
History | View | Annotate | Download (4.52 KB)
1 |
/*
|
---|---|
2 |
wiring_digital.c - digital input and output functions
|
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 |
#define ARDUINO_MAIN
|
28 |
#include "wiring_private.h" |
29 |
#include "pins_arduino.h" |
30 |
|
31 |
void pinMode(uint8_t pin, uint8_t mode)
|
32 |
{ |
33 |
uint8_t bit = digitalPinToBitMask(pin); |
34 |
uint8_t port = digitalPinToPort(pin); |
35 |
volatile uint8_t *reg;
|
36 |
|
37 |
if (port == NOT_A_PIN) return; |
38 |
|
39 |
// JWS: can I let the optimizer do this?
|
40 |
reg = portModeRegister(port); |
41 |
|
42 |
if (mode == INPUT) {
|
43 |
uint8_t oldSREG = SREG; |
44 |
cli(); |
45 |
*reg &= ~bit; |
46 |
SREG = oldSREG; |
47 |
} else {
|
48 |
uint8_t oldSREG = SREG; |
49 |
cli(); |
50 |
*reg |= bit; |
51 |
SREG = oldSREG; |
52 |
} |
53 |
} |
54 |
|
55 |
// Forcing this inline keeps the callers from having to push their own stuff
|
56 |
// on the stack. It is a good performance win and only takes 1 more byte per
|
57 |
// user than calling. (It will take more bytes on the 168.)
|
58 |
//
|
59 |
// But shouldn't this be moved into pinMode? Seems silly to check and do on
|
60 |
// each digitalread or write.
|
61 |
//
|
62 |
// Mark Sproul:
|
63 |
// - Removed inline. Save 170 bytes on atmega1280
|
64 |
// - changed to a switch statment; added 32 bytes but much easier to read and maintain.
|
65 |
// - Added more #ifdefs, now compiles for atmega645
|
66 |
//
|
67 |
//static inline void turnOffPWM(uint8_t timer) __attribute__ ((always_inline));
|
68 |
//static inline void turnOffPWM(uint8_t timer)
|
69 |
static void turnOffPWM(uint8_t timer) |
70 |
{ |
71 |
switch (timer)
|
72 |
{ |
73 |
#if defined(TCCR1A) && defined(COM1A1)
|
74 |
case TIMER1A: cbi(TCCR1A, COM1A1); break; |
75 |
#endif
|
76 |
#if defined(TCCR1A) && defined(COM1B1)
|
77 |
case TIMER1B: cbi(TCCR1A, COM1B1); break; |
78 |
#endif
|
79 |
|
80 |
#if defined(TCCR2) && defined(COM21)
|
81 |
case TIMER2: cbi(TCCR2, COM21); break; |
82 |
#endif
|
83 |
|
84 |
#if defined(TCCR0A) && defined(COM0A1)
|
85 |
case TIMER0A: cbi(TCCR0A, COM0A1); break; |
86 |
#endif
|
87 |
|
88 |
#if defined(TIMER0B) && defined(COM0B1)
|
89 |
case TIMER0B: cbi(TCCR0A, COM0B1); break; |
90 |
#endif
|
91 |
#if defined(TCCR2A) && defined(COM2A1)
|
92 |
case TIMER2A: cbi(TCCR2A, COM2A1); break; |
93 |
#endif
|
94 |
#if defined(TCCR2A) && defined(COM2B1)
|
95 |
case TIMER2B: cbi(TCCR2A, COM2B1); break; |
96 |
#endif
|
97 |
|
98 |
#if defined(TCCR3A) && defined(COM3A1)
|
99 |
case TIMER3A: cbi(TCCR3A, COM3A1); break; |
100 |
#endif
|
101 |
#if defined(TCCR3A) && defined(COM3B1)
|
102 |
case TIMER3B: cbi(TCCR3A, COM3B1); break; |
103 |
#endif
|
104 |
#if defined(TCCR3A) && defined(COM3C1)
|
105 |
case TIMER3C: cbi(TCCR3A, COM3C1); break; |
106 |
#endif
|
107 |
|
108 |
#if defined(TCCR4A) && defined(COM4A1)
|
109 |
case TIMER4A: cbi(TCCR4A, COM4A1); break; |
110 |
#endif
|
111 |
#if defined(TCCR4A) && defined(COM4B1)
|
112 |
case TIMER4B: cbi(TCCR4A, COM4B1); break; |
113 |
#endif
|
114 |
#if defined(TCCR4A) && defined(COM4C1)
|
115 |
case TIMER4C: cbi(TCCR4A, COM4C1); break; |
116 |
#endif
|
117 |
#if defined(TCCR5A)
|
118 |
case TIMER5A: cbi(TCCR5A, COM5A1); break; |
119 |
case TIMER5B: cbi(TCCR5A, COM5B1); break; |
120 |
case TIMER5C: cbi(TCCR5A, COM5C1); break; |
121 |
#endif
|
122 |
} |
123 |
} |
124 |
|
125 |
void digitalWrite(uint8_t pin, uint8_t val)
|
126 |
{ |
127 |
uint8_t timer = digitalPinToTimer(pin); |
128 |
uint8_t bit = digitalPinToBitMask(pin); |
129 |
uint8_t port = digitalPinToPort(pin); |
130 |
volatile uint8_t *out;
|
131 |
|
132 |
if (port == NOT_A_PIN) return; |
133 |
|
134 |
// If the pin that support PWM output, we need to turn it off
|
135 |
// before doing a digital write.
|
136 |
if (timer != NOT_ON_TIMER) turnOffPWM(timer);
|
137 |
|
138 |
out = portOutputRegister(port); |
139 |
|
140 |
uint8_t oldSREG = SREG; |
141 |
cli(); |
142 |
|
143 |
if (val == LOW) {
|
144 |
*out &= ~bit; |
145 |
} else {
|
146 |
*out |= bit; |
147 |
} |
148 |
|
149 |
SREG = oldSREG; |
150 |
} |
151 |
|
152 |
int digitalRead(uint8_t pin)
|
153 |
{ |
154 |
uint8_t timer = digitalPinToTimer(pin); |
155 |
uint8_t bit = digitalPinToBitMask(pin); |
156 |
uint8_t port = digitalPinToPort(pin); |
157 |
|
158 |
if (port == NOT_A_PIN) return LOW; |
159 |
|
160 |
// If the pin that support PWM output, we need to turn it off
|
161 |
// before getting a digital reading.
|
162 |
if (timer != NOT_ON_TIMER) turnOffPWM(timer);
|
163 |
|
164 |
if (*portInputRegister(port) & bit) return HIGH; |
165 |
return LOW;
|
166 |
} |