Firmware Library for X-NUCLEO-IKS01A1 (MEMS Inertial & Environmental Sensors) Expansion Board

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Dependents:   MultiTech_Dragonfly_2015_ATT_Gov_Solutions_Hackathon_Example HelloWorld_IKS01A1 LoRaWAN-test-10secs ServoMotorDemo ... more

Fork of X_NUCLEO_IKS01A1 by ST Expansion SW Team

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers x_nucleo_iks01a1.cpp Source File

x_nucleo_iks01a1.cpp

Go to the documentation of this file.
00001 /**
00002  ******************************************************************************
00003  * @file    x_nucleo_iks01a1.cpp
00004  * @author  AST / EST
00005  * @version V0.0.1
00006  * @date    08-October-2014
00007  * @brief   Implementation file for the X_NUCLEO_IKS01A1 singleton class
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 "x_nucleo_iks01a1.h"
00041 
00042 /* Static variables ----------------------------------------------------------*/
00043 X_NUCLEO_IKS01A1* X_NUCLEO_IKS01A1::_instance = NULL;
00044 
00045 
00046 /* Methods -------------------------------------------------------------------*/
00047 /**
00048  * @brief  Constructor
00049  */
00050 X_NUCLEO_IKS01A1::X_NUCLEO_IKS01A1(DevI2C *ext_i2c, PinName ff_irq_pin) : dev_i2c(ext_i2c),
00051     ht_sensor(new HTS221(*dev_i2c)),
00052     magnetometer(new LIS3MDL(*dev_i2c)),
00053     pt_sensor(new LPS25H(*dev_i2c)),
00054     gyro_lsm6ds0(new LSM6DS0(*dev_i2c))
00055 { 
00056     if(ff_irq_pin == NC) {
00057         gyro_lsm6ds3 = NULL;
00058     } else {
00059         gyro_lsm6ds3 = new LSM6DS3(*dev_i2c, ff_irq_pin);
00060     }
00061 }
00062 
00063 /**
00064  * @brief     Get singleton instance
00065  * @return    a pointer to the initialized singleton instance of class X_NUCLEO_IKS01A1.
00066  *            A return value of NULL indicates an out of memory situation.
00067  * @param[in] ext_i2c (optional) pointer to an instance of DevI2C to be used
00068  *            for communication on the expansion board. 
00069  *            Defaults to NULL.
00070  *            Taken into account only on the very first call of one of the 'Instance' functions.
00071  *            If not provided a new DevI2C will be created with standard
00072  *            configuration parameters.
00073  *            The used DevI2C object gets saved in instance variable dev_i2c.
00074  * @param[in] ff_irq_pin (optional) PinName of the pin associated to asynchronous 
00075  *            (i.e. interrupt based) free fall detection in case a LSM6DS3 3D 
00076  *            Acceleromenter and 3D Gyroscope is mounted on top of the DIL 24-pin socket.
00077  *            Defaults to IKS01A1_PIN_FF.
00078  *            Taken into account only on the very first call of one of the 'Instance' functions.
00079  *            A value of 'NC' will avoid instantiation of the LSM6DS3 even if present.
00080  */
00081 X_NUCLEO_IKS01A1* X_NUCLEO_IKS01A1::Instance(DevI2C *ext_i2c, PinName ff_irq_pin) {
00082     if(_instance == NULL) {
00083         if(ext_i2c == NULL)
00084             ext_i2c = new DevI2C(IKS01A1_PIN_I2C_SDA, IKS01A1_PIN_I2C_SCL);
00085 
00086         if(ext_i2c != NULL)
00087             _instance = new X_NUCLEO_IKS01A1(ext_i2c, ff_irq_pin);
00088     
00089         if(_instance != NULL) {
00090             bool ret = _instance->Init();
00091             if(!ret) {
00092                 error("Failed to init X_NUCLEO_IKS01A1 expansion board!\n");
00093             }
00094         }
00095     }
00096 
00097     return _instance;
00098 }
00099 
00100 /**
00101  * @brief     Get singleton instance
00102  * @return    a pointer to the initialized singleton instance of class X_NUCLEO_IKS01A1.
00103  *            A return value of NULL indicates an out of memory situation.
00104  * @param[in] sda I2C data line pin.
00105  *            Taken into account only on the very first call of one of the 'Instance' functions.
00106  *            A new DevI2C will be created based on parameters 'sda' and 'scl'.
00107  *            The used DevI2C object gets saved in instance variable dev_i2c.
00108  * @param[in] scl I2C clock line pin.
00109  *            Taken into account only on the very first call of one of the 'Instance' functions.
00110  *            A new DevI2C will be created based on parameters 'sda' and 'scl'.
00111  *            The used DevI2C object gets saved in instance variable dev_i2c.
00112  * @param[in] ff_irq_pin (optional) PinName of the pin associated to asynchronous 
00113  *            (i.e. interrupt based) free fall detection in case a LSM6DS3 3D 
00114  *            Acceleromenter and 3D Gyroscope is mounted on top of the DIL 24-pin socket.
00115  *            Defaults to NC.
00116  *            Taken into account only on the very first call of one of the 'Instance' functions.
00117  *            A value of 'NC' will avoid instantiation of the LSM6DS3 even if present.
00118  */
00119 X_NUCLEO_IKS01A1* X_NUCLEO_IKS01A1::Instance(PinName sda, PinName scl, PinName ff_irq_pin) {
00120     if(_instance == NULL) {
00121         DevI2C *ext_i2c = new DevI2C(sda, scl);
00122 
00123         if(ext_i2c != NULL)
00124             _instance = new X_NUCLEO_IKS01A1(ext_i2c, ff_irq_pin);
00125     
00126         if(_instance != NULL) {
00127             bool ret = _instance->Init();
00128             if(!ret) {
00129                 error("Failed to init X_NUCLEO_IKS01A1 expansion board!\n");
00130             }
00131         }
00132     }
00133 
00134     return _instance;
00135 }
00136 
00137 /**
00138  * @brief  Initialize the singleton's HT sensor
00139  * @retval true if initialization successful, 
00140  * @retval false otherwise
00141  */
00142 bool X_NUCLEO_IKS01A1::Init_HTS221(void) {
00143     uint8_t ht_id = 0;
00144     HUM_TEMP_InitTypeDef InitStructure;
00145 
00146     /* Check presence */
00147     if((ht_sensor->read_id(&ht_id) != HUM_TEMP_OK) ||
00148        (ht_id != I_AM_HTS221))
00149         {
00150             delete ht_sensor;
00151             ht_sensor = NULL;
00152             return true;
00153         }
00154     
00155     /* Configure sensor */
00156     InitStructure.OutputDataRate = HTS221_ODR_12_5Hz;
00157 
00158     if(ht_sensor->init(&InitStructure) != HUM_TEMP_OK)
00159         {
00160             return false;
00161         }
00162       
00163     return true;
00164 }
00165 
00166 /**
00167  * @brief  Initialize the singleton's magnetometer
00168  * @retval true if initialization successful, 
00169  * @retval false otherwise
00170  */
00171 bool X_NUCLEO_IKS01A1::Init_LIS3MDL(void) {
00172     uint8_t m_id = 0;
00173     MAGNETO_InitTypeDef InitStructure;
00174 
00175     /* Check presence */
00176     if((magnetometer->read_id(&m_id) != MAGNETO_OK) ||
00177        (m_id != I_AM_LIS3MDL_M))
00178         {
00179             delete magnetometer;
00180             magnetometer = NULL;
00181             return true;
00182         }
00183       
00184     /* Configure sensor */
00185     InitStructure.M_FullScale = LIS3MDL_M_FS_4;
00186     InitStructure.M_OperatingMode = LIS3MDL_M_MD_CONTINUOUS;
00187     InitStructure.M_XYOperativeMode = LIS3MDL_M_OM_HP;
00188     InitStructure.M_OutputDataRate = LIS3MDL_M_DO_80;
00189 
00190     if(magnetometer->init(&InitStructure) != MAGNETO_OK)
00191         {
00192             return false;
00193         }
00194       
00195     return true;
00196 }
00197 
00198 /**
00199  * @brief  Initialize the singleton's pressure sensor
00200  * @retval true if initialization successful, 
00201  * @retval false otherwise
00202  */
00203 bool X_NUCLEO_IKS01A1::Init_LPS25H(void) {
00204     uint8_t p_id = 0;
00205     PRESSURE_InitTypeDef InitStructure;
00206     
00207     /* Check presence */
00208     if((pt_sensor->read_id(&p_id) != PRESSURE_OK) ||
00209        (p_id != I_AM_LPS25H))
00210         {
00211             delete pt_sensor;
00212             pt_sensor = NULL;
00213             return true;
00214         }
00215             
00216     /* Configure sensor */
00217     InitStructure.OutputDataRate = LPS25H_ODR_1Hz;
00218     InitStructure.BlockDataUpdate = LPS25H_BDU_CONT;
00219     InitStructure.DiffEnable = LPS25H_DIFF_ENABLE;
00220     InitStructure.SPIMode = LPS25H_SPI_SIM_3W;
00221     InitStructure.PressureResolution = LPS25H_P_RES_AVG_32;
00222     InitStructure.TemperatureResolution = LPS25H_T_RES_AVG_16;
00223         
00224     if(pt_sensor->init(&InitStructure) != PRESSURE_OK)
00225         {
00226             return false;
00227         }
00228             
00229     return true;
00230 }
00231 
00232 /**
00233  * @brief  Initialize the singleton's LSM6DS0 gyroscope
00234  * @retval true if initialization successful, 
00235  * @retval false otherwise
00236  */
00237 bool X_NUCLEO_IKS01A1::Init_LSM6DS0(void) {
00238     IMU_6AXES_InitTypeDef InitStructure;
00239     uint8_t xg_id = 0;
00240 
00241     /* Check presence */
00242     if((gyro_lsm6ds3 != NULL) || // by default do not instantiate two gyroscopes
00243        (gyro_lsm6ds0->read_id(&xg_id) != IMU_6AXES_OK) ||
00244        (xg_id != I_AM_LSM6DS0_XG))
00245         {
00246             delete gyro_lsm6ds0;
00247             gyro_lsm6ds0 = NULL;
00248             return true;
00249         }
00250             
00251     /* Configure sensor */
00252     InitStructure.G_FullScale       = 2000.0f; /* 2000DPS */
00253     InitStructure.G_OutputDataRate  = 119.0f;  /* 119HZ */
00254     InitStructure.G_X_Axis          = 1;       /* Enable */
00255     InitStructure.G_Y_Axis          = 1;       /* Enable */
00256     InitStructure.G_Z_Axis          = 1;       /* Enable */
00257 
00258     InitStructure.X_FullScale       = 2.0f;    /* 2G */
00259     InitStructure.X_OutputDataRate  = 119.0f;  /* 119HZ */
00260     InitStructure.X_X_Axis          = 1;       /* Enable */
00261     InitStructure.X_Y_Axis          = 1;       /* Enable */
00262     InitStructure.X_Z_Axis          = 1;       /* Enable */
00263               
00264     if(gyro_lsm6ds0->init(&InitStructure) != IMU_6AXES_OK)
00265         {
00266             return false; 
00267         }
00268             
00269     return true;
00270 }
00271 
00272 /**
00273  * @brief  Initialize the singleton's LSMDS3 gyroscope
00274  * @retval true if initialization successful, 
00275  * @retval false otherwise
00276  */
00277 bool X_NUCLEO_IKS01A1::Init_LSM6DS3(void) {
00278     IMU_6AXES_InitTypeDef InitStructure;
00279     uint8_t xg_id = 0;
00280 
00281     /* Check presence */
00282     if(gyro_lsm6ds3 == NULL) return true;
00283 
00284     if((gyro_lsm6ds3->read_id(&xg_id) != IMU_6AXES_OK) ||
00285        (xg_id != I_AM_LSM6DS3_XG))
00286         {
00287             delete gyro_lsm6ds3;
00288             gyro_lsm6ds3 = NULL;
00289             return true;
00290         }
00291             
00292     /* Configure sensor */
00293     InitStructure.G_FullScale      = 2000.0f; /* 2000DPS */
00294     InitStructure.G_OutputDataRate = 104.0f;  /* 104HZ */
00295     InitStructure.G_X_Axis         = 1;       /* Enable */
00296     InitStructure.G_Y_Axis         = 1;       /* Enable */
00297     InitStructure.G_Z_Axis         = 1;       /* Enable */
00298         
00299     InitStructure.X_FullScale      = 2.0f;    /* 2G */
00300     InitStructure.X_OutputDataRate = 104.0f;  /* 104HZ */
00301     InitStructure.X_X_Axis         = 1;       /* Enable */
00302     InitStructure.X_Y_Axis         = 1;       /* Enable */
00303     InitStructure.X_Z_Axis         = 1;       /* Enable */
00304         
00305     if(gyro_lsm6ds3->init(&InitStructure) != IMU_6AXES_OK)
00306         {
00307             return false; 
00308         }
00309             
00310     return true;
00311 }