ST Americas mbed Team / Nucleo_Sensor_Shield

Dependents:   Nucleo_Sensors_Demo m2x-temp_ethernet_demo m2x-MEMS_ACKme_Wifi_demo m2x_MEMS_Ublox_Cellular_demo ... more

Fork of Nucleo_Sensor_Shield by Daniel Griffin

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers hts221.cpp Source File

hts221.cpp

00001 /**
00002 ******************************************************************************
00003 * @file    x_cube_mems_hts221.h
00004 * @author  AST / EST
00005 * @version V0.0.1
00006 * @date    1-December-2014
00007 * @brief   Header file for component HTS221
00008 ******************************************************************************
00009 * @attention
00010 *
00011 * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
00012 *
00013 * Redistribution and use in source and binary forms, with or without modification,
00014 * are permitted provided that the following conditions are met:
00015 *   1. Redistributions of source code must retain the above copyright notice,
00016 *      this list of conditions and the following disclaimer.
00017 *   2. Redistributions in binary form must reproduce the above copyright notice,
00018 *      this list of conditions and the following disclaimer in the documentation
00019 *      and/or other materials provided with the distribution.
00020 *   3. Neither the name of STMicroelectronics nor the names of its contributors
00021 *      may be used to endorse or promote products derived from this software
00022 *      without specific prior written permission.
00023 *
00024 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00025 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00028 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00030 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00032 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 *
00035 ******************************************************************************
00036 */
00037 
00038 /* Includes ------------------------------------------------------------------*/
00039 #include "mbed.h"
00040 #include "hts221.h"
00041 #include "hts221_platform.h"
00042 
00043 
00044 /* Temperature in degree for calibration  */
00045 float T0_degC, T1_degC;
00046 
00047 /* Output temperature value for calibration */
00048 int16_t T0_out, T1_out;
00049 
00050 
00051 /* Humidity for calibration  */
00052 float H0_rh, H1_rh;
00053 
00054 /* Output Humidity value for calibration */
00055 int16_t H0_T0_out, H1_T0_out;
00056 
00057 /* Methods -------------------------------------------------------------------*/
00058 
00059 /**
00060  * @brief  Read HTS221 output register, and calculate the temperature.
00061  * @param  pfData : Data out pointer
00062  * @retval None
00063  */
00064 int HTS221::GetTemperature(float* pfData)
00065 {
00066     int16_t T_out, temperature_t;
00067     uint8_t tempReg[2] = {0,0};
00068     uint8_t tmp = 0x00;
00069     float T_degC;
00070     int ret=-1;//TODO:Define Error types?
00071     
00072     if(isInitialized()==0)
00073       {
00074         return ret;
00075       }
00076     
00077     ret = dev_i2c.i2c_read(&tmp, HTS221_ADDRESS, HTS221_CTRL_REG1_ADDR, 1);
00078 
00079     /* Output Data Rate selection */
00080     tmp &= (HTS221_ODR_MASK);
00081     
00082     if(tmp == 0x00){
00083     
00084       ret = dev_i2c.i2c_read(&tmp, HTS221_ADDRESS, HTS221_CTRL_REG2_ADDR, 1);
00085       
00086       /* Serial Interface Mode selection */
00087       tmp &= ~(HTS221_ONE_SHOT_MASK);
00088       tmp |= HTS221_ONE_SHOT_START;
00089 
00090       ret = dev_i2c.i2c_write(&tmp, HTS221_ADDRESS, HTS221_CTRL_REG2_ADDR, 1);
00091     
00092       do{
00093       
00094         ret = dev_i2c.i2c_read(&tmp, HTS221_ADDRESS, HTS221_STATUS_REG_ADDR, 1);
00095       }while(!(tmp&&0x01));
00096     
00097     }
00098 
00099     ret = dev_i2c.i2c_read(&tempReg[0], HTS221_ADDRESS , HTS221_TEMP_OUT_L_ADDR + 0x80, 2);
00100     T_out = ((((int16_t)tempReg[1]) << 8)+(int16_t)tempReg[0]);
00101 
00102     T_degC = ((float)(T_out - T0_out))/(T1_out - T0_out) * (T1_degC - T0_degC) + T0_degC;
00103 
00104     temperature_t = (int16_t)(T_degC * pow((double)10,(double)TEMP_DECIMAL_DIGITS));
00105 
00106     *pfData = ((float)temperature_t)/pow((double)10,(double)TEMP_DECIMAL_DIGITS);
00107     
00108     return ret;
00109 }
00110 
00111 
00112 /**
00113  * @brief  Read HTS221 output register, and calculate the humidity.
00114  * @param  pfData : Data out pointer
00115  * @retval None
00116  */
00117 int HTS221::GetHumidity(float* pfData)
00118 {
00119     int16_t H_T_out, humidity_t;
00120     uint8_t tempReg[2] = {0,0};
00121     uint8_t tmp = 0x00;
00122     float H_rh;
00123     int ret;
00124     
00125     if(isInitialized()==0)
00126       {
00127         pfData = 0;
00128         return -1;
00129       }
00130     
00131     //HUM_TEMP_IO_Read(&tmp, HTS221_ADDRESS, HTS221_CTRL_REG1_ADDR, 1);
00132     ret = dev_i2c.i2c_read(&tmp, HTS221_ADDRESS , HTS221_CTRL_REG1_ADDR, 1);
00133 
00134     /* Output Data Rate selection */
00135     tmp &= (HTS221_ODR_MASK);
00136     
00137     if(tmp == 0x00){
00138     
00139       //HUM_TEMP_IO_Read(&tmp, HTS221_ADDRESS, HTS221_CTRL_REG2_ADDR, 1);
00140       ret = dev_i2c.i2c_read(&tmp, HTS221_ADDRESS , HTS221_CTRL_REG2_ADDR, 1);
00141 
00142       /* Serial Interface Mode selection */
00143       tmp &= ~(HTS221_ONE_SHOT_MASK);
00144       tmp |= HTS221_ONE_SHOT_START;
00145 
00146       //HUM_TEMP_IO_Write(&tmp, HTS221_ADDRESS, HTS221_CTRL_REG2_ADDR, 1);
00147       ret = dev_i2c.i2c_write(&tmp, HTS221_ADDRESS , HTS221_CTRL_REG2_ADDR, 1);
00148     
00149       do{
00150       
00151         //HUM_TEMP_IO_Read(&tmp, HTS221_ADDRESS, HTS221_STATUS_REG_ADDR, 1);
00152         ret = dev_i2c.i2c_read(&tmp, HTS221_ADDRESS , HTS221_STATUS_REG_ADDR, 1);
00153          
00154       }while(!(tmp&&0x02));
00155     
00156     }
00157     
00158     
00159     //HUM_TEMP_IO_Read(&tempReg[0], HTS221_ADDRESS, HTS221_HUMIDITY_OUT_L_ADDR + 0x80, 2);
00160     ret = dev_i2c.i2c_read(&tempReg[0], HTS221_ADDRESS , HTS221_HUMIDITY_OUT_L_ADDR + 0x80, 2);
00161     H_T_out = ((((int16_t)tempReg[1]) << 8)+(int16_t)tempReg[0]);
00162 
00163     H_rh = ((float)(H_T_out - H0_T0_out))/(H1_T0_out - H0_T0_out) * (H1_rh - H0_rh) + H0_rh;
00164 
00165     humidity_t = (uint16_t)(H_rh * pow((double)10,(double)HUM_DECIMAL_DIGITS));
00166 
00167     *pfData = ((float)humidity_t)/pow((double)10,(double)HUM_DECIMAL_DIGITS);
00168     
00169     return ret;
00170 }
00171 
00172 
00173 /**
00174  * @brief  Read ID address of HTS221
00175  * @param  Device ID address
00176  * @retval ID name
00177  */
00178 uint8_t HTS221::ReadID(void)
00179 {
00180     uint8_t tmp;
00181     int ret;
00182     
00183     /* Read WHO I AM register */
00184     //HUM_TEMP_IO_Read(&tmp, HTS221_ADDRESS, HTS221_WHO_AM_I_ADDR, 1);
00185     ret = dev_i2c.i2c_read(&tmp, HTS221_ADDRESS, HTS221_WHO_AM_I_ADDR, 1);
00186 
00187     /* Return the ID */
00188     return ((ret == 0) ? (uint8_t)tmp : 0);
00189 }
00190 
00191 /**
00192  * @brief  Set HTS221 Initialization.
00193  * @param  InitStruct: it contains the configuration setting for the HTS221.
00194  * @retval None
00195  */
00196 void HTS221::Init() {
00197     
00198     uint8_t tmp = 0x00;
00199     int ret;
00200     
00201     Power_ON();
00202 
00203     HTS221_Calibration();
00204     
00205     //HUM_TEMP_IO_Read(&tmp, HTS221_ADDRESS, HTS221_CTRL_REG1_ADDR, 1);
00206     ret = dev_i2c.i2c_read(&tmp, HTS221_ADDRESS, HTS221_CTRL_REG1_ADDR, 1);
00207     
00208     if (ret == 0)
00209     {
00210       /* Output Data Rate selection */
00211       tmp &= ~(HTS221_ODR_MASK);
00212       tmp |= HTS221_ODR_12_5Hz;
00213 
00214       //HUM_TEMP_IO_Write(&tmp, HTS221_ADDRESS, HTS221_CTRL_REG1_ADDR, 1);
00215       ret = dev_i2c.i2c_write(&tmp, HTS221_ADDRESS, HTS221_CTRL_REG1_ADDR, 1);
00216     }
00217     
00218     if (ret == 0)
00219     {
00220       if(ReadID() == I_AM_HTS221)
00221       {
00222         HumTempInitialized = 1;
00223         //ret = HUM_TEMP_OK;
00224       }
00225     }
00226     
00227     return;
00228 }
00229 
00230 int HTS221::Power_ON() {
00231     
00232     uint8_t tmpReg;
00233 
00234     /* Read the register content */
00235     int ret;    
00236     ret = dev_i2c.i2c_read(&tmpReg, HTS221_ADDRESS, HTS221_CTRL_REG1_ADDR, 1);
00237     if(ret) return ret;
00238 
00239     /* Set the power down bit */
00240     tmpReg |= HTS221_MODE_ACTIVE;
00241 
00242     /* Write register */
00243     ret = dev_i2c.i2c_write(&tmpReg, HTS221_ADDRESS, HTS221_CTRL_REG1_ADDR, 1);
00244     if(ret) return ret;       
00245     return ret;
00246 }
00247 
00248 int HTS221::HTS221_Calibration() {
00249   
00250     if(HumTempInitialized == 1)
00251     {
00252       return 1; //TODO: Error Codes definitions
00253     }
00254     
00255   /* Temperature Calibration */
00256     /* Temperature in degree for calibration ( "/8" to obtain float) */
00257     uint16_t T0_degC_x8_L, T0_degC_x8_H, T1_degC_x8_L, T1_degC_x8_H;
00258     uint8_t H0_rh_x2, H1_rh_x2;
00259     uint8_t tempReg[2] = {0,0};
00260 
00261     int ret;    
00262     ret = dev_i2c.i2c_read(tempReg, HTS221_ADDRESS, HTS221_T0_degC_X8_ADDR, 1);
00263     if(ret) return ret;
00264     
00265     T0_degC_x8_L = (uint16_t)tempReg[0];
00266 
00267     ret = dev_i2c.i2c_read(tempReg, HTS221_ADDRESS, HTS221_T1_T0_MSB_X8_ADDR, 1);
00268     if(ret) return ret;
00269     T0_degC_x8_H = (uint16_t) (tempReg[0] & 0x03);
00270 
00271     T0_degC = ((float)((T0_degC_x8_H<<8) | (T0_degC_x8_L)))/8;
00272 
00273     ret = dev_i2c.i2c_read(tempReg, HTS221_ADDRESS, HTS221_T1_degC_X8_ADDR, 1);
00274     T1_degC_x8_L = (uint16_t)tempReg[0];
00275 
00276     ret = dev_i2c.i2c_read(tempReg, HTS221_ADDRESS, HTS221_T1_T0_MSB_X8_ADDR, 1);
00277     T1_degC_x8_H = (uint16_t) (tempReg[0] & 0x0C);
00278     T1_degC_x8_H = T1_degC_x8_H >> 2;
00279 
00280     T1_degC = ((float)((T1_degC_x8_H<<8) | (T1_degC_x8_L)))/8;
00281 
00282     ret = dev_i2c.i2c_read(tempReg, HTS221_ADDRESS, HTS221_T0_OUT_L_ADDR + 0x80, 2);
00283     T0_out = ((((int16_t)tempReg[1]) << 8)+(int16_t)tempReg[0]);
00284 
00285     ret = dev_i2c.i2c_read(tempReg, HTS221_ADDRESS, HTS221_T1_OUT_L_ADDR + 0x80, 2);
00286     T1_out = ((((int16_t)tempReg[1]) << 8)+(int16_t)tempReg[0]);
00287 
00288     /* Humidity Calibration */
00289     /* Humidity in degree for calibration ( "/2" to obtain float) */
00290 
00291     ret = dev_i2c.i2c_read(&H0_rh_x2, HTS221_ADDRESS, HTS221_H0_RH_X2_ADDR, 1);
00292 
00293     ret = dev_i2c.i2c_read(&H1_rh_x2, HTS221_ADDRESS, HTS221_H1_RH_X2_ADDR, 1);
00294 
00295     ret = dev_i2c.i2c_read(&tempReg[0], HTS221_ADDRESS, HTS221_H0_T0_OUT_L_ADDR + 0x80, 2);
00296     H0_T0_out = ((((int16_t)tempReg[1]) << 8)+(int16_t)tempReg[0]);
00297 
00298     ret = dev_i2c.i2c_read(&tempReg[0], HTS221_ADDRESS, HTS221_H1_T0_OUT_L_ADDR + 0x80, 2);
00299     H1_T0_out = ((((int16_t)tempReg[1]) << 8)+(int16_t)tempReg[0]);
00300     
00301     H0_rh = ((float)H0_rh_x2)/2;
00302     H1_rh = ((float)H1_rh_x2)/2;
00303     
00304     return ret;
00305 }