Statistics
| Branch: | Revision:

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
}