| 
					
				 | 
			
			
				@@ -0,0 +1,378 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* Arduino DigitalIO Library 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Copyright (C) 2013 by William Greiman 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * This file is part of the Arduino DigitalIO Library 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * This Library is free software: you can redistribute it and/or modify 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * it under the terms of the GNU General Public License as published by 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * the Free Software Foundation, either version 3 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 General Public License for more details. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * You should have received a copy of the GNU General Public License 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * along with the Arduino DigitalIO Library.  If not, see 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <http://www.gnu.org/licenses/>. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @file 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @brief Fast Digital Pin functions 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @defgroup digitalPin Fast Pin I/O 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @details  Fast Digital I/O functions and template class. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifndef DigitalPin_h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define DigitalPin_h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "SystemInclude.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if defined(__AVR__)  || defined(DOXYGEN) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <avr/io.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** GpioPinMap type */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct GpioPinMap_t { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  volatile uint8_t* pin;   /**< address of PIN for this pin */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  volatile uint8_t* ddr;   /**< address of DDR for this pin */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  volatile uint8_t* port;  /**< address of PORT for this pin */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  uint8_t mask;            /**< bit mask for this pin */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Initializer macro. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define GPIO_PIN(reg, bit) {&PIN##reg, &DDR##reg, &PORT##reg, 1 << bit} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Include pin map for current board. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "boards/GpioPinMap.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** generate bad pin number error */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void badPinNumber(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  __attribute__((error("Pin number is too large or not a constant"))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Check for valid pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Number of pin to be checked. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void badPinCheck(uint8_t pin) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!__builtin_constant_p(pin) || pin >= NUM_DIGITAL_PINS) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     badPinNumber(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** DDR register address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Arduino pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @return register address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+volatile uint8_t* ddrReg(uint8_t pin) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  badPinCheck(pin); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return GpioPinMap[pin].ddr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Bit mask for pin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Arduino pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @return mask 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+uint8_t pinMask(uint8_t pin) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  badPinCheck(pin); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return GpioPinMap[pin].mask; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** PIN register address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Arduino pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @return register address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+volatile uint8_t* pinReg(uint8_t pin) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  badPinCheck(pin); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return GpioPinMap[pin].pin; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** PORT register address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Arduino pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @return register address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+volatile uint8_t* portReg(uint8_t pin) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  badPinCheck(pin); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return GpioPinMap[pin].port; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Fast write helper. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] address I/O register address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] mask bit mask for pin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] level value for bit 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void fastBitWriteSafe(volatile uint8_t* address, uint8_t mask, bool level) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  uint8_t s; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (address > reinterpret_cast<uint8_t*>(0X3F)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    s = SREG; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cli(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (level) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    *address |= mask; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    *address &= ~mask; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (address > reinterpret_cast<uint8_t*>(0X3F)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SREG = s; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Read pin value. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Arduino pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @return value read 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool fastDigitalRead(uint8_t pin) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return *pinReg(pin) & pinMask(pin); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Toggle a pin. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Arduino pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * If the pin is in output mode toggle the pin level. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * If the pin is in input mode toggle the state of the 20K pullup. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void fastDigitalToggle(uint8_t pin) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (pinReg(pin) > reinterpret_cast<uint8_t*>(0X3F)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // must write bit to high address port 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      *pinReg(pin) = pinMask(pin); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // will compile to sbi and PIN register will not be read. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      *pinReg(pin) |= pinMask(pin); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Set pin value. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Arduino pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] level value to write 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void fastDigitalWrite(uint8_t pin, bool level) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  fastBitWriteSafe(portReg(pin), pinMask(pin), level); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Write the DDR register. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Arduino pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] level value to write 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void fastDdrWrite(uint8_t pin, bool level) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  fastBitWriteSafe(ddrReg(pin), pinMask(pin), level); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Set pin mode. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Arduino pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] mode INPUT, OUTPUT, or INPUT_PULLUP. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * The internal pullup resistors will be enabled if mode is INPUT_PULLUP 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * and disabled if the mode is INPUT. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void fastPinMode(uint8_t pin, uint8_t mode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  fastDdrWrite(pin, mode == OUTPUT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (mode != OUTPUT) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fastDigitalWrite(pin, mode == INPUT_PULLUP); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#else  // defined(__AVR__) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if defined(CORE_TEENSY) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** read pin value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Arduino pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @return value read 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool fastDigitalRead(uint8_t pin) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return *portInputRegister(pin); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Set pin value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Arduino pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] level value to write 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void fastDigitalWrite(uint8_t pin, bool value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    *portSetRegister(pin) = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    *portClearRegister(pin) = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#elif defined(__SAM3X8E__) || defined(__SAM3X8H__) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** read pin value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Arduino pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @return value read 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool fastDigitalRead(uint8_t pin) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return g_APinDescription[pin].pPort->PIO_PDSR & g_APinDescription[pin].ulPin; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Set pin value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Arduino pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] level value to write 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void fastDigitalWrite(uint8_t pin, bool value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    g_APinDescription[pin].pPort->PIO_SODR = g_APinDescription[pin].ulPin; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    g_APinDescription[pin].pPort->PIO_CODR = g_APinDescription[pin].ulPin; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#elif defined(ESP8266) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Set pin value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Arduino pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] val value to write 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void fastDigitalWrite(uint8_t pin, uint8_t val) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (pin < 16) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (val) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      GPOS = (1 << pin); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      GPOC = (1 << pin); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else if (pin == 16) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (val) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      GP16O |= 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      GP16O &= ~1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Read pin value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Arduino pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @return value read 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool fastDigitalRead(uint8_t pin) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (pin < 16) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return GPIP(pin); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else if (pin == 16) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return GP16I & 0x01; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#else  // CORE_TEENSY 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+inline void fastDigitalWrite(uint8_t pin, bool value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  digitalWrite(pin, value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+inline bool fastDigitalRead(uint8_t pin) {return digitalRead(pin);} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif  // CORE_TEENSY 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+inline void fastDigitalToggle(uint8_t pin) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  fastDigitalWrite(pin, !fastDigitalRead(pin)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define fastPinMode(pin, mode) pinMode(pin, mode) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif  // __AVR__ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//------------------------------------------------------------------------------ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** set pin configuration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] pin Arduino pin number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] mode mode INPUT or OUTPUT. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param[in] level If mode is output, set level high/low. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *                  If mode is input, enable or disable the pin's 20K pullup. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define fastPinConfig(pin, mode, level)\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  {fastPinMode(pin, mode); fastDigitalWrite(pin, level);} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//============================================================================== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @class DigitalPin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @brief Fast digital port I/O 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<uint8_t PinNumber> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class DigitalPin { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //---------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /** Constructor */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  DigitalPin() {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //---------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /** Asignment operator. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * @param[in] value If true set the pin's level high else set the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *  pin's level low. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * @return This DigitalPin instance. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  inline DigitalPin & operator = (bool value) __attribute__((always_inline)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    write(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return *this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //---------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /** Parenthesis operator. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * @return Pin's level 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  inline operator bool () const __attribute__((always_inline)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return read(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //---------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /** Set pin configuration. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * @param[in] mode: INPUT or OUTPUT. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * @param[in] level If mode is OUTPUT, set level high/low. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *                  If mode is INPUT, enable or disable the pin's 20K pullup. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  void config(uint8_t mode, bool level) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fastPinConfig(PinNumber, mode, level); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //---------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * Set pin level high if output mode or enable 20K pullup if input mode. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  void high() {write(true);} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //---------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * Set pin level low if output mode or disable 20K pullup if input mode. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  void low() {write(false);} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //---------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * Set pin mode. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * @param[in] mode: INPUT, OUTPUT, or INPUT_PULLUP. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * The internal pullup resistors will be enabled if mode is INPUT_PULLUP 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * and disabled if the mode is INPUT. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  void mode(uint8_t mode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fastPinMode(PinNumber, mode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //---------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /** @return Pin's level. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  bool read() const { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return fastDigitalRead(PinNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //---------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /** Toggle a pin. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * If the pin is in output mode toggle the pin's level. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * If the pin is in input mode toggle the state of the 20K pullup. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  void toggle() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fastDigitalToggle(PinNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //---------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /** Write the pin's level. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * @param[in] value If true set the pin's level high else set the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *  pin's level low. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  inline __attribute__((always_inline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  void write(bool value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fastDigitalWrite(PinNumber, value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif  // DigitalPin_h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** @} */ 
			 |