use mbed os

Dependents:   Seeed_Grove_I2C_Touch_Example

Fork of MPR121 by Sam Grove

Committer:
Nathan Yonkee
Date:
Sun Jul 02 11:12:48 2017 -0600
Revision:
12:22d36da8df91
Parent:
11:ad26c0810f02
Child:
15:8c7fba79a28e
auo  format

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Nathan Yonkee 12:22d36da8df91 1 <<<<<<< working copy
Nate Yonkee 9:8cb5ce483be3 2 /**
Nate Yonkee 9:8cb5ce483be3 3 * @file MPR121.cpp
Nate Yonkee 9:8cb5ce483be3 4 * @brief Device driver - MPR121 capactiive touch IC
Nate Yonkee 9:8cb5ce483be3 5 * @author sam grove
Nate Yonkee 9:8cb5ce483be3 6 * @version 1.0
Nate Yonkee 9:8cb5ce483be3 7 * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MPR121.pdf
Nate Yonkee 9:8cb5ce483be3 8 *
Nate Yonkee 9:8cb5ce483be3 9 * Copyright (c) 2013
Nate Yonkee 9:8cb5ce483be3 10 *
Nate Yonkee 9:8cb5ce483be3 11 * Licensed under the Apache License, Version 2.0 (the "License");
Nate Yonkee 9:8cb5ce483be3 12 * you may not use this file except in compliance with the License.
Nate Yonkee 9:8cb5ce483be3 13 * You may obtain a copy of the License at
Nate Yonkee 9:8cb5ce483be3 14 *
Nate Yonkee 9:8cb5ce483be3 15 * http://www.apache.org/licenses/LICENSE-2.0
Nate Yonkee 9:8cb5ce483be3 16 *
Nate Yonkee 9:8cb5ce483be3 17 * Unless required by applicable law or agreed to in writing, software
Nate Yonkee 9:8cb5ce483be3 18 * distributed under the License is distributed on an "AS IS" BASIS,
Nate Yonkee 9:8cb5ce483be3 19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Nate Yonkee 9:8cb5ce483be3 20 * See the License for the specific language governing permissions and
Nate Yonkee 9:8cb5ce483be3 21 * limitations under the License.
Nate Yonkee 9:8cb5ce483be3 22 */
Nate Yonkee 9:8cb5ce483be3 23
Nate Yonkee 9:8cb5ce483be3 24 #include "MPR121.h"
Nate Yonkee 9:8cb5ce483be3 25 #include "mbed_debug.h"
Nate Yonkee 9:8cb5ce483be3 26
Nate Yonkee 9:8cb5ce483be3 27 #define DEBUG 1
Nate Yonkee 9:8cb5ce483be3 28
Nathan Yonkee 12:22d36da8df91 29 MPR121::MPR121(I2C &i2c, InterruptIn &pin, MPR121_ADDR i2c_addr) {
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 12:22d36da8df91 37 MPR121::MPR121(I2C &i2c, MPR121_ADDR fake) {
Nathan Yonkee 12:22d36da8df91 38 _i2c = &i2c;
Nathan Yonkee 12:22d36da8df91 39 _irq = NULL;
Nathan Yonkee 12:22d36da8df91 40 _i2c_addr = (0x1b << 1);
Nathan Yonkee 12:22d36da8df91 41 char reg[1] = { 0x03 };
Nathan Yonkee 12:22d36da8df91 42 int result=0;
Nathan Yonkee 12:22d36da8df91 43 char data = 10;
Nathan Yonkee 12:22d36da8df91 44 result = _i2c->write(_i2c_addr, reg, 1, true);
Nathan Yonkee 12:22d36da8df91 45 if(result == 0 ) debug("result is 0");
Nathan Yonkee 12:22d36da8df91 46 result = _i2c->read(_i2c_addr, &data, 1);
Nathan Yonkee 12:22d36da8df91 47 if(result == 0 ) debug("result is 0");
Nathan Yonkee 12:22d36da8df91 48
Nathan Yonkee 12:22d36da8df91 49 return;
Nathan Yonkee 12:22d36da8df91 50 }
Nathan Yonkee 12:22d36da8df91 51
Nathan Yonkee 12:22d36da8df91 52 void MPR121::init(void) {
Nathan Yonkee 12:22d36da8df91 53 // set the i2c speed
Nathan Yonkee 12:22d36da8df91 54 /* _i2c->frequency(400000);
Nathan Yonkee 12:22d36da8df91 55 */
Nathan Yonkee 12:22d36da8df91 56 // irq is open-collector and active-low
Nathan Yonkee 12:22d36da8df91 57 if(_irq != NULL) {
Nathan Yonkee 12:22d36da8df91 58 _irq->mode(PullUp);
Nathan Yonkee 12:22d36da8df91 59 }
Nathan Yonkee 12:22d36da8df91 60
Nathan Yonkee 12:22d36da8df91 61 // setup and registers - start with POR values (must be in stop mode)
Nathan Yonkee 12:22d36da8df91 62 MPR121::writeRegister(SRST, 0x63); //REG 0x80
Nathan Yonkee 12:22d36da8df91 63
Nathan Yonkee 12:22d36da8df91 64 // Baseline Filtering Control Register (changes response sensitivity)
Nathan Yonkee 12:22d36da8df91 65 // http://cache.freescale.com/files/sensors/doc/app_note/AN3891.pdf
Nathan Yonkee 12:22d36da8df91 66 MPR121::writeRegister(MHDR, 0x1); //REG 0x2B
Nathan Yonkee 12:22d36da8df91 67 MPR121::writeRegister(NHDR, 0x1); //REG 0x2C
Nathan Yonkee 12:22d36da8df91 68 MPR121::writeRegister(NCLR, 0x0); //REG 0x2D
Nathan Yonkee 12:22d36da8df91 69 MPR121::writeRegister(FDLR, 0x0); //REG 0x2E
Nathan Yonkee 12:22d36da8df91 70 MPR121::writeRegister(MHDF, 0x1); //REG 0x2F
Nathan Yonkee 12:22d36da8df91 71 MPR121::writeRegister(NHDF, 0x1); //REG 0x30
Nathan Yonkee 12:22d36da8df91 72 MPR121::writeRegister(NCLF, 0xFF); //REG 0x31
Nathan Yonkee 12:22d36da8df91 73 MPR121::writeRegister(FDLF, 0x2); //REG 0x32
Nathan Yonkee 12:22d36da8df91 74
Nathan Yonkee 12:22d36da8df91 75 // Touch / Release Threshold
Nathan Yonkee 12:22d36da8df91 76 // cache.freescale.com/files/sensors/doc/app_note/AN3892.pdf
Nathan Yonkee 12:22d36da8df91 77 for(int i=0; i<(12*2); i+=2) { // touch
Nathan Yonkee 12:22d36da8df91 78 MPR121::writeRegister(static_cast<MPR121_REGISTER>(E0TTH+i), 0x20); //REG 0x41...0x58 odd
Nathan Yonkee 12:22d36da8df91 79 }
Nathan Yonkee 12:22d36da8df91 80 for(int i=0; i<(12*2); i+=2) { // release
Nathan Yonkee 12:22d36da8df91 81 MPR121::writeRegister(static_cast<MPR121_REGISTER>(E0RTH+i), 0x10); //REG 0x41...0x58 even
Nathan Yonkee 12:22d36da8df91 82 }
Nathan Yonkee 12:22d36da8df91 83
Nathan Yonkee 12:22d36da8df91 84 // Debounce Register DR=b6...4, DT=b2...0
Nathan Yonkee 12:22d36da8df91 85 MPR121::writeRegister(DT_DR, 0x11); //REG 0x5B
Nathan Yonkee 12:22d36da8df91 86
Nathan Yonkee 12:22d36da8df91 87 // Filter and Global CDC CDT Configuration (sample time, charge current)
Nathan Yonkee 12:22d36da8df91 88 MPR121::writeRegister(CDC_CONFIG, 0x10); //REG 0x5C default 10
Nathan Yonkee 12:22d36da8df91 89 MPR121::writeRegister(CDT_CONFIG, 0x20); //REG 0x5D default 24
Nathan Yonkee 12:22d36da8df91 90
Nathan Yonkee 12:22d36da8df91 91 // Auto-Configuration Registers
Nathan Yonkee 12:22d36da8df91 92 // http://cache.freescale.com/files/sensors/doc/app_note/AN3889.pdf
Nathan Yonkee 12:22d36da8df91 93 MPR121::writeRegister(AUTO_CFG0, 0x33); // REG 0x7B
Nathan Yonkee 12:22d36da8df91 94 MPR121::writeRegister(AUTO_CFG1, 0x07); // REG 0x7C
Nathan Yonkee 12:22d36da8df91 95 MPR121::writeRegister(USL, 0xc9); // REG 0x7D((3.3-.07)/3.3) * 256
Nathan Yonkee 12:22d36da8df91 96 MPR121::writeRegister(LSL, 0x83); // REG 0x7E((3.3-.07)/3.3) * 256 * 0.65f
Nathan Yonkee 12:22d36da8df91 97 MPR121::writeRegister(TL, 0xb5); // REG 0x7F((3.3-.07)/3.3) * 256 * 0.9f
Nathan Yonkee 12:22d36da8df91 98 // 255 > USL > TL > LSL > 0
Nathan Yonkee 12:22d36da8df91 99
Nathan Yonkee 12:22d36da8df91 100 // Electrode Configuration Register - enable all 12 and start
Nathan Yonkee 12:22d36da8df91 101 MPR121::writeRegister(ECR, 0x8f);
Nathan Yonkee 12:22d36da8df91 102
Nathan Yonkee 12:22d36da8df91 103 return;
Nathan Yonkee 12:22d36da8df91 104 }
Nathan Yonkee 12:22d36da8df91 105
Nathan Yonkee 12:22d36da8df91 106 void MPR121::enable(void) {
Nathan Yonkee 12:22d36da8df91 107 _button = 0;
Nathan Yonkee 12:22d36da8df91 108 _button_has_changed = 0;
Nathan Yonkee 12:22d36da8df91 109 // enable the 12 electrodes - allow disable to put device into
Nathan Yonkee 12:22d36da8df91 110 // lower current consumption mode
Nathan Yonkee 12:22d36da8df91 111 MPR121::writeRegister(ECR, 0x8f);
Nathan Yonkee 12:22d36da8df91 112 // and attach the interrupt handler
Nathan Yonkee 12:22d36da8df91 113 if(_irq != NULL) {
Nathan Yonkee 12:22d36da8df91 114 _irq->fall(this, &MPR121::handler);
Nathan Yonkee 12:22d36da8df91 115 }
Nathan Yonkee 12:22d36da8df91 116
Nathan Yonkee 12:22d36da8df91 117 return;
Nathan Yonkee 12:22d36da8df91 118 }
Nathan Yonkee 12:22d36da8df91 119
Nathan Yonkee 12:22d36da8df91 120 void MPR121::disable(void) {
Nathan Yonkee 12:22d36da8df91 121 // detach the interrupt handler
Nathan Yonkee 12:22d36da8df91 122 _irq->fall(NULL);
Nathan Yonkee 12:22d36da8df91 123 _button = 0;
Nathan Yonkee 12:22d36da8df91 124 _button_has_changed = 0;
Nathan Yonkee 12:22d36da8df91 125 // put the device in low current consumption mode - dont re-init registers
Nathan Yonkee 12:22d36da8df91 126 MPR121::writeRegister(ECR, 0x0);
Nathan Yonkee 12:22d36da8df91 127 MPR121::writeRegister(AUTO_CFG0, 0x0); // REG 0x7B
Nathan Yonkee 12:22d36da8df91 128 MPR121::writeRegister(AUTO_CFG1, 0x0); // REG 0x7C
Nathan Yonkee 12:22d36da8df91 129
Nathan Yonkee 12:22d36da8df91 130 return;
Nathan Yonkee 12:22d36da8df91 131 }
Nathan Yonkee 12:22d36da8df91 132
Nathan Yonkee 12:22d36da8df91 133 uint32_t MPR121::isPressed(void) {
Nathan Yonkee 12:22d36da8df91 134
Nathan Yonkee 12:22d36da8df91 135 char reg[1] = { 0x03 };
Nathan Yonkee 12:22d36da8df91 136 int result=0;
Nathan Yonkee 12:22d36da8df91 137 char data = -1;
Nathan Yonkee 12:22d36da8df91 138 result = _i2c->write(_i2c_addr, reg, 1, true);
Nathan Yonkee 12:22d36da8df91 139 if(result == 0 ) debug("result is 0");
Nathan Yonkee 12:22d36da8df91 140 result = _i2c->read(_i2c_addr, &data, 1);
Nathan Yonkee 12:22d36da8df91 141 if(result == 0 ) debug("result is 0");
Nathan Yonkee 12:22d36da8df91 142 if(data > 0) data = true;
Nathan Yonkee 12:22d36da8df91 143 return data;
Nathan Yonkee 12:22d36da8df91 144 /* return _button_has_changed;
Nathan Yonkee 12:22d36da8df91 145 */
Nathan Yonkee 12:22d36da8df91 146 }
Nathan Yonkee 12:22d36da8df91 147
Nathan Yonkee 12:22d36da8df91 148 uint16_t MPR121::buttonPressed(void) {
Nathan Yonkee 12:22d36da8df91 149 char reg[1] = { 0x03 };
Nathan Yonkee 12:22d36da8df91 150 int result=0;
Nathan Yonkee 12:22d36da8df91 151 char data = -1;
Nathan Yonkee 12:22d36da8df91 152 result = _i2c->write(_i2c_addr, reg, 1, true);
Nathan Yonkee 12:22d36da8df91 153 if(result == 0 ) debug("result is 0");
Nathan Yonkee 12:22d36da8df91 154 result = _i2c->read(_i2c_addr, &data, 1);
Nathan Yonkee 12:22d36da8df91 155 if(result == 0 ) debug("result is 0");
Nathan Yonkee 12:22d36da8df91 156 if(data == 4) data = 3;
Nathan Yonkee 12:22d36da8df91 157 if(data == 2) data = 2;
Nathan Yonkee 12:22d36da8df91 158 if(data == 1) data = 1;
Nathan Yonkee 12:22d36da8df91 159 return data;
Nathan Yonkee 12:22d36da8df91 160 }
Nathan Yonkee 12:22d36da8df91 161
Nathan Yonkee 12:22d36da8df91 162 void MPR121::registerDump(Serial &obj) const {
Nathan Yonkee 12:22d36da8df91 163 uint8_t reg_val = 0;
Nathan Yonkee 12:22d36da8df91 164
Nathan Yonkee 12:22d36da8df91 165 for(int i=0; i<0x80; i++) {
Nathan Yonkee 12:22d36da8df91 166 reg_val = MPR121::readRegister(static_cast<MPR121_REGISTER>(i));
Nathan Yonkee 12:22d36da8df91 167 obj.printf("Reg 0x%02x: 0x%02x \n", i, reg_val);
Nathan Yonkee 12:22d36da8df91 168 }
Nathan Yonkee 12:22d36da8df91 169
Nathan Yonkee 12:22d36da8df91 170 return;
Nathan Yonkee 12:22d36da8df91 171 }
Nathan Yonkee 12:22d36da8df91 172
Nathan Yonkee 12:22d36da8df91 173 void MPR121::registerDump(void) const {
Nathan Yonkee 12:22d36da8df91 174 uint8_t reg_val = 0;
Nathan Yonkee 12:22d36da8df91 175
Nathan Yonkee 12:22d36da8df91 176 for(int i=0; i<0x80; i++) {
Nathan Yonkee 12:22d36da8df91 177 reg_val = MPR121::readRegister(static_cast<MPR121_REGISTER>(i));
Nathan Yonkee 12:22d36da8df91 178 printf("Reg 0x%02x: 0x%02x \n", i, reg_val);
Nathan Yonkee 12:22d36da8df91 179 }
Nathan Yonkee 12:22d36da8df91 180
Nathan Yonkee 12:22d36da8df91 181 return;
Nathan Yonkee 12:22d36da8df91 182 }
Nathan Yonkee 12:22d36da8df91 183
Nathan Yonkee 12:22d36da8df91 184 void MPR121::handler(void) {
Nathan Yonkee 12:22d36da8df91 185 uint16_t reg_val = 0, oor_val = 0;
Nathan Yonkee 12:22d36da8df91 186 // read register 0 and 1
Nathan Yonkee 12:22d36da8df91 187 reg_val = MPR121::readRegister(ELE0_7_STAT);
Nathan Yonkee 12:22d36da8df91 188 reg_val |= MPR121::readRegister(ELE8_11_STAT) << 8;
Nathan Yonkee 12:22d36da8df91 189 // 2 and 3
Nathan Yonkee 12:22d36da8df91 190 oor_val = MPR121::readRegister(ELE0_7_OOR_STAT);
Nathan Yonkee 12:22d36da8df91 191 oor_val |= MPR121::readRegister(ELE8_11_OOR_STAT) << 8;
Nathan Yonkee 12:22d36da8df91 192
Nathan Yonkee 12:22d36da8df91 193 // debugging stuff and errors - if OOR fails someone was touching the pad during auto-config
Nathan Yonkee 12:22d36da8df91 194 // Just reboot until they're not doing this
Nathan Yonkee 12:22d36da8df91 195 if((0 != oor_val) && DEBUG) {
Nathan Yonkee 12:22d36da8df91 196 debug("MPR121 OOR failure - 0x%04x\n", oor_val);
Nathan Yonkee 12:22d36da8df91 197 wait(0.1f);
Nathan Yonkee 12:22d36da8df91 198 NVIC_SystemReset();
Nathan Yonkee 12:22d36da8df91 199 }
Nathan Yonkee 12:22d36da8df91 200
Nathan Yonkee 12:22d36da8df91 201 _button = reg_val;
Nathan Yonkee 12:22d36da8df91 202 _button_has_changed = 1;
Nathan Yonkee 12:22d36da8df91 203
Nathan Yonkee 12:22d36da8df91 204 return;
Nathan Yonkee 12:22d36da8df91 205 }
Nathan Yonkee 12:22d36da8df91 206
Nathan Yonkee 12:22d36da8df91 207 void MPR121::writeRegister(MPR121_REGISTER const reg, uint8_t const data) const {
Nathan Yonkee 12:22d36da8df91 208 char buf[2] = {reg, data};
Nathan Yonkee 12:22d36da8df91 209 uint8_t result = 0;
Nathan Yonkee 12:22d36da8df91 210
Nathan Yonkee 12:22d36da8df91 211 result = _i2c->write(_i2c_addr, buf, 2);
Nathan Yonkee 12:22d36da8df91 212 if(result && DEBUG) {
Nathan Yonkee 12:22d36da8df91 213 debug("I2C write failed\n");
Nathan Yonkee 12:22d36da8df91 214 }
Nathan Yonkee 12:22d36da8df91 215
Nathan Yonkee 12:22d36da8df91 216 return;
Nathan Yonkee 12:22d36da8df91 217 }
Nathan Yonkee 12:22d36da8df91 218
Nathan Yonkee 12:22d36da8df91 219 uint8_t MPR121::readRegister(MPR121_REGISTER const reg) const {
Nathan Yonkee 12:22d36da8df91 220 char buf[1] = {reg}, data = 0;
Nathan Yonkee 12:22d36da8df91 221 uint8_t result = 1;
Nathan Yonkee 12:22d36da8df91 222
Nathan Yonkee 12:22d36da8df91 223 result &= _i2c->write(_i2c_addr, buf, 1, true);
Nathan Yonkee 12:22d36da8df91 224 result &= _i2c->read(_i2c_addr, &data, 1);
Nathan Yonkee 12:22d36da8df91 225
Nathan Yonkee 12:22d36da8df91 226 if(result && DEBUG) {
Nathan Yonkee 12:22d36da8df91 227 debug("I2C read failed\n");
Nathan Yonkee 12:22d36da8df91 228 }
Nathan Yonkee 12:22d36da8df91 229
Nathan Yonkee 12:22d36da8df91 230 return data;
Nathan Yonkee 12:22d36da8df91 231 }
Nathan Yonkee 12:22d36da8df91 232 =======
Nathan Yonkee 12:22d36da8df91 233 /**
Nathan Yonkee 12:22d36da8df91 234 * @file MPR121.cpp
Nathan Yonkee 12:22d36da8df91 235 * @brief Device driver - MPR121 capactiive touch IC
Nathan Yonkee 12:22d36da8df91 236 * @author sam grove
Nathan Yonkee 12:22d36da8df91 237 * @version 1.0
Nathan Yonkee 12:22d36da8df91 238 * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MPR121.pdf
Nathan Yonkee 12:22d36da8df91 239 *
Nathan Yonkee 12:22d36da8df91 240 * Copyright (c) 2013
Nathan Yonkee 12:22d36da8df91 241 *
Nathan Yonkee 12:22d36da8df91 242 * Licensed under the Apache License, Version 2.0 (the "License");
Nathan Yonkee 12:22d36da8df91 243 * you may not use this file except in compliance with the License.
Nathan Yonkee 12:22d36da8df91 244 * You may obtain a copy of the License at
Nathan Yonkee 12:22d36da8df91 245 *
Nathan Yonkee 12:22d36da8df91 246 * http://www.apache.org/licenses/LICENSE-2.0
Nathan Yonkee 12:22d36da8df91 247 *
Nathan Yonkee 12:22d36da8df91 248 * Unless required by applicable law or agreed to in writing, software
Nathan Yonkee 12:22d36da8df91 249 * distributed under the License is distributed on an "AS IS" BASIS,
Nathan Yonkee 12:22d36da8df91 250 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Nathan Yonkee 12:22d36da8df91 251 * See the License for the specific language governing permissions and
Nathan Yonkee 12:22d36da8df91 252 * limitations under the License.
Nathan Yonkee 12:22d36da8df91 253 */
Nathan Yonkee 12:22d36da8df91 254
Nathan Yonkee 12:22d36da8df91 255 #include "MPR121.h"
Nathan Yonkee 12:22d36da8df91 256 #include "mbed_debug.h"
Nathan Yonkee 12:22d36da8df91 257
Nathan Yonkee 12:22d36da8df91 258 #define DEBUG 1
Nathan Yonkee 12:22d36da8df91 259
Nathan Yonkee 12:22d36da8df91 260 MPR121::MPR121(I2C &i2c, InterruptIn &pin, MPR121_ADDR i2c_addr) {
Nathan Yonkee 12:22d36da8df91 261 _i2c = &i2c;
Nathan Yonkee 12:22d36da8df91 262 _irq = &pin;
Nathan Yonkee 12:22d36da8df91 263 _i2c_addr = (i2c_addr << 1);
Nathan Yonkee 12:22d36da8df91 264
Nathan Yonkee 12:22d36da8df91 265 return;
Nathan Yonkee 12:22d36da8df91 266 }
Nathan Yonkee 12:22d36da8df91 267
Nathan Yonkee 12:22d36da8df91 268 MPR121::MPR121(I2C &i2c, MPR121_ADDR i2c_addr) {
Nate Yonkee 9:8cb5ce483be3 269 _i2c = &i2c;
Nate Yonkee 9:8cb5ce483be3 270 _irq = NULL;
Nate Yonkee 9:8cb5ce483be3 271 _i2c_addr = (i2c_addr << 1);
Nate Yonkee 9:8cb5ce483be3 272
Nate Yonkee 9:8cb5ce483be3 273 return;
Nate Yonkee 9:8cb5ce483be3 274 }
Nate Yonkee 9:8cb5ce483be3 275
Nathan Yonkee 12:22d36da8df91 276 void MPR121::init(void) {
Nate Yonkee 9:8cb5ce483be3 277 // set the i2c speed
Nate Yonkee 9:8cb5ce483be3 278 _i2c->frequency(400000);
Nate Yonkee 9:8cb5ce483be3 279 // irq is open-collector and active-low
Nate Yonkee 9:8cb5ce483be3 280 if(_irq != NULL) {
Nate Yonkee 9:8cb5ce483be3 281 _irq->mode(PullUp);
Nate Yonkee 9:8cb5ce483be3 282 }
Nate Yonkee 9:8cb5ce483be3 283
Nate Yonkee 9:8cb5ce483be3 284 // setup and registers - start with POR values (must be in stop mode)
Nate Yonkee 9:8cb5ce483be3 285 MPR121::writeRegister(SRST, 0x63); //REG 0x80
Nate Yonkee 9:8cb5ce483be3 286
Nate Yonkee 9:8cb5ce483be3 287 // Baseline Filtering Control Register (changes response sensitivity)
Nate Yonkee 9:8cb5ce483be3 288 // http://cache.freescale.com/files/sensors/doc/app_note/AN3891.pdf
Nate Yonkee 9:8cb5ce483be3 289 MPR121::writeRegister(MHDR, 0x1); //REG 0x2B
Nate Yonkee 9:8cb5ce483be3 290 MPR121::writeRegister(NHDR, 0x1); //REG 0x2C
Nate Yonkee 9:8cb5ce483be3 291 MPR121::writeRegister(NCLR, 0x0); //REG 0x2D
Nate Yonkee 9:8cb5ce483be3 292 MPR121::writeRegister(FDLR, 0x0); //REG 0x2E
Nate Yonkee 9:8cb5ce483be3 293 MPR121::writeRegister(MHDF, 0x1); //REG 0x2F
Nate Yonkee 9:8cb5ce483be3 294 MPR121::writeRegister(NHDF, 0x1); //REG 0x30
Nate Yonkee 9:8cb5ce483be3 295 MPR121::writeRegister(NCLF, 0xFF); //REG 0x31
Nate Yonkee 9:8cb5ce483be3 296 MPR121::writeRegister(FDLF, 0x2); //REG 0x32
Nate Yonkee 9:8cb5ce483be3 297
Nate Yonkee 9:8cb5ce483be3 298 // Touch / Release Threshold
Nate Yonkee 9:8cb5ce483be3 299 // cache.freescale.com/files/sensors/doc/app_note/AN3892.pdf
Nate Yonkee 9:8cb5ce483be3 300 for(int i=0; i<(12*2); i+=2) { // touch
Nate Yonkee 9:8cb5ce483be3 301 MPR121::writeRegister(static_cast<MPR121_REGISTER>(E0TTH+i), 0x20); //REG 0x41...0x58 odd
Nate Yonkee 9:8cb5ce483be3 302 }
Nate Yonkee 9:8cb5ce483be3 303 for(int i=0; i<(12*2); i+=2) { // release
Nate Yonkee 9:8cb5ce483be3 304 MPR121::writeRegister(static_cast<MPR121_REGISTER>(E0RTH+i), 0x10); //REG 0x41...0x58 even
Nate Yonkee 9:8cb5ce483be3 305 }
Nate Yonkee 9:8cb5ce483be3 306
Nate Yonkee 9:8cb5ce483be3 307 // Debounce Register DR=b6...4, DT=b2...0
Nate Yonkee 9:8cb5ce483be3 308 MPR121::writeRegister(DT_DR, 0x11); //REG 0x5B
Nate Yonkee 9:8cb5ce483be3 309
Nate Yonkee 9:8cb5ce483be3 310 // Filter and Global CDC CDT Configuration (sample time, charge current)
Nate Yonkee 9:8cb5ce483be3 311 MPR121::writeRegister(CDC_CONFIG, 0x10); //REG 0x5C default 10
Nate Yonkee 9:8cb5ce483be3 312 MPR121::writeRegister(CDT_CONFIG, 0x20); //REG 0x5D default 24
Nate Yonkee 9:8cb5ce483be3 313
Nate Yonkee 9:8cb5ce483be3 314 // Auto-Configuration Registers
Nate Yonkee 9:8cb5ce483be3 315 // http://cache.freescale.com/files/sensors/doc/app_note/AN3889.pdf
Nate Yonkee 9:8cb5ce483be3 316 MPR121::writeRegister(AUTO_CFG0, 0x33); // REG 0x7B
Nate Yonkee 9:8cb5ce483be3 317 MPR121::writeRegister(AUTO_CFG1, 0x07); // REG 0x7C
Nate Yonkee 9:8cb5ce483be3 318 MPR121::writeRegister(USL, 0xc9); // REG 0x7D((3.3-.07)/3.3) * 256
Nate Yonkee 9:8cb5ce483be3 319 MPR121::writeRegister(LSL, 0x83); // REG 0x7E((3.3-.07)/3.3) * 256 * 0.65f
Nate Yonkee 9:8cb5ce483be3 320 MPR121::writeRegister(TL, 0xb5); // REG 0x7F((3.3-.07)/3.3) * 256 * 0.9f
Nate Yonkee 9:8cb5ce483be3 321 // 255 > USL > TL > LSL > 0
Nate Yonkee 9:8cb5ce483be3 322
Nate Yonkee 9:8cb5ce483be3 323 // Electrode Configuration Register - enable all 12 and start
Nate Yonkee 9:8cb5ce483be3 324 MPR121::writeRegister(ECR, 0x8f);
Nate Yonkee 9:8cb5ce483be3 325
Nate Yonkee 9:8cb5ce483be3 326 return;
Nate Yonkee 9:8cb5ce483be3 327 }
Nate Yonkee 9:8cb5ce483be3 328
Nathan Yonkee 12:22d36da8df91 329 void MPR121::enable(void) {
Nate Yonkee 9:8cb5ce483be3 330 _button = 0;
Nate Yonkee 9:8cb5ce483be3 331 _button_has_changed = 0;
Nate Yonkee 9:8cb5ce483be3 332 // enable the 12 electrodes - allow disable to put device into
Nate Yonkee 9:8cb5ce483be3 333 // lower current consumption mode
Nate Yonkee 9:8cb5ce483be3 334 MPR121::writeRegister(ECR, 0x8f);
Nate Yonkee 9:8cb5ce483be3 335 // and attach the interrupt handler
Nate Yonkee 9:8cb5ce483be3 336 if(_irq != NULL) {
Nate Yonkee 9:8cb5ce483be3 337 _irq->fall(this, &MPR121::handler);
Nate Yonkee 9:8cb5ce483be3 338 }
Nate Yonkee 9:8cb5ce483be3 339
Nate Yonkee 9:8cb5ce483be3 340 return;
Nate Yonkee 9:8cb5ce483be3 341 }
Nate Yonkee 9:8cb5ce483be3 342
Nathan Yonkee 12:22d36da8df91 343 void MPR121::disable(void) {
Nate Yonkee 9:8cb5ce483be3 344 // detach the interrupt handler
Nate Yonkee 9:8cb5ce483be3 345 _irq->fall(NULL);
Nate Yonkee 9:8cb5ce483be3 346 _button = 0;
Nate Yonkee 9:8cb5ce483be3 347 _button_has_changed = 0;
Nate Yonkee 9:8cb5ce483be3 348 // put the device in low current consumption mode - dont re-init registers
Nate Yonkee 9:8cb5ce483be3 349 MPR121::writeRegister(ECR, 0x0);
Nate Yonkee 9:8cb5ce483be3 350 MPR121::writeRegister(AUTO_CFG0, 0x0); // REG 0x7B
Nate Yonkee 9:8cb5ce483be3 351 MPR121::writeRegister(AUTO_CFG1, 0x0); // REG 0x7C
Nate Yonkee 9:8cb5ce483be3 352
Nate Yonkee 9:8cb5ce483be3 353 return;
Nate Yonkee 9:8cb5ce483be3 354 }
Nate Yonkee 9:8cb5ce483be3 355
Nathan Yonkee 12:22d36da8df91 356 uint32_t MPR121::isPressed(void) {
Nate Yonkee 9:8cb5ce483be3 357 return _button_has_changed;
Nate Yonkee 9:8cb5ce483be3 358 }
Nate Yonkee 9:8cb5ce483be3 359
Nathan Yonkee 12:22d36da8df91 360 uint16_t MPR121::buttonPressed(void) {
Nate Yonkee 9:8cb5ce483be3 361 if(_irq == NULL) {
Nate Yonkee 9:8cb5ce483be3 362 handler();
Nate Yonkee 9:8cb5ce483be3 363 }
Nate Yonkee 9:8cb5ce483be3 364 _button_has_changed = 0;
Nate Yonkee 9:8cb5ce483be3 365 return _button;
Nate Yonkee 9:8cb5ce483be3 366 }
Nate Yonkee 9:8cb5ce483be3 367
Nathan Yonkee 12:22d36da8df91 368 void MPR121::registerDump(Serial &obj) const {
Nate Yonkee 9:8cb5ce483be3 369 uint8_t reg_val = 0;
Nate Yonkee 9:8cb5ce483be3 370
Nate Yonkee 9:8cb5ce483be3 371 for(int i=0; i<0x80; i++) {
Nate Yonkee 9:8cb5ce483be3 372 reg_val = MPR121::readRegister(static_cast<MPR121_REGISTER>(i));
Nate Yonkee 9:8cb5ce483be3 373 obj.printf("Reg 0x%02x: 0x%02x \n", i, reg_val);
Nate Yonkee 9:8cb5ce483be3 374 }
Nate Yonkee 9:8cb5ce483be3 375
Nate Yonkee 9:8cb5ce483be3 376 return;
Nate Yonkee 9:8cb5ce483be3 377 }
Nate Yonkee 9:8cb5ce483be3 378
Nathan Yonkee 12:22d36da8df91 379 void MPR121::registerDump(void) const {
Nate Yonkee 9:8cb5ce483be3 380 uint8_t reg_val = 0;
Nate Yonkee 9:8cb5ce483be3 381
Nate Yonkee 9:8cb5ce483be3 382 for(int i=0; i<0x80; i++) {
Nate Yonkee 9:8cb5ce483be3 383 reg_val = MPR121::readRegister(static_cast<MPR121_REGISTER>(i));
Nate Yonkee 9:8cb5ce483be3 384 printf("Reg 0x%02x: 0x%02x \n", i, reg_val);
Nate Yonkee 9:8cb5ce483be3 385 }
Nate Yonkee 9:8cb5ce483be3 386
Nate Yonkee 9:8cb5ce483be3 387 return;
Nate Yonkee 9:8cb5ce483be3 388 }
Nate Yonkee 9:8cb5ce483be3 389
Nathan Yonkee 12:22d36da8df91 390 void MPR121::handler(void) {
Nate Yonkee 9:8cb5ce483be3 391 uint16_t reg_val = 0, oor_val = 0;
Nate Yonkee 9:8cb5ce483be3 392 // read register 0 and 1
Nate Yonkee 9:8cb5ce483be3 393 reg_val = MPR121::readRegister(ELE0_7_STAT);
Nate Yonkee 9:8cb5ce483be3 394 reg_val |= MPR121::readRegister(ELE8_11_STAT) << 8;
Nate Yonkee 9:8cb5ce483be3 395 // 2 and 3
Nate Yonkee 9:8cb5ce483be3 396 oor_val = MPR121::readRegister(ELE0_7_OOR_STAT);
Nate Yonkee 9:8cb5ce483be3 397 oor_val |= MPR121::readRegister(ELE8_11_OOR_STAT) << 8;
Nate Yonkee 9:8cb5ce483be3 398
Nate Yonkee 9:8cb5ce483be3 399 // debugging stuff and errors - if OOR fails someone was touching the pad during auto-config
Nate Yonkee 9:8cb5ce483be3 400 // Just reboot until they're not doing this
Nate Yonkee 9:8cb5ce483be3 401 if((0 != oor_val) && DEBUG) {
Nate Yonkee 9:8cb5ce483be3 402 debug("MPR121 OOR failure - 0x%04x\n", oor_val);
Nate Yonkee 9:8cb5ce483be3 403 wait(0.1f);
Nate Yonkee 9:8cb5ce483be3 404 NVIC_SystemReset();
Nate Yonkee 9:8cb5ce483be3 405 }
Nate Yonkee 9:8cb5ce483be3 406
Nate Yonkee 9:8cb5ce483be3 407 _button = reg_val;
Nate Yonkee 9:8cb5ce483be3 408 _button_has_changed = 1;
Nate Yonkee 9:8cb5ce483be3 409
Nate Yonkee 9:8cb5ce483be3 410 return;
Nate Yonkee 9:8cb5ce483be3 411 }
Nate Yonkee 9:8cb5ce483be3 412
Nathan Yonkee 12:22d36da8df91 413 void MPR121::writeRegister(MPR121_REGISTER const reg, uint8_t const data) const {
Nate Yonkee 9:8cb5ce483be3 414 char buf[2] = {reg, data};
Nate Yonkee 9:8cb5ce483be3 415 uint8_t result = 0;
Nate Yonkee 9:8cb5ce483be3 416
Nate Yonkee 9:8cb5ce483be3 417 result = _i2c->write(_i2c_addr, buf, 2);
Nathan Yonkee 12:22d36da8df91 418 if(result && DEBUG) {
Nate Yonkee 9:8cb5ce483be3 419 debug("I2C write failed\n");
Nate Yonkee 9:8cb5ce483be3 420 }
Nate Yonkee 9:8cb5ce483be3 421
Nate Yonkee 9:8cb5ce483be3 422 return;
Nate Yonkee 9:8cb5ce483be3 423 }
Nate Yonkee 9:8cb5ce483be3 424
Nathan Yonkee 12:22d36da8df91 425 uint8_t MPR121::readRegister(MPR121_REGISTER const reg) const {
Nate Yonkee 9:8cb5ce483be3 426 char buf[1] = {reg}, data = 0;
Nate Yonkee 9:8cb5ce483be3 427 uint8_t result = 1;
Nate Yonkee 9:8cb5ce483be3 428
Nate Yonkee 9:8cb5ce483be3 429 result &= _i2c->write(_i2c_addr, buf, 1, true);
Nate Yonkee 9:8cb5ce483be3 430 result &= _i2c->read(_i2c_addr, &data, 1);
Nate Yonkee 9:8cb5ce483be3 431
Nathan Yonkee 12:22d36da8df91 432 if(result && DEBUG) {
Nate Yonkee 9:8cb5ce483be3 433 debug("I2C read failed\n");
Nate Yonkee 9:8cb5ce483be3 434 }
Nate Yonkee 9:8cb5ce483be3 435
Nate Yonkee 9:8cb5ce483be3 436 return data;
Nate Yonkee 9:8cb5ce483be3 437 }
Nathan Yonkee 12:22d36da8df91 438 >>>>>>> merge rev