Home | History | Annotate | Download | only in adc121c021
      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 
     25 #include <iostream>
     26 #include <string>
     27 #include <stdexcept>
     28 
     29 #include "adc121c021.h"
     30 
     31 using namespace upm;
     32 using namespace std;
     33 
     34 
     35 ADC121C021::ADC121C021(int bus, uint8_t address, float vref)
     36 {
     37   // setup our i2c link
     38   m_i2c = mraa_i2c_init(bus);
     39   if ( !(m_i2c = mraa_i2c_init(bus)) )
     40     {
     41       throw std::invalid_argument(std::string(__FUNCTION__) +
     42                                   ": mraa_i2c_init() failed");
     43       return;
     44     }
     45 
     46   m_addr = address;
     47 
     48   mraa_result_t ret = mraa_i2c_address(m_i2c, m_addr);
     49 
     50   if (ret != MRAA_SUCCESS)
     51     {
     52       throw std::invalid_argument(std::string(__FUNCTION__) +
     53                                   ": mraa_i2c_address() failed");
     54       return;
     55     }
     56 
     57   m_vref = vref;
     58 }
     59 
     60 ADC121C021::~ADC121C021()
     61 {
     62   mraa_i2c_stop(m_i2c);
     63 }
     64 
     65 mraa_result_t ADC121C021::writeByte(uint8_t reg, uint8_t byte)
     66 {
     67   return mraa_i2c_write_byte_data(m_i2c, byte, reg);
     68 }
     69 
     70 mraa_result_t ADC121C021::writeWord(uint8_t reg, uint16_t word)
     71 {
     72   // We need to swap the bytes
     73   uint8_t b1 = (word & 0xff00) >> 8;
     74   word <<= 8;
     75   word |= b1;
     76 
     77   return mraa_i2c_write_word_data(m_i2c, word, reg);
     78 }
     79 
     80 uint8_t ADC121C021::readByte(uint8_t reg)
     81 {
     82   return mraa_i2c_read_byte_data(m_i2c, reg);
     83 }
     84 
     85 uint16_t ADC121C021::readWord(uint8_t reg)
     86 {
     87   uint16_t val = mraa_i2c_read_word_data(m_i2c, reg);
     88   uint8_t b1;
     89 
     90   // The value returned is in the wrong byte order, so we need to swap them
     91   b1 = (val & 0xff00) >> 8;
     92   val <<= 8;
     93   val |= b1;
     94 
     95   return val;
     96 }
     97 
     98 uint16_t ADC121C021::value()
     99 {
    100   // mask off alert flag and reserved bits
    101   return (readWord(ADC121C021_REG_RESULT) & 0x0fff);
    102 }
    103 
    104 float ADC121C021::valueToVolts(uint16_t val)
    105 {
    106   // The arduino example multiplies this by 2, which seems wrong.  If
    107   // the reference voltage is 3.0, then you should never get a voltage
    108   // value higher than that.
    109   //
    110   // val * m_vref * 2.0 / ADC121C021_RESOLUTION
    111   return (val * m_vref / ADC121C021_RESOLUTION);
    112 }
    113 
    114 bool ADC121C021::getAlertStatus()
    115 {
    116   // high order bit is the alert flag, mask off the rest
    117   bool rv = (readWord(ADC121C021_REG_RESULT) & 0x8000) ? true : false;
    118 
    119   if (rv)
    120     {
    121       // read the alert low and high values and set the appropriate
    122       // member variables
    123       uint8_t astatus = readByte(ADC121C021_REG_ALERT_STATUS);
    124       if (astatus & 0x01)
    125         m_alertLow = true;
    126       else
    127         m_alertLow = false;
    128 
    129       if (astatus & 0x02)
    130         m_alertHigh = true;
    131       else
    132         m_alertHigh = false;
    133     }
    134 
    135   return rv;
    136 }
    137 
    138 void ADC121C021::clearAlertStatus()
    139 {
    140   // zero out both the low and high alert flags
    141   writeByte(ADC121C021_REG_ALERT_STATUS, 0x03);
    142 
    143   m_alertHigh = false;
    144   m_alertLow = false;
    145 }
    146 
    147 void ADC121C021::enableAlertFlag(bool enable)
    148 {
    149   // read the current config register
    150   uint8_t val = readByte(ADC121C021_REG_CONFIG);
    151 
    152   if (enable)
    153     val |= 0x08;
    154   else
    155     val &= ~0x08;
    156 
    157   // write the register back
    158   writeByte(ADC121C021_REG_CONFIG, val);
    159 }
    160 
    161 void ADC121C021::enableAlertPin(bool enable)
    162 {
    163   // read the current config register
    164   uint8_t val = readByte(ADC121C021_REG_CONFIG);
    165 
    166   if (enable)
    167     val |= 0x04;
    168   else
    169     val &= ~0x04;
    170 
    171   // write the register back
    172   writeByte(ADC121C021_REG_CONFIG, val);
    173 }
    174 
    175 void ADC121C021::enableAlertHold(bool enable)
    176 {
    177   // read the current config register
    178   uint8_t val = readByte(ADC121C021_REG_CONFIG);
    179 
    180   if (enable)
    181     val |= 0x10;
    182   else
    183     val &= ~0x10;
    184 
    185   // write the register back
    186   writeByte(ADC121C021_REG_CONFIG, val);
    187 }
    188 
    189 void ADC121C021::enableAlertPinPolarityHigh(bool enable)
    190 {
    191   // read the current config register
    192   uint8_t val = readByte(ADC121C021_REG_CONFIG);
    193 
    194   if (enable)
    195     val |= 0x01;
    196   else
    197     val &= ~0x01;
    198 
    199   // write the register back
    200   writeByte(ADC121C021_REG_CONFIG, val);
    201 }
    202 
    203 void ADC121C021::setAutomaticConversion(ADC121C021_CYCLE_TIME_T cycleTime)
    204 {
    205   // first we
    206 
    207   // read the current config register, masking off the cycle time bits
    208   uint8_t val = readByte(ADC121C021_REG_CONFIG) & 0x1f;
    209 
    210   val |= ((uint8_t)cycleTime << 5);
    211 
    212   // write the register back
    213   writeByte(ADC121C021_REG_CONFIG, val);
    214 }
    215 
    216 mraa_result_t ADC121C021::setAlertLowLimit(uint16_t limit)
    217 {
    218   // mask off the invalid bits in case they were set
    219   limit &= 0x0fff;
    220 
    221   // write it
    222   return writeWord(ADC121C021_REG_ALERT_LIM_UNDER, limit);
    223 }
    224 
    225 mraa_result_t ADC121C021::setAlertHighLimit(uint16_t limit)
    226 {
    227   // mask off the invalid bits in case they were set
    228   limit &= 0x0fff;
    229 
    230   // write it
    231   return writeWord(ADC121C021_REG_ALERT_LIM_OVER, limit);
    232 }
    233 
    234 mraa_result_t ADC121C021::setHysteresis(uint16_t limit)
    235 {
    236   // mask off the invalid bits in case they were set
    237   limit &= 0x0fff;
    238 
    239   // write it
    240   return writeWord(ADC121C021_REG_ALERT_HYS, limit);
    241 }
    242 
    243 uint16_t ADC121C021::getHighestConversion()
    244 {
    245   return readWord(ADC121C021_REG_HIGHEST_CONV);
    246 }
    247 
    248 uint16_t ADC121C021::getLowestConversion()
    249 {
    250   return readWord(ADC121C021_REG_LOWEST_CONV);
    251 }
    252 
    253 mraa_result_t ADC121C021::clearHighestConversion()
    254 {
    255   return writeWord(ADC121C021_REG_HIGHEST_CONV, 0x0000);
    256 }
    257 
    258 mraa_result_t ADC121C021::clearLowestConversion()
    259 {
    260   return writeWord(ADC121C021_REG_LOWEST_CONV, 0x0fff);
    261 }
    262