Home | History | Annotate | Download | only in at42qt1070
      1 /*
      2  * Author: Jon Trulson <jtrulson (at) ics.com>
      3  * Copyright (c) 2015 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 <math.h>
     27 #include <iostream>
     28 #include <string>
     29 #include <stdexcept>
     30 
     31 #include "at42qt1070.h"
     32 
     33 using namespace upm;
     34 using namespace std;
     35 
     36 
     37 AT42QT1070::AT42QT1070(int bus, uint8_t address)
     38 {
     39     m_addr = address;
     40 
     41     // setup our i2c link
     42     if (!(m_i2c = mraa_i2c_init(bus))) {
     43         throw std::invalid_argument(std::string(__FUNCTION__) +
     44                                     ": mraa_i2c_init() failed");
     45         return;
     46     }
     47 
     48     mraa_result_t rv;
     49 
     50     if ((rv = mraa_i2c_address(m_i2c, m_addr)) != MRAA_SUCCESS) {
     51         throw std::invalid_argument(std::string(__FUNCTION__) +
     52                                     ": mraa_i2c_address() failed");
     53         return;
     54     }
     55 
     56     if (readChipID() != 0x2E) {
     57         throw std::runtime_error("Chip ID does not match the expected value (2Eh)");
     58     }
     59 
     60     m_buttonStates = 0;
     61     m_calibrating = false;
     62     m_overflow = false;
     63 }
     64 
     65 AT42QT1070::~AT42QT1070()
     66 {
     67     mraa_i2c_stop(m_i2c);
     68 }
     69 
     70 bool
     71 AT42QT1070::writeByte(uint8_t reg, uint8_t byte)
     72 {
     73     mraa_result_t rv = mraa_i2c_write_byte_data(m_i2c, byte, reg);
     74 
     75     if (rv != MRAA_SUCCESS) {
     76         throw std::runtime_error(std::string(__FUNCTION__) +
     77                                  ": mraa_i2c_write_byte() failed");
     78         return false;
     79     }
     80 
     81     return true;
     82 }
     83 
     84 bool
     85 AT42QT1070::writeWord(uint8_t reg, uint16_t word)
     86 {
     87     mraa_result_t rv = mraa_i2c_write_word_data(m_i2c, word, reg);
     88 
     89     if (rv != MRAA_SUCCESS) {
     90         throw std::runtime_error(std::string(__FUNCTION__) +
     91                                  ": mraa_i2c_write_word() failed");
     92         return false;
     93     }
     94 
     95     return true;
     96 }
     97 
     98 uint8_t
     99 AT42QT1070::readByte(uint8_t reg)
    100 {
    101     return mraa_i2c_read_byte_data(m_i2c, reg);
    102 }
    103 
    104 uint16_t
    105 AT42QT1070::readWord(uint8_t reg)
    106 {
    107     return mraa_i2c_read_word_data(m_i2c, reg);
    108 }
    109 
    110 uint8_t
    111 AT42QT1070::readChipID(void)
    112 {
    113     return readByte(REG_CHIPID);
    114 }
    115 
    116 void
    117 AT42QT1070::updateState()
    118 {
    119     uint8_t stat = readByte(REG_DETSTATUS);
    120 
    121     // if we are calibrating, don't change anything
    122     if (stat & DET_CALIBRATE) {
    123         m_calibrating = true;
    124         return;
    125     } else {
    126         m_calibrating = false;
    127     }
    128 
    129     if (stat & DET_OVERFLOW)
    130         m_overflow = true;
    131     else
    132         m_overflow = false;
    133 
    134     // if a touch is occurring, read the button states
    135     if (stat & DET_TOUCH) {
    136         uint8_t keys = readByte(REG_KEYSTATUS);
    137         // high bit is reserved, filter it out
    138         m_buttonStates = keys & ~0x80;
    139     } else {
    140         m_buttonStates = 0;
    141     }
    142 }
    143 
    144 uint8_t
    145 AT42QT1070::getLPMode(void)
    146 {
    147     return readByte(REG_LP);
    148 }
    149 
    150 uint8_t
    151 AT42QT1070::setLPMode(uint8_t mode)
    152 {
    153     writeByte(REG_LP, mode);
    154 
    155     return getLPMode();
    156 }
    157 
    158 uint8_t
    159 AT42QT1070::getAVE(uint8_t key)
    160 {
    161     uint8_t value, ave;
    162 
    163     if (key > 6) {
    164         throw std::invalid_argument("Only keys 0-6 are allowed");
    165     }
    166 
    167     value = readByte(REG_AVE0 + key);
    168     ave = (value & 0xFC) >> 2;
    169 
    170     return ave;
    171 }
    172 
    173 uint8_t
    174 AT42QT1070::setAVE(uint8_t key, uint8_t ave)
    175 {
    176     uint8_t value;
    177 
    178     if (key > 6) {
    179         throw std::invalid_argument("Only keys 0-6 are allowed");
    180     }
    181 
    182     switch (ave) {
    183         case 1:
    184         case 2:
    185         case 4:
    186         case 8:
    187         case 16:
    188         case 32:
    189             break;
    190 
    191         default:
    192             throw std::invalid_argument("Invalid averaging factor");
    193     }
    194 
    195     value = readByte(REG_AVE0 + key);
    196     value = value & 0x03;
    197     value = value | (ave << 2);
    198     writeByte(REG_AVE0 + key, value);
    199 
    200     return getAVE(key);
    201 }
    202 
    203 uint8_t
    204 AT42QT1070::getAKSGroup(uint8_t key)
    205 {
    206     uint8_t value, aks;
    207 
    208     if (key > 6) {
    209         throw std::invalid_argument("Only keys 0-6 are allowed");
    210     }
    211 
    212     value = readByte(REG_AVE0 + key);
    213     aks = value & 0x03;
    214 
    215     return aks;
    216 }
    217 
    218 uint8_t
    219 AT42QT1070::setAKSGroup(uint8_t key, uint8_t group)
    220 {
    221     uint8_t value;
    222 
    223     if (key > 6) {
    224         throw std::invalid_argument("Only keys 0-6 are allowed");
    225     }
    226 
    227     if (group > 3) {
    228         throw std::invalid_argument("Only groups 0-3 are allowed");
    229     }
    230 
    231     value = readByte(REG_AVE0 + key);
    232     value = value & 0xFC;
    233     value = value | group;
    234 
    235     writeByte(REG_AVE0 + key, value);
    236 
    237     return getAKSGroup(key);
    238 }
    239 
    240 bool
    241 AT42QT1070::reset()
    242 {
    243     // write a non-zero value to the reset register
    244     return writeByte(REG_RESET, 0xff);
    245 }
    246 
    247 bool
    248 AT42QT1070::calibrate()
    249 {
    250     // write a non-zero value to the calibrate register
    251     return writeByte(REG_CALIBRATE, 0xff);
    252 }
    253