use mbed os

Dependents:   Seeed_Grove_I2C_Touch_Example

Fork of MPR121 by Sam Grove

Committer:
Nathan Yonkee
Date:
Sun Jul 02 11:26:36 2017 -0600
Revision:
15:8c7fba79a28e
Parent:
12:22d36da8df91
Child:
19:eaa64138290b
merge

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 }