comparison projects/mpr121/I2C_MPR121.cpp @ 268:8d80eda512cd prerelease

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