diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index 67b07cf1..ae80b472 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -96,6 +96,7 @@ add_executable (grovegsr-example grovegsr.cxx) add_executable (ina132-example ina132.cxx) add_executable (l298-example l298.cxx) add_executable (l298-stepper-example l298-stepper.cxx) +add_executable (at42qt1070-example at42qt1070.cxx) include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l) include_directories (${PROJECT_SOURCE_DIR}/src/grove) @@ -173,6 +174,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/groveo2) include_directories (${PROJECT_SOURCE_DIR}/src/grovegsr) include_directories (${PROJECT_SOURCE_DIR}/src/ina132) include_directories (${PROJECT_SOURCE_DIR}/src/l298) +include_directories (${PROJECT_SOURCE_DIR}/src/at42qt1070) target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT}) @@ -270,3 +272,4 @@ target_link_libraries (grovegsr-example grovegsr ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (ina132-example ina132 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (l298-example l298 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (l298-stepper-example l298 ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries (at42qt1070-example at42qt1070 ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/c++/at42qt1070.cxx b/examples/c++/at42qt1070.cxx new file mode 100644 index 00000000..c22a9980 --- /dev/null +++ b/examples/c++/at42qt1070.cxx @@ -0,0 +1,90 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 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 +#include +#include +#include "at42qt1070.h" + +using namespace std; + +int shouldRun = true; + +void sig_handler(int signo) +{ + if (signo == SIGINT) + shouldRun = false; +} + +void printButtons(upm::AT42QT1070 *touch) +{ + bool buttonPressed = false; + uint8_t buttons = touch->getButtons(); + + cout << "Buttons Pressed: "; + for (int i=0; i<7; i++) + { + if (buttons & (1 << i)) + { + cout << i << " "; + buttonPressed = true; + } + } + + if (!buttonPressed) + cout << "None"; + + cout << endl; + + if (touch->isCalibrating()) + cout << "Calibration is occurring." << endl; + + if (touch->isOverflowed()) + cout << "Overflow was detected." << endl; +} + +int main(int argc, char **argv) +{ + signal(SIGINT, sig_handler); + +//! [Interesting] + // Instantiate an AT42QT1070 on I2C bus 0 + + upm::AT42QT1070 *touch = new upm::AT42QT1070(AT42QT1070_I2C_BUS, + AT42QT1070_DEFAULT_I2C_ADDR); + + while (shouldRun) + { + touch->updateState(); + printButtons(touch); + usleep(100000); + } + +//! [Interesting] + + cout << "Exiting..." << endl; + + delete touch; + return 0; +} diff --git a/examples/javascript/at42qt1070.js b/examples/javascript/at42qt1070.js new file mode 100644 index 00000000..c061f137 --- /dev/null +++ b/examples/javascript/at42qt1070.js @@ -0,0 +1,81 @@ +/*jslint node:true, vars:true, bitwise:true, unparam:true */ +/*jshint unused:true */ +/* +* Author: Zion Orent +* Copyright (c) 2015 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. +*/ + +/* functions */ +function printButtons(touchObj) +{ + var buttonPressed = false; + var buttons = touchObj.getButtons(); + + process.stdout.write("Buttons Pressed: "); + for (var i=0; i<7; i++) + { + if (buttons & (1 << i)) + { + process.stdout.write(i + " "); + buttonPressed = true; + } + } + + if (!buttonPressed) + process.stdout.write("None"); + + console.log(" "); + + if (touchObj.isCalibrating()) + console.log("Calibration is occurring."); + + if (touchObj.isOverflowed()) + console.log("Overflow was detected."); +} + + +/* Global code that runs on startup */ + +var touchSensor_lib = require('jsupm_at42qt1070'); + +var I2C_BUS = touchSensor_lib.AT42QT1070_I2C_BUS; +var DEFAULT_I2C_ADDR = touchSensor_lib.AT42QT1070_DEFAULT_I2C_ADDR; +// Instantiate an AT42QT1070 on I2C bus 0 +var mytouchSensor_obj = new touchSensor_lib.AT42QT1070(I2C_BUS, + DEFAULT_I2C_ADDR); + +var myInterval = setInterval(function() +{ + mytouchSensor_obj.updateState(); + printButtons(mytouchSensor_obj); +}, 100); + +// Print message when exiting and clear interval/memory +process.on('SIGINT', function() +{ + clearInterval(myInterval); + mytouchSensor_obj = null; + touchSensor_lib.cleanUp(); + touchSensor_lib = null; + console.log("Exiting"); + process.exit(0); +}); diff --git a/src/at42qt1070/CMakeLists.txt b/src/at42qt1070/CMakeLists.txt new file mode 100644 index 00000000..8b48db82 --- /dev/null +++ b/src/at42qt1070/CMakeLists.txt @@ -0,0 +1,5 @@ +set (libname "at42qt1070") +set (libdescription "upm module for the Atmel AT42QT1070 QTouch sensor") +set (module_src ${libname}.cxx) +set (module_h ${libname}.h) +upm_module_init() diff --git a/src/at42qt1070/at42qt1070.cxx b/src/at42qt1070/at42qt1070.cxx new file mode 100644 index 00000000..4d2e0755 --- /dev/null +++ b/src/at42qt1070/at42qt1070.cxx @@ -0,0 +1,145 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 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 +#include +#include +#include + +#include "at42qt1070.h" + +using namespace upm; +using namespace std; + + +AT42QT1070::AT42QT1070(int bus, uint8_t address) +{ + m_addr = address; + + // setup our i2c link + if ( !(m_i2c = mraa_i2c_init(bus)) ) + { + cerr << __FUNCTION__ << ": mraa_i2c_init() failed." << endl; + return; + } + + mraa_result_t rv; + + if ( (rv = mraa_i2c_address(m_i2c, m_addr)) != MRAA_SUCCESS) + { + cerr << __FUNCTION__ << ": Could not initialize i2c bus. " << endl; + mraa_result_print(rv); + return; + } + + m_buttonStates = false; + m_calibrating = false; + m_overflow = false; + +} + +AT42QT1070::~AT42QT1070() +{ + mraa_i2c_stop(m_i2c); +} + +bool AT42QT1070::writeByte(uint8_t reg, uint8_t byte) +{ + mraa_result_t rv = mraa_i2c_write_byte_data(m_i2c, byte, reg); + + if (rv != MRAA_SUCCESS) + { + cerr << __FUNCTION__ << ": mraa_i2c_write_byte() failed." << endl; + mraa_result_print(rv); + return false; + } + + return true; +} + +bool AT42QT1070::writeWord(uint8_t reg, uint16_t word) +{ + mraa_result_t rv = mraa_i2c_write_word_data(m_i2c, word, reg); + + if (rv != MRAA_SUCCESS) + { + cerr << __FUNCTION__ << ": mraa_i2c_write_word() failed." << endl; + mraa_result_print(rv); + return false; + } + + return true; +} + +uint8_t AT42QT1070::readByte(uint8_t reg) +{ + return mraa_i2c_read_byte_data(m_i2c, reg); +} + +uint16_t AT42QT1070::readWord(uint8_t reg) +{ + return mraa_i2c_read_word_data(m_i2c, reg); +} + +void AT42QT1070::updateState() +{ + uint8_t stat = readByte(REG_DETSTATUS); + + // if we are calibrating, don't change anything + if (stat & DET_CALIBRATE) + { + m_calibrating = true; + return; + } + else + m_calibrating = false; + + if (stat & DET_OVERFLOW) + m_overflow = true; + else + m_overflow = false; + + // if a touch is occurring, read the button states + if (stat & DET_TOUCH) + { + uint8_t keys = readByte(REG_KEYSTATUS); + // high bit is reserved, filter it out + m_buttonStates = keys & ~0x80; + } + else + m_buttonStates = 0; +} + +bool AT42QT1070::reset() +{ + // write a non-zero value to the reset register + return writeByte(REG_RESET, 0xff); +} + +bool AT42QT1070::calibrate() +{ + // write a non-zero value to the calibrate register + return writeByte(REG_CALIBRATE, 0xff); +} + diff --git a/src/at42qt1070/at42qt1070.h b/src/at42qt1070/at42qt1070.h new file mode 100644 index 00000000..0750c2d3 --- /dev/null +++ b/src/at42qt1070/at42qt1070.h @@ -0,0 +1,240 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 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 +#include + +#include +#include + +#define AT42QT1070_I2C_BUS 0 +#define AT42QT1070_DEFAULT_I2C_ADDR 0x1b + +namespace upm { + + /** + * @brief UPM module for the Atmel AT42QT1070 QTouch sensor + * @defgroup at42qt1070 libupm-at42qt1070 + * @ingroup seeed i2c touch + */ + + /** + * @sensor at42qt1070 + * @library at42qt1070 + * @name Atmel AT42QT1070 QTouch Sensor + * @category touch + * @manufacturer seeed + * @connection i2c + * + * @brief C++ API for the Atmel AT42QT1070 QTouch sensor + * + * This class implements support for the Atmel AT42QT1070 QTouch + * sensor, which supports 7 capacitive buttons. + * + * It was developed using the Grove Q Touch Sensor board. + * + * @snippet at42qt1070.cxx Interesting + */ + class AT42QT1070 { + public: + + // registers + typedef enum { REG_CHIPID = 0, + REG_FWVERS = 1, + + REG_DETSTATUS = 2, // detection status + REG_KEYSTATUS = 3, // key status + + REG_KEYSIG0_H = 4, // key signal + REG_KEYSIG0_L = 5, + REG_KEYSIG1_H = 6, + REG_KEYSIG1_L = 7, + REG_KEYSIG2_H = 8, + REG_KEYSIG2_L = 9, + REG_KEYSIG3_H = 10, + REG_KEYSIG3_L = 11, + REG_KEYSIG4_H = 12, + REG_KEYSIG4_L = 13, + REG_KEYSIG5_H = 14, + REG_KEYSIG5_L = 15, + REG_KEYSIG6_H = 16, + REG_KEYSIG6_L = 17, + + REG_REFDATA0_H = 18, // key reference data + REG_REFDATA0_L = 19, + REG_REFDATA1_H = 20, + REG_REFDATA1_L = 21, + REG_REFDATA2_H = 22, + REG_REFDATA2_L = 23, + REG_REFDATA3_H = 24, + REG_REFDATA3_L = 25, + REG_REFDATA4_H = 26, + REG_REFDATA4_L = 27, + REG_REFDATA5_H = 28, + REG_REFDATA5_L = 29, + REG_REFDATA6_H = 30, + REG_REFDATA6_L = 31, + + REG_NTHR0 = 32, // negative threshold level + REG_NTHR1 = 33, + REG_NTHR2 = 34, + REG_NTHR3 = 35, + REG_NTHR4 = 36, + REG_NTHR5 = 37, + REG_NTHR6 = 38, + + REG_AVE0 = 39, // key suppression + REG_AVE1 = 40, + REG_AVE2 = 41, + REG_AVE3 = 42, + REG_AVE4 = 43, + REG_AVE5 = 44, + REG_AVE6 = 45, + + REG_DI0 = 46, // detection integrator + REG_DI1 = 47, + REG_DI2 = 48, + REG_DI3 = 49, + REG_DI4 = 50, + REG_DI5 = 51, + REG_DI6 = 52, + + REG_GUARD = 53, // FastOutDI/Max Cal/Guard channel + REG_LP = 54, // low power + REG_MAXON = 55, // max on duration + REG_CALIBRATE = 56, + REG_RESET = 57 + } AT42QT1070_REG_T; + + // detection register bits + typedef enum { DET_TOUCH = 0x01, + // 0x02-0x20 reserved + DET_OVERFLOW = 0x40, + DET_CALIBRATE = 0x80 + } AT42QT1070_DET_T; + + + /** + * AT42QT1070 constructor + * + * @param bus i2c bus to use + * @param address the address for this sensor + */ + AT42QT1070(int bus, uint8_t address = AT42QT1070_DEFAULT_I2C_ADDR); + + /** + * AT42QT1070 Destructor + */ + ~AT42QT1070(); + + /** + * Write byte value into register + * + * @param reg register location to write into + * @param byte byte to write + * @return true if successful + */ + bool writeByte(uint8_t reg, uint8_t byte); + + /** + * Write word value at register. Note, the device must have the + * auto-increment bit set in the MODE1 register to work. + * + * @param reg register location to write into + * @param word word to write + * @return true if successful + */ + bool writeWord(uint8_t reg, uint16_t word); + + /** + * Read byte value from register + * + * @param reg register location to read from + * @return value at specified register + */ + uint8_t readByte(uint8_t reg); + + /** + * Read word value from register. Note, the device must have the + * auto-increment bit set in the MODE1 register to work. + * + * @param reg register location to read from + * @return value at specified register + */ + uint16_t readWord(uint8_t reg); + + /** + * Read the current touch status and detection state + * + * @return key status bits for all keys (0-6) + */ + void updateState(); + + /** + * return the overflow indicator + * + * @return true if overflow indicated + */ + bool isOverflowed() { return m_overflow; }; + + /** + * return the calibrating indicator + * + * @return true if calibration is in progress + */ + bool isCalibrating() { return m_calibrating; }; + + /** + * Issue a reset command + * + * @return true if reset successful + */ + bool reset(); + + /** + * Issue a calibrate command + * + * @return true if calibrate successful + */ + bool calibrate(); + + /** + * Get the current button states + * + * @returns the button states + */ + uint8_t getButtons() { return m_buttonStates; }; + + private: + uint8_t m_buttonStates; + bool m_calibrating; + bool m_overflow; + + mraa_i2c_context m_i2c; + uint8_t m_addr; + }; +} + + diff --git a/src/at42qt1070/jsupm_at42qt1070.i b/src/at42qt1070/jsupm_at42qt1070.i new file mode 100644 index 00000000..9c47e461 --- /dev/null +++ b/src/at42qt1070/jsupm_at42qt1070.i @@ -0,0 +1,8 @@ +%module jsupm_at42qt1070 +%include "../upm.i" + +%{ + #include "at42qt1070.h" +%} + +%include "at42qt1070.h" diff --git a/src/at42qt1070/pyupm_at42qt1070.i b/src/at42qt1070/pyupm_at42qt1070.i new file mode 100644 index 00000000..38664551 --- /dev/null +++ b/src/at42qt1070/pyupm_at42qt1070.i @@ -0,0 +1,13 @@ +%module pyupm_at42qt1070 +%include "../upm.i" + +%feature("autodoc", "3"); + +#ifdef DOXYGEN +%include "at42qt1070_doc.i" +#endif + +%include "at42qt1070.h" +%{ + #include "at42qt1070.h" +%}