Kaynağa Gözat

mpr121: Initial implementation

This module implements support for the Grove I2C touch sensor
(mpr121).

Signed-off-by: Jon Trulson <jtrulson@ics.com>
Signed-off-by: Zion Orent <zorent@ics.com>
Signed-off-by: John Van Drasek <john.r.van.drasek@intel.com>
Jon Trulson 10 yıl önce
ebeveyn
işleme
0c63500b36

+ 3
- 0
examples/CMakeLists.txt Dosyayı Görüntüle

@@ -65,6 +65,7 @@ add_executable (grovevdiv-example grovevdiv.cxx)
65 65
 add_executable (grovewater-example grovewater.cxx)
66 66
 add_executable (guvas12d-example guvas12d.cxx)
67 67
 add_executable (groveloudness-example groveloudness.cxx)
68
+add_executable (mpr121-example mpr121.cxx)
68 69
 
69 70
 include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l)
70 71
 include_directories (${PROJECT_SOURCE_DIR}/src/grove)
@@ -117,6 +118,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/grovevdiv)
117 118
 include_directories (${PROJECT_SOURCE_DIR}/src/grovewater)
118 119
 include_directories (${PROJECT_SOURCE_DIR}/src/guvas12d)
119 120
 include_directories (${PROJECT_SOURCE_DIR}/src/groveloudness)
121
+include_directories (${PROJECT_SOURCE_DIR}/src/mpr121)
120 122
 
121 123
 target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT})
122 124
 target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT})
@@ -185,3 +187,4 @@ target_link_libraries (grovevdiv-example grovevdiv ${CMAKE_THREAD_LIBS_INIT})
185 187
 target_link_libraries (grovewater-example grovewater ${CMAKE_THREAD_LIBS_INIT})
186 188
 target_link_libraries (guvas12d-example guvas12d ${CMAKE_THREAD_LIBS_INIT})
187 189
 target_link_libraries (groveloudness-example groveloudness ${CMAKE_THREAD_LIBS_INIT})
190
+target_link_libraries (mpr121-example mpr121 ${CMAKE_THREAD_LIBS_INIT})

+ 69
- 0
examples/javascript/mpr121.js Dosyayı Görüntüle

@@ -0,0 +1,69 @@
1
+/*jslint node:true, vars:true, bitwise:true, unparam:true */
2
+/*jshint unused:true */
3
+/*global */
4
+/*
5
+* Author: Zion Orent <zorent@ics.com>
6
+* Copyright (c) 2014 Intel Corporation.
7
+*
8
+* Permission is hereby granted, free of charge, to any person obtaining
9
+* a copy of this software and associated documentation files (the
10
+* "Software"), to deal in the Software without restriction, including
11
+* without limitation the rights to use, copy, modify, merge, publish,
12
+* distribute, sublicense, and/or sell copies of the Software, and to
13
+* permit persons to whom the Software is furnished to do so, subject to
14
+* the following conditions:
15
+*
16
+* The above copyright notice and this permission notice shall be
17
+* included in all copies or substantial portions of the Software.
18
+*
19
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+*/
27
+
28
+var touchSensor = require('jsupm_mpr121');
29
+
30
+var myTouchSensor = new touchSensor.MPR121(touchSensor.MPR121_I2C_BUS, touchSensor.MPR121_DEFAULT_I2C_ADDR);
31
+
32
+myTouchSensor.configAN3944();
33
+
34
+setInterval(function()
35
+{
36
+	myTouchSensor.readButtons();
37
+	printButtons(myTouchSensor);
38
+}, 1000);
39
+
40
+function printButtons(touchSensor)
41
+{
42
+	var buttonPressed = false;
43
+
44
+	var outputStr = "Buttons Pressed: ";
45
+	for (var i=0; i<12; i++)
46
+	{
47
+		if (touchSensor.m_buttonStates & (1 << i))
48
+		{
49
+			outputStr += (i + " ");
50
+			buttonPressed = true;
51
+		}
52
+	}
53
+
54
+	if (!buttonPressed)
55
+		outputStr += "None";
56
+
57
+	console.log(outputStr);
58
+
59
+	if (touchSensor.m_overCurrentFault)
60
+		console.log("Over Current Fault detected!");
61
+}
62
+
63
+// Print message when exiting
64
+process.on('SIGINT', function()
65
+{
66
+	console.log("Exiting...");
67
+	process.exit(0);
68
+});
69
+

+ 88
- 0
examples/mpr121.cxx Dosyayı Görüntüle

@@ -0,0 +1,88 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2014 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <unistd.h>
26
+#include <signal.h>
27
+#include <iostream>
28
+#include "mpr121.h"
29
+
30
+using namespace std;
31
+
32
+int shouldRun = true;
33
+
34
+void sig_handler(int signo)
35
+{
36
+  if (signo == SIGINT)
37
+    shouldRun = false;
38
+}
39
+
40
+void printButtons(upm::MPR121 *touch)
41
+{
42
+  bool buttonPressed = false;
43
+
44
+  cout << "Buttons Pressed: ";
45
+  for (int i=0; i<12; i++)
46
+    {
47
+      if (touch->m_buttonStates & (1 << i))
48
+        {
49
+          cout << i << " ";
50
+          buttonPressed = true;
51
+        }
52
+    }
53
+
54
+  if (!buttonPressed)
55
+    cout << "None";
56
+
57
+  if (touch->m_overCurrentFault)
58
+    cout << "Over Current Fault detected!" << endl;
59
+
60
+  cout << endl;
61
+}
62
+
63
+int main(int argc, char **argv)
64
+{
65
+  signal(SIGINT, sig_handler);
66
+
67
+//! [Interesting]
68
+  // Instantiate an MPR121 on I2C bus 0
69
+
70
+  upm::MPR121 *touch = new upm::MPR121(MPR121_I2C_BUS, MPR121_DEFAULT_I2C_ADDR);
71
+
72
+  // init according to AN3944 defaults
73
+  touch->configAN3944();
74
+
75
+  while (shouldRun)
76
+    {
77
+      touch->readButtons();
78
+      printButtons(touch);
79
+      sleep(1);
80
+    }
81
+
82
+//! [Interesting]
83
+
84
+  cout << "Exiting..." << endl;
85
+
86
+  delete touch;
87
+  return 0;
88
+}

+ 5
- 0
src/mpr121/CMakeLists.txt Dosyayı Görüntüle

@@ -0,0 +1,5 @@
1
+set (libname "mpr121")
2
+set (libdescription "upm mpr121 I2C Touch module")
3
+set (module_src ${libname}.cxx)
4
+set (module_h ${libname}.h)
5
+upm_module_init()

+ 8
- 0
src/mpr121/jsupm_mpr121.i Dosyayı Görüntüle

@@ -0,0 +1,8 @@
1
+%module jsupm_mpr121
2
+%include "../upm.i"
3
+
4
+%{
5
+    #include "mpr121.h"
6
+%}
7
+
8
+%include "mpr121.h"

+ 204
- 0
src/mpr121/mpr121.cxx Dosyayı Görüntüle

@@ -0,0 +1,204 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2014 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <iostream>
26
+#include <string>
27
+
28
+#include "mpr121.h"
29
+
30
+using namespace upm;
31
+using namespace std;
32
+
33
+
34
+MPR121::MPR121(int bus, uint8_t address)
35
+{
36
+  // setup our i2c link
37
+  m_i2c = mraa_i2c_init(bus);
38
+
39
+  m_addr = address;
40
+
41
+  mraa_result_t ret = mraa_i2c_address(m_i2c, m_addr);
42
+
43
+  if (ret != MRAA_SUCCESS) 
44
+    cerr << "MPR121: Could not initialize i2c bus. " << endl;
45
+
46
+  m_buttonStates = 0;
47
+  m_overCurrentFault = false;
48
+}
49
+
50
+MPR121::~MPR121()
51
+{
52
+  mraa_i2c_stop(m_i2c);
53
+}
54
+
55
+mraa_result_t MPR121::writeBytes(uint8_t reg, uint8_t *buffer, unsigned int len)
56
+{
57
+  if (!len || !buffer)
58
+    return MRAA_SUCCESS;
59
+
60
+  // create a buffer 1 byte larger than the supplied buffer,
61
+  // store the register in the first byte
62
+  uint8_t buf2[len + 1];
63
+
64
+  buf2[0] = reg;
65
+
66
+  // copy in the buffer after the reg byte
67
+  for (int i=1; i<(len + 1); i++)
68
+    buf2[i] = buffer[i-1];
69
+
70
+  mraa_i2c_address(m_i2c, m_addr);
71
+
72
+  return mraa_i2c_write(m_i2c, buf2, len + 1);
73
+}
74
+
75
+void MPR121::readBytes(uint8_t reg, uint8_t *buffer, unsigned int len)
76
+{
77
+  if (!len || !buffer)
78
+    return;
79
+
80
+  // The usual mraa_i2c_read() does not work here, so we need to
81
+  // read each byte individually.
82
+  for (int i=0; i<len; i++)
83
+    buffer[i] = mraa_i2c_read_byte_data(m_i2c, reg + i);
84
+
85
+  return;
86
+}
87
+
88
+bool MPR121::configAN3944()
89
+{
90
+  // Configure the mpr121 chip as recommended in the AN3944 MPR121
91
+  // Quick Start Guide
92
+
93
+  mraa_result_t rv;
94
+
95
+  // First, turn off all electrodes by zeroing out the Electrode Configuration
96
+  // register.
97
+  // If this one fails, it's unlikely any of the others will succeed.
98
+  uint8_t eleConf = 0x00;
99
+  if ((rv = writeBytes(0x5e, &eleConf, 1)) != MRAA_SUCCESS)
100
+    {
101
+      cerr << __FUNCTION__ << ": " << __LINE__<< ": I2C write failed." << endl;
102
+      return false;
103
+    }
104
+
105
+  // Section A
106
+  // Filtering when data is greater than baseline
107
+  // regs 0x2b-0x2e
108
+  uint8_t sectA[] = { 0x01, 0x01, 0x00, 0x00 };
109
+  if ((rv = writeBytes(0x2b, sectA, 4)) != MRAA_SUCCESS)
110
+    {
111
+      cerr << __FUNCTION__ << ": " << __LINE__<< ": I2C write failed." << endl;
112
+      return false;
113
+    }
114
+
115
+  // Section B
116
+  // Filtering when data is less than baseline
117
+  // regs 0x2f-0x32
118
+  uint8_t sectB[] = { 0x01, 0x01, 0xff, 0x02 };
119
+  if ((rv = writeBytes(0x2f, sectB, 4)) != MRAA_SUCCESS)
120
+    {
121
+      cerr << __FUNCTION__ << ": " << __LINE__<< ": I2C write failed." << endl;
122
+      return false;
123
+    }
124
+
125
+  // Section C
126
+  // Touch Threshold/Release registers, ELE0-ELE11
127
+  // regs 0x41-0x58
128
+  //                __T_  __R_
129
+  uint8_t sectC[] = { 0x0f, 0x0a, 
130
+                      0x0f, 0x0a,
131
+                      0x0f, 0x0a,
132
+                      0x0f, 0x0a,
133
+                      0x0f, 0x0a,
134
+                      0x0f, 0x0a,
135
+                      0x0f, 0x0a,
136
+                      0x0f, 0x0a,
137
+                      0x0f, 0x0a,
138
+                      0x0f, 0x0a,
139
+                      0x0f, 0x0a,
140
+                      0x0f, 0x0a };
141
+  if ((rv = writeBytes(0x41, sectC, 24)) != MRAA_SUCCESS)
142
+    {
143
+      cerr << __FUNCTION__ << ": " << __LINE__<< ": I2C write failed." << endl;
144
+      return false;
145
+    }
146
+
147
+  // Section D
148
+  // Filter configuration
149
+  // reg 0x5d
150
+  uint8_t filterConf = 0x04;
151
+  if ((rv = writeBytes(0x5d, &filterConf, 1)) != MRAA_SUCCESS)
152
+    {
153
+      cerr << __FUNCTION__ << ": " << __LINE__<< ": I2C write failed." << endl;
154
+      return false;
155
+    }
156
+
157
+  // Section F
158
+  // Autoconfiguration registers
159
+  // regs 0x7b-0x7f
160
+  uint8_t sectF0 = 0x0b;
161
+  if ((rv = writeBytes(0x7b, &sectF0, 1)) != MRAA_SUCCESS)
162
+    {
163
+      cerr << __FUNCTION__ << ": " << __LINE__<< ": I2C write failed." << endl;
164
+      return false;
165
+    }
166
+  uint8_t sectF1[] = { 0x9c, 0x65, 0x8c };
167
+  if ((rv = writeBytes(0x7d, sectF1, 3)) != MRAA_SUCCESS)
168
+    {
169
+      cerr << __FUNCTION__ << ": " << __LINE__<< ": I2C write failed." << endl;
170
+      return false;
171
+    }
172
+
173
+  // Section E - this one must be set last, and switches to run mode
174
+  // Enable all 12 electrodes, and set a pre-calibration to avoid
175
+  // excessive calibration delay on startup.
176
+  // reg 0x5e
177
+  eleConf = 0x8c;
178
+  if ((rv = writeBytes(0x5e, &eleConf, 1)) != MRAA_SUCCESS)
179
+    {
180
+      cerr << __FUNCTION__ << ": " << __LINE__<< ": I2C write failed." << endl;
181
+      return false;
182
+    }
183
+
184
+  return true;
185
+}
186
+
187
+void MPR121::readButtons()
188
+{
189
+  uint8_t rv;
190
+  uint8_t buffer[2];
191
+
192
+  // read in the 2 bytes at register 0x00-0x01, and setup the member
193
+  // variables accordingly.
194
+
195
+  readBytes(0x00, buffer, 2);
196
+
197
+  m_buttonStates = (buffer[0] | ((buffer[1] & 0x1f) << 8));
198
+  if (buffer[1] & 0x80)
199
+    m_overCurrentFault = true;
200
+  else
201
+    m_overCurrentFault = false;
202
+
203
+  return;
204
+}

+ 108
- 0
src/mpr121/mpr121.h Dosyayı Görüntüle

@@ -0,0 +1,108 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2014 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+#pragma once
25
+
26
+#include <string>
27
+#include <mraa/i2c.h>
28
+
29
+#define MPR121_I2C_BUS     0
30
+#define MPR121_DEFAULT_I2C_ADDR    0x5a
31
+
32
+namespace upm {
33
+
34
+  /**
35
+   * @brief C++ API for the MPR121 I2C touch sensor
36
+   *
37
+   * UPM module for the MPR121 touch sensor
38
+   *
39
+   * @ingroup i2c mpr121
40
+   * @snippet mpr121.cxx Interesting
41
+   */
42
+  class MPR121 {
43
+  public:
44
+    /**
45
+     * mpr121 touch sensor constructor
46
+     *
47
+     * @param bus i2c bus to use
48
+     */
49
+    MPR121(int bus, uint8_t address = MPR121_DEFAULT_I2C_ADDR);
50
+
51
+    /**
52
+     * MPR121 Destructor
53
+     */
54
+    ~MPR121();
55
+
56
+    /**
57
+     * Setup a default configuration, based on Application Note 3944
58
+     * (AN3944):
59
+     * http://cache.freescale.com/files/sensors/doc/app_note/AN3944.pdf
60
+     *
61
+     * After configuration, the sensor will be left in the Run State.
62
+     *
63
+     * @return True if configuration succeeded
64
+     */
65
+    bool configAN3944();
66
+
67
+    /**
68
+     * Read the button states into the m_buttonStates member variable.  Also
69
+     * set the m_overCurrentFault variable if an over current is detected.
70
+     */
71
+    void readButtons();
72
+
73
+    /**
74
+     * Write value(s) into registers
75
+     *
76
+     * @param reg register location to start writing into
77
+     * @param buffer buffer for data storage
78
+     * @param len number of bytes to write
79
+     * @return mraa_result_t
80
+     */
81
+    mraa_result_t writeBytes(uint8_t reg, uint8_t *buffer, unsigned int len);
82
+
83
+    /**
84
+     * Read value(s) from registers
85
+     *
86
+     * @param reg register location to start reading from
87
+     * @param buffer buffer for data storage
88
+     * @param len number of bytes to read
89
+     */
90
+    void readBytes(uint8_t reg, uint8_t *buffer, unsigned int len);
91
+
92
+    /**
93
+     * button states
94
+     */
95
+    uint16_t m_buttonStates;
96
+
97
+    /**
98
+     * Over current fault detected
99
+     */
100
+    bool m_overCurrentFault;
101
+
102
+  private:
103
+    mraa_i2c_context m_i2c;
104
+    uint8_t m_addr;
105
+  };
106
+}
107
+
108
+

+ 13
- 0
src/mpr121/pyupm_mpr121.i Dosyayı Görüntüle

@@ -0,0 +1,13 @@
1
+%module pyupm_mpr121
2
+%include "../upm.i"
3
+
4
+%feature("autodoc", "3");
5
+
6
+#ifdef DOXYGEN
7
+%include "mpr121_doc.i"
8
+#endif
9
+
10
+%include "mpr121.h"
11
+%{
12
+    #include "mpr121.h"
13
+%}