annotate examples/06-Sensors/mpr121/I2C_MPR121.cpp @ 484:afbc8f973bb3 prerelease

update_board can skip updating the IDE
author Giulio Moro <giuliomoro@yahoo.it>
date Tue, 21 Jun 2016 15:16:55 +0100
parents 8fcfbfb32aa0
children
rev   line source
robert@464 1 /*
robert@464 2 * I2C_MPR121.cpp
robert@464 3 *
robert@464 4 * Created on: Oct 14, 2013
robert@464 5 * Author: Victor Zappi
robert@464 6 */
robert@464 7
robert@464 8
robert@464 9 #include "I2C_MPR121.h"
robert@464 10
robert@464 11 I2C_MPR121::I2C_MPR121() {
robert@464 12
robert@464 13 }
robert@464 14
robert@464 15 boolean I2C_MPR121::begin(uint8_t bus, uint8_t i2caddr) {
robert@464 16 _i2c_address = i2caddr;
robert@464 17
robert@464 18 if(initI2C_RW(bus, i2caddr, 0) > 0)
robert@464 19 return false;
robert@464 20
robert@464 21 // soft reset
robert@464 22 writeRegister(MPR121_SOFTRESET, 0x63);
robert@464 23 usleep(1000);
robert@464 24 //delay(1);
robert@464 25 for (uint8_t i=0; i<0x7F; i++) {
robert@464 26 // Serial.print("$"); Serial.print(i, HEX);
robert@464 27 // Serial.print(": 0x"); Serial.println(readRegister8(i));
robert@464 28 }
robert@464 29
robert@464 30
robert@464 31 writeRegister(MPR121_ECR, 0x0);
robert@464 32
robert@464 33 uint8_t c = readRegister8(MPR121_CONFIG2);
robert@464 34
robert@464 35 if (c != 0x24) {
robert@464 36 rt_printf("MPR121 read 0x%x instead of 0x24\n", c);
robert@464 37 return false;
robert@464 38 }
robert@464 39
robert@464 40 setThresholds(12, 6);
robert@464 41 writeRegister(MPR121_MHDR, 0x01);
robert@464 42 writeRegister(MPR121_NHDR, 0x01);
robert@464 43 writeRegister(MPR121_NCLR, 0x0E);
robert@464 44 writeRegister(MPR121_FDLR, 0x00);
robert@464 45
robert@464 46 writeRegister(MPR121_MHDF, 0x01);
robert@464 47 writeRegister(MPR121_NHDF, 0x05);
robert@464 48 writeRegister(MPR121_NCLF, 0x01);
robert@464 49 writeRegister(MPR121_FDLF, 0x00);
robert@464 50
robert@464 51 writeRegister(MPR121_NHDT, 0x00);
robert@464 52 writeRegister(MPR121_NCLT, 0x00);
robert@464 53 writeRegister(MPR121_FDLT, 0x00);
robert@464 54
robert@464 55 writeRegister(MPR121_DEBOUNCE, 0);
robert@464 56 writeRegister(MPR121_CONFIG1, 0x10); // default, 16uA charge current
robert@464 57 writeRegister(MPR121_CONFIG2, 0x20); // 0.5uS encoding, 1ms period
robert@464 58
robert@464 59 // writeRegister(MPR121_AUTOCONFIG0, 0x8F);
robert@464 60
robert@464 61 // writeRegister(MPR121_UPLIMIT, 150);
robert@464 62 // writeRegister(MPR121_TARGETLIMIT, 100); // should be ~400 (100 shifted)
robert@464 63 // writeRegister(MPR121_LOWLIMIT, 50);
robert@464 64 // enable all electrodes
robert@464 65 writeRegister(MPR121_ECR, 0x8F); // start with first 5 bits of baseline tracking
robert@464 66
robert@464 67 return true;
robert@464 68 }
robert@464 69
robert@464 70 void I2C_MPR121::setThresholds(uint8_t touch, uint8_t release) {
robert@464 71 for (uint8_t i=0; i<12; i++) {
robert@464 72 writeRegister(MPR121_TOUCHTH_0 + 2*i, touch);
robert@464 73 writeRegister(MPR121_RELEASETH_0 + 2*i, release);
robert@464 74 }
robert@464 75 }
robert@464 76
robert@464 77 uint16_t I2C_MPR121::filteredData(uint8_t t) {
robert@464 78 if (t > 12) return 0;
robert@464 79 return readRegister16(MPR121_FILTDATA_0L + t*2);
robert@464 80 }
robert@464 81
robert@464 82 uint16_t I2C_MPR121::baselineData(uint8_t t) {
robert@464 83 if (t > 12) return 0;
robert@464 84 uint16_t bl = readRegister8(MPR121_BASELINE_0 + t);
robert@464 85 return (bl << 2);
robert@464 86 }
robert@464 87
robert@464 88 uint16_t I2C_MPR121::touched(void) {
robert@464 89 uint16_t t = readRegister16(MPR121_TOUCHSTATUS_L);
robert@464 90 return t & 0x0FFF;
robert@464 91 }
robert@464 92
robert@464 93 /*********************************************************************/
robert@464 94
robert@464 95
robert@464 96 uint8_t I2C_MPR121::readRegister8(uint8_t reg) {
robert@464 97 unsigned char inbuf, outbuf;
robert@464 98 struct i2c_rdwr_ioctl_data packets;
robert@464 99 struct i2c_msg messages[2];
robert@464 100
robert@464 101 /*
robert@464 102 * In order to read a register, we first do a "dummy write" by writing
robert@464 103 * 0 bytes to the register we want to read from. This is similar to
robert@464 104 * the packet in set_i2c_register, except it's 1 byte rather than 2.
robert@464 105 */
robert@464 106 outbuf = reg;
robert@464 107 messages[0].addr = 0x5A;
robert@464 108 messages[0].flags = 0;
robert@464 109 messages[0].len = sizeof(outbuf);
robert@464 110 messages[0].buf = &outbuf;
robert@464 111
robert@464 112 /* The data will get returned in this structure */
robert@464 113 messages[1].addr = 0x5A;
robert@464 114 messages[1].flags = I2C_M_RD/* | I2C_M_NOSTART*/;
robert@464 115 messages[1].len = sizeof(inbuf);
robert@464 116 messages[1].buf = &inbuf;
robert@464 117
robert@464 118 /* Send the request to the kernel and get the result back */
robert@464 119 packets.msgs = messages;
robert@464 120 packets.nmsgs = 2;
robert@464 121 if(ioctl(i2C_file, I2C_RDWR, &packets) < 0) {
robert@464 122 rt_printf("Unable to send data");
robert@464 123 return 0;
robert@464 124 }
robert@464 125
robert@464 126 return inbuf;
robert@464 127 }
robert@464 128
robert@464 129 uint16_t I2C_MPR121::readRegister16(uint8_t reg) {
robert@464 130 unsigned char inbuf[2], outbuf;
robert@464 131 struct i2c_rdwr_ioctl_data packets;
robert@464 132 struct i2c_msg messages[2];
robert@464 133
robert@464 134 /*
robert@464 135 * In order to read a register, we first do a "dummy write" by writing
robert@464 136 * 0 bytes to the register we want to read from. This is similar to
robert@464 137 * the packet in set_i2c_register, except it's 1 byte rather than 2.
robert@464 138 */
robert@464 139 outbuf = reg;
robert@464 140 messages[0].addr = _i2c_address;
robert@464 141 messages[0].flags = 0;
robert@464 142 messages[0].len = sizeof(outbuf);
robert@464 143 messages[0].buf = &outbuf;
robert@464 144
robert@464 145 /* The data will get returned in this structure */
robert@464 146 messages[1].addr = _i2c_address;
robert@464 147 messages[1].flags = I2C_M_RD/* | I2C_M_NOSTART*/;
robert@464 148 messages[1].len = sizeof(inbuf);
robert@464 149 messages[1].buf = inbuf;
robert@464 150
robert@464 151 /* Send the request to the kernel and get the result back */
robert@464 152 packets.msgs = messages;
robert@464 153 packets.nmsgs = 2;
robert@464 154 if(ioctl(i2C_file, I2C_RDWR, &packets) < 0) {
robert@464 155 rt_printf("Unable to send data");
robert@464 156 return 0;
robert@464 157 }
robert@464 158
robert@464 159 return (uint16_t)inbuf[0] | (((uint16_t)inbuf[1]) << 8);
robert@464 160 }
robert@464 161
robert@464 162 /**************************************************************************/
robert@464 163 /*!
robert@464 164 @brief Writes 8-bits to the specified destination register
robert@464 165 */
robert@464 166 /**************************************************************************/
robert@464 167 void I2C_MPR121::writeRegister(uint8_t reg, uint8_t value) {
robert@464 168 uint8_t buf[2] = { reg, value };
robert@464 169
robert@464 170 if(write(i2C_file, buf, 2) != 2)
robert@464 171 {
robert@464 172 cout << "Failed to write register " << (int)reg << " on MPR121\n";
robert@464 173 return;
robert@464 174 }
robert@464 175 }
robert@464 176