A sample library to get the MPR121-based touch board from SparkFun up and running. This code is based on the sample Arduino code from SparkFun but is ported to C++ for mbed. The Mbed will require 4.7K pull-up resistors on the i2c SCL and SDA lines to communicate with the board. The IRQ line does not. The example code has the SDA on P28, SCL on P27 and IRQ on P26

Dependencies:   mbed

Committer:
abuckton
Date:
Mon Feb 28 12:20:18 2011 +0000
Revision:
1:d1837531c318
Parent:
0:2e5b82508aea
Cleaned up copyright, attributed original source

Who changed what in which revision?

UserRevisionLine numberNew contents of line
abuckton 1:d1837531c318 1 /*
abuckton 1:d1837531c318 2 Copyright (c) 2011 Anthony Buckton (abuckton [at] blackink [dot} net {dot} au)
abuckton 1:d1837531c318 3
abuckton 1:d1837531c318 4 Permission is hereby granted, free of charge, to any person obtaining a copy
abuckton 1:d1837531c318 5 of this software and associated documentation files (the "Software"), to deal
abuckton 1:d1837531c318 6 in the Software without restriction, including without limitation the rights
abuckton 1:d1837531c318 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
abuckton 1:d1837531c318 8 copies of the Software, and to permit persons to whom the Software is
abuckton 1:d1837531c318 9 furnished to do so, subject to the following conditions:
abuckton 1:d1837531c318 10
abuckton 1:d1837531c318 11 The above copyright notice and this permission notice shall be included in
abuckton 1:d1837531c318 12 all copies or substantial portions of the Software.
abuckton 1:d1837531c318 13
abuckton 1:d1837531c318 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
abuckton 1:d1837531c318 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
abuckton 1:d1837531c318 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
abuckton 1:d1837531c318 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
abuckton 1:d1837531c318 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
abuckton 1:d1837531c318 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
abuckton 1:d1837531c318 20 THE SOFTWARE.
abuckton 1:d1837531c318 21 */
abuckton 1:d1837531c318 22
abuckton 0:2e5b82508aea 23 #include <mbed.h>
abuckton 0:2e5b82508aea 24 #include <sstream>
abuckton 0:2e5b82508aea 25 #include <string>
abuckton 0:2e5b82508aea 26 #include <list>
abuckton 0:2e5b82508aea 27
abuckton 0:2e5b82508aea 28 #include <mpr121.h>
abuckton 1:d1837531c318 29
abuckton 1:d1837531c318 30 Mpr121::Mpr121(I2C *i2c, Address i2cAddress)
abuckton 1:d1837531c318 31 {
abuckton 1:d1837531c318 32 this->i2c = i2c;
abuckton 1:d1837531c318 33
abuckton 1:d1837531c318 34 address = i2cAddress;
abuckton 1:d1837531c318 35
abuckton 1:d1837531c318 36 // Configure the MPR121 settings to default
abuckton 1:d1837531c318 37 this->configureSettings();
abuckton 1:d1837531c318 38 }
abuckton 0:2e5b82508aea 39
abuckton 1:d1837531c318 40
abuckton 1:d1837531c318 41 void Mpr121::configureSettings()
abuckton 1:d1837531c318 42 {
abuckton 1:d1837531c318 43 // Put the MPR into setup mode
abuckton 1:d1837531c318 44 this->write(ELE_CFG,0x00);
abuckton 0:2e5b82508aea 45
abuckton 1:d1837531c318 46 // Electrode filters for when data is > baseline
abuckton 1:d1837531c318 47 unsigned char gtBaseline[] = {
abuckton 1:d1837531c318 48 0x01, //MHD_R
abuckton 1:d1837531c318 49 0x01, //NHD_R
abuckton 1:d1837531c318 50 0x00, //NCL_R
abuckton 1:d1837531c318 51 0x00 //FDL_R
abuckton 1:d1837531c318 52 };
abuckton 1:d1837531c318 53
abuckton 1:d1837531c318 54 writeMany(MHD_R,gtBaseline,4);
abuckton 1:d1837531c318 55
abuckton 1:d1837531c318 56 // Electrode filters for when data is < baseline
abuckton 1:d1837531c318 57 unsigned char ltBaseline[] = {
abuckton 1:d1837531c318 58 0x01, //MHD_F
abuckton 1:d1837531c318 59 0x01, //NHD_F
abuckton 1:d1837531c318 60 0xFF, //NCL_F
abuckton 1:d1837531c318 61 0x02 //FDL_F
abuckton 1:d1837531c318 62 };
abuckton 0:2e5b82508aea 63
abuckton 1:d1837531c318 64 writeMany(MHD_F,ltBaseline,4);
abuckton 0:2e5b82508aea 65
abuckton 1:d1837531c318 66 // Electrode touch and release thresholds
abuckton 1:d1837531c318 67 unsigned char electrodeThresholds[] = {
abuckton 1:d1837531c318 68 E_THR_T, // Touch Threshhold
abuckton 1:d1837531c318 69 E_THR_R // Release Threshold
abuckton 1:d1837531c318 70 };
abuckton 1:d1837531c318 71
abuckton 1:d1837531c318 72 for(int i=0; i<12; i++){
abuckton 1:d1837531c318 73 int result = writeMany((ELE0_T+(i*2)),electrodeThresholds,2);
abuckton 1:d1837531c318 74 }
abuckton 1:d1837531c318 75
abuckton 1:d1837531c318 76 // Proximity Settings
abuckton 1:d1837531c318 77 unsigned char proximitySettings[] = {
abuckton 1:d1837531c318 78 0xff, //MHD_Prox_R
abuckton 1:d1837531c318 79 0xff, //NHD_Prox_R
abuckton 1:d1837531c318 80 0x00, //NCL_Prox_R
abuckton 1:d1837531c318 81 0x00, //FDL_Prox_R
abuckton 1:d1837531c318 82 0x01, //MHD_Prox_F
abuckton 1:d1837531c318 83 0x01, //NHD_Prox_F
abuckton 1:d1837531c318 84 0xFF, //NCL_Prox_F
abuckton 1:d1837531c318 85 0xff, //FDL_Prox_F
abuckton 1:d1837531c318 86 0x00, //NHD_Prox_T
abuckton 1:d1837531c318 87 0x00, //NCL_Prox_T
abuckton 1:d1837531c318 88 0x00 //NFD_Prox_T
abuckton 1:d1837531c318 89 };
abuckton 1:d1837531c318 90 writeMany(MHDPROXR,proximitySettings,11);
abuckton 1:d1837531c318 91
abuckton 1:d1837531c318 92 unsigned char proxThresh[] = {
abuckton 1:d1837531c318 93 PROX_THR_T, // Touch Threshold
abuckton 1:d1837531c318 94 PROX_THR_R // Release Threshold
abuckton 1:d1837531c318 95 };
abuckton 1:d1837531c318 96 writeMany(EPROXTTH,proxThresh,2);
abuckton 1:d1837531c318 97
abuckton 1:d1837531c318 98 this->write(FIL_CFG,0x04);
abuckton 1:d1837531c318 99
abuckton 1:d1837531c318 100 // Set the electrode config to transition to active mode
abuckton 1:d1837531c318 101 this->write(ELE_CFG,0x0c);
abuckton 1:d1837531c318 102 }
abuckton 0:2e5b82508aea 103
abuckton 1:d1837531c318 104 void Mpr121::setElectrodeThreshold(int electrode, unsigned char touch, unsigned char release){
abuckton 1:d1837531c318 105
abuckton 1:d1837531c318 106 if(electrode > 11) return;
abuckton 1:d1837531c318 107
abuckton 1:d1837531c318 108 // Get the current mode
abuckton 1:d1837531c318 109 unsigned char mode = this->read(ELE_CFG);
abuckton 1:d1837531c318 110
abuckton 1:d1837531c318 111 // Put the MPR into setup mode
abuckton 1:d1837531c318 112 this->write(ELE_CFG,0x00);
abuckton 1:d1837531c318 113
abuckton 1:d1837531c318 114 // Write the new threshold
abuckton 1:d1837531c318 115 this->write((ELE0_T+(electrode*2)), touch);
abuckton 1:d1837531c318 116 this->write((ELE0_T+(electrode*2)+1), release);
abuckton 1:d1837531c318 117
abuckton 1:d1837531c318 118 //Restore the operating mode
abuckton 1:d1837531c318 119 this->write(ELE_CFG, mode);
abuckton 1:d1837531c318 120 }
abuckton 1:d1837531c318 121
abuckton 1:d1837531c318 122
abuckton 1:d1837531c318 123 unsigned char Mpr121::read(int key){
abuckton 1:d1837531c318 124
abuckton 1:d1837531c318 125 unsigned char data[2];
abuckton 1:d1837531c318 126
abuckton 1:d1837531c318 127 //Start the command
abuckton 1:d1837531c318 128 i2c->start();
abuckton 1:d1837531c318 129
abuckton 1:d1837531c318 130 // Address the target (Write mode)
abuckton 1:d1837531c318 131 int ack1= i2c->write(address);
abuckton 1:d1837531c318 132
abuckton 1:d1837531c318 133 // Set the register key to read
abuckton 1:d1837531c318 134 int ack2 = i2c->write(key);
abuckton 1:d1837531c318 135
abuckton 1:d1837531c318 136 // Re-start for read of data
abuckton 1:d1837531c318 137 i2c->start();
abuckton 1:d1837531c318 138
abuckton 1:d1837531c318 139 // Re-send the target address in read mode
abuckton 1:d1837531c318 140 int ack3 = i2c->write(address+1);
abuckton 0:2e5b82508aea 141
abuckton 1:d1837531c318 142 // Read in the result
abuckton 1:d1837531c318 143 data[0] = i2c->read(0);
abuckton 1:d1837531c318 144
abuckton 1:d1837531c318 145 // Reset the bus
abuckton 1:d1837531c318 146 i2c->stop();
abuckton 1:d1837531c318 147
abuckton 1:d1837531c318 148 return data[0];
abuckton 1:d1837531c318 149 }
abuckton 1:d1837531c318 150
abuckton 1:d1837531c318 151
abuckton 1:d1837531c318 152 int Mpr121::write(int key, unsigned char value){
abuckton 1:d1837531c318 153
abuckton 1:d1837531c318 154 //Start the command
abuckton 1:d1837531c318 155 i2c->start();
abuckton 1:d1837531c318 156
abuckton 1:d1837531c318 157 // Address the target (Write mode)
abuckton 1:d1837531c318 158 int ack1= i2c->write(address);
abuckton 0:2e5b82508aea 159
abuckton 1:d1837531c318 160 // Set the register key to write
abuckton 1:d1837531c318 161 int ack2 = i2c->write(key);
abuckton 1:d1837531c318 162
abuckton 1:d1837531c318 163 // Read in the result
abuckton 1:d1837531c318 164 int ack3 = i2c->write(value);
abuckton 1:d1837531c318 165
abuckton 1:d1837531c318 166 // Reset the bus
abuckton 1:d1837531c318 167 i2c->stop();
abuckton 1:d1837531c318 168
abuckton 1:d1837531c318 169 return (ack1+ack2+ack3)-3;
abuckton 1:d1837531c318 170 }
abuckton 1:d1837531c318 171
abuckton 1:d1837531c318 172
abuckton 1:d1837531c318 173 int Mpr121::writeMany(int start, unsigned char* dataSet, int length){
abuckton 1:d1837531c318 174 //Start the command
abuckton 1:d1837531c318 175 i2c->start();
abuckton 1:d1837531c318 176
abuckton 1:d1837531c318 177 // Address the target (Write mode)
abuckton 1:d1837531c318 178 int ack= i2c->write(address);
abuckton 1:d1837531c318 179 if(ack!=1){
abuckton 1:d1837531c318 180 return -1;
abuckton 0:2e5b82508aea 181 }
abuckton 0:2e5b82508aea 182
abuckton 1:d1837531c318 183 // Set the register key to write
abuckton 1:d1837531c318 184 ack = i2c->write(start);
abuckton 1:d1837531c318 185 if(ack!=1){
abuckton 1:d1837531c318 186 return -1;
abuckton 0:2e5b82508aea 187 }
abuckton 0:2e5b82508aea 188
abuckton 1:d1837531c318 189 // Write the date set
abuckton 1:d1837531c318 190 int count = 0;
abuckton 1:d1837531c318 191 while(ack==1 && (count < length)){
abuckton 1:d1837531c318 192 ack = i2c->write(dataSet[count]);
abuckton 1:d1837531c318 193 count++;
abuckton 1:d1837531c318 194 }
abuckton 1:d1837531c318 195 // Stop the cmd
abuckton 1:d1837531c318 196 i2c->stop();
abuckton 1:d1837531c318 197
abuckton 1:d1837531c318 198 return count;
abuckton 1:d1837531c318 199 }
abuckton 1:d1837531c318 200
abuckton 0:2e5b82508aea 201
abuckton 1:d1837531c318 202 bool Mpr121::getProximityMode(){
abuckton 1:d1837531c318 203 if(this->read(ELE_CFG) > 0x0c)
abuckton 1:d1837531c318 204 return true;
abuckton 1:d1837531c318 205 else
abuckton 1:d1837531c318 206 return false;
abuckton 1:d1837531c318 207 }
abuckton 1:d1837531c318 208
abuckton 1:d1837531c318 209 void Mpr121::setProximityMode(bool mode){
abuckton 1:d1837531c318 210 this->write(ELE_CFG,0x00);
abuckton 1:d1837531c318 211 if(mode){
abuckton 1:d1837531c318 212 this->write(ELE_CFG,0x30); //Sense proximity from ALL pads
abuckton 1:d1837531c318 213 } else {
abuckton 1:d1837531c318 214 this->write(ELE_CFG,0x0c); //Sense touch, all 12 pads active.
abuckton 1:d1837531c318 215 }
abuckton 1:d1837531c318 216 }
abuckton 1:d1837531c318 217
abuckton 1:d1837531c318 218
abuckton 1:d1837531c318 219 int Mpr121::readTouchData(){
abuckton 1:d1837531c318 220 return this->read(0x00);
abuckton 1:d1837531c318 221 }