Mercurial > hg > beaglert
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 |