A collection of Analog Devices drivers for the mbed platform

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CN0357.cpp Source File

CN0357.cpp

00001 /**
00002 *   @file     cn0357.cpp
00003 *   @brief    Source file for CN0357
00004 *   @author   Analog Devices Inc.
00005 *
00006 * For support please go to:
00007 * Github: https://github.com/analogdevicesinc/mbed-adi
00008 * Support: https://ez.analog.com/community/linux-device-drivers/microcontroller-no-os-drivers
00009 * Product: www.analog.com/EVAL-CN0357-ARDZ
00010 * More: https://wiki.analog.com/resources/tools-software/mbed-drivers-all
00011 
00012 ********************************************************************************
00013 * Copyright 2016(c) Analog Devices, Inc.
00014 *
00015 * All rights reserved.
00016 *
00017 * Redistribution and use in source and binary forms, with or without
00018 * modification, are permitted provided that the following conditions are met:
00019 *  - Redistributions of source code must retain the above copyright
00020 *    notice, this list of conditions and the following disclaimer.
00021 *  - Redistributions in binary form must reproduce the above copyright
00022 *    notice, this list of conditions and the following disclaimer in
00023 *    the documentation and/or other materials provided with the
00024 *    distribution.
00025 *  - Neither the name of Analog Devices, Inc. nor the names of its
00026 *    contributors may be used to endorse or promote products derived
00027 *    from this software without specific prior written permission.
00028 *  - The use of this software may or may not infringe the patent rights
00029 *    of one or more patent holders.  This license does not release you
00030 *    from the requirement that you obtain separate licenses from these
00031 *    patent holders to use this software.
00032 *  - Use of the software either in source or binary form, must be run
00033 *    on or directly connected to an Analog Devices Inc. component.
00034 *
00035 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
00036 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
00037 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00038 * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
00039 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00040 * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
00041 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00042 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00043 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00044 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00045 *
00046 ********************************************************************************/
00047 
00048 #include "mbed.h"
00049 #include "AD7790.h"
00050 #include "AD5270.h"
00051 #include "CN0357.h"
00052 
00053 /**
00054  * @brief CN0357 constructor
00055  * @param CSAD7790 - (optional)chip select of the AD7790
00056  * @param CSAD5270 - (optional)chip select of the AD5270
00057  * @param MOSI - (optional)pin of the SPI interface
00058  * @param MISO - (optional)pin of the SPI interface
00059  * @param SCK  - (optional)pin of the SPI interface
00060  */
00061 CN0357::CN0357(PinName CSAD7790, PinName CSAD5270, PinName MOSI, PinName MISO,
00062                PinName SCK) :
00063     _vref(1.2), _sensor_sensitivity(0), _sensor_range(0), _RDACvalue(0),
00064     ad7790(_vref, CSAD7790, MOSI, MISO, SCK), ad5270(CSAD5270, 20000.0, MOSI, MISO, SCK)
00065 
00066 {
00067 }
00068 
00069 /**
00070  * @brief initializes the AD7790 and the AD5270
00071  * @param range - range of the sensor used (in ppm)
00072  * @param sensitivity - sensitivity of the sensor (A/ppm)
00073  * @param jp - (optional)jumper configuration of the CN0357
00074  * @param mode_val - (optional)if jp is set to InternalADC, configures the mode register of the Internal ADC
00075  * @param filter_val - (optional)if jp is set to InternalADC, configures the filter register of the Internal ADC
00076  */
00077 void CN0357::init(float range, float sensitivity, JumperConfig_t jp, uint8_t mode_val, uint8_t filter_val)
00078 {
00079     ad5270.frequency(500000);
00080     ad7790.frequency(500000);
00081 
00082     float resistance = set_sensor_parameters(range, sensitivity);
00083 
00084     if(jp == INTERNAL_AD7790) {
00085         _AD7790_init(mode_val, filter_val);
00086     }
00087     _rdac_init(resistance);
00088 }
00089 
00090 /**
00091  * @brief initializes the RDAC and sets SDO to HiZ
00092  * @param resistance - resistance value to initialize the RDAC
00093  * @return
00094  */
00095 void CN0357::_rdac_init(float resistance)
00096 {
00097     /* RDAC initialization*/
00098     /* Compute for the nearest RDAC value from given resistance and save data to the structure */
00099     set_RDAC_value(resistance);
00100     /* Set AD5270 SDO to Hi-Z */
00101     ad5270.set_SDO_HiZ();
00102 }
00103 
00104 /**
00105  * @brief initializes the AD7790
00106  * @param mode_val -  configures the mode register of the Internal ADC
00107  * @param filter_val -  configures the filter register of the Internal ADC
00108  */
00109 void CN0357::_AD7790_init(uint8_t mode_val, uint8_t filter_val)
00110 {
00111     ad7790.reset();
00112     wait_ms(50);
00113 
00114     ad7790.write_mode_reg(mode_val);
00115     wait_us(2);
00116 
00117     ad7790.write_filter_reg(filter_val);
00118     wait_ms(50);
00119 }
00120 
00121 /**
00122  * @brief reads the status register of the AD7790
00123  * @return status register value
00124  */
00125 uint8_t CN0357::read_adc_status(void)
00126 {
00127     return ad7790.read_status_reg();
00128 }
00129 
00130 /**
00131  * @brief reads the ADC and computes the sensor voltage
00132  * @return sensor voltage
00133  */
00134 float CN0357::read_sensor_voltage(void)
00135 {
00136     return ad7790.read_voltage();
00137 }
00138 
00139 /**
00140  * @brief reads the data register of the AD7790
00141  * @return data register value
00142  */
00143 uint16_t CN0357::read_sensor(void)
00144 {
00145     return ad7790.read_u16();
00146 }
00147 
00148 /**
00149  * @brief reads and computes the sensor reading in PPM
00150  * @return value of the sensor reading in PPM
00151  */
00152 float CN0357::read_ppm()
00153 {
00154     return calc_ppm(ad7790.read_voltage()); /* Convert voltage to Gas concentration*/
00155 }
00156 
00157 /**
00158  * @brief computes a value in PPM from a reading received as a param
00159  * @param adcVoltage - voltage to be converted to PPM
00160  * @return sensor value in PPM
00161  */
00162 float CN0357::calc_ppm(float adcVoltage)
00163 {
00164     float fConcentration = 0;
00165     fConcentration = (fabs(adcVoltage) / _RDACvalue) / _sensor_sensitivity;
00166     return fConcentration;
00167 }
00168 
00169 /**
00170  * @brief computes voltage from a 16 bit ADC value received as a parameter
00171  * @param data - ADC value
00172  * @return sensor voltage
00173  */
00174 float CN0357::data_to_voltage(uint16_t data)
00175 {
00176     return ad7790.data_to_voltage(data);
00177 }
00178 
00179 /**
00180  * @brief sets a new value for the RDAC
00181  * @param resistance new value for the resistance
00182  * @return none
00183  */
00184 void CN0357::set_RDAC_value(float resistance)
00185 {
00186     _RDACvalue = ad5270.write_RDAC(resistance);
00187 }
00188 
00189 /**
00190  * @brief getter method for RDAC value
00191  * @return value of the RDAC in ohms
00192  */
00193 float CN0357::get_RDAC_value()
00194 {
00195     return _RDACvalue;
00196 }
00197 
00198 /**
00199  * @brief set sensor range and sensitivity
00200  * sets sensor range, sensitivity
00201  * returns suggested resistance value for feedback resistor
00202  * @param range - range of the sensor used (in ppm)
00203  * @param sensitivity - sensitivity of the sensor (in A/ppm)
00204  * @return suggested resistance value for feedback resistor
00205  */
00206 float CN0357::set_sensor_parameters(float range, float sensitivity)
00207 {
00208     _sensor_sensitivity = static_cast<float>(sensitivity);
00209     _sensor_range = range;
00210     return (_vref / (static_cast<float>(_sensor_range * _sensor_sensitivity)));
00211 }
00212 
00213 /**
00214  * @brief getter method for sensor sensitivity
00215  * @return sensor sensitivity (in A/ppm)
00216  */
00217 float CN0357::get_sensor_sensitivity()
00218 {
00219     return _sensor_sensitivity;
00220 }
00221 
00222 /**
00223  * @brief getter method for sensor range
00224  * @return sensor range (in ppm)
00225  */
00226 float CN0357::get_sensor_range()
00227 {
00228     return _sensor_range;
00229 }