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