root / arduino-1.0 / hardware / arduino / cores / arduino / wiring_digital.c @ 58d82c77
History | View | Annotate | Download (4.52 KB)
1 | 58d82c77 | Tom Mullins | /*
|
---|---|---|---|
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 | } |