use mbed os

Dependents:   Seeed_Grove_I2C_Touch_Example

Fork of MPR121 by Sam Grove

Committer:
Nathan Yonkee
Date:
Sun Jul 02 10:58:16 2017 -0600
Revision:
10:fb2d2454fea4
Parent:
6:b6bb38744edd
Child:
11:ad26c0810f02
Fix the simple functions of which button is pressed and when

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sam_grove 0:42add775212a 1 /**
sam_grove 0:42add775212a 2 * @file MPR121.cpp
sam_grove 0:42add775212a 3 * @brief Device driver - MPR121 capactiive touch IC
sam_grove 0:42add775212a 4 * @author sam grove
sam_grove 0:42add775212a 5 * @version 1.0
sam_grove 0:42add775212a 6 * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MPR121.pdf
sam_grove 0:42add775212a 7 *
sam_grove 0:42add775212a 8 * Copyright (c) 2013
sam_grove 0:42add775212a 9 *
sam_grove 0:42add775212a 10 * Licensed under the Apache License, Version 2.0 (the "License");
sam_grove 0:42add775212a 11 * you may not use this file except in compliance with the License.
sam_grove 0:42add775212a 12 * You may obtain a copy of the License at
sam_grove 0:42add775212a 13 *
sam_grove 0:42add775212a 14 * http://www.apache.org/licenses/LICENSE-2.0
sam_grove 0:42add775212a 15 *
sam_grove 0:42add775212a 16 * Unless required by applicable law or agreed to in writing, software
sam_grove 0:42add775212a 17 * distributed under the License is distributed on an "AS IS" BASIS,
sam_grove 0:42add775212a 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
sam_grove 0:42add775212a 19 * See the License for the specific language governing permissions and
sam_grove 0:42add775212a 20 * limitations under the License.
sam_grove 0:42add775212a 21 */
sam_grove 0:42add775212a 22
sam_grove 0:42add775212a 23 #include "MPR121.h"
sam_grove 3:828260f21de6 24 #include "mbed_debug.h"
sam_grove 3:828260f21de6 25
sam_grove 3:828260f21de6 26 #define DEBUG 1
sam_grove 5:3934358ec2b7 27
sam_grove 0:42add775212a 28 MPR121::MPR121(I2C &i2c, InterruptIn &pin, MPR121_ADDR i2c_addr)
sam_grove 0:42add775212a 29 {
sam_grove 0:42add775212a 30 _i2c = &i2c;
sam_grove 0:42add775212a 31 _irq = &pin;
sam_grove 0:42add775212a 32 _i2c_addr = (i2c_addr << 1);
sam_grove 5:3934358ec2b7 33
sam_grove 5:3934358ec2b7 34 return;
sam_grove 5:3934358ec2b7 35 }
sam_grove 5:3934358ec2b7 36
Nathan Yonkee 10:fb2d2454fea4 37 MPR121::MPR121(I2C &i2c, MPR121_ADDR fake)
sam_grove 5:3934358ec2b7 38 {
sam_grove 5:3934358ec2b7 39 _i2c = &i2c;
sam_grove 5:3934358ec2b7 40 _irq = NULL;
Nathan Yonkee 10:fb2d2454fea4 41 _i2c_addr = (0x1b << 1);
Nathan Yonkee 10:fb2d2454fea4 42 char reg[1] = { 0x03 };
Nathan Yonkee 10:fb2d2454fea4 43 int result=0;
Nathan Yonkee 10:fb2d2454fea4 44 char data = 10;
Nathan Yonkee 10:fb2d2454fea4 45 result = _i2c->write(_i2c_addr, reg, 1, true);
Nathan Yonkee 10:fb2d2454fea4 46 if(result == 0 ) debug("result is 0");
Nathan Yonkee 10:fb2d2454fea4 47 result = _i2c->read(_i2c_addr, &data, 1);
Nathan Yonkee 10:fb2d2454fea4 48 if(result == 0 ) debug("result is 0");
sam_grove 5:3934358ec2b7 49
sam_grove 0:42add775212a 50 return;
sam_grove 0:42add775212a 51 }
sam_grove 0:42add775212a 52
sam_grove 0:42add775212a 53 void MPR121::init(void)
sam_grove 0:42add775212a 54 {
sam_grove 0:42add775212a 55 // set the i2c speed
Nathan Yonkee 10:fb2d2454fea4 56 /* _i2c->frequency(400000); */
sam_grove 0:42add775212a 57 // irq is open-collector and active-low
sam_grove 5:3934358ec2b7 58 if(_irq != NULL) {
sam_grove 5:3934358ec2b7 59 _irq->mode(PullUp);
sam_grove 5:3934358ec2b7 60 }
sam_grove 5:3934358ec2b7 61
sam_grove 0:42add775212a 62 // setup and registers - start with POR values (must be in stop mode)
sam_grove 0:42add775212a 63 MPR121::writeRegister(SRST, 0x63); //REG 0x80
sam_grove 5:3934358ec2b7 64
sam_grove 0:42add775212a 65 // Baseline Filtering Control Register (changes response sensitivity)
sam_grove 0:42add775212a 66 // http://cache.freescale.com/files/sensors/doc/app_note/AN3891.pdf
sam_grove 0:42add775212a 67 MPR121::writeRegister(MHDR, 0x1); //REG 0x2B
sam_grove 0:42add775212a 68 MPR121::writeRegister(NHDR, 0x1); //REG 0x2C
sam_grove 0:42add775212a 69 MPR121::writeRegister(NCLR, 0x0); //REG 0x2D
sam_grove 0:42add775212a 70 MPR121::writeRegister(FDLR, 0x0); //REG 0x2E
sam_grove 0:42add775212a 71 MPR121::writeRegister(MHDF, 0x1); //REG 0x2F
sam_grove 0:42add775212a 72 MPR121::writeRegister(NHDF, 0x1); //REG 0x30
sam_grove 0:42add775212a 73 MPR121::writeRegister(NCLF, 0xFF); //REG 0x31
sam_grove 0:42add775212a 74 MPR121::writeRegister(FDLF, 0x2); //REG 0x32
sam_grove 5:3934358ec2b7 75
sam_grove 0:42add775212a 76 // Touch / Release Threshold
sam_grove 0:42add775212a 77 // cache.freescale.com/files/sensors/doc/app_note/AN3892.pdf
sam_grove 5:3934358ec2b7 78 for(int i=0; i<(12*2); i+=2) { // touch
sam_grove 3:828260f21de6 79 MPR121::writeRegister(static_cast<MPR121_REGISTER>(E0TTH+i), 0x20); //REG 0x41...0x58 odd
sam_grove 0:42add775212a 80 }
sam_grove 5:3934358ec2b7 81 for(int i=0; i<(12*2); i+=2) { // release
sam_grove 3:828260f21de6 82 MPR121::writeRegister(static_cast<MPR121_REGISTER>(E0RTH+i), 0x10); //REG 0x41...0x58 even
sam_grove 0:42add775212a 83 }
sam_grove 5:3934358ec2b7 84
sam_grove 0:42add775212a 85 // Debounce Register DR=b6...4, DT=b2...0
sam_grove 0:42add775212a 86 MPR121::writeRegister(DT_DR, 0x11); //REG 0x5B
sam_grove 5:3934358ec2b7 87
sam_grove 0:42add775212a 88 // Filter and Global CDC CDT Configuration (sample time, charge current)
sam_grove 0:42add775212a 89 MPR121::writeRegister(CDC_CONFIG, 0x10); //REG 0x5C default 10
sam_grove 0:42add775212a 90 MPR121::writeRegister(CDT_CONFIG, 0x20); //REG 0x5D default 24
sam_grove 5:3934358ec2b7 91
sam_grove 0:42add775212a 92 // Auto-Configuration Registers
sam_grove 0:42add775212a 93 // http://cache.freescale.com/files/sensors/doc/app_note/AN3889.pdf
sam_grove 0:42add775212a 94 MPR121::writeRegister(AUTO_CFG0, 0x33); // REG 0x7B
sam_grove 0:42add775212a 95 MPR121::writeRegister(AUTO_CFG1, 0x07); // REG 0x7C
sam_grove 0:42add775212a 96 MPR121::writeRegister(USL, 0xc9); // REG 0x7D((3.3-.07)/3.3) * 256
sam_grove 0:42add775212a 97 MPR121::writeRegister(LSL, 0x83); // REG 0x7E((3.3-.07)/3.3) * 256 * 0.65f
sam_grove 0:42add775212a 98 MPR121::writeRegister(TL, 0xb5); // REG 0x7F((3.3-.07)/3.3) * 256 * 0.9f
sam_grove 0:42add775212a 99 // 255 > USL > TL > LSL > 0
sam_grove 5:3934358ec2b7 100
sam_grove 0:42add775212a 101 // Electrode Configuration Register - enable all 12 and start
sam_grove 0:42add775212a 102 MPR121::writeRegister(ECR, 0x8f);
sam_grove 5:3934358ec2b7 103
sam_grove 0:42add775212a 104 return;
sam_grove 0:42add775212a 105 }
sam_grove 0:42add775212a 106
sam_grove 0:42add775212a 107 void MPR121::enable(void)
sam_grove 0:42add775212a 108 {
sam_grove 0:42add775212a 109 _button = 0;
sam_grove 0:42add775212a 110 _button_has_changed = 0;
sam_grove 1:cee45334b36a 111 // enable the 12 electrodes - allow disable to put device into
sam_grove 1:cee45334b36a 112 // lower current consumption mode
sam_grove 1:cee45334b36a 113 MPR121::writeRegister(ECR, 0x8f);
sam_grove 1:cee45334b36a 114 // and attach the interrupt handler
sam_grove 5:3934358ec2b7 115 if(_irq != NULL) {
sam_grove 5:3934358ec2b7 116 _irq->fall(this, &MPR121::handler);
sam_grove 5:3934358ec2b7 117 }
sam_grove 5:3934358ec2b7 118
sam_grove 0:42add775212a 119 return;
sam_grove 0:42add775212a 120 }
sam_grove 0:42add775212a 121
sam_grove 0:42add775212a 122 void MPR121::disable(void)
sam_grove 0:42add775212a 123 {
sam_grove 1:cee45334b36a 124 // detach the interrupt handler
sam_grove 0:42add775212a 125 _irq->fall(NULL);
sam_grove 0:42add775212a 126 _button = 0;
sam_grove 0:42add775212a 127 _button_has_changed = 0;
sam_grove 1:cee45334b36a 128 // put the device in low current consumption mode - dont re-init registers
sam_grove 1:cee45334b36a 129 MPR121::writeRegister(ECR, 0x0);
sam_grove 1:cee45334b36a 130 MPR121::writeRegister(AUTO_CFG0, 0x0); // REG 0x7B
sam_grove 1:cee45334b36a 131 MPR121::writeRegister(AUTO_CFG1, 0x0); // REG 0x7C
sam_grove 5:3934358ec2b7 132
sam_grove 0:42add775212a 133 return;
sam_grove 0:42add775212a 134 }
sam_grove 0:42add775212a 135
sam_grove 0:42add775212a 136 uint32_t MPR121::isPressed(void)
sam_grove 0:42add775212a 137 {
Nathan Yonkee 10:fb2d2454fea4 138
Nathan Yonkee 10:fb2d2454fea4 139 char reg[1] = { 0x03 };
Nathan Yonkee 10:fb2d2454fea4 140 int result=0;
Nathan Yonkee 10:fb2d2454fea4 141 char data = -1;
Nathan Yonkee 10:fb2d2454fea4 142 result = _i2c->write(_i2c_addr, reg, 1, true);
Nathan Yonkee 10:fb2d2454fea4 143 if(result == 0 ) debug("result is 0");
Nathan Yonkee 10:fb2d2454fea4 144 result = _i2c->read(_i2c_addr, &data, 1);
Nathan Yonkee 10:fb2d2454fea4 145 if(result == 0 ) debug("result is 0");
Nathan Yonkee 10:fb2d2454fea4 146 if(data > 0) data = true;
Nathan Yonkee 10:fb2d2454fea4 147 return data;
Nathan Yonkee 10:fb2d2454fea4 148 /* return _button_has_changed; */
sam_grove 0:42add775212a 149 }
sam_grove 0:42add775212a 150
sam_grove 0:42add775212a 151 uint16_t MPR121::buttonPressed(void)
sam_grove 0:42add775212a 152 {
Nathan Yonkee 10:fb2d2454fea4 153 char reg[1] = { 0x03 };
Nathan Yonkee 10:fb2d2454fea4 154 int result=0;
Nathan Yonkee 10:fb2d2454fea4 155 char data = -1;
Nathan Yonkee 10:fb2d2454fea4 156 result = _i2c->write(_i2c_addr, reg, 1, true);
Nathan Yonkee 10:fb2d2454fea4 157 if(result == 0 ) debug("result is 0");
Nathan Yonkee 10:fb2d2454fea4 158 result = _i2c->read(_i2c_addr, &data, 1);
Nathan Yonkee 10:fb2d2454fea4 159 if(result == 0 ) debug("result is 0");
Nathan Yonkee 10:fb2d2454fea4 160 if(data == 4) data = 3;
Nathan Yonkee 10:fb2d2454fea4 161 if(data == 2) data = 2;
Nathan Yonkee 10:fb2d2454fea4 162 if(data == 1) data = 1;
Nathan Yonkee 10:fb2d2454fea4 163 return data;
sam_grove 0:42add775212a 164 }
sam_grove 0:42add775212a 165
sam_grove 3:828260f21de6 166 void MPR121::registerDump(Serial &obj) const
sam_grove 0:42add775212a 167 {
sam_grove 0:42add775212a 168 uint8_t reg_val = 0;
sam_grove 5:3934358ec2b7 169
sam_grove 5:3934358ec2b7 170 for(int i=0; i<0x80; i++) {
sam_grove 3:828260f21de6 171 reg_val = MPR121::readRegister(static_cast<MPR121_REGISTER>(i));
sam_grove 3:828260f21de6 172 obj.printf("Reg 0x%02x: 0x%02x \n", i, reg_val);
sam_grove 0:42add775212a 173 }
sam_grove 5:3934358ec2b7 174
sam_grove 5:3934358ec2b7 175 return;
sam_grove 5:3934358ec2b7 176 }
sam_grove 5:3934358ec2b7 177
sam_grove 5:3934358ec2b7 178 void MPR121::registerDump(void) const
sam_grove 5:3934358ec2b7 179 {
sam_grove 5:3934358ec2b7 180 uint8_t reg_val = 0;
sam_grove 5:3934358ec2b7 181
sam_grove 5:3934358ec2b7 182 for(int i=0; i<0x80; i++) {
sam_grove 5:3934358ec2b7 183 reg_val = MPR121::readRegister(static_cast<MPR121_REGISTER>(i));
sam_grove 5:3934358ec2b7 184 printf("Reg 0x%02x: 0x%02x \n", i, reg_val);
sam_grove 5:3934358ec2b7 185 }
sam_grove 5:3934358ec2b7 186
sam_grove 0:42add775212a 187 return;
sam_grove 0:42add775212a 188 }
sam_grove 0:42add775212a 189
sam_grove 0:42add775212a 190 void MPR121::handler(void)
sam_grove 0:42add775212a 191 {
sam_grove 0:42add775212a 192 uint16_t reg_val = 0, oor_val = 0;
sam_grove 0:42add775212a 193 // read register 0 and 1
sam_grove 0:42add775212a 194 reg_val = MPR121::readRegister(ELE0_7_STAT);
sam_grove 0:42add775212a 195 reg_val |= MPR121::readRegister(ELE8_11_STAT) << 8;
sam_grove 0:42add775212a 196 // 2 and 3
sam_grove 0:42add775212a 197 oor_val = MPR121::readRegister(ELE0_7_OOR_STAT);
sam_grove 0:42add775212a 198 oor_val |= MPR121::readRegister(ELE8_11_OOR_STAT) << 8;
sam_grove 5:3934358ec2b7 199
sam_grove 3:828260f21de6 200 // debugging stuff and errors - if OOR fails someone was touching the pad during auto-config
sam_grove 3:828260f21de6 201 // Just reboot until they're not doing this
sam_grove 5:3934358ec2b7 202 if((0 != oor_val) && DEBUG) {
sam_grove 3:828260f21de6 203 debug("MPR121 OOR failure - 0x%04x\n", oor_val);
sam_grove 3:828260f21de6 204 wait(0.1f);
sam_grove 3:828260f21de6 205 NVIC_SystemReset();
sam_grove 0:42add775212a 206 }
sam_grove 5:3934358ec2b7 207
sam_grove 0:42add775212a 208 _button = reg_val;
sam_grove 0:42add775212a 209 _button_has_changed = 1;
sam_grove 5:3934358ec2b7 210
sam_grove 0:42add775212a 211 return;
sam_grove 0:42add775212a 212 }
sam_grove 0:42add775212a 213
sam_grove 3:828260f21de6 214 void MPR121::writeRegister(MPR121_REGISTER const reg, uint8_t const data) const
sam_grove 0:42add775212a 215 {
sam_grove 0:42add775212a 216 char buf[2] = {reg, data};
sam_grove 0:42add775212a 217 uint8_t result = 0;
sam_grove 5:3934358ec2b7 218
sam_grove 0:42add775212a 219 result = _i2c->write(_i2c_addr, buf, 2);
sam_grove 3:828260f21de6 220 if(result && DEBUG)
sam_grove 0:42add775212a 221 {
sam_grove 4:c1bc00c5e8e5 222 debug("I2C write failed\n");
sam_grove 0:42add775212a 223 }
sam_grove 5:3934358ec2b7 224
sam_grove 0:42add775212a 225 return;
sam_grove 0:42add775212a 226 }
sam_grove 0:42add775212a 227
sam_grove 3:828260f21de6 228 uint8_t MPR121::readRegister(MPR121_REGISTER const reg) const
sam_grove 0:42add775212a 229 {
sam_grove 3:828260f21de6 230 char buf[1] = {reg}, data = 0;
sam_grove 3:828260f21de6 231 uint8_t result = 1;
sam_grove 5:3934358ec2b7 232
sam_grove 3:828260f21de6 233 result &= _i2c->write(_i2c_addr, buf, 1, true);
sam_grove 3:828260f21de6 234 result &= _i2c->read(_i2c_addr, &data, 1);
sam_grove 0:42add775212a 235
sam_grove 3:828260f21de6 236 if(result && DEBUG)
sam_grove 0:42add775212a 237 {
sam_grove 4:c1bc00c5e8e5 238 debug("I2C read failed\n");
sam_grove 0:42add775212a 239 }
sam_grove 5:3934358ec2b7 240
sam_grove 0:42add775212a 241 return data;
sam_grove 0:42add775212a 242 }