A device driver for the Freescale MPR121 capactive touch IC. Not optimized for any particular system, just a starting point to get the chip up in running in no time. Changes to registers init() method will tailor the library for end system use.

Dependents:   Seeed_Grove_I2C_Touch_Example MPR121_HelloWorld mbed_petbottle_holder_shikake test_DEV-10508 ... more

Datasheet:

http://cache.freescale.com/files/sensors/doc/data_sheet/MPR121.pdf

Information

Must add pull-ups to the I2C bus!!

Files at this revision

API Documentation at this revision

Comitter:
sam_grove
Date:
Fri Aug 15 23:00:13 2014 +0000
Parent:
3:828260f21de6
Child:
6:b6bb38744edd
Commit message:
Updated library to work without the IRQ pin being connected

Changed in this revision

MPR121.cpp Show annotated file Show diff for this revision Revisions of this file
MPR121.h Show annotated file Show diff for this revision Revisions of this file
--- a/MPR121.cpp	Tue Aug 27 21:39:33 2013 +0000
+++ b/MPR121.cpp	Fri Aug 15 23:00:13 2014 +0000
@@ -24,13 +24,22 @@
 #include "mbed_debug.h"
 
 #define DEBUG 1
-    
+
 MPR121::MPR121(I2C &i2c, InterruptIn &pin, MPR121_ADDR i2c_addr)
 {
     _i2c = &i2c;
     _irq = &pin;
     _i2c_addr = (i2c_addr << 1);
-    
+
+    return;
+}
+
+MPR121::MPR121(I2C &i2c, MPR121_ADDR i2c_addr)
+{
+    _i2c = &i2c;
+    _irq = NULL;
+    _i2c_addr = (i2c_addr << 1);
+
     return;
 }
 
@@ -39,11 +48,13 @@
     // set the i2c speed
     _i2c->frequency(400000);
     // irq is open-collector and active-low
-    _irq->mode(PullUp);
-    
+    if(_irq != NULL) {
+        _irq->mode(PullUp);
+    }
+
     // setup and registers - start with POR values (must be in stop mode)
     MPR121::writeRegister(SRST, 0x63); //REG 0x80
-    
+
     // Baseline Filtering Control Register (changes response sensitivity)
     // http://cache.freescale.com/files/sensors/doc/app_note/AN3891.pdf
     MPR121::writeRegister(MHDR, 0x1);  //REG 0x2B
@@ -54,25 +65,23 @@
     MPR121::writeRegister(NHDF, 0x1);  //REG 0x30
     MPR121::writeRegister(NCLF, 0xFF); //REG 0x31
     MPR121::writeRegister(FDLF, 0x2);  //REG 0x32
-    
+
     // Touch / Release Threshold
     // cache.freescale.com/files/sensors/doc/app_note/AN3892.pdf
-    for(int i=0; i<(12*2); i+=2) // touch
-    {
+    for(int i=0; i<(12*2); i+=2) { // touch
         MPR121::writeRegister(static_cast<MPR121_REGISTER>(E0TTH+i), 0x20); //REG 0x41...0x58 odd
     }
-    for(int i=0; i<(12*2); i+=2) // release
-    {
+    for(int i=0; i<(12*2); i+=2) { // release
         MPR121::writeRegister(static_cast<MPR121_REGISTER>(E0RTH+i), 0x10); //REG 0x41...0x58 even
     }
-    
+
     // Debounce Register DR=b6...4, DT=b2...0
     MPR121::writeRegister(DT_DR, 0x11); //REG 0x5B
-    
+
     // Filter and Global CDC CDT Configuration (sample time, charge current)
     MPR121::writeRegister(CDC_CONFIG, 0x10); //REG 0x5C default 10
     MPR121::writeRegister(CDT_CONFIG, 0x20); //REG 0x5D default 24
-    
+
     // Auto-Configuration Registers
     // http://cache.freescale.com/files/sensors/doc/app_note/AN3889.pdf
     MPR121::writeRegister(AUTO_CFG0, 0x33); // REG 0x7B
@@ -81,10 +90,10 @@
     MPR121::writeRegister(LSL, 0x83);       // REG 0x7E((3.3-.07)/3.3) * 256 * 0.65f
     MPR121::writeRegister(TL,  0xb5);       // REG 0x7F((3.3-.07)/3.3) * 256 * 0.9f
     // 255 > USL > TL > LSL > 0
-    
+
     // Electrode Configuration Register - enable all 12 and start
     MPR121::writeRegister(ECR, 0x8f);
-    
+
     return;
 }
 
@@ -96,8 +105,10 @@
     //  lower current consumption mode
     MPR121::writeRegister(ECR, 0x8f);
     // and attach the interrupt handler
-    _irq->fall(this, &MPR121::handler);
-    
+    if(_irq != NULL) {
+        _irq->fall(this, &MPR121::handler);
+    }
+
     return;
 }
 
@@ -111,7 +122,7 @@
     MPR121::writeRegister(ECR, 0x0);
     MPR121::writeRegister(AUTO_CFG0, 0x0); // REG 0x7B
     MPR121::writeRegister(AUTO_CFG1, 0x0); // REG 0x7C
-    
+
     return;
 }
 
@@ -122,6 +133,9 @@
 
 uint16_t MPR121::buttonPressed(void)
 {
+    if(_irq == NULL) {
+        handler();
+    }
     _button_has_changed = 0;
     return _button;
 }
@@ -129,13 +143,24 @@
 void MPR121::registerDump(Serial &obj) const
 {
     uint8_t reg_val = 0;
-    
-    for(int i=0; i<0x80; i++)
-    {
+
+    for(int i=0; i<0x80; i++) {
         reg_val = MPR121::readRegister(static_cast<MPR121_REGISTER>(i));
         obj.printf("Reg 0x%02x: 0x%02x \n", i, reg_val);
     }
-    
+
+    return;
+}
+
+void MPR121::registerDump(void) const
+{
+    uint8_t reg_val = 0;
+
+    for(int i=0; i<0x80; i++) {
+        reg_val = MPR121::readRegister(static_cast<MPR121_REGISTER>(i));
+        printf("Reg 0x%02x: 0x%02x \n", i, reg_val);
+    }
+
     return;
 }
 
@@ -148,19 +173,18 @@
     // 2 and 3
     oor_val  = MPR121::readRegister(ELE0_7_OOR_STAT);
     oor_val |= MPR121::readRegister(ELE8_11_OOR_STAT) << 8;
-    
+
     // debugging stuff and errors - if OOR fails someone was touching the pad during auto-config
     //  Just reboot until they're not doing this
-    if((0 != oor_val) && DEBUG)
-    {
+    if((0 != oor_val) && DEBUG) {
         debug("MPR121 OOR failure - 0x%04x\n", oor_val);
         wait(0.1f);
         NVIC_SystemReset();
     }
-   
+
     _button = reg_val;
     _button_has_changed = 1;
-    
+
     return;
 }
 
@@ -168,14 +192,13 @@
 {
     char buf[2] = {reg, data};
     uint8_t result = 0;
-    
+
     result = _i2c->write(_i2c_addr, buf, 2);
-    
-    if(result && DEBUG)
-    {
+
+    if(result && DEBUG) {
         debug("I2c write failed\n");
     }
-    
+
     return;
 }
 
@@ -183,14 +206,13 @@
 {
     char buf[1] = {reg}, data = 0;
     uint8_t result = 1;
-    
+
     result &= _i2c->write(_i2c_addr, buf, 1, true);
-    result &= _i2c->read(_i2c_addr, &data, 1); 
-    
-    if(result && DEBUG)
-    {
+    result &= _i2c->read(_i2c_addr, &data, 1);
+
+    if(result && DEBUG) {
         debug("I2c read failed\n");
     }
-    
+
     return data;
 }
--- a/MPR121.h	Tue Aug 27 21:39:33 2013 +0000
+++ b/MPR121.h	Fri Aug 15 23:00:13 2014 +0000
@@ -147,6 +147,12 @@
      */    
     MPR121(I2C &i2c, InterruptIn &pin, MPR121_ADDR i2c_addr);
     
+    /** Create the MPR121 object
+     *  @param i2c - A defined I2C object
+     *  @param i2c_addr - Connection of the address line
+     */    
+    MPR121(I2C &i2c, MPR121_ADDR i2c_addr);
+    
     /** Clear state variables and initilize the dependant objects
      */
     void init(void);
@@ -176,6 +182,10 @@
      */
     void registerDump(Serial &obj) const;
     
+    /** print the register map and values to the console
+     */
+    void registerDump(void) const;
+    
     /** Write to a register (exposed for debugging reasons)
      *  Note: most writes are only valid in stop mode
      *  @param reg - The register to be written