Skip to content

Commit

Permalink
Support non-AVR boards
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulStoffregen committed Jun 15, 2014
1 parent 4a5dc4f commit 34c0873
Showing 2 changed files with 86 additions and 37 deletions.
59 changes: 29 additions & 30 deletions CapacitiveSensor.cpp
Original file line number Diff line number Diff line change
@@ -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,42 +134,46 @@ 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
}

// 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
64 changes: 57 additions & 7 deletions CapacitiveSensor.h
Original file line number Diff line number Diff line change
@@ -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);
};

0 comments on commit 34c0873

Please sign in to comment.