aboutsummaryrefslogtreecommitdiff
path: root/cores/arduino
diff options
context:
space:
mode:
authorDavid A. Mellis <d.mellis@arduino.cc>2011-03-02 23:05:25 -0500
committerDavid A. Mellis <d.mellis@arduino.cc>2011-03-02 23:05:25 -0500
commitd7a87f18f06481f2ca3c342dfdd1268d934ecedb (patch)
treec6281a08db8943ba157257abfc095312144075cf /cores/arduino
parent218eb5e80706b53c691da133461830c895e0c8ff (diff)
Re-arranging header files and small fixes to optimized core functions.
Diffstat (limited to 'cores/arduino')
-rwxr-xr-xcores/arduino/Arduino.h70
-rw-r--r--cores/arduino/WConstants.h1
-rwxr-xr-xcores/arduino/WInterrupts.c1
-rw-r--r--cores/arduino/pins_arduino.h51
-rwxr-xr-xcores/arduino/wiring.h29
5 files changed, 69 insertions, 83 deletions
diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h
index 213f623..d4c1c46 100755
--- a/cores/arduino/Arduino.h
+++ b/cores/arduino/Arduino.h
@@ -112,6 +112,53 @@ void detachInterrupt(uint8_t);
void setup(void);
void loop(void);
+// Get the bit location within the hardware port of the given virtual pin.
+// This comes from the pins_*.c file for the active board configuration.
+
+#define analogInPinToBit(P) (P)
+
+INLINED uint8_t digitalPinToPort(uint8_t pin) {
+ if (__builtin_constant_p(pin))
+ return inlined_digitalPinToPort(pin);
+ else
+ return pgm_read_byte( digital_pin_to_port_PGM + pin );
+}
+
+INLINED uint8_t digitalPinToBitMask(uint8_t pin) {
+ if (__builtin_constant_p(pin))
+ return inlined_digitalPinToBitMask(pin);
+ else
+ return pgm_read_byte( digital_pin_to_bit_mask_PGM + pin );
+}
+
+INLINED uint8_t digitalPinToTimer(uint8_t pin) {
+ if (__builtin_constant_p(pin))
+ return inlined_digitalPinToTimer(pin);
+ else
+ return pgm_read_byte( digital_pin_to_timer_PGM + pin );
+}
+
+INLINED volatile uint8_t *portOutputRegister(uint8_t index) {
+ if (__builtin_constant_p(index))
+ return inlined_portOutputRegister(index);
+ else
+ return (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + index ) );
+}
+
+INLINED volatile uint8_t* portInputRegister(uint8_t index) {
+ if (__builtin_constant_p(index))
+ return inlined_portInputRegister(index);
+ else
+ return (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + index) );
+}
+
+INLINED volatile uint8_t* portModeRegister(uint8_t index) {
+ if (__builtin_constant_p(index))
+ return inlined_portModeRegister(index);
+ else
+ return (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + index) );
+}
+
/*
* Check if a given pin requires locking.
* When accessing lower 32 IO ports we can use SBI/CBI instructions, which are atomic. However
@@ -127,6 +174,15 @@ INLINED int portWriteNeedsLocking(uint8_t pin)
return 0;
}
+INLINED int portModeNeedsLocking(uint8_t pin)
+{
+ /* SBI/CBI instructions only work on lower 32 IO ports */
+ if (inlined_portModeRegister(inlined_digitalPinToPort(pin)) > (volatile uint8_t*)&_SFR_IO8(0x1F)) {
+ return 1;
+ }
+ return 0;
+}
+
/*
* These functions will perform OR/AND on a given register, and are atomic.
*/
@@ -157,10 +213,18 @@ INLINED void digitalWrite(uint8_t pin, uint8_t value)
INLINED void pinMode(uint8_t pin, uint8_t mode)
{
if (__builtin_constant_p(pin)) {
- if (mode==INPUT) {
- *inlined_portModeRegister(inlined_digitalPinToPort(pin)) &= ~(inlined_digitalPinToBitMask(pin));
+ if (portModeNeedsLocking(pin)) {
+ if (mode==INPUT) {
+ __digitalWriteAND_locked(inlined_portModeRegister(inlined_digitalPinToPort(pin)),~inlined_digitalPinToBitMask(pin));
+ } else {
+ __digitalWriteOR_locked(inlined_portModeRegister(inlined_digitalPinToPort(pin)),inlined_digitalPinToBitMask(pin));
+ }
} else {
- *inlined_portModeRegister(inlined_digitalPinToPort(pin)) |= inlined_digitalPinToBitMask(pin);
+ if (mode==INPUT) {
+ *inlined_portModeRegister(inlined_digitalPinToPort(pin)) &= ~(inlined_digitalPinToBitMask(pin));
+ } else {
+ *inlined_portModeRegister(inlined_digitalPinToPort(pin)) |= inlined_digitalPinToBitMask(pin);
+ }
}
} else {
pinMode_lookup(pin,mode);
diff --git a/cores/arduino/WConstants.h b/cores/arduino/WConstants.h
deleted file mode 100644
index 3e19ac4..0000000
--- a/cores/arduino/WConstants.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "wiring.h"
diff --git a/cores/arduino/WInterrupts.c b/cores/arduino/WInterrupts.c
index 3b3e0c9..75c713b 100755
--- a/cores/arduino/WInterrupts.c
+++ b/cores/arduino/WInterrupts.c
@@ -30,7 +30,6 @@
#include <avr/pgmspace.h>
#include <stdio.h>
-#include "WConstants.h"
#include "wiring_private.h"
volatile static voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];
diff --git a/cores/arduino/pins_arduino.h b/cores/arduino/pins_arduino.h
index f48d5bc..e9d3fc7 100644
--- a/cores/arduino/pins_arduino.h
+++ b/cores/arduino/pins_arduino.h
@@ -385,7 +385,7 @@ INLINED uint8_t inlined_digitalPinToTimer(uint8_t pin)
case 44: return TIMER5C; // PL 5 ** 44 ** D44
case 45: return TIMER5B; // PL 4 ** 45 ** D45
case 46: return TIMER5A; // PL 3 ** 46 ** D46
- default: invalidPinSpecified();
+ default: return NOT_ON_TIMER;
}
}
@@ -494,57 +494,10 @@ INLINED uint8_t inlined_digitalPinToTimer(uint8_t pin)
#endif
case 9: return TIMER1A;
case 10: return TIMER1B;
- default: invalidPinSpecified();
+ default: return NOT_ON_TIMER;
}
}
#endif // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
-// Get the bit location within the hardware port of the given virtual pin.
-// This comes from the pins_*.c file for the active board configuration.
-
-#define analogInPinToBit(P) (P)
-
-INLINED uint8_t digitalPinToPort(uint8_t pin) {
- if (__builtin_constant_p(pin))
- return inlined_digitalPinToPort(pin);
- else
- return pgm_read_byte( digital_pin_to_port_PGM + pin );
-}
-
-INLINED uint8_t digitalPinToBitMask(uint8_t pin) {
- if (__builtin_constant_p(pin))
- return inlined_digitalPinToBitMask(pin);
- else
- return pgm_read_byte( digital_pin_to_bit_mask_PGM + pin );
-}
-
-INLINED uint8_t digitalPinToTimer(uint8_t pin) {
- if (__builtin_constant_p(pin))
- return inlined_digitalPinToTimer(pin);
- else
- return pgm_read_byte( digital_pin_to_timer_PGM + pin );
-}
-
-INLINED volatile uint8_t *portOutputRegister(uint8_t index) {
- if (__builtin_constant_p(index))
- return inlined_portOutputRegister(index);
- else
- return (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + index ) );
-}
-
-INLINED volatile uint8_t* portInputRegister(uint8_t index) {
- if (__builtin_constant_p(index))
- return inlined_portInputRegister(index);
- else
- return (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + index) );
-}
-
-INLINED volatile uint8_t* portModeRegister(uint8_t index) {
- if (__builtin_constant_p(index))
- return inlined_portModeRegister(index);
- else
- return (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + index) );
-}
-
#endif
diff --git a/cores/arduino/wiring.h b/cores/arduino/wiring.h
deleted file mode 100755
index b8a44ae..0000000
--- a/cores/arduino/wiring.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- wiring.h - Partial implementation of the Wiring API for the ATmega8.
- Part of Arduino - http://www.arduino.cc/
-
- Copyright (c) 2005-2006 David A. Mellis
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General
- Public License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- Boston, MA 02111-1307 USA
-
- $Id$
-*/
-
-#ifndef Wiring_h
-#define Wiring_h
-
-
-#endif