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>
This commit is contained in:
Jon Trulson 2014-12-09 13:44:01 -07:00 committed by John Van Drasek
parent 2eb0047643
commit 0c63500b36
8 changed files with 498 additions and 0 deletions

View File

@ -65,6 +65,7 @@ add_executable (grovevdiv-example grovevdiv.cxx)
add_executable (grovewater-example grovewater.cxx)
add_executable (guvas12d-example guvas12d.cxx)
add_executable (groveloudness-example groveloudness.cxx)
add_executable (mpr121-example mpr121.cxx)
include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l)
include_directories (${PROJECT_SOURCE_DIR}/src/grove)
@ -117,6 +118,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/grovevdiv)
include_directories (${PROJECT_SOURCE_DIR}/src/grovewater)
include_directories (${PROJECT_SOURCE_DIR}/src/guvas12d)
include_directories (${PROJECT_SOURCE_DIR}/src/groveloudness)
include_directories (${PROJECT_SOURCE_DIR}/src/mpr121)
target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT})
@ -185,3 +187,4 @@ target_link_libraries (grovevdiv-example grovevdiv ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries (grovewater-example grovewater ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries (guvas12d-example guvas12d ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries (groveloudness-example groveloudness ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries (mpr121-example mpr121 ${CMAKE_THREAD_LIBS_INIT})

View File

@ -0,0 +1,69 @@
/*jslint node:true, vars:true, bitwise:true, unparam:true */
/*jshint unused:true */
/*global */
/*
* Author: Zion Orent <zorent@ics.com>
* Copyright (c) 2014 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
var touchSensor = require('jsupm_mpr121');
var myTouchSensor = new touchSensor.MPR121(touchSensor.MPR121_I2C_BUS, touchSensor.MPR121_DEFAULT_I2C_ADDR);
myTouchSensor.configAN3944();
setInterval(function()
{
myTouchSensor.readButtons();
printButtons(myTouchSensor);
}, 1000);
function printButtons(touchSensor)
{
var buttonPressed = false;
var outputStr = "Buttons Pressed: ";
for (var i=0; i<12; i++)
{
if (touchSensor.m_buttonStates & (1 << i))
{
outputStr += (i + " ");
buttonPressed = true;
}
}
if (!buttonPressed)
outputStr += "None";
console.log(outputStr);
if (touchSensor.m_overCurrentFault)
console.log("Over Current Fault detected!");
}
// Print message when exiting
process.on('SIGINT', function()
{
console.log("Exiting...");
process.exit(0);
});

88
examples/mpr121.cxx Normal file
View File

@ -0,0 +1,88 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2014 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <unistd.h>
#include <signal.h>
#include <iostream>
#include "mpr121.h"
using namespace std;
int shouldRun = true;
void sig_handler(int signo)
{
if (signo == SIGINT)
shouldRun = false;
}
void printButtons(upm::MPR121 *touch)
{
bool buttonPressed = false;
cout << "Buttons Pressed: ";
for (int i=0; i<12; i++)
{
if (touch->m_buttonStates & (1 << i))
{
cout << i << " ";
buttonPressed = true;
}
}
if (!buttonPressed)
cout << "None";
if (touch->m_overCurrentFault)
cout << "Over Current Fault detected!" << endl;
cout << endl;
}
int main(int argc, char **argv)
{
signal(SIGINT, sig_handler);
//! [Interesting]
// Instantiate an MPR121 on I2C bus 0
upm::MPR121 *touch = new upm::MPR121(MPR121_I2C_BUS, MPR121_DEFAULT_I2C_ADDR);
// init according to AN3944 defaults
touch->configAN3944();
while (shouldRun)
{
touch->readButtons();
printButtons(touch);
sleep(1);
}
//! [Interesting]
cout << "Exiting..." << endl;
delete touch;
return 0;
}

View File

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

View File

@ -0,0 +1,8 @@
%module jsupm_mpr121
%include "../upm.i"
%{
#include "mpr121.h"
%}
%include "mpr121.h"

204
src/mpr121/mpr121.cxx Normal file
View File

@ -0,0 +1,204 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2014 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <iostream>
#include <string>
#include "mpr121.h"
using namespace upm;
using namespace std;
MPR121::MPR121(int bus, uint8_t address)
{
// setup our i2c link
m_i2c = mraa_i2c_init(bus);
m_addr = address;
mraa_result_t ret = mraa_i2c_address(m_i2c, m_addr);
if (ret != MRAA_SUCCESS)
cerr << "MPR121: Could not initialize i2c bus. " << endl;
m_buttonStates = 0;
m_overCurrentFault = false;
}
MPR121::~MPR121()
{
mraa_i2c_stop(m_i2c);
}
mraa_result_t MPR121::writeBytes(uint8_t reg, uint8_t *buffer, unsigned int len)
{
if (!len || !buffer)
return MRAA_SUCCESS;
// create a buffer 1 byte larger than the supplied buffer,
// store the register in the first byte
uint8_t buf2[len + 1];
buf2[0] = reg;
// copy in the buffer after the reg byte
for (int i=1; i<(len + 1); i++)
buf2[i] = buffer[i-1];
mraa_i2c_address(m_i2c, m_addr);
return mraa_i2c_write(m_i2c, buf2, len + 1);
}
void MPR121::readBytes(uint8_t reg, uint8_t *buffer, unsigned int len)
{
if (!len || !buffer)
return;
// The usual mraa_i2c_read() does not work here, so we need to
// read each byte individually.
for (int i=0; i<len; i++)
buffer[i] = mraa_i2c_read_byte_data(m_i2c, reg + i);
return;
}
bool MPR121::configAN3944()
{
// Configure the mpr121 chip as recommended in the AN3944 MPR121
// Quick Start Guide
mraa_result_t rv;
// First, turn off all electrodes by zeroing out the Electrode Configuration
// register.
// If this one fails, it's unlikely any of the others will succeed.
uint8_t eleConf = 0x00;
if ((rv = writeBytes(0x5e, &eleConf, 1)) != MRAA_SUCCESS)
{
cerr << __FUNCTION__ << ": " << __LINE__<< ": I2C write failed." << endl;
return false;
}
// Section A
// Filtering when data is greater than baseline
// regs 0x2b-0x2e
uint8_t sectA[] = { 0x01, 0x01, 0x00, 0x00 };
if ((rv = writeBytes(0x2b, sectA, 4)) != MRAA_SUCCESS)
{
cerr << __FUNCTION__ << ": " << __LINE__<< ": I2C write failed." << endl;
return false;
}
// Section B
// Filtering when data is less than baseline
// regs 0x2f-0x32
uint8_t sectB[] = { 0x01, 0x01, 0xff, 0x02 };
if ((rv = writeBytes(0x2f, sectB, 4)) != MRAA_SUCCESS)
{
cerr << __FUNCTION__ << ": " << __LINE__<< ": I2C write failed." << endl;
return false;
}
// Section C
// Touch Threshold/Release registers, ELE0-ELE11
// regs 0x41-0x58
// __T_ __R_
uint8_t sectC[] = { 0x0f, 0x0a,
0x0f, 0x0a,
0x0f, 0x0a,
0x0f, 0x0a,
0x0f, 0x0a,
0x0f, 0x0a,
0x0f, 0x0a,
0x0f, 0x0a,
0x0f, 0x0a,
0x0f, 0x0a,
0x0f, 0x0a,
0x0f, 0x0a };
if ((rv = writeBytes(0x41, sectC, 24)) != MRAA_SUCCESS)
{
cerr << __FUNCTION__ << ": " << __LINE__<< ": I2C write failed." << endl;
return false;
}
// Section D
// Filter configuration
// reg 0x5d
uint8_t filterConf = 0x04;
if ((rv = writeBytes(0x5d, &filterConf, 1)) != MRAA_SUCCESS)
{
cerr << __FUNCTION__ << ": " << __LINE__<< ": I2C write failed." << endl;
return false;
}
// Section F
// Autoconfiguration registers
// regs 0x7b-0x7f
uint8_t sectF0 = 0x0b;
if ((rv = writeBytes(0x7b, &sectF0, 1)) != MRAA_SUCCESS)
{
cerr << __FUNCTION__ << ": " << __LINE__<< ": I2C write failed." << endl;
return false;
}
uint8_t sectF1[] = { 0x9c, 0x65, 0x8c };
if ((rv = writeBytes(0x7d, sectF1, 3)) != MRAA_SUCCESS)
{
cerr << __FUNCTION__ << ": " << __LINE__<< ": I2C write failed." << endl;
return false;
}
// Section E - this one must be set last, and switches to run mode
// Enable all 12 electrodes, and set a pre-calibration to avoid
// excessive calibration delay on startup.
// reg 0x5e
eleConf = 0x8c;
if ((rv = writeBytes(0x5e, &eleConf, 1)) != MRAA_SUCCESS)
{
cerr << __FUNCTION__ << ": " << __LINE__<< ": I2C write failed." << endl;
return false;
}
return true;
}
void MPR121::readButtons()
{
uint8_t rv;
uint8_t buffer[2];
// read in the 2 bytes at register 0x00-0x01, and setup the member
// variables accordingly.
readBytes(0x00, buffer, 2);
m_buttonStates = (buffer[0] | ((buffer[1] & 0x1f) << 8));
if (buffer[1] & 0x80)
m_overCurrentFault = true;
else
m_overCurrentFault = false;
return;
}

108
src/mpr121/mpr121.h Normal file
View File

@ -0,0 +1,108 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2014 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <string>
#include <mraa/i2c.h>
#define MPR121_I2C_BUS 0
#define MPR121_DEFAULT_I2C_ADDR 0x5a
namespace upm {
/**
* @brief C++ API for the MPR121 I2C touch sensor
*
* UPM module for the MPR121 touch sensor
*
* @ingroup i2c mpr121
* @snippet mpr121.cxx Interesting
*/
class MPR121 {
public:
/**
* mpr121 touch sensor constructor
*
* @param bus i2c bus to use
*/
MPR121(int bus, uint8_t address = MPR121_DEFAULT_I2C_ADDR);
/**
* MPR121 Destructor
*/
~MPR121();
/**
* Setup a default configuration, based on Application Note 3944
* (AN3944):
* http://cache.freescale.com/files/sensors/doc/app_note/AN3944.pdf
*
* After configuration, the sensor will be left in the Run State.
*
* @return True if configuration succeeded
*/
bool configAN3944();
/**
* Read the button states into the m_buttonStates member variable. Also
* set the m_overCurrentFault variable if an over current is detected.
*/
void readButtons();
/**
* Write value(s) into registers
*
* @param reg register location to start writing into
* @param buffer buffer for data storage
* @param len number of bytes to write
* @return mraa_result_t
*/
mraa_result_t writeBytes(uint8_t reg, uint8_t *buffer, unsigned int len);
/**
* Read value(s) from registers
*
* @param reg register location to start reading from
* @param buffer buffer for data storage
* @param len number of bytes to read
*/
void readBytes(uint8_t reg, uint8_t *buffer, unsigned int len);
/**
* button states
*/
uint16_t m_buttonStates;
/**
* Over current fault detected
*/
bool m_overCurrentFault;
private:
mraa_i2c_context m_i2c;
uint8_t m_addr;
};
}

13
src/mpr121/pyupm_mpr121.i Normal file
View File

@ -0,0 +1,13 @@
%module pyupm_mpr121
%include "../upm.i"
%feature("autodoc", "3");
#ifdef DOXYGEN
%include "mpr121_doc.i"
#endif
%include "mpr121.h"
%{
#include "mpr121.h"
%}