Start of a microbit mpr121 library

Dependents:   microbitmpr121-example

Committer:
owenbrotherwood
Date:
Mon Jan 16 23:02:19 2017 +0000
Revision:
8:cda72c6b04c0
Parent:
7:ac942cee2975
ok;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
owenbrotherwood 4:f63476855239 1 /*
owenbrotherwood 4:f63476855239 2 The MIT License (MIT)
owenbrotherwood 4:f63476855239 3
owenbrotherwood 4:f63476855239 4 Copyright (c) 2016 British Broadcasting Corporation.
owenbrotherwood 4:f63476855239 5 This software is provided by Lancaster University by arrangement with the BBC.
owenbrotherwood 0:fb4572fc4901 6
owenbrotherwood 4:f63476855239 7 Permission is hereby granted, free of charge, to any person obtaining a
owenbrotherwood 4:f63476855239 8 copy of this software and associated documentation files (the "Software"),
owenbrotherwood 4:f63476855239 9 to deal in the Software without restriction, including without limitation
owenbrotherwood 4:f63476855239 10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
owenbrotherwood 4:f63476855239 11 and/or sell copies of the Software, and to permit persons to whom the
owenbrotherwood 4:f63476855239 12 Software is furnished to do so, subject to the following conditions:
owenbrotherwood 4:f63476855239 13
owenbrotherwood 4:f63476855239 14 The above copyright notice and this permission notice shall be included in
owenbrotherwood 4:f63476855239 15 all copies or substantial portions of the Software.
owenbrotherwood 4:f63476855239 16
owenbrotherwood 4:f63476855239 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
owenbrotherwood 4:f63476855239 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
owenbrotherwood 4:f63476855239 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
owenbrotherwood 4:f63476855239 20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
owenbrotherwood 4:f63476855239 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
owenbrotherwood 4:f63476855239 22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
owenbrotherwood 4:f63476855239 23 DEALINGS IN THE SOFTWARE.
owenbrotherwood 4:f63476855239 24 */
owenbrotherwood 1:f6fed00a3ff2 25
owenbrotherwood 4:f63476855239 26 #include "MicroBitConfig.h"
owenbrotherwood 4:f63476855239 27 #include "MicroBitPin.h"
owenbrotherwood 4:f63476855239 28 #include "MicroBitMpr121.h"
owenbrotherwood 4:f63476855239 29 #include "MicroBitFiber.h"
owenbrotherwood 4:f63476855239 30 #include "ErrorNo.h"
owenbrotherwood 4:f63476855239 31
owenbrotherwood 4:f63476855239 32 void MicroBitMpr121::init(uint16_t id, uint16_t address)
owenbrotherwood 0:fb4572fc4901 33 {
owenbrotherwood 4:f63476855239 34 this->id = id;
owenbrotherwood 4:f63476855239 35 this->address = address;
owenbrotherwood 4:f63476855239 36
owenbrotherwood 6:103a5a2ca571 37 // setup and registers - start with POR values (must be in stop mode)
owenbrotherwood 6:103a5a2ca571 38 MicroBitMpr121::writeCommand(SRST, 0x63); //REG 0x80
owenbrotherwood 6:103a5a2ca571 39
owenbrotherwood 6:103a5a2ca571 40 // Baseline Filtering Control Register (changes response sensitivity)
owenbrotherwood 6:103a5a2ca571 41 // http://cache.freescale.com/files/sensors/doc/app_note/AN3891.pdf
owenbrotherwood 6:103a5a2ca571 42 MicroBitMpr121::writeCommand(MHDR, 0x1); //REG 0x2B
owenbrotherwood 6:103a5a2ca571 43 MicroBitMpr121::writeCommand(NHDR, 0x1); //REG 0x2C
owenbrotherwood 6:103a5a2ca571 44 MicroBitMpr121::writeCommand(NCLR, 0x0); //REG 0x2D
owenbrotherwood 6:103a5a2ca571 45 MicroBitMpr121::writeCommand(FDLR, 0x0); //REG 0x2E
owenbrotherwood 6:103a5a2ca571 46 MicroBitMpr121::writeCommand(MHDF, 0x1); //REG 0x2F
owenbrotherwood 6:103a5a2ca571 47 MicroBitMpr121::writeCommand(NHDF, 0x1); //REG 0x30
owenbrotherwood 6:103a5a2ca571 48 MicroBitMpr121::writeCommand(NCLF, 0xFF); //REG 0x31
owenbrotherwood 6:103a5a2ca571 49 MicroBitMpr121::writeCommand(FDLF, 0x2); //REG 0x32
owenbrotherwood 6:103a5a2ca571 50
owenbrotherwood 6:103a5a2ca571 51 // Touch / Release Threshold
owenbrotherwood 6:103a5a2ca571 52 // cache.freescale.com/files/sensors/doc/app_note/AN3892.pdf
owenbrotherwood 6:103a5a2ca571 53 for(int i=0; i<(12*2); i+=2) { // touch
owenbrotherwood 6:103a5a2ca571 54 MicroBitMpr121::writeCommand(static_cast<MPR121_REGISTER>(E0TTH+i), 0x20); //REG 0x41...0x58 odd
owenbrotherwood 6:103a5a2ca571 55 }
owenbrotherwood 6:103a5a2ca571 56 for(int i=0; i<(12*2); i+=2) { // release
owenbrotherwood 6:103a5a2ca571 57 MicroBitMpr121::writeCommand(static_cast<MPR121_REGISTER>(E0RTH+i), 0x10); //REG 0x41...0x58 even
owenbrotherwood 6:103a5a2ca571 58 }
owenbrotherwood 6:103a5a2ca571 59
owenbrotherwood 6:103a5a2ca571 60 // Debounce Register DR=b6...4, DT=b2...0
owenbrotherwood 6:103a5a2ca571 61 MicroBitMpr121::writeCommand(DT_DR, 0x11); //REG 0x5B
owenbrotherwood 6:103a5a2ca571 62
owenbrotherwood 6:103a5a2ca571 63 // Filter and Global CDC CDT Configuration (sample time, charge current)
owenbrotherwood 6:103a5a2ca571 64 MicroBitMpr121::writeCommand(CDC_CONFIG, 0x10); //REG 0x5C default 10
owenbrotherwood 6:103a5a2ca571 65 MicroBitMpr121::writeCommand(CDT_CONFIG, 0x20); //REG 0x5D default 24
owenbrotherwood 6:103a5a2ca571 66
owenbrotherwood 6:103a5a2ca571 67 // Auto-Configuration Registers
owenbrotherwood 6:103a5a2ca571 68 // http://cache.freescale.com/files/sensors/doc/app_note/AN3889.pdf
owenbrotherwood 6:103a5a2ca571 69 MicroBitMpr121::writeCommand(AUTO_CFG0, 0x33); // REG 0x7B
owenbrotherwood 6:103a5a2ca571 70 MicroBitMpr121::writeCommand(AUTO_CFG1, 0x07); // REG 0x7C
owenbrotherwood 6:103a5a2ca571 71 MicroBitMpr121::writeCommand(USL, 0xc9); // REG 0x7D((3.3-.07)/3.3) * 256
owenbrotherwood 6:103a5a2ca571 72 MicroBitMpr121::writeCommand(LSL, 0x83); // REG 0x7E((3.3-.07)/3.3) * 256 * 0.65f
owenbrotherwood 6:103a5a2ca571 73 MicroBitMpr121::writeCommand(TL, 0xb5); // REG 0x7F((3.3-.07)/3.3) * 256 * 0.9f
owenbrotherwood 6:103a5a2ca571 74 // 255 > USL > TL > LSL > 0
owenbrotherwood 6:103a5a2ca571 75
owenbrotherwood 6:103a5a2ca571 76 // Electrode Configuration Register - enable all 12 and start
owenbrotherwood 6:103a5a2ca571 77 MicroBitMpr121::writeCommand(ECR, 0x8f);
owenbrotherwood 6:103a5a2ca571 78
owenbrotherwood 4:f63476855239 79 // Indicate that we're up and running.
owenbrotherwood 4:f63476855239 80 status |= MICROBIT_COMPONENT_RUNNING;
owenbrotherwood 0:fb4572fc4901 81 }
owenbrotherwood 0:fb4572fc4901 82
owenbrotherwood 6:103a5a2ca571 83 MicroBitMpr121::MicroBitMpr121(MicroBitI2C& _i2c, uint16_t address, DigitalIn intPin, uint16_t id) :
owenbrotherwood 6:103a5a2ca571 84 int1(intPin), // Not sure what this does :( and is our pin needs to be pull up !!!!!!!!!!!!!!
owenbrotherwood 4:f63476855239 85 i2c(_i2c)
owenbrotherwood 6:103a5a2ca571 86
owenbrotherwood 0:fb4572fc4901 87 {
owenbrotherwood 4:f63476855239 88 init(id, address);
owenbrotherwood 0:fb4572fc4901 89 }
owenbrotherwood 0:fb4572fc4901 90
owenbrotherwood 6:103a5a2ca571 91 void MicroBitMpr121::enable(void)
owenbrotherwood 6:103a5a2ca571 92 {
owenbrotherwood 6:103a5a2ca571 93 _button = 0;
owenbrotherwood 6:103a5a2ca571 94 _button_has_changed = 0;
owenbrotherwood 6:103a5a2ca571 95 // enable the 12 electrodes - allow disable to put device into
owenbrotherwood 6:103a5a2ca571 96 // lower current consumption mode
owenbrotherwood 6:103a5a2ca571 97 MicroBitMpr121::writeCommand(ECR, 0x8f);
owenbrotherwood 6:103a5a2ca571 98 // and attach the interrupt handler TODO
owenbrotherwood 6:103a5a2ca571 99 // _irq->fall(this, &MicroBitMpr121::handler);
owenbrotherwood 6:103a5a2ca571 100
owenbrotherwood 6:103a5a2ca571 101 return;
owenbrotherwood 6:103a5a2ca571 102 }
owenbrotherwood 6:103a5a2ca571 103
owenbrotherwood 8:cda72c6b04c0 104 void MicroBitMpr121::registerDump()
owenbrotherwood 6:103a5a2ca571 105 {
owenbrotherwood 8:cda72c6b04c0 106 for(uint8_t i=0; i<0x80; i++) {
owenbrotherwood 8:cda72c6b04c0 107 int response = read8(i);
owenbrotherwood 8:cda72c6b04c0 108 printf("Reg 0x%02x: 0x%02x \n", i, response);
owenbrotherwood 6:103a5a2ca571 109 }
owenbrotherwood 6:103a5a2ca571 110 return;
owenbrotherwood 6:103a5a2ca571 111 }
owenbrotherwood 6:103a5a2ca571 112
owenbrotherwood 6:103a5a2ca571 113 void MicroBitMpr121::disable(void)
owenbrotherwood 6:103a5a2ca571 114 {
owenbrotherwood 6:103a5a2ca571 115 // detach the interrupt handler TODO
owenbrotherwood 6:103a5a2ca571 116 //_irq->fall(NULL);
owenbrotherwood 6:103a5a2ca571 117 _button = 0;
owenbrotherwood 6:103a5a2ca571 118 _button_has_changed = 0;
owenbrotherwood 6:103a5a2ca571 119 // put the device in low current consumption mode - dont re-init registers
owenbrotherwood 6:103a5a2ca571 120 MicroBitMpr121::writeCommand(ECR, 0x0);
owenbrotherwood 6:103a5a2ca571 121 MicroBitMpr121::writeCommand(AUTO_CFG0, 0x0); // REG 0x7B
owenbrotherwood 6:103a5a2ca571 122 MicroBitMpr121::writeCommand(AUTO_CFG1, 0x0); // REG 0x7C
owenbrotherwood 6:103a5a2ca571 123
owenbrotherwood 6:103a5a2ca571 124 return;
owenbrotherwood 6:103a5a2ca571 125 }
owenbrotherwood 6:103a5a2ca571 126
owenbrotherwood 4:f63476855239 127 int MicroBitMpr121::writeCommand(uint8_t reg, uint8_t value)
owenbrotherwood 0:fb4572fc4901 128 {
owenbrotherwood 4:f63476855239 129 uint8_t command[2];
owenbrotherwood 4:f63476855239 130 command[0] = reg;
owenbrotherwood 4:f63476855239 131 command[1] = value;
owenbrotherwood 4:f63476855239 132
owenbrotherwood 4:f63476855239 133 return i2c.write(address, (const char *)command, 2);
owenbrotherwood 0:fb4572fc4901 134 }
owenbrotherwood 0:fb4572fc4901 135
owenbrotherwood 4:f63476855239 136 int MicroBitMpr121::readCommand(uint8_t reg, uint8_t* buffer, int length)
owenbrotherwood 0:fb4572fc4901 137 {
owenbrotherwood 4:f63476855239 138 int result;
owenbrotherwood 4:f63476855239 139
owenbrotherwood 4:f63476855239 140 if (buffer == NULL || length <= 0)
owenbrotherwood 4:f63476855239 141 return MICROBIT_INVALID_PARAMETER;
owenbrotherwood 0:fb4572fc4901 142
owenbrotherwood 4:f63476855239 143 result = i2c.write(address, (const char *)&reg, 1, true);
owenbrotherwood 4:f63476855239 144 if (result !=0)
owenbrotherwood 4:f63476855239 145 return MICROBIT_I2C_ERROR;
owenbrotherwood 4:f63476855239 146
owenbrotherwood 4:f63476855239 147 result = i2c.read(address, (char *)buffer, length);
owenbrotherwood 4:f63476855239 148 if (result !=0)
owenbrotherwood 4:f63476855239 149 return MICROBIT_I2C_ERROR;
owenbrotherwood 4:f63476855239 150
owenbrotherwood 4:f63476855239 151 return MICROBIT_OK;
owenbrotherwood 0:fb4572fc4901 152 }
owenbrotherwood 0:fb4572fc4901 153
owenbrotherwood 4:f63476855239 154 int MicroBitMpr121::read16(uint8_t reg)
owenbrotherwood 0:fb4572fc4901 155 {
owenbrotherwood 4:f63476855239 156 uint8_t cmd[2];
owenbrotherwood 4:f63476855239 157 int result;
owenbrotherwood 4:f63476855239 158
owenbrotherwood 4:f63476855239 159 cmd[0] = reg;
owenbrotherwood 4:f63476855239 160 result = i2c.write(address, (const char *)cmd, 1);
owenbrotherwood 4:f63476855239 161 if (result !=0)
owenbrotherwood 4:f63476855239 162 return MICROBIT_I2C_ERROR;
owenbrotherwood 1:f6fed00a3ff2 163
owenbrotherwood 4:f63476855239 164 cmd[0] = 0x00;
owenbrotherwood 4:f63476855239 165 cmd[1] = 0x00;
owenbrotherwood 1:f6fed00a3ff2 166
owenbrotherwood 4:f63476855239 167 result = i2c.read(address, (char *)cmd, 2);
owenbrotherwood 4:f63476855239 168 if (result !=0)
owenbrotherwood 4:f63476855239 169 return MICROBIT_I2C_ERROR;
owenbrotherwood 4:f63476855239 170
owenbrotherwood 4:f63476855239 171 return (int16_t) ((cmd[1] | (cmd[0] << 8))); //concatenate the MSB and LSB
owenbrotherwood 0:fb4572fc4901 172 }
owenbrotherwood 0:fb4572fc4901 173
owenbrotherwood 4:f63476855239 174 int MicroBitMpr121::read8(uint8_t reg)
owenbrotherwood 0:fb4572fc4901 175 {
owenbrotherwood 4:f63476855239 176 uint8_t data;
owenbrotherwood 4:f63476855239 177 int result;
owenbrotherwood 4:f63476855239 178
owenbrotherwood 4:f63476855239 179 data = 0;
owenbrotherwood 4:f63476855239 180 result = readCommand(reg, (uint8_t*) &data, 1);
owenbrotherwood 4:f63476855239 181 if (result != MICROBIT_OK)
owenbrotherwood 4:f63476855239 182 return MICROBIT_I2C_ERROR;
owenbrotherwood 4:f63476855239 183
owenbrotherwood 4:f63476855239 184 return data;
owenbrotherwood 0:fb4572fc4901 185 }
owenbrotherwood 0:fb4572fc4901 186
owenbrotherwood 4:f63476855239 187 void MicroBitMpr121::idleTick()
owenbrotherwood 0:fb4572fc4901 188 {
owenbrotherwood 6:103a5a2ca571 189
owenbrotherwood 0:fb4572fc4901 190 }
owenbrotherwood 0:fb4572fc4901 191
owenbrotherwood 4:f63476855239 192 int MicroBitMpr121::whoAmI()
owenbrotherwood 0:fb4572fc4901 193 {
owenbrotherwood 4:f63476855239 194 uint8_t data;
owenbrotherwood 4:f63476855239 195 int result;
owenbrotherwood 4:f63476855239 196
owenbrotherwood 6:103a5a2ca571 197 // result = readCommand(MPR121_WHOAMI, &data, 1);
owenbrotherwood 4:f63476855239 198 if (result != MICROBIT_OK)
owenbrotherwood 4:f63476855239 199 return MICROBIT_I2C_ERROR;
owenbrotherwood 4:f63476855239 200
owenbrotherwood 4:f63476855239 201 return (int)data;
owenbrotherwood 0:fb4572fc4901 202 }
owenbrotherwood 4:f63476855239 203
owenbrotherwood 4:f63476855239 204 MicroBitMpr121::~MicroBitMpr121()
owenbrotherwood 4:f63476855239 205 {
owenbrotherwood 4:f63476855239 206 fiber_remove_idle_component(this);
owenbrotherwood 4:f63476855239 207 }