ThreeSixes/EzClock

Touch sensor IRQs not registering

Closed this issue · 4 comments

The touch sensor's IRQ requests aren't registering when a touch event occurs. This is either a hardware issue with a pullup resistor or the CAP1188 registers aren't set correctly under configTouch().

The issue is that the INT bit has been set to 1 following an interrupt and not cleared per the CAP1188 data sheet. The INT bit must be cleared in the main configuration register (0x00), and the main configuration register should be set to 0x00 at init. A new function should be created to clear the interrupt bit after the interrupt has been detected and processed - something like this:

// Clear the INT bit on the main configuration register.
cap.writeRegister(0x00, cap.readRegister(0x00) & 0xFE);

Also, the main configuration register should be set like this inside configTouch() at startup:
cap.writeRegister(0x00, 0x00);

Issue test code:

#include <Wire.h> // I2C support for RTC and cap touch sensor
#include <SPI.h> // Required for CAP1188 touch sensor, but not used.
#include <Adafruit_CAP1188.h> // Touch sensor support

#define T_IRQPIN 2 // The Uno uses D3 for the IRQ
#define T_IRQ 0 // Which is IRQ #1

Adafruit_CAP1188 cap = Adafruit_CAP1188();

volatile boolean t_IrqFlag = 0;

void setup() {
Serial.begin(115200);

// Set up the touch sensor
Serial.println("Init CAP1188...");

// Did we start the CAP1188
if (!cap.begin()) {
Serial.println("CAP1188 not found.");
}

pinMode(T_IRQPIN, INPUT);

attachInterrupt(T_IRQ, setTIrqFlag, FALLING); // Touch

// Configure touch sensor.
configTouch();
}

void loop() {
if (t_IrqFlag) {
Serial.println("Got IRQ.");
t_IrqFlag = 0;
// Clear the INT bit on the main config register to make sure IRQs are processed.
cap.writeRegister(0x00, cap.readRegister(0x00) & 0xFE);
}
}

// Configure the touch sensor.
void configTouch() {

Serial.println("Configuring touch sensor...");

// Configure the necessary registers.
cap.writeRegister(0x00, 0x00); // Clear the main config register.
cap.writeRegister(0x27, 0xFF); // Activate IRQ for all touch channels!
cap.writeRegister(0x28, 0x00); // Turn off interrupt on hold.
cap.writeRegister(0x2A, 0x00); // Allow multiple touches because the diagnostic LEDs look cool.
cap.writeRegister(0x41, 0x40); // "Speedup" off.
cap.writeRegister(0x44, 0x41); // Set interrupt on press but not release?
}

// Set our touch IRQ flag.
void setTIrqFlag() {
// Set the flag
t_IrqFlag = 1;
}

The relevant fixes are in place, and the code now needs to be tested.

Issue resolved by proposed code changes, and tested to be working.