use mbed os

Dependents:   Seeed_Grove_I2C_Touch_Example

Fork of MPR121 by Sam Grove

Committer:
Nathan Yonkee
Date:
Sun Jul 02 11:55:42 2017 -0600
Revision:
19:eaa64138290b
Parent:
15:8c7fba79a28e
Child:
22:b1fa74a5123b
revert to original fixes before merges

Who changed what in which revision?

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