Bladeren bron

Support non-AVR boards

PaulStoffregen 11 jaren geleden
bovenliggende
commit
34c087341c
2 gewijzigde bestanden met toevoegingen van 86 en 37 verwijderingen
  1. 29 30
      CapacitiveSensor.cpp
  2. 57 7
      CapacitiveSensor.h

+ 29 - 30
CapacitiveSensor.cpp

@@ -1,6 +1,7 @@
 /*
  CapacitiveSense.h v.04 - Capacitive Sensing Library for 'duino / Wiring
  Copyright (c) 2009 Paul Bagder  All right reserved.
+ Version 05 by Paul Stoffregen - Support Teensy 3.0, 3.1
  Version 04 by Paul Stoffregen - Arduino 1.0 compatibility, issue 146 fix
  vim: set ts=4:
  */
@@ -20,8 +21,6 @@
 
 CapacitiveSensor::CapacitiveSensor(uint8_t sendPin, uint8_t receivePin)
 {
-	uint8_t sPort, rPort;
-
 	// initialize this instance's variables
 	// Serial.begin(9600);		// for debugging
 	error = 1;
@@ -42,17 +41,13 @@ CapacitiveSensor::CapacitiveSensor(uint8_t sendPin, uint8_t receivePin)
 
 	pinMode(sendPin, OUTPUT);						// sendpin to OUTPUT
 	pinMode(receivePin, INPUT);						// receivePin to INPUT
+	digitalWrite(sendPin, LOW);
 
 	sBit =  digitalPinToBitMask(sendPin);			// get send pin's ports and bitmask
-	sPort = digitalPinToPort(sendPin);
-	sReg = portModeRegister(sPort);
-	sOut = portOutputRegister(sPort);				// get pointer to output register
+	sReg = PIN_TO_BASEREG(sendPin);					// get pointer to output register
 
 	rBit = digitalPinToBitMask(receivePin);			// get receive pin's ports and bitmask
-	rPort = digitalPinToPort(receivePin);
-	rReg = portModeRegister(rPort);
-	rIn  = portInputRegister(rPort);
-   	rOut = portOutputRegister(rPort);
+	rReg = PIN_TO_BASEREG(receivePin);
 
 	// get pin mapping and port for receive Pin - from digital pin functions in Wiring.c
 	leastTotal = 0x0FFFFFFFL;   // input large value for autocalibrate begin
@@ -139,22 +134,20 @@ void CapacitiveSensor::set_CS_Timeout_Millis(unsigned long timeout_millis){
 int CapacitiveSensor::SenseOneCycle(void)
 {
     noInterrupts();
-	*sOut &= ~sBit;        // sendPin Register low
-
-	*rReg &= ~rBit;        // receivePin to input
-	*rOut &= ~rBit;        // receivePin Register low to make sure pullups are off
-
-	*rReg |= rBit;         // receivePin to OUTPUT - pin is now LOW AND OUTPUT
-	*rReg &= ~rBit;        // receivePin to INPUT
-
-	*sOut |= sBit;         // sendPin High
+	DIRECT_WRITE_LOW(sReg, sBit);	// sendPin Register low
+	DIRECT_MODE_INPUT(rReg, rBit);	// receivePin to input (pullups are off)
+	DIRECT_MODE_OUTPUT(rReg, rBit); // receivePin to OUTPUT
+	DIRECT_WRITE_LOW(rReg, rBit);	// pin is now LOW AND OUTPUT
+	delayMicroseconds(10);
+	DIRECT_MODE_INPUT(rReg, rBit);	// receivePin to input (pullups are off)
+	DIRECT_WRITE_HIGH(sReg, sBit);	// sendPin High
     interrupts();
 
-	while ( !(*rIn & rBit)  && (total < CS_Timeout_Millis) ) {  // while receive pin is LOW AND total is positive value
+	while ( !DIRECT_READ(rReg, rBit) && (total < CS_Timeout_Millis) ) {  // while receive pin is LOW AND total is positive value
 		total++;
 	}
-	Serial.print("SenseOneCycle(1): ");
-	Serial.println(total);
+	//Serial.print("SenseOneCycle(1): ");
+	//Serial.println(total);
 
 	if (total > CS_Timeout_Millis) {
 		return -2;         //  total variable over timeout
@@ -162,19 +155,25 @@ int CapacitiveSensor::SenseOneCycle(void)
 
 	// set receive pin HIGH briefly to charge up fully - because the while loop above will exit when pin is ~ 2.5V
     noInterrupts();
-	*rOut  |= rBit;        // receivePin - turns on pullup
-	*rReg |= rBit;         // receivePin to OUTPUT - pin is now HIGH AND OUTPUT
-	*rReg &= ~rBit;        // receivePin to INPUT
-	*rOut  &= ~rBit;       // receivePin turn off pullup
-
-	*sOut &= ~sBit;        // sendPin LOW
+	DIRECT_WRITE_HIGH(rReg, rBit);
+	DIRECT_MODE_OUTPUT(rReg, rBit);  // receivePin to OUTPUT - pin is now HIGH AND OUTPUT
+	DIRECT_WRITE_HIGH(rReg, rBit);
+	DIRECT_MODE_INPUT(rReg, rBit);	// receivePin to INPUT (pullup is off)
+	DIRECT_WRITE_LOW(sReg, sBit);	// sendPin LOW
     interrupts();
 
-	while ( (*rIn & rBit) && (total < CS_Timeout_Millis) ) {  // while receive pin is HIGH  AND total is less than timeout
+#ifdef FIVE_VOLT_TOLERANCE_WORKAROUND
+	DIRECT_MODE_OUTPUT(rReg, rBit);
+	DIRECT_WRITE_LOW(rReg, rBit);
+	delayMicroseconds(10);
+	DIRECT_MODE_INPUT(rReg, rBit);	// receivePin to INPUT (pullup is off)
+#else
+	while ( DIRECT_READ(rReg, rBit) && (total < CS_Timeout_Millis) ) {  // while receive pin is HIGH  AND total is less than timeout
 		total++;
 	}
-	Serial.print("SenseOneCycle(2): ");
-	Serial.println(total);
+#endif
+	//Serial.print("SenseOneCycle(2): ");
+	//Serial.println(total);
 
 	if (total >= CS_Timeout_Millis) {
 		return -2;     // total variable over timeout

+ 57 - 7
CapacitiveSensor.h

@@ -15,6 +15,59 @@
 #include "WProgram.h"
 #endif
 
+// Direct I/O through registers and bitmask (from OneWire library)
+
+#if defined(__AVR__)
+#define PIN_TO_BASEREG(pin)             (portInputRegister(digitalPinToPort(pin)))
+#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
+#define IO_REG_TYPE uint8_t
+#define DIRECT_READ(base, mask)         (((*(base)) & (mask)) ? 1 : 0)
+#define DIRECT_MODE_INPUT(base, mask)   ((*((base)+1)) &= ~(mask), (*((base)+2)) &= ~(mask))
+#define DIRECT_MODE_OUTPUT(base, mask)  ((*((base)+1)) |= (mask))
+#define DIRECT_WRITE_LOW(base, mask)    ((*((base)+2)) &= ~(mask))
+#define DIRECT_WRITE_HIGH(base, mask)   ((*((base)+2)) |= (mask))
+
+#elif defined(__MK20DX128__) || defined(__MK20DX256__)
+#define PIN_TO_BASEREG(pin)             (portOutputRegister(pin))
+#define PIN_TO_BITMASK(pin)             (1)
+#define IO_REG_TYPE uint8_t
+#define IO_REG_ASM
+#define DIRECT_READ(base, mask)         (*((base)+512))
+#define DIRECT_MODE_INPUT(base, mask)   (*((base)+640) = 0)
+#define DIRECT_MODE_OUTPUT(base, mask)  (*((base)+640) = 1)
+#define DIRECT_WRITE_LOW(base, mask)    (*((base)+256) = 1)
+#define DIRECT_WRITE_HIGH(base, mask)   (*((base)+128) = 1)
+
+#elif defined(__SAM3X8E__)
+#define PIN_TO_BASEREG(pin)             (&(digitalPinToPort(pin)->PIO_PER))
+#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
+#define IO_REG_TYPE uint32_t
+#define IO_REG_ASM
+#define DIRECT_READ(base, mask)         (((*((base)+15)) & (mask)) ? 1 : 0)
+#define DIRECT_MODE_INPUT(base, mask)   ((*((base)+5)) = (mask))
+#define DIRECT_MODE_OUTPUT(base, mask)  ((*((base)+4)) = (mask))
+#define DIRECT_WRITE_LOW(base, mask)    ((*((base)+13)) = (mask))
+#define DIRECT_WRITE_HIGH(base, mask)   ((*((base)+12)) = (mask))
+
+#elif defined(__PIC32MX__)
+#define PIN_TO_BASEREG(pin)             (portModeRegister(digitalPinToPort(pin)))
+#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
+#define IO_REG_TYPE uint32_t
+#define IO_REG_ASM
+#define DIRECT_READ(base, mask)         (((*(base+4)) & (mask)) ? 1 : 0)  //PORTX + 0x10
+#define DIRECT_MODE_INPUT(base, mask)   ((*(base+2)) = (mask))            //TRISXSET + 0x08
+#define DIRECT_MODE_OUTPUT(base, mask)  ((*(base+1)) = (mask))            //TRISXCLR + 0x04
+#define DIRECT_WRITE_LOW(base, mask)    ((*(base+8+1)) = (mask))          //LATXCLR  + 0x24
+#define DIRECT_WRITE_HIGH(base, mask)   ((*(base+8+2)) = (mask))          //LATXSET + 0x28
+
+#endif
+
+// some 3.3V chips with 5V tolerant pins need this workaround
+//
+#if defined(__MK20DX256__)
+#define FIVE_VOLT_TOLERANCE_WORKAROUND
+#endif
+
 // library interface description
 class CapacitiveSensor
 {
@@ -37,13 +90,10 @@ class CapacitiveSensor
 	unsigned long  CS_AutocaL_Millis;
 	unsigned long  lastCal;
 	unsigned long  total;
-	uint8_t sBit;   // send pin's ports and bitmask
-	volatile uint8_t *sReg;
-	volatile uint8_t *sOut;
-	uint8_t rBit;    // receive pin's ports and bitmask 
-	volatile uint8_t *rReg;
-	volatile uint8_t *rIn;
-	volatile uint8_t *rOut;
+	IO_REG_TYPE sBit;   // send pin's ports and bitmask
+	volatile IO_REG_TYPE *sReg;
+	IO_REG_TYPE rBit;    // receive pin's ports and bitmask
+	volatile IO_REG_TYPE *rReg;
   // methods
 	int SenseOneCycle(void);
 };