Pratyush Mallick / Mbed OS nano_dac
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers adt7420.c Source File

adt7420.c

Go to the documentation of this file.
00001 /***************************************************************************//**
00002  *   @file   adt7420.c
00003  *   @brief  Implementation of ADT7420 Driver.
00004  *   @author DBogdan (dragos.bogdan@analog.com)
00005 ********************************************************************************
00006  * Copyright 2012(c) Analog Devices, Inc.
00007  *
00008  * All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions are met:
00012  *  - Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  *  - Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *  - Neither the name of Analog Devices, Inc. nor the names of its
00019  *    contributors may be used to endorse or promote products derived
00020  *    from this software without specific prior written permission.
00021  *  - The use of this software may or may not infringe the patent rights
00022  *    of one or more patent holders.  This license does not release you
00023  *    from the requirement that you obtain separate licenses from these
00024  *    patent holders to use this software.
00025  *  - Use of the software either in source or binary form, must be run
00026  *    on or directly connected to an Analog Devices Inc. component.
00027  *
00028  * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
00029  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
00030  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00031  * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
00032  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00033  * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
00034  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00035  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00036  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00037  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00038 *******************************************************************************/
00039 
00040 /******************************************************************************/
00041 /***************************** Include Files **********************************/
00042 /******************************************************************************/
00043 #include <stdlib.h>
00044 #include "adt7420.h"
00045 
00046 /***************************************************************************//**
00047  * @brief Reads the value of a register.
00048  *
00049  * @param dev              - The device structure.
00050  * @param register_address - Address of the register.
00051  *
00052  * @return register_value  - Value of the register.
00053 *******************************************************************************/
00054 uint8_t adt7420_get_register_value(struct adt7420_dev *dev,
00055                    uint8_t register_address)
00056 {
00057     uint8_t register_value = 0;
00058 
00059     i2c_write(dev->i2c_desc,
00060           &register_address,
00061           1,
00062           0);
00063     i2c_read(dev->i2c_desc,
00064          &register_value,
00065          1,
00066          1);
00067 
00068     return register_value;
00069 }
00070 
00071 /***************************************************************************//**
00072  * @brief Sets the value of a register.
00073  *
00074  * @param dev              - The device structure.
00075  * @param register_address - Address of the register.
00076  * @param register_value   - Value of the register.
00077  *
00078  * @return None.
00079 *******************************************************************************/
00080 void adt7420_set_register_value(struct adt7420_dev *dev,
00081                 uint8_t register_address,
00082                 uint8_t register_value)
00083 {
00084     uint8_t data_buffer[2] = {0, 0};
00085 
00086     data_buffer[0] = register_address;
00087     data_buffer[1] = register_value;
00088     i2c_write(dev->i2c_desc,
00089           data_buffer,
00090           2,
00091           1);
00092 }
00093 
00094 /***************************************************************************//**
00095  * @brief Initializes the communication peripheral and checks if the device is
00096  *        present.
00097  *
00098  * @param device     - The device structure.
00099  * @param init_param - The structure that contains the device initial
00100  *             parameters.
00101  *
00102  * @return status - The result of the initialization procedure.
00103  *                  Example: -1 - I2C peripheral was not initialized or the
00104  *                                device is not present.
00105  *                            0 - I2C peripheral was initialized and the
00106  *                                device is present.
00107 *******************************************************************************/
00108 int32_t adt7420_init(struct adt7420_dev **device,
00109              struct adt7420_init_param init_param)
00110 {
00111     struct adt7420_dev *dev;
00112     int32_t status;
00113     uint8_t test = 0;
00114 
00115     dev = (struct adt7420_dev *)malloc(sizeof(*dev));
00116     if (!dev)
00117         return -1;
00118 
00119     /* I2C */
00120     status = i2c_init(&dev->i2c_desc, &init_param.i2c_init);
00121 
00122     /* Device Settings */
00123     dev->resolution_setting = init_param.resolution_setting;
00124 
00125     test   = adt7420_get_register_value(dev, ADT7420_REG_ID);
00126     if(test != ADT7420_DEFAULT_ID)
00127         status = -1;
00128 
00129     *device = dev;
00130 
00131     return status;
00132 }
00133 
00134 /***************************************************************************//**
00135  * @brief Free the resources allocated by adt7420_init().
00136  *
00137  * @param dev - The device structure.
00138  *
00139  * @return ret - The result of the remove procedure.
00140 *******************************************************************************/
00141 int32_t adt7420_remove(struct adt7420_dev *dev)
00142 {
00143     int32_t ret;
00144 
00145     ret = i2c_remove(dev->i2c_desc);
00146 
00147     free(dev);
00148 
00149     return ret;
00150 }
00151 
00152 /***************************************************************************//**
00153  * @brief Resets the ADT7420.
00154  *        The ADT7420 does not respond to I2C bus commands while the default
00155  *        values upload (approximately 200 us).
00156  *
00157  * @param dev - The device structure.
00158  *
00159  * @return None.
00160 *******************************************************************************/
00161 void adt7420_reset(struct adt7420_dev *dev)
00162 {
00163     uint8_t register_address = ADT7420_REG_RESET;
00164 
00165     i2c_write(dev->i2c_desc,
00166           &register_address,
00167           1,
00168           1);
00169     dev->resolution_setting = 0;
00170 }
00171 
00172 /***************************************************************************//**
00173  * @brief Sets the operational mode for ADT7420.
00174  *
00175  * @param dev  - The device structure.
00176  * @param mode - Operation mode.
00177  *               Example: ADT7420_OP_MODE_CONT_CONV - continuous conversion;
00178  *                        ADT7420_OP_MODE_ONE_SHOT  - one shot;
00179  *                        ADT7420_OP_MODE_1_SPS     - 1 SPS mode;
00180  *                        ADT7420_OP_MODE_SHUTDOWN  - shutdown.
00181  *
00182  * @return None.
00183 *******************************************************************************/
00184 void adt7420_set_operation_mode(struct adt7420_dev *dev,
00185                 uint8_t mode)
00186 {
00187     uint8_t register_value = 0;
00188 
00189     register_value  = adt7420_get_register_value(dev, ADT7420_REG_CONFIG);
00190     register_value &= ~ADT7420_CONFIG_OP_MODE(ADT7420_OP_MODE_SHUTDOWN);
00191     register_value |= ADT7420_CONFIG_OP_MODE(mode);
00192     adt7420_set_register_value(dev, ADT7420_REG_CONFIG, register_value);
00193 }
00194 
00195 /***************************************************************************//**
00196  * @brief Sets the resolution for ADT7420.
00197  *
00198  * @param dev        - The device structure.
00199  * @param resolution - Resolution.
00200  *                     Example: 0 - 13-bit resolution;
00201  *                              1 - 16-bit resolution.
00202  *
00203  * @return None.
00204 *******************************************************************************/
00205 void adt7420_set_resolution(struct adt7420_dev *dev,
00206                 uint8_t resolution)
00207 {
00208     uint8_t register_value = 0;
00209 
00210     register_value  = adt7420_get_register_value(dev, ADT7420_REG_CONFIG);
00211     register_value &= ~ADT7420_CONFIG_RESOLUTION;
00212     register_value |= (resolution * ADT7420_CONFIG_RESOLUTION);
00213     adt7420_set_register_value(dev, ADT7420_REG_CONFIG, register_value);
00214     dev->resolution_setting = resolution;
00215 }
00216 
00217 /***************************************************************************//**
00218  * @brief Reads the temperature data and converts it to Celsius degrees.
00219  *
00220  * @param dev - The device structure.
00221  *
00222  * @return temperature - Temperature in degrees Celsius.
00223 *******************************************************************************/
00224 float adt7420_get_temperature(struct adt7420_dev *dev)
00225 {
00226     uint8_t msb_temp = 0;
00227     uint8_t lsb_temp = 0;
00228     uint16_t temp = 0;
00229     float temp_c = 0;
00230 
00231     msb_temp = adt7420_get_register_value(dev, ADT7420_REG_TEMP_MSB);
00232     lsb_temp = adt7420_get_register_value(dev, ADT7420_REG_TEMP_LSB);
00233     temp    = ((uint16_t)msb_temp << 8) + lsb_temp;
00234     if(dev->resolution_setting) {
00235         if(temp & 0x8000)
00236             /*! Negative temperature */
00237             temp_c = (float)((int32_t)temp - 65536) / 128;
00238         else
00239             /*! Positive temperature */
00240             temp_c = (float)temp / 128;
00241     } else {
00242         temp >>= 3;
00243         if(temp & 0x1000)
00244             /*! Negative temperature */
00245             temp_c = (float)((int32_t)temp - 8192) / 16;
00246         else
00247             /*! Positive temperature */
00248             temp_c = (float)temp / 16;
00249     }
00250 
00251     return temp_c;
00252 }