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:07:17 2011 +0000
Revision:
0:2e5b82508aea
Child:
1:d1837531c318
First cut to get things moving

Who changed what in which revision?

UserRevisionLine numberNew contents of line
abuckton 0:2e5b82508aea 1 #include <mbed.h>
abuckton 0:2e5b82508aea 2 #include <sstream>
abuckton 0:2e5b82508aea 3 #include <string>
abuckton 0:2e5b82508aea 4 #include <list>
abuckton 0:2e5b82508aea 5
abuckton 0:2e5b82508aea 6 #include <mpr121.h>
abuckton 0:2e5b82508aea 7
abuckton 0:2e5b82508aea 8 using namespace std;
abuckton 0:2e5b82508aea 9
abuckton 0:2e5b82508aea 10 Mpr121::Mpr121(I2C *i2c, Address i2cAddress)
abuckton 0:2e5b82508aea 11 {
abuckton 0:2e5b82508aea 12 this->i2c = i2c;
abuckton 0:2e5b82508aea 13
abuckton 0:2e5b82508aea 14 address = i2cAddress;
abuckton 0:2e5b82508aea 15
abuckton 0:2e5b82508aea 16 // Configure the MPR121 settings to default
abuckton 0:2e5b82508aea 17 this->configureSettings();
abuckton 0:2e5b82508aea 18 }
abuckton 0:2e5b82508aea 19
abuckton 0:2e5b82508aea 20
abuckton 0:2e5b82508aea 21 void Mpr121::configureSettings()
abuckton 0:2e5b82508aea 22 {
abuckton 0:2e5b82508aea 23 // Put the MPR into setup mode
abuckton 0:2e5b82508aea 24 this->write(ELE_CFG,0x00);
abuckton 0:2e5b82508aea 25
abuckton 0:2e5b82508aea 26 // Electrode filters for when data is > baseline
abuckton 0:2e5b82508aea 27 unsigned char gtBaseline[] = {
abuckton 0:2e5b82508aea 28 0x01, //MHD_R
abuckton 0:2e5b82508aea 29 0x01, //NHD_R
abuckton 0:2e5b82508aea 30 0x00, //NCL_R
abuckton 0:2e5b82508aea 31 0x00 //FDL_R
abuckton 0:2e5b82508aea 32 };
abuckton 0:2e5b82508aea 33
abuckton 0:2e5b82508aea 34 writeMany(MHD_R,gtBaseline,4);
abuckton 0:2e5b82508aea 35
abuckton 0:2e5b82508aea 36 // Electrode filters for when data is < baseline
abuckton 0:2e5b82508aea 37 unsigned char ltBaseline[] = {
abuckton 0:2e5b82508aea 38 0x01, //MHD_F
abuckton 0:2e5b82508aea 39 0x01, //NHD_F
abuckton 0:2e5b82508aea 40 0xFF, //NCL_F
abuckton 0:2e5b82508aea 41 0x02 //FDL_F
abuckton 0:2e5b82508aea 42 };
abuckton 0:2e5b82508aea 43
abuckton 0:2e5b82508aea 44 writeMany(MHD_F,ltBaseline,4);
abuckton 0:2e5b82508aea 45
abuckton 0:2e5b82508aea 46 // Electrode touch and release thresholds
abuckton 0:2e5b82508aea 47 unsigned char electrodeThresholds[] = {
abuckton 0:2e5b82508aea 48 E_THR_T, // Touch Threshhold
abuckton 0:2e5b82508aea 49 E_THR_R // Release Threshold
abuckton 0:2e5b82508aea 50 };
abuckton 0:2e5b82508aea 51
abuckton 0:2e5b82508aea 52 for(int i=0; i<12; i++){
abuckton 0:2e5b82508aea 53 int result = writeMany((ELE0_T+(i*2)),electrodeThresholds,2);
abuckton 0:2e5b82508aea 54 }
abuckton 0:2e5b82508aea 55
abuckton 0:2e5b82508aea 56 // Proximity Settings
abuckton 0:2e5b82508aea 57 unsigned char proximitySettings[] = {
abuckton 0:2e5b82508aea 58 0xff, //MHD_Prox_R
abuckton 0:2e5b82508aea 59 0xff, //NHD_Prox_R
abuckton 0:2e5b82508aea 60 0x00, //NCL_Prox_R
abuckton 0:2e5b82508aea 61 0x00, //FDL_Prox_R
abuckton 0:2e5b82508aea 62 0x01, //MHD_Prox_F
abuckton 0:2e5b82508aea 63 0x01, //NHD_Prox_F
abuckton 0:2e5b82508aea 64 0xFF, //NCL_Prox_F
abuckton 0:2e5b82508aea 65 0xff, //FDL_Prox_F
abuckton 0:2e5b82508aea 66 0x00, //NHD_Prox_T
abuckton 0:2e5b82508aea 67 0x00, //NCL_Prox_T
abuckton 0:2e5b82508aea 68 0x00 //NFD_Prox_T
abuckton 0:2e5b82508aea 69 };
abuckton 0:2e5b82508aea 70 writeMany(MHDPROXR,proximitySettings,11);
abuckton 0:2e5b82508aea 71
abuckton 0:2e5b82508aea 72 unsigned char proxThresh[] = {
abuckton 0:2e5b82508aea 73 PROX_THR_T, // Touch Threshold
abuckton 0:2e5b82508aea 74 PROX_THR_R // Release Threshold
abuckton 0:2e5b82508aea 75 };
abuckton 0:2e5b82508aea 76 writeMany(EPROXTTH,proxThresh,2);
abuckton 0:2e5b82508aea 77
abuckton 0:2e5b82508aea 78 this->write(FIL_CFG,0x04);
abuckton 0:2e5b82508aea 79
abuckton 0:2e5b82508aea 80 // Set the electrode config to transition to active mode
abuckton 0:2e5b82508aea 81 this->write(ELE_CFG,0x0c);
abuckton 0:2e5b82508aea 82 }
abuckton 0:2e5b82508aea 83
abuckton 0:2e5b82508aea 84 void Mpr121::setElectrodeThreshold(int electrode, unsigned char touch, unsigned char release){
abuckton 0:2e5b82508aea 85
abuckton 0:2e5b82508aea 86 if(electrode > 11) return;
abuckton 0:2e5b82508aea 87
abuckton 0:2e5b82508aea 88 // Get the current mode
abuckton 0:2e5b82508aea 89 unsigned char mode = this->read(ELE_CFG);
abuckton 0:2e5b82508aea 90
abuckton 0:2e5b82508aea 91 // Put the MPR into setup mode
abuckton 0:2e5b82508aea 92 this->write(ELE_CFG,0x00);
abuckton 0:2e5b82508aea 93
abuckton 0:2e5b82508aea 94 // Write the new threshold
abuckton 0:2e5b82508aea 95 this->write((ELE0_T+(electrode*2)), touch);
abuckton 0:2e5b82508aea 96 this->write((ELE0_T+(electrode*2)+1), release);
abuckton 0:2e5b82508aea 97
abuckton 0:2e5b82508aea 98 //Restore the operating mode
abuckton 0:2e5b82508aea 99 this->write(ELE_CFG, mode);
abuckton 0:2e5b82508aea 100 }
abuckton 0:2e5b82508aea 101
abuckton 0:2e5b82508aea 102
abuckton 0:2e5b82508aea 103 unsigned char Mpr121::read(int key){
abuckton 0:2e5b82508aea 104
abuckton 0:2e5b82508aea 105 unsigned char data[2];
abuckton 0:2e5b82508aea 106
abuckton 0:2e5b82508aea 107 //Start the command
abuckton 0:2e5b82508aea 108 i2c->start();
abuckton 0:2e5b82508aea 109
abuckton 0:2e5b82508aea 110 // Address the target (Write mode)
abuckton 0:2e5b82508aea 111 int ack1= i2c->write(address);
abuckton 0:2e5b82508aea 112
abuckton 0:2e5b82508aea 113 // Set the register key to read
abuckton 0:2e5b82508aea 114 int ack2 = i2c->write(key);
abuckton 0:2e5b82508aea 115
abuckton 0:2e5b82508aea 116 // Re-start for read of data
abuckton 0:2e5b82508aea 117 i2c->start();
abuckton 0:2e5b82508aea 118
abuckton 0:2e5b82508aea 119 // Re-send the target address in read mode
abuckton 0:2e5b82508aea 120 int ack3 = i2c->write(address+1);
abuckton 0:2e5b82508aea 121
abuckton 0:2e5b82508aea 122 // Read in the result
abuckton 0:2e5b82508aea 123 data[0] = i2c->read(0);
abuckton 0:2e5b82508aea 124
abuckton 0:2e5b82508aea 125 // Reset the bus
abuckton 0:2e5b82508aea 126 i2c->stop();
abuckton 0:2e5b82508aea 127
abuckton 0:2e5b82508aea 128 return data[0];
abuckton 0:2e5b82508aea 129 }
abuckton 0:2e5b82508aea 130
abuckton 0:2e5b82508aea 131
abuckton 0:2e5b82508aea 132 int Mpr121::write(int key, unsigned char value){
abuckton 0:2e5b82508aea 133
abuckton 0:2e5b82508aea 134 //Start the command
abuckton 0:2e5b82508aea 135 i2c->start();
abuckton 0:2e5b82508aea 136
abuckton 0:2e5b82508aea 137 // Address the target (Write mode)
abuckton 0:2e5b82508aea 138 int ack1= i2c->write(address);
abuckton 0:2e5b82508aea 139
abuckton 0:2e5b82508aea 140 // Set the register key to write
abuckton 0:2e5b82508aea 141 int ack2 = i2c->write(key);
abuckton 0:2e5b82508aea 142
abuckton 0:2e5b82508aea 143 // Read in the result
abuckton 0:2e5b82508aea 144 int ack3 = i2c->write(value);
abuckton 0:2e5b82508aea 145
abuckton 0:2e5b82508aea 146 // Reset the bus
abuckton 0:2e5b82508aea 147 i2c->stop();
abuckton 0:2e5b82508aea 148
abuckton 0:2e5b82508aea 149 return (ack1+ack2+ack3)-3;
abuckton 0:2e5b82508aea 150 }
abuckton 0:2e5b82508aea 151
abuckton 0:2e5b82508aea 152
abuckton 0:2e5b82508aea 153 int Mpr121::writeMany(int start, unsigned char* dataSet, int length){
abuckton 0:2e5b82508aea 154 //Start the command
abuckton 0:2e5b82508aea 155 i2c->start();
abuckton 0:2e5b82508aea 156
abuckton 0:2e5b82508aea 157 // Address the target (Write mode)
abuckton 0:2e5b82508aea 158 int ack= i2c->write(address);
abuckton 0:2e5b82508aea 159 if(ack!=1){
abuckton 0:2e5b82508aea 160 return -1;
abuckton 0:2e5b82508aea 161 }
abuckton 0:2e5b82508aea 162
abuckton 0:2e5b82508aea 163 // Set the register key to write
abuckton 0:2e5b82508aea 164 ack = i2c->write(start);
abuckton 0:2e5b82508aea 165 if(ack!=1){
abuckton 0:2e5b82508aea 166 return -1;
abuckton 0:2e5b82508aea 167 }
abuckton 0:2e5b82508aea 168
abuckton 0:2e5b82508aea 169 // Write the date set
abuckton 0:2e5b82508aea 170 int count = 0;
abuckton 0:2e5b82508aea 171 while(ack==1 && (count < length)){
abuckton 0:2e5b82508aea 172 ack = i2c->write(dataSet[count]);
abuckton 0:2e5b82508aea 173 count++;
abuckton 0:2e5b82508aea 174 }
abuckton 0:2e5b82508aea 175 // Stop the cmd
abuckton 0:2e5b82508aea 176 i2c->stop();
abuckton 0:2e5b82508aea 177
abuckton 0:2e5b82508aea 178 return count;
abuckton 0:2e5b82508aea 179 }
abuckton 0:2e5b82508aea 180
abuckton 0:2e5b82508aea 181
abuckton 0:2e5b82508aea 182 bool Mpr121::getProximityMode(){
abuckton 0:2e5b82508aea 183 if(this->read(ELE_CFG) > 0x0c)
abuckton 0:2e5b82508aea 184 return true;
abuckton 0:2e5b82508aea 185 else
abuckton 0:2e5b82508aea 186 return false;
abuckton 0:2e5b82508aea 187 }
abuckton 0:2e5b82508aea 188
abuckton 0:2e5b82508aea 189 void Mpr121::setProximityMode(bool mode){
abuckton 0:2e5b82508aea 190 this->write(ELE_CFG,0x00);
abuckton 0:2e5b82508aea 191 if(mode){
abuckton 0:2e5b82508aea 192 this->write(ELE_CFG,0x30); //Sense proximity from ALL pads
abuckton 0:2e5b82508aea 193 } else {
abuckton 0:2e5b82508aea 194 this->write(ELE_CFG,0x0c); //Sense touch, all 12 pads active.
abuckton 0:2e5b82508aea 195 }
abuckton 0:2e5b82508aea 196 }
abuckton 0:2e5b82508aea 197
abuckton 0:2e5b82508aea 198
abuckton 0:2e5b82508aea 199 int Mpr121::readTouchData(){
abuckton 0:2e5b82508aea 200 return this->read(0x00);
abuckton 0:2e5b82508aea 201 }