1 /* 2 * Author: Jon Trulson <jtrulson (at) 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 ADC121C021_I2C_BUS 0 30 #define ADC121C021_DEFAULT_I2C_ADDR 0x55 31 32 #define ADC121C021_RESOLUTION 4096 // 12 bits 33 34 /** 35 * ADC121C021 registers 36 */ 37 38 #define ADC121C021_REG_RESULT 0x00 39 #define ADC121C021_REG_ALERT_STATUS 0x01 40 #define ADC121C021_REG_CONFIG 0x02 41 #define ADC121C021_REG_ALERT_LIM_UNDER 0x03 42 #define ADC121C021_REG_ALERT_LIM_OVER 0x04 43 #define ADC121C021_REG_ALERT_HYS 0x05 44 #define ADC121C021_REG_LOWEST_CONV 0x06 45 #define ADC121C021_REG_HIGHEST_CONV 0x07 46 47 // For the Grove I2C ADC 48 #define ADC121C021_DEFAULT_VREF 3.0 49 50 namespace upm { 51 /** 52 * @brief ADC121C021 I2C Analog-to-Digital Converter library 53 * @defgroup adc121c021 libupm-adc121c021 54 * @ingroup seeed i2c electric 55 */ 56 57 58 /** 59 * Valid cycle times for the automatic conversion mode 60 */ 61 62 typedef enum { ADC121C021_CYCLE_NONE = 0, // disabled 63 ADC121C021_CYCLE_32 = 1, // 27 ksps 64 ADC121C021_CYCLE_64 = 2, // 13.5 65 ADC121C021_CYCLE_128 = 3, // 6.7 66 ADC121C021_CYCLE_256 = 4, // 3.4 67 ADC121C021_CYCLE_512 = 5, // 1.7 68 ADC121C021_CYCLE_1024 = 6, // 0.9 69 ADC121C021_CYCLE_2048 = 7 // 0.4 70 } ADC121C021_CYCLE_TIME_T; 71 72 /** 73 * @library adc121c021 74 * @sensor adc121c021 75 * @comname ADC121C021 Analog-to-Digital Converter 76 * @altname Grove I2C ADC 77 * @type electric 78 * @man seeed 79 * @web http://www.seeedstudio.com/depot/Grove-I2C-ADC-p-1580.html 80 * @con i2c 81 * 82 * @brief API for the ADC121C021 I2C Analog-to-Digital Converter 83 * 84 * UPM module for the ADC121C021 12-bit analog-to-digital converter (ADC). 85 * By constantly providing a reference voltage, this sensor helps 86 * increase the accuracy of a value collected from an analog sensor. 87 * 88 * @image html adc121c021.jpg 89 * @snippet adc121c021.cxx Interesting 90 */ 91 class ADC121C021 { 92 public: 93 /** 94 * ADC121C021 ADC constructor 95 * 96 * @param bus I2C bus to use 97 * @param address Address for this sensor; default is 0x55 98 * @param vref Reference voltage for this sensor; default is 3.0v 99 */ 100 ADC121C021(int bus, uint8_t address = ADC121C021_DEFAULT_I2C_ADDR, 101 float vref = ADC121C021_DEFAULT_VREF); 102 103 /** 104 * ADC121C021 destructor 105 */ 106 ~ADC121C021(); 107 108 /** 109 * Writes a byte value into the register 110 * 111 * @param reg Register location to write into 112 * @param byte Byte to write 113 * @return 0 (MRAA_SUCCESS) if successful; non-zero otherwise 114 */ 115 mraa_result_t writeByte(uint8_t reg, uint8_t byte); 116 117 /** 118 * Writes a word value into the register 119 * 120 * @param reg Register location to write into 121 * @param word Word to write 122 * @return 0 (MRAA_SUCCESS) if successful; non-zero otherwise 123 */ 124 mraa_result_t writeWord(uint8_t reg, uint16_t word); 125 126 /** 127 * Reads the byte value from the register 128 * 129 * @param reg Register location to read from 130 * @return Value in the specified register 131 */ 132 uint8_t readByte(uint8_t reg); 133 134 /** 135 * Reads the word value from the register 136 * 137 * @param reg Register location to read from 138 * @return Value in the specified register 139 */ 140 uint16_t readWord(uint8_t reg); 141 142 /** 143 * Reads the current value of conversion 144 * 145 * @return Current value of conversion 146 */ 147 uint16_t value(); 148 149 /** 150 * Converts a supplied value to voltage based on the set vref 151 * 152 * @param val Value of conversion (from value()) 153 * @return Value of conversion in volts 154 */ 155 float valueToVolts(uint16_t val); 156 157 /** 158 * Reads the current status of the alert flag. If the flag is set, the 159 * low or high alert indicators are set as appropriate, and 160 * you can access these values with alertLowTriggered() or 161 * alertHighTriggered(). 162 * 163 * @return True if the alert flag is set 164 */ 165 bool getAlertStatus(); 166 167 /** 168 * Returns the current value of m_alertLow. You must call 169 * getAlertStatus() to update this value. 170 * 171 * @return Current status of the alert low flag 172 */ 173 bool alertLowTriggered() { return m_alertLow; }; 174 175 /** 176 * Returns the current value of m_alertHigh. You must call 177 * getAlertStatus() to update this value. 178 * 179 * @return Current status of the alert high flag 180 */ 181 bool alertHighTriggered() { return m_alertHigh; }; 182 183 /** 184 * Clears the alert low and alert high flags. This also clears the 185 * last stored alert values. 186 */ 187 void clearAlertStatus(); 188 189 /** 190 * Enables or disables the alert flag functionality. If enabled, 191 * when the measured value exceeds the low or high limits 192 * configured, the alert flag is set. Use getAlertStatus() 193 * to access these values. 194 * 195 * @param enable If true, enables the alert flag; otherwise, disables the 196 * alert flag 197 */ 198 void enableAlertFlag(bool enable); 199 200 /** 201 * Enables or disables the alert pin functionality. 202 * 203 * @param enable If true, enables the alert pin; otherwise, disables the 204 * alert pin 205 */ 206 void enableAlertPin(bool enable); 207 208 /** 209 * Enables or disables the alert hold functionality. When the alert 210 * hold is enabled, the alert status remains until manually 211 * cleared via clearAlertStatus(). Otherwise, the alert self-clears 212 * when the value moves into the defined limits if alerts 213 * are enabled via enableAlertFlag(). 214 * 215 * @param enable If true, enables the alert hold; otherwise, disables the 216 * alert hold 217 */ 218 void enableAlertHold(bool enable); 219 220 /** 221 * If the alert pin is enabled, defines the active 222 * polarity of the pin in an alert condition. Enabling this sets 223 * the pin to active high in an alert condition; otherwise, 224 * active low is used. 225 * 226 * @param enable If true, the alert pin is active high; otherwise, active 227 * low 228 */ 229 void enableAlertPinPolarityHigh(bool enable); 230 231 /** 232 * Enables or disables the automatic conversion mode. When enabled, the 233 * ADC samples and updates the conversion value independently. 234 * It is disabled by default, so conversion is only done by 235 * calling value(). 236 * 237 * @param cycleTime Sets the cycle time for automatic conversion 238 */ 239 void setAutomaticConversion(ADC121C021_CYCLE_TIME_T cycleTime); 240 241 /** 242 * Sets the alert low limit. If alerts are enabled and the 243 * measured conversion value is lower than the low limit, an alert is 244 * triggered. 245 * 246 * @param limit Alert low limit 247 * @return 0 (MRAA_SUCCESS) if successful; non-zero otherwise 248 */ 249 mraa_result_t setAlertLowLimit(uint16_t limit); 250 251 /** 252 * Sets the alert high limit. If alerts are enabled and the 253 * measured conversion value is higher than the high limit, an alert is 254 * triggered. 255 * 256 * @param limit Alert high limit 257 * @return 0 (MRAA_SUCCESS) if successful; non-zero otherwise 258 */ 259 mraa_result_t setAlertHighLimit(uint16_t limit); 260 261 /** 262 * Sets the hysteresis value. If a high or low alert condition is 263 * triggered, the conversion result must move within the high or 264 * low limit by more than this value to clear the alert condition. 265 * If the alert hold is set, the alert doesn't self-clear 266 * regardless of this value. 267 * 268 * @param limit Hysteresis limit 269 * @return 0 (MRAA_SUCCESS) if successful; non-zero otherwise 270 */ 271 mraa_result_t setHysteresis(uint16_t limit); 272 273 /** 274 * Returns the highest conversion value recorded so far. This value 275 * is only updated by the converter when the automatic conversion mode 276 * is enabled. 277 * 278 * @return Highest conversion value 279 */ 280 uint16_t getHighestConversion(); 281 282 /** 283 * Returns the lowest conversion value recorded so far. This value 284 * is only updated by the converter when the automatic conversion mode 285 * is enabled. 286 * 287 * @return Lowest conversion value 288 */ 289 uint16_t getLowestConversion(); 290 291 /** 292 * Clears the highest conversion value recorded so far. 293 * 294 * @return 0 (MRAA_SUCCESS) if successful; non-zero otherwise 295 */ 296 mraa_result_t clearHighestConversion(); 297 298 /** 299 * Clears the lowest conversion value recorded so far. 300 * 301 * @return 0 (MRAA_SUCCESS) if successful; non-zero otherwise 302 */ 303 mraa_result_t clearLowestConversion(); 304 305 private: 306 mraa_i2c_context m_i2c; 307 uint8_t m_addr; 308 float m_vref; 309 bool m_alertLow; 310 bool m_alertHigh; 311 }; 312 } 313 314 315