Workshop example

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Files at this revision

API Documentation at this revision

Comitter:
screamer
Date:
Sun Dec 16 13:53:42 2018 +0000
Parent:
17:fc98adcf835a
Child:
19:503bae65b9bd
Commit message:
Reorganize sensors

Changed in this revision

sensors/HTS221.lib Show diff for this revision Revisions of this file
sensors/HTS221/HTS221Sensor.cpp Show annotated file Show diff for this revision Revisions of this file
sensors/HTS221/HTS221Sensor.h Show annotated file Show diff for this revision Revisions of this file
sensors/HTS221/HTS221_driver.c Show annotated file Show diff for this revision Revisions of this file
sensors/HTS221/HTS221_driver.h Show annotated file Show diff for this revision Revisions of this file
sensors/LIS3MDL.lib Show diff for this revision Revisions of this file
sensors/LIS3MDL/lis3mdl.h Show annotated file Show diff for this revision Revisions of this file
sensors/LIS3MDL/lis3mdl_class.cpp Show annotated file Show diff for this revision Revisions of this file
sensors/LIS3MDL/lis3mdl_class.h Show annotated file Show diff for this revision Revisions of this file
sensors/LIS3MDL/magneto.h Show annotated file Show diff for this revision Revisions of this file
sensors/LIS3MDL/readme.txt Show annotated file Show diff for this revision Revisions of this file
sensors/LPS22HB.lib Show diff for this revision Revisions of this file
sensors/LPS22HB/LPS22HBSensor.cpp Show annotated file Show diff for this revision Revisions of this file
sensors/LPS22HB/LPS22HBSensor.h Show annotated file Show diff for this revision Revisions of this file
sensors/LPS22HB/LPS22HB_driver.c Show annotated file Show diff for this revision Revisions of this file
sensors/LPS22HB/LPS22HB_driver.h Show annotated file Show diff for this revision Revisions of this file
sensors/LSM6DSL.lib Show diff for this revision Revisions of this file
sensors/LSM6DSL/LSM6DSLSensor.cpp Show annotated file Show diff for this revision Revisions of this file
sensors/LSM6DSL/LSM6DSLSensor.h Show annotated file Show diff for this revision Revisions of this file
sensors/LSM6DSL/LSM6DSL_acc_gyro_driver.c Show annotated file Show diff for this revision Revisions of this file
sensors/LSM6DSL/LSM6DSL_acc_gyro_driver.h Show annotated file Show diff for this revision Revisions of this file
sensors/VL53L0X.lib Show diff for this revision Revisions of this file
sensors/VL53L0X/STMPE1600/Stmpe1600.h Show annotated file Show diff for this revision Revisions of this file
sensors/VL53L0X/VL53L0X.cpp Show annotated file Show diff for this revision Revisions of this file
sensors/VL53L0X/VL53L0X.h Show annotated file Show diff for this revision Revisions of this file
sensors/VL53L0X/VL53L0X_def.h Show annotated file Show diff for this revision Revisions of this file
sensors/VL53L0X/VL53L0X_device.h Show annotated file Show diff for this revision Revisions of this file
sensors/VL53L0X/VL53L0X_i2c_platform.h Show annotated file Show diff for this revision Revisions of this file
sensors/VL53L0X/VL53L0X_interrupt_threshold_settings.h Show annotated file Show diff for this revision Revisions of this file
sensors/VL53L0X/VL53L0X_platform.h Show annotated file Show diff for this revision Revisions of this file
sensors/VL53L0X/VL53L0X_platform_log.h Show annotated file Show diff for this revision Revisions of this file
sensors/VL53L0X/VL53L0X_tuning.h Show annotated file Show diff for this revision Revisions of this file
sensors/VL53L0X/VL53L0X_types.h Show annotated file Show diff for this revision Revisions of this file
sensors/common/ST_INTERFACES.lib Show annotated file Show diff for this revision Revisions of this file
sensors/common/X_NUCLEO_COMMON.lib Show annotated file Show diff for this revision Revisions of this file
--- a/sensors/HTS221.lib	Sun Dec 16 13:29:53 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://developer.mbed.org/teams/ST/code/HTS221/#312ee2694a77
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/HTS221/HTS221Sensor.cpp	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,312 @@
+/**
+ ******************************************************************************
+ * @file    HTS221Sensor.cpp
+ * @author  CLab
+ * @version V1.0.0
+ * @date    5 August 2016
+ * @brief   Implementation of an HTS221 Humidity and Temperature sensor.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+
+
+#include "HTS221Sensor.h"
+
+
+/* Class Implementation ------------------------------------------------------*/
+
+HTS221Sensor::HTS221Sensor(SPI *spi, PinName cs_pin, PinName drdy_pin) : 
+                           _dev_spi(spi), _cs_pin(cs_pin), _drdy_pin(drdy_pin)  // SPI3W ONLY
+{    
+    assert(spi); 
+    _dev_i2c = NULL;
+};
+
+/** Constructor
+ * @param i2c object of an helper class which handles the I2C peripheral
+ * @param address the address of the component's instance
+ */
+HTS221Sensor::HTS221Sensor(DevI2C *i2c, uint8_t address, PinName drdy_pin) :
+                           _dev_i2c(i2c), _address(address), _cs_pin(NC), _drdy_pin(drdy_pin)
+{
+    assert(i2c);
+    _dev_spi = NULL;
+};
+
+/**
+ * @brief     Initializing the component.
+ * @param[in] init pointer to device specific initalization structure.
+ * @retval    "0" in case of success, an error code otherwise.
+ */
+int HTS221Sensor::init(void *init)
+{
+  /* Power down the device */
+  if ( HTS221_DeActivate( (void *)this ) == HTS221_ERROR )
+  {
+    return 1;
+  }
+
+  /* Enable BDU */
+  if ( HTS221_Set_BduMode( (void *)this, HTS221_ENABLE ) == HTS221_ERROR )
+  {
+    return 1;
+  }
+  
+  if(set_odr(1.0f) == 1)
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief  Enable HTS221
+ * @retval 0 in case of success, an error code otherwise
+ */
+int HTS221Sensor::enable(void)
+{
+  /* Power up the device */
+  if ( HTS221_Activate( (void *)this ) == HTS221_ERROR )
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Disable HTS221
+ * @retval 0 in case of success, an error code otherwise
+ */
+int HTS221Sensor::disable(void)
+{
+  /* Power up the device */
+  if ( HTS221_DeActivate( (void *)this ) == HTS221_ERROR )
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Read ID address of HTS221
+ * @param  id the pointer where the ID of the device is stored
+ * @retval 0 in case of success, an error code otherwise
+ */
+int HTS221Sensor::read_id(uint8_t *id)
+{
+  if(!id)
+  { 
+    return 1;
+  }
+  
+  /* Read WHO AM I register */
+  if ( HTS221_Get_DeviceID( (void *)this, id ) == HTS221_ERROR )
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Reboot memory content of HTS221
+ * @param  None
+ * @retval 0 in case of success, an error code otherwise
+ */
+int HTS221Sensor::reset(void)
+{
+    uint8_t tmpreg;
+
+    /* Read CTRL_REG2 register */
+    if (read_reg(HTS221_CTRL_REG2, &tmpreg) != 0)
+    {
+      return 1;
+    }
+
+    /* Enable or Disable the reboot memory */
+    tmpreg |= (0x01 << HTS221_BOOT_BIT);
+
+    /* Write value to MEMS CTRL_REG2 regsister */
+    if (write_reg(HTS221_CTRL_REG2, tmpreg) != 0)
+    {
+      return 1;
+    }
+    
+    return 0;
+}
+
+/**
+ * @brief  Read HTS221 output register, and calculate the humidity
+ * @param  pfData the pointer to data output
+ * @retval 0 in case of success, an error code otherwise
+ */
+int HTS221Sensor::get_humidity(float* pfData)
+{
+  uint16_t uint16data = 0;
+
+  /* Read data from HTS221. */
+  if ( HTS221_Get_Humidity( (void *)this, &uint16data ) == HTS221_ERROR )
+  {
+    return 1;
+  }
+
+  *pfData = ( float )uint16data / 10.0f;
+
+  return 0;
+}
+
+/**
+ * @brief  Read HTS221 output register, and calculate the temperature
+ * @param  pfData the pointer to data output
+ * @retval 0 in case of success, an error code otherwise
+ */
+int HTS221Sensor::get_temperature(float* pfData)
+{
+  int16_t int16data = 0;
+
+  /* Read data from HTS221. */
+  if ( HTS221_Get_Temperature( (void *)this, &int16data ) == HTS221_ERROR )
+  {
+    return 1;
+  }
+
+  *pfData = ( float )int16data / 10.0f;
+
+  return 0;
+}
+
+/**
+ * @brief  Read HTS221 output register, and calculate the humidity
+ * @param  odr the pointer to the output data rate
+ * @retval 0 in case of success, an error code otherwise
+ */
+int HTS221Sensor::get_odr(float* odr)
+{
+  HTS221_Odr_et odr_low_level;
+
+  if ( HTS221_Get_Odr( (void *)this, &odr_low_level ) == HTS221_ERROR )
+  {
+    return 1;
+  }
+
+  switch( odr_low_level )
+  {
+    case HTS221_ODR_ONE_SHOT:
+      *odr =  0.0f;
+      break;
+    case HTS221_ODR_1HZ     :
+      *odr =  1.0f;
+      break;
+    case HTS221_ODR_7HZ     :
+      *odr =  7.0f;
+      break;
+    case HTS221_ODR_12_5HZ  :
+      *odr = 12.5f;
+      break;
+    default                 :
+      *odr = -1.0f;
+      return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set ODR
+ * @param  odr the output data rate to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int HTS221Sensor::set_odr(float odr)
+{
+  HTS221_Odr_et new_odr;
+
+  new_odr = ( odr <= 1.0f ) ? HTS221_ODR_1HZ
+          : ( odr <= 7.0f ) ? HTS221_ODR_7HZ
+          :                   HTS221_ODR_12_5HZ;
+
+  if ( HTS221_Set_Odr( (void *)this, new_odr ) == HTS221_ERROR )
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+
+/**
+ * @brief Read the data from register
+ * @param reg register address
+ * @param data register data
+ * @retval 0 in case of success
+ * @retval 1 in case of failure
+ */
+int HTS221Sensor::read_reg( uint8_t reg, uint8_t *data )
+{
+
+  if ( HTS221_read_reg( (void *)this, reg, 1, data ) == HTS221_ERROR )
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief Write the data to register
+ * @param reg register address
+ * @param data register data
+ * @retval 0 in case of success
+ * @retval 1 in case of failure
+ */
+int HTS221Sensor::write_reg( uint8_t reg, uint8_t data )
+{
+
+  if ( HTS221_write_reg( (void *)this, reg, 1, &data ) == HTS221_ERROR )
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+uint8_t HTS221_io_write( void *handle, uint8_t WriteAddr, uint8_t *pBuffer, uint16_t nBytesToWrite )
+{
+  return ((HTS221Sensor *)handle)->io_write(pBuffer, WriteAddr, nBytesToWrite);
+}
+
+uint8_t HTS221_io_read( void *handle, uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead )
+{
+  return ((HTS221Sensor *)handle)->io_read(pBuffer, ReadAddr, nBytesToRead);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/HTS221/HTS221Sensor.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,141 @@
+/**
+ ******************************************************************************
+ * @file    HTS221Sensor.h
+ * @author  CLab
+ * @version V1.0.0
+ * @date    5 August 2016
+ * @brief   Abstract class of an HTS221 Humidity and Temperature sensor.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+
+/* Prevent recursive inclusion -----------------------------------------------*/
+
+#ifndef __HTS221Sensor_H__
+#define __HTS221Sensor_H__
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "DevI2C.h"
+#include "HTS221_driver.h"
+#include "HumiditySensor.h"
+#include "TempSensor.h"
+#include <assert.h>
+
+/* Class Declaration ---------------------------------------------------------*/
+
+/**
+ * Abstract class of an HTS221 Humidity and Temperature sensor.
+ */
+class HTS221Sensor : public HumiditySensor, public TempSensor
+{
+  public:
+    HTS221Sensor(SPI *spi, PinName cs_pin=NC, PinName drdy_pin=NC);    // SPI3W ONLY
+    HTS221Sensor(DevI2C *i2c, uint8_t address=HTS221_I2C_ADDRESS, PinName drdy_pin=NC);
+    virtual int init(void *init);
+    virtual int read_id(uint8_t *id);
+    virtual int get_humidity(float *pfData);
+    virtual int get_temperature(float *pfData);
+    int enable(void);
+    int disable(void);
+    int reset(void);
+    int get_odr(float *odr);
+    int set_odr(float odr);
+    int read_reg(uint8_t reg, uint8_t *data);
+    int write_reg(uint8_t reg, uint8_t data);
+    /**
+     * @brief Utility function to read data.
+     * @param  pBuffer: pointer to data to be read.
+     * @param  RegisterAddr: specifies internal address register to be read.
+     * @param  NumByteToRead: number of bytes to be read.
+     * @retval 0 if ok, an error code otherwise.
+     */
+    uint8_t io_read(uint8_t* pBuffer, uint8_t RegisterAddr, uint16_t NumByteToRead)
+    {
+        if (_dev_spi) {
+        /* Write Reg Address */
+            _dev_spi->lock();
+            _cs_pin = 0;           
+            /* Write RD Reg Address with RD bit*/
+            uint8_t TxByte = RegisterAddr | 0x80;    
+            _dev_spi->write((char *)&TxByte, 1, (char *)pBuffer, (int) NumByteToRead);
+            _cs_pin = 1;
+            _dev_spi->unlock(); 
+            return 0;
+        }                       
+        if (_dev_i2c) return (uint8_t) _dev_i2c->i2c_read(pBuffer, _address, RegisterAddr, NumByteToRead);
+        return 1;
+    }
+    
+    /**
+     * @brief Utility function to write data.
+     * @param  pBuffer: pointer to data to be written.
+     * @param  RegisterAddr: specifies internal address register to be written.
+     * @param  NumByteToWrite: number of bytes to write.
+     * @retval 0 if ok, an error code otherwise.
+     */
+    uint8_t io_write(uint8_t* pBuffer, uint8_t RegisterAddr, uint16_t NumByteToWrite)
+    {
+        if (_dev_spi) { 
+            _dev_spi->lock();
+            _cs_pin = 0;
+            int data = _dev_spi->write(RegisterAddr);                    
+            _dev_spi->write((char *)pBuffer, (int) NumByteToWrite, NULL, 0);                     
+            _cs_pin = 1;                    
+            _dev_spi->unlock();
+            return data;                    
+        }        
+        if (_dev_i2c) return (uint8_t) _dev_i2c->i2c_write(pBuffer, _address, RegisterAddr, NumByteToWrite);    
+        return 1;
+    }
+
+  private:
+
+    /* Helper classes. */
+    DevI2C *_dev_i2c;
+    SPI    * _dev_spi;
+    
+    /* Configuration */
+    uint8_t _address;
+    DigitalOut  _cs_pin;        
+    InterruptIn _drdy_pin;    
+};
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+uint8_t HTS221_io_write( void *handle, uint8_t WriteAddr, uint8_t *pBuffer, uint16_t nBytesToWrite );
+uint8_t HTS221_io_read( void *handle, uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead );
+#ifdef __cplusplus
+  }
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/HTS221/HTS221_driver.c	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,987 @@
+/**
+ ******************************************************************************
+ * @file    HTS221_driver.c
+ * @author  HESA Application Team
+ * @version V1.1
+ * @date    10-August-2016
+ * @brief   HTS221 driver file
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "HTS221_driver.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifdef  USE_FULL_ASSERT_HTS221
+#include <stdio.h>
+#endif
+
+
+/** @addtogroup Environmental_Sensor
+* @{
+*/
+
+/** @defgroup HTS221_DRIVER
+* @brief HTS221 DRIVER
+* @{
+*/
+
+/** @defgroup HTS221_Imported_Function_Prototypes
+* @{
+*/
+
+extern uint8_t HTS221_io_write( void *handle, uint8_t WriteAddr, uint8_t *pBuffer, uint16_t nBytesToWrite );
+extern uint8_t HTS221_io_read( void *handle, uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead );
+
+/**
+* @}
+*/
+
+/** @defgroup HTS221_Private_Function_Prototypes
+* @{
+*/
+
+/**
+* @}
+*/
+
+/** @defgroup HTS221_Private_Functions
+* @{
+*/
+
+/**
+* @}
+*/
+
+/** @defgroup HTS221_Public_Functions
+* @{
+*/
+
+/*******************************************************************************
+* Function Name   : HTS221_read_reg
+* Description   : Generic Reading function. It must be fullfilled with either
+*         : I2C or SPI reading functions
+* Input       : Register Address
+* Output      : Data Read
+* Return      : None
+*******************************************************************************/
+HTS221_Error_et HTS221_read_reg( void *handle, uint8_t RegAddr, uint16_t NumByteToRead, uint8_t *Data )
+{
+
+  if ( NumByteToRead > 1 ) RegAddr |= 0x80;
+
+  if ( HTS221_io_read( handle, RegAddr, Data, NumByteToRead ) )
+    return HTS221_ERROR;
+  else
+    return HTS221_OK;
+}
+
+/*******************************************************************************
+* Function Name   : HTS221_write_reg
+* Description   : Generic Writing function. It must be fullfilled with either
+*         : I2C or SPI writing function
+* Input       : Register Address, Data to be written
+* Output      : None
+* Return      : None
+*******************************************************************************/
+HTS221_Error_et HTS221_write_reg( void *handle, uint8_t RegAddr, uint16_t NumByteToWrite, uint8_t *Data )
+{
+
+  if ( NumByteToWrite > 1 ) RegAddr |= 0x80;
+
+  if ( HTS221_io_write( handle, RegAddr, Data, NumByteToWrite ) )
+    return HTS221_ERROR;
+  else
+    return HTS221_OK;
+}
+
+/**
+* @brief  Get the version of this driver.
+* @param  pxVersion pointer to a HTS221_DriverVersion_st structure that contains the version information.
+*         This parameter is a pointer to @ref HTS221_DriverVersion_st.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_DriverVersion(HTS221_DriverVersion_st* version)
+{
+  version->Major = HTS221_DRIVER_VERSION_MAJOR;
+  version->Minor = HTS221_DRIVER_VERSION_MINOR;
+  version->Point = HTS221_DRIVER_VERSION_POINT;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Get device type ID.
+* @param  *handle Device handle.
+* @param  deviceid pointer to the returned device type ID.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_DeviceID(void *handle, uint8_t* deviceid)
+{
+  if(HTS221_read_reg(handle, HTS221_WHO_AM_I_REG, 1, deviceid))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Initializes the HTS221 with the specified parameters in HTS221_Init_st struct.
+* @param  *handle Device handle.
+* @param  pxInit pointer to a HTS221_Init_st structure that contains the configuration.
+*         This parameter is a pointer to @ref HTS221_Init_st.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Set_InitConfig(void *handle, HTS221_Init_st* pxInit)
+{
+  uint8_t buffer[3];
+
+  HTS221_assert_param(IS_HTS221_AVGH(pxInit->avg_h));
+  HTS221_assert_param(IS_HTS221_AVGT(pxInit->avg_t));
+  HTS221_assert_param(IS_HTS221_ODR(pxInit->odr));
+  HTS221_assert_param(IS_HTS221_State(pxInit->bdu_status));
+  HTS221_assert_param(IS_HTS221_State(pxInit->heater_status));
+
+  HTS221_assert_param(IS_HTS221_DrdyLevelType(pxInit->irq_level));
+  HTS221_assert_param(IS_HTS221_OutputType(pxInit->irq_output_type));
+  HTS221_assert_param(IS_HTS221_State(pxInit->irq_enable));
+
+  if(HTS221_read_reg(handle, HTS221_AV_CONF_REG, 1, buffer))
+    return HTS221_ERROR;
+
+  buffer[0] &= ~(HTS221_AVGH_MASK | HTS221_AVGT_MASK);
+  buffer[0] |= (uint8_t)pxInit->avg_h;
+  buffer[0] |= (uint8_t)pxInit->avg_t;
+
+  if(HTS221_write_reg(handle, HTS221_AV_CONF_REG, 1, buffer))
+    return HTS221_ERROR;
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG1, 3, buffer))
+    return HTS221_ERROR;
+
+  buffer[0] &= ~(HTS221_BDU_MASK | HTS221_ODR_MASK);
+  buffer[0] |= (uint8_t)pxInit->odr;
+  buffer[0] |= ((uint8_t)pxInit->bdu_status) << HTS221_BDU_BIT;
+
+  buffer[1] &= ~HTS221_HEATHER_BIT;
+  buffer[1] |= ((uint8_t)pxInit->heater_status) << HTS221_HEATHER_BIT;
+
+  buffer[2] &= ~(HTS221_DRDY_H_L_MASK | HTS221_PP_OD_MASK | HTS221_DRDY_MASK);
+  buffer[2] |= ((uint8_t)pxInit->irq_level) << HTS221_DRDY_H_L_BIT;
+  buffer[2] |= (uint8_t)pxInit->irq_output_type;
+  buffer[2] |= ((uint8_t)pxInit->irq_enable) << HTS221_DRDY_BIT;
+
+  if(HTS221_write_reg(handle, HTS221_CTRL_REG1, 3, buffer))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Returns a HTS221_Init_st struct with the actual configuration.
+* @param  *handle Device handle.
+* @param  pxInit pointer to a HTS221_Init_st structure.
+*         This parameter is a pointer to @ref HTS221_Init_st.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_InitConfig(void *handle, HTS221_Init_st* pxInit)
+{
+  uint8_t buffer[3];
+
+  if(HTS221_read_reg(handle, HTS221_AV_CONF_REG, 1, buffer))
+    return HTS221_ERROR;
+
+  pxInit->avg_h = (HTS221_Avgh_et)(buffer[0] & HTS221_AVGH_MASK);
+  pxInit->avg_t = (HTS221_Avgt_et)(buffer[0] & HTS221_AVGT_MASK);
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG1, 3, buffer))
+    return HTS221_ERROR;
+
+  pxInit->odr = (HTS221_Odr_et)(buffer[0] & HTS221_ODR_MASK);
+  pxInit->bdu_status = (HTS221_State_et)((buffer[0] & HTS221_BDU_MASK) >> HTS221_BDU_BIT);
+  pxInit->heater_status = (HTS221_State_et)((buffer[1] & HTS221_HEATHER_MASK) >> HTS221_HEATHER_BIT);
+
+  pxInit->irq_level = (HTS221_DrdyLevel_et)(buffer[2] & HTS221_DRDY_H_L_MASK);
+  pxInit->irq_output_type = (HTS221_OutputType_et)(buffer[2] & HTS221_PP_OD_MASK);
+  pxInit->irq_enable = (HTS221_State_et)((buffer[2] & HTS221_DRDY_MASK) >> HTS221_DRDY_BIT);
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  De initialization function for HTS221.
+*         This function put the HTS221 in power down, make a memory boot and clear the data output flags.
+* @param  *handle Device handle.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_DeInit(void *handle)
+{
+  uint8_t buffer[4];
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG1, 2, buffer))
+    return HTS221_ERROR;
+
+  /* HTS221 in power down */
+  buffer[0] |= 0x01 << HTS221_PD_BIT;
+
+  /* Make HTS221 boot */
+  buffer[1] |= 0x01 << HTS221_BOOT_BIT;
+
+  if(HTS221_write_reg(handle, HTS221_CTRL_REG1, 2, buffer))
+    return HTS221_ERROR;
+
+  /* Dump of data output */
+  if(HTS221_read_reg(handle, HTS221_HR_OUT_L_REG, 4, buffer))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Read HTS221 output registers, and calculate humidity and temperature.
+* @param  *handle Device handle.
+* @param  humidity pointer to the returned humidity value that must be divided by 10 to get the value in [%].
+* @param  temperature pointer to the returned temperature value that must be divided by 10 to get the value in ['C].
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_Measurement(void *handle, uint16_t* humidity, int16_t* temperature)
+{
+  if ( HTS221_Get_Temperature( handle, temperature ) == HTS221_ERROR ) return HTS221_ERROR;
+  if ( HTS221_Get_Humidity( handle, humidity ) == HTS221_ERROR ) return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Read HTS221 output registers. Humidity and temperature.
+* @param  *handle Device handle.
+* @param  humidity pointer to the returned humidity raw value.
+* @param  temperature pointer to the returned temperature raw value.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_RawMeasurement(void *handle, int16_t* humidity, int16_t* temperature)
+{
+  uint8_t buffer[4];
+
+  if(HTS221_read_reg(handle, HTS221_HR_OUT_L_REG, 4, buffer))
+    return HTS221_ERROR;
+
+  *humidity = (int16_t)((((uint16_t)buffer[1]) << 8) | (uint16_t)buffer[0]);
+  *temperature = (int16_t)((((uint16_t)buffer[3]) << 8) | (uint16_t)buffer[2]);
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Read HTS221 Humidity output registers, and calculate humidity.
+* @param  *handle Device handle.
+* @param  Pointer to the returned humidity value that must be divided by 10 to get the value in [%].
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_Humidity(void *handle, uint16_t* value)
+{
+  int16_t H0_T0_out, H1_T0_out, H_T_out;
+  int16_t H0_rh, H1_rh;
+  uint8_t buffer[2];
+  float   tmp_f;
+
+  if(HTS221_read_reg(handle, HTS221_H0_RH_X2, 2, buffer))
+    return HTS221_ERROR;
+  H0_rh = buffer[0] >> 1;
+  H1_rh = buffer[1] >> 1;
+
+  if(HTS221_read_reg(handle, HTS221_H0_T0_OUT_L, 2, buffer))
+    return HTS221_ERROR;
+  H0_T0_out = (((uint16_t)buffer[1]) << 8) | (uint16_t)buffer[0];
+
+  if(HTS221_read_reg(handle, HTS221_H1_T0_OUT_L, 2, buffer))
+    return HTS221_ERROR;
+  H1_T0_out = (((uint16_t)buffer[1]) << 8) | (uint16_t)buffer[0];
+
+  if(HTS221_read_reg(handle, HTS221_HR_OUT_L_REG, 2, buffer))
+    return HTS221_ERROR;
+  H_T_out = (((uint16_t)buffer[1]) << 8) | (uint16_t)buffer[0];
+
+  tmp_f = (float)(H_T_out - H0_T0_out) * (float)(H1_rh - H0_rh) / (float)(H1_T0_out - H0_T0_out)  +  H0_rh;
+  tmp_f *= 10.0f;
+
+  *value = ( tmp_f > 1000.0f ) ? 1000
+           : ( tmp_f <    0.0f ) ?    0
+           : ( uint16_t )tmp_f;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Read HTS221 humidity output registers.
+* @param  *handle Device handle.
+* @param  Pointer to the returned humidity raw value.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_HumidityRaw(void *handle, int16_t* value)
+{
+  uint8_t buffer[2];
+
+  if(HTS221_read_reg(handle, HTS221_HR_OUT_L_REG, 2, buffer))
+    return HTS221_ERROR;
+
+  *value = (int16_t)((((uint16_t)buffer[1]) << 8) | (uint16_t)buffer[0]);
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Read HTS221 temperature output registers, and calculate temperature.
+* @param  *handle Device handle.
+* @param  Pointer to the returned temperature value that must be divided by 10 to get the value in ['C].
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_Temperature(void *handle, int16_t *value)
+{
+  int16_t T0_out, T1_out, T_out, T0_degC_x8_u16, T1_degC_x8_u16;
+  int16_t T0_degC, T1_degC;
+  uint8_t buffer[4], tmp;
+  float   tmp_f;
+
+  if(HTS221_read_reg(handle, HTS221_T0_DEGC_X8, 2, buffer))
+    return HTS221_ERROR;
+  if(HTS221_read_reg(handle, HTS221_T0_T1_DEGC_H2, 1, &tmp))
+    return HTS221_ERROR;
+
+  T0_degC_x8_u16 = (((uint16_t)(tmp & 0x03)) << 8) | ((uint16_t)buffer[0]);
+  T1_degC_x8_u16 = (((uint16_t)(tmp & 0x0C)) << 6) | ((uint16_t)buffer[1]);
+  T0_degC = T0_degC_x8_u16 >> 3;
+  T1_degC = T1_degC_x8_u16 >> 3;
+
+  if(HTS221_read_reg(handle, HTS221_T0_OUT_L, 4, buffer))
+    return HTS221_ERROR;
+
+  T0_out = (((uint16_t)buffer[1]) << 8) | (uint16_t)buffer[0];
+  T1_out = (((uint16_t)buffer[3]) << 8) | (uint16_t)buffer[2];
+
+  if(HTS221_read_reg(handle, HTS221_TEMP_OUT_L_REG, 2, buffer))
+    return HTS221_ERROR;
+
+  T_out = (((uint16_t)buffer[1]) << 8) | (uint16_t)buffer[0];
+
+  tmp_f = (float)(T_out - T0_out) * (float)(T1_degC - T0_degC) / (float)(T1_out - T0_out)  +  T0_degC;
+  tmp_f *= 10.0f;
+
+  *value = ( int16_t )tmp_f;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Read HTS221 temperature output registers.
+* @param  *handle Device handle.
+* @param  Pointer to the returned temperature raw value.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_TemperatureRaw(void *handle, int16_t* value)
+{
+  uint8_t buffer[2];
+
+  if(HTS221_read_reg(handle, HTS221_TEMP_OUT_L_REG, 2, buffer))
+    return HTS221_ERROR;
+
+  *value = (int16_t)((((uint16_t)buffer[1]) << 8) | (uint16_t)buffer[0]);
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Get the availability of new data for humidity and temperature.
+* @param  *handle Device handle.
+* @param  humidity pointer to the returned humidity data status [HTS221_SET/HTS221_RESET].
+* @param  temperature pointer to the returned temperature data status [HTS221_SET/HTS221_RESET].
+*         This parameter is a pointer to @ref HTS221_BitStatus_et.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_DataStatus(void *handle, HTS221_BitStatus_et* humidity, HTS221_BitStatus_et* temperature)
+{
+  uint8_t tmp;
+
+  if(HTS221_read_reg(handle, HTS221_STATUS_REG, 1, &tmp))
+    return HTS221_ERROR;
+
+  *humidity = (HTS221_BitStatus_et)((tmp & HTS221_HDA_MASK) >> HTS221_H_DA_BIT);
+  *temperature = (HTS221_BitStatus_et)(tmp & HTS221_TDA_MASK);
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Exit from power down mode.
+* @param  *handle Device handle.
+* @param  void.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Activate(void *handle)
+{
+  uint8_t tmp;
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG1, 1, &tmp))
+    return HTS221_ERROR;
+
+  tmp |= HTS221_PD_MASK;
+
+  if(HTS221_write_reg(handle, HTS221_CTRL_REG1, 1, &tmp))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Put the sensor in power down mode.
+* @param  *handle Device handle.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_DeActivate(void *handle)
+{
+  uint8_t tmp;
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG1, 1, &tmp))
+    return HTS221_ERROR;
+
+  tmp &= ~HTS221_PD_MASK;
+
+  if(HTS221_write_reg(handle, HTS221_CTRL_REG1, 1, &tmp))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+
+
+/**
+* @brief  Check if the single measurement has completed.
+* @param  *handle Device handle.
+* @param  tmp is set to 1, when the measure is completed
+* @retval Status [HTS221_ERROR, HTS221_OK]
+*/
+HTS221_Error_et HTS221_IsMeasurementCompleted(void *handle, HTS221_BitStatus_et* Is_Measurement_Completed)
+{
+  uint8_t tmp;
+
+  if(HTS221_read_reg(handle, HTS221_STATUS_REG, 1, &tmp))
+    return HTS221_ERROR;
+
+  if((tmp & (uint8_t)(HTS221_HDA_MASK | HTS221_TDA_MASK)) == (uint8_t)(HTS221_HDA_MASK | HTS221_TDA_MASK))
+    *Is_Measurement_Completed = HTS221_SET;
+  else
+    *Is_Measurement_Completed = HTS221_RESET;
+
+  return HTS221_OK;
+}
+
+
+/**
+* @brief  Set_ humidity and temperature average mode.
+* @param  *handle Device handle.
+* @param  avgh is the average mode for humidity, this parameter is @ref HTS221_Avgh_et.
+* @param  avgt is the average mode for temperature, this parameter is @ref HTS221_Avgt_et.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Set_AvgHT(void *handle, HTS221_Avgh_et avgh, HTS221_Avgt_et avgt)
+{
+  uint8_t tmp;
+
+  HTS221_assert_param(IS_HTS221_AVGH(avgh));
+  HTS221_assert_param(IS_HTS221_AVGT(avgt));
+
+  if(HTS221_read_reg(handle, HTS221_AV_CONF_REG, 1, &tmp))
+    return HTS221_ERROR;
+
+  tmp &= ~(HTS221_AVGH_MASK | HTS221_AVGT_MASK);
+  tmp |= (uint8_t)avgh;
+  tmp |= (uint8_t)avgt;
+
+  if(HTS221_write_reg(handle, HTS221_AV_CONF_REG, 1, &tmp))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Set humidity average mode.
+* @param  *handle Device handle.
+* @param  avgh is the average mode for humidity, this parameter is @ref HTS221_Avgh_et.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Set_AvgH(void *handle, HTS221_Avgh_et avgh)
+{
+  uint8_t tmp;
+
+  HTS221_assert_param(IS_HTS221_AVGH(avgh));
+
+  if(HTS221_read_reg(handle, HTS221_AV_CONF_REG, 1, &tmp))
+    return HTS221_ERROR;
+
+  tmp &= ~HTS221_AVGH_MASK;
+  tmp |= (uint8_t)avgh;
+
+  if(HTS221_write_reg(handle, HTS221_AV_CONF_REG, 1, &tmp))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Set temperature average mode.
+* @param  *handle Device handle.
+* @param  avgt is the average mode for temperature, this parameter is @ref HTS221_Avgt_et.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Set_AvgT(void *handle, HTS221_Avgt_et avgt)
+{
+  uint8_t tmp;
+
+  HTS221_assert_param(IS_HTS221_AVGT(avgt));
+
+  if(HTS221_read_reg(handle, HTS221_AV_CONF_REG, 1, &tmp))
+    return HTS221_ERROR;
+
+  tmp &= ~HTS221_AVGT_MASK;
+  tmp |= (uint8_t)avgt;
+
+  if(HTS221_write_reg(handle, HTS221_AV_CONF_REG, 1, &tmp))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Get humidity and temperature average mode.
+* @param  *handle Device handle.
+* @param  avgh pointer to the returned value with the humidity average mode.
+* @param  avgt pointer to the returned value with the temperature average mode.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_AvgHT(void *handle, HTS221_Avgh_et* avgh, HTS221_Avgt_et* avgt)
+{
+  uint8_t tmp;
+
+  if(HTS221_read_reg(handle, HTS221_AV_CONF_REG, 1, &tmp))
+    return HTS221_ERROR;
+
+  *avgh = (HTS221_Avgh_et)(tmp & HTS221_AVGH_MASK);
+  *avgt = (HTS221_Avgt_et)(tmp & HTS221_AVGT_MASK);
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Set block data update mode.
+* @param  *handle Device handle.
+* @param  status can be HTS221_ENABLE: enable the block data update, output data registers are updated once both MSB and LSB are read.
+* @param  status can be HTS221_DISABLE: output data registers are continuously updated.
+*         This parameter is a @ref HTS221_BitStatus_et.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Set_BduMode(void *handle, HTS221_State_et status)
+{
+  uint8_t tmp;
+
+  HTS221_assert_param(IS_HTS221_State(status));
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG1, 1, &tmp))
+    return HTS221_ERROR;
+
+  tmp &= ~HTS221_BDU_MASK;
+  tmp |= ((uint8_t)status) << HTS221_BDU_BIT;
+
+  if(HTS221_write_reg(handle, HTS221_CTRL_REG1, 1, &tmp))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Get block data update mode.
+* @param  *handle Device handle.
+* @param  Pointer to the returned value with block data update mode status.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_BduMode(void *handle, HTS221_State_et* status)
+{
+  uint8_t tmp;
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG1, 1, &tmp))
+    return HTS221_ERROR;
+
+  *status = (HTS221_State_et)((tmp & HTS221_BDU_MASK) >> HTS221_BDU_BIT);
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Enter or exit from power down mode.
+* @param  *handle Device handle.
+* @param  status can be HTS221_SET: HTS221 in power down mode.
+* @param  status can be HTS221_REET: HTS221 in active mode.
+*         This parameter is a @ref HTS221_BitStatus_et.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Set_PowerDownMode(void *handle, HTS221_BitStatus_et status)
+{
+  uint8_t tmp;
+
+  HTS221_assert_param(IS_HTS221_BitStatus(status));
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG1, 1, &tmp))
+    return HTS221_ERROR;
+
+  tmp &= ~HTS221_PD_MASK;
+  tmp |= ((uint8_t)status) << HTS221_PD_BIT;
+
+  if(HTS221_write_reg(handle, HTS221_CTRL_REG1, 1, &tmp))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Get if HTS221 is in active mode or in power down mode.
+* @param  *handle Device handle.
+* @param  Pointer to the returned value with HTS221 status.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_PowerDownMode(void *handle, HTS221_BitStatus_et* status)
+{
+  uint8_t tmp;
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG1, 1, &tmp))
+    return HTS221_ERROR;
+
+  *status = (HTS221_BitStatus_et)((tmp & HTS221_PD_MASK) >> HTS221_PD_BIT);
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Set the output data rate mode.
+* @param  *handle Device handle.
+* @param  odr is the output data rate mode.
+*         This parameter is a @ref HTS221_Odr_et.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Set_Odr(void *handle, HTS221_Odr_et odr)
+{
+  uint8_t tmp;
+
+  HTS221_assert_param(IS_HTS221_ODR(odr));
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG1, 1, &tmp))
+    return HTS221_ERROR;
+
+  tmp &= ~HTS221_ODR_MASK;
+  tmp |= (uint8_t)odr;
+
+  if(HTS221_write_reg(handle, HTS221_CTRL_REG1, 1, &tmp))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Get the output data rate mode.
+* @param  *handle Device handle.
+* @param  Pointer to the returned value with output data rate mode.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_Odr(void *handle, HTS221_Odr_et* odr)
+{
+  uint8_t tmp;
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG1, 1, &tmp))
+    return HTS221_ERROR;
+
+  tmp &= HTS221_ODR_MASK;
+  *odr = (HTS221_Odr_et)tmp;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Reboot Memory Content.
+* @param  *handle Device handle.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_MemoryBoot(void *handle)
+{
+  uint8_t tmp;
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG2, 1, &tmp))
+    return HTS221_ERROR;
+
+  tmp |= HTS221_BOOT_MASK;
+
+  if(HTS221_write_reg(handle, HTS221_CTRL_REG2, 1, &tmp))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Configure the internal heater.
+* @param  *handle Device handle.
+* @param  The status of the internal heater [HTS221_ENABLE/HTS221_DISABLE].
+*         This parameter is a @ref HTS221_State_et.
+* @retval Error code [HTS221_OK, HTS221_ERROR]
+*/
+HTS221_Error_et HTS221_Set_HeaterState(void *handle, HTS221_State_et status)
+{
+  uint8_t tmp;
+
+  HTS221_assert_param(IS_HTS221_State(status));
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG2, 1, &tmp))
+    return HTS221_ERROR;
+
+  tmp &= ~HTS221_HEATHER_MASK;
+  tmp |= ((uint8_t)status) << HTS221_HEATHER_BIT;
+
+  if(HTS221_write_reg(handle, HTS221_CTRL_REG2, 1, &tmp))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Get the internal heater.
+* @param  *handle Device handle.
+* @param  Pointer to the returned status of the internal heater [HTS221_ENABLE/HTS221_DISABLE].
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_HeaterState(void *handle, HTS221_State_et* status)
+{
+  uint8_t tmp;
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG2, 1, &tmp))
+    return HTS221_ERROR;
+
+  *status = (HTS221_State_et)((tmp & HTS221_HEATHER_MASK) >> HTS221_HEATHER_BIT);
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Set ONE_SHOT bit to start a new conversion (ODR mode has to be 00).
+*         Once the measurement is done, ONE_SHOT bit is self-cleared.
+* @param  *handle Device handle.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_StartOneShotMeasurement(void *handle)
+{
+  uint8_t tmp;
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG2, 1, &tmp))
+    return HTS221_ERROR;
+
+  tmp |= HTS221_ONE_SHOT_MASK;
+
+  if(HTS221_write_reg(handle, HTS221_CTRL_REG2, 1, &tmp))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+
+}
+
+/**
+* @brief  Set level configuration of the interrupt pin DRDY.
+* @param  *handle Device handle.
+* @param  status can be HTS221_LOW_LVL: active level is LOW.
+* @param  status can be HTS221_HIGH_LVL: active level is HIGH.
+*         This parameter is a @ref HTS221_State_et.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Set_IrqActiveLevel(void *handle, HTS221_DrdyLevel_et value)
+{
+  uint8_t tmp;
+
+  HTS221_assert_param(IS_HTS221_DrdyLevelType(value));
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG3, 1, &tmp))
+    return HTS221_ERROR;
+
+  tmp &= ~HTS221_DRDY_H_L_MASK;
+  tmp |= (uint8_t)value;
+
+  if(HTS221_write_reg(handle, HTS221_CTRL_REG3, 1, &tmp))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Get level configuration of the interrupt pin DRDY.
+* @param  *handle Device handle.
+* @param  Pointer to the returned status of the level configuration [HTS221_ENABLE/HTS221_DISABLE].
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_IrqActiveLevel(void *handle, HTS221_DrdyLevel_et* value)
+{
+  uint8_t tmp;
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG3, 1, &tmp))
+    return HTS221_ERROR;
+
+  *value = (HTS221_DrdyLevel_et)(tmp & HTS221_DRDY_H_L_MASK);
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Set Push-pull/open drain configuration for the interrupt pin DRDY.
+* @param  *handle Device handle.
+* @param  value is the output type configuration.
+*         This parameter is a @ref HTS221_OutputType_et.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Set_IrqOutputType(void *handle, HTS221_OutputType_et value)
+{
+  uint8_t tmp;
+
+  HTS221_assert_param(IS_HTS221_OutputType(value));
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG3, 1, &tmp))
+    return HTS221_ERROR;
+
+  tmp &= ~HTS221_PP_OD_MASK;
+  tmp |= (uint8_t)value;
+
+  if(HTS221_write_reg(handle, HTS221_CTRL_REG3, 1, &tmp))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Get the configuration for the interrupt pin DRDY.
+* @param  *handle Device handle.
+* @param  Pointer to the returned value with output type configuration.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_IrqOutputType(void *handle, HTS221_OutputType_et* value)
+{
+  uint8_t tmp;
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG3, 1, &tmp))
+    return HTS221_ERROR;
+
+  *value = (HTS221_OutputType_et)(tmp & HTS221_PP_OD_MASK);
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Enable/disable the interrupt mode.
+* @param  *handle Device handle.
+* @param  status is the enable/disable for the interrupt mode.
+*         This parameter is a @ref HTS221_State_et.
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Set_IrqEnable(void *handle, HTS221_State_et status)
+{
+  uint8_t tmp;
+
+  HTS221_assert_param(IS_HTS221_State(status));
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG3, 1, &tmp))
+    return HTS221_ERROR;
+
+  tmp &= ~HTS221_DRDY_MASK;
+  tmp |= ((uint8_t)status) << HTS221_DRDY_BIT;
+
+  if(HTS221_write_reg(handle, HTS221_CTRL_REG3, 1, &tmp))
+    return HTS221_ERROR;
+
+  return HTS221_OK;
+}
+
+/**
+* @brief  Get the interrupt mode.
+* @param  *handle Device handle.
+* @param  Pointer to the returned status of the interrupt mode configuration [HTS221_ENABLE/HTS221_DISABLE].
+* @retval Error code [HTS221_OK, HTS221_ERROR].
+*/
+HTS221_Error_et HTS221_Get_IrqEnable(void *handle, HTS221_State_et* status)
+{
+  uint8_t tmp;
+
+  if(HTS221_read_reg(handle, HTS221_CTRL_REG3, 1, &tmp))
+    return HTS221_ERROR;
+
+  *status = (HTS221_State_et)((tmp & HTS221_DRDY_MASK) >> HTS221_DRDY_BIT);
+
+  return HTS221_OK;
+}
+
+
+#ifdef  USE_FULL_ASSERT_HTS221
+/**
+* @brief  Reports the name of the source file and the source line number
+*         where the assert_param error has occurred.
+* @param file: pointer to the source file name
+* @param line: assert_param error line source number
+* @retval : None
+*/
+void HTS221_assert_failed(uint8_t* file, uint32_t line)
+{
+  /* User can add his own implementation to report the file name and line number */
+  printf("Wrong parameters value: file %s on line %d\r\n", file, (int)line);
+
+  /* Infinite loop */
+  while (1)
+  {
+  }
+}
+#endif
+
+#ifdef __cplusplus
+  }
+#endif
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/HTS221/HTS221_driver.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,514 @@
+/**
+ ******************************************************************************
+ * @file    HTS221_driver.h
+ * @author  HESA Application Team
+ * @version V1.1
+ * @date    10-August-2016
+ * @brief   HTS221 driver header file
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HTS221_DRIVER__H
+#define __HTS221_DRIVER__H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Uncomment the line below to expanse the "assert_param" macro in the drivers code */
+#define USE_FULL_ASSERT_HTS221
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef  USE_FULL_ASSERT_HTS221
+
+/**
+* @brief  The assert_param macro is used for function's parameters check.
+* @param  expr: If expr is false, it calls assert_failed function which reports
+*         the name of the source file and the source line number of the call
+*         that failed. If expr is true, it returns no value.
+* @retval None
+*/
+#define HTS221_assert_param(expr) ((expr) ? (void)0 : HTS221_assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+void HTS221_assert_failed(uint8_t* file, uint32_t line);
+#else
+#define HTS221_assert_param(expr) ((void)0)
+#endif /* USE_FULL_ASSERT_HTS221 */
+
+/** @addtogroup Environmental_Sensor
+* @{
+*/
+
+/** @addtogroup HTS221_DRIVER
+* @{
+*/
+
+/* Exported Types -------------------------------------------------------------*/
+/** @defgroup HTS221_Exported_Types
+* @{
+*/
+
+
+/**
+* @brief  Error code type.
+*/
+typedef enum {HTS221_OK = (uint8_t)0, HTS221_ERROR = !HTS221_OK} HTS221_Error_et;
+
+/**
+* @brief  State type.
+*/
+typedef enum {HTS221_DISABLE = (uint8_t)0, HTS221_ENABLE = !HTS221_DISABLE} HTS221_State_et;
+#define IS_HTS221_State(MODE) ((MODE == HTS221_ENABLE) || (MODE == HTS221_DISABLE))
+
+/**
+* @brief  Bit status type.
+*/
+typedef enum {HTS221_RESET = (uint8_t)0, HTS221_SET = !HTS221_RESET} HTS221_BitStatus_et;
+#define IS_HTS221_BitStatus(MODE) ((MODE == HTS221_RESET) || (MODE == HTS221_SET))
+
+/**
+* @brief  Humidity average.
+*/
+typedef enum
+{
+  HTS221_AVGH_4         = (uint8_t)0x00,         /*!< Internal average on 4 samples */
+  HTS221_AVGH_8         = (uint8_t)0x01,         /*!< Internal average on 8 samples */
+  HTS221_AVGH_16        = (uint8_t)0x02,         /*!< Internal average on 16 samples */
+  HTS221_AVGH_32        = (uint8_t)0x03,         /*!< Internal average on 32 samples */
+  HTS221_AVGH_64        = (uint8_t)0x04,         /*!< Internal average on 64 samples */
+  HTS221_AVGH_128       = (uint8_t)0x05,         /*!< Internal average on 128 samples */
+  HTS221_AVGH_256       = (uint8_t)0x06,         /*!< Internal average on 256 samples */
+  HTS221_AVGH_512       = (uint8_t)0x07          /*!< Internal average on 512 samples */
+} HTS221_Avgh_et;
+#define IS_HTS221_AVGH(AVGH) ((AVGH == HTS221_AVGH_4) || (AVGH == HTS221_AVGH_8) || \
+                              (AVGH == HTS221_AVGH_16) || (AVGH == HTS221_AVGH_32) || \
+                              (AVGH == HTS221_AVGH_64) || (AVGH == HTS221_AVGH_128) || \
+                              (AVGH == HTS221_AVGH_256) || (AVGH == HTS221_AVGH_512))
+
+/**
+* @brief  Temperature average.
+*/
+typedef enum
+{
+  HTS221_AVGT_2         = (uint8_t)0x00,        /*!< Internal average on 2 samples */
+  HTS221_AVGT_4         = (uint8_t)0x08,        /*!< Internal average on 4 samples */
+  HTS221_AVGT_8         = (uint8_t)0x10,        /*!< Internal average on 8 samples */
+  HTS221_AVGT_16        = (uint8_t)0x18,        /*!< Internal average on 16 samples */
+  HTS221_AVGT_32        = (uint8_t)0x20,        /*!< Internal average on 32 samples */
+  HTS221_AVGT_64        = (uint8_t)0x28,        /*!< Internal average on 64 samples */
+  HTS221_AVGT_128       = (uint8_t)0x30,        /*!< Internal average on 128 samples */
+  HTS221_AVGT_256       = (uint8_t)0x38         /*!< Internal average on 256 samples */
+} HTS221_Avgt_et;
+#define IS_HTS221_AVGT(AVGT) ((AVGT == HTS221_AVGT_2) || (AVGT == HTS221_AVGT_4) || \
+                              (AVGT == HTS221_AVGT_8) || (AVGT == HTS221_AVGT_16) || \
+                              (AVGT == HTS221_AVGT_32) || (AVGT == HTS221_AVGT_64) || \
+                              (AVGT == HTS221_AVGT_128) || (AVGT == HTS221_AVGT_256))
+
+/**
+* @brief  Output data rate configuration.
+*/
+typedef enum
+{
+  HTS221_ODR_ONE_SHOT  = (uint8_t)0x00,         /*!< Output Data Rate: one shot */
+  HTS221_ODR_1HZ       = (uint8_t)0x01,         /*!< Output Data Rate: 1Hz */
+  HTS221_ODR_7HZ       = (uint8_t)0x02,         /*!< Output Data Rate: 7Hz */
+  HTS221_ODR_12_5HZ    = (uint8_t)0x03,         /*!< Output Data Rate: 12.5Hz */
+} HTS221_Odr_et;
+#define IS_HTS221_ODR(ODR) ((ODR == HTS221_ODR_ONE_SHOT) || (ODR == HTS221_ODR_1HZ) || \
+                            (ODR == HTS221_ODR_7HZ) || (ODR == HTS221_ODR_12_5HZ))
+
+
+/**
+* @brief  Push-pull/Open Drain selection on DRDY pin.
+*/
+typedef enum
+{
+  HTS221_PUSHPULL   = (uint8_t)0x00,   /*!< DRDY pin in push pull */
+  HTS221_OPENDRAIN  = (uint8_t)0x40    /*!< DRDY pin in open drain */
+} HTS221_OutputType_et;
+#define IS_HTS221_OutputType(MODE) ((MODE == HTS221_PUSHPULL) || (MODE == HTS221_OPENDRAIN))
+
+/**
+* @brief  Active level of DRDY pin.
+*/
+typedef enum
+{
+  HTS221_HIGH_LVL   = (uint8_t)0x00,   /*!< HIGH state level for DRDY pin */
+  HTS221_LOW_LVL    = (uint8_t)0x80    /*!< LOW state level for DRDY pin */
+} HTS221_DrdyLevel_et;
+#define IS_HTS221_DrdyLevelType(MODE) ((MODE == HTS221_HIGH_LVL) || (MODE == HTS221_LOW_LVL))
+
+/**
+* @brief  Driver Version Info structure definition.
+*/
+typedef struct
+{
+  uint8_t   Major;
+  uint8_t   Minor;
+  uint8_t   Point;
+} HTS221_DriverVersion_st;
+
+
+/**
+* @brief  HTS221 Init structure definition.
+*/
+typedef struct
+{
+  HTS221_Avgh_et        avg_h;            /*!< Humidity average */
+  HTS221_Avgt_et        avg_t;            /*!< Temperature average */
+  HTS221_Odr_et         odr;              /*!< Output data rate */
+  HTS221_State_et       bdu_status;       /*!< HTS221_ENABLE/HTS221_DISABLE the block data update */
+  HTS221_State_et       heater_status;    /*!< HTS221_ENABLE/HTS221_DISABLE the internal heater */
+
+  HTS221_DrdyLevel_et   irq_level;        /*!< HTS221_HIGH_LVL/HTS221_LOW_LVL the level for DRDY pin */
+  HTS221_OutputType_et  irq_output_type;  /*!< Output configuration for DRDY pin */
+  HTS221_State_et       irq_enable;       /*!< HTS221_ENABLE/HTS221_DISABLE interrupt on DRDY pin */
+} HTS221_Init_st;
+
+/**
+* @}
+*/
+
+
+/* Exported Constants ---------------------------------------------------------*/
+/** @defgroup HTS221_Exported_Constants
+* @{
+*/
+
+/**
+* @brief  Bitfield positioning.
+*/
+#define HTS221_BIT(x) ((uint8_t)x)
+
+/**
+* @brief  I2C address.
+*/
+#define HTS221_I2C_ADDRESS  (uint8_t)0xBE
+
+/**
+* @brief  Driver version.
+*/
+#define HTS221_DRIVER_VERSION_MAJOR (uint8_t)1
+#define HTS221_DRIVER_VERSION_MINOR (uint8_t)1
+#define HTS221_DRIVER_VERSION_POINT (uint8_t)0
+
+/**
+* @addtogroup HTS221_Registers
+* @{
+*/
+
+
+/**
+* @brief Device Identification register.
+* \code
+* Read
+* Default value: 0xBC
+* 7:0 This read-only register contains the device identifier for HTS221.
+* \endcode
+*/
+#define HTS221_WHO_AM_I_REG          (uint8_t)0x0F
+
+/**
+* @brief Device Identification value.
+*/
+#define HTS221_WHO_AM_I_VAL         (uint8_t)0xBC
+
+
+/**
+* @brief Humidity and temperature average mode register.
+* \code
+* Read/write
+* Default value: 0x1B
+* 7:6 Reserved.
+* 5:3 AVGT2-AVGT1-AVGT0: Select the temperature internal average.
+*
+*      AVGT2 | AVGT1 | AVGT0 | Nr. Internal Average
+*   ----------------------------------------------------
+*       0    |   0   |   0   |    2
+*       0    |   0   |   1   |    4
+*       0    |   1   |   0   |    8
+*       0    |   1   |   1   |    16
+*       1    |   0   |   0   |    32
+*       1    |   0   |   1   |    64
+*       1    |   1   |   0   |    128
+*       1    |   1   |   1   |    256
+*
+* 2:0 AVGH2-AVGH1-AVGH0: Select humidity internal average.
+*      AVGH2 | AVGH1 |  AVGH0 | Nr. Internal Average
+*   ------------------------------------------------------
+*       0    |   0   |   0   |    4
+*       0    |   0   |   1   |    8
+*       0    |   1   |   0   |    16
+*       0    |   1   |   1   |    32
+*       1    |   0   |   0   |    64
+*       1    |   0   |   1   |    128
+*       1    |   1   |   0   |    256
+*       1    |   1   |   1   |    512
+*
+* \endcode
+*/
+#define HTS221_AV_CONF_REG        (uint8_t)0x10
+
+#define HTS221_AVGT_BIT           HTS221_BIT(3)
+#define HTS221_AVGH_BIT           HTS221_BIT(0)
+
+#define HTS221_AVGH_MASK          (uint8_t)0x07
+#define HTS221_AVGT_MASK          (uint8_t)0x38
+
+/**
+* @brief Control register 1.
+* \code
+* Read/write
+* Default value: 0x00
+* 7 PD: power down control. 0 - power down mode; 1 - active mode.
+* 6:3 Reserved.
+* 2 BDU: block data update. 0 - continuous update; 1 - output registers not updated until MSB and LSB reading.
+* 1:0 ODR1, ODR0: output data rate selection.
+*
+*   ODR1  | ODR0  | Humidity output data-rate(Hz)  | Pressure output data-rate(Hz)
+*   ----------------------------------------------------------------------------------
+*     0   |   0   |         one shot               |         one shot
+*     0   |   1   |            1                   |            1
+*     1   |   0   |            7                   |            7
+*     1   |   1   |           12.5                 |           12.5
+*
+* \endcode
+*/
+#define HTS221_CTRL_REG1      (uint8_t)0x20
+
+#define HTS221_PD_BIT          HTS221_BIT(7)
+#define HTS221_BDU_BIT         HTS221_BIT(2)
+#define HTS221_ODR_BIT         HTS221_BIT(0)
+
+#define HTS221_PD_MASK        (uint8_t)0x80
+#define HTS221_BDU_MASK       (uint8_t)0x04
+#define HTS221_ODR_MASK       (uint8_t)0x03
+
+/**
+* @brief Control register 2.
+* \code
+* Read/write
+* Default value: 0x00
+* 7 BOOT:  Reboot memory content. 0: normal mode; 1: reboot memory content. Self-cleared upon completation.
+* 6:2 Reserved.
+* 1 HEATHER: 0: heater enable; 1: heater disable.
+* 0 ONE_SHOT: 0: waiting for start of conversion; 1: start for a new dataset. Self-cleared upon completation.
+* \endcode
+*/
+#define HTS221_CTRL_REG2      (uint8_t)0x21
+
+#define HTS221_BOOT_BIT        HTS221_BIT(7)
+#define HTS221_HEATHER_BIT     HTS221_BIT(1)
+#define HTS221_ONESHOT_BIT     HTS221_BIT(0)
+
+#define HTS221_BOOT_MASK      (uint8_t)0x80
+#define HTS221_HEATHER_MASK   (uint8_t)0x02
+#define HTS221_ONE_SHOT_MASK  (uint8_t)0x01
+
+/**
+* @brief Control register 3.
+* \code
+* Read/write
+* Default value: 0x00
+* 7 DRDY_H_L: Interrupt edge. 0: active high, 1: active low.
+* 6 PP_OD: Push-Pull/OpenDrain selection on interrupt pads. 0: push-pull; 1: open drain.
+* 5:3 Reserved.
+* 2 DRDY: interrupt config. 0: disable, 1: enable.
+* \endcode
+*/
+#define HTS221_CTRL_REG3      (uint8_t)0x22
+
+#define HTS221_DRDY_H_L_BIT    HTS221_BIT(7)
+#define HTS221_PP_OD_BIT       HTS221_BIT(6)
+#define HTS221_DRDY_BIT        HTS221_BIT(2)
+
+#define HTS221_DRDY_H_L_MASK  (uint8_t)0x80
+#define HTS221_PP_OD_MASK     (uint8_t)0x40
+#define HTS221_DRDY_MASK      (uint8_t)0x04
+
+/**
+* @brief  Status register.
+* \code
+* Read
+* Default value: 0x00
+* 7:2 Reserved.
+* 1 H_DA: Humidity data available. 0: new data for humidity is not yet available; 1: new data for humidity is available.
+* 0 T_DA: Temperature data available. 0: new data for temperature is not yet available; 1: new data for temperature is available.
+* \endcode
+*/
+#define HTS221_STATUS_REG    (uint8_t)0x27
+
+#define HTS221_H_DA_BIT       HTS221_BIT(1)
+#define HTS221_T_DA_BIT       HTS221_BIT(0)
+
+#define HTS221_HDA_MASK      (uint8_t)0x02
+#define HTS221_TDA_MASK      (uint8_t)0x01
+
+/**
+* @brief  Humidity data (LSB).
+* \code
+* Read
+* Default value: 0x00.
+* HOUT7 - HOUT0: Humidity data LSB (2's complement).
+* \endcode
+*/
+#define HTS221_HR_OUT_L_REG        (uint8_t)0x28
+
+/**
+* @brief  Humidity data (MSB).
+* \code
+* Read
+* Default value: 0x00.
+* HOUT15 - HOUT8: Humidity data MSB (2's complement).
+* \endcode
+*/
+#define HTS221_HR_OUT_H_REG        (uint8_t)0x29
+
+
+/**
+* @brief  Temperature data (LSB).
+* \code
+* Read
+* Default value: 0x00.
+* TOUT7 - TOUT0: temperature data LSB.
+* \endcode
+*/
+#define HTS221_TEMP_OUT_L_REG         (uint8_t)0x2A
+
+/**
+* @brief  Temperature data (MSB).
+* \code
+* Read
+* Default value: 0x00.
+* TOUT15 - TOUT8: temperature data MSB.
+* \endcode
+*/
+#define HTS221_TEMP_OUT_H_REG         (uint8_t)0x2B
+
+/**
+* @brief  Calibration registers.
+* \code
+* Read
+* \endcode
+*/
+#define HTS221_H0_RH_X2        (uint8_t)0x30
+#define HTS221_H1_RH_X2        (uint8_t)0x31
+#define HTS221_T0_DEGC_X8      (uint8_t)0x32
+#define HTS221_T1_DEGC_X8      (uint8_t)0x33
+#define HTS221_T0_T1_DEGC_H2   (uint8_t)0x35
+#define HTS221_H0_T0_OUT_L     (uint8_t)0x36
+#define HTS221_H0_T0_OUT_H     (uint8_t)0x37
+#define HTS221_H1_T0_OUT_L     (uint8_t)0x3A
+#define HTS221_H1_T0_OUT_H     (uint8_t)0x3B
+#define HTS221_T0_OUT_L        (uint8_t)0x3C
+#define HTS221_T0_OUT_H        (uint8_t)0x3D
+#define HTS221_T1_OUT_L        (uint8_t)0x3E
+#define HTS221_T1_OUT_H        (uint8_t)0x3F
+
+
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+
+/* Exported Functions -------------------------------------------------------------*/
+/** @defgroup HTS221_Exported_Functions
+* @{
+*/
+
+HTS221_Error_et HTS221_read_reg( void *handle, uint8_t RegAddr, uint16_t NumByteToRead, uint8_t *Data );
+HTS221_Error_et HTS221_write_reg( void *handle, uint8_t RegAddr, uint16_t NumByteToWrite, uint8_t *Data );
+
+HTS221_Error_et HTS221_Get_DriverVersion(HTS221_DriverVersion_st* version);
+HTS221_Error_et HTS221_Get_DeviceID(void *handle, uint8_t* deviceid);
+
+HTS221_Error_et HTS221_Set_InitConfig(void *handle, HTS221_Init_st* pxInit);
+HTS221_Error_et HTS221_Get_InitConfig(void *handle, HTS221_Init_st* pxInit);
+HTS221_Error_et HTS221_DeInit(void *handle);
+HTS221_Error_et HTS221_IsMeasurementCompleted(void *handle, HTS221_BitStatus_et* Is_Measurement_Completed);
+
+HTS221_Error_et HTS221_Get_Measurement(void *handle, uint16_t* humidity, int16_t* temperature);
+HTS221_Error_et HTS221_Get_RawMeasurement(void *handle, int16_t* humidity, int16_t* temperature);
+HTS221_Error_et HTS221_Get_Humidity(void *handle, uint16_t* value);
+HTS221_Error_et HTS221_Get_HumidityRaw(void *handle, int16_t* value);
+HTS221_Error_et HTS221_Get_TemperatureRaw(void *handle, int16_t* value);
+HTS221_Error_et HTS221_Get_Temperature(void *handle, int16_t* value);
+HTS221_Error_et HTS221_Get_DataStatus(void *handle, HTS221_BitStatus_et* humidity, HTS221_BitStatus_et* temperature);
+HTS221_Error_et HTS221_Activate(void *handle);
+HTS221_Error_et HTS221_DeActivate(void *handle);
+
+HTS221_Error_et HTS221_Set_AvgHT(void *handle, HTS221_Avgh_et avgh, HTS221_Avgt_et avgt);
+HTS221_Error_et HTS221_Set_AvgH(void *handle, HTS221_Avgh_et avgh);
+HTS221_Error_et HTS221_Set_AvgT(void *handle, HTS221_Avgt_et avgt);
+HTS221_Error_et HTS221_Get_AvgHT(void *handle, HTS221_Avgh_et* avgh, HTS221_Avgt_et* avgt);
+HTS221_Error_et HTS221_Set_BduMode(void *handle, HTS221_State_et status);
+HTS221_Error_et HTS221_Get_BduMode(void *handle, HTS221_State_et* status);
+HTS221_Error_et HTS221_Set_PowerDownMode(void *handle, HTS221_BitStatus_et status);
+HTS221_Error_et HTS221_Get_PowerDownMode(void *handle, HTS221_BitStatus_et* status);
+HTS221_Error_et HTS221_Set_Odr(void *handle, HTS221_Odr_et odr);
+HTS221_Error_et HTS221_Get_Odr(void *handle, HTS221_Odr_et* odr);
+HTS221_Error_et HTS221_MemoryBoot(void *handle);
+HTS221_Error_et HTS221_Set_HeaterState(void *handle, HTS221_State_et status);
+HTS221_Error_et HTS221_Get_HeaterState(void *handle, HTS221_State_et* status);
+HTS221_Error_et HTS221_StartOneShotMeasurement(void *handle);
+HTS221_Error_et HTS221_Set_IrqActiveLevel(void *handle, HTS221_DrdyLevel_et status);
+HTS221_Error_et HTS221_Get_IrqActiveLevel(void *handle, HTS221_DrdyLevel_et* status);
+HTS221_Error_et HTS221_Set_IrqOutputType(void *handle, HTS221_OutputType_et value);
+HTS221_Error_et HTS221_Get_IrqOutputType(void *handle, HTS221_OutputType_et* value);
+HTS221_Error_et HTS221_Set_IrqEnable(void *handle, HTS221_State_et status);
+HTS221_Error_et HTS221_Get_IrqEnable(void *handle, HTS221_State_et* status);
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HTS221_DRIVER__H */
+
+/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/
--- a/sensors/LIS3MDL.lib	Sun Dec 16 13:29:53 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://developer.mbed.org/teams/ST/code/LIS3MDL/#308889c4d074
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/LIS3MDL/lis3mdl.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,456 @@
+/**
+ ******************************************************************************
+ * @file    lis3mdl.h
+ * @author  MEMS Application Team
+ * @version V1.3.0
+ * @date    28-May-2015
+ * @brief   This file contains definitions for the lis3mdl.c
+ *          firmware driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LIS3MDL_H
+#define __LIS3MDL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "magneto.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup LIS3MDL
+ * @{
+ */
+
+/** @defgroup LIS3MDL_Exported_Defines LIS3MDL_Exported_Defines
+ * @{
+ */
+#ifndef NULL
+#define NULL      (void *) 0
+#endif
+
+
+/******************************************************************************/
+/***************** START MAGNETIC SENSOR REGISTER MAPPING  ********************/
+/******************************************************************************/
+
+/**
+  * @brief Device identifier register.
+  * \code
+  * Read
+  * Default value:
+  * 7:0 This read-only register contains the device identifier
+  * \endcode
+*/
+#define LIS3MDL_M_WHO_AM_I_ADDR                             0x0F
+
+
+/**
+ * @brief Magnetic sensor Control Register 1
+ * \code
+ * Read/write
+ * Default value: 0x10
+ * [7] TEMP_COMP: Temperature compensation enable
+ * [6:5] OM1-0: X and Y axes operative mode selection
+ * [4:2] DO2-0: Output data rate selection
+ * [1] This bit must be set to �0� for the correct operation of the device
+ * [0] ST: Self-test enable
+ * \endcode
+ */
+#define LIS3MDL_M_CTRL_REG1_M                               0x20
+
+
+/**
+ * @brief Magnetic sensor Control Register 2
+ * \code
+ * Read/write
+ * Default value: 0x00
+ * [7] These bits must be set to �0� for the correct operation of the device
+ * [6:5] FS1-0: Full-scale configuration
+ * [4] These bits must be set to �0� for the correct operation of the device
+ * [3] REBOOT: Reboot memory content
+ * [2] SOFT_RST: Configuration registers and user register reset function
+ * [1:0] These bits must be set to �0� for the correct operation of the device
+ * \endcode
+ */
+#define LIS3MDL_M_CTRL_REG2_M                               0x21
+
+
+/**
+ * @brief Magnetic sensor Control Register 3
+ * \code
+ * Read/write
+ * Default value: 0x03
+ * [7] I2C_DISABLE: Disable I2C interface
+ * [6] These bits must be set to �0� for the correct operation of the device
+ * [5] LP: Low-power mode configuration
+ * [4:3] These bits must be set to �0� for the correct operation of the device
+ * [2] SIM: SPI Serial Interface mode selection
+ * [1:0] MD1-0: Operating mode selection
+ * \endcode
+ */
+#define LIS3MDL_M_CTRL_REG3_M                               0x22
+
+
+/**
+ * @brief Magnetic sensor data (LSB)
+ * \code
+ * Read
+ * \endcode
+ */
+#define LIS3MDL_M_OUT_X_L_M                                 0x28
+
+
+/**
+ * @brief Magnetic sensor data (MSB)
+ * \code
+ * Read
+ * \endcode
+ */
+#define LIS3MDL_M_OUT_X_H_M                                  0x29
+
+
+/**
+ * @brief Magnetic sensor data (LSB)
+ * \code
+ * Read
+ * \endcode
+ */
+#define LIS3MDL_M_OUT_Y_L_M                                  0x2A
+
+
+/**
+ * @brief Magnetic sensor data (MSB)
+ * \code
+ * Read
+ * \endcode
+ */
+#define LIS3MDL_M_OUT_Y_H_M                                  0x2B
+
+
+/**
+ * @brief Magnetic sensor data (LSB)
+ * \code
+ * Read
+ * \endcode
+ */
+#define LIS3MDL_M_OUT_Z_L_M                                  0x2C
+
+
+/**
+ * @brief Magnetic sensor data (MSB)
+ * \code
+ * Read
+ * \endcode
+ */
+#define LIS3MDL_M_OUT_Z_H_M                                  0x2D
+
+
+/**
+ * @brief Magnetic sensor Interrupt config register
+ * \code
+ * Read/write
+ * Default value: 0x00
+ * [7] XIEN: Enable interrupt generation on X axis
+ * [6] YIEN: Enable interrupt generation on Y axis
+ * [5] ZIEN: Enable interrupt generation on Z axis
+ * [4:3] Must be 0
+ * [2] IEA: Interrupt active configuration on INT
+ * [1] LIR: Latch interrupt request
+ * [0] IEN: Interrupt enable on INT pin
+ * \endcode
+ */
+#define LIS3MDL_M_INT_CFG                                   0x30
+
+
+/**
+ * @brief Magnetic sensor Interrupt source register
+ * \code
+ * Read/write
+ * Default value: 0x00
+ * [7] PTH_X: Value on X-axis exceeds the threshold on the positive side
+ * [6] PTH_Y: Value on Y-axis exceeds the threshold on the positive side
+ * [5] PTH_Z: Value on Z-axis exceeds the threshold on the positive side
+ * [4] NTH_X: Value on X-axis exceeds the threshold on the negative side
+ * [3] NTH_Y: Value on Y-axis exceeds the threshold on the negative side
+ * [2] NTH_Z: Value on Z-axis exceeds the threshold on the negative side
+ * [1] MROI: Internal measurement range overflow on magnetic value
+ * [0] INT: This bit signals when interrupt event occours
+ * \endcode
+ */
+#define LIS3MDL_M_INT_SRC                                   0x31
+
+
+/**
+ * @brief Magnetic sensor Interrupt threshold register low
+ * \code
+ * Read/write
+ * Default value: 0x00
+ * [7:0] THS7-0: Least 8 significant bits of interrupt threshold
+ * \endcode
+ */
+#define LIS3MDL_M_INT_THS_L_M                               0x32
+
+
+/**
+ * @brief Magnetic sensor Interrupt threshold register high
+ * \code
+ * Read/write
+ * Default value: 0x00
+ * [7] Must be 0
+ * [6:0] THS14-8: Most 7 significant bits of interrupt threshold
+ * \endcode
+ */
+#define LIS3MDL_M_INT_THS_H_M                               0x33
+
+/******************************************************************************/
+/******************* END MAGNETIC SENSOR REGISTER MAPPING  ********************/
+/******************************************************************************/
+
+/**
+ * @brief Multiple Byte. Mask for enabling multiple byte read/write command.
+ */
+#define LIS3MDL_I2C_MULTIPLEBYTE_CMD                      ((uint8_t)0x80)
+
+/**
+ * @brief I2C Device Address
+ */
+//#define LIS3MDL_M_MEMS_ADDRESS                              0x3C    // SAD[1] = 1
+#define LIS3MDL_M_MEMS_ADDRESS_LOW                               0x38    // SAD[1] = 0
+#define LIS3MDL_M_MEMS_ADDRESS_HIGH                              0x3C    // SAD[1] = 1
+
+/**
+ * @brief Device Identifier. Default value of the WHO_AM_I register.
+ */
+#define I_AM_LIS3MDL_M                                  ((uint8_t)0x3D)
+
+
+/*********************************** MAGNETIC SENSOR REGISTERS VALUE ****************************************/
+
+/** @defgroup LIS3MDL_M_Temperature_Compensation_Enable_Selection_CTRL_REG1_M LIS3MDL_M_Temperature_Compensation_Enable_Selection_CTRL_REG1_M
+ * @{
+ */
+#define LIS3MDL_M_TEMP_COMP_DISABLE                     ((uint8_t)0x00) /*!< Temperature compensation: disable */
+#define LIS3MDL_M_TEMP_COMP_ENABLE                      ((uint8_t)0x80) /*!< Temperature compensation: enable */
+
+#define LIS3MDL_M_TEMP_COMP_MASK                        ((uint8_t)0x80)
+/**
+  * @}
+  */
+
+/** @defgroup LIS3MDL_M_X_And_Y_Axes_Operative_Mode_Selection_CTRL_REG1_M LIS3MDL_M_X_And_Y_Axes_Operative_Mode_Selection_CTRL_REG1_M
+ * @{
+ */
+#define LIS3MDL_M_OM_LP                                 ((uint8_t)0x00) /*!< X and Y axes operative mode: Low-power mode */
+#define LIS3MDL_M_OM_MP                                 ((uint8_t)0x20) /*!< X and Y axes operative mode: Medium-performance mode */
+#define LIS3MDL_M_OM_HP                                 ((uint8_t)0x40) /*!< X and Y axes operative mode: High-performance mode */
+#define LIS3MDL_M_OM_UHP                                ((uint8_t)0x60) /*!< X and Y axes operative mode: Ultra-high performance mode */
+
+#define LIS3MDL_M_OM_MASK                               ((uint8_t)0x60)
+/**
+  * @}
+  */
+
+/** @defgroup LIS3MDL_M_Output_Data_Rate_Selection_CTRL_REG1_M LIS3MDL_M_Output_Data_Rate_Selection_CTRL_REG1_M
+ * @{
+ */
+#define LIS3MDL_M_DO_0_625                              ((uint8_t)0x00) /*!< Output data rate selection: 0.625 */
+#define LIS3MDL_M_DO_1_25                               ((uint8_t)0x04) /*!< Output data rate selection: 1.25 */
+#define LIS3MDL_M_DO_2_5                                ((uint8_t)0x08) /*!< Output data rate selection: 2.5 */
+#define LIS3MDL_M_DO_5                                  ((uint8_t)0x0C) /*!< Output data rate selection: 5 */
+#define LIS3MDL_M_DO_10                                 ((uint8_t)0x10) /*!< Output data rate selection: 10 */
+#define LIS3MDL_M_DO_20                                 ((uint8_t)0x14) /*!< Output data rate selection: 20 */
+#define LIS3MDL_M_DO_40                                 ((uint8_t)0x18) /*!< Output data rate selection: 40 */
+#define LIS3MDL_M_DO_80                                 ((uint8_t)0x1C) /*!< Output data rate selection: 80 */
+
+#define LIS3MDL_M_DO_MASK                               ((uint8_t)0x1C)
+/**
+  * @}
+  */
+
+/** @defgroup LIS3MDL_M_Self_Test_Enable_Selection_CTRL_REG1_M LIS3MDL_M_Self_Test_Enable_Selection_CTRL_REG1_M
+ * @{
+ */
+#define LIS3MDL_M_ST_DISABLE                            ((uint8_t)0x00) /*!< Self-test: disable */
+#define LIS3MDL_M_ST_ENABLE                             ((uint8_t)0x01) /*!< Self-test: enable */
+
+#define LIS3MDL_M_ST_MASK                               ((uint8_t)0x01)
+/**
+  * @}
+  */
+
+/** @defgroup LIS3MDL_M_Full_Scale_Selection_CTRL_REG2_M LIS3MDL_M_Full_Scale_Selection_CTRL_REG2_M
+ * @{
+ */
+#define LIS3MDL_M_FS_4                                  ((uint8_t)0x00) /*!< Full scale: +-4 guass */
+#define LIS3MDL_M_FS_8                                  ((uint8_t)0x20) /*!< Full scale: +-8 gauss */
+#define LIS3MDL_M_FS_12                                 ((uint8_t)0x40) /*!< Full scale: +-12 gauss */
+#define LIS3MDL_M_FS_16                                 ((uint8_t)0x60) /*!< Full scale: +-16 gauss */
+
+#define LIS3MDL_M_FS_MASK                               ((uint8_t)0x60)
+/**
+  * @}
+  */
+
+/** @defgroup LIS3MDL_M_Reboot_Memory_Selection_CTRL_REG2_M LIS3MDL_M_Reboot_Memory_Selection_CTRL_REG2_M
+ * @{
+ */
+#define LIS3MDL_M_REBOOT_NORMAL                         ((uint8_t)0x00) /*!< Reboot mode: normal mode */
+#define LIS3MDL_M_REBOOT_MEM_CONTENT                    ((uint8_t)0x08) /*!< Reboot mode: reboot memory content */
+
+#define LIS3MDL_M_REBOOT_MASK                           ((uint8_t)0x08)
+/**
+  * @}
+  */
+
+/** @defgroup LIS3MDL_M_Configuration_Registers_And_User_Register_Reset_CTRL_REG2_M LIS3MDL_M_Configuration_Registers_And_User_Register_Reset_CTRL_REG2_M
+ * @{
+ */
+#define LIS3MDL_M_SOFT_RST_DEFAULT                      ((uint8_t)0x00) /*!< Reset function: default value */
+#define LIS3MDL_M_SOFT_RST_RESET                        ((uint8_t)0x04) /*!< Reset function: reset operation */
+
+#define LIS3MDL_M_SOFT_RST_MASK                         ((uint8_t)0x04)
+/**
+  * @}
+  */
+
+/** @defgroup LIS3MDL_M_Disable_I2C_Interface_Selection_CTRL_REG3_M LIS3MDL_M_Disable_I2C_Interface_Selection_CTRL_REG3_M
+ * @{
+ */
+#define LIS3MDL_M_I2C_ENABLE                            ((uint8_t)0x00) /*!< I2C interface: enable */
+#define LIS3MDL_M_I2C_DISABLE                           ((uint8_t)0x80) /*!< I2C interface: disable */
+
+#define LIS3MDL_M_I2C_MASK                              ((uint8_t)0x80)
+/**
+  * @}
+  */
+
+/** @defgroup LIS3MDL_M_Low_Power_Mode_Selection_CTRL_REG3_M LIS3MDL_M_Low_Power_Mode_Selection_CTRL_REG3_M
+ * @{
+ */
+#define LIS3MDL_M_LP_ENABLE                            ((uint8_t)0x00) /*!< Low-power mode: magnetic data rate is configured by
+                                                                                            the DO bits in the CTRL_REG1_M */
+#define LIS3MDL_M_LP_DISABLE                           ((uint8_t)0x20) /*!< Low-power mode: the DO bits is set to 0.625 Hz and the system performs,
+                                                                                            for each channel, the minimum number of averages */
+
+#define LIS3MDL_M_LP_MASK                              ((uint8_t)0x20)
+/**
+  * @}
+  */
+
+/** @defgroup LIS3MDL_M_SPI_Serial_Interface_Mode_Selection_CTRL_REG3_M LIS3MDL_M_SPI_Serial_Interface_Mode_Selection_CTRL_REG3_M
+ * @{
+ */
+#define LIS3MDL_M_SPI_R_ENABLE                          ((uint8_t)0x00) /*!< SPI Serial Interface mode: only write operations enabled */
+#define LIS3MDL_M_SPI_R_DISABLE                         ((uint8_t)0x40) /*!< SPI Serial Interface mode: read and write operations enable */
+
+#define LIS3MDL_M_SPI_R_MASK                            ((uint8_t)0x40)
+/**
+  * @}
+  */
+
+/** @defgroup LIS3MDL_M_Operating_Mode_Selection_CTRL_REG3_M LIS3MDL_M_Operating_Mode_Selection_CTRL_REG3_M
+ * @{
+ */
+#define LIS3MDL_M_MD_CONTINUOUS                         ((uint8_t)0x00) /*!< Operating mode: Continuous-conversion mode */
+#define LIS3MDL_M_MD_SINGLE                             ((uint8_t)0x01) /*!< Operating mode: Single-conversion mode has to be used with sampling frequency from 0.625 Hz to 80 Hz. */
+#define LIS3MDL_M_MD_PD                                 ((uint8_t)0x02) /*!< Operating mode: Power-down mode */
+
+#define LIS3MDL_M_MD_MASK                               ((uint8_t)0x03)
+/**
+ * @}
+ */
+
+/**
+  * @}
+  */
+
+/** @defgroup LIS3MDL_Imported_Functions LIS3MDL_Imported_Functions
+ * @{
+ */
+
+/* Magneto sensor IO functions */
+extern MAGNETO_StatusTypeDef LIS3MDL_IO_Init(void);
+extern MAGNETO_StatusTypeDef LIS3MDL_IO_Write(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr,
+    uint16_t NumByteToWrite);
+extern MAGNETO_StatusTypeDef LIS3MDL_IO_Read(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr,
+    uint16_t NumByteToRead);
+extern void LIS3MDL_IO_ITConfig( void );
+
+/**
+ * @}
+ */
+
+/* ------------------------------------------------------- */
+/* Here you should declare the internal struct of          */
+/* extended features of LSM6DS0. See the example of        */
+/* LSM6DS3 in lsm6ds3.h                                    */
+/* ------------------------------------------------------- */
+typedef enum { LIS3MDL_SPI_4_WIRE = (uint8_t)0x00, LIS3MDL_SPI_3_WIRE = (uint8_t)0x04} LIS3MDL_SPIMode_t;  
+/** @addtogroup LIS3MDL_Exported_Variables LIS3MDL_Exported_Variables
+ * @{
+ */
+/* Magneto sensor driver structure */
+extern MAGNETO_DrvTypeDef LIS3MDLDrv;
+extern MAGNETO_DrvExtTypeDef LIS3MDLDrv_ext;
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LIS3MDL_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/LIS3MDL/lis3mdl_class.cpp	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,266 @@
+/**
+ ******************************************************************************
+ * @file    lis3mdl_class.cpp
+ * @author  AST / EST
+ * @version V0.0.1
+ * @date    14-April-2015
+ * @brief   Implementation file for the LIS3MDL driver class
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "lis3mdl_class.h"
+#include "lis3mdl.h"
+
+/* Methods -------------------------------------------------------------------*/
+/* betzw - based on:
+           X-CUBE-MEMS1/trunk/Drivers/BSP/Components/lis3mdl/lis3mdl.c: revision #400,
+           X-CUBE-MEMS1/trunk: revision #416
+*/
+
+LIS3MDL::LIS3MDL(SPI *spi, PinName cs_pin, PinName int_pin, SPI_type_t spi_type) : 
+                _dev_spi(spi), _cs_pin(cs_pin), _int_pin(int_pin), _spi_type(spi_type)
+{
+    assert (spi);
+    if (cs_pin == NC) 
+    {
+        printf ("ERROR LIS3MDL CS MUST NOT BE NC\n\r");       
+        _dev_spi = NULL;
+        _dev_i2c=NULL;
+        return;
+    }       
+
+    _cs_pin = 0;    
+    _dev_i2c=NULL;    
+    
+    if (_spi_type == SPI3W) LIS3MDL_Set_SpiInterface ((void *)this, LIS3MDL_SPI_3_WIRE);
+    else if (_spi_type == SPI4W) LIS3MDL_Set_SpiInterface ((void *)this, LIS3MDL_SPI_4_WIRE);
+}  
+
+LIS3MDL::LIS3MDL(DevI2C *i2c, uint8_t address, PinName int_pin) :
+       _dev_i2c(i2c), _address(address), _cs_pin(NC), _int_pin(int_pin)  
+{
+    assert (i2c);
+    _dev_spi = NULL;
+}  
+
+
+MAGNETO_StatusTypeDef LIS3MDL::LIS3MDL_Set_SpiInterface (void *handle, LIS3MDL_SPIMode_t spimode)
+{
+    uint8_t tmp=0x03;  //deft LIS3MDL_CTRL_REG3 value  
+
+    tmp |= (uint8_t)spimode;
+    if (LIS3MDL_IO_Write(&tmp, LIS3MDL_M_CTRL_REG3_M, 1) != MAGNETO_OK) return MAGNETO_ERROR;      
+    return MAGNETO_OK;
+}
+
+/**
+ * @brief  Set LIS3MDL Initialization
+ * @param  LIS3MDL_Init the configuration setting for the LIS3MDL
+ * @retval MAGNETO_OK in case of success, an error code otherwise
+ */
+MAGNETO_StatusTypeDef LIS3MDL::LIS3MDL_Init(MAGNETO_InitTypeDef *LIS3MDL_Init)
+{
+  uint8_t tmp1 = 0x00;
+  MAGNETO_InitTypeDef *initStructure = LIS3MDL_Init;
+  MAGNETO_InitTypeDef tempInit;  
+  
+  if (initStructure == NULL) {// default params   
+    tempInit.M_FullScale = LIS3MDL_M_FS_4;
+    tempInit.M_OperatingMode = LIS3MDL_M_MD_CONTINUOUS;
+    tempInit.M_XYOperativeMode = LIS3MDL_M_OM_HP;
+    tempInit.M_OutputDataRate = LIS3MDL_M_DO_80;
+    initStructure = &tempInit;
+  }
+  
+  
+  /* Configure the low level interface ---------------------------------------*/
+  if(LIS3MDL_IO_Init() != MAGNETO_OK)
+  {
+    return MAGNETO_ERROR;
+  }
+  
+  /****** Magnetic sensor *******/
+  
+  if(LIS3MDL_IO_Read(&tmp1, LIS3MDL_M_CTRL_REG3_M, 1) != MAGNETO_OK)
+  {
+    return MAGNETO_ERROR;
+  }
+  
+  /* Conversion mode selection */
+  tmp1 &= ~(LIS3MDL_M_MD_MASK);
+  tmp1 |= initStructure->M_OperatingMode;
+  
+  if(LIS3MDL_IO_Write(&tmp1, LIS3MDL_M_CTRL_REG3_M, 1) != MAGNETO_OK)
+  {
+    return MAGNETO_ERROR;
+  }
+  
+  if(LIS3MDL_IO_Read(&tmp1, LIS3MDL_M_CTRL_REG1_M, 1) != MAGNETO_OK)
+  {
+    return MAGNETO_ERROR;
+  }
+  
+  /* Output data rate selection */
+  tmp1 &= ~(LIS3MDL_M_DO_MASK);
+  tmp1 |= initStructure->M_OutputDataRate;
+  
+  /* X and Y axes Operative mode selection */
+  tmp1 &= ~(LIS3MDL_M_OM_MASK);
+  tmp1 |= initStructure->M_XYOperativeMode;
+  
+  if(LIS3MDL_IO_Write(&tmp1, LIS3MDL_M_CTRL_REG1_M, 1) != MAGNETO_OK)
+  {
+    return MAGNETO_ERROR;
+  }
+  
+  if(LIS3MDL_IO_Read(&tmp1, LIS3MDL_M_CTRL_REG2_M, 1) != MAGNETO_OK)
+  {
+    return MAGNETO_ERROR;
+  }
+  
+  /* Full scale selection */
+  tmp1 &= ~(LIS3MDL_M_FS_MASK);
+  tmp1 |= initStructure->M_FullScale;
+  
+  if(LIS3MDL_IO_Write(&tmp1, LIS3MDL_M_CTRL_REG2_M, 1) != MAGNETO_OK)
+  {
+    return MAGNETO_ERROR;
+  }
+  
+  /* Configure interrupt lines */
+  LIS3MDL_IO_ITConfig();
+  
+  return MAGNETO_OK;
+  
+  /******************************/
+}
+
+
+/**
+ * @brief  Read ID of LIS3MDL Magnetic sensor
+ * @param  m_id the pointer where the ID of the device is stored
+ * @retval MAGNETO_OK in case of success, an error code otherwise
+ */
+MAGNETO_StatusTypeDef LIS3MDL::LIS3MDL_Read_M_ID(uint8_t *m_id)
+{
+  if(!m_id)
+  {
+    return MAGNETO_ERROR;
+  }
+  
+  return LIS3MDL_IO_Read(m_id, LIS3MDL_M_WHO_AM_I_ADDR, 1);
+}
+
+
+/**
+ * @brief  Read raw data from LIS3MDL Magnetic sensor output register
+ * @param  pData the pointer where the magnetometer raw data are stored
+ * @retval MAGNETO_OK in case of success, an error code otherwise
+ */
+MAGNETO_StatusTypeDef LIS3MDL::LIS3MDL_M_GetAxesRaw(int16_t *pData)
+{
+  uint8_t tempReg[2] = {0, 0};
+  
+  if(LIS3MDL_IO_Read(&tempReg[0], (LIS3MDL_M_OUT_X_L_M | LIS3MDL_I2C_MULTIPLEBYTE_CMD),
+                     2) != MAGNETO_OK)
+  {
+    return MAGNETO_ERROR;
+  }
+  
+  pData[0] = ((((int16_t)tempReg[1]) << 8) + (int16_t)tempReg[0]);
+  
+  if(LIS3MDL_IO_Read(&tempReg[0], (LIS3MDL_M_OUT_Y_L_M | LIS3MDL_I2C_MULTIPLEBYTE_CMD),
+                     2) != MAGNETO_OK)
+  {
+    return MAGNETO_ERROR;
+  }
+  
+  pData[1] = ((((int16_t)tempReg[1]) << 8) + (int16_t)tempReg[0]);
+  
+  if(LIS3MDL_IO_Read(&tempReg[0], (LIS3MDL_M_OUT_Z_L_M | LIS3MDL_I2C_MULTIPLEBYTE_CMD),
+                     2) != MAGNETO_OK)
+  {
+    return MAGNETO_ERROR;
+  }
+  
+  pData[2] = ((((int16_t)tempReg[1]) << 8) + (int16_t)tempReg[0]);
+  
+  return MAGNETO_OK;
+}
+
+
+/**
+ * @brief Read data from LIS3MDL Magnetic sensor and calculate Magnetic in mgauss
+ * @param pData the pointer where the magnetometer data are stored
+ * @retval MAGNETO_OK in case of success, an error code otherwise
+ */
+MAGNETO_StatusTypeDef LIS3MDL::LIS3MDL_M_GetAxes(int32_t *pData)
+{
+  uint8_t tempReg = 0x00;
+  int16_t pDataRaw[3];
+  float sensitivity = 0;
+  
+  if(LIS3MDL_M_GetAxesRaw(pDataRaw) != MAGNETO_OK)
+  {
+    return MAGNETO_ERROR;
+  }
+  
+  if(LIS3MDL_IO_Read(&tempReg, LIS3MDL_M_CTRL_REG2_M, 1) != MAGNETO_OK)
+  {
+    return MAGNETO_ERROR;
+  }
+  
+  tempReg &= LIS3MDL_M_FS_MASK;
+  
+  switch(tempReg)
+  {
+    case LIS3MDL_M_FS_4:
+      sensitivity = 0.14;
+      break;
+    case LIS3MDL_M_FS_8:
+      sensitivity = 0.29;
+      break;
+    case LIS3MDL_M_FS_12:
+      sensitivity = 0.43;
+      break;
+    case LIS3MDL_M_FS_16:
+      sensitivity = 0.58;
+      break;
+  }
+  
+  pData[0] = (int32_t)(pDataRaw[0] * sensitivity);
+  pData[1] = (int32_t)(pDataRaw[1] * sensitivity);
+  pData[2] = (int32_t)(pDataRaw[2] * sensitivity);
+  
+  return MAGNETO_OK;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/LIS3MDL/lis3mdl_class.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,190 @@
+/**
+ ******************************************************************************
+ * @file    lis3mdl_class.h
+ * @author  AST / EST
+ * @version V0.0.1
+ * @date    14-April-2015
+ * @brief   Header file for component LIS3MDL
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+*/
+
+#ifndef __LIS3MDL_CLASS_H
+#define __LIS3MDL_CLASS_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "mbed.h"
+#include "DevI2C.h"
+#include "lis3mdl.h"
+#include "MagneticSensor.h"
+#include <assert.h>
+
+
+/* Classes -------------------------------------------------------------------*/
+/** Class representing a LIS3MDL sensor component
+ */
+class LIS3MDL : public MagneticSensor {
+ public:
+    enum SPI_type_t {SPI3W, SPI4W};    
+    
+    LIS3MDL(SPI *spi, PinName cs_pin, PinName int_pin=NC, SPI_type_t spi_type=SPI4W);
+        
+	/** Constructor
+	 * @param[in] i2c device I2C to be used for communication
+	 */    
+	 
+    LIS3MDL(DevI2C *i2c, uint8_t address=LIS3MDL_M_MEMS_ADDRESS_HIGH, PinName int_pin=NC);
+	
+	/** Destructor
+	 */
+        virtual ~LIS3MDL() {}
+	
+	/*** Interface Methods ***/
+	virtual int init(void *init_struct) {
+		return LIS3MDL_Init((MAGNETO_InitTypeDef*)init_struct);
+	}
+
+	virtual int read_id(uint8_t *m_id) {
+		return LIS3MDL_Read_M_ID(m_id);
+	}
+
+	virtual int get_m_axes(int32_t *pData) {
+		return LIS3MDL_M_GetAxes(pData);
+	}
+
+	virtual int get_m_axes_raw(int16_t *pData) {
+		return LIS3MDL_M_GetAxesRaw(pData);
+	}
+
+ protected:
+	/*** Methods ***/
+	MAGNETO_StatusTypeDef LIS3MDL_Init(MAGNETO_InitTypeDef *LIS3MDL_Init);
+	MAGNETO_StatusTypeDef LIS3MDL_Read_M_ID(uint8_t *m_id);
+	MAGNETO_StatusTypeDef LIS3MDL_M_GetAxes(int32_t *pData);
+	MAGNETO_StatusTypeDef LIS3MDL_M_GetAxesRaw(int16_t *pData);
+	MAGNETO_StatusTypeDef LIS3MDL_Set_SpiInterface (void *handle, LIS3MDL_SPIMode_t spimode);
+
+	/**
+	 * @brief  Configures LIS3MDL interrupt lines for NUCLEO boards
+	 */
+	void LIS3MDL_IO_ITConfig(void)
+	{
+		/* To be implemented */
+	}
+
+	/**
+	 * @brief  Configures LIS3MDL I2C interface
+	 * @return MAGNETO_OK in case of success, an error code otherwise
+	 */
+	MAGNETO_StatusTypeDef LIS3MDL_IO_Init(void)
+	{
+		return MAGNETO_OK; /* done in constructor */
+	}
+
+	/**
+	 * @brief      Utility function to read data from LIS3MDL
+	 * @param[out] pBuffer pointer to the byte-array to read data in to
+	 * @param[in]  RegisterAddr specifies internal address register to read from.
+	 * @param[in]  NumByteToRead number of bytes to be read.
+	 * @retval     MAGNETO_OK if ok, 
+	 * @retval     MAGNETO_ERROR if an I2C error has occured
+	 */
+	MAGNETO_StatusTypeDef LIS3MDL_IO_Read(uint8_t* pBuffer, 
+					      uint8_t RegisterAddr, uint16_t NumByteToRead)
+	{
+        if (_dev_spi) {
+        /* Write Reg Address */
+            _dev_spi->lock();
+            _cs_pin = 0;           
+            if (_spi_type == SPI4W) {            
+                _dev_spi->write(RegisterAddr | 0x80);
+                for (int i=0; i<NumByteToRead; i++) {
+                    *(pBuffer+i) = _dev_spi->write(0x00);
+                }
+            } else if (_spi_type == SPI3W){
+                /* Write RD Reg Address with RD bit*/
+                uint8_t TxByte = RegisterAddr | 0x80;    
+                _dev_spi->write((char *)&TxByte, 1, (char *)pBuffer, (int) NumByteToRead);
+            }            
+            _cs_pin = 1;
+            _dev_spi->unlock(); 
+            return MAGNETO_OK;
+        }            		
+        if (!_dev_i2c) return MAGNETO_ERROR;			
+		int ret = _dev_i2c->i2c_read(pBuffer,
+					   _address,
+					   RegisterAddr,
+					   NumByteToRead);
+		if(ret != 0) {
+			return MAGNETO_ERROR;
+		}
+		return MAGNETO_OK;
+	}
+	
+	/**
+	 * @brief      Utility function to write data to LIS3MDL
+	 * @param[in]  pBuffer pointer to the byte-array data to send
+	 * @param[in]  RegisterAddr specifies internal address register to read from.
+	 * @param[in]  NumByteToWrite number of bytes to write.
+	 * @retval     MAGNETO_OK if ok, 
+	 * @retval     MAGNETO_ERROR if an I2C error has occured
+	 */
+	MAGNETO_StatusTypeDef LIS3MDL_IO_Write(uint8_t* pBuffer, 
+					       uint8_t RegisterAddr, uint16_t NumByteToWrite)
+	{
+		
+        if (_dev_spi) { 
+            _dev_spi->lock();
+            _cs_pin = 0;
+            int data = _dev_spi->write(RegisterAddr);                    
+            _dev_spi->write((char *)pBuffer, (int) NumByteToWrite, NULL, 0);                     
+            _cs_pin = 1;                    
+            _dev_spi->unlock();
+            return MAGNETO_OK;                    
+        }        
+		
+        if (!_dev_i2c) return MAGNETO_ERROR;	
+		int ret = _dev_i2c->i2c_write(pBuffer, _address, RegisterAddr, NumByteToWrite);
+		if(ret != 0) {
+			return MAGNETO_ERROR;
+		}
+		return MAGNETO_OK;
+	}
+	
+	/*** Instance Variables ***/
+	/* IO Device */
+	DevI2C *_dev_i2c;
+	SPI    *_dev_spi;
+    uint8_t _address;	
+    DigitalOut  _cs_pin; 
+    InterruptIn _int_pin;    
+    SPI_type_t _spi_type;        
+};
+
+#endif // __LIS3MDL_CLASS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/LIS3MDL/magneto.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,142 @@
+/**
+ ******************************************************************************
+ * @file    magneto.h
+ * @author  MEMS Application Team
+ * @version V1.2.0
+ * @date    28-January-2015
+ * @brief   This header file contains the functions prototypes for the
+ *          magneto driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MAGNETO_H
+#define __MAGNETO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Components
+  * @{
+  */
+
+/** @addtogroup MAGNETO
+  * @{
+  */
+
+/** @defgroup MAGNETO_Exported_Types
+  * @{
+  */
+
+/**
+* @brief  MAGNETO init structure definition
+*/
+typedef struct
+{
+  uint8_t M_OutputDataRate;
+  uint8_t M_OperatingMode;
+  uint8_t M_FullScale;
+  uint8_t M_XYOperativeMode;
+} MAGNETO_InitTypeDef;
+
+/**
+* @brief  MAGNETO status enumerator definition
+*/
+typedef enum
+{
+  MAGNETO_OK = 0,
+  MAGNETO_ERROR = 1,
+  MAGNETO_TIMEOUT = 2,
+  MAGNETO_NOT_IMPLEMENTED = 3
+} MAGNETO_StatusTypeDef;
+
+/**
+ * @brief  MAGNETO component id enumerator definition
+ */
+typedef enum
+{
+  MAGNETO_NONE_COMPONENT = 0,
+  MAGNETO_LIS3MDL_COMPONENT = 1
+} MAGNETO_ComponentTypeDef;
+
+/**
+ * @brief  MAGNETO driver extended structure definition
+ */
+typedef struct
+{
+  MAGNETO_ComponentTypeDef
+  id; /* This id must be unique for each component belonging to this class that wants to extend common class */
+  void *pData; /* This pointer is specific for each component */
+} MAGNETO_DrvExtTypeDef;
+
+/**
+* @brief  MAGNETO driver structure definition
+*/
+typedef struct
+{
+  MAGNETO_StatusTypeDef       (*Init)(MAGNETO_InitTypeDef *);
+  MAGNETO_StatusTypeDef       (*Read_M_ID)(uint8_t *);
+  MAGNETO_StatusTypeDef       (*Get_M_Axes)(int32_t *);
+  MAGNETO_StatusTypeDef       (*Get_M_AxesRaw)(int16_t *);
+  MAGNETO_DrvExtTypeDef       *extData;
+} MAGNETO_DrvTypeDef;
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MAGNETO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/LIS3MDL/readme.txt	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,3 @@
+lis3mdl.h corresponds to:
+- X-CUBE-MEMS1/trunk/Drivers/BSP/Components/lis3mdl/lis3mdl.h: revision #402,
+- X-CUBE-MEMS1/trunk: revision #416
--- a/sensors/LPS22HB.lib	Sun Dec 16 13:29:53 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://developer.mbed.org/teams/ST/code/LPS22HB/#f7b403c70f6b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/LPS22HB/LPS22HBSensor.cpp	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,410 @@
+/**
+ ******************************************************************************
+ * @file    LPS22HBSensor.cpp
+ * @author  CLab
+ * @version V1.0.0
+ * @date    5 August 2016
+ * @brief   Implementation of an LPS22HB Pressure sensor.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+
+
+#include "LPS22HBSensor.h"
+
+
+/* Class Implementation ------------------------------------------------------*/
+
+LPS22HBSensor::LPS22HBSensor(SPI *spi, PinName cs_pin, PinName int_pin, SPI_type_t spi_type)  : _dev_spi(spi), _cs_pin(cs_pin), _int_pin(int_pin), _spi_type(spi_type)
+{
+    assert (spi);
+    if (cs_pin == NC) 
+    {
+        printf ("ERROR LPS22HBSensor CS MUST NOT BE NC\n\r");       
+        _dev_spi = NULL;
+        _dev_i2c=NULL;
+        return;
+    }       
+
+    _cs_pin = 1;    
+    _dev_i2c=NULL;    
+    
+    if (_spi_type == SPI3W) LPS22HB_Set_SpiInterface ((void *)this, LPS22HB_SPI_3_WIRE);
+    else if (_spi_type == SPI4W) LPS22HB_Set_SpiInterface ((void *)this, LPS22HB_SPI_4_WIRE);
+    
+    LPS22HB_Set_I2C ((void *)this, LPS22HB_DISABLE);
+}
+
+/** Constructor
+ * @param i2c object of an helper class which handles the I2C peripheral
+ * @param address the address of the component's instance
+ */
+LPS22HBSensor::LPS22HBSensor(DevI2C *i2c, uint8_t address, PinName int_pin) : 
+                            _dev_i2c(i2c), _address(address), _cs_pin(NC), _int_pin(int_pin)
+{
+    assert (i2c);
+    _dev_spi = NULL;
+    LPS22HB_Set_I2C ((void *)this, LPS22HB_ENABLE);         
+};
+
+/**
+ * @brief     Initializing the component.
+ * @param[in] init pointer to device specific initalization structure.
+ * @retval    "0" in case of success, an error code otherwise.
+ */
+int LPS22HBSensor::init(void *init)
+{
+  if ( LPS22HB_Set_PowerMode( (void *)this, LPS22HB_LowPower) == LPS22HB_ERROR )
+  {
+    return 1;
+  }
+
+  /* Power down the device */
+  if ( LPS22HB_Set_Odr( (void *)this, LPS22HB_ODR_ONE_SHOT ) == LPS22HB_ERROR )
+  {
+    return 1;
+  }
+
+  /* Disable low-pass filter on LPS22HB pressure data */
+  if( LPS22HB_Set_LowPassFilter( (void *)this, LPS22HB_DISABLE) == LPS22HB_ERROR )
+  {
+    return 1;
+  }
+
+  /* Set low-pass filter cutoff configuration*/
+  if( LPS22HB_Set_LowPassFilterCutoff( (void *)this, LPS22HB_ODR_9) == LPS22HB_ERROR )
+  {
+    return 1;
+  }
+
+  /* Set block data update mode */
+  if ( LPS22HB_Set_Bdu( (void *)this, LPS22HB_BDU_NO_UPDATE ) == LPS22HB_ERROR )
+  {
+    return 1;
+  }
+
+  /* Set automatic increment for multi-byte read/write */
+  if( LPS22HB_Set_AutomaticIncrementRegAddress( (void *)this, LPS22HB_ENABLE) == LPS22HB_ERROR )
+  {
+    return 1;
+  }
+
+  _is_enabled = 0;
+  _last_odr = 25.0f;
+  
+  return 0;
+}
+
+
+/**
+ * @brief  Enable LPS22HB
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LPS22HBSensor::enable(void)
+{
+  /* Check if the component is already enabled */
+  if ( _is_enabled == 1 )
+  {
+    return 0;
+  }
+  
+  if(Set_ODR_When_Enabled(_last_odr) == 1)
+  {
+    return 1;
+  }
+  
+  _is_enabled = 1;
+
+  return 0;
+}
+
+/**
+ * @brief  Disable LPS22HB
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LPS22HBSensor::disable(void)
+{
+  /* Check if the component is already disabled */
+  if ( _is_enabled == 0 )
+  {
+    return 0;
+  }
+  
+  /* Power down the device */
+  if ( LPS22HB_Set_Odr( (void *)this, LPS22HB_ODR_ONE_SHOT ) == LPS22HB_ERROR )
+  {
+    return 1;
+  }
+  
+  _is_enabled = 0;
+
+  return 0;
+}
+
+/**
+ * @brief  Read ID address of LPS22HB
+ * @param  id the pointer where the ID of the device is stored
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LPS22HBSensor::read_id(uint8_t *id)
+{
+  if(!id)
+  { 
+    return 1;
+  }
+ 
+  /* Read WHO AM I register */
+  if ( LPS22HB_Get_DeviceID( (void *)this, id ) == LPS22HB_ERROR )
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Reboot memory content of LPS22HB
+ * @param  None
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LPS22HBSensor::reset(void)
+{
+  /* Read WHO AM I register */
+  if ( LPS22HB_MemoryBoot((void *)this) == LPS22HB_ERROR )
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Read LPS22HB output register, and calculate the pressure in mbar
+ * @param  pfData the pressure value in mbar
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LPS22HBSensor::get_pressure(float* pfData)
+{
+  int32_t int32data = 0;
+
+  /* Read data from LPS22HB. */
+  if ( LPS22HB_Get_Pressure( (void *)this, &int32data ) == LPS22HB_ERROR )
+  {
+    return 1;
+  }
+
+  *pfData = ( float )int32data / 100.0f;
+
+  return 0;
+}
+
+/**
+ * @brief  Read LPS22HB output register, and calculate the temperature
+ * @param  pfData the temperature value
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LPS22HBSensor::get_temperature(float *pfData)
+{
+  int16_t int16data = 0;
+
+  /* Read data from LPS22HB. */
+  if ( LPS22HB_Get_Temperature( (void *)this, &int16data ) == LPS22HB_ERROR )
+  {
+    return 1;
+  }
+
+  *pfData = ( float )int16data / 10.0f;
+
+  return 0;
+}
+
+/**
+ * @brief  Read LPS22HB output data rate
+ * @param  odr the pointer to the output data rate
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LPS22HBSensor::get_odr(float* odr)
+{
+  LPS22HB_Odr_et odr_low_level;
+
+  if ( LPS22HB_Get_Odr( (void *)this, &odr_low_level ) == LPS22HB_ERROR )
+  {
+    return 1;
+  }
+
+  switch( odr_low_level )
+  {
+    case LPS22HB_ODR_ONE_SHOT:
+      *odr = 0.0f;
+      break;
+    case LPS22HB_ODR_1HZ:
+      *odr = 1.0f;
+      break;
+    case LPS22HB_ODR_10HZ:
+      *odr = 10.0f;
+      break;
+    case LPS22HB_ODR_25HZ:
+      *odr = 25.0f;
+      break;
+    case LPS22HB_ODR_50HZ:
+      *odr = 50.0f;
+      break;
+    case LPS22HB_ODR_75HZ:
+      *odr = 75.0f;
+      break;
+    default:
+      *odr = -1.0f;
+      return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set ODR
+ * @param  odr the output data rate to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LPS22HBSensor::set_odr(float odr)
+{
+  if(_is_enabled == 1)
+  {
+    if(Set_ODR_When_Enabled(odr) == 1)
+    {
+      return 1;
+    }
+  }
+  else
+  {
+    if(Set_ODR_When_Disabled(odr) == 1)
+    {
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+
+/**
+ * @brief Set the LPS22HB sensor output data rate when enabled
+ * @param odr the functional output data rate to be set
+ * @retval 0 in case of success
+ * @retval 1 in case of failure
+ */
+int LPS22HBSensor::Set_ODR_When_Enabled( float odr )
+{
+  LPS22HB_Odr_et new_odr;
+
+  new_odr = ( odr <=  1.0f ) ? LPS22HB_ODR_1HZ
+          : ( odr <= 10.0f ) ? LPS22HB_ODR_10HZ
+          : ( odr <= 25.0f ) ? LPS22HB_ODR_25HZ
+          : ( odr <= 50.0f ) ? LPS22HB_ODR_50HZ
+          :                    LPS22HB_ODR_75HZ;
+
+  if ( LPS22HB_Set_Odr( (void *)this, new_odr ) == LPS22HB_ERROR )
+  {
+    return 1;
+  }
+
+  if ( get_odr( &_last_odr ) == 1 )
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief Set the LPS22HB sensor output data rate when disabled
+ * @param odr the functional output data rate to be set
+ * @retval 0 in case of success
+ * @retval 1 in case of failure
+ */
+int LPS22HBSensor::Set_ODR_When_Disabled( float odr )
+{
+  _last_odr = ( odr <=  1.0f ) ? 1.0f
+           : ( odr <= 10.0f ) ? 10.0f
+           : ( odr <= 25.0f ) ? 25.0f
+           : ( odr <= 50.0f ) ? 50.0f
+           :                    75.0f;
+
+  return 0;
+}
+
+
+/**
+ * @brief Read the data from register
+ * @param reg register address
+ * @param data register data
+ * @retval 0 in case of success
+ * @retval 1 in case of failure
+ */
+int LPS22HBSensor::read_reg( uint8_t reg, uint8_t *data )
+{
+
+  if ( LPS22HB_read_reg( (void *)this, reg, 1, data ) == LPS22HB_ERROR )
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief Write the data to register
+ * @param reg register address
+ * @param data register data
+ * @retval 0 in case of success
+ * @retval 1 in case of failure
+ */
+int LPS22HBSensor::write_reg( uint8_t reg, uint8_t data )
+{
+
+  if ( LPS22HB_write_reg( (void *)this, reg, 1, &data ) == LPS22HB_ERROR )
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+
+uint8_t LPS22HB_io_write( void *handle, uint8_t WriteAddr, uint8_t *pBuffer, uint16_t nBytesToWrite )
+{
+  return ((LPS22HBSensor *)handle)->io_write(pBuffer, WriteAddr, nBytesToWrite);
+}
+
+uint8_t LPS22HB_io_read( void *handle, uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead )
+{
+  return ((LPS22HBSensor *)handle)->io_read(pBuffer, ReadAddr, nBytesToRead);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/LPS22HB/LPS22HBSensor.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,157 @@
+/**
+ ******************************************************************************
+ * @file    LPS22HBSensor.h
+ * @author  CLab
+ * @version V1.0.0
+ * @date    5 August 2016
+ * @brief   Abstract Class of an LPS22HB Pressure sensor.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+
+/* Prevent recursive inclusion -----------------------------------------------*/
+
+#ifndef __LPS22HBSensor_H__
+#define __LPS22HBSensor_H__
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "DevI2C.h"
+#include "LPS22HB_driver.h"
+#include "PressureSensor.h"
+#include "TempSensor.h"
+#include <assert.h>
+
+/* Class Declaration ---------------------------------------------------------*/
+
+/**
+ * Abstract class of an LPS22HB Pressure sensor.
+ */
+class LPS22HBSensor : public PressureSensor, public TempSensor
+{
+  public:
+  
+    enum SPI_type_t {SPI3W, SPI4W};  
+    LPS22HBSensor(SPI *spi, PinName cs_pin, PinName int_pin=NC, SPI_type_t spi_type=SPI4W);     
+    LPS22HBSensor(DevI2C *i2c, uint8_t address=LPS22HB_ADDRESS_HIGH, PinName int_pin=NC);
+    virtual int init(void *init);
+    virtual int read_id(uint8_t *id);
+    virtual int get_pressure(float *pfData);
+    virtual int get_temperature(float *pfData);
+    int enable(void);
+    int disable(void);
+    int reset(void);
+    int get_odr(float *odr);
+    int set_odr(float odr);
+    int read_reg(uint8_t reg, uint8_t *data);
+    int write_reg(uint8_t reg, uint8_t data);
+    
+    /**
+     * @brief Utility function to read data.
+     * @param  pBuffer: pointer to data to be read.
+     * @param  RegisterAddr: specifies internal address register to be read.
+     * @param  NumByteToRead: number of bytes to be read.
+     * @retval 0 if ok, an error code otherwise.
+     */
+    uint8_t io_read(uint8_t* pBuffer, uint8_t RegisterAddr, uint16_t NumByteToRead)
+    {
+        if (_dev_spi) {
+        /* Write Reg Address */
+            _dev_spi->lock();
+            _cs_pin = 0;           
+            if (_spi_type == SPI4W) {            
+                _dev_spi->write(RegisterAddr | 0x80);
+                for (int i=0; i<NumByteToRead; i++) {
+                    *(pBuffer+i) = _dev_spi->write(0x00);
+                }
+            } else if (_spi_type == SPI3W){
+                /* Write RD Reg Address with RD bit*/
+                uint8_t TxByte = RegisterAddr | 0x80;    
+                _dev_spi->write((char *)&TxByte, 1, (char *)pBuffer, (int) NumByteToRead);
+            }            
+            _cs_pin = 1;
+            _dev_spi->unlock(); 
+            return 0;
+        }                       
+        if (_dev_i2c) return (uint8_t) _dev_i2c->i2c_read(pBuffer, _address, RegisterAddr, NumByteToRead);
+        return 1;
+    }
+    
+    /**
+     * @brief Utility function to write data.
+     * @param  pBuffer: pointer to data to be written.
+     * @param  RegisterAddr: specifies internal address register to be written.
+     * @param  NumByteToWrite: number of bytes to write.
+     * @retval 0 if ok, an error code otherwise.
+     */
+    uint8_t io_write(uint8_t* pBuffer, uint8_t RegisterAddr, uint16_t NumByteToWrite)
+    {
+        if (_dev_spi) { 
+            _dev_spi->lock();
+            _cs_pin = 0;
+            int data = _dev_spi->write(RegisterAddr);                    
+            _dev_spi->write((char *)pBuffer, (int) NumByteToWrite, NULL, 0);                     
+            _cs_pin = 1;                    
+            _dev_spi->unlock();
+            return data;                    
+        }        
+        if (_dev_i2c) return (uint8_t) _dev_i2c->i2c_write(pBuffer, _address, RegisterAddr, NumByteToWrite);    
+        return 1;
+    }
+
+  private:
+    int Set_ODR_When_Enabled(float odr);
+    int Set_ODR_When_Disabled(float odr);
+
+    /* Helper classes. */
+    DevI2C *_dev_i2c;
+    SPI    *_dev_spi;     
+    
+    /* Configuration */
+    uint8_t _address;
+    DigitalOut  _cs_pin; 
+    InterruptIn _int_pin;    
+    SPI_type_t _spi_type;    
+    
+    uint8_t _is_enabled;
+    float _last_odr;
+};
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+uint8_t LPS22HB_io_write( void *handle, uint8_t WriteAddr, uint8_t *pBuffer, uint16_t nBytesToWrite );
+uint8_t LPS22HB_io_read( void *handle, uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead );
+#ifdef __cplusplus
+  }
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/LPS22HB/LPS22HB_driver.c	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,1761 @@
+/**
+ *******************************************************************************
+ * @file    LPS22HB_driver.c
+ * @author  HESA Application Team
+ * @version V1.1
+ * @date    10-August-2016
+ * @brief   LPS22HB driver file
+ *******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "LPS22HB_driver.h"
+#ifdef  USE_FULL_ASSERT_LPS22HB
+#include <stdio.h>
+#endif
+
+/** @addtogroup Environmental_Sensor
+* @{
+*/
+
+/** @defgroup LPS22HB_DRIVER
+* @brief LPS22HB DRIVER
+* @{
+*/
+
+/** @defgroup LPS22HB_Imported_Function_Prototypes
+* @{
+*/
+
+extern uint8_t LPS22HB_io_write( void *handle, uint8_t WriteAddr, uint8_t *pBuffer, uint16_t nBytesToWrite );
+extern uint8_t LPS22HB_io_read( void *handle, uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead );
+
+/**
+* @}
+*/
+
+/** @defgroup LPS22HB_Private_Function_Prototypes
+* @{
+*/
+
+/**
+* @}
+*/
+
+/** @defgroup LPS22HB_Private_Functions
+* @{
+*/
+
+/**
+* @}
+*/
+
+/** @defgroup LPS22HB_Public_Functions
+* @{
+*/
+
+/*******************************************************************************
+* Function Name   : LPS22HB_read_reg
+* Description   : Generic Reading function. It must be fullfilled with either
+*         : I2C or SPI reading functions
+* Input       : Register Address
+* Output      : Data Read
+* Return      : None
+*******************************************************************************/
+LPS22HB_Error_et LPS22HB_read_reg( void *handle, uint8_t RegAddr, uint16_t NumByteToRead, uint8_t *Data )
+{
+
+  if ( LPS22HB_io_read( handle, RegAddr, Data, NumByteToRead ) )
+    return LPS22HB_ERROR;
+  else
+    return LPS22HB_OK;
+}
+
+/*******************************************************************************
+* Function Name   : LPS22HB_write_reg
+* Description   : Generic Writing function. It must be fullfilled with either
+*         : I2C or SPI writing function
+* Input       : Register Address, Data to be written
+* Output      : None
+* Return      : None
+*******************************************************************************/
+LPS22HB_Error_et LPS22HB_write_reg( void *handle, uint8_t RegAddr, uint16_t NumByteToWrite, uint8_t *Data )
+{
+
+  if ( LPS22HB_io_write( handle, RegAddr, Data, NumByteToWrite ) )
+    return LPS22HB_ERROR;
+  else
+    return LPS22HB_OK;
+}
+
+/**
+* @brief  Read identification code by WHO_AM_I register
+* @param  *handle Device handle.
+* @param  Buffer to empty by Device identification Value.
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_DeviceID(void *handle, uint8_t* deviceid)
+{
+  if(LPS22HB_read_reg(handle, LPS22HB_WHO_AM_I_REG, 1, deviceid))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+
+/**
+* @brief  Get the LPS22HB driver version.
+* @param  None
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_DriverVersion(LPS22HB_driverVersion_st *Version)
+{
+  Version->Major = LPS22HB_driverVersion_Major;
+  Version->Minor = LPS22HB_driverVersion_Minor;
+  Version->Point = LPS22HB_driverVersion_Point;
+
+  return LPS22HB_OK;
+}
+
+
+/**
+* @brief  Set LPS22HB Low Power or Low Noise Mode Configuration
+* @param  *handle Device handle.
+* @param  LPS22HB_LowNoise or LPS22HB_LowPower mode
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_PowerMode(void *handle, LPS22HB_PowerMode_et mode)
+{
+  uint8_t tmp;
+
+  LPS22HB_assert_param(IS_LPS22HB_PowerMode(mode));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_RES_CONF_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_LCEN_MASK;
+  tmp |= (uint8_t)mode;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_RES_CONF_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  Get LPS22HB Power Mode
+* @param  *handle Device handle.
+* @param   Buffer to empty with Mode: Low Noise or Low Current
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_PowerMode(void *handle, LPS22HB_PowerMode_et* mode)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_RES_CONF_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  *mode = (LPS22HB_PowerMode_et)(tmp & LPS22HB_LCEN_MASK);
+
+  return LPS22HB_OK;
+}
+
+
+/**
+* @brief  Set LPS22HB Output Data Rate
+* @param  *handle Device handle.
+* @param  Output Data Rate
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_Odr(void *handle, LPS22HB_Odr_et odr)
+{
+  uint8_t tmp;
+
+
+  LPS22HB_assert_param(IS_LPS22HB_ODR(odr));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG1, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_ODR_MASK;
+  tmp |= (uint8_t)odr;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG1, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  Get LPS22HB Output Data Rate
+* @param  *handle Device handle.
+* @param  Buffer to empty with Output Data Rate
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_Odr(void *handle, LPS22HB_Odr_et* odr)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG1, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  *odr = (LPS22HB_Odr_et)(tmp & LPS22HB_ODR_MASK);
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  Enable/Disale low-pass filter on LPS22HB pressure data
+* @param  *handle Device handle.
+* @param  state: enable or disable
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_LowPassFilter(void *handle, LPS22HB_State_et state)
+{
+  uint8_t tmp;
+
+  LPS22HB_assert_param(IS_LPS22HB_State(state));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG1, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_LPFP_MASK;
+  tmp |= ((uint8_t)state)<<LPS22HB_LPFP_BIT;
+
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG1, 1, &tmp))
+    return LPS22HB_ERROR;
+
+
+  return LPS22HB_OK;
+}
+
+
+/**
+* @brief  Set low-pass filter cutoff configuration on LPS22HB pressure data
+* @param  *handle Device handle.
+* @param  Filter Cutoff ODR/9 or ODR/20
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_LowPassFilterCutoff(void *handle, LPS22HB_LPF_Cutoff_et cutoff){
+
+  uint8_t tmp;
+
+  LPS22HB_assert_param(IS_LPS22HB_LPF_Cutoff(cutoff));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG1, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_LPFP_CUTOFF_MASK;
+  tmp |= (uint8_t)cutoff;
+
+
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG1, 1, &tmp))
+    return LPS22HB_ERROR;
+
+
+  return LPS22HB_OK;
+
+}
+
+/**
+* @brief  Set Block Data Mode
+* @detail It is recommended to set BDU bit to ‘1’.
+* @detail This feature avoids reading LSB and MSB related to different samples.
+* @param  *handle Device handle.
+* @param  LPS22HB_BDU_CONTINUOUS_UPDATE, LPS22HB_BDU_NO_UPDATE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+
+LPS22HB_Error_et LPS22HB_Set_Bdu(void *handle, LPS22HB_Bdu_et bdu)
+{
+  uint8_t tmp;
+
+
+  LPS22HB_assert_param(IS_LPS22HB_BDUMode(bdu));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG1, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_BDU_MASK;
+  tmp |= ((uint8_t)bdu);
+
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG1, 1, &tmp))
+  return LPS22HB_OK;
+
+   return LPS22HB_OK;
+}
+
+/**
+* @brief  Get Block Data Mode
+* @param  *handle Device handle.
+* @param Buffer to empty whit the bdu mode read from sensor
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_Bdu(void *handle, LPS22HB_Bdu_et* bdu)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG1, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  *bdu = (LPS22HB_Bdu_et)(tmp & LPS22HB_BDU_MASK);
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  Set SPI mode: 3 Wire Interface or 4 Wire Interface
+* @param  *handle Device handle.
+* @param LPS22HB_SPI_3_WIRE, LPS22HB_SPI_4_WIRE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_SpiInterface(void *handle, LPS22HB_SPIMode_et spimode)
+{
+  uint8_t tmp=0;  //deft LPS22HB_CTRL_REG1 value
+
+  LPS22HB_assert_param(IS_LPS22HB_SPIMode(spimode));
+
+/** FIXME could not read before setting SPI mode **/	
+//  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG1, 1, &tmp))
+//    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_SIM_MASK;
+  tmp |= (uint8_t)spimode;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG1, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  Clock Tree Configuration
+* @param  *handle Device handle.
+* @param  LPS22HB_CTE_NotBalanced, LPS22HB_CTE_ABalanced
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_ClockTreeConfifuration(void *handle, LPS22HB_CTE_et mode)
+{
+  uint8_t tmp;
+
+
+  LPS22HB_assert_param(IS_LPS22HB_CTE(mode));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CLOCK_TREE_CONFIGURATION, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_CTE_MASK;
+  tmp |= (uint8_t)mode;
+
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CLOCK_TREE_CONFIGURATION, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+
+/**
+* @brief  Get SPI mode: 3 Wire Interface or 4 Wire Interface
+* @param  *handle Device handle.
+* @param Buffet to empty with spi mode read from Sensor
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_SpiInterface(void *handle, LPS22HB_SPIMode_et* spimode)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG1, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  *spimode = (LPS22HB_SPIMode_et)(tmp & LPS22HB_SIM_MASK);
+
+  return LPS22HB_OK;
+}
+
+  /**
+* @brief   Software Reset. Self-clearing upon completion
+* @param  *handle Device handle.
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_SwReset(void *handle)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp |= (0x01<<LPS22HB_SW_RESET_BIT);
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  Reboot Memory Content
+* @param  *handle Device handle.
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+
+LPS22HB_Error_et LPS22HB_MemoryBoot(void *handle)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp |= (0x01<<LPS22HB_BOOT_BIT);
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief   Software Reset ann Reboot Memory Content.
+* @detail  The device is reset to the power on configuration if the SWRESET bit is set to ‘1’
+ + and BOOT is set to ‘1’; Self-clearing upon completion.
+* @param  *handle Device handle.
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_SwResetAndMemoryBoot(void *handle)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp |= ((0x01<<LPS22HB_SW_RESET_BIT) | (0x01<<LPS22HB_BOOT_BIT));
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+
+/**
+* @brief   Enable/Disable FIFO Mode
+* @param  *handle Device handle.
+* @param LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_FifoModeUse(void *handle, LPS22HB_State_et status)
+{
+  uint8_t tmp;
+
+  LPS22HB_assert_param(IS_LPS22HB_State(status));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_FIFO_EN_MASK;
+  tmp |= ((uint8_t)status)<<LPS22HB_FIFO_EN_BIT;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+/**
+* @brief   Enable/Disable FIFO Watermark Level Use
+* @param  *handle Device handle.
+* @param   LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_FifoWatermarkLevelUse(void *handle, LPS22HB_State_et status)
+{
+  uint8_t tmp;
+
+  LPS22HB_assert_param(IS_LPS22HB_State(status));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_WTM_EN_MASK;
+  tmp |= ((uint8_t)status)<<LPS22HB_WTM_EN_BIT;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+ /**
+* @brief  Enable or Disable the Automatic increment register address during a multiple byte access with a serial interface (I2C or SPI)
+* @param  *handle Device handle.
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE. Default is LPS22HB_ENABLE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_AutomaticIncrementRegAddress(void *handle, LPS22HB_State_et status){
+
+  uint8_t tmp;
+
+ LPS22HB_assert_param(IS_LPS22HB_State(status));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_ADD_INC_MASK;
+  tmp |= (((uint8_t)status)<<LPS22HB_ADD_INC_BIT);
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+
+}
+
+/**
+* @brief  Enable/Disable I2C Interface
+* @param  *handle Device handle.
+* @param State: LPS22HB_ENABLE (reset bit)/ LPS22HB_DISABLE (set bit)
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_I2C(void *handle, LPS22HB_State_et statei2c)
+{
+  uint8_t tmp;
+
+  LPS22HB_assert_param(IS_LPS22HB_State(statei2c));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  /*Reset Bit->I2C Enabled*/
+  tmp &= ~LPS22HB_I2C_MASK;
+  tmp|=((uint8_t)~statei2c)<<LPS22HB_I2C_BIT;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+
+/**
+* @brief   Set the one-shot bit in order to start acquisition when the ONE SHOT mode
+*          has been selected by the ODR configuration.
+* @detail  Once the measurement is done, ONE_SHOT bit will self-clear.
+* @param  *handle Device handle.
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_StartOneShotMeasurement(void *handle)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  /* Set the one shot bit */
+  /* Once the measurement is done, one shot bit will self-clear*/
+  tmp |= LPS22HB_ONE_SHOT_MASK;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+
+}
+
+/**
+* @brief  Set Interrupt Active on High or Low Level
+* @param  *handle Device handle.
+* @param  LPS22HB_ActiveHigh/LPS22HB_ActiveLow
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_InterruptActiveLevel(void *handle, LPS22HB_InterruptActiveLevel_et mode)
+{
+  uint8_t tmp;
+
+  LPS22HB_assert_param(IS_LPS22HB_InterruptActiveLevel(mode));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG3, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_INT_H_L_MASK;
+  tmp |= ((uint8_t)mode);
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG3, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+
+/**
+* @brief   Push-pull/open drain selection on interrupt pads. Default tmp: 0
+* @param  *handle Device handle.
+* @param   LPS22HB_PushPull/LPS22HB_OpenDrain
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_InterruptOutputType(void *handle, LPS22HB_OutputType_et output)
+{
+  uint8_t tmp;
+
+  LPS22HB_assert_param(IS_LPS22HB_OutputType(output));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG3, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_PP_OD_MASK;
+  tmp |= (uint8_t)output;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG3, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  Set Data signal on INT pad control bits.
+* @param  *handle Device handle.
+* @param  LPS22HB_DATA,LPS22HB_P_HIGH_LPS22HB_P_LOW,LPS22HB_P_LOW_HIGH
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_InterruptControlConfig(void *handle, LPS22HB_OutputSignalConfig_et config)
+{
+  uint8_t tmp;
+
+  LPS22HB_assert_param(IS_LPS22HB_OutputSignal(config));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG3, 1, &tmp))
+    return LPS22HB_ERROR;
+
+    tmp &= ~(LPS22HB_INT_S12_MASK);
+    tmp |= (uint8_t)config;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG3, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+
+/**
+* @brief   Enable/Disable Data-ready signal on INT_DRDY pin.
+* @param  *handle Device handle.
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_DRDYInterrupt(void *handle, LPS22HB_State_et status)
+{
+  uint8_t tmp;
+
+
+  LPS22HB_assert_param(IS_LPS22HB_State(status));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG3, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_DRDY_MASK;
+  tmp |= ((uint8_t)status)<<LPS22HB_DRDY_BIT;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG3, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+ /**
+* @brief   Enable/Disable FIFO overrun interrupt on INT_DRDY pin.
+* @param  *handle Device handle.
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_FIFO_OVR_Interrupt(void *handle, LPS22HB_State_et status)
+{
+  uint8_t tmp;
+
+
+  LPS22HB_assert_param(IS_LPS22HB_State(status));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG3, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_FIFO_OVR_MASK;
+  tmp |= ((uint8_t)status)<<LPS22HB_FIFO_OVR_BIT;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG3, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+ /**
+* @brief   Enable/Disable FIFO threshold (Watermark) interrupt on INT_DRDY pin.
+* @param  *handle Device handle.
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_FIFO_FTH_Interrupt(void *handle, LPS22HB_State_et status)
+{
+  uint8_t tmp;
+
+  LPS22HB_assert_param(IS_LPS22HB_State(status));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG3, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_FIFO_FTH_MASK;
+  tmp |= ((uint8_t)status)<<LPS22HB_FIFO_FTH_BIT;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG3, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief   Enable/Disable FIFO FULL interrupt on INT_DRDY pin.
+* @param  *handle Device handle.
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_FIFO_FULL_Interrupt(void *handle, LPS22HB_State_et status)
+{
+  uint8_t tmp;
+
+  LPS22HB_assert_param(IS_LPS22HB_State(status));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG3, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_FIFO_FULL_MASK;
+  tmp |= ((uint8_t)status)<<LPS22HB_FIFO_FULL_BIT;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_REG3, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+
+
+/**
+* @brief   Enable AutoRifP function
+* @detail When this function is enabled, an internal register is set with the current pressure values
+*         and the content is subtracted from the pressure output value and result is used for the interrupt generation.
+*               the AutoRifP is slf creared.
+* @param  *handle Device handle.
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_AutoRifP(void *handle)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp |= ((uint8_t)LPS22HB_AUTORIFP_MASK);
+
+  if(LPS22HB_write_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief   Disable AutoRifP function
+* @detail  the RESET_ARP bit is used to disable the AUTORIFP function. This bis i is selfdleared
+* @param  *handle Device handle.
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_ResetAutoRifP(void *handle)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+
+  tmp |= ((uint8_t)LPS22HB_RESET_ARP_MASK);
+
+  if(LPS22HB_write_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+
+/*
+* @brief  Set AutoZero Function bit
+* @detail When set to ‘1’, the actual pressure output is copied in the REF_P reg (@0x15..0x17)
+* @param  *handle Device handle.
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_AutoZeroFunction(void *handle)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp |= LPS22HB_AUTOZERO_MASK;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+
+/*
+* @brief  Set ResetAutoZero Function bit
+* @details REF_P reg (@0x015..17) set pressure reference to default value RPDS reg (0x18/19).
+* @param  *handle Device handle.
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_ResetAutoZeroFunction(void *handle)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  /* Set the RESET_AZ bit*/
+  /* RESET_AZ is self cleared*/
+  tmp |= LPS22HB_RESET_AZ_MASK;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+
+  return LPS22HB_OK;
+}
+
+
+/**
+* @brief  Enable/ Disable the computing of differential pressure output (Interrupt Generation)
+* @param  *handle Device handle.
+* @param  LPS22HB_ENABLE,LPS22HB_DISABLE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_InterruptDifferentialGeneration(void *handle, LPS22HB_State_et diff_en)
+{
+  uint8_t tmp;
+
+  LPS22HB_assert_param(IS_LPS22HB_State(diff_en));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_DIFF_EN_MASK;
+  tmp |= ((uint8_t)diff_en)<<LPS22HB_DIFF_EN_BIT;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+
+/**
+* @brief  Get the DIFF_EN bit value
+* @param  *handle Device handle.
+* @param  buffer to empty with the read value of DIFF_EN bit
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_InterruptDifferentialGeneration(void *handle, LPS22HB_State_et* diff_en)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  *diff_en= (LPS22HB_State_et)((tmp & LPS22HB_DIFF_EN_MASK)>>LPS22HB_DIFF_EN_BIT);
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  Latch Interrupt request to the INT_SOURCE register.
+* @param  *handle Device handle.
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_LatchInterruptRequest(void *handle, LPS22HB_State_et status)
+{
+  uint8_t tmp;
+
+ LPS22HB_assert_param(IS_LPS22HB_State(status));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_LIR_MASK;
+  tmp |= (((uint8_t)status)<<LPS22HB_LIR_BIT);
+
+  if(LPS22HB_write_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+
+
+  /**
+* @brief  Enable\Disable Interrupt Generation on differential pressure Low event
+* @param  *handle Device handle.
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_PLE(void *handle, LPS22HB_State_et status)
+{
+  uint8_t tmp;
+
+  LPS22HB_assert_param(IS_LPS22HB_State(status));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_PLE_MASK;
+  tmp |= (((uint8_t)status)<<LPS22HB_PLE_BIT);
+
+  if(LPS22HB_write_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  Enable\Disable Interrupt Generation on differential pressure High event
+* @param  *handle Device handle.
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_PHE(void *handle, LPS22HB_State_et status)
+{
+  uint8_t tmp;
+
+  LPS22HB_assert_param(IS_LPS22HB_State(status));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_PHE_MASK;
+  tmp |= (((uint8_t)status)<<LPS22HB_PHE_BIT);
+
+  if(LPS22HB_write_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief   Get the Interrupt Generation on differential pressure status event and the Boot Status.
+* @detail  The INT_SOURCE register is cleared by reading it.
+* @param  *handle Device handle.
+* @param   Status Event Flag: BOOT, PH,PL,IA
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_InterruptDifferentialEventStatus(void *handle, LPS22HB_InterruptDiffStatus_st* interruptsource)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_INTERRUPT_SOURCE_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  interruptsource->PH = (uint8_t)(tmp & LPS22HB_PH_MASK);
+  interruptsource->PL = (uint8_t)((tmp & LPS22HB_PL_MASK)>>LPS22HB_PL_BIT);
+  interruptsource->IA = (uint8_t)((tmp & LPS22HB_IA_MASK)>>LPS22HB_IA_BIT);
+  interruptsource->BOOT= (uint8_t)((tmp & LPS22HB_BOOT_STATUS_MASK)>>LPS22HB_BOOT_STATUS_BIT);
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  Get the status of Pressure and Temperature data
+* @param  *handle Device handle.
+* @param  Data Status Flag:  TempDataAvailable, TempDataOverrun, PressDataAvailable, PressDataOverrun
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_DataStatus(void *handle, LPS22HB_DataStatus_st* datastatus)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_STATUS_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  datastatus->PressDataAvailable = (uint8_t)(tmp & LPS22HB_PDA_MASK);
+  datastatus->TempDataAvailable = (uint8_t)((tmp & LPS22HB_TDA_MASK)>>LPS22HB_PDA_BIT);
+  datastatus->TempDataOverrun = (uint8_t)((tmp & LPS22HB_TOR_MASK)>>LPS22HB_TOR_BIT);
+  datastatus->PressDataOverrun = (uint8_t)((tmp & LPS22HB_POR_MASK)>>LPS22HB_POR_BIT);
+
+  return LPS22HB_OK;
+}
+
+
+
+/**
+* @brief  Get the LPS22HB raw presure value
+* @detail   The data are expressed as PRESS_OUT_H/_L/_XL in 2’s complement.
+            Pout(hPA)=PRESS_OUT / 4096
+* @param  *handle Device handle.
+* @param  The buffer to empty with the pressure raw value
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_RawPressure(void *handle, int32_t *raw_press)
+{
+  uint8_t buffer[3];
+  uint32_t tmp = 0;
+  uint8_t i;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_PRESS_OUT_XL_REG, 3, buffer))
+    return LPS22HB_ERROR;
+
+  /* Build the raw data */
+  for(i=0; i<3; i++)
+    tmp |= (((uint32_t)buffer[i]) << (8*i));
+
+  /* convert the 2's complement 24 bit to 2's complement 32 bit */
+  if(tmp & 0x00800000)
+    tmp |= 0xFF000000;
+
+  *raw_press = ((int32_t)tmp);
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief    Get the LPS22HB Pressure value in hPA.
+* @detail   The data are expressed as PRESS_OUT_H/_L/_XL in 2’s complement.
+            Pout(hPA)=PRESS_OUT / 4096
+* @param  *handle Device handle.
+* @param      The buffer to empty with the pressure value that must be divided by 100 to get the value in hPA
+* @retval   Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_Pressure(void *handle, int32_t* Pout)
+{
+  int32_t raw_press;
+
+  if(LPS22HB_Get_RawPressure(handle, &raw_press))
+    return LPS22HB_ERROR;
+
+  *Pout = (raw_press*100)/4096;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief    Get the Raw Temperature value.
+* @detail   Temperature data are expressed as TEMP_OUT_H&TEMP_OUT_L as 2’s complement number.
+*            Tout(degC)=TEMP_OUT/100
+* @param  *handle Device handle.
+* @param     Buffer to empty with the temperature raw tmp.
+* @retval   Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_RawTemperature(void *handle, int16_t* raw_data)
+{
+  uint8_t buffer[2];
+  uint16_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_TEMP_OUT_L_REG, 2, buffer))
+    return LPS22HB_ERROR;
+
+  /* Build the raw tmp */
+  tmp = (((uint16_t)buffer[1]) << 8) + (uint16_t)buffer[0];
+
+  *raw_data = ((int16_t)tmp);
+
+  return LPS22HB_OK;
+}
+
+
+/**
+* @brief    Get the Temperature value in °C.
+* @detail   Temperature data are expressed as TEMP_OUT_H&TEMP_OUT_L as 2’s complement number.
+*           Tout(degC)=TEMP_OUT/100
+* @param  *handle Device handle.
+* @param Buffer to empty with the temperature value that must be divided by 10 to get the value in °C
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_Temperature(void *handle, int16_t* Tout)
+{
+  int16_t raw_data;
+
+  if(LPS22HB_Get_RawTemperature(handle, &raw_data))
+    return LPS22HB_ERROR;
+
+  *Tout = (raw_data*10)/100;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief    Get the threshold value used for pressure interrupt generation (hPA).
+* @detail   THS_P=THS_P_H&THS_P_L and is expressed as unsigned number. P_ths(hPA)=(THS_P)/16.
+* @param  *handle Device handle.
+* @param    Buffer to empty with the pressure threshold in hPA
+* @retval   Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_PressureThreshold(void *handle, int16_t* P_ths)
+{
+  uint8_t tempReg[2];
+
+  if(LPS22HB_read_reg(handle, LPS22HB_THS_P_LOW_REG, 2, tempReg))
+    return LPS22HB_ERROR;
+
+  *P_ths= (((((uint16_t)tempReg[1])<<8) + tempReg[0])/16);
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief    Set the threshold value  used for pressure interrupt generation (hPA).
+* @detail   THS_P=THS_P_H&THS_P_L and is expressed as unsigned number. P_ths(hPA)=(THS_P)/16.
+* @param  *handle Device handle.
+* @param      Pressure threshold in hPA
+* @retval   Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_PressureThreshold(void *handle, int16_t P_ths)
+{
+  uint8_t buffer[2];
+
+  buffer[0] = (uint8_t)(16 * P_ths);
+  buffer[1] = (uint8_t)(((uint16_t)(16 * P_ths))>>8);
+
+  if(LPS22HB_write_reg(handle, LPS22HB_THS_P_LOW_REG, 2, buffer))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  Set Fifo Mode.
+* @param  *handle Device handle.
+* @param  Fifo Mode struct
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_FifoMode(void *handle, LPS22HB_FifoMode_et fifomode)
+{
+  uint8_t tmp;
+
+ LPS22HB_assert_param(IS_LPS22HB_FifoMode(fifomode));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_FIFO_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_FIFO_MODE_MASK;
+  tmp |= (uint8_t)fifomode;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_FIFO_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief    Get Fifo Mode
+* @param  *handle Device handle.
+* @param   buffer to empty with fifo mode tmp
+* @retval   Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_FifoMode(void *handle, LPS22HB_FifoMode_et* fifomode)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_FIFO_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= LPS22HB_FIFO_MODE_MASK;
+  *fifomode = (LPS22HB_FifoMode_et)tmp;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief    Set Fifo Watermark Level.
+* @param  *handle Device handle.
+* @param    Watermark level value [0 31]
+* @retval   Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_FifoWatermarkLevel(void *handle, uint8_t wtmlevel)
+{
+  uint8_t tmp;
+
+  LPS22HB_assert_param(IS_LPS22HB_WtmLevel(wtmlevel));
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_FIFO_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  tmp &= ~LPS22HB_WTM_POINT_MASK;
+  tmp |= wtmlevel;
+
+  if(LPS22HB_write_reg(handle, LPS22HB_CTRL_FIFO_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief   Get FIFO Watermark Level
+* @param  *handle Device handle.
+* @param   buffer to empty with watermak level[0,31] value read from sensor
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_FifoWatermarkLevel(void *handle, uint8_t *wtmlevel)
+{
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_FIFO_REG, 1, wtmlevel))
+    return LPS22HB_ERROR;
+
+  *wtmlevel &= LPS22HB_WTM_POINT_MASK;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief    Get the Fifo Status
+* @param  *handle Device handle.
+* @param    Status Flag: FIFO_FTH,FIFO_EMPTY,FIFO_FULL,FIFO_OVR and level of the FIFO->FIFO_LEVEL
+* @retval   Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_FifoStatus(void *handle, LPS22HB_FifoStatus_st* status)
+{
+  uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_STATUS_FIFO_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  status->FIFO_FTH = (uint8_t)((tmp & LPS22HB_FTH_FIFO_MASK)>>LPS22HB_FTH_FIFO_BIT);
+  status->FIFO_OVR=(uint8_t)((tmp & LPS22HB_OVR_FIFO_MASK)>>LPS22HB_OVR_FIFO_BIT);
+  status->FIFO_LEVEL = (uint8_t)(tmp & LPS22HB_LEVEL_FIFO_MASK);
+
+  if(status->FIFO_LEVEL ==LPS22HB_FIFO_EMPTY)
+    status->FIFO_EMPTY=0x01;
+  else
+    status->FIFO_EMPTY=0x00;
+
+  if (status->FIFO_LEVEL ==LPS22HB_FIFO_FULL)
+     status->FIFO_FULL=0x01;
+  else
+    status->FIFO_FULL=0x00;
+
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  Get the reference pressure after soldering for computing differential pressure (hPA)
+* @param  *handle Device handle.
+* @param buffer to empty with the he pressure value (hPA)
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_PressureOffsetValue(void *handle, int16_t *pressoffset)
+{
+  uint8_t buffer[2];
+  int16_t raw_press;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_RPDS_L_REG, 2, buffer))
+    return LPS22HB_ERROR;
+
+  raw_press = (int16_t)((((uint16_t)buffer[1]) << 8) + (uint16_t)buffer[0]);
+
+  *pressoffset = (raw_press*100)/4096;
+
+  return LPS22HB_OK;
+}
+
+
+/**
+* @brief  Get the Reference Pressure value
+* @detail  It is a 24-bit data added to the sensor output measurement to detect a measured pressure beyond programmed limits.
+* @param  *handle Device handle.
+* @param  Buffer to empty with reference pressure value
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_ReferencePressure(void *handle, int32_t* RefP)
+{
+  uint8_t buffer[3];
+  uint32_t tempVal=0;
+  int32_t raw_press;
+  uint8_t i;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_REF_P_XL_REG, 3, buffer))
+    return LPS22HB_ERROR;
+
+  /* Build the raw data */
+  for(i=0; i<3; i++)
+    tempVal |= (((uint32_t)buffer[i]) << (8*i));
+
+  /* convert the 2's complement 24 bit to 2's complement 32 bit */
+  if(tempVal & 0x00800000)
+    tempVal |= 0xFF000000;
+
+  raw_press =((int32_t)tempVal);
+  *RefP = (raw_press*100)/4096;
+
+
+  return LPS22HB_OK;
+}
+
+
+/**
+* @brief  Check if the single measurement has completed.
+* @param  *handle Device handle.
+* @param  the returned value is set to 1, when the measurement is completed
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_IsMeasurementCompleted(void *handle, uint8_t* Is_Measurement_Completed)
+{
+  uint8_t tmp;
+  LPS22HB_DataStatus_st datastatus;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_STATUS_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  datastatus.TempDataAvailable=(uint8_t)((tmp&LPS22HB_TDA_MASK)>>LPS22HB_TDA_BIT);
+  datastatus.PressDataAvailable= (uint8_t)(tmp&LPS22HB_PDA_MASK);
+
+  *Is_Measurement_Completed=(uint8_t)((datastatus.PressDataAvailable) & (datastatus.TempDataAvailable));
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  Get the values of the last single measurement.
+* @param  *handle Device handle.
+* @param  Pressure and temperature tmp
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_Measurement(void *handle, LPS22HB_MeasureTypeDef_st *Measurement_Value)
+{
+  int16_t Tout;
+  int32_t Pout;
+
+  if(LPS22HB_Get_Temperature(handle, &Tout))
+    return LPS22HB_ERROR;
+
+  Measurement_Value->Tout=Tout;
+
+  if(LPS22HB_Get_Pressure(handle, &Pout))
+    return LPS22HB_ERROR;
+
+  Measurement_Value->Pout=Pout;
+
+  return LPS22HB_OK;
+
+}
+
+/**
+* @brief  Initialization function for LPS22HB.
+*         This function make a memory boot.
+*         Init the sensor with a standard basic confifuration.
+*         Low Power, ODR 25 Hz, Low Pass Filter disabled; BDU enabled; I2C enabled;
+*        NO FIFO; NO Interrupt Enabled.
+* @param  *handle Device handle.
+* @retval Error code[LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Init(void *handle)
+{
+  LPS22HB_ConfigTypeDef_st pLPS22HBInit;
+
+  /* Make LPS22HB Reset and Reboot */
+  if(LPS22HB_SwResetAndMemoryBoot(handle))
+    return LPS22HB_ERROR;
+
+ pLPS22HBInit.PowerMode=LPS22HB_LowPower;
+ pLPS22HBInit.OutputDataRate=LPS22HB_ODR_25HZ;
+ pLPS22HBInit.LowPassFilter=LPS22HB_DISABLE;
+ pLPS22HBInit.LPF_Cutoff=LPS22HB_ODR_9;
+ pLPS22HBInit.BDU=LPS22HB_BDU_NO_UPDATE;
+ pLPS22HBInit.IfAddInc=LPS22HB_ENABLE; //default
+ pLPS22HBInit.Sim= LPS22HB_SPI_4_WIRE;
+
+ /* Set Generic Configuration*/
+ if(LPS22HB_Set_GenericConfig(handle, &pLPS22HBInit))
+   return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  De initialization function for LPS22HB.
+*         This function make a memory boot and clear the data output flags.
+* @param  *handle Device handle.
+* @retval Error code[LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_DeInit(void *handle)
+{
+  LPS22HB_MeasureTypeDef_st Measurement_Value;
+
+  /* Make LPS22HB Reset and Reboot */
+  if(LPS22HB_SwResetAndMemoryBoot(handle))
+    return LPS22HB_ERROR;
+
+  /* Dump of data output */
+  if(LPS22HB_Get_Measurement(handle, &Measurement_Value))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+
+/**
+* @brief   Set Generic Configuration
+* @param  *handle Device handle.
+* @param   Struct to empty with the chosen values
+* @retval  Error code[LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_GenericConfig(void *handle, LPS22HB_ConfigTypeDef_st* pxLPS22HBInit)
+{
+
+  /* Enable Low Current Mode (low Power) or Low Noise Mode*/
+   if(LPS22HB_Set_PowerMode(handle, pxLPS22HBInit->PowerMode))
+    return LPS22HB_ERROR;
+
+  /* Init the Output Data Rate*/
+  if(LPS22HB_Set_Odr(handle, pxLPS22HBInit->OutputDataRate))
+    return LPS22HB_ERROR;
+
+  /* BDU bit is used to inhibit the output registers update between the reading of upper and
+  lower register parts. In default mode (BDU = ‘0’), the lower and upper register parts are
+  updated continuously. If it is not sure to read faster than output data rate, it is recommended
+  to set BDU bit to ‘1’. In this way, after the reading of the lower (upper) register part, the
+  content of that output registers is not updated until the upper (lower) part is read too.
+  This feature avoids reading LSB and MSB related to different samples.*/
+
+  if(LPS22HB_Set_Bdu(handle, pxLPS22HBInit->BDU))
+    return LPS22HB_ERROR;
+
+  /*Enable/Disale low-pass filter on LPS22HB pressure data*/
+  if(LPS22HB_Set_LowPassFilter(handle, pxLPS22HBInit->LowPassFilter))
+    return LPS22HB_ERROR;
+
+   /* Set low-pass filter cutoff configuration*/
+  if(LPS22HB_Set_LowPassFilterCutoff(handle, pxLPS22HBInit->LPF_Cutoff))
+    return LPS22HB_ERROR;
+
+  /* SIM bit selects the SPI serial interface mode.*/
+  /* This feature has effect only if SPI interface is used*/
+
+    if(LPS22HB_Set_SpiInterface(handle, pxLPS22HBInit->Sim))
+    return LPS22HB_ERROR;
+
+  /*Enable or Disable the Automatic increment register address during a multiple byte access with a serial interface (I2C or SPI)*/
+  if(LPS22HB_Set_AutomaticIncrementRegAddress(handle, pxLPS22HBInit->IfAddInc))
+    return LPS22HB_ERROR;
+
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  Get Generic configuration
+* @param  *handle Device handle.
+* @param  Struct to empty with configuration values
+* @retval Error code[LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_GenericConfig(void *handle, LPS22HB_ConfigTypeDef_st* pxLPS22HBInit)
+{
+
+  uint8_t tmp;
+
+  /*Read LPS22HB_RES_CONF_REG*/
+ if(LPS22HB_Get_PowerMode(handle, &pxLPS22HBInit->PowerMode))
+   return LPS22HB_ERROR;
+
+  /*Read LPS22HB_CTRL_REG1*/
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG1, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  pxLPS22HBInit->OutputDataRate= (LPS22HB_Odr_et)(tmp & LPS22HB_ODR_MASK);
+  pxLPS22HBInit->BDU=(LPS22HB_Bdu_et)(tmp & LPS22HB_BDU_MASK);
+  pxLPS22HBInit->Sim=(LPS22HB_SPIMode_et)(tmp& LPS22HB_SIM_MASK);
+  pxLPS22HBInit->LowPassFilter=(LPS22HB_State_et)((tmp& LPS22HB_LPFP_MASK)>>LPS22HB_LPFP_BIT);
+  pxLPS22HBInit->LPF_Cutoff=(LPS22HB_LPF_Cutoff_et)(tmp& LPS22HB_LPFP_CUTOFF_MASK);
+
+  /*Read LPS22HB_CTRL_REG2*/
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  pxLPS22HBInit->IfAddInc=(LPS22HB_State_et)((tmp& LPS22HB_ADD_INC_MASK)>>LPS22HB_ADD_INC_BIT);
+
+  return LPS22HB_OK;
+}
+
+
+/**
+* @brief  Set Interrupt configuration
+* @param  *handle Device handle.
+* @param  Struct holding the configuration values
+* @retval  Error code[LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_InterruptConfig(void *handle, LPS22HB_InterruptTypeDef_st* pLPS22HBInt)
+{
+  /* Enable Low Current Mode (low Power) or Low Noise Mode*/
+   if(LPS22HB_Set_InterruptActiveLevel(handle, pLPS22HBInt->INT_H_L))
+    return LPS22HB_ERROR;
+
+   /* Push-pull/open drain selection on interrupt pads.*/
+   if(LPS22HB_Set_InterruptOutputType(handle, pLPS22HBInt->PP_OD))
+    return LPS22HB_ERROR;
+
+   /* Set Data signal on INT pad control bits.*/
+   if(LPS22HB_Set_InterruptControlConfig(handle, pLPS22HBInt->OutputSignal_INT))
+    return LPS22HB_ERROR;
+
+   /* Enable/Disable Data-ready signal on INT_DRDY pin. */
+   if(LPS22HB_Set_DRDYInterrupt(handle, pLPS22HBInt->DRDY))
+    return LPS22HB_ERROR;
+
+    /* Enable/Disable FIFO overrun interrupt on INT_DRDY pin. */
+   if(LPS22HB_Set_FIFO_OVR_Interrupt(handle, pLPS22HBInt->FIFO_OVR))
+    return LPS22HB_ERROR;
+
+   /* Enable/Disable FIFO Treshold interrupt on INT_DRDY pin. */
+   if(LPS22HB_Set_FIFO_FTH_Interrupt(handle, pLPS22HBInt->FIFO_FTH))
+    return LPS22HB_ERROR;
+
+   /* Enable/Disable FIFO FULL interrupt on INT_DRDY pin. */
+   if(LPS22HB_Set_FIFO_FULL_Interrupt(handle, pLPS22HBInt->FIFO_FULL))
+    return LPS22HB_ERROR;
+
+  /* Latch Interrupt request to the INT_SOURCE register. */
+    if(LPS22HB_LatchInterruptRequest(handle, pLPS22HBInt->LatchIRQ))
+      return LPS22HB_ERROR;
+
+    /* Set the threshold value  used for pressure interrupt generation (hPA). */
+   if(LPS22HB_Set_PressureThreshold(handle, pLPS22HBInt->THS_threshold))
+      return LPS22HB_ERROR;
+
+   /*Enable/Disable  AutoRifP function */
+  if(pLPS22HBInt->AutoRifP==LPS22HB_ENABLE){
+    if(LPS22HB_Set_AutoRifP(handle))
+      return LPS22HB_ERROR;
+  }
+  else{
+    if(LPS22HB_ResetAutoRifP(handle))
+      return LPS22HB_ERROR;
+  }
+
+  /*Enable/Disable AutoZero function*/
+  if(pLPS22HBInt->AutoZero==LPS22HB_ENABLE){
+    if(LPS22HB_Set_AutoZeroFunction(handle))
+      return LPS22HB_ERROR;
+  }
+  else{
+    if(LPS22HB_ResetAutoZeroFunction(handle))
+      return LPS22HB_ERROR;
+  }
+
+
+   if(pLPS22HBInt->OutputSignal_INT==LPS22HB_P_HIGH)
+   {
+    /* Enable\Disable Interrupt Generation on differential pressure high event*/
+      if(LPS22HB_Set_PHE(handle, LPS22HB_ENABLE))
+        return LPS22HB_ERROR;
+       if(LPS22HB_Set_InterruptDifferentialGeneration(handle, LPS22HB_ENABLE))
+          return LPS22HB_ERROR;
+   }
+   else  if(pLPS22HBInt->OutputSignal_INT==LPS22HB_P_LOW)
+      {
+    /* Enable Interrupt Generation on differential pressure Loe event*/
+      if(LPS22HB_Set_PLE(handle, LPS22HB_ENABLE))
+        return LPS22HB_ERROR;
+       if(LPS22HB_Set_InterruptDifferentialGeneration(handle, LPS22HB_ENABLE))
+          return LPS22HB_ERROR;
+   }
+    else  if(pLPS22HBInt->OutputSignal_INT==LPS22HB_P_LOW_HIGH)
+    {
+      /* Enable Interrupt Generation on differential pressure high event*/
+      if(LPS22HB_Set_PHE(handle, LPS22HB_ENABLE))
+        return LPS22HB_ERROR;
+    /* Enable\Disable Interrupt Generation on differential pressure Loe event*/
+      if(LPS22HB_Set_PLE(handle, LPS22HB_ENABLE))
+        return LPS22HB_ERROR;
+       if(LPS22HB_Set_InterruptDifferentialGeneration(handle, LPS22HB_ENABLE))
+          return LPS22HB_ERROR;
+   }
+   else
+   {
+      if(LPS22HB_Set_InterruptDifferentialGeneration(handle, LPS22HB_DISABLE))
+          return LPS22HB_ERROR;
+      /* Disable Interrupt Generation on differential pressure High event*/
+      if(LPS22HB_Set_PHE(handle, LPS22HB_DISABLE))
+        return LPS22HB_ERROR;
+     /* Disable Interrupt Generation on differential pressure Low event*/
+      if(LPS22HB_Set_PLE(handle, LPS22HB_DISABLE))
+        return LPS22HB_ERROR;
+   }
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  LPS22HBGet_InterruptConfig
+* @param  *handle Device handle.
+* @param  Struct to empty with configuration values
+* @retval S Error code[LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_InterruptConfig(void *handle, LPS22HB_InterruptTypeDef_st* pLPS22HBInt)
+{
+   uint8_t tmp;
+
+  /*Read LPS22HB_CTRL_REG3*/
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG3, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  pLPS22HBInt->INT_H_L= (LPS22HB_InterruptActiveLevel_et)(tmp & LPS22HB_INT_H_L_MASK);
+  pLPS22HBInt->PP_OD=(LPS22HB_OutputType_et)(tmp & LPS22HB_PP_OD_MASK);
+  pLPS22HBInt->OutputSignal_INT=(LPS22HB_OutputSignalConfig_et)(tmp& LPS22HB_INT_S12_MASK);
+  pLPS22HBInt->DRDY=(LPS22HB_State_et)((tmp& LPS22HB_DRDY_MASK)>>LPS22HB_DRDY_BIT);
+  pLPS22HBInt->FIFO_OVR=(LPS22HB_State_et)((tmp& LPS22HB_FIFO_OVR_MASK)>>LPS22HB_FIFO_OVR_BIT);
+  pLPS22HBInt->FIFO_FTH=(LPS22HB_State_et)((tmp& LPS22HB_FIFO_FTH_MASK)>>LPS22HB_FIFO_FTH_BIT);
+  pLPS22HBInt->FIFO_FULL=(LPS22HB_State_et)((tmp& LPS22HB_FIFO_FULL_MASK)>>LPS22HB_FIFO_FULL_BIT);
+
+  /*Read LPS22HB_INTERRUPT_CFG_REG*/
+  if(LPS22HB_read_reg(handle, LPS22HB_INTERRUPT_CFG_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  pLPS22HBInt->LatchIRQ= (LPS22HB_State_et)((tmp& LPS22HB_LIR_MASK)>>LPS22HB_LIR_BIT);
+
+  if(LPS22HB_Get_PressureThreshold(handle, &pLPS22HBInt->THS_threshold))
+    return LPS22HB_ERROR;
+
+  //AutoRifP and Autozero are self clear //
+  pLPS22HBInt->AutoRifP=LPS22HB_DISABLE;
+  pLPS22HBInt->AutoZero=LPS22HB_DISABLE;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  Set Fifo configuration
+* @param  *handle Device handle.
+* @param  Struct holding the configuration values
+* @retval  Error code[LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_FifoConfig(void *handle, LPS22HB_FIFOTypeDef_st* pLPS22HBFIFO)
+{
+
+   if(pLPS22HBFIFO->FIFO_MODE == LPS22HB_FIFO_BYPASS_MODE) {
+    /* FIFO Disable-> FIFO_EN bit=0 in CTRL_REG2*/
+    if(LPS22HB_Set_FifoModeUse(handle, LPS22HB_DISABLE))
+      return LPS22HB_ERROR;
+    /* Force->Disable FIFO Watermark Level Use*/
+     if(LPS22HB_Set_FifoWatermarkLevelUse(handle, LPS22HB_DISABLE))
+          return LPS22HB_ERROR;
+
+    /* Force->Disable FIFO Treshold interrupt on INT_DRDY pin. */
+     if(LPS22HB_Set_FIFO_FTH_Interrupt(handle, LPS22HB_DISABLE))
+            return LPS22HB_ERROR;
+  }
+  else {
+    /* FIFO Enable-> FIFO_EN bit=1 in CTRL_REG2*/
+    if(LPS22HB_Set_FifoModeUse(handle, LPS22HB_ENABLE))
+      return LPS22HB_ERROR;
+
+      if (pLPS22HBFIFO->WTM_INT){
+        /* Enable FIFO Watermark Level Use*/
+        if(LPS22HB_Set_FifoWatermarkLevelUse(handle, LPS22HB_ENABLE))
+          return LPS22HB_ERROR;
+        /*Set Fifo Watermark Level*/
+        if(LPS22HB_Set_FifoWatermarkLevel(handle, pLPS22HBFIFO->WTM_LEVEL))
+          return LPS22HB_ERROR;
+        /* Force->enable FIFO Treshold interrupt on INT_DRDY pin. */
+        if(LPS22HB_Set_FIFO_FTH_Interrupt(handle, LPS22HB_ENABLE))
+            return LPS22HB_ERROR;
+      }
+  }
+
+  if(LPS22HB_Set_FifoMode(handle, pLPS22HBFIFO->FIFO_MODE))
+    return LPS22HB_ERROR;
+
+  return LPS22HB_OK;
+}
+
+/**
+* @brief  Get Fifo configuration
+* @param  *handle Device handle.
+* @param  Struct to empty with the configuration values
+* @retval Error code[LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_FifoConfig(void *handle, LPS22HB_FIFOTypeDef_st* pLPS22HBFIFO)
+{
+   uint8_t tmp;
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_FIFO_REG, 1, &tmp))
+    return LPS22HB_ERROR;
+
+  /*!< Fifo Mode Selection */
+  pLPS22HBFIFO->FIFO_MODE= (LPS22HB_FifoMode_et)(tmp& LPS22HB_FIFO_MODE_MASK);
+
+  /*!< FIFO threshold/Watermark level selection*/
+  pLPS22HBFIFO->WTM_LEVEL= (uint8_t)(tmp& LPS22HB_WTM_POINT_MASK);
+
+  if(LPS22HB_read_reg(handle, LPS22HB_CTRL_REG2, 1, &tmp))
+    return LPS22HB_ERROR;
+
+   /*!< Enable/Disable the watermark interrupt*/
+  pLPS22HBFIFO->WTM_INT= (LPS22HB_State_et)((tmp& LPS22HB_WTM_EN_MASK)>>LPS22HB_WTM_EN_BIT);
+
+
+  return LPS22HB_OK;
+}
+
+#ifdef  USE_FULL_ASSERT_LPS22HB
+/**
+* @brief  Reports the name of the source file and the source line number
+*         where the assert_param error has occurred.
+* @param file: pointer to the source file name
+* @param line: assert_param error line source number
+* @retval : None
+*/
+void LPS22HB_assert_failed(uint8_t* file, uint32_t line)
+{
+  /* User can add his own implementation to report the file name and line number */
+  printf("Wrong parameters tmp: file %s on line %d\r\n", file, (int)line);
+
+  /* Infinite loop */
+  while (1)
+  {
+  }
+}
+#endif
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/LPS22HB/LPS22HB_driver.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,1305 @@
+/**
+ ******************************************************************************
+ * @file    LPS22HB_driver.h
+ * @author  HESA Application Team
+ * @version V1.1
+ * @date    10-August-2016
+ * @brief   LPS22HB driver header file
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LPS22HB_DRIVER__H
+#define __LPS22HB_DRIVER__H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// the user must include the proper file where HAL_read_reg and HAL_write_reg are implemented
+//#include "HAL_EnvSensors.h"
+
+/* Uncomment the line below to expanse the "assert_param" macro in the  drivers code */
+//#define USE_FULL_ASSERT_LPS22HB
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef  USE_FULL_ASSERT_LPS22HB
+
+/**
+* @brief  The assert_param macro is used for function's parameters check.
+* @param  expr: If expr is false, it calls assert_failed function which reports
+*         the name of the source file and the source line number of the call
+*         that failed. If expr is true, it returns no value.
+* @retval None
+*/
+#define LPS22HB_assert_param(expr) ((expr) ? (void)0 : LPS22HB_assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+void LPS22HB_assert_failed(uint8_t* file, uint32_t line);
+#else
+#define LPS22HB_assert_param(expr) ((void)0)
+#endif /* USE_FULL_ASSERT_LPS22HB */
+
+  /** @addtogroup Environmental_Sensor
+  * @{
+  */
+
+  /** @addtogroup LPS22HB_DRIVER
+  * @{
+  */
+
+  /* Exported Types -------------------------------------------------------------*/
+  /** @defgroup LPS22HB_Exported_Types
+  * @{
+  */
+
+  /**
+  * @brief  Error type.
+  */
+  typedef enum {LPS22HB_OK = (uint8_t)0, LPS22HB_ERROR = !LPS22HB_OK} LPS22HB_Error_et;
+
+  /**
+  * @brief  Enable/Disable type.
+  */
+  typedef enum {LPS22HB_DISABLE = (uint8_t)0, LPS22HB_ENABLE = !LPS22HB_DISABLE} LPS22HB_State_et;
+#define IS_LPS22HB_State(MODE) ((MODE == LPS22HB_ENABLE) || (MODE == LPS22HB_DISABLE) )
+
+  /**
+  * @brief  Bit status type.
+  */
+  typedef enum {LPS22HB_RESET = (uint8_t)0, LPS22HB_SET = !LPS22HB_RESET} LPS22HB_BitStatus_et;
+#define IS_LPS22HB_BitStatus(MODE) ((MODE == LPS22HB_RESET) || (MODE == LPS22HB_SET))
+
+  /*RES_CONF see LC_EN bit*/
+ /**
+* @brief  LPS22HB Power/Noise Mode configuration.
+*/
+typedef enum {
+  LPS22HB_LowNoise   =  (uint8_t)0x00,       /*!< Low Noise mode */
+  LPS22HB_LowPower   =  (uint8_t)0x01        /*!< Low Current mode */
+} LPS22HB_PowerMode_et;
+
+#define IS_LPS22HB_PowerMode(MODE) ((MODE == LPS22HB_LowNoise) || (MODE == LPS22HB_LowPower))
+
+/**
+* @brief  Output data rate configuration.
+*/
+typedef enum {
+
+  LPS22HB_ODR_ONE_SHOT  = (uint8_t)0x00,         /*!< Output Data Rate: one shot */
+  LPS22HB_ODR_1HZ       = (uint8_t)0x10,         /*!< Output Data Rate: 1Hz */
+  LPS22HB_ODR_10HZ       = (uint8_t)0x20,         /*!< Output Data Rate: 10Hz */
+  LPS22HB_ODR_25HZ    = (uint8_t)0x30,         /*!< Output Data Rate: 25Hz */
+  LPS22HB_ODR_50HZ      = (uint8_t)0x40,          /*!< Output Data Rate: 50Hz */
+  LPS22HB_ODR_75HZ      = (uint8_t)0x50          /*!< Output Data Rate: 75Hz */
+} LPS22HB_Odr_et;
+
+#define IS_LPS22HB_ODR(ODR) ((ODR == LPS22HB_ODR_ONE_SHOT) || (ODR == LPS22HB_ODR_1HZ) || \
+(ODR == LPS22HB_ODR_10HZ) || (ODR == LPS22HB_ODR_25HZ)|| (ODR == LPS22HB_ODR_50HZ) || (ODR == LPS22HB_ODR_75HZ))
+
+/**
+* @brief  Low Pass Filter Cutoff Configuration.
+*/
+typedef enum {
+
+  LPS22HB_ODR_9  = (uint8_t)0x00,         /*!< Filter Cutoff ODR/9 */
+  LPS22HB_ODR_20 = (uint8_t)0x04          /*!< Filter Cutoff ODR/20 */
+} LPS22HB_LPF_Cutoff_et;
+
+#define IS_LPS22HB_LPF_Cutoff(CUTOFF) ((CUTOFF == LPS22HB_ODR_9) || (CUTOFF == LPS22HB_ODR_20) )
+
+/**
+* @brief  Block data update.
+*/
+
+typedef enum {
+  LPS22HB_BDU_CONTINUOUS_UPDATE     =  (uint8_t)0x00,  /*!< Data updated continuously */
+  LPS22HB_BDU_NO_UPDATE             =  (uint8_t)0x02   /*!< Data updated after a read operation */
+} LPS22HB_Bdu_et;
+#define IS_LPS22HB_BDUMode(MODE) ((MODE == LPS22HB_BDU_CONTINUOUS_UPDATE) || (MODE == LPS22HB_BDU_NO_UPDATE))
+
+/**
+* @brief  LPS22HB Spi Mode configuration.
+*/
+typedef enum {
+  LPS22HB_SPI_4_WIRE   =  (uint8_t)0x00,
+  LPS22HB_SPI_3_WIRE   =  (uint8_t)0x01
+} LPS22HB_SPIMode_et;
+
+#define IS_LPS22HB_SPIMode(MODE) ((MODE == LPS22HB_SPI_4_WIRE) || (MODE == LPS22HB_SPI_3_WIRE))
+
+
+/**
+* @brief  LPS22HB Interrupt Active Level Configuration (on High or Low)
+*/
+typedef enum
+{
+  LPS22HB_ActiveHigh = (uint8_t)0x00,
+  LPS22HB_ActiveLow  = (uint8_t)0x80
+}LPS22HB_InterruptActiveLevel_et;
+#define IS_LPS22HB_InterruptActiveLevel(MODE) ((MODE == LPS22HB_ActiveHigh) || (MODE == LPS22HB_ActiveLow))
+
+/**
+* @brief  LPS22HB Push-pull/Open Drain selection on Interrupt pads.
+*/
+typedef enum
+{
+  LPS22HB_PushPull = (uint8_t)0x00,
+  LPS22HB_OpenDrain  = (uint8_t)0x40
+}LPS22HB_OutputType_et;
+#define IS_LPS22HB_OutputType(MODE) ((MODE == LPS22HB_PushPull) || (MODE == LPS22HB_OpenDrain))
+
+
+/**
+* @brief  Data Signal on INT pad control bits.
+*/
+typedef enum
+{
+  LPS22HB_DATA = (uint8_t)0x00,
+  LPS22HB_P_HIGH = (uint8_t)0x01,
+  LPS22HB_P_LOW = (uint8_t)0x02,
+  LPS22HB_P_LOW_HIGH = (uint8_t)0x03
+}LPS22HB_OutputSignalConfig_et;
+#define IS_LPS22HB_OutputSignal(MODE) ((MODE == LPS22HB_DATA) || (MODE == LPS22HB_P_HIGH)||\
+(MODE == LPS22HB_P_LOW) || (MODE == LPS22HB_P_LOW_HIGH))
+
+
+
+/**
+* @brief  LPS22HB Interrupt Differential Status.
+*/
+
+typedef struct
+{
+  uint8_t PH;          /*!< High Differential Pressure event occured */
+  uint8_t PL;          /*!< Low Differential Pressure event occured */
+  uint8_t IA;          /*!< One or more interrupt events have been  generated.Interrupt Active */
+  uint8_t BOOT;        /*!< i '1' indicates that the Boot (Reboot) phase is running */
+}LPS22HB_InterruptDiffStatus_st;
+
+
+/**
+* @brief  LPS22HB Pressure and Temperature data status.
+*/
+typedef struct
+{
+  uint8_t TempDataAvailable;           /*!< Temperature data available bit */
+  uint8_t PressDataAvailable;          /*!< Pressure data available bit */
+  uint8_t TempDataOverrun;             /*!< Temperature data over-run bit */
+  uint8_t PressDataOverrun;            /*!< Pressure data over-run bit */
+}LPS22HB_DataStatus_st;
+
+
+/**
+* @brief  LPS22HB Clock Tree  configuration.
+*/
+typedef enum {
+  LPS22HB_CTE_NotBalanced   =  (uint8_t)0x00,
+  LPS22HB_CTE_Balanced   =  (uint8_t)0x20
+} LPS22HB_CTE_et;
+
+#define IS_LPS22HB_CTE(MODE) ((MODE == LPS22HB_CTE_NotBalanced) || (MODE == LPS22HB_CTE_Balanced))
+
+/**
+* @brief  LPS22HB Fifo Mode.
+*/
+
+typedef enum {
+  LPS22HB_FIFO_BYPASS_MODE                    = (uint8_t)0x00,    /*!< The FIFO is disabled and empty. The pressure is read directly*/
+  LPS22HB_FIFO_MODE                           = (uint8_t)0x20,    /*!< Stops collecting data when full */
+  LPS22HB_FIFO_STREAM_MODE                    = (uint8_t)0x40,    /*!< Keep the newest measurements in the FIFO*/
+  LPS22HB_FIFO_TRIGGER_STREAMTOFIFO_MODE      = (uint8_t)0x60,    /*!< STREAM MODE until trigger deasserted, then change to FIFO MODE*/
+  LPS22HB_FIFO_TRIGGER_BYPASSTOSTREAM_MODE    = (uint8_t)0x80,    /*!< BYPASS MODE until trigger deasserted, then STREAM MODE*/
+  LPS22HB_FIFO_TRIGGER_BYPASSTOFIFO_MODE      = (uint8_t)0xE0     /*!< BYPASS mode until trigger deasserted, then FIFO MODE*/
+} LPS22HB_FifoMode_et;
+
+#define IS_LPS22HB_FifoMode(MODE) ((MODE == LPS22HB_FIFO_BYPASS_MODE) || (MODE ==LPS22HB_FIFO_MODE)||\
+(MODE == LPS22HB_FIFO_STREAM_MODE) || (MODE == LPS22HB_FIFO_TRIGGER_STREAMTOFIFO_MODE)||\
+  (MODE == LPS22HB_FIFO_TRIGGER_BYPASSTOSTREAM_MODE) ||  (MODE == LPS22HB_FIFO_TRIGGER_BYPASSTOFIFO_MODE))
+
+
+/**
+* @brief  LPS22HB Fifo Satus.
+*/
+typedef struct {
+  uint8_t FIFO_LEVEL;          /*!< FIFO Stored data level: 00000: FIFO empty; 10000: FIFO is FULL and ha 32 unread samples  */
+  uint8_t FIFO_EMPTY;          /*!< Empty FIFO Flag .1 FIFO is empty (see FIFO_level)   */
+  uint8_t FIFO_FULL;          /*!< Full FIFO flag.1 FIFO is Full (see FIFO_level)   */
+  uint8_t FIFO_OVR;           /*!< Overrun bit status. 1 FIFO is full and at least one sample in the FIFO has been overwritten */
+  uint8_t FIFO_FTH;            /*!< FIFO Threshold (Watermark) Status. 1 FIFO filling is equal or higher then FTH (wtm) level.*/
+}LPS22HB_FifoStatus_st;
+
+
+
+/**
+* @brief  LPS22HB Configuration structure definition.
+*/
+typedef struct
+{
+  LPS22HB_PowerMode_et   PowerMode;                    /*!< Enable Low Current Mode (low Power) or Low Noise Mode*/
+  LPS22HB_Odr_et         OutputDataRate;                /*!< Output Data Rate */
+  LPS22HB_Bdu_et         BDU;                           /*!< Enable to inhibit the output registers update between the reading of upper and lower register parts.*/
+  LPS22HB_State_et       LowPassFilter;             /*!< Enable/ Disable Low Pass Filter */
+  LPS22HB_LPF_Cutoff_et  LPF_Cutoff;                    /*!< Low Pass Filter Configuration */
+  LPS22HB_SPIMode_et     Sim;                   /*!< SPI Serial Interface Mode selection */
+  LPS22HB_State_et       IfAddInc;                       /*!< Enable/Disable Register address automatically inceremented during a multiple byte access */
+}LPS22HB_ConfigTypeDef_st;
+
+
+  /**
+* @brief  LPS22HB Interrupt structure definition .
+*/
+typedef struct {
+  LPS22HB_InterruptActiveLevel_et       INT_H_L;                /*!< Interrupt active high, low. Default value: 0 */
+  LPS22HB_OutputType_et             PP_OD;              /*!< Push-pull/open drain selection on interrupt pads. Default value: 0 */
+  LPS22HB_OutputSignalConfig_et         OutputSignal_INT;   /*!< Data signal on INT Pad: Data,Pressure High, Preessure Low,P High or Low*/
+  LPS22HB_State_et                              DRDY;                   /*!< Enable/Disable Data Ready Interrupt on INT_DRDY Pin*/
+  LPS22HB_State_et                              FIFO_OVR;                /*!< Enable/Disable FIFO Overrun Interrupt on INT_DRDY Pin*/
+  LPS22HB_State_et                              FIFO_FTH;                /*!< Enable/Disable FIFO threshold (Watermark) interrupt on INT_DRDY pin.*/
+  LPS22HB_State_et                              FIFO_FULL;               /*!< Enable/Disable FIFO FULL interrupt on INT_DRDY pin.*/
+  LPS22HB_State_et              LatchIRQ;       /*!< Latch Interrupt request in to INT_SOURCE reg*/
+  int16_t                   THS_threshold;      /*!< Threshold value for pressure interrupt generation*/
+  LPS22HB_State_et       AutoRifP;                                      /*!< Enable/Disable  AutoRifP function */
+  LPS22HB_State_et       AutoZero;                                      /*!< Enable/Disable  AutoZero function */
+}LPS22HB_InterruptTypeDef_st;
+
+/**
+* @brief  LPS22HB FIFO structure definition.
+*/
+typedef struct {
+  LPS22HB_FifoMode_et           FIFO_MODE;               /*!< Fifo Mode Selection */
+  LPS22HB_State_et          WTM_INT;        /*!< Enable/Disable the watermark interrupt*/
+  uint8_t               WTM_LEVEL;      /*!< FIFO threshold/Watermark level selection*/
+}LPS22HB_FIFOTypeDef_st;
+
+#define IS_LPS22HB_WtmLevel(LEVEL) ((LEVEL > 0) && (LEVEL <=31))
+/**
+* @brief  LPS22HB Measure Type definition.
+*/
+typedef struct {
+  int16_t Tout;
+  int32_t Pout;
+}LPS22HB_MeasureTypeDef_st;
+
+
+/**
+* @brief  LPS22HB Driver Version Info structure definition.
+*/
+typedef struct {
+  uint8_t   Major;
+  uint8_t   Minor;
+  uint8_t Point;
+}LPS22HB_driverVersion_st;
+
+
+/**
+* @brief  Bitfield positioning.
+*/
+#define LPS22HB_BIT(x) ((uint8_t)x)
+
+/**
+* @brief  I2C address.
+*/
+/* SD0/SA0(pin 5) is connected to the voltage supply */
+#define LPS22HB_ADDRESS_HIGH     0xBA  /**< LPS22HB I2C Address High */
+/* SDO/SA0 (pin5) is connected to the GND */
+#define LPS22HB_ADDRESS_LOW      0xB8  /**< LPS22HB I2C Address Low */
+
+/**
+* @brief  Set the LPS22HB driver version.
+*/
+
+#define LPS22HB_driverVersion_Major (uint8_t)1
+#define LPS22HB_driverVersion_Minor (uint8_t)0
+#define LPS22HB_driverVersion_Point (uint8_t)0
+
+/**
+* @}
+*/
+
+
+/* Exported Constants ---------------------------------------------------------*/
+/** @defgroup LPS22HB_Exported_Constants
+* @{
+*/
+
+
+/**
+* @addtogroup LPS22HB_Register
+* @{
+*/
+
+
+
+/**
+* @brief Device Identification register.
+* \code
+* Read
+* Default value: 0xB1
+* 7:0 This read-only register contains the device identifier that, for LPS22HB, is set to B1h.
+* \endcode
+*/
+
+#define LPS22HB_WHO_AM_I_REG         (uint8_t)0x0F
+
+/**
+* @brief Device Identification value.
+*/
+#define LPS22HB_WHO_AM_I_VAL         (uint8_t)0xB1
+
+
+/**
+* @brief Reference Pressure  Register(LSB data)
+* \code
+* Read/write
+* Default value: 0x00
+* 7:0 REFL7-0: Lower part of the reference pressure value that
+*      is sum to the sensor output pressure.
+* \endcode
+*/
+#define LPS22HB_REF_P_XL_REG         (uint8_t)0x15
+
+
+/**
+* @brief Reference Pressure Register (Middle data)
+* \code
+* Read/write
+* Default value: 0x00
+* 7:0 REFL15-8: Middle part of the reference pressure value that
+*      is sum to the sensor output pressure.
+* \endcode
+*/
+#define LPS22HB_REF_P_L_REG          (uint8_t)0x16
+
+/**
+* @brief Reference Pressure Register (MSB data)
+* \code
+* Read/write
+* Default value: 0x00
+* 7:0 REFL23-16 Higest part of the reference pressure value that
+*      is sum to the sensor output pressure.
+* \endcode
+*/
+#define LPS22HB_REF_P_H_REG          (uint8_t)0x17
+
+
+/**
+* @brief Pressure and temperature resolution mode Register
+* \code
+* Read/write
+* Default value: 0x05
+* 7:2 These bits must be set to 0 for proper operation of the device
+* 1: Reserved
+* 0 LC_EN: Low Current Mode Enable. Default 0
+* \endcode
+*/
+#define LPS22HB_RES_CONF_REG     (uint8_t)0x1A
+
+#define LPS22HB_LCEN_MASK        (uint8_t)0x01
+
+/**
+* @brief Control Register 1
+* \code
+* Read/write
+* Default value: 0x00
+* 7: This bit must be set to 0 for proper operation of the device
+* 6:4 ODR2, ODR1, ODR0: output data rate selection.Default 000
+*     ODR2  | ODR1  | ODR0  | Pressure output data-rate(Hz)  | Pressure output data-rate(Hz)
+*   ----------------------------------------------------------------------------------
+*      0    |  0    |  0    |         one shot               |         one shot
+*      0    |  0    |  1    |            1                   |            1
+*      0    |  1    |  0    |            10                  |           10
+*      0    |  1    |  1    |            25                  |           25
+*      1    |  0    |  0    |            50                  |           50
+*      1    |  0    |  1    |            75                  |         75
+*      1    |  1    |  0    |         Reserved               |         Reserved
+*      1    |  1    |  1    |         Reserved               |         Reserved
+*
+* 3 EN_LPFP: Enable Low Pass filter on Pressure data. Default value:0
+* 2:LPF_CFG Low-pass configuration register. (0: Filter cutoff is ODR/9; 1: filter cutoff is ODR/20)
+* 1 BDU: block data update. 0 - continuous update; 1 - output registers not updated until MSB and LSB reading.
+* 0 SIM: SPI Serial Interface Mode selection. 0 - SPI 4-wire; 1 - SPI 3-wire
+* \endcode
+*/
+#define LPS22HB_CTRL_REG1      (uint8_t)0x10
+
+#define LPS22HB_ODR_MASK                (uint8_t)0x70
+#define LPS22HB_LPFP_MASK               (uint8_t)0x08
+#define LPS22HB_LPFP_CUTOFF_MASK        (uint8_t)0x04
+#define LPS22HB_BDU_MASK                (uint8_t)0x02
+#define LPS22HB_SIM_MASK                (uint8_t)0x01
+
+#define LPS22HB_LPFP_BIT    LPS22HB_BIT(3)
+
+
+/**
+* @brief Control  Register 2
+* \code
+* Read/write
+* Default value: 0x10
+* 7 BOOT:  Reboot memory content. 0: normal mode; 1: reboot memory content. Self-clearing upon completation
+* 6 FIFO_EN: FIFO Enable. 0: disable; 1:  enable
+* 5 STOP_ON_FTH: Stop on FIFO Threshold  FIFO Watermark level use. 0: disable; 1: enable
+* 4 IF_ADD_INC: Register address automatically incrementeed during a multiple byte access with a serial interface (I2C or SPI). Default value 1.( 0: disable; 1: enable)
+* 3 I2C DIS:  Disable I2C interface 0: I2C Enabled; 1: I2C disabled
+* 2 SWRESET: Software reset. 0: normal mode; 1: SW reset. Self-clearing upon completation
+* 1 AUTO_ZERO: Autozero enable. 0: normal mode; 1: autozero enable.
+* 0 ONE_SHOT: One shot enable. 0: waiting for start of conversion; 1: start for a new dataset
+* \endcode
+*/
+#define LPS22HB_CTRL_REG2      (uint8_t)0x11
+
+#define LPS22HB_BOOT_BIT       LPS22HB_BIT(7)
+#define LPS22HB_FIFO_EN_BIT    LPS22HB_BIT(6)
+#define LPS22HB_WTM_EN_BIT     LPS22HB_BIT(5)
+#define LPS22HB_ADD_INC_BIT    LPS22HB_BIT(4)
+#define LPS22HB_I2C_BIT        LPS22HB_BIT(3)
+#define LPS22HB_SW_RESET_BIT   LPS22HB_BIT(2)
+
+#define LPS22HB_FIFO_EN_MASK   (uint8_t)0x40
+#define LPS22HB_WTM_EN_MASK    (uint8_t)0x20
+#define LPS22HB_ADD_INC_MASK   (uint8_t)0x10
+#define LPS22HB_I2C_MASK       (uint8_t)0x08
+#define LPS22HB_ONE_SHOT_MASK  (uint8_t)0x01
+
+
+/**
+* @brief CTRL Reg3 Interrupt Control Register
+* \code
+* Read/write
+* Default value: 0x00
+* 7 INT_H_L: Interrupt active high, low. 0:active high; 1: active low.
+* 6 PP_OD: Push-Pull/OpenDrain selection on interrupt pads. 0: Push-pull; 1: open drain.
+* 5 F_FSS5: FIFO full flag on INT_DRDY pin. Defaul value: 0. (0: Diasable; 1 : Enable).
+* 4 F_FTH: FIFO threshold (watermark) status on INT_DRDY pin. Defaul value: 0. (0: Diasable; 1 : Enable).
+* 3 F_OVR: FIFO overrun interrupt on INT_DRDY pin. Defaul value: 0. (0: Diasable; 1 : Enable).
+* 2 DRDY: Data-ready signal on INT_DRDY pin. Defaul value: 0. (0: Diasable; 1 : Enable).
+* 1:0 INT_S2, INT_S1: data signal on INT pad control bits.
+*    INT_S2  | INT_S1  | INT pin
+*   ------------------------------------------------------
+*        0       |      0      |     Data signal( in order of priority:PTH_DRDY or F_FTH or F_OVR_or F_FSS5
+*        0       |      1      |     Pressure high (P_high)
+*        1       |      0      |     Pressure low (P_low)
+*        1       |      1      |     P_low OR P_high
+* \endcode
+*/
+#define LPS22HB_CTRL_REG3      (uint8_t)0x12
+
+#define LPS22HB_PP_OD_BIT       LPS22HB_BIT(6)
+#define LPS22HB_FIFO_FULL_BIT   LPS22HB_BIT(5)
+#define LPS22HB_FIFO_FTH_BIT    LPS22HB_BIT(4)
+#define LPS22HB_FIFO_OVR_BIT    LPS22HB_BIT(3)
+#define LPS22HB_DRDY_BIT        LPS22HB_BIT(2)
+
+
+#define LPS22HB_INT_H_L_MASK            (uint8_t)0x80
+#define LPS22HB_PP_OD_MASK              (uint8_t)0x40
+#define LPS22HB_FIFO_FULL_MASK          (uint8_t)0x20
+#define LPS22HB_FIFO_FTH_MASK           (uint8_t)0x10
+#define LPS22HB_FIFO_OVR_MASK           (uint8_t)0x08
+#define LPS22HB_DRDY_MASK               (uint8_t)0x04
+#define LPS22HB_INT_S12_MASK            (uint8_t)0x03
+
+
+/**
+* @brief Interrupt Differential configuration Register
+* \code
+* Read/write
+* Default value: 0x00.
+* 7 AUTORIFP: AutoRifP Enable ??
+* 6 RESET_ARP: Reset AutoRifP function
+* 4 AUTOZERO: Autozero enabled
+* 5 RESET_AZ: Reset Autozero Function
+* 3 DIFF_EN: Interrupt generation enable
+* 2 LIR: Latch Interrupt request into INT_SOURCE register. 0 - interrupt request not latched; 1 - interrupt request latched
+* 1 PL_E: Enable interrupt generation on differential pressure low event. 0 - disable; 1 - enable
+* 0 PH_E: Enable interrupt generation on differential pressure high event. 0 - disable; 1 - enable
+* \endcode
+*/
+#define LPS22HB_INTERRUPT_CFG_REG  (uint8_t)0x0B
+
+#define LPS22HB_DIFF_EN_BIT       LPS22HB_BIT(3)
+#define LPS22HB_LIR_BIT           LPS22HB_BIT(2)
+#define LPS22HB_PLE_BIT           LPS22HB_BIT(1)
+#define LPS22HB_PHE_BIT           LPS22HB_BIT(0)
+
+#define LPS22HB_AUTORIFP_MASK     (uint8_t)0x80
+#define LPS22HB_RESET_ARP_MASK    (uint8_t)0x40
+#define LPS22HB_AUTOZERO_MASK     (uint8_t)0x20
+#define LPS22HB_RESET_AZ_MASK     (uint8_t)0x10
+#define LPS22HB_DIFF_EN_MASK      (uint8_t)0x08
+#define LPS22HB_LIR_MASK          (uint8_t)0x04
+#define LPS22HB_PLE_MASK          (uint8_t)0x02
+#define LPS22HB_PHE_MASK          (uint8_t)0x01
+
+
+
+/**
+* @brief Interrupt source Register (It is cleared by reading it)
+* \code
+* Read
+* Default value: ----.
+* 7 BOOT_STATUS:  If 1 indicates that the Boot (Reboot) phase is running.
+* 6:3 Reserved: Keep these bits at 0
+* 2 IA: Interrupt Active.0: no interrupt has been generated; 1: one or more interrupt events have been generated.
+* 1 PL: Differential pressure Low. 0: no interrupt has been generated; 1: Low differential pressure event has occurred.
+* 0 PH: Differential pressure High. 0: no interrupt has been generated; 1: High differential pressure event has occurred.
+* \endcode
+*/
+#define LPS22HB_INTERRUPT_SOURCE_REG   (uint8_t)0x25
+
+#define LPS22HB_BOOT_STATUS_BIT        LPS22HB_BIT(7)
+#define LPS22HB_IA_BIT                 LPS22HB_BIT(2)
+#define LPS22HB_PL_BIT                 LPS22HB_BIT(1)
+#define LPS22HB_PH_BIT                 LPS22HB_BIT(0)
+
+#define LPS22HB_BOOT_STATUS_MASK      (uint8_t)0x80
+#define LPS22HB_IA_MASK               (uint8_t)0x04
+#define LPS22HB_PL_MASK               (uint8_t)0x02
+#define LPS22HB_PH_MASK               (uint8_t)0x01
+
+
+/**
+* @brief  Status Register
+* \code
+* Read
+* Default value: ---
+* 7:6 Reserved: 0
+* 5 T_OR: Temperature data overrun. 0: no overrun has occurred; 1: a new data for temperature has overwritten the previous one.
+* 4 P_OR: Pressure data overrun. 0: no overrun has occurred; 1: new data for pressure has overwritten the previous one.
+* 3:2 Reserved: 0
+* 1 T_DA: Temperature data available. 0: new data for temperature is not yet available; 1: new data for temperature is available.
+* 0 P_DA: Pressure data available. 0: new data for pressure is not yet available; 1: new data for pressure is available.
+* \endcode
+*/
+#define LPS22HB_STATUS_REG         (uint8_t)0x27
+
+#define LPS22HB_TOR_BIT            LPS22HB_BIT(5)
+#define LPS22HB_POR_BIT            LPS22HB_BIT(4)
+#define LPS22HB_TDA_BIT            LPS22HB_BIT(1)
+#define LPS22HB_PDA_BIT            LPS22HB_BIT(0)
+
+#define LPS22HB_TOR_MASK           (uint8_t)0x20
+#define LPS22HB_POR_MASK           (uint8_t)0x10
+#define LPS22HB_TDA_MASK           (uint8_t)0x02
+#define LPS22HB_PDA_MASK           (uint8_t)0x01
+
+
+
+/**
+* @brief  Pressure data (LSB) register.
+* \code
+* Read
+* Default value: 0x00.(To be verified)
+* POUT7 - POUT0: Pressure data LSB (2's complement).
+* Pressure output data: Pout(hPA)=(PRESS_OUT_H & PRESS_OUT_L &
+* PRESS_OUT_XL)[dec]/4096.
+* \endcode
+*/
+
+#define LPS22HB_PRESS_OUT_XL_REG        (uint8_t)0x28
+/**
+* @brief  Pressure data (Middle part) register.
+* \code
+* Read
+* Default value: 0x80.
+* POUT15 - POUT8: Pressure data middle part (2's complement).
+* Pressure output data: Pout(hPA)=(PRESS_OUT_H & PRESS_OUT_L &
+* PRESS_OUT_XL)[dec]/4096.
+* \endcode
+*/
+#define LPS22HB_PRESS_OUT_L_REG        (uint8_t)0x29
+
+/**
+* @brief  Pressure data (MSB) register.
+* \code
+* Read
+* Default value: 0x2F.
+* POUT23 - POUT16: Pressure data MSB (2's complement).
+* Pressure output data: Pout(hPA)=(PRESS_OUT_H & PRESS_OUT_L &
+* PRESS_OUT_XL)[dec]/4096.
+* \endcode
+*/
+#define LPS22HB_PRESS_OUT_H_REG        (uint8_t)0x2A
+
+/**
+* @brief  Temperature data (LSB) register.
+* \code
+* Read
+* Default value: 0x00.
+* TOUT7 - TOUT0: temperature data LSB.
+* Tout(degC)=TEMP_OUT/100
+* \endcode
+*/
+#define LPS22HB_TEMP_OUT_L_REG         (uint8_t)0x2B
+
+/**
+* @brief  Temperature data (MSB) register.
+* \code
+* Read
+* Default value: 0x00.
+* TOUT15 - TOUT8: temperature data MSB.
+* Tout(degC)=TEMP_OUT/100
+* \endcode
+*/
+#define LPS22HBH_TEMP_OUT_H_REG         (uint8_t)0x2C
+
+/**
+* @brief Threshold pressure (LSB) register.
+* \code
+* Read/write
+* Default value: 0x00.
+* 7:0 THS7-THS0: LSB Threshold pressure Low part of threshold value for pressure interrupt
+* generation. The complete threshold value is given by THS_P_H & THS_P_L and is
+* expressed as unsigned number. P_ths(hPA)=(THS_P_H & THS_P_L)[dec]/16.
+* \endcode
+*/
+#define LPS22HB_THS_P_LOW_REG           (uint8_t)0x0C
+
+/**
+* @brief Threshold pressure (MSB)
+* \code
+* Read/write
+* Default value: 0x00.
+* 7:0 THS15-THS8: MSB Threshold pressure. High part of threshold value for pressure interrupt
+* generation. The complete threshold value is given by THS_P_H & THS_P_L and is
+* expressed as unsigned number. P_ths(mbar)=(THS_P_H & THS_P_L)[dec]/16.
+* \endcode
+*/
+#define LPS22HB_THS_P_HIGH_REG         (uint8_t)0x0D
+
+/**
+* @brief FIFO control register
+* \code
+* Read/write
+* Default value: 0x00
+* 7:5 F_MODE2, F_MODE1, F_MODE0: FIFO mode selection.
+*     FM2   | FM1   | FM0   |    FIFO MODE
+*   ---------------------------------------------------
+*      0    |  0    |  0    | BYPASS MODE
+*      0    |  0    |  1    | FIFO MODE. Stops collecting data when full
+*      0    |  1    |  0    | STREAM MODE: Keep the newest measurements in the FIFO
+*      0    |  1    |  1    | STREAM MODE until trigger deasserted, then change to FIFO MODE
+*      1    |  0    |  0    | BYPASS MODE until trigger deasserted, then STREAM MODE
+*      1    |  0    |  1    | Reserved for future use
+*      1    |  1    |  0    | Reserved
+*      1    |  1    |  1    | BYPASS mode until trigger deasserted, then FIFO MODE
+*
+* 4:0 WTM_POINT4-0 : FIFO Watermark level selection (0-31)
+*/
+#define LPS22HB_CTRL_FIFO_REG          (uint8_t)0x14
+
+#define LPS22HB_FIFO_MODE_MASK        (uint8_t)0xE0
+#define LPS22HB_WTM_POINT_MASK        (uint8_t)0x1F
+
+
+/**
+* @brief FIFO Status register
+* \code
+* Read
+* Default value: ----
+* 7 FTH_FIFO: FIFO threshold status. 0:FIFO filling is lower than FTH level; 1: FIFO is equal or higher than FTH level.
+* 6 OVR: Overrun bit status. 0 - FIFO not full; 1 -FIFO is full and at least one sample in the FIFO has been overwritten.
+* 5:0 FSS: FIFO Stored data level. 000000: FIFO empty, 100000: FIFO is full and has 32 unread samples.
+* \endcode
+*/
+#define LPS22HB_STATUS_FIFO_REG        (uint8_t)0x26
+
+#define LPS22HB_FTH_FIFO_BIT          LPS22HB_BIT(7)
+#define LPS22HB_OVR_FIFO_BIT          LPS22HB_BIT(6)
+
+#define LPS22HB_FTH_FIFO_MASK         (uint8_t)0x80
+#define LPS22HB_OVR_FIFO_MASK         (uint8_t)0x40
+#define LPS22HB_LEVEL_FIFO_MASK       (uint8_t)0x3F
+#define LPS22HB_FIFO_EMPTY            (uint8_t)0x00
+#define LPS22HB_FIFO_FULL             (uint8_t)0x20
+
+
+
+/**
+* @brief Pressure offset register  (LSB)
+* \code
+* Read/write
+* Default value: 0x00
+* 7:0 RPDS7-0:Pressure Offset for 1 point calibration (OPC) after soldering.
+* This register contains the low part of the pressure offset value after soldering,for
+* differential pressure computing. The complete value is given by RPDS_L & RPDS_H
+* and is expressed as signed 2 complement value.
+* \endcode
+*/
+#define LPS22HB_RPDS_L_REG        (uint8_t)0x18
+
+/**
+* @brief Pressure offset register (MSB)
+* \code
+* Read/write
+* Default value: 0x00
+* 7:0 RPDS15-8:Pressure Offset for 1 point calibration  (OPC) after soldering.
+* This register contains the high part of the pressure offset value after soldering (see description RPDS_L)
+* \endcode
+*/
+#define LPS22HB_RPDS_H_REG        (uint8_t)0x19
+
+
+/**
+* @brief Clock Tree Configuration register
+* \code
+* Read/write
+* Default value: 0x00
+* 7:6 Reserved.
+* 5: CTE: Clock Tree Enhancement
+* \endcode
+*/
+
+#define LPS22HB_CLOCK_TREE_CONFIGURATION        (uint8_t)0x43
+
+#define LPS22HB_CTE_MASK           (uint8_t)0x20
+
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+
+/* Exported Functions -------------------------------------------------------------*/
+/** @defgroup LPS22HB_Exported_Functions
+* @{
+*/
+
+LPS22HB_Error_et LPS22HB_read_reg( void *handle, uint8_t RegAddr, uint16_t NumByteToRead, uint8_t *Data );
+LPS22HB_Error_et LPS22HB_write_reg( void *handle, uint8_t RegAddr, uint16_t NumByteToWrite, uint8_t *Data );
+
+/**
+* @brief  Init the HAL layer.
+* @param  None
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+#define LPS22HB_HalInit  (LPS22HB_Error_et)HAL_Init_I2C
+
+/**
+* @brief  DeInit the HAL layer.
+* @param  None
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+#define LPS22HB_HalDeInit  (LPS22HB_Error_et)HAL_DeInit_I2C
+
+
+/**
+* @brief  Get the LPS22HB driver version.
+* @param  None
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_DriverVersion(LPS22HB_driverVersion_st *Version);
+
+/**
+* @brief  Initialization function for LPS22HB.
+*         This function make a memory boot.
+*         Init the sensor with a standard basic confifuration.
+*         Low Power, ODR 25 Hz, Low Pass Filter disabled; BDU enabled; I2C enabled;
+*         NO FIFO; NO Interrupt Enabled.
+* @param  None.
+* @retval Error code[LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Init(void *handle);
+
+/**
+* @brief  DeInit the LPS2Hb driver.
+* @param  None
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+
+LPS22HB_Error_et LPS22HB_DeInit(void *handle);
+
+
+/**
+* @brief  Read identification code by WHO_AM_I register
+* @param  Buffer to empty by Device identification Value.
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_DeviceID(void *handle, uint8_t* deviceid);
+
+
+/**
+* @brief  Set LPS22HB Low Power or Low Noise Mode Configuration
+* @param  LPS22HB_LowNoise or LPS22HB_LowPower mode
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_PowerMode(void *handle, LPS22HB_PowerMode_et mode);
+
+/**
+* @brief  Get LPS22HB Power Mode
+* @param   Buffer to empty with Mode: Low Noise or Low Current
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_PowerMode(void *handle, LPS22HB_PowerMode_et* mode);
+
+
+/**
+* @brief  Set LPS22HB Output Data Rate
+* @param  Output Data Rate
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_Odr(void *handle, LPS22HB_Odr_et odr);
+
+
+/**
+* @brief  Get LPS22HB Output Data Rate
+* @param  Buffer to empty with Output Data Rate
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_Odr(void *handle, LPS22HB_Odr_et* odr);
+
+/**
+* @brief  Enable/Disale low-pass filter on LPS22HB pressure data
+* @param  state: enable or disable
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_LowPassFilter(void *handle, LPS22HB_State_et state);
+
+
+/**
+* @brief  Set low-pass filter cutoff configuration on LPS22HB pressure data
+* @param Filter Cutoff ODR/9 or ODR/20
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_LowPassFilterCutoff(void *handle, LPS22HB_LPF_Cutoff_et cutoff);
+
+/**
+* @brief  Set Block Data Update mode
+* @param  LPS22HB_BDU_CONTINUOS_UPDATE/ LPS22HB_BDU_NO_UPDATE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_Bdu(void *handle, LPS22HB_Bdu_et bdu);
+
+
+/**
+* @brief  Get Block Data Update mode
+* @param  Buffer to empty whit the bdu mode read from sensor
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_Bdu(void *handle, LPS22HB_Bdu_et* bdu);
+
+/**
+* @brief  Set SPI mode: 3 Wire Interface OR 4 Wire Interface
+* @param  LPS22HB_SPI_4_WIRE/LPS22HB_SPI_3_WIRE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_SpiInterface(void *handle, LPS22HB_SPIMode_et spimode);
+
+/**
+* @brief  Get SPI mode: 3 Wire Interface OR 4 Wire Interface
+* @param  buffer to empty with SPI mode
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_SpiInterface(void *handle, LPS22HB_SPIMode_et* spimode);
+
+/**
+* @brief Software Reset
+* @param  void
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_SwReset(void *handle);
+
+/**
+* @brief Reboot Memory Content.
+* @param  void
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_MemoryBoot(void *handle);
+
+/**
+* @brief Software Reset ann BOOT
+* @param  void
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_SwResetAndMemoryBoot(void *handle);
+
+
+/**
+* @brief  Enable or Disable FIFO
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_FifoModeUse(void *handle, LPS22HB_State_et status);
+
+/**
+* @brief  Enable or Disable FIFO Watermark level use. Stop on FIFO Threshold
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_FifoWatermarkLevelUse(void *handle, LPS22HB_State_et status);
+
+/**
+* @brief  Enable or Disable the Automatic increment register address during a multiple byte access with a serial interface (I2C or SPI)
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE. Default is LPS22HB_ENABLE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_AutomaticIncrementRegAddress(void *handle, LPS22HB_State_et status);
+
+
+/**
+* @brief  Set One Shot bit to start a new conversion (ODR mode has to be 000)
+* @param  void
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_StartOneShotMeasurement(void *handle);
+
+/**
+* @brief  Enable/Disable I2C
+* @param  State. Enable (reset bit)/ Disable (set bit)
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_I2C(void *handle, LPS22HB_State_et i2cstate);
+
+
+/*CTRL_REG3 Interrupt Control*/
+/**
+* @brief  Set Interrupt Active on High or Low Level
+* @param  LPS22HB_ActiveHigh/LPS22HB_ActiveLow
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_InterruptActiveLevel(void *handle, LPS22HB_InterruptActiveLevel_et mode);
+
+/**
+* @brief  Set Push-pull/open drain selection on interrupt pads.
+* @param  LPS22HB_PushPull/LPS22HB_OpenDrain
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_InterruptOutputType(void *handle, LPS22HB_OutputType_et output);
+
+/**
+* @brief  Set Data signal on INT1 pad control bits.
+* @param  LPS22HB_DATA,LPS22HB_P_HIGH_LPS22HB_P_LOW,LPS22HB_P_LOW_HIGH
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_InterruptControlConfig(void *handle, LPS22HB_OutputSignalConfig_et config);
+
+
+/**
+* @brief   Enable/Disable Data-ready signal on INT_DRDY pin.
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_DRDYInterrupt(void *handle, LPS22HB_State_et status);
+
+ /**
+* @brief   Enable/Disable FIFO overrun interrupt on INT_DRDY pin.
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_FIFO_OVR_Interrupt(void *handle, LPS22HB_State_et status);
+
+ /**
+* @brief   Enable/Disable FIFO threshold (Watermark) interrupt on INT_DRDY pin.
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_FIFO_FTH_Interrupt(void *handle, LPS22HB_State_et status);
+
+/**
+* @brief   Enable/Disable FIFO FULL interrupt on INT_DRDY pin.
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_FIFO_FULL_Interrupt(void *handle, LPS22HB_State_et status);
+
+/**
+* @brief   Enable AutoRifP function
+* @param   none
+* @detail When this function is enabled, an internal register is set with the current pressure values
+*         and the content is subtracted from the pressure output value and result is used for the interrupt generation.
+*        the AutoRifP is slf creared.
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_AutoRifP(void *handle);
+
+/**
+* @brief   Disable AutoRifP
+* @param   none
+* @detail  the RESET_ARP bit is used to disable the AUTORIFP function. This bis i is selfdleared
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_ResetAutoRifP(void *handle);
+
+/**?????
+* @brief  Set AutoZero Function bit
+* @detail When set to ‘1’, the actual pressure output is copied in the REF_P reg (@0x15..0x17)
+* @param  None
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_AutoZeroFunction(void *handle);
+
+/**???
+* @brief  Set ResetAutoZero Function bit
+* @details REF_P reg (@0x015..17) set pressure reference to default value RPDS reg (0x18/19).
+* @param  None
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_ResetAutoZeroFunction(void *handle);
+
+
+/**
+* @brief  Enable/ Disable the computing of differential pressure output (Interrupt Generation)
+* @param  LPS22HB_ENABLE,LPS22HB_DISABLE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_InterruptDifferentialGeneration(void *handle, LPS22HB_State_et diff_en) ;
+
+
+
+/**
+* @brief  Get the DIFF_EN bit value
+* @param  buffer to empty with the read value of DIFF_EN bit
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_InterruptDifferentialGeneration(void *handle, LPS22HB_State_et* diff_en);
+
+
+/**
+* @brief  Latch Interrupt request to the INT_SOURCE register.
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_LatchInterruptRequest(void *handle, LPS22HB_State_et status);
+
+/**
+* @brief  Enable\Disable Interrupt Generation on differential pressure Low event
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_PLE(void *handle, LPS22HB_State_et status);
+
+/**
+* @brief  Enable\Disable Interrupt Generation on differential pressure High event
+* @param  LPS22HB_ENABLE/LPS22HB_DISABLE
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_PHE(void *handle, LPS22HB_State_et status);
+
+/**
+* @brief   Get the Interrupt Generation on differential pressure status event and the Boot Status.
+* @detail  The INT_SOURCE register is cleared by reading it.
+* @param   Status Event Flag: BOOT, PH,PL,IA
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_InterruptDifferentialEventStatus(void *handle, LPS22HB_InterruptDiffStatus_st* interruptsource);
+
+
+/**
+* @brief  Get the status of Pressure and Temperature data
+* @param  Data Status Flag:  TempDataAvailable, TempDataOverrun, PressDataAvailable, PressDataOverrun
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_DataStatus(void *handle, LPS22HB_DataStatus_st* datastatus);
+
+
+/**
+* @brief  Get the LPS22HB raw presure value
+* @param  The buffer to empty with the pressure raw value
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_RawPressure(void *handle, int32_t *raw_press);
+
+/**
+* @brief  Get the LPS22HB Pressure value in hPA.
+* @param  The buffer to empty with the pressure value that must be divided by 100 to get the value in hPA
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_Pressure(void *handle, int32_t* Pout);
+
+/**
+* @brief  Read LPS22HB output register, and calculate the raw temperature.
+* @param  The buffer to empty with the temperature raw value
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_RawTemperature(void *handle, int16_t *raw_data);
+
+/**
+* @brief  Read the Temperature value in °C.
+* @param  The buffer to empty with the temperature value that must be divided by 10 to get the value in ['C]
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_Temperature(void *handle, int16_t* Tout);
+
+/**
+* @brief  Get the threshold value used for pressure interrupt generation.
+* @param  The buffer to empty with the temperature value
+* @retval  Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_PressureThreshold(void *handle, int16_t *P_ths);
+
+/**
+* @brief  Set the threshold value used for pressure interrupt generation.
+* @param  The buffer to empty with the temperature value
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_PressureThreshold(void *handle, int16_t P_ths);
+
+/**
+* @brief  Set Fifo Mode.
+* @param  Fifo Mode struct
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_FifoMode(void *handle, LPS22HB_FifoMode_et fifomode);
+/**
+* @brief  Get Fifo Mode.
+* @param  Buffer to empty with fifo mode value
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_FifoMode(void *handle, LPS22HB_FifoMode_et* fifomode);
+
+/**
+* @brief  Set Fifo Watermark Level.
+* @param  Watermark level value [0 31]
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_FifoWatermarkLevel(void *handle, uint8_t wtmlevel);
+
+/**
+* @brief   Get FIFO Watermark Level
+* @param   buffer to empty with watermak level[0,31] value read from sensor
+* @retval  Status [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_FifoWatermarkLevel(void *handle, uint8_t *wtmlevel);
+
+
+/**
+* @brief  Get Fifo Status.
+* @param  Buffer to empty with fifo status
+* @retval Status [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_FifoStatus(void *handle, LPS22HB_FifoStatus_st* status);
+
+
+/**
+* @brief  Get the reference pressure after soldering for computing differential pressure (hPA)
+* @param buffer to empty with the he pressure value (hPA)
+* @retval  Status [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_PressureOffsetValue(void *handle, int16_t *pressoffset);
+
+/**
+* @brief  Get the Reference Pressure value
+* @detail  It is a 24-bit data added to the sensor output measurement to detect a measured pressure beyond programmed limits.
+* @param  Buffer to empty with reference pressure value
+* @retval  Status [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_ReferencePressure(void *handle, int32_t* RefP);
+
+
+/**
+* @brief  Check if the single measurement has completed.
+* @param  the returned value is set to 1, when the measurement is completed
+* @retval Status [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_IsMeasurementCompleted(void *handle, uint8_t* Is_Measurement_Completed);
+
+
+/**
+* @brief  Get the values of the last single measurement.
+* @param  Pressure and temperature value
+* @retvalStatus [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_Measurement(void *handle, LPS22HB_MeasureTypeDef_st *Measurement_Value);
+
+
+/**
+* @brief   Set Generic Configuration
+* @param   Struct to empty with the chosen values
+* @retval  Error code[LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_GenericConfig(void *handle, LPS22HB_ConfigTypeDef_st* pxLPS22HBInit);
+
+/**
+* @brief  Get Generic configuration
+* @param  Struct to empty with configuration values
+* @retval Error code[LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_GenericConfig(void *handle, LPS22HB_ConfigTypeDef_st* pxLPS22HBInit);
+
+/**
+* @brief  Set Interrupt configuration
+* @param  Struct holding the configuration values
+* @retval  Error code[LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_InterruptConfig(void *handle, LPS22HB_InterruptTypeDef_st* pLPS22HBInt);
+
+/**
+* @brief  LPS22HBGet_InterruptConfig
+* @param  Struct to empty with configuration values
+* @retval S Error code[LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_InterruptConfig(void *handle, LPS22HB_InterruptTypeDef_st* pLPS22HBInt);
+
+/**
+* @brief  Set Fifo configuration
+* @param  Struct holding the configuration values
+* @retval  Error code[LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_FifoConfig(void *handle, LPS22HB_FIFOTypeDef_st* pLPS22HBFIFO);
+
+/**
+* @brief  Get Fifo configuration
+* @param  Struct to empty with the configuration values
+* @retval Error code[LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Get_FifoConfig(void *handle, LPS22HB_FIFOTypeDef_st* pLPS22HBFIFO);
+
+/**
+* @brief  Clock Tree Confoguration
+* @param  LPS22HB_CTE_NotBalanced, LPS22HB_CTE_ABalanced
+* @retval Error Code [LPS22HB_ERROR, LPS22HB_OK]
+*/
+LPS22HB_Error_et LPS22HB_Set_ClockTreeConfifuration(void *handle, LPS22HB_CTE_et mode);
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LPS22HB_DRIVER__H */
+
+/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/
--- a/sensors/LSM6DSL.lib	Sun Dec 16 13:29:53 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://developer.mbed.org/teams/ST/code/LSM6DSL/#20ccff7dd652
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/LSM6DSL/LSM6DSLSensor.cpp	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,2139 @@
+/**
+ ******************************************************************************
+ * @file    LSM6DSLSensor.cpp
+ * @author  CLab
+ * @version V1.0.0
+ * @date    5 August 2016
+ * @brief   Implementation of an LSM6DSL Inertial Measurement Unit (IMU) 6 axes
+ *          sensor.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "LSM6DSLSensor.h"
+
+
+/* Class Implementation ------------------------------------------------------*/
+
+LSM6DSLSensor::LSM6DSLSensor(SPI *spi, PinName cs_pin, PinName int1_pin, PinName int2_pin, SPI_type_t spi_type ) : 
+                             _dev_spi(spi), _cs_pin(cs_pin), _int1_irq(int1_pin), _int2_irq(int2_pin), _spi_type(spi_type)
+{
+    assert (spi);
+    if (cs_pin == NC) 
+    {
+        printf ("ERROR LPS22HBSensor CS MUST NOT BE NC\n\r");       
+        _dev_spi = NULL;
+        _dev_i2c=NULL;
+        return;
+    }       
+    _cs_pin = 1;    
+    _dev_i2c=NULL;
+    
+    if (_spi_type == SPI3W) LSM6DSL_ACC_GYRO_W_SPI_Mode((void *)this, LSM6DSL_ACC_GYRO_SIM_3_WIRE);
+    else LSM6DSL_ACC_GYRO_W_SPI_Mode((void *)this, LSM6DSL_ACC_GYRO_SIM_4_WIRE);
+    
+    LSM6DSL_ACC_GYRO_W_I2C_MASTER_Enable((void *)this, LSM6DSL_ACC_GYRO_MASTER_ON_DISABLED);    
+}
+
+/** Constructor
+ * @param i2c object of an helper class which handles the I2C peripheral
+ * @param address the address of the component's instance
+ */
+LSM6DSLSensor::LSM6DSLSensor(DevI2C *i2c, uint8_t address, PinName int1_pin, PinName int2_pin) :
+                             _dev_i2c(i2c), _address(address), _cs_pin(NC), _int1_irq(int1_pin), _int2_irq(int2_pin)
+{
+    assert (i2c);
+    _dev_spi = NULL;
+}
+
+/**
+ * @brief     Initializing the component.
+ * @param[in] init pointer to device specific initalization structure.
+ * @retval    "0" in case of success, an error code otherwise.
+ */
+int LSM6DSLSensor::init(void *init)
+{
+  /* Enable register address automatically incremented during a multiple byte
+     access with a serial interface. */
+  if ( LSM6DSL_ACC_GYRO_W_IF_Addr_Incr( (void *)this, LSM6DSL_ACC_GYRO_IF_INC_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Enable BDU */
+  if ( LSM6DSL_ACC_GYRO_W_BDU( (void *)this, LSM6DSL_ACC_GYRO_BDU_BLOCK_UPDATE ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* FIFO mode selection */
+  if ( LSM6DSL_ACC_GYRO_W_FIFO_MODE( (void *)this, LSM6DSL_ACC_GYRO_FIFO_MODE_BYPASS ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Output data rate selection - power down. */
+  if ( LSM6DSL_ACC_GYRO_W_ODR_XL( (void *)this, LSM6DSL_ACC_GYRO_ODR_XL_POWER_DOWN ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Full scale selection. */
+  if ( set_x_fs( 2.0f ) == 1 )
+  {
+    return 1;
+  }
+
+  /* Output data rate selection - power down */
+  if ( LSM6DSL_ACC_GYRO_W_ODR_G( (void *)this, LSM6DSL_ACC_GYRO_ODR_G_POWER_DOWN ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+
+  /* Full scale selection. */
+  if ( set_g_fs( 2000.0f ) == 1 )
+  {
+    return 1;
+  }
+  
+  _x_last_odr = 104.0f;
+
+  _x_is_enabled = 0;
+  
+  _g_last_odr = 104.0f;
+
+  _g_is_enabled = 0;
+  
+  return 0;
+}
+
+/**
+ * @brief  Enable LSM6DSL Accelerator
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::enable_x(void)
+{ 
+  /* Check if the component is already enabled */
+  if ( _x_is_enabled == 1 )
+  {
+    return 0;
+  }
+  
+  /* Output data rate selection. */
+  if ( set_x_odr_when_enabled( _x_last_odr ) == 1 )
+  {
+    return 1;
+  }
+  
+  _x_is_enabled = 1;
+  
+  return 0;
+}
+
+/**
+ * @brief  Enable LSM6DSL Gyroscope
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::enable_g(void)
+{ 
+  /* Check if the component is already enabled */
+  if ( _g_is_enabled == 1 )
+  {
+    return 0;
+  }
+  
+  /* Output data rate selection. */
+  if ( set_g_odr_when_enabled( _g_last_odr ) == 1 )
+  {
+    return 1;
+  }
+  
+  _g_is_enabled = 1;
+  
+  return 0;
+}
+
+/**
+ * @brief  Disable LSM6DSL Accelerator
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::disable_x(void)
+{ 
+  /* Check if the component is already disabled */
+  if ( _x_is_enabled == 0 )
+  {
+    return 0;
+  }
+  
+  /* Store actual output data rate. */
+  if ( get_x_odr( &_x_last_odr ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Output data rate selection - power down. */
+  if ( LSM6DSL_ACC_GYRO_W_ODR_XL( (void *)this, LSM6DSL_ACC_GYRO_ODR_XL_POWER_DOWN ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  _x_is_enabled = 0;
+  
+  return 0;
+}
+
+/**
+ * @brief  Disable LSM6DSL Gyroscope
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::disable_g(void)
+{ 
+  /* Check if the component is already disabled */
+  if ( _g_is_enabled == 0 )
+  {
+    return 0;
+  }
+  
+  /* Store actual output data rate. */
+  if ( get_g_odr( &_g_last_odr ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Output data rate selection - power down */
+  if ( LSM6DSL_ACC_GYRO_W_ODR_G( (void *)this, LSM6DSL_ACC_GYRO_ODR_G_POWER_DOWN ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  _g_is_enabled = 0;
+  
+  return 0;
+}
+
+/**
+ * @brief  Read ID of LSM6DSL Accelerometer and Gyroscope
+ * @param  p_id the pointer where the ID of the device is stored
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::read_id(uint8_t *id)
+{
+  if(!id)
+  { 
+    return 1;
+  }
+
+  /* Read WHO AM I register */
+  if ( LSM6DSL_ACC_GYRO_R_WHO_AM_I( (void *)this, id ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief  Read data from LSM6DSL Accelerometer
+ * @param  pData the pointer where the accelerometer data are stored
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_x_axes(int32_t *pData)
+{
+  int16_t dataRaw[3];
+  float sensitivity = 0;
+  
+  /* Read raw data from LSM6DSL output register. */
+  if ( get_x_axes_raw( dataRaw ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Get LSM6DSL actual sensitivity. */
+  if ( get_x_sensitivity( &sensitivity ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Calculate the data. */
+  pData[0] = ( int32_t )( dataRaw[0] * sensitivity );
+  pData[1] = ( int32_t )( dataRaw[1] * sensitivity );
+  pData[2] = ( int32_t )( dataRaw[2] * sensitivity );
+  
+  return 0;
+}
+
+/**
+ * @brief  Read data from LSM6DSL Gyroscope
+ * @param  pData the pointer where the gyroscope data are stored
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_g_axes(int32_t *pData)
+{
+  int16_t dataRaw[3];
+  float sensitivity = 0;
+  
+  /* Read raw data from LSM6DSL output register. */
+  if ( get_g_axes_raw( dataRaw ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Get LSM6DSL actual sensitivity. */
+  if ( get_g_sensitivity( &sensitivity ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Calculate the data. */
+  pData[0] = ( int32_t )( dataRaw[0] * sensitivity );
+  pData[1] = ( int32_t )( dataRaw[1] * sensitivity );
+  pData[2] = ( int32_t )( dataRaw[2] * sensitivity );
+  
+  return 0;
+}
+
+/**
+ * @brief  Read Accelerometer Sensitivity
+ * @param  pfData the pointer where the accelerometer sensitivity is stored
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_x_sensitivity(float *pfData)
+{
+  LSM6DSL_ACC_GYRO_FS_XL_t fullScale;
+  
+  /* Read actual full scale selection from sensor. */
+  if ( LSM6DSL_ACC_GYRO_R_FS_XL( (void *)this, &fullScale ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Store the sensitivity based on actual full scale. */
+  switch( fullScale )
+  {
+    case LSM6DSL_ACC_GYRO_FS_XL_2g:
+      *pfData = ( float )LSM6DSL_ACC_SENSITIVITY_FOR_FS_2G;
+      break;
+    case LSM6DSL_ACC_GYRO_FS_XL_4g:
+      *pfData = ( float )LSM6DSL_ACC_SENSITIVITY_FOR_FS_4G;
+      break;
+    case LSM6DSL_ACC_GYRO_FS_XL_8g:
+      *pfData = ( float )LSM6DSL_ACC_SENSITIVITY_FOR_FS_8G;
+      break;
+    case LSM6DSL_ACC_GYRO_FS_XL_16g:
+      *pfData = ( float )LSM6DSL_ACC_SENSITIVITY_FOR_FS_16G;
+      break;
+    default:
+      *pfData = -1.0f;
+      return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief  Read Gyroscope Sensitivity
+ * @param  pfData the pointer where the gyroscope sensitivity is stored
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_g_sensitivity(float *pfData)
+{
+  LSM6DSL_ACC_GYRO_FS_125_t fullScale125;
+  LSM6DSL_ACC_GYRO_FS_G_t   fullScale;
+  
+  /* Read full scale 125 selection from sensor. */
+  if ( LSM6DSL_ACC_GYRO_R_FS_125( (void *)this, &fullScale125 ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  if ( fullScale125 == LSM6DSL_ACC_GYRO_FS_125_ENABLED )
+  {
+    *pfData = ( float )LSM6DSL_GYRO_SENSITIVITY_FOR_FS_125DPS;
+  }
+  
+  else
+  {
+  
+    /* Read actual full scale selection from sensor. */
+    if ( LSM6DSL_ACC_GYRO_R_FS_G( (void *)this, &fullScale ) == MEMS_ERROR )
+    {
+      return 1;
+    }
+    
+    /* Store the sensitivity based on actual full scale. */
+    switch( fullScale )
+    {
+      case LSM6DSL_ACC_GYRO_FS_G_245dps:
+        *pfData = ( float )LSM6DSL_GYRO_SENSITIVITY_FOR_FS_245DPS;
+        break;
+      case LSM6DSL_ACC_GYRO_FS_G_500dps:
+        *pfData = ( float )LSM6DSL_GYRO_SENSITIVITY_FOR_FS_500DPS;
+        break;
+      case LSM6DSL_ACC_GYRO_FS_G_1000dps:
+        *pfData = ( float )LSM6DSL_GYRO_SENSITIVITY_FOR_FS_1000DPS;
+        break;
+      case LSM6DSL_ACC_GYRO_FS_G_2000dps:
+        *pfData = ( float )LSM6DSL_GYRO_SENSITIVITY_FOR_FS_2000DPS;
+        break;
+      default:
+        *pfData = -1.0f;
+        return 1;
+    }
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief  Read raw data from LSM6DSL Accelerometer
+ * @param  pData the pointer where the accelerometer raw data are stored
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_x_axes_raw(int16_t *pData)
+{
+  uint8_t regValue[6] = {0, 0, 0, 0, 0, 0};
+  
+  /* Read output registers from LSM6DSL_ACC_GYRO_OUTX_L_XL to LSM6DSL_ACC_GYRO_OUTZ_H_XL. */
+  if ( LSM6DSL_ACC_GYRO_GetRawAccData( (void *)this, regValue ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Format the data. */
+  pData[0] = ( ( ( ( int16_t )regValue[1] ) << 8 ) + ( int16_t )regValue[0] );
+  pData[1] = ( ( ( ( int16_t )regValue[3] ) << 8 ) + ( int16_t )regValue[2] );
+  pData[2] = ( ( ( ( int16_t )regValue[5] ) << 8 ) + ( int16_t )regValue[4] );
+  
+  return 0;
+}
+
+/**
+ * @brief  Read raw data from LSM6DSL Gyroscope
+ * @param  pData the pointer where the gyroscope raw data are stored
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_g_axes_raw(int16_t *pData)
+{
+  uint8_t regValue[6] = {0, 0, 0, 0, 0, 0};
+  
+  /* Read output registers from LSM6DSL_ACC_GYRO_OUTX_L_G to LSM6DSL_ACC_GYRO_OUTZ_H_G. */
+  if ( LSM6DSL_ACC_GYRO_GetRawGyroData( (void *)this, regValue ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Format the data. */
+  pData[0] = ( ( ( ( int16_t )regValue[1] ) << 8 ) + ( int16_t )regValue[0] );
+  pData[1] = ( ( ( ( int16_t )regValue[3] ) << 8 ) + ( int16_t )regValue[2] );
+  pData[2] = ( ( ( ( int16_t )regValue[5] ) << 8 ) + ( int16_t )regValue[4] );
+  
+  return 0;
+}
+
+/**
+ * @brief  Read LSM6DSL Accelerometer output data rate
+ * @param  odr the pointer to the output data rate
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_x_odr(float* odr)
+{
+  LSM6DSL_ACC_GYRO_ODR_XL_t odr_low_level;
+  
+  if ( LSM6DSL_ACC_GYRO_R_ODR_XL( (void *)this, &odr_low_level ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  switch( odr_low_level )
+  {
+    case LSM6DSL_ACC_GYRO_ODR_XL_POWER_DOWN:
+      *odr = 0.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_XL_13Hz:
+      *odr = 13.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_XL_26Hz:
+      *odr = 26.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_XL_52Hz:
+      *odr = 52.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_XL_104Hz:
+      *odr = 104.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_XL_208Hz:
+      *odr = 208.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_XL_416Hz:
+      *odr = 416.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_XL_833Hz:
+      *odr = 833.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_XL_1660Hz:
+      *odr = 1660.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_XL_3330Hz:
+      *odr = 3330.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_XL_6660Hz:
+      *odr = 6660.0f;
+      break;
+    default:
+      *odr = -1.0f;
+      return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief  Read LSM6DSL Gyroscope output data rate
+ * @param  odr the pointer to the output data rate
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_g_odr(float* odr)
+{
+  LSM6DSL_ACC_GYRO_ODR_G_t odr_low_level;
+  
+  if ( LSM6DSL_ACC_GYRO_R_ODR_G( (void *)this, &odr_low_level ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  switch( odr_low_level )
+  {
+    case LSM6DSL_ACC_GYRO_ODR_G_POWER_DOWN:
+      *odr = 0.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_G_13Hz:
+      *odr = 13.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_G_26Hz:
+      *odr = 26.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_G_52Hz:
+      *odr = 52.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_G_104Hz:
+      *odr = 104.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_G_208Hz:
+      *odr = 208.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_G_416Hz:
+      *odr = 416.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_G_833Hz:
+      *odr = 833.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_G_1660Hz:
+      *odr = 1660.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_G_3330Hz:
+      *odr = 3330.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_ODR_G_6660Hz:
+      *odr = 6660.0f;
+      break;
+    default:
+      *odr = -1.0f;
+      return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief  Set LSM6DSL Accelerometer output data rate
+ * @param  odr the output data rate to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::set_x_odr(float odr)
+{
+  if(_x_is_enabled == 1)
+  {
+    if(set_x_odr_when_enabled(odr) == 1)
+    {
+      return 1;
+    }
+  }
+  else
+  {
+    if(set_x_odr_when_disabled(odr) == 1)
+    {
+      return 1;
+    }
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief  Set LSM6DSL Accelerometer output data rate when enabled
+ * @param  odr the output data rate to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::set_x_odr_when_enabled(float odr)
+{
+  LSM6DSL_ACC_GYRO_ODR_XL_t new_odr;
+  
+  new_odr = ( odr <=   13.0f ) ? LSM6DSL_ACC_GYRO_ODR_XL_13Hz
+          : ( odr <=   26.0f ) ? LSM6DSL_ACC_GYRO_ODR_XL_26Hz
+          : ( odr <=   52.0f ) ? LSM6DSL_ACC_GYRO_ODR_XL_52Hz
+          : ( odr <=  104.0f ) ? LSM6DSL_ACC_GYRO_ODR_XL_104Hz
+          : ( odr <=  208.0f ) ? LSM6DSL_ACC_GYRO_ODR_XL_208Hz
+          : ( odr <=  416.0f ) ? LSM6DSL_ACC_GYRO_ODR_XL_416Hz
+          : ( odr <=  833.0f ) ? LSM6DSL_ACC_GYRO_ODR_XL_833Hz
+          : ( odr <= 1660.0f ) ? LSM6DSL_ACC_GYRO_ODR_XL_1660Hz
+          : ( odr <= 3330.0f ) ? LSM6DSL_ACC_GYRO_ODR_XL_3330Hz
+          :                      LSM6DSL_ACC_GYRO_ODR_XL_6660Hz;
+            
+  if ( LSM6DSL_ACC_GYRO_W_ODR_XL( (void *)this, new_odr ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief  Set LSM6DSL Accelerometer output data rate when disabled
+ * @param  odr the output data rate to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::set_x_odr_when_disabled(float odr)
+{ 
+  _x_last_odr = ( odr <=   13.0f ) ? 13.0f
+             : ( odr <=   26.0f ) ? 26.0f
+             : ( odr <=   52.0f ) ? 52.0f
+             : ( odr <=  104.0f ) ? 104.0f
+             : ( odr <=  208.0f ) ? 208.0f
+             : ( odr <=  416.0f ) ? 416.0f
+             : ( odr <=  833.0f ) ? 833.0f
+             : ( odr <= 1660.0f ) ? 1660.0f
+             : ( odr <= 3330.0f ) ? 3330.0f
+             :                      6660.0f;
+                                 
+  return 0;
+}
+
+/**
+ * @brief  Set LSM6DSL Gyroscope output data rate
+ * @param  odr the output data rate to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::set_g_odr(float odr)
+{
+  if(_g_is_enabled == 1)
+  {
+    if(set_g_odr_when_enabled(odr) == 1)
+    {
+      return 1;
+    }
+  }
+  else
+  {
+    if(set_g_odr_when_disabled(odr) == 1)
+    {
+      return 1;
+    }
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief  Set LSM6DSL Gyroscope output data rate when enabled
+ * @param  odr the output data rate to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::set_g_odr_when_enabled(float odr)
+{
+  LSM6DSL_ACC_GYRO_ODR_G_t new_odr;
+  
+  new_odr = ( odr <=  13.0f )  ? LSM6DSL_ACC_GYRO_ODR_G_13Hz
+          : ( odr <=  26.0f )  ? LSM6DSL_ACC_GYRO_ODR_G_26Hz
+          : ( odr <=  52.0f )  ? LSM6DSL_ACC_GYRO_ODR_G_52Hz
+          : ( odr <= 104.0f )  ? LSM6DSL_ACC_GYRO_ODR_G_104Hz
+          : ( odr <= 208.0f )  ? LSM6DSL_ACC_GYRO_ODR_G_208Hz
+          : ( odr <= 416.0f )  ? LSM6DSL_ACC_GYRO_ODR_G_416Hz
+          : ( odr <= 833.0f )  ? LSM6DSL_ACC_GYRO_ODR_G_833Hz
+          : ( odr <= 1660.0f ) ? LSM6DSL_ACC_GYRO_ODR_G_1660Hz
+          : ( odr <= 3330.0f ) ? LSM6DSL_ACC_GYRO_ODR_G_3330Hz
+          :                      LSM6DSL_ACC_GYRO_ODR_G_6660Hz;
+            
+  if ( LSM6DSL_ACC_GYRO_W_ODR_G( (void *)this, new_odr ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief  Set LSM6DSL Gyroscope output data rate when disabled
+ * @param  odr the output data rate to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::set_g_odr_when_disabled(float odr)
+{
+  _g_last_odr = ( odr <=  13.0f )  ? 13.0f
+             : ( odr <=  26.0f )  ? 26.0f
+             : ( odr <=  52.0f )  ? 52.0f
+             : ( odr <= 104.0f )  ? 104.0f
+             : ( odr <= 208.0f )  ? 208.0f
+             : ( odr <= 416.0f )  ? 416.0f
+             : ( odr <= 833.0f )  ? 833.0f
+             : ( odr <= 1660.0f ) ? 1660.0f
+             : ( odr <= 3330.0f ) ? 3330.0f
+             :                      6660.0f;
+                                 
+  return 0;
+}
+
+/**
+ * @brief  Read LSM6DSL Accelerometer full scale
+ * @param  fullScale the pointer to the full scale
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_x_fs(float* fullScale)
+{
+  LSM6DSL_ACC_GYRO_FS_XL_t fs_low_level;
+  
+  if ( LSM6DSL_ACC_GYRO_R_FS_XL( (void *)this, &fs_low_level ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  switch( fs_low_level )
+  {
+    case LSM6DSL_ACC_GYRO_FS_XL_2g:
+      *fullScale = 2.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_FS_XL_4g:
+      *fullScale = 4.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_FS_XL_8g:
+      *fullScale = 8.0f;
+      break;
+    case LSM6DSL_ACC_GYRO_FS_XL_16g:
+      *fullScale = 16.0f;
+      break;
+    default:
+      *fullScale = -1.0f;
+      return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief  Read LSM6DSL Gyroscope full scale
+ * @param  fullScale the pointer to the full scale
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_g_fs(float* fullScale)
+{
+  LSM6DSL_ACC_GYRO_FS_G_t fs_low_level;
+  LSM6DSL_ACC_GYRO_FS_125_t fs_125;
+  
+  if ( LSM6DSL_ACC_GYRO_R_FS_125( (void *)this, &fs_125 ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  if ( LSM6DSL_ACC_GYRO_R_FS_G( (void *)this, &fs_low_level ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  if ( fs_125 == LSM6DSL_ACC_GYRO_FS_125_ENABLED )
+  {
+    *fullScale = 125.0f;
+  }
+  
+  else
+  {
+    switch( fs_low_level )
+    {
+      case LSM6DSL_ACC_GYRO_FS_G_245dps:
+        *fullScale = 245.0f;
+        break;
+      case LSM6DSL_ACC_GYRO_FS_G_500dps:
+        *fullScale = 500.0f;
+        break;
+      case LSM6DSL_ACC_GYRO_FS_G_1000dps:
+        *fullScale = 1000.0f;
+        break;
+      case LSM6DSL_ACC_GYRO_FS_G_2000dps:
+        *fullScale = 2000.0f;
+        break;
+      default:
+        *fullScale = -1.0f;
+        return 1;
+    }
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief  Set LSM6DSL Accelerometer full scale
+ * @param  fullScale the full scale to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::set_x_fs(float fullScale)
+{
+  LSM6DSL_ACC_GYRO_FS_XL_t new_fs;
+  
+  new_fs = ( fullScale <= 2.0f ) ? LSM6DSL_ACC_GYRO_FS_XL_2g
+         : ( fullScale <= 4.0f ) ? LSM6DSL_ACC_GYRO_FS_XL_4g
+         : ( fullScale <= 8.0f ) ? LSM6DSL_ACC_GYRO_FS_XL_8g
+         :                         LSM6DSL_ACC_GYRO_FS_XL_16g;
+           
+  if ( LSM6DSL_ACC_GYRO_W_FS_XL( (void *)this, new_fs ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief  Set LSM6DSL Gyroscope full scale
+ * @param  fullScale the full scale to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::set_g_fs(float fullScale)
+{
+  LSM6DSL_ACC_GYRO_FS_G_t new_fs;
+  
+  if ( fullScale <= 125.0f )
+  {
+    if ( LSM6DSL_ACC_GYRO_W_FS_125( (void *)this, LSM6DSL_ACC_GYRO_FS_125_ENABLED ) == MEMS_ERROR )
+    {
+      return 1;
+    }
+  }
+  else
+  {
+    new_fs = ( fullScale <=  245.0f ) ? LSM6DSL_ACC_GYRO_FS_G_245dps
+           : ( fullScale <=  500.0f ) ? LSM6DSL_ACC_GYRO_FS_G_500dps
+           : ( fullScale <= 1000.0f ) ? LSM6DSL_ACC_GYRO_FS_G_1000dps
+           :                            LSM6DSL_ACC_GYRO_FS_G_2000dps;
+             
+    if ( LSM6DSL_ACC_GYRO_W_FS_125( (void *)this, LSM6DSL_ACC_GYRO_FS_125_DISABLED ) == MEMS_ERROR )
+    {
+      return 1;
+    }
+    if ( LSM6DSL_ACC_GYRO_W_FS_G( (void *)this, new_fs ) == MEMS_ERROR )
+    {
+      return 1;
+    }
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief  Enable free fall detection
+ * @param pin the interrupt pin to be used
+ * @note  This function sets the LSM6DSL accelerometer ODR to 416Hz and the LSM6DSL accelerometer full scale to 2g
+ * @retval 0 in case of success, an error code otherwise
+*/
+int LSM6DSLSensor::enable_free_fall_detection(LSM6DSL_Interrupt_Pin_t pin)
+{
+  /* Output Data Rate selection */
+  if(set_x_odr(416.0f) == 1)
+  {
+    return 1;
+  }
+  
+  /* Full scale selection */
+  if ( LSM6DSL_ACC_GYRO_W_FS_XL( (void *)this, LSM6DSL_ACC_GYRO_FS_XL_2g ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* FF_DUR setting */
+  if ( LSM6DSL_ACC_GYRO_W_FF_Duration( (void *)this, 0x06 ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* WAKE_DUR setting */
+  if ( LSM6DSL_ACC_GYRO_W_WAKE_DUR( (void *)this, 0x00 ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* TIMER_HR setting */
+  if ( LSM6DSL_ACC_GYRO_W_TIMER_HR( (void *)this, LSM6DSL_ACC_GYRO_TIMER_HR_6_4ms ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* SLEEP_DUR setting */
+  if ( LSM6DSL_ACC_GYRO_W_SLEEP_DUR( (void *)this, 0x00 ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* FF_THS setting */
+  if ( LSM6DSL_ACC_GYRO_W_FF_THS( (void *)this, LSM6DSL_ACC_GYRO_FF_THS_312mg ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Enable basic Interrupts */
+  if ( LSM6DSL_ACC_GYRO_W_BASIC_INT( (void *)this, LSM6DSL_ACC_GYRO_BASIC_INT_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Enable free fall event on either INT1 or INT2 pin */
+  switch (pin)
+  {
+  case LSM6DSL_INT1_PIN:
+    if ( LSM6DSL_ACC_GYRO_W_FFEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_FF_ENABLED ) == MEMS_ERROR )
+    {
+      return 1;
+    }
+    break;
+
+  case LSM6DSL_INT2_PIN:
+    if ( LSM6DSL_ACC_GYRO_W_FFEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_FF_ENABLED ) == MEMS_ERROR )
+    {
+      return 1;
+    }
+    break;
+
+  default:
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief  Disable free fall detection
+ * @param  None
+ * @retval 0 in case of success, an error code otherwise
+*/
+int LSM6DSLSensor::disable_free_fall_detection(void)
+{
+  /* Disable free fall event on INT1 pin */
+  if ( LSM6DSL_ACC_GYRO_W_FFEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_FF_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable free fall event on INT2 pin */
+  if ( LSM6DSL_ACC_GYRO_W_FFEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_FF_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable basic Interrupts */
+  if ( LSM6DSL_ACC_GYRO_W_BASIC_INT( (void *)this, LSM6DSL_ACC_GYRO_BASIC_INT_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* FF_DUR setting */
+  if ( LSM6DSL_ACC_GYRO_W_FF_Duration( (void *)this, 0x00 ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* FF_THS setting */
+  if ( LSM6DSL_ACC_GYRO_W_FF_THS( (void *)this, LSM6DSL_ACC_GYRO_FF_THS_156mg ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Set the free fall detection threshold for LSM6DSL accelerometer sensor
+ * @param thr the threshold to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::set_free_fall_threshold(uint8_t thr)
+{
+
+  if ( LSM6DSL_ACC_GYRO_W_FF_THS( (void *)this, (LSM6DSL_ACC_GYRO_FF_THS_t)thr ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Enable the pedometer feature for LSM6DSL accelerometer sensor
+ * @note  This function sets the LSM6DSL accelerometer ODR to 26Hz and the LSM6DSL accelerometer full scale to 2g
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::enable_pedometer(void)
+{
+  /* Output Data Rate selection */
+  if( set_x_odr(26.0f) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Full scale selection. */
+  if( set_x_fs(2.0f) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Set pedometer threshold. */
+  if ( set_pedometer_threshold(LSM6DSL_PEDOMETER_THRESHOLD_MID_HIGH) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Enable embedded functionalities. */
+  if ( LSM6DSL_ACC_GYRO_W_FUNC_EN( (void *)this, LSM6DSL_ACC_GYRO_FUNC_EN_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Enable pedometer algorithm. */
+  if ( LSM6DSL_ACC_GYRO_W_PEDO( (void *)this, LSM6DSL_ACC_GYRO_PEDO_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Enable pedometer on INT1. */
+  if ( LSM6DSL_ACC_GYRO_W_STEP_DET_on_INT1( (void *)this, LSM6DSL_ACC_GYRO_INT1_PEDO_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Disable the pedometer feature for LSM6DSL accelerometer sensor
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::disable_pedometer(void)
+{
+  /* Disable pedometer on INT1. */
+  if ( LSM6DSL_ACC_GYRO_W_STEP_DET_on_INT1( (void *)this, LSM6DSL_ACC_GYRO_INT1_PEDO_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable pedometer algorithm. */
+  if ( LSM6DSL_ACC_GYRO_W_PEDO( (void *)this, LSM6DSL_ACC_GYRO_PEDO_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable embedded functionalities. */
+  if ( LSM6DSL_ACC_GYRO_W_FUNC_EN( (void *)this, LSM6DSL_ACC_GYRO_FUNC_EN_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Reset pedometer threshold. */
+  if ( set_pedometer_threshold(0x0) == 1 )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Get the step counter for LSM6DSL accelerometer sensor
+ * @param step_count the pointer to the step counter
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_step_counter(uint16_t *step_count)
+{
+  if ( LSM6DSL_ACC_GYRO_Get_GetStepCounter( (void *)this, ( uint8_t* )step_count ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Reset of the step counter for LSM6DSL accelerometer sensor
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::reset_step_counter(void)
+{
+  if ( LSM6DSL_ACC_GYRO_W_PedoStepReset( (void *)this, LSM6DSL_ACC_GYRO_PEDO_RST_STEP_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  wait_ms(10);
+  
+  if ( LSM6DSL_ACC_GYRO_W_PedoStepReset( (void *)this, LSM6DSL_ACC_GYRO_PEDO_RST_STEP_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Set the pedometer threshold for LSM6DSL accelerometer sensor
+ * @param thr the threshold to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::set_pedometer_threshold(uint8_t thr)
+{
+  if ( LSM6DSL_ACC_GYRO_W_PedoThreshold( (void *)this, thr ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Enable the tilt detection for LSM6DSL accelerometer sensor
+ * @param pin the interrupt pin to be used
+ * @note  This function sets the LSM6DSL accelerometer ODR to 26Hz and the LSM6DSL accelerometer full scale to 2g
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::enable_tilt_detection(LSM6DSL_Interrupt_Pin_t pin)
+{
+  /* Output Data Rate selection */
+  if( set_x_odr(26.0f) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Full scale selection. */
+  if( set_x_fs(2.0f) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Enable embedded functionalities */
+  if ( LSM6DSL_ACC_GYRO_W_FUNC_EN( (void *)this, LSM6DSL_ACC_GYRO_FUNC_EN_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Enable tilt calculation. */
+  if ( LSM6DSL_ACC_GYRO_W_TILT( (void *)this, LSM6DSL_ACC_GYRO_TILT_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+
+  /* Enable tilt detection on either INT1 or INT2 pin */
+  switch (pin)
+  {
+  case LSM6DSL_INT1_PIN:
+    if ( LSM6DSL_ACC_GYRO_W_TiltEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_TILT_ENABLED ) == MEMS_ERROR )
+    {
+      return 1;
+    }
+    break;
+
+  case LSM6DSL_INT2_PIN:
+    if ( LSM6DSL_ACC_GYRO_W_TiltEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_TILT_ENABLED ) == MEMS_ERROR )
+    {
+      return 1;
+    }
+    break;
+
+  default:
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief Disable the tilt detection for LSM6DSL accelerometer sensor
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::disable_tilt_detection(void)
+{
+  /* Disable tilt event on INT1. */
+  if ( LSM6DSL_ACC_GYRO_W_TiltEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_TILT_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+
+  /* Disable tilt event on INT2. */
+  if ( LSM6DSL_ACC_GYRO_W_TiltEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_TILT_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable tilt calculation. */
+  if ( LSM6DSL_ACC_GYRO_W_TILT( (void *)this, LSM6DSL_ACC_GYRO_TILT_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable embedded functionalities */
+  if ( LSM6DSL_ACC_GYRO_W_FUNC_EN( (void *)this, LSM6DSL_ACC_GYRO_FUNC_EN_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Enable the wake up detection for LSM6DSL accelerometer sensor
+ * @param pin the interrupt pin to be used
+ * @note  This function sets the LSM6DSL accelerometer ODR to 416Hz and the LSM6DSL accelerometer full scale to 2g
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::enable_wake_up_detection(LSM6DSL_Interrupt_Pin_t pin)
+{
+  /* Output Data Rate selection */
+  if( set_x_odr(416.0f) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Full scale selection. */
+  if( set_x_fs(2.0f) == 1 )
+  {
+    return 1;
+  }
+  
+  /* WAKE_DUR setting */
+  if ( LSM6DSL_ACC_GYRO_W_WAKE_DUR( (void *)this, 0x00 ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Set wake up threshold. */
+  if ( LSM6DSL_ACC_GYRO_W_WK_THS( (void *)this, 0x02 ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Enable basic Interrupts */
+  if ( LSM6DSL_ACC_GYRO_W_BASIC_INT( (void *)this, LSM6DSL_ACC_GYRO_BASIC_INT_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+
+  /* Enable wake up detection on either INT1 or INT2 pin */
+  switch (pin)
+  {
+  case LSM6DSL_INT1_PIN:
+    if ( LSM6DSL_ACC_GYRO_W_WUEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_WU_ENABLED ) == MEMS_ERROR )
+    {
+      return 1;
+    }
+    break;
+
+  case LSM6DSL_INT2_PIN:
+    if ( LSM6DSL_ACC_GYRO_W_WUEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_WU_ENABLED ) == MEMS_ERROR )
+    {
+      return 1;
+    }
+    break;
+
+  default:
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Disable the wake up detection for LSM6DSL accelerometer sensor
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::disable_wake_up_detection(void)
+{
+  /* Disable wake up event on INT1 */
+  if ( LSM6DSL_ACC_GYRO_W_WUEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_WU_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+
+  /* Disable wake up event on INT2 */
+  if ( LSM6DSL_ACC_GYRO_W_WUEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_WU_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable basic Interrupts */
+  if ( LSM6DSL_ACC_GYRO_W_BASIC_INT( (void *)this, LSM6DSL_ACC_GYRO_BASIC_INT_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* WU_DUR setting */
+  if ( LSM6DSL_ACC_GYRO_W_WAKE_DUR( (void *)this, 0x00 ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* WU_THS setting */
+  if ( LSM6DSL_ACC_GYRO_W_WK_THS( (void *)this, 0x00 ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Set the wake up threshold for LSM6DSL accelerometer sensor
+ * @param thr the threshold to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::set_wake_up_threshold(uint8_t thr)
+{
+  if ( LSM6DSL_ACC_GYRO_W_WK_THS( (void *)this, thr ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Enable the single tap detection for LSM6DSL accelerometer sensor
+ * @param pin the interrupt pin to be used
+ * @note  This function sets the LSM6DSL accelerometer ODR to 416Hz and the LSM6DSL accelerometer full scale to 2g
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::enable_single_tap_detection(LSM6DSL_Interrupt_Pin_t pin)
+{
+  /* Output Data Rate selection */
+  if( set_x_odr(416.0f) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Full scale selection. */
+  if( set_x_fs(2.0f) == 1 )
+  {
+    return 1;
+  }
+
+  /* Enable X direction in tap recognition. */
+  if ( LSM6DSL_ACC_GYRO_W_TAP_X_EN( (void *)this, LSM6DSL_ACC_GYRO_TAP_X_EN_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Enable Y direction in tap recognition. */
+  if ( LSM6DSL_ACC_GYRO_W_TAP_Y_EN( (void *)this, LSM6DSL_ACC_GYRO_TAP_Y_EN_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Enable Z direction in tap recognition. */
+  if ( LSM6DSL_ACC_GYRO_W_TAP_Z_EN( (void *)this, LSM6DSL_ACC_GYRO_TAP_Z_EN_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Set tap threshold. */
+  if ( set_tap_threshold( LSM6DSL_TAP_THRESHOLD_MID_LOW ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Set tap shock time window. */
+  if ( set_tap_shock_time( LSM6DSL_TAP_SHOCK_TIME_MID_HIGH ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Set tap quiet time window. */
+  if ( set_tap_quiet_time( LSM6DSL_TAP_QUIET_TIME_MID_LOW ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* _NOTE_: Tap duration time window - don't care for single tap. */
+  
+  /* _NOTE_: Single/Double Tap event - don't care of this flag for single tap. */
+  
+  /* Enable basic Interrupts */
+  if ( LSM6DSL_ACC_GYRO_W_BASIC_INT( (void *)this, LSM6DSL_ACC_GYRO_BASIC_INT_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Enable single tap on either INT1 or INT2 pin */
+  switch (pin)
+  {
+  case LSM6DSL_INT1_PIN:
+    if ( LSM6DSL_ACC_GYRO_W_SingleTapOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_ENABLED ) == MEMS_ERROR )
+    {
+      return 1;
+    }
+    break;
+
+  case LSM6DSL_INT2_PIN:
+    if ( LSM6DSL_ACC_GYRO_W_SingleTapOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_ENABLED ) == MEMS_ERROR )
+    {
+      return 1;
+    }
+    break;
+
+  default:
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Disable the single tap detection for LSM6DSL accelerometer sensor
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::disable_single_tap_detection(void)
+{
+  /* Disable single tap interrupt on INT1 pin. */
+  if ( LSM6DSL_ACC_GYRO_W_SingleTapOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable single tap interrupt on INT2 pin. */
+  if ( LSM6DSL_ACC_GYRO_W_SingleTapOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable basic Interrupts */
+  if ( LSM6DSL_ACC_GYRO_W_BASIC_INT( (void *)this, LSM6DSL_ACC_GYRO_BASIC_INT_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Reset tap threshold. */
+  if ( set_tap_threshold( 0x0 ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Reset tap shock time window. */
+  if ( set_tap_shock_time( 0x0 ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Reset tap quiet time window. */
+  if ( set_tap_quiet_time( 0x0 ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* _NOTE_: Tap duration time window - don't care for single tap. */
+  
+  /* _NOTE_: Single/Double Tap event - don't care of this flag for single tap. */
+  
+  /* Disable Z direction in tap recognition. */
+  if ( LSM6DSL_ACC_GYRO_W_TAP_Z_EN( (void *)this, LSM6DSL_ACC_GYRO_TAP_Z_EN_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable Y direction in tap recognition. */
+  if ( LSM6DSL_ACC_GYRO_W_TAP_Y_EN( (void *)this, LSM6DSL_ACC_GYRO_TAP_Y_EN_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable X direction in tap recognition. */
+  if ( LSM6DSL_ACC_GYRO_W_TAP_X_EN( (void *)this, LSM6DSL_ACC_GYRO_TAP_X_EN_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Enable the double tap detection for LSM6DSL accelerometer sensor
+ * @param pin the interrupt pin to be used
+ * @note  This function sets the LSM6DSL accelerometer ODR to 416Hz and the LSM6DSL accelerometer full scale to 2g
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::enable_double_tap_detection(LSM6DSL_Interrupt_Pin_t pin)
+{
+  /* Output Data Rate selection */
+  if( set_x_odr(416.0f) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Full scale selection. */
+  if( set_x_fs(2.0f) == 1 )
+  {
+    return 1;
+  }
+
+  /* Enable X direction in tap recognition. */
+  if ( LSM6DSL_ACC_GYRO_W_TAP_X_EN( (void *)this, LSM6DSL_ACC_GYRO_TAP_X_EN_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Enable Y direction in tap recognition. */
+  if ( LSM6DSL_ACC_GYRO_W_TAP_Y_EN( (void *)this, LSM6DSL_ACC_GYRO_TAP_Y_EN_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Enable Z direction in tap recognition. */
+  if ( LSM6DSL_ACC_GYRO_W_TAP_Z_EN( (void *)this, LSM6DSL_ACC_GYRO_TAP_Z_EN_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Set tap threshold. */
+  if ( set_tap_threshold( LSM6DSL_TAP_THRESHOLD_MID_LOW ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Set tap shock time window. */
+  if ( set_tap_shock_time( LSM6DSL_TAP_SHOCK_TIME_HIGH ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Set tap quiet time window. */
+  if ( set_tap_quiet_time( LSM6DSL_TAP_QUIET_TIME_HIGH ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Set tap duration time window. */
+  if ( set_tap_duration_time( LSM6DSL_TAP_DURATION_TIME_MID ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Single and double tap enabled. */
+  if ( LSM6DSL_ACC_GYRO_W_SINGLE_DOUBLE_TAP_EV( (void *)this, LSM6DSL_ACC_GYRO_SINGLE_DOUBLE_TAP_DOUBLE_TAP ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Enable basic Interrupts */
+  if ( LSM6DSL_ACC_GYRO_W_BASIC_INT( (void *)this, LSM6DSL_ACC_GYRO_BASIC_INT_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Enable double tap on either INT1 or INT2 pin */
+  switch (pin)
+  {
+  case LSM6DSL_INT1_PIN:
+    if ( LSM6DSL_ACC_GYRO_W_TapEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_TAP_ENABLED ) == MEMS_ERROR )
+    {
+      return 1;
+    }
+    break;
+
+  case LSM6DSL_INT2_PIN:
+    if ( LSM6DSL_ACC_GYRO_W_TapEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_TAP_ENABLED ) == MEMS_ERROR )
+    {
+      return 1;
+    }
+    break;
+
+  default:
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Disable the double tap detection for LSM6DSL accelerometer sensor
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::disable_double_tap_detection(void)
+{
+  /* Disable double tap interrupt on INT1 pin. */
+  if ( LSM6DSL_ACC_GYRO_W_TapEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_TAP_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable double tap interrupt on INT2 pin. */
+  if ( LSM6DSL_ACC_GYRO_W_TapEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_TAP_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable basic Interrupts */
+  if ( LSM6DSL_ACC_GYRO_W_BASIC_INT( (void *)this, LSM6DSL_ACC_GYRO_BASIC_INT_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Reset tap threshold. */
+  if ( set_tap_threshold( 0x0 ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Reset tap shock time window. */
+  if ( set_tap_shock_time( 0x0 ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Reset tap quiet time window. */
+  if ( set_tap_quiet_time( 0x0 ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Reset tap duration time window. */
+  if ( set_tap_duration_time( 0x0 ) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Only single tap enabled. */
+  if ( LSM6DSL_ACC_GYRO_W_SINGLE_DOUBLE_TAP_EV( (void *)this, LSM6DSL_ACC_GYRO_SINGLE_DOUBLE_TAP_SINGLE_TAP ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable Z direction in tap recognition. */
+  if ( LSM6DSL_ACC_GYRO_W_TAP_Z_EN( (void *)this, LSM6DSL_ACC_GYRO_TAP_Z_EN_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable Y direction in tap recognition. */
+  if ( LSM6DSL_ACC_GYRO_W_TAP_Y_EN( (void *)this, LSM6DSL_ACC_GYRO_TAP_Y_EN_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable X direction in tap recognition. */
+  if ( LSM6DSL_ACC_GYRO_W_TAP_X_EN( (void *)this, LSM6DSL_ACC_GYRO_TAP_X_EN_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Set the tap threshold for LSM6DSL accelerometer sensor
+ * @param thr the threshold to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::set_tap_threshold(uint8_t thr)
+{
+  if ( LSM6DSL_ACC_GYRO_W_TAP_THS( (void *)this, thr ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Set the tap shock time window for LSM6DSL accelerometer sensor
+ * @param time the shock time window to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::set_tap_shock_time(uint8_t time)
+{
+  if ( LSM6DSL_ACC_GYRO_W_SHOCK_Duration( (void *)this, time ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Set the tap quiet time window for LSM6DSL accelerometer sensor
+ * @param time the quiet time window to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::set_tap_quiet_time(uint8_t time)
+{
+  if ( LSM6DSL_ACC_GYRO_W_QUIET_Duration( (void *)this, time ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Set the tap duration of the time window for LSM6DSL accelerometer sensor
+ * @param time the duration of the time window to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::set_tap_duration_time(uint8_t time)
+{
+  if ( LSM6DSL_ACC_GYRO_W_DUR( (void *)this, time ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Enable the 6D orientation detection for LSM6DSL accelerometer sensor
+ * @param pin the interrupt pin to be used
+ * @note  This function sets the LSM6DSL accelerometer ODR to 416Hz and the LSM6DSL accelerometer full scale to 2g
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::enable_6d_orientation(LSM6DSL_Interrupt_Pin_t pin)
+{
+  /* Output Data Rate selection */
+  if( set_x_odr(416.0f) == 1 )
+  {
+    return 1;
+  }
+  
+  /* Full scale selection. */
+  if( set_x_fs(2.0f) == 1 )
+  {
+    return 1;
+  }
+
+  /* Set 6D threshold. */
+  if ( LSM6DSL_ACC_GYRO_W_SIXD_THS( (void *)this, LSM6DSL_ACC_GYRO_SIXD_THS_60_degree ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Enable basic Interrupts */
+  if ( LSM6DSL_ACC_GYRO_W_BASIC_INT( (void *)this, LSM6DSL_ACC_GYRO_BASIC_INT_ENABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Enable 6D orientation on either INT1 or INT2 pin */
+  switch (pin)
+  {
+  case LSM6DSL_INT1_PIN:
+    if ( LSM6DSL_ACC_GYRO_W_6DEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_6D_ENABLED ) == MEMS_ERROR )
+    {
+      return 1;
+    }
+    break;
+
+  case LSM6DSL_INT2_PIN:
+    if ( LSM6DSL_ACC_GYRO_W_6DEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_6D_ENABLED ) == MEMS_ERROR )
+    {
+      return 1;
+    }
+    break;
+
+  default:
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Disable the 6D orientation detection for LSM6DSL accelerometer sensor
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::disable_6d_orientation(void)
+{
+  /* Disable 6D orientation interrupt on INT1 pin. */
+  if ( LSM6DSL_ACC_GYRO_W_6DEvOnInt1( (void *)this, LSM6DSL_ACC_GYRO_INT1_6D_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable 6D orientation interrupt on INT2 pin. */
+  if ( LSM6DSL_ACC_GYRO_W_6DEvOnInt2( (void *)this, LSM6DSL_ACC_GYRO_INT2_6D_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Disable basic Interrupts */
+  if ( LSM6DSL_ACC_GYRO_W_BASIC_INT( (void *)this, LSM6DSL_ACC_GYRO_BASIC_INT_DISABLED ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  /* Reset 6D threshold. */
+  if ( LSM6DSL_ACC_GYRO_W_SIXD_THS( (void *)this, LSM6DSL_ACC_GYRO_SIXD_THS_80_degree ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Get the 6D orientation XL axis for LSM6DSL accelerometer sensor
+ * @param xl the pointer to the 6D orientation XL axis
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_6d_orientation_xl(uint8_t *xl)
+{
+  LSM6DSL_ACC_GYRO_DSD_XL_t xl_raw;
+  
+  if ( LSM6DSL_ACC_GYRO_R_DSD_XL( (void *)this, &xl_raw ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  switch( xl_raw )
+  {
+    case LSM6DSL_ACC_GYRO_DSD_XL_DETECTED:
+      *xl = 1;
+      break;
+    case LSM6DSL_ACC_GYRO_DSD_XL_NOT_DETECTED:
+      *xl = 0;
+      break;
+    default:
+      return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Get the 6D orientation XH axis for LSM6DSL accelerometer sensor
+ * @param xh the pointer to the 6D orientation XH axis
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_6d_orientation_xh(uint8_t *xh)
+{
+  LSM6DSL_ACC_GYRO_DSD_XH_t xh_raw;
+  
+  if ( LSM6DSL_ACC_GYRO_R_DSD_XH( (void *)this, &xh_raw ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  switch( xh_raw )
+  {
+    case LSM6DSL_ACC_GYRO_DSD_XH_DETECTED:
+      *xh = 1;
+      break;
+    case LSM6DSL_ACC_GYRO_DSD_XH_NOT_DETECTED:
+      *xh = 0;
+      break;
+    default:
+      return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Get the 6D orientation YL axis for LSM6DSL accelerometer sensor
+ * @param yl the pointer to the 6D orientation YL axis
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_6d_orientation_yl(uint8_t *yl)
+{
+  LSM6DSL_ACC_GYRO_DSD_YL_t yl_raw;
+  
+  if ( LSM6DSL_ACC_GYRO_R_DSD_YL( (void *)this, &yl_raw ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  switch( yl_raw )
+  {
+    case LSM6DSL_ACC_GYRO_DSD_YL_DETECTED:
+      *yl = 1;
+      break;
+    case LSM6DSL_ACC_GYRO_DSD_YL_NOT_DETECTED:
+      *yl = 0;
+      break;
+    default:
+      return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Get the 6D orientation YH axis for LSM6DSL accelerometer sensor
+ * @param yh the pointer to the 6D orientation YH axis
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_6d_orientation_yh(uint8_t *yh)
+{
+  LSM6DSL_ACC_GYRO_DSD_YH_t yh_raw;
+  
+  if ( LSM6DSL_ACC_GYRO_R_DSD_YH( (void *)this, &yh_raw ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  switch( yh_raw )
+  {
+    case LSM6DSL_ACC_GYRO_DSD_YH_DETECTED:
+      *yh = 1;
+      break;
+    case LSM6DSL_ACC_GYRO_DSD_YH_NOT_DETECTED:
+      *yh = 0;
+      break;
+    default:
+      return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Get the 6D orientation ZL axis for LSM6DSL accelerometer sensor
+ * @param zl the pointer to the 6D orientation ZL axis
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_6d_orientation_zl(uint8_t *zl)
+{
+  LSM6DSL_ACC_GYRO_DSD_ZL_t zl_raw;
+  
+  if ( LSM6DSL_ACC_GYRO_R_DSD_ZL( (void *)this, &zl_raw ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  switch( zl_raw )
+  {
+    case LSM6DSL_ACC_GYRO_DSD_ZL_DETECTED:
+      *zl = 1;
+      break;
+    case LSM6DSL_ACC_GYRO_DSD_ZL_NOT_DETECTED:
+      *zl = 0;
+      break;
+    default:
+      return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Get the 6D orientation ZH axis for LSM6DSL accelerometer sensor
+ * @param zh the pointer to the 6D orientation ZH axis
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_6d_orientation_zh(uint8_t *zh)
+{
+  LSM6DSL_ACC_GYRO_DSD_ZH_t zh_raw;
+  
+  if ( LSM6DSL_ACC_GYRO_R_DSD_ZH( (void *)this, &zh_raw ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+  
+  switch( zh_raw )
+  {
+    case LSM6DSL_ACC_GYRO_DSD_ZH_DETECTED:
+      *zh = 1;
+      break;
+    case LSM6DSL_ACC_GYRO_DSD_ZH_NOT_DETECTED:
+      *zh = 0;
+      break;
+    default:
+      return 1;
+  }
+  
+  return 0;
+}
+
+/**
+ * @brief Get the status of all hardware events for LSM6DSL accelerometer sensor
+ * @param status the pointer to the status of all hardware events
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::get_event_status(LSM6DSL_Event_Status_t *status)
+{
+  uint8_t Wake_Up_Src = 0, Tap_Src = 0, D6D_Src = 0, Func_Src = 0, Md1_Cfg = 0, Md2_Cfg = 0, Int1_Ctrl = 0;
+
+  memset((void *)status, 0x0, sizeof(LSM6DSL_Event_Status_t));
+
+  if(read_reg(LSM6DSL_ACC_GYRO_WAKE_UP_SRC, &Wake_Up_Src) != 0)
+  {
+    return 1;
+  }
+
+  if(read_reg(LSM6DSL_ACC_GYRO_TAP_SRC, &Tap_Src) != 0)
+  {
+    return 1;
+  }
+
+  if(read_reg(LSM6DSL_ACC_GYRO_D6D_SRC, &D6D_Src) != 0)
+  {
+    return 1;
+  }
+
+  if(read_reg(LSM6DSL_ACC_GYRO_FUNC_SRC, &Func_Src) != 0)
+  {
+    return 1;
+  }
+
+  if(read_reg(LSM6DSL_ACC_GYRO_MD1_CFG, &Md1_Cfg ) != 0 )
+  {
+    return 1;
+  }
+
+  if(read_reg(LSM6DSL_ACC_GYRO_MD2_CFG, &Md2_Cfg ) != 0)
+  {
+    return 1;
+  }
+
+  if(read_reg(LSM6DSL_ACC_GYRO_INT1_CTRL, &Int1_Ctrl ) != 0)
+  {
+    return 1;
+  }
+
+  if((Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_FF_MASK) || (Md2_Cfg & LSM6DSL_ACC_GYRO_INT2_FF_MASK))
+  {
+    if((Wake_Up_Src & LSM6DSL_ACC_GYRO_FF_EV_STATUS_MASK))
+    {
+      status->FreeFallStatus = 1;  
+    }
+  }
+
+  if((Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_WU_MASK) || (Md2_Cfg & LSM6DSL_ACC_GYRO_INT2_WU_MASK))
+  {
+    if((Wake_Up_Src & LSM6DSL_ACC_GYRO_WU_EV_STATUS_MASK))
+    {
+      status->WakeUpStatus = 1;  
+    }
+  }
+
+  if((Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_MASK) || (Md2_Cfg & LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_MASK))
+  {
+    if((Tap_Src & LSM6DSL_ACC_GYRO_SINGLE_TAP_EV_STATUS_MASK))
+    {
+      status->TapStatus = 1;  
+    }
+  }
+
+  if((Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_TAP_MASK) || (Md2_Cfg & LSM6DSL_ACC_GYRO_INT2_TAP_MASK))
+  {
+    if((Tap_Src & LSM6DSL_ACC_GYRO_DOUBLE_TAP_EV_STATUS_MASK))
+    {
+      status->DoubleTapStatus = 1;  
+    }
+  }
+
+  if((Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_6D_MASK) || (Md2_Cfg & LSM6DSL_ACC_GYRO_INT2_6D_MASK))
+  {
+    if((D6D_Src & LSM6DSL_ACC_GYRO_D6D_EV_STATUS_MASK))
+    {
+      status->D6DOrientationStatus = 1;  
+    }
+  }
+
+  if((Int1_Ctrl & LSM6DSL_ACC_GYRO_INT1_PEDO_MASK))
+  {
+    if((Func_Src & LSM6DSL_ACC_GYRO_PEDO_EV_STATUS_MASK))
+    {
+      status->StepStatus = 1;  
+    }
+  }
+
+  if((Md1_Cfg & LSM6DSL_ACC_GYRO_INT1_TILT_MASK) || (Md2_Cfg & LSM6DSL_ACC_GYRO_INT2_TILT_MASK))
+  {
+    if((Func_Src & LSM6DSL_ACC_GYRO_TILT_EV_STATUS_MASK))
+    {
+      status->TiltStatus = 1;  
+    }
+  }
+
+  return 0;
+}
+
+/**
+ * @brief Read the data from register
+ * @param reg register address
+ * @param data register data
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::read_reg( uint8_t reg, uint8_t *data )
+{
+
+  if ( LSM6DSL_ACC_GYRO_read_reg( (void *)this, reg, data, 1 ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief Write the data to register
+ * @param reg register address
+ * @param data register data
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSLSensor::write_reg( uint8_t reg, uint8_t data )
+{
+
+  if ( LSM6DSL_ACC_GYRO_write_reg( (void *)this, reg, &data, 1 ) == MEMS_ERROR )
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+
+uint8_t LSM6DSL_io_write( void *handle, uint8_t WriteAddr, uint8_t *pBuffer, uint16_t nBytesToWrite )
+{
+  return ((LSM6DSLSensor *)handle)->io_write(pBuffer, WriteAddr, nBytesToWrite);
+}
+
+uint8_t LSM6DSL_io_read( void *handle, uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead )
+{
+  return ((LSM6DSLSensor *)handle)->io_read(pBuffer, ReadAddr, nBytesToRead);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/LSM6DSL/LSM6DSLSensor.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,331 @@
+/**
+ ******************************************************************************
+ * @file    LSM6DSLSensor.h
+ * @author  CLab
+ * @version V1.0.0
+ * @date    5 August 2016
+ * @brief   Abstract Class of an LSM6DSL Inertial Measurement Unit (IMU) 6 axes
+ *          sensor.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+
+/* Prevent recursive inclusion -----------------------------------------------*/
+
+#ifndef __LSM6DSLSensor_H__
+#define __LSM6DSLSensor_H__
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "DevI2C.h"
+#include "LSM6DSL_acc_gyro_driver.h"
+#include "MotionSensor.h"
+#include "GyroSensor.h"
+#include <assert.h>
+
+/* Defines -------------------------------------------------------------------*/
+
+#define LSM6DSL_ACC_SENSITIVITY_FOR_FS_2G   0.061  /**< Sensitivity value for 2 g full scale [mg/LSB] */
+#define LSM6DSL_ACC_SENSITIVITY_FOR_FS_4G   0.122  /**< Sensitivity value for 4 g full scale [mg/LSB] */
+#define LSM6DSL_ACC_SENSITIVITY_FOR_FS_8G   0.244  /**< Sensitivity value for 8 g full scale [mg/LSB] */
+#define LSM6DSL_ACC_SENSITIVITY_FOR_FS_16G  0.488  /**< Sensitivity value for 16 g full scale [mg/LSB] */
+
+#define LSM6DSL_GYRO_SENSITIVITY_FOR_FS_125DPS   04.375  /**< Sensitivity value for 125 dps full scale [mdps/LSB] */
+#define LSM6DSL_GYRO_SENSITIVITY_FOR_FS_245DPS   08.750  /**< Sensitivity value for 245 dps full scale [mdps/LSB] */
+#define LSM6DSL_GYRO_SENSITIVITY_FOR_FS_500DPS   17.500  /**< Sensitivity value for 500 dps full scale [mdps/LSB] */
+#define LSM6DSL_GYRO_SENSITIVITY_FOR_FS_1000DPS  35.000  /**< Sensitivity value for 1000 dps full scale [mdps/LSB] */
+#define LSM6DSL_GYRO_SENSITIVITY_FOR_FS_2000DPS  70.000  /**< Sensitivity value for 2000 dps full scale [mdps/LSB] */
+
+#define LSM6DSL_PEDOMETER_THRESHOLD_LOW       0x00  /**< Lowest  value of pedometer threshold */
+#define LSM6DSL_PEDOMETER_THRESHOLD_MID_LOW   0x07
+#define LSM6DSL_PEDOMETER_THRESHOLD_MID       0x0F
+#define LSM6DSL_PEDOMETER_THRESHOLD_MID_HIGH  0x17
+#define LSM6DSL_PEDOMETER_THRESHOLD_HIGH      0x1F  /**< Highest value of pedometer threshold */
+
+#define LSM6DSL_WAKE_UP_THRESHOLD_LOW       0x01  /**< Lowest  value of wake up threshold */
+#define LSM6DSL_WAKE_UP_THRESHOLD_MID_LOW   0x0F
+#define LSM6DSL_WAKE_UP_THRESHOLD_MID       0x1F
+#define LSM6DSL_WAKE_UP_THRESHOLD_MID_HIGH  0x2F
+#define LSM6DSL_WAKE_UP_THRESHOLD_HIGH      0x3F  /**< Highest value of wake up threshold */
+
+#define LSM6DSL_TAP_THRESHOLD_LOW       0x01  /**< Lowest  value of wake up threshold */
+#define LSM6DSL_TAP_THRESHOLD_MID_LOW   0x08
+#define LSM6DSL_TAP_THRESHOLD_MID       0x10
+#define LSM6DSL_TAP_THRESHOLD_MID_HIGH  0x18
+#define LSM6DSL_TAP_THRESHOLD_HIGH      0x1F  /**< Highest value of wake up threshold */
+
+#define LSM6DSL_TAP_SHOCK_TIME_LOW       0x00  /**< Lowest  value of wake up threshold */
+#define LSM6DSL_TAP_SHOCK_TIME_MID_LOW   0x01
+#define LSM6DSL_TAP_SHOCK_TIME_MID_HIGH  0x02
+#define LSM6DSL_TAP_SHOCK_TIME_HIGH      0x03  /**< Highest value of wake up threshold */
+
+#define LSM6DSL_TAP_QUIET_TIME_LOW       0x00  /**< Lowest  value of wake up threshold */
+#define LSM6DSL_TAP_QUIET_TIME_MID_LOW   0x01
+#define LSM6DSL_TAP_QUIET_TIME_MID_HIGH  0x02
+#define LSM6DSL_TAP_QUIET_TIME_HIGH      0x03  /**< Highest value of wake up threshold */
+
+#define LSM6DSL_TAP_DURATION_TIME_LOW       0x00  /**< Lowest  value of wake up threshold */
+#define LSM6DSL_TAP_DURATION_TIME_MID_LOW   0x04
+#define LSM6DSL_TAP_DURATION_TIME_MID       0x08
+#define LSM6DSL_TAP_DURATION_TIME_MID_HIGH  0x0C
+#define LSM6DSL_TAP_DURATION_TIME_HIGH      0x0F  /**< Highest value of wake up threshold */
+
+/* Typedefs ------------------------------------------------------------------*/
+
+typedef enum
+{
+  LSM6DSL_INT1_PIN,
+  LSM6DSL_INT2_PIN
+} LSM6DSL_Interrupt_Pin_t;
+
+typedef struct
+{
+  unsigned int FreeFallStatus : 1;
+  unsigned int TapStatus : 1;
+  unsigned int DoubleTapStatus : 1;
+  unsigned int WakeUpStatus : 1;
+  unsigned int StepStatus : 1;
+  unsigned int TiltStatus : 1;
+  unsigned int D6DOrientationStatus : 1;
+} LSM6DSL_Event_Status_t;
+
+/* Class Declaration ---------------------------------------------------------*/
+   
+/**
+ * Abstract class of an LSM6DSL Inertial Measurement Unit (IMU) 6 axes
+ * sensor.
+ */
+class LSM6DSLSensor : public MotionSensor, public GyroSensor
+{
+  public:
+    enum SPI_type_t {SPI3W, SPI4W};      
+    LSM6DSLSensor(SPI *spi, PinName cs_pin, PinName INT1_pin=NC, PinName INT2_pin=NC, SPI_type_t spi_type=SPI4W);  
+    LSM6DSLSensor(DevI2C *i2c, uint8_t address=LSM6DSL_ACC_GYRO_I2C_ADDRESS_HIGH, PinName INT1_pin=NC, PinName INT2_pin=NC);
+    virtual int init(void *init);
+    virtual int read_id(uint8_t *id);
+    virtual int get_x_axes(int32_t *pData);
+    virtual int get_g_axes(int32_t *pData);
+    virtual int get_x_sensitivity(float *pfData);
+    virtual int get_g_sensitivity(float *pfData);
+    virtual int get_x_axes_raw(int16_t *pData);
+    virtual int get_g_axes_raw(int16_t *pData);
+    virtual int get_x_odr(float *odr);
+    virtual int get_g_odr(float *odr);
+    virtual int set_x_odr(float odr);
+    virtual int set_g_odr(float odr);
+    virtual int get_x_fs(float *fullScale);
+    virtual int get_g_fs(float *fullScale);
+    virtual int set_x_fs(float fullScale);
+    virtual int set_g_fs(float fullScale);
+    int enable_x(void);
+    int enable_g(void);
+    int disable_x(void);
+    int disable_g(void);
+    int enable_free_fall_detection(LSM6DSL_Interrupt_Pin_t pin = LSM6DSL_INT1_PIN);
+    int disable_free_fall_detection(void);
+    int set_free_fall_threshold(uint8_t thr);
+    int enable_pedometer(void);
+    int disable_pedometer(void);
+    int get_step_counter(uint16_t *step_count);
+    int reset_step_counter(void);
+    int set_pedometer_threshold(uint8_t thr);
+    int enable_tilt_detection(LSM6DSL_Interrupt_Pin_t pin = LSM6DSL_INT1_PIN);
+    int disable_tilt_detection(void);
+    int enable_wake_up_detection(LSM6DSL_Interrupt_Pin_t pin = LSM6DSL_INT2_PIN);
+    int disable_wake_up_detection(void);
+    int set_wake_up_threshold(uint8_t thr);
+    int enable_single_tap_detection(LSM6DSL_Interrupt_Pin_t pin = LSM6DSL_INT1_PIN);
+    int disable_single_tap_detection(void);
+    int enable_double_tap_detection(LSM6DSL_Interrupt_Pin_t pin = LSM6DSL_INT1_PIN);
+    int disable_double_tap_detection(void);
+    int set_tap_threshold(uint8_t thr);
+    int set_tap_shock_time(uint8_t time);
+    int set_tap_quiet_time(uint8_t time);
+    int set_tap_duration_time(uint8_t time);
+    int enable_6d_orientation(LSM6DSL_Interrupt_Pin_t pin = LSM6DSL_INT1_PIN);
+    int disable_6d_orientation(void);
+    int get_6d_orientation_xl(uint8_t *xl);
+    int get_6d_orientation_xh(uint8_t *xh);
+    int get_6d_orientation_yl(uint8_t *yl);
+    int get_6d_orientation_yh(uint8_t *yh);
+    int get_6d_orientation_zl(uint8_t *zl);
+    int get_6d_orientation_zh(uint8_t *zh);
+    int get_event_status(LSM6DSL_Event_Status_t *status);
+    int read_reg(uint8_t reg, uint8_t *data);
+    int write_reg(uint8_t reg, uint8_t data);
+    
+    /**
+     * @brief  Attaching an interrupt handler to the INT1 interrupt.
+     * @param  fptr An interrupt handler.
+     * @retval None.
+     */
+    void attach_int1_irq(void (*fptr)(void))
+    {
+        _int1_irq.rise(fptr);
+    }
+
+    /**
+     * @brief  Enabling the INT1 interrupt handling.
+     * @param  None.
+     * @retval None.
+     */
+    void enable_int1_irq(void)
+    {
+        _int1_irq.enable_irq();
+    }
+    
+    /**
+     * @brief  Disabling the INT1 interrupt handling.
+     * @param  None.
+     * @retval None.
+     */
+    void disable_int1_irq(void)
+    {
+        _int1_irq.disable_irq();
+    }
+    
+    /**
+     * @brief  Attaching an interrupt handler to the INT2 interrupt.
+     * @param  fptr An interrupt handler.
+     * @retval None.
+     */
+    void attach_int2_irq(void (*fptr)(void))
+    {
+        _int2_irq.rise(fptr);
+    }
+
+    /**
+     * @brief  Enabling the INT2 interrupt handling.
+     * @param  None.
+     * @retval None.
+     */
+    void enable_int2_irq(void)
+    {
+        _int2_irq.enable_irq();
+    }
+    
+    /**
+     * @brief  Disabling the INT2 interrupt handling.
+     * @param  None.
+     * @retval None.
+     */
+    void disable_int2_irq(void)
+    {
+        _int2_irq.disable_irq();
+    }
+    
+    /**
+     * @brief Utility function to read data.
+     * @param  pBuffer: pointer to data to be read.
+     * @param  RegisterAddr: specifies internal address register to be read.
+     * @param  NumByteToRead: number of bytes to be read.
+     * @retval 0 if ok, an error code otherwise.
+     */
+    uint8_t io_read(uint8_t* pBuffer, uint8_t RegisterAddr, uint16_t NumByteToRead)
+    {        
+        if (_dev_spi) {
+        /* Write Reg Address */
+            _dev_spi->lock();
+            _cs_pin = 0;           
+            if (_spi_type == SPI4W) {            
+                _dev_spi->write(RegisterAddr | 0x80);
+                for (int i=0; i<NumByteToRead; i++) {
+                    *(pBuffer+i) = _dev_spi->write(0x00);
+                }
+            } else if (_spi_type == SPI3W){
+                /* Write RD Reg Address with RD bit*/
+                uint8_t TxByte = RegisterAddr | 0x80;    
+                _dev_spi->write((char *)&TxByte, 1, (char *)pBuffer, (int) NumByteToRead);
+            }            
+            _cs_pin = 1;
+            _dev_spi->unlock(); 
+            return 0;
+        }                       
+        if (_dev_i2c) return (uint8_t) _dev_i2c->i2c_read(pBuffer, _address, RegisterAddr, NumByteToRead);
+        return 1;
+    }
+    
+    /**
+     * @brief Utility function to write data.
+     * @param  pBuffer: pointer to data to be written.
+     * @param  RegisterAddr: specifies internal address register to be written.
+     * @param  NumByteToWrite: number of bytes to write.
+     * @retval 0 if ok, an error code otherwise.
+     */
+    uint8_t io_write(uint8_t* pBuffer, uint8_t RegisterAddr, uint16_t NumByteToWrite)
+    {
+        int data;   
+        if (_dev_spi) { 
+            _dev_spi->lock();
+            _cs_pin = 0;
+            data = _dev_spi->write(RegisterAddr);                    
+            _dev_spi->write((char *)pBuffer, (int) NumByteToWrite, NULL, 0);                     
+            _cs_pin = 1;                    
+            _dev_spi->unlock();
+            return data;                    
+        }        
+        if (_dev_i2c) return (uint8_t) _dev_i2c->i2c_write(pBuffer, _address, RegisterAddr, NumByteToWrite);    
+        return 1;
+    }
+
+  private:
+    int set_x_odr_when_enabled(float odr);
+    int set_g_odr_when_enabled(float odr);
+    int set_x_odr_when_disabled(float odr);
+    int set_g_odr_when_disabled(float odr);
+
+    /* Helper classes. */
+    DevI2C *_dev_i2c;
+    SPI    *_dev_spi;
+    SPI_type_t _spi_type;
+    
+    /* Configuration */
+    uint8_t _address;
+    DigitalOut  _cs_pin;        
+    InterruptIn _int1_irq;
+    InterruptIn _int2_irq;
+    
+    uint8_t _x_is_enabled;
+    float _x_last_odr;
+    uint8_t _g_is_enabled;
+    float _g_last_odr;
+};
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+uint8_t LSM6DSL_io_write( void *handle, uint8_t WriteAddr, uint8_t *pBuffer, uint16_t nBytesToWrite );
+uint8_t LSM6DSL_io_read( void *handle, uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead );
+#ifdef __cplusplus
+  }
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/LSM6DSL/LSM6DSL_acc_gyro_driver.c	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,6393 @@
+/**
+ ******************************************************************************
+ * @file    LSM6DSL_acc_gyro_driver.c
+ * @author  MEMS Application Team
+ * @version V1.5
+ * @date    17-May-2016
+ * @brief   LSM6DSL driver file
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "LSM6DSL_acc_gyro_driver.h"   
+
+/* Imported function prototypes ----------------------------------------------*/
+extern uint8_t LSM6DSL_io_write(void *handle, uint8_t WriteAddr, uint8_t *pBuffer, uint16_t nBytesToWrite);
+extern uint8_t LSM6DSL_io_read(void *handle, uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead);                                
+
+/* Private typedef -----------------------------------------------------------*/
+
+/* Private define ------------------------------------------------------------*/
+
+/* Private macro -------------------------------------------------------------*/
+
+/* Private variables ---------------------------------------------------------*/
+
+/* Private functions ---------------------------------------------------------*/
+
+/* Exported functions ---------------------------------------------------------*/
+
+/************** Generic Function  *******************/
+
+/*******************************************************************************
+* Function Name     : LSM6DSL_ACC_GYRO_read_reg
+* Description       : Generic Reading function. It must be fullfilled with either
+*                   : I2C or SPI reading functions                  
+* Input             : Register Address, length of buffer
+* Output            : Data REad
+* Return            : None
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_read_reg(void *handle, u8_t Reg, u8_t* Data, u16_t len) 
+{
+  if (LSM6DSL_io_read(handle, Reg, Data, len))
+  {
+    return MEMS_ERROR;
+  }
+  else
+  {
+    return MEMS_SUCCESS;
+  }
+}
+
+/*******************************************************************************
+* Function Name     : LSM6DSL_ACC_GYRO_write_reg
+* Description       : Generic Writing function. It must be fullfilled with either
+*                   : I2C or SPI writing function
+* Input             : Register Address, Data to be written, length of buffer
+* Output            : None
+* Return            : None
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_write_reg(void *handle, u8_t Reg, u8_t *Data, u16_t len) 
+{
+  if (LSM6DSL_io_write(handle, Reg, Data, len))
+  {
+    return MEMS_ERROR;
+  }
+  else
+  {
+    return MEMS_SUCCESS;
+  }
+}
+
+/**************** Base Function  *******************/
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_WHO_AM_I
+* Description    : Read WHO_AM_I_BIT
+* Input          : Pointer to u8_t
+* Output         : Status of WHO_AM_I_BIT 
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_WHO_AM_I(void *handle, u8_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WHO_AM_I_REG, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_WHO_AM_I_BIT_MASK; //coerce    
+  *value = *value >> LSM6DSL_ACC_GYRO_WHO_AM_I_BIT_POSITION; //mask 
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_BDU
+* Description    : Write BDU
+* Input          : LSM6DSL_ACC_GYRO_BDU_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_BDU(void *handle, LSM6DSL_ACC_GYRO_BDU_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_BDU_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_BDU
+* Description    : Read BDU
+* Input          : Pointer to LSM6DSL_ACC_GYRO_BDU_t
+* Output         : Status of BDU see LSM6DSL_ACC_GYRO_BDU_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_BDU(void *handle, LSM6DSL_ACC_GYRO_BDU_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_BDU_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_FS_XL
+* Description    : Write FS_XL
+* Input          : LSM6DSL_ACC_GYRO_FS_XL_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_FS_XL(void *handle, LSM6DSL_ACC_GYRO_FS_XL_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL1_XL, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_FS_XL_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL1_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FS_XL
+* Description    : Read FS_XL
+* Input          : Pointer to LSM6DSL_ACC_GYRO_FS_XL_t
+* Output         : Status of FS_XL see LSM6DSL_ACC_GYRO_FS_XL_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FS_XL(void *handle, LSM6DSL_ACC_GYRO_FS_XL_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL1_XL, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_FS_XL_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : mems_status_t LSM6DSL_ACC_GYRO_GetRawAccData(u8_t *buff)
+* Description    : Read GetAccData output register
+* Input          : pointer to [u8_t]
+* Output         : GetAccData buffer u8_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_GetRawAccData(void *handle, u8_t *buff) 
+{
+  u8_t i, j, k;
+  u8_t numberOfByteForDimension;
+  
+  numberOfByteForDimension=6/3;
+
+  k=0;
+  for (i=0; i<3;i++ ) 
+  {
+    for (j=0; j<numberOfByteForDimension;j++ )
+    {   
+        if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_OUTX_L_XL+k, &buff[k], 1))
+          return MEMS_ERROR;
+        k++;    
+    }
+  }
+
+  return MEMS_SUCCESS; 
+}
+
+/*******************************************************************************
+* Function Name  : mems_status_t LSM6DSL_ACC_Get_Acceleration(void *handle, int *buff, u8_t from_fifo)
+* Description    : Read GetAccData output register
+* Input          : pointer to [u8_t]
+* Output         : values are expressed in mg
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+/*
+ * Following is the table of sensitivity values for each case.
+ * Values are expressed in ug/digit.
+ */
+static const long long LSM6DSL_ACC_Sensitivity_List[4] = {
+      61,   /* FS @2g */
+      122,  /* FS @4g */
+      244,  /* FS @8g */
+      488,  /* FS @16g */
+};
+mems_status_t LSM6DSL_ACC_Get_Acceleration(void *handle, int *buff, u8_t from_fifo)
+{
+  LSM6DSL_ACC_GYRO_FS_XL_t fs;
+  long long sensitivity = 0;
+  Type3Axis16bit_U raw_data_tmp;
+
+  /* Read out current odr, fs, hf setting */
+  LSM6DSL_ACC_GYRO_R_FS_XL(handle, &fs);
+
+  /* Determine the sensitivity according to fs */
+  switch(fs) {
+  case LSM6DSL_ACC_GYRO_FS_XL_2g:
+    sensitivity = LSM6DSL_ACC_Sensitivity_List[0];
+    break;
+
+  case LSM6DSL_ACC_GYRO_FS_XL_4g:
+    sensitivity = LSM6DSL_ACC_Sensitivity_List[1];
+    break;
+
+  case LSM6DSL_ACC_GYRO_FS_XL_8g:
+    sensitivity = LSM6DSL_ACC_Sensitivity_List[2];
+    break;
+
+  case LSM6DSL_ACC_GYRO_FS_XL_16g:
+    sensitivity = LSM6DSL_ACC_Sensitivity_List[3];
+    break;
+  }
+
+  /* Read out raw accelerometer samples */
+  if (from_fifo) {
+    u8_t i;
+
+    /* read all 3 axis from FIFO */
+    for(i = 0; i < 3; i++)
+      LSM6DSL_ACC_GYRO_Get_GetFIFOData(handle, raw_data_tmp.u8bit + 2*i);
+  } else
+    LSM6DSL_ACC_GYRO_GetRawAccData(handle, raw_data_tmp.u8bit);
+
+  /* Apply proper shift and sensitivity */
+  buff[0] = (raw_data_tmp.i16bit[0] * sensitivity + 500)/1000;
+  buff[1] = (raw_data_tmp.i16bit[1] * sensitivity + 500)/1000;
+  buff[2] = (raw_data_tmp.i16bit[2] * sensitivity + 500)/1000;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_ODR_XL
+* Description    : Write ODR_XL
+* Input          : LSM6DSL_ACC_GYRO_ODR_XL_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_ODR_XL(void *handle, LSM6DSL_ACC_GYRO_ODR_XL_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL1_XL, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_ODR_XL_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL1_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_ODR_XL
+* Description    : Read ODR_XL
+* Input          : Pointer to LSM6DSL_ACC_GYRO_ODR_XL_t
+* Output         : Status of ODR_XL see LSM6DSL_ACC_GYRO_ODR_XL_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_ODR_XL(void *handle, LSM6DSL_ACC_GYRO_ODR_XL_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL1_XL, (u8_t *)value, 1))
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_ODR_XL_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_translate_ODR_XL
+* Description    : Read ODR_XL
+* Input          : LSM6DSL_ACC_GYRO_ODR_XL_t
+* Output         : The ODR value in Hz
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_translate_ODR_XL(LSM6DSL_ACC_GYRO_ODR_XL_t value, u16_t *odr_hz_val)
+{
+  switch(value) {
+  case LSM6DSL_ACC_GYRO_ODR_XL_POWER_DOWN:
+    *odr_hz_val = 0;
+    break;
+
+  case LSM6DSL_ACC_GYRO_ODR_XL_13Hz:
+    *odr_hz_val = 13;
+    break;
+
+  case LSM6DSL_ACC_GYRO_ODR_XL_26Hz:
+    *odr_hz_val = 26;
+    break;
+
+  case LSM6DSL_ACC_GYRO_ODR_XL_52Hz:
+    *odr_hz_val = 52;
+    break;
+
+  case LSM6DSL_ACC_GYRO_ODR_XL_104Hz:
+    *odr_hz_val = 104;
+    break;
+
+  case LSM6DSL_ACC_GYRO_ODR_XL_208Hz:
+    *odr_hz_val = 208;
+    break;
+
+  case LSM6DSL_ACC_GYRO_ODR_XL_416Hz:
+    *odr_hz_val = 416;
+    break;
+
+  case LSM6DSL_ACC_GYRO_ODR_XL_833Hz:
+    *odr_hz_val = 833;
+    break;
+
+  case LSM6DSL_ACC_GYRO_ODR_XL_1660Hz:
+    *odr_hz_val = 1660;
+    break;
+
+  default:
+    return MEMS_ERROR;
+  }
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_FS_G
+* Description    : Write FS_G
+* Input          : LSM6DSL_ACC_GYRO_FS_G_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_FS_G(void *handle, LSM6DSL_ACC_GYRO_FS_G_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL2_G, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_FS_G_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL2_G, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FS_G
+* Description    : Read FS_G
+* Input          : Pointer to LSM6DSL_ACC_GYRO_FS_G_t
+* Output         : Status of FS_G see LSM6DSL_ACC_GYRO_FS_G_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FS_G(void *handle, LSM6DSL_ACC_GYRO_FS_G_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL2_G, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_FS_G_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : mems_status_t LSM6DSL_ACC_GYRO_GetRawGyroData(u8_t *buff)
+* Description    : Read GetGyroData output register
+* Input          : pointer to [u8_t]
+* Output         : GetGyroData buffer u8_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_GetRawGyroData(void *handle, u8_t *buff) 
+{
+  u8_t i, j, k;
+  u8_t numberOfByteForDimension;
+  
+  numberOfByteForDimension=6/3;
+
+  k=0;
+  for (i=0; i<3;i++ ) 
+  {
+    for (j=0; j<numberOfByteForDimension;j++ )
+    {   
+        if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_OUTX_L_G+k, &buff[k], 1))
+          return MEMS_ERROR;
+        k++;    
+    }
+  }
+
+  return MEMS_SUCCESS; 
+}
+
+/*******************************************************************************
+* Function Name  : mems_status_t LSM6DSL_ACC_Get_AngularRate(u8_t *buff)
+* Description    : Read GetGyroData output register
+* Input          : pointer to [u8_t]
+* Output         : Returned values are espressed in mdps
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+/*
+ * Following is the table of sensitivity values for each case.
+ * Values are espressed in udps/digit.
+ */
+static const long long LSM6DSL_GYRO_Sensitivity_List[5] = {
+      4375, /* FS @125 */
+      8750, /* FS @245 */
+      17500,    /* FS @500 */
+      35000,    /* FS @1000 */
+      70000,    /* FS @2000 */
+};
+mems_status_t LSM6DSL_ACC_Get_AngularRate(void *handle, int *buff, u8_t from_fifo)
+{
+  LSM6DSL_ACC_GYRO_FS_125_t fs_125;
+  LSM6DSL_ACC_GYRO_FS_G_t fs;
+  long long sensitivity = 0;
+  Type3Axis16bit_U raw_data_tmp;
+
+  /* Read out current odr, fs, hf setting */
+  LSM6DSL_ACC_GYRO_R_FS_125(handle, &fs_125);
+  if (fs_125 == LSM6DSL_ACC_GYRO_FS_125_ENABLED) {
+    sensitivity = LSM6DSL_GYRO_Sensitivity_List[0];
+  } else {
+    LSM6DSL_ACC_GYRO_R_FS_G(handle, &fs);
+
+    /* Determine the sensitivity according to fs */
+    switch(fs) {
+    case LSM6DSL_ACC_GYRO_FS_G_245dps:
+      sensitivity = LSM6DSL_GYRO_Sensitivity_List[1];
+      break;
+
+    case LSM6DSL_ACC_GYRO_FS_G_500dps:
+      sensitivity = LSM6DSL_GYRO_Sensitivity_List[2];
+      break;
+
+    case LSM6DSL_ACC_GYRO_FS_G_1000dps:
+      sensitivity = LSM6DSL_GYRO_Sensitivity_List[3];
+      break;
+
+    case LSM6DSL_ACC_GYRO_FS_G_2000dps:
+      sensitivity = LSM6DSL_GYRO_Sensitivity_List[4];
+      break;
+    }
+  }
+
+  /* Read out raw accelerometer samples */
+  if (from_fifo) {
+    u8_t i;
+
+    /* read all 3 axis from FIFO */
+    for(i = 0; i < 3; i++)
+      LSM6DSL_ACC_GYRO_Get_GetFIFOData(handle, raw_data_tmp.u8bit + 2*i);
+  } else
+    LSM6DSL_ACC_GYRO_GetRawGyroData(handle, raw_data_tmp.u8bit);
+
+  /* Apply proper shift and sensitivity */
+  buff[0] = (raw_data_tmp.i16bit[0] * sensitivity + 500)/1000;
+  buff[1] = (raw_data_tmp.i16bit[1] * sensitivity + 500)/1000;
+  buff[2] = (raw_data_tmp.i16bit[2] * sensitivity + 500)/1000;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_ODR_G
+* Description    : Write ODR_G
+* Input          : LSM6DSL_ACC_GYRO_ODR_G_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_ODR_G(void *handle, LSM6DSL_ACC_GYRO_ODR_G_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL2_G, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_ODR_G_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL2_G, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_ODR_G
+* Description    : Read ODR_G
+* Input          : Pointer to LSM6DSL_ACC_GYRO_ODR_G_t
+* Output         : Status of ODR_G see LSM6DSL_ACC_GYRO_ODR_G_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_ODR_G(void *handle, LSM6DSL_ACC_GYRO_ODR_G_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL2_G, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_ODR_G_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_translate_ODR_G
+* Description    : Read ODR_G
+* Input          : LSM6DSL_ACC_GYRO_ODR_G_t
+* Output         : The ODR value in Hz
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_translate_ODR_G(LSM6DSL_ACC_GYRO_ODR_G_t value, u16_t *odr_hz_val)
+{
+  switch(value) {
+  case LSM6DSL_ACC_GYRO_ODR_G_POWER_DOWN:
+    *odr_hz_val = 0;
+    break;
+
+  case LSM6DSL_ACC_GYRO_ODR_G_13Hz:
+    *odr_hz_val = 13;
+    break;
+
+  case LSM6DSL_ACC_GYRO_ODR_G_26Hz:
+    *odr_hz_val = 26;
+    break;
+
+  case LSM6DSL_ACC_GYRO_ODR_G_52Hz:
+    *odr_hz_val = 52;
+    break;
+
+  case LSM6DSL_ACC_GYRO_ODR_G_104Hz:
+    *odr_hz_val = 104;
+    break;
+
+  case LSM6DSL_ACC_GYRO_ODR_G_208Hz:
+    *odr_hz_val = 208;
+    break;
+
+  case LSM6DSL_ACC_GYRO_ODR_G_416Hz:
+    *odr_hz_val = 416;
+    break;
+
+  case LSM6DSL_ACC_GYRO_ODR_G_833Hz:
+    *odr_hz_val = 833;
+    break;
+
+  case LSM6DSL_ACC_GYRO_ODR_G_1660Hz:
+    *odr_hz_val = 1660;
+    break;
+
+  default:
+    return MEMS_ERROR;
+  }
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_FS_125
+* Description    : Write FS_125
+* Input          : LSM6DSL_ACC_GYRO_FS_125_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_FS_125(void *handle, LSM6DSL_ACC_GYRO_FS_125_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL2_G, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_FS_125_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL2_G, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FS_125
+* Description    : Read FS_125
+* Input          : Pointer to LSM6DSL_ACC_GYRO_FS_125_t
+* Output         : Status of FS_125 see LSM6DSL_ACC_GYRO_FS_125_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FS_125(void *handle, LSM6DSL_ACC_GYRO_FS_125_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL2_G, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_FS_125_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/**************** Advanced Function  *******************/
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_BW_SEL
+* Description    : Write BW_SEL
+* Input          : LSM6DSL_ACC_GYRO_BW_SEL_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_BW_SEL(void *handle, LSM6DSL_ACC_GYRO_BW_SEL_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL1_XL, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_BW_SEL_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL1_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_BW_SEL
+* Description    : Read BW_SEL
+* Input          : Pointer to LSM6DSL_ACC_GYRO_BW_SEL_t
+* Output         : Status of BW_SEL see LSM6DSL_ACC_GYRO_BW_SEL_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_BW_SEL(void *handle, LSM6DSL_ACC_GYRO_BW_SEL_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL1_XL, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_BW_SEL_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_BLE
+* Description    : Write BLE
+* Input          : LSM6DSL_ACC_GYRO_BLE_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_BLE(void *handle, LSM6DSL_ACC_GYRO_BLE_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_BLE_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_BLE
+* Description    : Read BLE
+* Input          : Pointer to LSM6DSL_ACC_GYRO_BLE_t
+* Output         : Status of BLE see LSM6DSL_ACC_GYRO_BLE_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_BLE(void *handle, LSM6DSL_ACC_GYRO_BLE_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_BLE_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_EmbeddedAccess
+* Description    : Write EMB_ACC
+* Input          : LSM6DSL_ACC_GYRO_EMB_ACC_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_EmbeddedAccess(void *handle, LSM6DSL_ACC_GYRO_EMB_ACC_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FUNC_CFG_ACCESS, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_EMB_ACC_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_FUNC_CFG_ACCESS, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_EmbeddedAccess
+* Description    : Read EMB_ACC
+* Input          : Pointer to LSM6DSL_ACC_GYRO_EMB_ACC_t
+* Output         : Status of EMB_ACC see LSM6DSL_ACC_GYRO_EMB_ACC_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_EmbeddedAccess(void *handle, LSM6DSL_ACC_GYRO_EMB_ACC_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FUNC_CFG_ACCESS, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_EMB_ACC_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SYNC_RES_RATIO
+* Description    : Write RR
+* Input          : LSM6DSL_ACC_GYRO_SYNC_RES_RATIO_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SYNC_RES_RATIO(void *handle, LSM6DSL_ACC_GYRO_SYNC_RES_RATIO_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_SENSOR_RES_RATIO, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_SYNC_RES_RATIO_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_SENSOR_RES_RATIO, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SYNC_RES_RATIO
+* Description    : Read RR
+* Input          : Pointer to LSM6DSL_ACC_GYRO_SYNC_RES_RATIO_t
+* Output         : Status of RR see LSM6DSL_ACC_GYRO_SYNC_RES_RATIO_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SYNC_RES_RATIO(void *handle, LSM6DSL_ACC_GYRO_SYNC_RES_RATIO_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_SENSOR_RES_RATIO, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_SYNC_RES_RATIO_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_Stamping_Time_Frame
+* Description    : Write TPH
+* Input          : u8_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_Stamping_Time_Frame(void *handle, u8_t newValue)
+{
+  u8_t value;
+
+  newValue = newValue << LSM6DSL_ACC_GYRO_TPH_POSITION; //mask  
+  newValue &= LSM6DSL_ACC_GYRO_TPH_MASK; //coerce
+  
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_SENSOR_SYNC_TIME, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= (u8_t)~LSM6DSL_ACC_GYRO_TPH_MASK;
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_SENSOR_SYNC_TIME, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_Stamping_Time_Frame
+* Description    : Read TPH
+* Input          : Pointer to u8_t
+* Output         : Status of TPH 
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_Stamping_Time_Frame(void *handle, u8_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_SENSOR_SYNC_TIME, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_TPH_MASK; //coerce 
+  *value = *value >> LSM6DSL_ACC_GYRO_TPH_POSITION; //mask  
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_FIFO_Watermark
+* Description    : Write WTM_FIFO
+* Input          : u16_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_FIFO_Watermark(void *handle, u16_t newValue)
+{
+  u8_t valueH, valueL;
+  u8_t value;
+
+  valueL = newValue & 0xFF;
+  valueH = (newValue >> 8) & 0xFF;
+  
+  /* Low part goes in FIFO_CTRL1 */
+  valueL = valueL << LSM6DSL_ACC_GYRO_WTM_FIFO_CTRL1_POSITION; //mask   
+  valueL &= LSM6DSL_ACC_GYRO_WTM_FIFO_CTRL1_MASK; //coerce
+  
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL1, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= (u8_t)~LSM6DSL_ACC_GYRO_WTM_FIFO_CTRL1_MASK;
+  value |= valueL;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL1, &value, 1) )
+    return MEMS_ERROR;
+
+  /* High part goes in FIFO_CTRL2 */
+  valueH = valueH << LSM6DSL_ACC_GYRO_WTM_FIFO_CTRL2_POSITION; //mask   
+  valueH &= LSM6DSL_ACC_GYRO_WTM_FIFO_CTRL2_MASK; //coerce
+  
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL2, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_WTM_FIFO_CTRL2_MASK; 
+  value |= valueH;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL2, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FIFO_Watermark
+* Description    : Read WTM_FIFO
+* Input          : Pointer to u16_t
+* Output         : Status of WTM_FIFO 
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFO_Watermark(void *handle, u16_t *value)
+{
+  u8_t valueH, valueL;
+
+  /* Low part from FIFO_CTRL1 */
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL1, (u8_t *)&valueL, 1) )
+    return MEMS_ERROR;
+
+  valueL &= LSM6DSL_ACC_GYRO_WTM_FIFO_CTRL1_MASK; //coerce
+  valueL = valueL >> LSM6DSL_ACC_GYRO_WTM_FIFO_CTRL1_POSITION; //mask
+
+  /* High part from FIFO_CTRL2 */
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL2, (u8_t *)&valueH, 1) )
+    return MEMS_ERROR;
+
+  valueH &= LSM6DSL_ACC_GYRO_WTM_FIFO_CTRL2_MASK; //coerce
+  valueH = valueH >> LSM6DSL_ACC_GYRO_WTM_FIFO_CTRL2_POSITION; //mask
+
+  *value = ((valueH << 8) & 0xFF00) | valueL;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_FIFO_TEMP
+* Description    : Write FIFO_TEMP_EN
+* Input          : LSM6DSL_ACC_GYRO_FIFO_TEMP_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_FIFO_TEMP(void *handle, LSM6DSL_ACC_GYRO_FIFO_TEMP_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL2, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_FIFO_TEMP_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL2, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FIFO_TEMP
+* Description    : Read FIFO_TEMP_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_FIFO_TEMP_t
+* Output         : Status of FIFO_TEMP_EN see LSM6DSL_ACC_GYRO_FIFO_TEMP_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFO_TEMP(void *handle, LSM6DSL_ACC_GYRO_FIFO_TEMP_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL2, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_FIFO_TEMP_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_TIM_PEDO_FIFO_Write_En
+* Description    : Write TIM_PEDO_FIFO_DRDY
+* Input          : LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_DRDY_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_TIM_PEDO_FIFO_Write_En(void *handle, LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_DRDY_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL2, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_DRDY_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL2, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TIM_PEDO_FIFO_Write_En
+* Description    : Read TIM_PEDO_FIFO_DRDY
+* Input          : Pointer to LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_DRDY_t
+* Output         : Status of TIM_PEDO_FIFO_DRDY see LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_DRDY_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TIM_PEDO_FIFO_Write_En(void *handle, LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_DRDY_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL2, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_DRDY_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_TIM_PEDO_FIFO_En
+* Description    : Write TIM_PEDO_FIFO_EN
+* Input          : LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_EN_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_TIM_PEDO_FIFO_En(void *handle, LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_EN_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL2, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_EN_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL2, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TIM_PEDO_FIFO_En
+* Description    : Read TIM_PEDO_FIFO_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_EN_t
+* Output         : Status of TIM_PEDO_FIFO_EN see LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_EN_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TIM_PEDO_FIFO_En(void *handle, LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_EN_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL2, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_EN_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DEC_FIFO_XL
+* Description    : Write DEC_FIFO_XL
+* Input          : LSM6DSL_ACC_GYRO_DEC_FIFO_XL_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DEC_FIFO_XL(void *handle, LSM6DSL_ACC_GYRO_DEC_FIFO_XL_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL3, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_DEC_FIFO_XL_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL3, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DEC_FIFO_XL_val
+* Description    : Write DEC_FIFO_XL
+* Input          : u16_t
+* Output         : Program XL decimation value from unsigned short
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DEC_FIFO_XL_val(void *handle, u16_t newValue)
+{
+  switch(newValue) {
+  case 0:
+    LSM6DSL_ACC_GYRO_W_DEC_FIFO_XL(handle, LSM6DSL_ACC_GYRO_DEC_FIFO_XL_DATA_NOT_IN_FIFO);
+    break;
+
+  case 1:
+    LSM6DSL_ACC_GYRO_W_DEC_FIFO_XL(handle, LSM6DSL_ACC_GYRO_DEC_FIFO_XL_NO_DECIMATION);
+    break;
+
+  case 2:
+    LSM6DSL_ACC_GYRO_W_DEC_FIFO_XL(handle, LSM6DSL_ACC_GYRO_DEC_FIFO_XL_DECIMATION_BY_2);
+    break;
+
+  case 3:
+    LSM6DSL_ACC_GYRO_W_DEC_FIFO_XL(handle, LSM6DSL_ACC_GYRO_DEC_FIFO_XL_DECIMATION_BY_3);
+    break;
+
+  case 4:
+    LSM6DSL_ACC_GYRO_W_DEC_FIFO_XL(handle, LSM6DSL_ACC_GYRO_DEC_FIFO_XL_DECIMATION_BY_4);
+    break;
+
+  case 8:
+    LSM6DSL_ACC_GYRO_W_DEC_FIFO_XL(handle, LSM6DSL_ACC_GYRO_DEC_FIFO_XL_DECIMATION_BY_8);
+    break;
+
+  case 16:
+    LSM6DSL_ACC_GYRO_W_DEC_FIFO_XL(handle, LSM6DSL_ACC_GYRO_DEC_FIFO_XL_DECIMATION_BY_16);
+    break;
+
+  case 32:
+    LSM6DSL_ACC_GYRO_W_DEC_FIFO_XL(handle, LSM6DSL_ACC_GYRO_DEC_FIFO_XL_DECIMATION_BY_32);
+    break;
+
+  default:
+    return MEMS_ERROR;
+  }
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DEC_FIFO_XL
+* Description    : Read DEC_FIFO_XL
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DEC_FIFO_XL_t
+* Output         : Status of DEC_FIFO_XL see LSM6DSL_ACC_GYRO_DEC_FIFO_XL_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DEC_FIFO_XL(void *handle, LSM6DSL_ACC_GYRO_DEC_FIFO_XL_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL3, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DEC_FIFO_XL_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DEC_FIFO_G
+* Description    : Write DEC_FIFO_G
+* Input          : LSM6DSL_ACC_GYRO_DEC_FIFO_G_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DEC_FIFO_G(void *handle, LSM6DSL_ACC_GYRO_DEC_FIFO_G_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL3, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_DEC_FIFO_G_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL3, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DEC_FIFO_G_val
+* Description    : Write DEC_FIFO_G
+* Input          : u16_t
+* Output         : Program G decimation value from unsigned short
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DEC_FIFO_G_val(void *handle, u16_t newValue)
+{
+  switch(newValue) {
+  case 0:
+    LSM6DSL_ACC_GYRO_W_DEC_FIFO_G(handle, LSM6DSL_ACC_GYRO_DEC_FIFO_G_DATA_NOT_IN_FIFO);
+    break;
+
+  case 1:
+    LSM6DSL_ACC_GYRO_W_DEC_FIFO_G(handle, LSM6DSL_ACC_GYRO_DEC_FIFO_G_NO_DECIMATION);
+    break;
+
+  case 2:
+    LSM6DSL_ACC_GYRO_W_DEC_FIFO_G(handle, LSM6DSL_ACC_GYRO_DEC_FIFO_G_DECIMATION_BY_2);
+    break;
+
+  case 3:
+    LSM6DSL_ACC_GYRO_W_DEC_FIFO_G(handle, LSM6DSL_ACC_GYRO_DEC_FIFO_G_DECIMATION_BY_3);
+    break;
+
+  case 4:
+    LSM6DSL_ACC_GYRO_W_DEC_FIFO_G(handle, LSM6DSL_ACC_GYRO_DEC_FIFO_G_DECIMATION_BY_4);
+    break;
+
+  case 8:
+    LSM6DSL_ACC_GYRO_W_DEC_FIFO_G(handle, LSM6DSL_ACC_GYRO_DEC_FIFO_G_DECIMATION_BY_8);
+    break;
+
+  case 16:
+    LSM6DSL_ACC_GYRO_W_DEC_FIFO_G(handle, LSM6DSL_ACC_GYRO_DEC_FIFO_G_DECIMATION_BY_16);
+    break;
+
+  case 32:
+    LSM6DSL_ACC_GYRO_W_DEC_FIFO_G(handle, LSM6DSL_ACC_GYRO_DEC_FIFO_G_DECIMATION_BY_32);
+    break;
+
+  default:
+    return MEMS_ERROR;
+  }
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DEC_FIFO_G
+* Description    : Read DEC_FIFO_G
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DEC_FIFO_G_t
+* Output         : Status of DEC_FIFO_G see LSM6DSL_ACC_GYRO_DEC_FIFO_G_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DEC_FIFO_G(void *handle, LSM6DSL_ACC_GYRO_DEC_FIFO_G_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL3, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DEC_FIFO_G_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DEC_FIFO_DS3
+* Description    : Write DEC_DS3_FIFO
+* Input          : LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DEC_FIFO_DS3(void *handle, LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL4, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL4, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DEC_FIFO_DS3
+* Description    : Read DEC_DS3_FIFO
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_t
+* Output         : Status of DEC_DS3_FIFO see LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DEC_FIFO_DS3(void *handle, LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL4, (u8_t *)value, 1))
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DEC_FIFO_DS4
+* Description    : Write DEC_DS4_FIFO
+* Input          : LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DEC_FIFO_DS4(void *handle, LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL4, &value, 1))
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL4, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DEC_FIFO_DS4
+* Description    : Read DEC_DS4_FIFO
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_t
+* Output         : Status of DEC_DS4_FIFO see LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DEC_FIFO_DS4(void *handle, LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL4, (u8_t *)value, 1))
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_HI_DATA_ONLY
+* Description    : Write HI_DATA_ONLY
+* Input          : LSM6DSL_ACC_GYRO_HI_DATA_ONLY_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_HI_DATA_ONLY(void *handle, LSM6DSL_ACC_GYRO_HI_DATA_ONLY_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL4, &value, 1))
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_HI_DATA_ONLY_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL4, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_HI_DATA_ONLY
+* Description    : Read HI_DATA_ONLY
+* Input          : Pointer to LSM6DSL_ACC_GYRO_HI_DATA_ONLY_t
+* Output         : Status of HI_DATA_ONLY see LSM6DSL_ACC_GYRO_HI_DATA_ONLY_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_HI_DATA_ONLY(void *handle, LSM6DSL_ACC_GYRO_HI_DATA_ONLY_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL4, (u8_t *)value, 1))
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_HI_DATA_ONLY_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_STOP_ON_FTH
+* Description    : Write STOP_ON_FTH
+* Input          : LSM6DSL_ACC_GYRO_STOP_ON_FTH_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_STOP_ON_FTH(void *handle, LSM6DSL_ACC_GYRO_STOP_ON_FTH_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL4, &value, 1))
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_STOP_ON_FTH_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL4, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_STOP_ON_FTH
+* Description    : Read STOP_ON_FTH
+* Input          : Pointer to LSM6DSL_ACC_GYRO_STOP_ON_FTH_t
+* Output         : Status of STOP_ON_FTH see LSM6DSL_ACC_GYRO_STOP_ON_FTH_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_STOP_ON_FTH(void *handle, LSM6DSL_ACC_GYRO_STOP_ON_FTH_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL4, (u8_t *)value, 1))
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_STOP_ON_FTH_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_FIFO_MODE
+* Description    : Write FIFO_MODE
+* Input          : LSM6DSL_ACC_GYRO_FIFO_MODE_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_FIFO_MODE(void *handle, LSM6DSL_ACC_GYRO_FIFO_MODE_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL5, &value, 1))
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_FIFO_MODE_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL5, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FIFO_MODE
+* Description    : Read FIFO_MODE
+* Input          : Pointer to LSM6DSL_ACC_GYRO_FIFO_MODE_t
+* Output         : Status of FIFO_MODE see LSM6DSL_ACC_GYRO_FIFO_MODE_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFO_MODE(void *handle, LSM6DSL_ACC_GYRO_FIFO_MODE_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL5, (u8_t *)value, 1))
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_FIFO_MODE_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_ODR_FIFO
+* Description    : Write ODR_FIFO
+* Input          : LSM6DSL_ACC_GYRO_ODR_FIFO_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_ODR_FIFO(void *handle, LSM6DSL_ACC_GYRO_ODR_FIFO_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL5, &value, 1))
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_ODR_FIFO_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL5, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_ODR_FIFO
+* Description    : Read ODR_FIFO
+* Input          : Pointer to LSM6DSL_ACC_GYRO_ODR_FIFO_t
+* Output         : Status of ODR_FIFO see LSM6DSL_ACC_GYRO_ODR_FIFO_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_ODR_FIFO(void *handle, LSM6DSL_ACC_GYRO_ODR_FIFO_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_CTRL5, (u8_t *)value, 1))
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_ODR_FIFO_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DRDY_PULSE
+* Description    : Write DRDY_PULSE
+* Input          : LSM6DSL_ACC_GYRO_DRDY_PULSE_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DRDY_PULSE(void *handle, LSM6DSL_ACC_GYRO_DRDY_PULSE_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_DRDY_PULSE_CFG_G, &value, 1))
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_DRDY_PULSE_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_DRDY_PULSE_CFG_G, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DRDY_PULSE
+* Description    : Read DRDY_PULSE
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DRDY_PULSE_t
+* Output         : Status of DRDY_PULSE see LSM6DSL_ACC_GYRO_DRDY_PULSE_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DRDY_PULSE(void *handle, LSM6DSL_ACC_GYRO_DRDY_PULSE_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_DRDY_PULSE_CFG_G, (u8_t *)value, 1))
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DRDY_PULSE_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DRDY_XL_on_INT1
+* Description    : Write INT1_DRDY_XL
+* Input          : LSM6DSL_ACC_GYRO_INT1_DRDY_XL_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DRDY_XL_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_DRDY_XL_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, &value, 1))
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT1_DRDY_XL_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DRDY_XL_on_INT1
+* Description    : Read INT1_DRDY_XL
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT1_DRDY_XL_t
+* Output         : Status of INT1_DRDY_XL see LSM6DSL_ACC_GYRO_INT1_DRDY_XL_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DRDY_XL_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_DRDY_XL_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, (u8_t *)value, 1))
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT1_DRDY_XL_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DRDY_G_on_INT1
+* Description    : Write INT1_DRDY_G
+* Input          : LSM6DSL_ACC_GYRO_INT1_DRDY_G_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DRDY_G_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_DRDY_G_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, &value, 1))
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT1_DRDY_G_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DRDY_G_on_INT1
+* Description    : Read INT1_DRDY_G
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT1_DRDY_G_t
+* Output         : Status of INT1_DRDY_G see LSM6DSL_ACC_GYRO_INT1_DRDY_G_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DRDY_G_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_DRDY_G_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT1_DRDY_G_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_BOOT_on_INT1
+* Description    : Write INT1_BOOT
+* Input          : LSM6DSL_ACC_GYRO_INT1_BOOT_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_BOOT_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_BOOT_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT1_BOOT_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_BOOT_on_INT1
+* Description    : Read INT1_BOOT
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT1_BOOT_t
+* Output         : Status of INT1_BOOT see LSM6DSL_ACC_GYRO_INT1_BOOT_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_BOOT_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_BOOT_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, (u8_t *)value, 1))
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT1_BOOT_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_FIFO_TSHLD_on_INT1
+* Description    : Write INT1_FTH
+* Input          : LSM6DSL_ACC_GYRO_INT1_FTH_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_FIFO_TSHLD_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_FTH_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT1_FTH_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FIFO_TSHLD_on_INT1
+* Description    : Read INT1_FTH
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT1_FTH_t
+* Output         : Status of INT1_FTH see LSM6DSL_ACC_GYRO_INT1_FTH_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFO_TSHLD_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_FTH_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT1_FTH_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_OVERRUN_on_INT1
+* Description    : Write INT1_OVR
+* Input          : LSM6DSL_ACC_GYRO_INT1_OVR_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_OVERRUN_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_OVR_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT1_OVR_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, &value, 1))
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_OVERRUN_on_INT1
+* Description    : Read INT1_OVR
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT1_OVR_t
+* Output         : Status of INT1_OVR see LSM6DSL_ACC_GYRO_INT1_OVR_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_OVERRUN_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_OVR_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT1_OVR_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_FULL_FLAG_on_INT1
+* Description    : Write INT1_FULL_FLAG
+* Input          : LSM6DSL_ACC_GYRO_INT1_FULL_FLAG_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_FULL_FLAG_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_FULL_FLAG_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT1_FULL_FLAG_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FULL_FLAG_on_INT1
+* Description    : Read INT1_FULL_FLAG
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT1_FULL_FLAG_t
+* Output         : Status of INT1_FULL_FLAG see LSM6DSL_ACC_GYRO_INT1_FULL_FLAG_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FULL_FLAG_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_FULL_FLAG_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT1_FULL_FLAG_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SIGN_MOT_on_INT1
+* Description    : Write INT1_SIGN_MOT
+* Input          : LSM6DSL_ACC_GYRO_INT1_SIGN_MOT_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SIGN_MOT_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_SIGN_MOT_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT1_SIGN_MOT_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SIGN_MOT_on_INT1
+* Description    : Read INT1_SIGN_MOT
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT1_SIGN_MOT_t
+* Output         : Status of INT1_SIGN_MOT see LSM6DSL_ACC_GYRO_INT1_SIGN_MOT_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SIGN_MOT_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_SIGN_MOT_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT1_SIGN_MOT_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_STEP_DET_on_INT1
+* Description    : Write INT1_PEDO
+* Input          : LSM6DSL_ACC_GYRO_INT1_PEDO_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_STEP_DET_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_PEDO_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT1_PEDO_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_STEP_DET_on_INT1
+* Description    : Read INT1_PEDO
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT1_PEDO_t
+* Output         : Status of INT1_PEDO see LSM6DSL_ACC_GYRO_INT1_PEDO_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_STEP_DET_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_PEDO_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT1_CTRL, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT1_PEDO_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DRDY_XL_on_INT2
+* Description    : Write INT2_DRDY_XL
+* Input          : LSM6DSL_ACC_GYRO_INT2_DRDY_XL_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DRDY_XL_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_DRDY_XL_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_DRDY_XL_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DRDY_XL_on_INT2
+* Description    : Read INT2_DRDY_XL
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_DRDY_XL_t
+* Output         : Status of INT2_DRDY_XL see LSM6DSL_ACC_GYRO_INT2_DRDY_XL_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DRDY_XL_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_DRDY_XL_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_DRDY_XL_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DRDY_G_on_INT2
+* Description    : Write INT2_DRDY_G
+* Input          : LSM6DSL_ACC_GYRO_INT2_DRDY_G_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DRDY_G_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_DRDY_G_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_DRDY_G_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DRDY_G_on_INT2
+* Description    : Read INT2_DRDY_G
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_DRDY_G_t
+* Output         : Status of INT2_DRDY_G see LSM6DSL_ACC_GYRO_INT2_DRDY_G_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DRDY_G_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_DRDY_G_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_DRDY_G_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DRDY_TEMP_on_INT2
+* Description    : Write INT2_DRDY_TEMP
+* Input          : LSM6DSL_ACC_GYRO_INT2_DRDY_TEMP_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DRDY_TEMP_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_DRDY_TEMP_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_DRDY_TEMP_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DRDY_TEMP_on_INT2
+* Description    : Read INT2_DRDY_TEMP
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_DRDY_TEMP_t
+* Output         : Status of INT2_DRDY_TEMP see LSM6DSL_ACC_GYRO_INT2_DRDY_TEMP_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DRDY_TEMP_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_DRDY_TEMP_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_DRDY_TEMP_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_FIFO_TSHLD_on_INT2
+* Description    : Write INT2_FTH
+* Input          : LSM6DSL_ACC_GYRO_INT2_FTH_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_FIFO_TSHLD_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_FTH_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_FTH_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FIFO_TSHLD_on_INT2
+* Description    : Read INT2_FTH
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_FTH_t
+* Output         : Status of INT2_FTH see LSM6DSL_ACC_GYRO_INT2_FTH_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFO_TSHLD_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_FTH_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_FTH_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_OVERRUN_on_INT2
+* Description    : Write INT2_OVR
+* Input          : LSM6DSL_ACC_GYRO_INT2_OVR_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_OVERRUN_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_OVR_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_OVR_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_OVERRUN_on_INT2
+* Description    : Read INT2_OVR
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_OVR_t
+* Output         : Status of INT2_OVR see LSM6DSL_ACC_GYRO_INT2_OVR_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_OVERRUN_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_OVR_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_OVR_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_FULL_FLAG_on_INT2
+* Description    : Write INT2_FULL_FLAG
+* Input          : LSM6DSL_ACC_GYRO_INT2_FULL_FLAG_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_FULL_FLAG_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_FULL_FLAG_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_FULL_FLAG_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FULL_FLAG_on_INT2
+* Description    : Read INT2_FULL_FLAG
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_FULL_FLAG_t
+* Output         : Status of INT2_FULL_FLAG see LSM6DSL_ACC_GYRO_INT2_FULL_FLAG_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FULL_FLAG_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_FULL_FLAG_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_FULL_FLAG_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_STEP_COUNT_OV_on_INT2
+* Description    : Write INT2_STEP_COUNT_OV
+* Input          : LSM6DSL_ACC_GYRO_INT2_STEP_COUNT_OV_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_STEP_COUNT_OV_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_STEP_COUNT_OV_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_STEP_COUNT_OV_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_STEP_COUNT_OV_on_INT2
+* Description    : Read INT2_STEP_COUNT_OV
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_STEP_COUNT_OV_t
+* Output         : Status of INT2_STEP_COUNT_OV see LSM6DSL_ACC_GYRO_INT2_STEP_COUNT_OV_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_STEP_COUNT_OV_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_STEP_COUNT_OV_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_STEP_COUNT_OV_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_STEP_DELTA_on_INT2
+* Description    : Write INT2_STEP_DELTA
+* Input          : LSM6DSL_ACC_GYRO_INT2_STEP_DELTA_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_STEP_DELTA_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_STEP_DELTA_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_STEP_DELTA_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_STEP_DELTA_on_INT2
+* Description    : Read INT2_STEP_DELTA
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_STEP_DELTA_t
+* Output         : Status of INT2_STEP_DELTA see LSM6DSL_ACC_GYRO_INT2_STEP_DELTA_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_STEP_DELTA_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_STEP_DELTA_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT2_CTRL, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_STEP_DELTA_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SW_RESET
+* Description    : Write SW_RESET
+* Input          : LSM6DSL_ACC_GYRO_SW_RESET_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SW_RESET(void *handle, LSM6DSL_ACC_GYRO_SW_RESET_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_SW_RESET_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SW_RESET
+* Description    : Read SW_RESET
+* Input          : Pointer to LSM6DSL_ACC_GYRO_SW_RESET_t
+* Output         : Status of SW_RESET see LSM6DSL_ACC_GYRO_SW_RESET_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SW_RESET(void *handle, LSM6DSL_ACC_GYRO_SW_RESET_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_SW_RESET_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_IF_Addr_Incr
+* Description    : Write IF_INC
+* Input          : LSM6DSL_ACC_GYRO_IF_INC_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_IF_Addr_Incr(void *handle, LSM6DSL_ACC_GYRO_IF_INC_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_IF_INC_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_IF_Addr_Incr
+* Description    : Read IF_INC
+* Input          : Pointer to LSM6DSL_ACC_GYRO_IF_INC_t
+* Output         : Status of IF_INC see LSM6DSL_ACC_GYRO_IF_INC_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_IF_Addr_Incr(void *handle, LSM6DSL_ACC_GYRO_IF_INC_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_IF_INC_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SPI_Mode
+* Description    : Write SIM
+* Input          : LSM6DSL_ACC_GYRO_SIM_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SPI_Mode(void *handle, LSM6DSL_ACC_GYRO_SIM_t newValue)
+{
+  u8_t value=0x04;
+
+//  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, &value, 1)) 
+//    return MEMS_ERROR;  /** FIXED not possible to read in 3w as deft spi is 4w
+
+  value &= ~LSM6DSL_ACC_GYRO_SIM_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SPI_Mode
+* Description    : Read SIM
+* Input          : Pointer to LSM6DSL_ACC_GYRO_SIM_t
+* Output         : Status of SIM see LSM6DSL_ACC_GYRO_SIM_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SPI_Mode(void *handle, LSM6DSL_ACC_GYRO_SIM_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_SIM_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_PadSel
+* Description    : Write PP_OD
+* Input          : LSM6DSL_ACC_GYRO_PP_OD_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_PadSel(void *handle, LSM6DSL_ACC_GYRO_PP_OD_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_PP_OD_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_PadSel
+* Description    : Read PP_OD
+* Input          : Pointer to LSM6DSL_ACC_GYRO_PP_OD_t
+* Output         : Status of PP_OD see LSM6DSL_ACC_GYRO_PP_OD_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_PadSel(void *handle, LSM6DSL_ACC_GYRO_PP_OD_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_PP_OD_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_INT_ACT_LEVEL
+* Description    : Write INT_ACT_LEVEL
+* Input          : LSM6DSL_ACC_GYRO_INT_ACT_LEVEL_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_INT_ACT_LEVEL(void *handle, LSM6DSL_ACC_GYRO_INT_ACT_LEVEL_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT_ACT_LEVEL_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_INT_ACT_LEVEL
+* Description    : Read INT_ACT_LEVEL
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT_ACT_LEVEL_t
+* Output         : Status of INT_ACT_LEVEL see LSM6DSL_ACC_GYRO_INT_ACT_LEVEL_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_INT_ACT_LEVEL(void *handle, LSM6DSL_ACC_GYRO_INT_ACT_LEVEL_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT_ACT_LEVEL_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_BOOT
+* Description    : Write BOOT
+* Input          : LSM6DSL_ACC_GYRO_BOOT_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_BOOT(void *handle, LSM6DSL_ACC_GYRO_BOOT_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_BOOT_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_BOOT
+* Description    : Read BOOT
+* Input          : Pointer to LSM6DSL_ACC_GYRO_BOOT_t
+* Output         : Status of BOOT see LSM6DSL_ACC_GYRO_BOOT_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_BOOT(void *handle, LSM6DSL_ACC_GYRO_BOOT_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL3_C, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_BOOT_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_LPF1_SEL_G
+* Description    : Write LPF1_SEL_G
+* Input          : LSM6DSL_ACC_GYRO_LPF1_SEL_G_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_LPF1_SEL_G(void *handle, LSM6DSL_ACC_GYRO_LPF1_SEL_G_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL4_C, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_LPF1_SEL_G_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL4_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_LPF1_SEL_G
+* Description    : Read LPF1_SEL_G
+* Input          : Pointer to LSM6DSL_ACC_GYRO_LPF1_SEL_G_t
+* Output         : Status of LPF1_SEL_G see LSM6DSL_ACC_GYRO_LPF1_SEL_G_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_LPF1_SEL_G(void *handle, LSM6DSL_ACC_GYRO_LPF1_SEL_G_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL4_C, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_LPF1_SEL_G_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_I2C_DISABLE
+* Description    : Write I2C_DISABLE
+* Input          : LSM6DSL_ACC_GYRO_I2C_DISABLE_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_I2C_DISABLE(void *handle, LSM6DSL_ACC_GYRO_I2C_DISABLE_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL4_C, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_I2C_DISABLE_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL4_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_I2C_DISABLE
+* Description    : Read I2C_DISABLE
+* Input          : Pointer to LSM6DSL_ACC_GYRO_I2C_DISABLE_t
+* Output         : Status of I2C_DISABLE see LSM6DSL_ACC_GYRO_I2C_DISABLE_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_I2C_DISABLE(void *handle, LSM6DSL_ACC_GYRO_I2C_DISABLE_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL4_C, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_I2C_DISABLE_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DRDY_MSK
+* Description    : Write DRDY_MSK
+* Input          : LSM6DSL_ACC_GYRO_DRDY_MSK_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DRDY_MSK(void *handle, LSM6DSL_ACC_GYRO_DRDY_MSK_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL4_C, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_DRDY_MSK_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL4_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DRDY_MSK
+* Description    : Read DRDY_MSK
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DRDY_MSK_t
+* Output         : Status of DRDY_MSK see LSM6DSL_ACC_GYRO_DRDY_MSK_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DRDY_MSK(void *handle, LSM6DSL_ACC_GYRO_DRDY_MSK_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL4_C, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DRDY_MSK_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_INT2_ON_INT1
+* Description    : Write INT2_ON_INT1
+* Input          : LSM6DSL_ACC_GYRO_INT2_ON_INT1_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_INT2_ON_INT1(void *handle, LSM6DSL_ACC_GYRO_INT2_ON_INT1_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL4_C, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_ON_INT1_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL4_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_INT2_ON_INT1
+* Description    : Read INT2_ON_INT1
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_ON_INT1_t
+* Output         : Status of INT2_ON_INT1 see LSM6DSL_ACC_GYRO_INT2_ON_INT1_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_INT2_ON_INT1(void *handle, LSM6DSL_ACC_GYRO_INT2_ON_INT1_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL4_C, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_ON_INT1_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SleepMode_G
+* Description    : Write SLEEP_G
+* Input          : LSM6DSL_ACC_GYRO_SLEEP_G_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SleepMode_G(void *handle, LSM6DSL_ACC_GYRO_SLEEP_G_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL4_C, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_SLEEP_G_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL4_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SleepMode_G
+* Description    : Read SLEEP_G
+* Input          : Pointer to LSM6DSL_ACC_GYRO_SLEEP_G_t
+* Output         : Status of SLEEP_G see LSM6DSL_ACC_GYRO_SLEEP_G_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SleepMode_G(void *handle, LSM6DSL_ACC_GYRO_SLEEP_G_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL4_C, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_SLEEP_G_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SelfTest_XL
+* Description    : Write ST_XL
+* Input          : LSM6DSL_ACC_GYRO_ST_XL_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SelfTest_XL(void *handle, LSM6DSL_ACC_GYRO_ST_XL_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL5_C, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_ST_XL_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL5_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SelfTest_XL
+* Description    : Read ST_XL
+* Input          : Pointer to LSM6DSL_ACC_GYRO_ST_XL_t
+* Output         : Status of ST_XL see LSM6DSL_ACC_GYRO_ST_XL_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SelfTest_XL(void *handle, LSM6DSL_ACC_GYRO_ST_XL_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL5_C, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_ST_XL_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SelfTest_G
+* Description    : Write ST_G
+* Input          : LSM6DSL_ACC_GYRO_ST_G_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SelfTest_G(void *handle, LSM6DSL_ACC_GYRO_ST_G_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL5_C, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_ST_G_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL5_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SelfTest_G
+* Description    : Read ST_G
+* Input          : Pointer to LSM6DSL_ACC_GYRO_ST_G_t
+* Output         : Status of ST_G see LSM6DSL_ACC_GYRO_ST_G_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SelfTest_G(void *handle, LSM6DSL_ACC_GYRO_ST_G_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL5_C, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_ST_G_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DEN_Polarity
+* Description    : Write DEN_LH
+* Input          : LSM6DSL_ACC_GYRO_DEN_LH_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DEN_Polarity(void *handle, LSM6DSL_ACC_GYRO_DEN_LH_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL5_C, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_DEN_LH_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL5_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DEN_Polarity
+* Description    : Read DEN_LH
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DEN_LH_t
+* Output         : Status of DEN_LH see LSM6DSL_ACC_GYRO_DEN_LH_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DEN_Polarity(void *handle, LSM6DSL_ACC_GYRO_DEN_LH_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL5_C, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DEN_LH_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_CircularBurstMode
+* Description    : Write ST_ROUNDING
+* Input          : LSM6DSL_ACC_GYRO_ROUNDING_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_CircularBurstMode(void *handle, LSM6DSL_ACC_GYRO_ROUNDING_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL5_C, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_LSM6DSL_ACC_GYRO_ROUNDING_t_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL5_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_CircularBurstMode
+* Description    : Read ST_ROUNDING
+* Input          : Pointer to LSM6DSL_ACC_GYRO_ROUNDING_t
+* Output         : Status of ST_ROUNDING see LSM6DSL_ACC_GYRO_ROUNDING_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_CircularBurstMode(void *handle, LSM6DSL_ACC_GYRO_ROUNDING_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL5_C, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_LSM6DSL_ACC_GYRO_ROUNDING_t_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_LP_BW_G
+* Description    : Write FTYPE
+* Input          : LSM6DSL_ACC_GYRO_FTYPE_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_LP_BW_G(void *handle, LSM6DSL_ACC_GYRO_FTYPE_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_FTYPE_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_LP_BW_G
+* Description    : Read FTYPE
+* Input          : Pointer to LSM6DSL_ACC_GYRO_FTYPE_t
+* Output         : Status of FTYPE see LSM6DSL_ACC_GYRO_FTYPE_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_LP_BW_G(void *handle, LSM6DSL_ACC_GYRO_FTYPE_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_FTYPE_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_UserOffsetWeight
+* Description    : Write USR_OFF_W
+* Input          : LSM6DSL_ACC_GYRO_USR_OFF_W_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_UserOffsetWeight(void *handle, LSM6DSL_ACC_GYRO_USR_OFF_W_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_USR_OFF_W_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_UserOffsetWeight
+* Description    : Read USR_OFF_W
+* Input          : Pointer to LSM6DSL_ACC_GYRO_USR_OFF_W_t
+* Output         : Status of USR_OFF_W see LSM6DSL_ACC_GYRO_USR_OFF_W_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_UserOffsetWeight(void *handle, LSM6DSL_ACC_GYRO_USR_OFF_W_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_USR_OFF_W_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_LowPower_XL
+* Description    : Write LP_XL
+* Input          : LSM6DSL_ACC_GYRO_LP_XL_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_LowPower_XL(void *handle, LSM6DSL_ACC_GYRO_LP_XL_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_LP_XL_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_LowPower_XL
+* Description    : Read LP_XL
+* Input          : Pointer to LSM6DSL_ACC_GYRO_LP_XL_t
+* Output         : Status of LP_XL see LSM6DSL_ACC_GYRO_LP_XL_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_LowPower_XL(void *handle, LSM6DSL_ACC_GYRO_LP_XL_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_LP_XL_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DEN_LVL2_EN
+* Description    : Write DEN_LVL2_EN
+* Input          : LSM6DSL_ACC_GYRO_DEN_LVL2_EN_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DEN_LVL2_EN(void *handle, LSM6DSL_ACC_GYRO_DEN_LVL2_EN_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_DEN_LVL2_EN_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DEN_LVL2_EN
+* Description    : Read DEN_LVL2_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DEN_LVL2_EN_t
+* Output         : Status of DEN_LVL2_EN see LSM6DSL_ACC_GYRO_DEN_LVL2_EN_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DEN_LVL2_EN(void *handle, LSM6DSL_ACC_GYRO_DEN_LVL2_EN_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, (u8_t *)value, 1)) 
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DEN_LVL2_EN_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DEN_LVL_EN
+* Description    : Write DEN_LVL_EN
+* Input          : LSM6DSL_ACC_GYRO_DEN_LVL_EN_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DEN_LVL_EN(void *handle, LSM6DSL_ACC_GYRO_DEN_LVL_EN_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, &value, 1)) 
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_DEN_LVL_EN_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DEN_LVL_EN
+* Description    : Read DEN_LVL_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DEN_LVL_EN_t
+* Output         : Status of DEN_LVL_EN see LSM6DSL_ACC_GYRO_DEN_LVL_EN_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DEN_LVL_EN(void *handle, LSM6DSL_ACC_GYRO_DEN_LVL_EN_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DEN_LVL_EN_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_ExternalTrigger
+* Description    : Write DEN_EDGE_EN
+* Input          : LSM6DSL_ACC_GYRO_DEN_EDGE_EN_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_ExternalTrigger(void *handle, LSM6DSL_ACC_GYRO_DEN_EDGE_EN_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_DEN_EDGE_EN_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_ExternalTrigger
+* Description    : Read DEN_EDGE_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DEN_EDGE_EN_t
+* Output         : Status of DEN_EDGE_EN see LSM6DSL_ACC_GYRO_DEN_EDGE_EN_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_ExternalTrigger(void *handle, LSM6DSL_ACC_GYRO_DEN_EDGE_EN_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL6_G, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DEN_EDGE_EN_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_HPM_G
+* Description    : Write HPM_G
+* Input          : LSM6DSL_ACC_GYRO_HPM_G_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_HPM_G(void *handle, LSM6DSL_ACC_GYRO_HPM_G_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_HPM_G_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_HPM_G
+* Description    : Read HPM_G
+* Input          : Pointer to LSM6DSL_ACC_GYRO_HPM_G_t
+* Output         : Status of HPM_G see LSM6DSL_ACC_GYRO_HPM_G_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_HPM_G(void *handle, LSM6DSL_ACC_GYRO_HPM_G_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_HPM_G_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_RoundingOnStatusRegisters
+* Description    : Write HPM_G
+* Input          : LSM6DSL_ACC_GYRO_RND_STATUS_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_RoundingOnStatusRegisters(void *handle, LSM6DSL_ACC_GYRO_RND_STATUS_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_RND_STATUS_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_RoundingOnStatusRegisters
+* Description    : Read HPM_G
+* Input          : Pointer to LSM6DSL_ACC_GYRO_RND_STATUS_t
+* Output         : Status of HPM_G see LSM6DSL_ACC_GYRO_RND_STATUS_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_RoundingOnStatusRegisters(void *handle, LSM6DSL_ACC_GYRO_RND_STATUS_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, (u8_t *)value, 1))
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_RND_STATUS_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_HPFilter_En
+* Description    : Write HP_EN
+* Input          : LSM6DSL_ACC_GYRO_HP_EN_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_HPFilter_En(void *handle, LSM6DSL_ACC_GYRO_HP_EN_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_HP_EN_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_HPFilter_En
+* Description    : Read HP_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_HP_EN_t
+* Output         : Status of HP_EN see LSM6DSL_ACC_GYRO_HP_EN_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_HPFilter_En(void *handle, LSM6DSL_ACC_GYRO_HP_EN_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_HP_EN_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_LP_Mode
+* Description    : Write LP_EN
+* Input          : LSM6DSL_ACC_GYRO_LP_EN_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_LP_Mode(void *handle, LSM6DSL_ACC_GYRO_LP_EN_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_LP_EN_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_LP_Mode
+* Description    : Read LP_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_LP_EN_t
+* Output         : Status of LP_EN see LSM6DSL_ACC_GYRO_LP_EN_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_LP_Mode(void *handle, LSM6DSL_ACC_GYRO_LP_EN_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_LP_EN_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_ROUNDING_STATUS
+* Description    : Write ROUNDING_STATUS
+* Input          : LSM6DSL_ACC_GYRO_ROUNDING_STATUS_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_ROUNDING_STATUS(void *handle, LSM6DSL_ACC_GYRO_ROUNDING_STATUS_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_ROUNDING_STATUS_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_ROUNDING_STATUS
+* Description    : Read ROUNDING_STATUS
+* Input          : Pointer to LSM6DSL_ACC_GYRO_ROUNDING_STATUS_t
+* Output         : Status of ROUNDING_STATUS see LSM6DSL_ACC_GYRO_ROUNDING_STATUS_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_ROUNDING_STATUS(void *handle, LSM6DSL_ACC_GYRO_ROUNDING_STATUS_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_ROUNDING_STATUS_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_HP_G_RST
+* Description    : Write HP_G_RST
+* Input          : LSM6DSL_ACC_GYRO_HP_G_RST_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_HP_G_RST(void *handle, LSM6DSL_ACC_GYRO_HP_G_RST_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_HP_G_RST_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_HP_G_RST
+* Description    : Read HP_G_RST
+* Input          : Pointer to LSM6DSL_ACC_GYRO_HP_G_RST_t
+* Output         : Status of HP_G_RST see LSM6DSL_ACC_GYRO_HP_G_RST_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_HP_G_RST(void *handle, LSM6DSL_ACC_GYRO_HP_G_RST_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL7_G, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_HP_G_RST_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_InComposit
+* Description    : Write INPUT_COMPOSITE
+* Input          : LSM6DSL_ACC_GYRO_IN_COMP_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_InComposit(void *handle, LSM6DSL_ACC_GYRO_IN_COMP_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_IN_COMP_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_InComposit
+* Description    : Read INPUT_COMPOSITE
+* Input          : Pointer to LSM6DSL_ACC_GYRO_IN_COMP_t
+* Output         : Status of INPUT_COMPOSITE see LSM6DSL_ACC_GYRO_IN_COMP_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_InComposit(void *handle, LSM6DSL_ACC_GYRO_IN_COMP_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_IN_COMP_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_HPfilterReference
+* Description    : Write HP_REF_MODE
+* Input          : LSM6DSL_ACC_GYRO_HP_REF_MODE_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_HPfilterReference(void *handle, LSM6DSL_ACC_GYRO_HP_REF_MODE_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_HP_REF_MODE_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_HPfilterReference
+* Description    : Read HP_REF_MODE
+* Input          : Pointer to LSM6DSL_ACC_GYRO_HP_REF_MODE_t
+* Output         : Status of HP_REF_MODE see LSM6DSL_ACC_GYRO_HP_REF_MODE_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_HPfilterReference(void *handle, LSM6DSL_ACC_GYRO_HP_REF_MODE_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_HP_REF_MODE_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_HPCF_XL
+* Description    : Write HPCF_XL
+* Input          : LSM6DSL_ACC_GYRO_HPCF_XL_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_HPCF_XL(void *handle, LSM6DSL_ACC_GYRO_HPCF_XL_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_HPCF_XL_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_HPCF_XL
+* Description    : Read HPCF_XL
+* Input          : Pointer to LSM6DSL_ACC_GYRO_HPCF_XL_t
+* Output         : Status of HPCF_XL see LSM6DSL_ACC_GYRO_HPCF_XL_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_HPCF_XL(void *handle, LSM6DSL_ACC_GYRO_HPCF_XL_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_HPCF_XL_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_LowPassFiltSel_XL
+* Description    : Write LPF2_XL_EN
+* Input          : LSM6DSL_ACC_GYRO_LPF2_XL_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_LowPassFiltSel_XL(void *handle, LSM6DSL_ACC_GYRO_LPF2_XL_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_LPF2_XL_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_LowPassFiltSel_XL
+* Description    : Read LPF2_XL_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_LPF2_XL_t
+* Output         : Status of LPF2_XL_EN see LSM6DSL_ACC_GYRO_LPF2_XL_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_LowPassFiltSel_XL(void *handle, LSM6DSL_ACC_GYRO_LPF2_XL_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_LPF2_XL_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_LOW_PASS_ON_6D
+* Description    : Write LOW_PASS_ON_6D
+* Input          : LSM6DSL_ACC_GYRO_LOW_PASS_ON_6D_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_LOW_PASS_ON_6D(void *handle, LSM6DSL_ACC_GYRO_LOW_PASS_ON_6D_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_LOW_PASS_ON_6D_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_LOW_PASS_ON_6D
+* Description    : Read LOW_PASS_ON_6D
+* Input          : Pointer to LSM6DSL_ACC_GYRO_LOW_PASS_ON_6D_t
+* Output         : Status of LOW_PASS_ON_6D see LSM6DSL_ACC_GYRO_LOW_PASS_ON_6D_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_LOW_PASS_ON_6D(void *handle, LSM6DSL_ACC_GYRO_LOW_PASS_ON_6D_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_LOW_PASS_ON_6D_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_HP_SLOPE_XL
+* Description    : Write HP_SLOPE_XL_EN
+* Input          : LSM6DSL_ACC_GYRO_HP_SLOPE_XL_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_HP_SLOPE_XL(void *handle, LSM6DSL_ACC_GYRO_HP_SLOPE_XL_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_HP_SLOPE_XL_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_HP_SLOPE_XL
+* Description    : Read HP_SLOPE_XL_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_HP_SLOPE_XL_t
+* Output         : Status of HP_SLOPE_XL_EN see LSM6DSL_ACC_GYRO_HP_SLOPE_XL_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_HP_SLOPE_XL(void *handle, LSM6DSL_ACC_GYRO_HP_SLOPE_XL_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL8_XL, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_HP_SLOPE_XL_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SOFT
+* Description    : Write SOFT_EN
+* Input          : LSM6DSL_ACC_GYRO_SOFT_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SOFT(void *handle, LSM6DSL_ACC_GYRO_SOFT_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL9_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_SOFT_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL9_XL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SOFT
+* Description    : Read SOFT_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_SOFT_t
+* Output         : Status of SOFT_EN see LSM6DSL_ACC_GYRO_SOFT_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SOFT(void *handle, LSM6DSL_ACC_GYRO_SOFT_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL9_XL, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_SOFT_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SignifcantMotion
+* Description    : Write SIGN_MOTION_EN
+* Input          : LSM6DSL_ACC_GYRO_SIGN_MOTION_EN_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SignifcantMotion(void *handle, LSM6DSL_ACC_GYRO_SIGN_MOTION_EN_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_SIGN_MOTION_EN_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SignifcantMotion
+* Description    : Read SIGN_MOTION_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_SIGN_MOTION_EN_t
+* Output         : Status of SIGN_MOTION_EN see LSM6DSL_ACC_GYRO_SIGN_MOTION_EN_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SignifcantMotion(void *handle, LSM6DSL_ACC_GYRO_SIGN_MOTION_EN_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_SIGN_MOTION_EN_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_PedoStepReset
+* Description    : Write PEDO_RST_STEP
+* Input          : LSM6DSL_ACC_GYRO_PEDO_RST_STEP_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_PedoStepReset(void *handle, LSM6DSL_ACC_GYRO_PEDO_RST_STEP_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_PEDO_RST_STEP_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_PedoStepReset
+* Description    : Read PEDO_RST_STEP
+* Input          : Pointer to LSM6DSL_ACC_GYRO_PEDO_RST_STEP_t
+* Output         : Status of PEDO_RST_STEP see LSM6DSL_ACC_GYRO_PEDO_RST_STEP_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_PedoStepReset(void *handle, LSM6DSL_ACC_GYRO_PEDO_RST_STEP_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_PEDO_RST_STEP_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_TILT
+* Description    : Write XEN_G
+* Input          : LSM6DSL_ACC_GYRO_TILT_G_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_TILT(void *handle, LSM6DSL_ACC_GYRO_TILT_G_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_TILT_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TILT
+* Description    : Read XEN_G
+* Input          : Pointer to LSM6DSL_ACC_GYRO_TILT_G_t
+* Output         : Status of XEN_G see LSM6DSL_ACC_GYRO_TILT_G_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TILT(void *handle, LSM6DSL_ACC_GYRO_TILT_G_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_TILT_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_PEDO
+* Description    : Write PEDO_EN
+* Input          : LSM6DSL_ACC_GYRO_PEDO_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_PEDO(void *handle, LSM6DSL_ACC_GYRO_PEDO_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_PEDO_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_PEDO
+* Description    : Read PEDO_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_PEDO_t
+* Output         : Status of PEDO_EN see LSM6DSL_ACC_GYRO_PEDO_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_PEDO(void *handle, LSM6DSL_ACC_GYRO_PEDO_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_PEDO_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_TIMER
+* Description    : Write TIMER_EN
+* Input          : LSM6DSL_ACC_GYRO_TIMER_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_TIMER(void *handle, LSM6DSL_ACC_GYRO_TIMER_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_TIMER_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TIMER
+* Description    : Read TIMER_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_TIMER_t
+* Output         : Status of TIMER_EN see LSM6DSL_ACC_GYRO_TIMER_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TIMER(void *handle, LSM6DSL_ACC_GYRO_TIMER_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_TIMER_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_FUNC_EN
+* Description    : Write FUNC_EN
+* Input          : LSM6DSL_ACC_GYRO_FUNC_EN_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_FUNC_EN(void *handle, LSM6DSL_ACC_GYRO_FUNC_EN_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_FUNC_EN_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FUNC_EN
+* Description    : Read FUNC_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_FUNC_EN_t
+* Output         : Status of FUNC_EN see LSM6DSL_ACC_GYRO_FUNC_EN_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FUNC_EN(void *handle, LSM6DSL_ACC_GYRO_FUNC_EN_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CTRL10_C, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_FUNC_EN_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_I2C_MASTER_Enable
+* Description    : Write MASTER_ON
+* Input          : LSM6DSL_ACC_GYRO_MASTER_ON_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_I2C_MASTER_Enable(void *handle, LSM6DSL_ACC_GYRO_MASTER_ON_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_MASTER_ON_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_I2C_MASTER_Enable
+* Description    : Read MASTER_ON
+* Input          : Pointer to LSM6DSL_ACC_GYRO_MASTER_ON_t
+* Output         : Status of MASTER_ON see LSM6DSL_ACC_GYRO_MASTER_ON_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_I2C_MASTER_Enable(void *handle, LSM6DSL_ACC_GYRO_MASTER_ON_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_MASTER_ON_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_IronCorrection_EN
+* Description    : Write IRON_EN
+* Input          : LSM6DSL_ACC_GYRO_IRON_EN_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_IronCorrection_EN(void *handle, LSM6DSL_ACC_GYRO_IRON_EN_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_IRON_EN_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_IronCorrection_EN
+* Description    : Read IRON_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_IRON_EN_t
+* Output         : Status of IRON_EN see LSM6DSL_ACC_GYRO_IRON_EN_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_IronCorrection_EN(void *handle, LSM6DSL_ACC_GYRO_IRON_EN_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_IRON_EN_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_PASS_THRU_MODE
+* Description    : Write PASS_THRU_MODE
+* Input          : LSM6DSL_ACC_GYRO_PASS_THRU_MODE_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_PASS_THRU_MODE(void *handle, LSM6DSL_ACC_GYRO_PASS_THRU_MODE_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_PASS_THRU_MODE_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_PASS_THRU_MODE
+* Description    : Read PASS_THRU_MODE
+* Input          : Pointer to LSM6DSL_ACC_GYRO_PASS_THRU_MODE_t
+* Output         : Status of PASS_THRU_MODE see LSM6DSL_ACC_GYRO_PASS_THRU_MODE_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_PASS_THRU_MODE(void *handle, LSM6DSL_ACC_GYRO_PASS_THRU_MODE_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_PASS_THRU_MODE_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_PULL_UP_EN
+* Description    : Write PULL_UP_EN
+* Input          : LSM6DSL_ACC_GYRO_PULL_UP_EN_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_PULL_UP_EN(void *handle, LSM6DSL_ACC_GYRO_PULL_UP_EN_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_PULL_UP_EN_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_PULL_UP_EN
+* Description    : Read PULL_UP_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_PULL_UP_EN_t
+* Output         : Status of PULL_UP_EN see LSM6DSL_ACC_GYRO_PULL_UP_EN_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_PULL_UP_EN(void *handle, LSM6DSL_ACC_GYRO_PULL_UP_EN_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_PULL_UP_EN_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SensorHUB_Trigger_Sel
+* Description    : Write START_CONFIG
+* Input          : LSM6DSL_ACC_GYRO_START_CONFIG_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SensorHUB_Trigger_Sel(void *handle, LSM6DSL_ACC_GYRO_START_CONFIG_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_START_CONFIG_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SensorHUB_Trigger_Sel
+* Description    : Read START_CONFIG
+* Input          : Pointer to LSM6DSL_ACC_GYRO_START_CONFIG_t
+* Output         : Status of START_CONFIG see LSM6DSL_ACC_GYRO_START_CONFIG_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SensorHUB_Trigger_Sel(void *handle, LSM6DSL_ACC_GYRO_START_CONFIG_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_START_CONFIG_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DATA_VAL_SEL_FIFO
+* Description    : Write DATA_VAL_SEL_FIFO
+* Input          : LSM6DSL_ACC_GYRO_DATA_VAL_SEL_FIFO_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DATA_VAL_SEL_FIFO(void *handle, LSM6DSL_ACC_GYRO_DATA_VAL_SEL_FIFO_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_DATA_VAL_SEL_FIFO_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DATA_VAL_SEL_FIFO
+* Description    : Read DATA_VAL_SEL_FIFO
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DATA_VAL_SEL_FIFO_t
+* Output         : Status of DATA_VAL_SEL_FIFO see LSM6DSL_ACC_GYRO_DATA_VAL_SEL_FIFO_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DATA_VAL_SEL_FIFO(void *handle, LSM6DSL_ACC_GYRO_DATA_VAL_SEL_FIFO_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DATA_VAL_SEL_FIFO_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DRDY_ON_INT1
+* Description    : Write DRDY_ON_INT1
+* Input          : LSM6DSL_ACC_GYRO_DRDY_ON_INT1_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DRDY_ON_INT1(void *handle, LSM6DSL_ACC_GYRO_DRDY_ON_INT1_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_DRDY_ON_INT1_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DRDY_ON_INT1
+* Description    : Read DRDY_ON_INT1
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DRDY_ON_INT1_t
+* Output         : Status of DRDY_ON_INT1 see LSM6DSL_ACC_GYRO_DRDY_ON_INT1_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DRDY_ON_INT1(void *handle, LSM6DSL_ACC_GYRO_DRDY_ON_INT1_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MASTER_CONFIG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DRDY_ON_INT1_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_Z_WU
+* Description    : Read Z_WU
+* Input          : Pointer to LSM6DSL_ACC_GYRO_Z_WU_t
+* Output         : Status of Z_WU see LSM6DSL_ACC_GYRO_Z_WU_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_Z_WU(void *handle, LSM6DSL_ACC_GYRO_Z_WU_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_Z_WU_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_Y_WU
+* Description    : Read Y_WU
+* Input          : Pointer to LSM6DSL_ACC_GYRO_Y_WU_t
+* Output         : Status of Y_WU see LSM6DSL_ACC_GYRO_Y_WU_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_Y_WU(void *handle, LSM6DSL_ACC_GYRO_Y_WU_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_Y_WU_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_X_WU
+* Description    : Read X_WU
+* Input          : Pointer to LSM6DSL_ACC_GYRO_X_WU_t
+* Output         : Status of X_WU see LSM6DSL_ACC_GYRO_X_WU_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_X_WU(void *handle, LSM6DSL_ACC_GYRO_X_WU_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_X_WU_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_WU_EV_STATUS
+* Description    : Read WU_EV_STATUS
+* Input          : Pointer to LSM6DSL_ACC_GYRO_WU_EV_STATUS_t
+* Output         : Status of WU_EV_STATUS see LSM6DSL_ACC_GYRO_WU_EV_STATUS_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_WU_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_WU_EV_STATUS_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_WU_EV_STATUS_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SLEEP_EV_STATUS
+* Description    : Read SLEEP_EV_STATUS
+* Input          : Pointer to LSM6DSL_ACC_GYRO_SLEEP_EV_STATUS_t
+* Output         : Status of SLEEP_EV_STATUS see LSM6DSL_ACC_GYRO_SLEEP_EV_STATUS_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SLEEP_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_SLEEP_EV_STATUS_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_SLEEP_EV_STATUS_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FF_EV_STATUS
+* Description    : Read FF_EV_STATUS
+* Input          : Pointer to LSM6DSL_ACC_GYRO_FF_EV_STATUS_t
+* Output         : Status of FF_EV_STATUS see LSM6DSL_ACC_GYRO_FF_EV_STATUS_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FF_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_FF_EV_STATUS_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_FF_EV_STATUS_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_Z_TAP
+* Description    : Read Z_TAP
+* Input          : Pointer to LSM6DSL_ACC_GYRO_Z_TAP_t
+* Output         : Status of Z_TAP see LSM6DSL_ACC_GYRO_Z_TAP_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_Z_TAP(void *handle, LSM6DSL_ACC_GYRO_Z_TAP_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_Z_TAP_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_Y_TAP
+* Description    : Read Y_TAP
+* Input          : Pointer to LSM6DSL_ACC_GYRO_Y_TAP_t
+* Output         : Status of Y_TAP see LSM6DSL_ACC_GYRO_Y_TAP_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_Y_TAP(void *handle, LSM6DSL_ACC_GYRO_Y_TAP_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_Y_TAP_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_X_TAP
+* Description    : Read X_TAP
+* Input          : Pointer to LSM6DSL_ACC_GYRO_X_TAP_t
+* Output         : Status of X_TAP see LSM6DSL_ACC_GYRO_X_TAP_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_X_TAP(void *handle, LSM6DSL_ACC_GYRO_X_TAP_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_X_TAP_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TAP_SIGN
+* Description    : Read TAP_SIGN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_TAP_SIGN_t
+* Output         : Status of TAP_SIGN see LSM6DSL_ACC_GYRO_TAP_SIGN_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TAP_SIGN(void *handle, LSM6DSL_ACC_GYRO_TAP_SIGN_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_TAP_SIGN_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DOUBLE_TAP_EV_STATUS
+* Description    : Read DOUBLE_TAP_EV_STATUS
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DOUBLE_TAP_EV_STATUS_t
+* Output         : Status of DOUBLE_TAP_EV_STATUS see LSM6DSL_ACC_GYRO_DOUBLE_TAP_EV_STATUS_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DOUBLE_TAP_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_DOUBLE_TAP_EV_STATUS_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DOUBLE_TAP_EV_STATUS_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SINGLE_TAP_EV_STATUS
+* Description    : Read SINGLE_TAP_EV_STATUS
+* Input          : Pointer to LSM6DSL_ACC_GYRO_SINGLE_TAP_EV_STATUS_t
+* Output         : Status of SINGLE_TAP_EV_STATUS see LSM6DSL_ACC_GYRO_SINGLE_TAP_EV_STATUS_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SINGLE_TAP_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_SINGLE_TAP_EV_STATUS_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_SINGLE_TAP_EV_STATUS_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TAP_EV_STATUS
+* Description    : Read TAP_EV_STATUS
+* Input          : Pointer to LSM6DSL_ACC_GYRO_TAP_EV_STATUS_t
+* Output         : Status of TAP_EV_STATUS see LSM6DSL_ACC_GYRO_TAP_EV_STATUS_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TAP_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_TAP_EV_STATUS_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_TAP_EV_STATUS_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DSD_XL
+* Description    : Read DSD_XL
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DSD_XL_t
+* Output         : Status of DSD_XL see LSM6DSL_ACC_GYRO_DSD_XL_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DSD_XL(void *handle, LSM6DSL_ACC_GYRO_DSD_XL_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_D6D_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DSD_XL_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DSD_XH
+* Description    : Read DSD_XH
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DSD_XH_t
+* Output         : Status of DSD_XH see LSM6DSL_ACC_GYRO_DSD_XH_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DSD_XH(void *handle, LSM6DSL_ACC_GYRO_DSD_XH_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_D6D_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DSD_XH_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DSD_YL
+* Description    : Read DSD_YL
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DSD_YL_t
+* Output         : Status of DSD_YL see LSM6DSL_ACC_GYRO_DSD_YL_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DSD_YL(void *handle, LSM6DSL_ACC_GYRO_DSD_YL_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_D6D_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DSD_YL_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DSD_YH
+* Description    : Read DSD_YH
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DSD_YH_t
+* Output         : Status of DSD_YH see LSM6DSL_ACC_GYRO_DSD_YH_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DSD_YH(void *handle, LSM6DSL_ACC_GYRO_DSD_YH_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_D6D_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DSD_YH_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DSD_ZL
+* Description    : Read DSD_ZL
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DSD_ZL_t
+* Output         : Status of DSD_ZL see LSM6DSL_ACC_GYRO_DSD_ZL_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DSD_ZL(void *handle, LSM6DSL_ACC_GYRO_DSD_ZL_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_D6D_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DSD_ZL_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DSD_ZH
+* Description    : Read DSD_ZH
+* Input          : Pointer to LSM6DSL_ACC_GYRO_DSD_ZH_t
+* Output         : Status of DSD_ZH see LSM6DSL_ACC_GYRO_DSD_ZH_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DSD_ZH(void *handle, LSM6DSL_ACC_GYRO_DSD_ZH_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_D6D_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DSD_ZH_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_D6D_EV_STATUS
+* Description    : Read D6D_EV_STATUS
+* Input          : Pointer to LSM6DSL_ACC_GYRO_D6D_EV_STATUS_t
+* Output         : Status of D6D_EV_STATUS see LSM6DSL_ACC_GYRO_D6D_EV_STATUS_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_D6D_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_D6D_EV_STATUS_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_D6D_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_D6D_EV_STATUS_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_XLDA
+* Description    : Read XLDA
+* Input          : Pointer to LSM6DSL_ACC_GYRO_XLDA_t
+* Output         : Status of XLDA see LSM6DSL_ACC_GYRO_XLDA_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_XLDA(void *handle, LSM6DSL_ACC_GYRO_XLDA_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_STATUS_REG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_XLDA_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_GDA
+* Description    : Read GDA
+* Input          : Pointer to LSM6DSL_ACC_GYRO_GDA_t
+* Output         : Status of GDA see LSM6DSL_ACC_GYRO_GDA_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_GDA(void *handle, LSM6DSL_ACC_GYRO_GDA_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_STATUS_REG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_GDA_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TDA
+* Description    : Read GDA
+* Input          : Pointer to LSM6DSL_ACC_GYRO_TDA_t
+* Output         : Status of GDA see LSM6DSL_ACC_GYRO_TDA_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TDA(void *handle, LSM6DSL_ACC_GYRO_TDA_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_STATUS_REG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_TDA_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FIFONumOfEntries
+* Description    : Read DIFF_FIFO
+* Input          : Pointer to u16_t
+* Output         : Status of DIFF_FIFO 
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFONumOfEntries(void *handle, u16_t *value)
+{
+  u8_t valueH, valueL;
+
+  /* Low part from FIFO_STATUS1 */
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_STATUS1, (u8_t *)&valueL, 1) )
+    return MEMS_ERROR;
+
+  valueL &= LSM6DSL_ACC_GYRO_DIFF_FIFO_STATUS1_MASK; //coerce
+  valueL = valueL >> LSM6DSL_ACC_GYRO_DIFF_FIFO_STATUS1_POSITION; //mask
+
+  /* High part from FIFO_STATUS2 */
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_STATUS2, (u8_t *)&valueH, 1) )
+    return MEMS_ERROR;
+
+  valueH &= LSM6DSL_ACC_GYRO_DIFF_FIFO_STATUS2_MASK; //coerce
+  valueH = valueH >> LSM6DSL_ACC_GYRO_DIFF_FIFO_STATUS2_POSITION; //mask
+
+  *value = ((valueH << 8) & 0xFF00) | valueL;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FIFOEmpty
+* Description    : Read FIFO_EMPTY
+* Input          : Pointer to LSM6DSL_ACC_GYRO_FIFO_EMPTY_t
+* Output         : Status of FIFO_EMPTY see LSM6DSL_ACC_GYRO_FIFO_EMPTY_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFOEmpty(void *handle, LSM6DSL_ACC_GYRO_FIFO_EMPTY_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_STATUS2, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_FIFO_EMPTY_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FIFOFull
+* Description    : Read FIFO_FULL
+* Input          : Pointer to LSM6DSL_ACC_GYRO_FIFO_FULL_t
+* Output         : Status of FIFO_FULL see LSM6DSL_ACC_GYRO_FIFO_FULL_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFOFull(void *handle, LSM6DSL_ACC_GYRO_FIFO_FULL_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_STATUS2, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_FIFO_FULL_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_OVERRUN
+* Description    : Read OVERRUN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_OVERRUN_t
+* Output         : Status of OVERRUN see LSM6DSL_ACC_GYRO_OVERRUN_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_OVERRUN(void *handle, LSM6DSL_ACC_GYRO_OVERRUN_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_STATUS2, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_OVERRUN_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_WaterMark
+* Description    : Read WTM
+* Input          : Pointer to LSM6DSL_ACC_GYRO_WTM_t
+* Output         : Status of WTM see LSM6DSL_ACC_GYRO_WTM_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_WaterMark(void *handle, LSM6DSL_ACC_GYRO_WTM_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_STATUS2, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_WTM_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FIFOPattern
+* Description    : Read FIFO_PATTERN
+* Input          : Pointer to u16_t
+* Output         : Status of FIFO_PATTERN 
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFOPattern(void *handle, u16_t *value)
+{
+  u8_t valueH, valueL;
+
+  /* Low part from FIFO_STATUS3 */
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_STATUS3, (u8_t *)&valueL, 1) )
+    return MEMS_ERROR;
+
+  valueL &= LSM6DSL_ACC_GYRO_FIFO_STATUS3_PATTERN_MASK; //coerce
+  valueL = valueL >> LSM6DSL_ACC_GYRO_FIFO_STATUS3_PATTERN_POSITION; //mask
+
+  /* High part from FIFO_STATUS4 */
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_STATUS4, (u8_t *)&valueH, 1) )
+    return MEMS_ERROR;
+
+  valueH &= LSM6DSL_ACC_GYRO_FIFO_STATUS4_PATTERN_MASK; //coerce
+  valueH = valueH >> LSM6DSL_ACC_GYRO_FIFO_STATUS4_PATTERN_POSITION; //mask
+
+  *value = ((valueH << 8) & 0xFF00) | valueL;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SENS_HUB_END
+* Description    : Read SENS_HUB_END
+* Input          : Pointer to LSM6DSL_ACC_GYRO_SENS_HUB_END_t
+* Output         : Status of SENS_HUB_END see LSM6DSL_ACC_GYRO_SENS_HUB_END_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SENS_HUB_END(void *handle, LSM6DSL_ACC_GYRO_SENS_HUB_END_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FUNC_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_SENS_HUB_END_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SOFT_IRON_END
+* Description    : Read SOFT_IRON_END
+* Input          : Pointer to LSM6DSL_ACC_GYRO_SOFT_IRON_END_t
+* Output         : Status of SOFT_IRON_END see LSM6DSL_ACC_GYRO_SOFT_IRON_END_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SOFT_IRON_END(void *handle, LSM6DSL_ACC_GYRO_SOFT_IRON_END_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FUNC_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_SOFT_IRON_END_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_HardIron
+* Description    : Read HI_FAIL
+* Input          : Pointer to LSM6DSL_ACC_GYRO_SOFT_HARD_IRON_STAT_t
+* Output         : Status of HI_FAIL see LSM6DSL_ACC_GYRO_SOFT_HARD_IRON_STAT_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_HardIron(void *handle, LSM6DSL_ACC_GYRO_SOFT_HARD_IRON_STAT_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FUNC_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_HARD_IRON_STAT_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_STEP_OVERFLOW
+* Description    : Read STEP_OVERFLOW
+* Input          : Pointer to LSM6DSL_ACC_GYRO_STEP_OVERFLOW_t
+* Output         : Status of STEP_OVERFLOW see LSM6DSL_ACC_GYRO_STEP_OVERFLOW_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_STEP_OVERFLOW(void *handle, LSM6DSL_ACC_GYRO_STEP_OVERFLOW_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FUNC_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_STEP_OVERFLOW_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_STEP_COUNT_DELTA
+* Description    : Read STEP_COUNT_DELTA_IA
+* Input          : Pointer to LSM6DSL_ACC_GYRO_STEP_COUNT_DELTA_t
+* Output         : Status of STEP_COUNT_DELTA_IA see LSM6DSL_ACC_GYRO_STEP_COUNT_DELTA_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_STEP_COUNT_DELTA(void *handle, LSM6DSL_ACC_GYRO_STEP_COUNT_DELTA_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FUNC_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_STEP_COUNT_DELTA_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_PEDO_EV_STATUS
+* Description    : Read PEDO_EV_STATUS
+* Input          : Pointer to LSM6DSL_ACC_GYRO_PEDO_EV_STATUS_t
+* Output         : Status of PEDO_EV_STATUS see LSM6DSL_ACC_GYRO_PEDO_EV_STATUS_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_PEDO_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_PEDO_EV_STATUS_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FUNC_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_PEDO_EV_STATUS_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TILT_EV_STATUS
+* Description    : Read TILT_EV_STATUS
+* Input          : Pointer to LSM6DSL_ACC_GYRO_TILT_EV_STATUS_t
+* Output         : Status of TILT_EV_STATUS see LSM6DSL_ACC_GYRO_TILT_EV_STATUS_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TILT_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_TILT_EV_STATUS_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FUNC_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_TILT_EV_STATUS_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SIGN_MOT_EV_STATUS
+* Description    : Read SIGN_MOT_EV_STATUS
+* Input          : Pointer to LSM6DSL_ACC_GYRO_SIGN_MOT_EV_STATUS_t
+* Output         : Status of SIGN_MOT_EV_STATUS see LSM6DSL_ACC_GYRO_SIGN_MOT_EV_STATUS_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SIGN_MOT_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_SIGN_MOT_EV_STATUS_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FUNC_SRC, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_SIGN_MOT_EV_STATUS_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_LIR
+* Description    : Write LIR
+* Input          : LSM6DSL_ACC_GYRO_LIR_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_LIR(void *handle, LSM6DSL_ACC_GYRO_LIR_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_LIR_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_LIR
+* Description    : Read LIR
+* Input          : Pointer to LSM6DSL_ACC_GYRO_LIR_t
+* Output         : Status of LIR see LSM6DSL_ACC_GYRO_LIR_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_LIR(void *handle, LSM6DSL_ACC_GYRO_LIR_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_LIR_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_TAP_Z_EN
+* Description    : Write TAP_Z_EN
+* Input          : LSM6DSL_ACC_GYRO_TAP_Z_EN_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_TAP_Z_EN(void *handle, LSM6DSL_ACC_GYRO_TAP_Z_EN_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_TAP_Z_EN_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TAP_Z_EN
+* Description    : Read TAP_Z_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_TAP_Z_EN_t
+* Output         : Status of TAP_Z_EN see LSM6DSL_ACC_GYRO_TAP_Z_EN_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TAP_Z_EN(void *handle, LSM6DSL_ACC_GYRO_TAP_Z_EN_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_TAP_Z_EN_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_TAP_Y_EN
+* Description    : Write TAP_Y_EN
+* Input          : LSM6DSL_ACC_GYRO_TAP_Y_EN_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_TAP_Y_EN(void *handle, LSM6DSL_ACC_GYRO_TAP_Y_EN_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_TAP_Y_EN_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TAP_Y_EN
+* Description    : Read TAP_Y_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_TAP_Y_EN_t
+* Output         : Status of TAP_Y_EN see LSM6DSL_ACC_GYRO_TAP_Y_EN_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TAP_Y_EN(void *handle, LSM6DSL_ACC_GYRO_TAP_Y_EN_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_TAP_Y_EN_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_TAP_X_EN
+* Description    : Write TAP_X_EN
+* Input          : LSM6DSL_ACC_GYRO_TAP_X_EN_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_TAP_X_EN(void *handle, LSM6DSL_ACC_GYRO_TAP_X_EN_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_TAP_X_EN_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TAP_X_EN
+* Description    : Read TAP_X_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_TAP_X_EN_t
+* Output         : Status of TAP_X_EN see LSM6DSL_ACC_GYRO_TAP_X_EN_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TAP_X_EN(void *handle, LSM6DSL_ACC_GYRO_TAP_X_EN_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_TAP_X_EN_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SLOPE_FDS
+* Description    : Write SLOPE_FDS
+* Input          : LSM6DSL_ACC_GYRO_SLOPE_FDS_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SLOPE_FDS(void *handle, LSM6DSL_ACC_GYRO_SLOPE_FDS_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_SLOPE_FDS_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SLOPE_FDS
+* Description    : Read SLOPE_FDS
+* Input          : Pointer to LSM6DSL_ACC_GYRO_SLOPE_FDS_t
+* Output         : Status of SLOPE_FDS see LSM6DSL_ACC_GYRO_SLOPE_FDS_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SLOPE_FDS(void *handle, LSM6DSL_ACC_GYRO_SLOPE_FDS_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_SLOPE_FDS_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_BASIC_INT
+* Description    : Write INTERRUPTS_ENABLE
+* Input          : LSM6DSL_ACC_GYRO_INT_EN_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_BASIC_INT(void *handle, LSM6DSL_ACC_GYRO_INT_EN_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT_EN_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_BASIC_INT
+* Description    : Read INTERRUPTS_ENABLE
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT_EN_t
+* Output         : Status of INTERRUPTS_ENABLE see LSM6DSL_ACC_GYRO_INT_EN_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_BASIC_INT(void *handle, LSM6DSL_ACC_GYRO_INT_EN_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_CFG1, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT_EN_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_TAP_THS
+* Description    : Write TAP_THS
+* Input          : u8_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_TAP_THS(void *handle, u8_t newValue)
+{
+  u8_t value;
+
+  newValue = newValue << LSM6DSL_ACC_GYRO_TAP_THS_POSITION; //mask  
+  newValue &= LSM6DSL_ACC_GYRO_TAP_THS_MASK; //coerce
+  
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_THS_6D, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_TAP_THS_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_TAP_THS_6D, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TAP_THS
+* Description    : Read TAP_THS
+* Input          : Pointer to u8_t
+* Output         : Status of TAP_THS 
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TAP_THS(void *handle, u8_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_THS_6D, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_TAP_THS_MASK; //coerce 
+  *value = *value >> LSM6DSL_ACC_GYRO_TAP_THS_POSITION; //mask  
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SIXD_THS
+* Description    : Write SIXD_THS
+* Input          : LSM6DSL_ACC_GYRO_SIXD_THS_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SIXD_THS(void *handle, LSM6DSL_ACC_GYRO_SIXD_THS_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_THS_6D, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_SIXD_THS_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_TAP_THS_6D, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SIXD_THS
+* Description    : Read SIXD_THS
+* Input          : Pointer to LSM6DSL_ACC_GYRO_SIXD_THS_t
+* Output         : Status of SIXD_THS see LSM6DSL_ACC_GYRO_SIXD_THS_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SIXD_THS(void *handle, LSM6DSL_ACC_GYRO_SIXD_THS_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_THS_6D, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_SIXD_THS_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_D4D
+* Description    : Write D4D_EN
+* Input          : LSM6DSL_ACC_GYRO_D4D_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_D4D(void *handle, LSM6DSL_ACC_GYRO_D4D_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_THS_6D, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_D4D_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_TAP_THS_6D, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_D4D
+* Description    : Read D4D_EN
+* Input          : Pointer to LSM6DSL_ACC_GYRO_D4D_t
+* Output         : Status of D4D_EN see LSM6DSL_ACC_GYRO_D4D_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_D4D(void *handle, LSM6DSL_ACC_GYRO_D4D_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TAP_THS_6D, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_D4D_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SHOCK_Duration
+* Description    : Write SHOCK
+* Input          : u8_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SHOCK_Duration(void *handle, u8_t newValue)
+{
+  u8_t value;
+
+  newValue = newValue << LSM6DSL_ACC_GYRO_SHOCK_POSITION; //mask    
+  newValue &= LSM6DSL_ACC_GYRO_SHOCK_MASK; //coerce
+  
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT_DUR2, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_SHOCK_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT_DUR2, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SHOCK_Duration
+* Description    : Read SHOCK
+* Input          : Pointer to u8_t
+* Output         : Status of SHOCK 
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SHOCK_Duration(void *handle, u8_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT_DUR2, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_SHOCK_MASK; //coerce   
+  *value = *value >> LSM6DSL_ACC_GYRO_SHOCK_POSITION; //mask    
+
+  return MEMS_SUCCESS;
+}
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_QUIET_Duration
+* Description    : Write QUIET
+* Input          : u8_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_QUIET_Duration(void *handle, u8_t newValue)
+{
+  u8_t value;
+
+  newValue = newValue << LSM6DSL_ACC_GYRO_QUIET_POSITION; //mask    
+  newValue &= LSM6DSL_ACC_GYRO_QUIET_MASK; //coerce
+  
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT_DUR2, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_QUIET_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT_DUR2, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_QUIET_Duration
+* Description    : Read QUIET
+* Input          : Pointer to u8_t
+* Output         : Status of QUIET 
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_QUIET_Duration(void *handle, u8_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT_DUR2, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_QUIET_MASK; //coerce   
+  *value = *value >> LSM6DSL_ACC_GYRO_QUIET_POSITION; //mask    
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_DUR
+* Description    : Write DUR
+* Input          : u8_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_DUR(void *handle, u8_t newValue)
+{
+  u8_t value;
+
+  newValue = newValue << LSM6DSL_ACC_GYRO_DUR_POSITION; //mask  
+  newValue &= LSM6DSL_ACC_GYRO_DUR_MASK; //coerce
+  
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT_DUR2, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_DUR_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_INT_DUR2, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_DUR
+* Description    : Read DUR
+* Input          : Pointer to u8_t
+* Output         : Status of DUR 
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_DUR(void *handle, u8_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_INT_DUR2, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_DUR_MASK; //coerce 
+  *value = *value >> LSM6DSL_ACC_GYRO_DUR_POSITION; //mask  
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_WK_THS
+* Description    : Write WK_THS
+* Input          : u8_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_WK_THS(void *handle, u8_t newValue)
+{
+  u8_t value;
+
+  newValue = newValue << LSM6DSL_ACC_GYRO_WK_THS_POSITION; //mask   
+  newValue &= LSM6DSL_ACC_GYRO_WK_THS_MASK; //coerce
+  
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_THS, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_WK_THS_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_THS, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_WK_THS
+* Description    : Read WK_THS
+* Input          : Pointer to u8_t
+* Output         : Status of WK_THS 
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_WK_THS(void *handle, u8_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_THS, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_WK_THS_MASK; //coerce  
+  *value = *value >> LSM6DSL_ACC_GYRO_WK_THS_POSITION; //mask   
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SINGLE_DOUBLE_TAP_EV
+* Description    : Write SINGLE_DOUBLE_TAP
+* Input          : LSM6DSL_ACC_GYRO_SINGLE_DOUBLE_TAP_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SINGLE_DOUBLE_TAP_EV(void *handle, LSM6DSL_ACC_GYRO_SINGLE_DOUBLE_TAP_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_THS, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_SINGLE_DOUBLE_TAP_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_THS, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SINGLE_DOUBLE_TAP_EV
+* Description    : Read SINGLE_DOUBLE_TAP
+* Input          : Pointer to LSM6DSL_ACC_GYRO_SINGLE_DOUBLE_TAP_t
+* Output         : Status of SINGLE_DOUBLE_TAP see LSM6DSL_ACC_GYRO_SINGLE_DOUBLE_TAP_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SINGLE_DOUBLE_TAP_EV(void *handle, LSM6DSL_ACC_GYRO_SINGLE_DOUBLE_TAP_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_THS, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_SINGLE_DOUBLE_TAP_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SLEEP_DUR
+* Description    : Write SLEEP_DUR
+* Input          : u8_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SLEEP_DUR(void *handle, u8_t newValue)
+{
+  u8_t value;
+
+  newValue = newValue << LSM6DSL_ACC_GYRO_SLEEP_DUR_POSITION; //mask    
+  newValue &= LSM6DSL_ACC_GYRO_SLEEP_DUR_MASK; //coerce
+  
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_DUR, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_SLEEP_DUR_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_DUR, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SLEEP_DUR
+* Description    : Read SLEEP_DUR
+* Input          : Pointer to u8_t
+* Output         : Status of SLEEP_DUR 
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SLEEP_DUR(void *handle, u8_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_DUR, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_SLEEP_DUR_MASK; //coerce   
+  *value = *value >> LSM6DSL_ACC_GYRO_SLEEP_DUR_POSITION; //mask    
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_TIMER_HR
+* Description    : Write TIMER_HR
+* Input          : LSM6DSL_ACC_GYRO_TIMER_HR_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_TIMER_HR(void *handle, LSM6DSL_ACC_GYRO_TIMER_HR_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_DUR, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_TIMER_HR_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_DUR, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TIMER_HR
+* Description    : Read TIMER_HR
+* Input          : Pointer to LSM6DSL_ACC_GYRO_TIMER_HR_t
+* Output         : Status of TIMER_HR see LSM6DSL_ACC_GYRO_TIMER_HR_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TIMER_HR(void *handle, LSM6DSL_ACC_GYRO_TIMER_HR_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_DUR, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_TIMER_HR_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_WAKE_DUR
+* Description    : Write WAKE_DUR
+* Input          : u8_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_WAKE_DUR(void *handle, u8_t newValue)
+{
+  u8_t value;
+
+  newValue = newValue << LSM6DSL_ACC_GYRO_WAKE_DUR_POSITION; //mask 
+  newValue &= LSM6DSL_ACC_GYRO_WAKE_DUR_MASK; //coerce
+  
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_DUR, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_WAKE_DUR_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_DUR, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_WAKE_DUR
+* Description    : Read WAKE_DUR
+* Input          : Pointer to u8_t
+* Output         : Status of WAKE_DUR 
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_WAKE_DUR(void *handle, u8_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_DUR, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_WAKE_DUR_MASK; //coerce    
+  *value = *value >> LSM6DSL_ACC_GYRO_WAKE_DUR_POSITION; //mask 
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_FF_THS
+* Description    : Write FF_THS
+* Input          : LSM6DSL_ACC_GYRO_FF_THS_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_FF_THS(void *handle, LSM6DSL_ACC_GYRO_FF_THS_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FREE_FALL, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_FF_THS_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_FREE_FALL, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FF_THS
+* Description    : Read FF_THS
+* Input          : Pointer to LSM6DSL_ACC_GYRO_FF_THS_t
+* Output         : Status of FF_THS see LSM6DSL_ACC_GYRO_FF_THS_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FF_THS(void *handle, LSM6DSL_ACC_GYRO_FF_THS_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FREE_FALL, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_FF_THS_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_FF_Duration
+* Description    : Write FF_DUR
+* Input          : u8_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_FF_Duration(void *handle, u8_t newValue)
+{
+  u8_t valueH, valueL;
+  u8_t value;
+
+  valueL = newValue & 0x1F;
+  valueH = (newValue >> 5) & 0x1;
+
+  /* Low part in FREE_FALL reg */
+  valueL = valueL << LSM6DSL_ACC_GYRO_FF_FREE_FALL_DUR_POSITION; //mask 
+  valueL &= LSM6DSL_ACC_GYRO_FF_FREE_FALL_DUR_MASK; //coerce
+  
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FREE_FALL, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_FF_FREE_FALL_DUR_MASK; 
+  value |= valueL;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_FREE_FALL, &value, 1) )
+    return MEMS_ERROR;
+
+  /* High part in WAKE_UP_DUR reg */
+  valueH = valueH << LSM6DSL_ACC_GYRO_FF_WAKE_UP_DUR_POSITION; //mask   
+  valueH &= LSM6DSL_ACC_GYRO_FF_WAKE_UP_DUR_MASK; //coerce
+  
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_DUR, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_FF_WAKE_UP_DUR_MASK; 
+  value |= valueH;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_DUR, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FF_Duration
+* Description    : Read FF_DUR
+* Input          : Pointer to u8_t
+* Output         : Status of FF_DUR 
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FF_Duration(void *handle, u8_t *value)
+{
+  u8_t valueH, valueL;
+
+  /* Low part from FREE_FALL reg */
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FREE_FALL, (u8_t *)&valueL, 1) )
+    return MEMS_ERROR;
+
+  valueL &= LSM6DSL_ACC_GYRO_FF_FREE_FALL_DUR_MASK; //coerce
+  valueL = valueL >> LSM6DSL_ACC_GYRO_FF_FREE_FALL_DUR_POSITION; //mask
+
+  /* High part from WAKE_UP_DUR reg */
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_WAKE_UP_DUR, (u8_t *)&valueH, 1) )
+    return MEMS_ERROR;
+
+  valueH &= LSM6DSL_ACC_GYRO_FF_WAKE_UP_DUR_MASK; //coerce
+  valueH = valueH >> LSM6DSL_ACC_GYRO_FF_WAKE_UP_DUR_POSITION; //mask
+
+  *value = ((valueH << 5) & 0x20) | valueL;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_TimerEvRouteInt1
+* Description    : Write INT1_TIMER
+* Input          : LSM6DSL_ACC_GYRO_INT1_TIMER_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_TimerEvRouteInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_TIMER_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT1_TIMER_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TimerEvRouteInt1
+* Description    : Read INT1_TIMER
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT1_TIMER_t
+* Output         : Status of INT1_TIMER see LSM6DSL_ACC_GYRO_INT1_TIMER_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TimerEvRouteInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_TIMER_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT1_TIMER_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_TiltEvOnInt1
+* Description    : Write INT1_TILT
+* Input          : LSM6DSL_ACC_GYRO_INT1_TILT_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_TiltEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_TILT_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT1_TILT_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TiltEvOnInt1
+* Description    : Read INT1_TILT
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT1_TILT_t
+* Output         : Status of INT1_TILT see LSM6DSL_ACC_GYRO_INT1_TILT_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TiltEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_TILT_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT1_TILT_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_6DEvOnInt1
+* Description    : Write INT1_6D
+* Input          : LSM6DSL_ACC_GYRO_INT1_6D_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_6DEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_6D_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT1_6D_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_6DEvOnInt1
+* Description    : Read INT1_6D
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT1_6D_t
+* Output         : Status of INT1_6D see LSM6DSL_ACC_GYRO_INT1_6D_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_6DEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_6D_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT1_6D_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_TapEvOnInt1
+* Description    : Write INT1_TAP
+* Input          : LSM6DSL_ACC_GYRO_INT1_TAP_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_TapEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_TAP_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT1_TAP_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TapEvOnInt1
+* Description    : Read INT1_TAP
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT1_TAP_t
+* Output         : Status of INT1_TAP see LSM6DSL_ACC_GYRO_INT1_TAP_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TapEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_TAP_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT1_TAP_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_FFEvOnInt1
+* Description    : Write INT1_FF
+* Input          : LSM6DSL_ACC_GYRO_INT1_FF_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_FFEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_FF_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT1_FF_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FFEvOnInt1
+* Description    : Read INT1_FF
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT1_FF_t
+* Output         : Status of INT1_FF see LSM6DSL_ACC_GYRO_INT1_FF_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FFEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_FF_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT1_FF_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_WUEvOnInt1
+* Description    : Write INT1_WU
+* Input          : LSM6DSL_ACC_GYRO_INT1_WU_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_WUEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_WU_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT1_WU_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_WUEvOnInt1
+* Description    : Read INT1_WU
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT1_WU_t
+* Output         : Status of INT1_WU see LSM6DSL_ACC_GYRO_INT1_WU_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_WUEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_WU_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT1_WU_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SingleTapOnInt1
+* Description    : Write INT1_SINGLE_TAP
+* Input          : LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SingleTapOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SingleTapOnInt1
+* Description    : Read INT1_SINGLE_TAP
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_t
+* Output         : Status of INT1_SINGLE_TAP see LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SingleTapOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SleepEvOnInt1
+* Description    : Write INT1_SLEEP
+* Input          : LSM6DSL_ACC_GYRO_INT1_SLEEP_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SleepEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_SLEEP_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT1_SLEEP_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SleepEvOnInt1
+* Description    : Read INT1_SLEEP
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT1_SLEEP_t
+* Output         : Status of INT1_SLEEP see LSM6DSL_ACC_GYRO_INT1_SLEEP_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SleepEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_SLEEP_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD1_CFG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT1_SLEEP_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_MagCorrection_Int2
+* Description    : Write INT2_IRON
+* Input          : LSM6DSL_ACC_GYRO_INT2_IRON_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_MagCorrection_Int2(void *handle, LSM6DSL_ACC_GYRO_INT2_IRON_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_IRON_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_MagCorrection_Int2
+* Description    : Read INT2_IRON
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_IRON_t
+* Output         : Status of INT2_IRON see LSM6DSL_ACC_GYRO_INT2_IRON_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_MagCorrection_Int2(void *handle, LSM6DSL_ACC_GYRO_INT2_IRON_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_IRON_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_TiltEvOnInt2
+* Description    : Write INT2_TILT
+* Input          : LSM6DSL_ACC_GYRO_INT2_TILT_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_TiltEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_TILT_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_TILT_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TiltEvOnInt2
+* Description    : Read INT2_TILT
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_TILT_t
+* Output         : Status of INT2_TILT see LSM6DSL_ACC_GYRO_INT2_TILT_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TiltEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_TILT_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_TILT_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_6DEvOnInt2
+* Description    : Write INT2_6D
+* Input          : LSM6DSL_ACC_GYRO_INT2_6D_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_6DEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_6D_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_6D_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_6DEvOnInt2
+* Description    : Read INT2_6D
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_6D_t
+* Output         : Status of INT2_6D see LSM6DSL_ACC_GYRO_INT2_6D_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_6DEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_6D_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_6D_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_TapEvOnInt2
+* Description    : Write INT2_TAP
+* Input          : LSM6DSL_ACC_GYRO_INT2_TAP_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_TapEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_TAP_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_TAP_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_TapEvOnInt2
+* Description    : Read INT2_TAP
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_TAP_t
+* Output         : Status of INT2_TAP see LSM6DSL_ACC_GYRO_INT2_TAP_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_TapEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_TAP_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_TAP_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_FFEvOnInt2
+* Description    : Write INT2_FF
+* Input          : LSM6DSL_ACC_GYRO_INT2_FF_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_FFEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_FF_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_FF_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_FFEvOnInt2
+* Description    : Read INT2_FF
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_FF_t
+* Output         : Status of INT2_FF see LSM6DSL_ACC_GYRO_INT2_FF_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_FFEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_FF_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_FF_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_WUEvOnInt2
+* Description    : Write INT2_WU
+* Input          : LSM6DSL_ACC_GYRO_INT2_WU_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_WUEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_WU_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_WU_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_WUEvOnInt2
+* Description    : Read INT2_WU
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_WU_t
+* Output         : Status of INT2_WU see LSM6DSL_ACC_GYRO_INT2_WU_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_WUEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_WU_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_WU_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SingleTapOnInt2
+* Description    : Write INT2_SINGLE_TAP
+* Input          : LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SingleTapOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SingleTapOnInt2
+* Description    : Read INT2_SINGLE_TAP
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_t
+* Output         : Status of INT2_SINGLE_TAP see LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SingleTapOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_SleepEvOnInt2
+* Description    : Write INT2_SLEEP
+* Input          : LSM6DSL_ACC_GYRO_INT2_SLEEP_t
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_SleepEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_SLEEP_t newValue)
+{
+  u8_t value;
+
+  if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  value &= ~LSM6DSL_ACC_GYRO_INT2_SLEEP_MASK; 
+  value |= newValue;
+  
+  if( !LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, &value, 1) )
+    return MEMS_ERROR;
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_R_SleepEvOnInt2
+* Description    : Read INT2_SLEEP
+* Input          : Pointer to LSM6DSL_ACC_GYRO_INT2_SLEEP_t
+* Output         : Status of INT2_SLEEP see LSM6DSL_ACC_GYRO_INT2_SLEEP_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_R_SleepEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_SLEEP_t *value)
+{
+ if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_MD2_CFG, (u8_t *)value, 1) )
+    return MEMS_ERROR;
+
+  *value &= LSM6DSL_ACC_GYRO_INT2_SLEEP_MASK; //mask
+
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : mems_status_t LSM6DSL_ACC_GYRO_Get_GetFIFOData(u8_t *buff)
+* Description    : Read GetFIFOData output register
+* Input          : pointer to [u8_t]
+* Output         : GetFIFOData buffer u8_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_Get_GetFIFOData(void *handle, u8_t *buff) 
+{
+  u8_t i, j, k;
+  u8_t numberOfByteForDimension;
+  
+  numberOfByteForDimension=2/1;
+
+  k=0;
+  for (i=0; i<1;i++ ) 
+  {
+    for (j=0; j<numberOfByteForDimension;j++ )
+    {   
+        if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_FIFO_DATA_OUT_L+k, &buff[k], 1))
+          return MEMS_ERROR;
+        k++;    
+    }
+  }
+
+  return MEMS_SUCCESS; 
+}
+
+/*******************************************************************************
+* Function Name  : mems_status_t LSM6DSL_ACC_GYRO_Get_GetTimestamp(u8_t *buff)
+* Description    : Read GetTimestamp output register
+* Input          : pointer to [u8_t]
+* Output         : GetTimestamp buffer u8_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_Get_GetTimestamp(void *handle, u8_t *buff) 
+{
+  u8_t i, j, k;
+  u8_t numberOfByteForDimension;
+  
+  numberOfByteForDimension=3/1;
+
+  k=0;
+  for (i=0; i<1;i++ ) 
+  {
+    for (j=0; j<numberOfByteForDimension;j++ )
+    {   
+        if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_TIMESTAMP0_REG+k, &buff[k], 1))
+          return MEMS_ERROR;
+        k++;    
+    }
+  }
+
+  return MEMS_SUCCESS; 
+}
+
+/*******************************************************************************
+* Function Name  : mems_status_t LSM6DSL_ACC_GYRO_Get_GetStepCounter(u8_t *buff)
+* Description    : Read GetStepCounter output register
+* Input          : pointer to [u8_t]
+* Output         : GetStepCounter buffer u8_t
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_Get_GetStepCounter(void *handle, u8_t *buff) 
+{
+  u8_t i, j, k;
+  u8_t numberOfByteForDimension;
+  
+  numberOfByteForDimension=2/1;
+
+  k=0;
+  for (i=0; i<1;i++ ) 
+  {
+    for (j=0; j<numberOfByteForDimension;j++ )
+    {   
+        if( !LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_STEP_COUNTER_L+k, &buff[k], 1))
+          return MEMS_ERROR;
+        k++;    
+    }
+  }
+
+  return MEMS_SUCCESS; 
+}
+
+/*******************************************************************************
+* Function Name  : LSM6DSL_ACC_GYRO_W_PedoThreshold(void *handle, u8_t newValue)
+* Description    : Set accelerometer threshold for pedometer
+* Input          : pointer to [u8_t]
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_PedoThreshold(void *handle, u8_t newValue)
+{
+  u8_t value;
+
+  /* Open Embedded Function Register page*/
+  LSM6DSL_ACC_GYRO_W_EmbeddedAccess(handle, LSM6DSL_ACC_GYRO_EMBEDDED_ACCESS_ENABLED);
+
+  /* read current value */
+  LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_CONFIG_PEDO_THS_MIN, &value, 1);
+
+  value &= ~0x1F; 
+  value |= (newValue & 0x1F);
+  
+  /* write new value */
+  LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_CONFIG_PEDO_THS_MIN, &value, 1);
+
+  /* Close Embedded Function Register page*/
+  LSM6DSL_ACC_GYRO_W_EmbeddedAccess(handle, LSM6DSL_ACC_GYRO_EMBEDDED_ACCESS_DISABLED);
+
+  return MEMS_SUCCESS;
+}
+
+/************** Use Sensor Hub  *******************/
+/* 
+ * Program the nine Soft Iron Matrix coefficients.
+ * The SI_Matrix buffer must provide coefficients
+ * in xx, xy, xz, yx, yy, yz, zx, zy, zz order.
+ */
+mems_status_t LSM6DSL_ACC_GYRO_SH_init_SI_Matrix(void *handle, u8_t *SI_matrix)
+{
+  /* Open Embedded Function Register page*/
+  LSM6DSL_ACC_GYRO_W_EmbeddedAccess(handle, LSM6DSL_ACC_GYRO_EMBEDDED_ACCESS_ENABLED);
+
+  /* Write the Soft Iron Matrix coefficients */
+  LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_MAG_SI_XX, SI_matrix, 9);
+
+  /* Close Embedded Function Register page*/
+  LSM6DSL_ACC_GYRO_W_EmbeddedAccess(handle, LSM6DSL_ACC_GYRO_EMBEDDED_ACCESS_DISABLED);
+
+  return MEMS_SUCCESS; 
+}
+
+/* Read a remote device through I2C Sensor Hub Slave 0 */
+mems_status_t LSM6DSL_ACC_GYRO_SH0_Program(void *handle, u8_t SlvAddr, u8_t Reg, u8_t len)
+{
+  /* Open Embedded Function Register page*/
+  LSM6DSL_ACC_GYRO_W_EmbeddedAccess(handle, LSM6DSL_ACC_GYRO_EMBEDDED_ACCESS_ENABLED);
+
+  /* Write remote device I2C slave address */
+  SlvAddr |= 0x1; /* Raise the read op bit */
+  LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_SLV0_ADD, &SlvAddr, 1);
+
+  /* Write remote device I2C subaddress */
+  LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_SLV0_SUBADD, &Reg, 1);
+
+  /* Write number of bytes to read [SLAVE0_CONFIG - 04h ]*/
+  u8_t sl0_cfg = 0;
+  sl0_cfg |= 0x00;       //00 bit [7-6] : no decimation 
+  sl0_cfg |= 0x00;       //00 bit [5-4] : one sensor 
+  sl0_cfg |= 0x00;       // 0 bit [3] : source mode read disabled
+  sl0_cfg |= len & 0x07; // bit [2-0] : number of bytes
+  
+  LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_SLAVE0_CONFIG, &sl0_cfg, 1);
+
+  /* Close Embedded Function Register page*/
+  LSM6DSL_ACC_GYRO_W_EmbeddedAccess(handle, LSM6DSL_ACC_GYRO_EMBEDDED_ACCESS_DISABLED);
+
+  /* Enable FUNC */
+  LSM6DSL_ACC_GYRO_W_FUNC_EN(handle, LSM6DSL_ACC_GYRO_FUNC_EN_ENABLED);
+
+  /* MASTER_EN */
+  LSM6DSL_ACC_GYRO_W_I2C_MASTER_Enable(handle, LSM6DSL_ACC_GYRO_MASTER_ON_ENABLED);
+
+  return MEMS_SUCCESS; 
+}
+
+/* Read a remote device through I2C Sensor Hub Slave 0 */
+mems_status_t LSM6DSL_ACC_GYRO_SH0_ReadMem(void *handle, u8_t SlvAddr, u8_t Reg, u8_t *Bufp, u8_t len, u8_t stop)
+{
+  LSM6DSL_ACC_GYRO_SENS_HUB_END_t op_cmpl = LSM6DSL_ACC_GYRO_SENS_HUB_END_STILL_ONGOING;
+  LSM6DSL_ACC_GYRO_XLDA_t op_update = LSM6DSL_ACC_GYRO_XLDA_NO_DATA_AVAIL;
+  u8_t dummy[6];
+  
+  LSM6DSL_ACC_GYRO_W_ODR_XL(handle, LSM6DSL_ACC_GYRO_ODR_XL_POWER_DOWN);
+  
+  LSM6DSL_ACC_GYRO_SH0_Program(handle, SlvAddr, Reg, len);
+
+  /* Syncronize the SH with internal trigger (xl) */
+  LSM6DSL_ACC_GYRO_W_ODR_XL(handle, LSM6DSL_ACC_GYRO_ODR_XL_104Hz);
+  
+  /* Wait until operation is not completed */
+  LSM6DSL_ACC_GYRO_GetRawAccData(handle, dummy);
+  do {
+    LSM6DSL_ACC_GYRO_R_XLDA(handle, &op_update);
+  } while(op_update != LSM6DSL_ACC_GYRO_XLDA_DATA_AVAIL);
+  do {
+    LSM6DSL_ACC_GYRO_R_SENS_HUB_END(handle, &op_cmpl);
+  } while(op_cmpl != LSM6DSL_ACC_GYRO_SENS_HUB_END_OP_COMPLETED);
+
+    
+  /* Read the result */
+  LSM6DSL_ACC_GYRO_read_reg(handle, LSM6DSL_ACC_GYRO_SENSORHUB1_REG, Bufp, len);
+
+  LSM6DSL_ACC_GYRO_W_ODR_XL(handle, LSM6DSL_ACC_GYRO_ODR_XL_POWER_DOWN);
+  
+  if (stop) { 
+    /* Stop everything */
+    LSM6DSL_ACC_GYRO_W_FUNC_EN(handle, LSM6DSL_ACC_GYRO_FUNC_EN_DISABLED); 
+    LSM6DSL_ACC_GYRO_W_I2C_MASTER_Enable(handle, LSM6DSL_ACC_GYRO_MASTER_ON_DISABLED); 
+  }
+
+  return MEMS_SUCCESS; 
+}
+
+/* Write a remote device through I2C Sensor Hub Slave 0 */
+mems_status_t LSM6DSL_ACC_GYRO_SH0_WriteByte(void *handle, u8_t SlvAddr, u8_t Reg, u8_t Bufp)
+{
+  LSM6DSL_ACC_GYRO_SENS_HUB_END_t op_cmpl = LSM6DSL_ACC_GYRO_SENS_HUB_END_STILL_ONGOING;
+  LSM6DSL_ACC_GYRO_XLDA_t op_update = LSM6DSL_ACC_GYRO_XLDA_NO_DATA_AVAIL;
+  u8_t dummy[6];
+  
+  /* Open Embedded Function Register page*/
+  LSM6DSL_ACC_GYRO_W_EmbeddedAccess(handle, LSM6DSL_ACC_GYRO_EMBEDDED_ACCESS_ENABLED);
+
+  /* Write remote device I2C slave address */
+  LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_SLV0_ADD, &SlvAddr, 1);
+
+  /* Write remote device I2C subaddress */
+  LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_SLV0_SUBADD, &Reg, 1);
+
+  /* Write the data */
+  LSM6DSL_ACC_GYRO_write_reg(handle, LSM6DSL_ACC_GYRO_DATAWRITE_SRC_MODE_SUB_SLV0, &Bufp, 1);
+
+  /* Close Embedded Function Register page*/
+  LSM6DSL_ACC_GYRO_W_EmbeddedAccess(handle, LSM6DSL_ACC_GYRO_EMBEDDED_ACCESS_DISABLED);
+
+  /* Enable FUNC */
+  LSM6DSL_ACC_GYRO_W_FUNC_EN(handle, LSM6DSL_ACC_GYRO_FUNC_EN_ENABLED);
+
+    /* Enable PULL_UP_EN and MASTER_EN */
+  //LSM6DSL_ACC_GYRO_W_PULL_UP_EN(handle, LSM6DSL_ACC_GYRO_PULL_UP_EN_ENABLED);
+  LSM6DSL_ACC_GYRO_W_I2C_MASTER_Enable(handle, LSM6DSL_ACC_GYRO_MASTER_ON_ENABLED);
+
+  /* Syncronize the SH with internal trigger (xl) */
+  LSM6DSL_ACC_GYRO_W_ODR_XL(handle, LSM6DSL_ACC_GYRO_ODR_XL_104Hz);
+  
+  /* Wait until operation is not completed */
+  LSM6DSL_ACC_GYRO_GetRawAccData(handle, dummy);
+  do {
+    LSM6DSL_ACC_GYRO_R_XLDA(handle, &op_update);
+  } while(op_update != LSM6DSL_ACC_GYRO_XLDA_DATA_AVAIL);
+  do {
+    LSM6DSL_ACC_GYRO_R_SENS_HUB_END(handle, &op_cmpl);
+  } while(op_cmpl != LSM6DSL_ACC_GYRO_SENS_HUB_END_OP_COMPLETED);
+  
+  LSM6DSL_ACC_GYRO_W_ODR_XL(handle, LSM6DSL_ACC_GYRO_ODR_XL_POWER_DOWN);
+  
+  /* Stop everything */
+  LSM6DSL_ACC_GYRO_W_FUNC_EN(handle, LSM6DSL_ACC_GYRO_FUNC_EN_DISABLED);
+  LSM6DSL_ACC_GYRO_W_I2C_MASTER_Enable(handle, LSM6DSL_ACC_GYRO_MASTER_ON_DISABLED);
+  
+
+  return MEMS_SUCCESS; 
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/LSM6DSL/LSM6DSL_acc_gyro_driver.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,2752 @@
+/**
+ ******************************************************************************
+ * @file    LSM6DSL_acc_gyro_driver.h
+ * @author  MEMS Application Team
+ * @version V1.5
+ * @date    17-May-2016
+ * @brief   LSM6DSL header driver file
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LSM6DSL_ACC_GYRO_DRIVER__H
+#define __LSM6DSL_ACC_GYRO_DRIVER__H
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+/* Exported types ------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//these could change accordingly with the architecture
+
+#ifndef __ARCHDEP__TYPES
+#define __ARCHDEP__TYPES
+
+typedef unsigned char u8_t;
+typedef unsigned short int u16_t;
+typedef unsigned int u32_t;
+typedef int i32_t;
+typedef short int i16_t;
+typedef signed char i8_t;
+
+#endif /*__ARCHDEP__TYPES*/
+
+/* Exported common structure --------------------------------------------------------*/
+
+#ifndef __SHARED__TYPES
+#define __SHARED__TYPES
+
+typedef union{
+    i16_t i16bit[3];
+    u8_t u8bit[6];
+} Type3Axis16bit_U; 
+
+typedef union{
+    i16_t i16bit;
+    u8_t u8bit[2];
+} Type1Axis16bit_U;
+
+typedef union{
+    i32_t i32bit;
+    u8_t u8bit[4];
+} Type1Axis32bit_U;
+
+typedef enum {
+  MEMS_SUCCESS              =       0x01,
+  MEMS_ERROR                =       0x00    
+} mems_status_t;
+
+#endif /*__SHARED__TYPES*/
+
+/* Exported macro ------------------------------------------------------------*/
+
+/* Exported constants --------------------------------------------------------*/
+
+/************** I2C Address *****************/
+
+#define LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW   0xD4  // SAD[0] = 0
+#define LSM6DSL_ACC_GYRO_I2C_ADDRESS_HIGH  0xD6  // SAD[0] = 1
+
+/************** Who am I  *******************/
+
+#define LSM6DSL_ACC_GYRO_WHO_AM_I         0x6A
+
+/************** Device Register  *******************/
+
+#define LSM6DSL_ACC_GYRO_FUNC_CFG_ACCESS    0X01
+
+#define LSM6DSL_ACC_GYRO_SENSOR_SYNC_TIME   0X04
+#define LSM6DSL_ACC_GYRO_SENSOR_RES_RATIO   0X05
+
+#define LSM6DSL_ACC_GYRO_FIFO_CTRL1     0X06
+#define LSM6DSL_ACC_GYRO_FIFO_CTRL2     0X07
+#define LSM6DSL_ACC_GYRO_FIFO_CTRL3     0X08
+#define LSM6DSL_ACC_GYRO_FIFO_CTRL4     0X09
+#define LSM6DSL_ACC_GYRO_FIFO_CTRL5     0X0A
+
+#define LSM6DSL_ACC_GYRO_DRDY_PULSE_CFG_G   0X0B
+#define LSM6DSL_ACC_GYRO_INT1_CTRL      0X0D
+#define LSM6DSL_ACC_GYRO_INT2_CTRL      0X0E
+#define LSM6DSL_ACC_GYRO_WHO_AM_I_REG   0X0F
+#define LSM6DSL_ACC_GYRO_CTRL1_XL   0X10
+#define LSM6DSL_ACC_GYRO_CTRL2_G    0X11
+#define LSM6DSL_ACC_GYRO_CTRL3_C    0X12
+#define LSM6DSL_ACC_GYRO_CTRL4_C    0X13
+#define LSM6DSL_ACC_GYRO_CTRL5_C    0X14
+#define LSM6DSL_ACC_GYRO_CTRL6_G    0X15
+#define LSM6DSL_ACC_GYRO_CTRL7_G    0X16
+#define LSM6DSL_ACC_GYRO_CTRL8_XL   0X17
+#define LSM6DSL_ACC_GYRO_CTRL9_XL   0X18
+#define LSM6DSL_ACC_GYRO_CTRL10_C   0X19
+
+#define LSM6DSL_ACC_GYRO_MASTER_CONFIG      0X1A
+#define LSM6DSL_ACC_GYRO_WAKE_UP_SRC    0X1B
+#define LSM6DSL_ACC_GYRO_TAP_SRC    0X1C
+#define LSM6DSL_ACC_GYRO_D6D_SRC    0X1D
+#define LSM6DSL_ACC_GYRO_STATUS_REG     0X1E
+
+#define LSM6DSL_ACC_GYRO_OUT_TEMP_L     0X20
+#define LSM6DSL_ACC_GYRO_OUT_TEMP_H     0X21
+#define LSM6DSL_ACC_GYRO_OUTX_L_G   0X22
+#define LSM6DSL_ACC_GYRO_OUTX_H_G   0X23
+#define LSM6DSL_ACC_GYRO_OUTY_L_G   0X24
+#define LSM6DSL_ACC_GYRO_OUTY_H_G   0X25
+#define LSM6DSL_ACC_GYRO_OUTZ_L_G   0X26
+#define LSM6DSL_ACC_GYRO_OUTZ_H_G   0X27
+#define LSM6DSL_ACC_GYRO_OUTX_L_XL      0X28
+#define LSM6DSL_ACC_GYRO_OUTX_H_XL      0X29
+#define LSM6DSL_ACC_GYRO_OUTY_L_XL      0X2A
+#define LSM6DSL_ACC_GYRO_OUTY_H_XL      0X2B
+#define LSM6DSL_ACC_GYRO_OUTZ_L_XL      0X2C
+#define LSM6DSL_ACC_GYRO_OUTZ_H_XL      0X2D
+#define LSM6DSL_ACC_GYRO_SENSORHUB1_REG     0X2E
+#define LSM6DSL_ACC_GYRO_SENSORHUB2_REG     0X2F
+#define LSM6DSL_ACC_GYRO_SENSORHUB3_REG     0X30
+#define LSM6DSL_ACC_GYRO_SENSORHUB4_REG     0X31
+#define LSM6DSL_ACC_GYRO_SENSORHUB5_REG     0X32
+#define LSM6DSL_ACC_GYRO_SENSORHUB6_REG     0X33
+#define LSM6DSL_ACC_GYRO_SENSORHUB7_REG     0X34
+#define LSM6DSL_ACC_GYRO_SENSORHUB8_REG     0X35
+#define LSM6DSL_ACC_GYRO_SENSORHUB9_REG     0X36
+#define LSM6DSL_ACC_GYRO_SENSORHUB10_REG    0X37
+#define LSM6DSL_ACC_GYRO_SENSORHUB11_REG    0X38
+#define LSM6DSL_ACC_GYRO_SENSORHUB12_REG    0X39
+#define LSM6DSL_ACC_GYRO_FIFO_STATUS1   0X3A
+#define LSM6DSL_ACC_GYRO_FIFO_STATUS2   0X3B
+#define LSM6DSL_ACC_GYRO_FIFO_STATUS3   0X3C
+#define LSM6DSL_ACC_GYRO_FIFO_STATUS4   0X3D
+#define LSM6DSL_ACC_GYRO_FIFO_DATA_OUT_L    0X3E
+#define LSM6DSL_ACC_GYRO_FIFO_DATA_OUT_H    0X3F
+#define LSM6DSL_ACC_GYRO_TIMESTAMP0_REG     0X40
+#define LSM6DSL_ACC_GYRO_TIMESTAMP1_REG     0X41
+#define LSM6DSL_ACC_GYRO_TIMESTAMP2_REG     0X42
+
+#define LSM6DSL_ACC_GYRO_TIMESTAMP_L    0X49
+#define LSM6DSL_ACC_GYRO_TIMESTAMP_H    0X4A
+
+#define LSM6DSL_ACC_GYRO_STEP_COUNTER_L     0X4B
+#define LSM6DSL_ACC_GYRO_STEP_COUNTER_H     0X4C
+
+#define LSM6DSL_ACC_GYRO_SENSORHUB13_REG    0X4D
+#define LSM6DSL_ACC_GYRO_SENSORHUB14_REG    0X4E
+#define LSM6DSL_ACC_GYRO_SENSORHUB15_REG    0X4F
+#define LSM6DSL_ACC_GYRO_SENSORHUB16_REG    0X50
+#define LSM6DSL_ACC_GYRO_SENSORHUB17_REG    0X51
+#define LSM6DSL_ACC_GYRO_SENSORHUB18_REG    0X52
+
+#define LSM6DSL_ACC_GYRO_FUNC_SRC   0X53
+#define LSM6DSL_ACC_GYRO_TAP_CFG1   0X58
+#define LSM6DSL_ACC_GYRO_TAP_THS_6D     0X59
+#define LSM6DSL_ACC_GYRO_INT_DUR2   0X5A
+#define LSM6DSL_ACC_GYRO_WAKE_UP_THS    0X5B
+#define LSM6DSL_ACC_GYRO_WAKE_UP_DUR    0X5C
+#define LSM6DSL_ACC_GYRO_FREE_FALL      0X5D
+#define LSM6DSL_ACC_GYRO_MD1_CFG    0X5E
+#define LSM6DSL_ACC_GYRO_MD2_CFG    0X5F
+
+#define LSM6DSL_ACC_GYRO_OUT_MAG_RAW_X_L    0X66 
+#define LSM6DSL_ACC_GYRO_OUT_MAG_RAW_X_H    0X67
+#define LSM6DSL_ACC_GYRO_OUT_MAG_RAW_Y_L    0X68
+#define LSM6DSL_ACC_GYRO_OUT_MAG_RAW_Y_H    0X69
+#define LSM6DSL_ACC_GYRO_OUT_MAG_RAW_Z_L    0X6A
+#define LSM6DSL_ACC_GYRO_OUT_MAG_RAW_Z_H    0X6B
+
+#define LSM6DSL_ACC_GYRO_X_OFS_USR      0X73
+#define LSM6DSL_ACC_GYRO_Y_OFS_USR      0X74
+#define LSM6DSL_ACC_GYRO_Z_OFS_USR      0X75
+
+/************** Embedded functions register mapping  *******************/
+#define LSM6DSL_ACC_GYRO_SLV0_ADD                     0x02
+#define LSM6DSL_ACC_GYRO_SLV0_SUBADD                  0x03
+#define LSM6DSL_ACC_GYRO_SLAVE0_CONFIG                0x04
+#define LSM6DSL_ACC_GYRO_SLV1_ADD                     0x05
+#define LSM6DSL_ACC_GYRO_SLV1_SUBADD                  0x06
+#define LSM6DSL_ACC_GYRO_SLAVE1_CONFIG                0x07
+#define LSM6DSL_ACC_GYRO_SLV2_ADD                     0x08
+#define LSM6DSL_ACC_GYRO_SLV2_SUBADD                  0x09
+#define LSM6DSL_ACC_GYRO_SLAVE2_CONFIG                0x0A
+#define LSM6DSL_ACC_GYRO_SLV3_ADD                     0x0B
+#define LSM6DSL_ACC_GYRO_SLV3_SUBADD                  0x0C
+#define LSM6DSL_ACC_GYRO_SLAVE3_CONFIG                0x0D
+#define LSM6DSL_ACC_GYRO_DATAWRITE_SRC_MODE_SUB_SLV0  0x0E
+#define LSM6DSL_ACC_GYRO_CONFIG_PEDO_THS_MIN          0x0F
+
+#define LSM6DSL_ACC_GYRO_SM_STEP_THS                  0x13
+#define LSM6DSL_ACC_GYRO_PEDO_DEB_REG                0x14
+#define LSM6DSL_ACC_GYRO_STEP_COUNT_DELTA            0x15
+
+#define LSM6DSL_ACC_GYRO_MAG_SI_XX                    0x24
+#define LSM6DSL_ACC_GYRO_MAG_SI_XY                    0x25
+#define LSM6DSL_ACC_GYRO_MAG_SI_XZ                    0x26
+#define LSM6DSL_ACC_GYRO_MAG_SI_YX                    0x27
+#define LSM6DSL_ACC_GYRO_MAG_SI_YY                    0x28
+#define LSM6DSL_ACC_GYRO_MAG_SI_YZ                    0x29
+#define LSM6DSL_ACC_GYRO_MAG_SI_ZX                    0x2A
+#define LSM6DSL_ACC_GYRO_MAG_SI_ZY                    0x2B
+#define LSM6DSL_ACC_GYRO_MAG_SI_ZZ                    0x2C
+#define LSM6DSL_ACC_GYRO_MAG_OFFX_L                   0x2D
+#define LSM6DSL_ACC_GYRO_MAG_OFFX_H                   0x2E
+#define LSM6DSL_ACC_GYRO_MAG_OFFY_L                   0x2F
+#define LSM6DSL_ACC_GYRO_MAG_OFFY_H                   0x30
+#define LSM6DSL_ACC_GYRO_MAG_OFFZ_L                   0x31
+#define LSM6DSL_ACC_GYRO_MAG_OFFZ_H                   0x32
+
+/************** Generic Function  *******************/
+
+/*******************************************************************************
+* Register      : Generic - All
+* Address       : Generic - All
+* Bit Group Name: None
+* Permission    : W
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_write_reg( void *handle, u8_t Reg, u8_t *Bufp, u16_t len );
+
+/*******************************************************************************
+* Register      : Generic - All
+* Address       : Generic - All
+* Bit Group Name: None
+* Permission    : R
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_read_reg( void *handle, u8_t Reg, u8_t *Bufp, u16_t len );
+
+/**************** Base Function  *******************/
+
+/*******************************************************************************
+* Register      : WHO_AM_I
+* Address       : 0X0F
+* Bit Group Name: WHO_AM_I_BIT
+* Permission    : RO
+*******************************************************************************/
+#define       LSM6DSL_ACC_GYRO_WHO_AM_I_BIT_MASK      0xFF
+#define       LSM6DSL_ACC_GYRO_WHO_AM_I_BIT_POSITION      0
+mems_status_t LSM6DSL_ACC_GYRO_R_WHO_AM_I(void *handle, u8_t *value);
+
+/*******************************************************************************
+* Register      : CTRL3_C
+* Address       : 0X12
+* Bit Group Name: BDU
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_BDU_CONTINUOS       =0x00,
+    LSM6DSL_ACC_GYRO_BDU_BLOCK_UPDATE        =0x40,
+} LSM6DSL_ACC_GYRO_BDU_t;
+
+#define       LSM6DSL_ACC_GYRO_BDU_MASK   0x40
+mems_status_t LSM6DSL_ACC_GYRO_W_BDU(void *handle, LSM6DSL_ACC_GYRO_BDU_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_BDU(void *handle, LSM6DSL_ACC_GYRO_BDU_t *value);
+
+/*******************************************************************************
+* Register      : CTRL1_XL
+* Address       : 0X10
+* Bit Group Name: FS_XL
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_FS_XL_2g        =0x00,
+    LSM6DSL_ACC_GYRO_FS_XL_16g       =0x04,
+    LSM6DSL_ACC_GYRO_FS_XL_4g        =0x08,
+    LSM6DSL_ACC_GYRO_FS_XL_8g        =0x0C,
+} LSM6DSL_ACC_GYRO_FS_XL_t;
+
+#define       LSM6DSL_ACC_GYRO_FS_XL_MASK     0x0C
+mems_status_t LSM6DSL_ACC_GYRO_W_FS_XL(void *handle, LSM6DSL_ACC_GYRO_FS_XL_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_FS_XL(void *handle, LSM6DSL_ACC_GYRO_FS_XL_t *value);
+
+/*******************************************************************************
+* Register      : <REGISTER_L> - <REGISTER_H>
+* Output Type   : GetAccData
+* Permission    : RO 
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_GetRawAccData(void *handle, u8_t *buff);
+mems_status_t LSM6DSL_ACC_Get_Acceleration(void *handle, int *buff, u8_t from_fifo);
+
+/*******************************************************************************
+* Register      : CTRL1_XL
+* Address       : 0X10
+* Bit Group Name: ODR_XL
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_ODR_XL_POWER_DOWN       =0x00,
+    LSM6DSL_ACC_GYRO_ODR_XL_13Hz         =0x10,
+    LSM6DSL_ACC_GYRO_ODR_XL_26Hz         =0x20,
+    LSM6DSL_ACC_GYRO_ODR_XL_52Hz         =0x30,
+    LSM6DSL_ACC_GYRO_ODR_XL_104Hz        =0x40,
+    LSM6DSL_ACC_GYRO_ODR_XL_208Hz        =0x50,
+    LSM6DSL_ACC_GYRO_ODR_XL_416Hz        =0x60,
+    LSM6DSL_ACC_GYRO_ODR_XL_833Hz        =0x70,
+    LSM6DSL_ACC_GYRO_ODR_XL_1660Hz       =0x80,
+    LSM6DSL_ACC_GYRO_ODR_XL_3330Hz       =0x90,
+    LSM6DSL_ACC_GYRO_ODR_XL_6660Hz       =0xA0,
+} LSM6DSL_ACC_GYRO_ODR_XL_t;
+
+#define       LSM6DSL_ACC_GYRO_ODR_XL_MASK    0xF0
+mems_status_t LSM6DSL_ACC_GYRO_W_ODR_XL(void *handle, LSM6DSL_ACC_GYRO_ODR_XL_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_ODR_XL(void *handle, LSM6DSL_ACC_GYRO_ODR_XL_t *value);
+mems_status_t LSM6DSL_ACC_GYRO_translate_ODR_XL(LSM6DSL_ACC_GYRO_ODR_XL_t value, u16_t *odr_hz_val);
+
+/*******************************************************************************
+* Register      : CTRL2_G
+* Address       : 0X11
+* Bit Group Name: FS_G
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_FS_G_245dps         =0x00,
+    LSM6DSL_ACC_GYRO_FS_G_500dps         =0x04,
+    LSM6DSL_ACC_GYRO_FS_G_1000dps        =0x08,
+    LSM6DSL_ACC_GYRO_FS_G_2000dps        =0x0C,
+} LSM6DSL_ACC_GYRO_FS_G_t;
+
+#define       LSM6DSL_ACC_GYRO_FS_G_MASK      0x0C
+mems_status_t LSM6DSL_ACC_GYRO_W_FS_G(void *handle, LSM6DSL_ACC_GYRO_FS_G_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_FS_G(void *handle, LSM6DSL_ACC_GYRO_FS_G_t *value);
+
+/*******************************************************************************
+* Register      : CTRL2_G
+* Address       : 0X11
+* Bit Group Name: ODR_G
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_ODR_G_POWER_DOWN        =0x00,
+    LSM6DSL_ACC_GYRO_ODR_G_13Hz          =0x10,
+    LSM6DSL_ACC_GYRO_ODR_G_26Hz          =0x20,
+    LSM6DSL_ACC_GYRO_ODR_G_52Hz          =0x30,
+    LSM6DSL_ACC_GYRO_ODR_G_104Hz         =0x40,
+    LSM6DSL_ACC_GYRO_ODR_G_208Hz         =0x50,
+    LSM6DSL_ACC_GYRO_ODR_G_416Hz         =0x60,
+    LSM6DSL_ACC_GYRO_ODR_G_833Hz         =0x70,
+    LSM6DSL_ACC_GYRO_ODR_G_1660Hz        =0x80,
+    LSM6DSL_ACC_GYRO_ODR_G_3330Hz        =0x90,
+    LSM6DSL_ACC_GYRO_ODR_G_6660Hz        =0xA0,
+} LSM6DSL_ACC_GYRO_ODR_G_t;
+
+#define       LSM6DSL_ACC_GYRO_ODR_G_MASK     0xF0
+mems_status_t LSM6DSL_ACC_GYRO_W_ODR_G(void *handle, LSM6DSL_ACC_GYRO_ODR_G_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_ODR_G(void *handle, LSM6DSL_ACC_GYRO_ODR_G_t *value);
+mems_status_t LSM6DSL_ACC_GYRO_translate_ODR_G(LSM6DSL_ACC_GYRO_ODR_G_t value, u16_t *odr_hz_val);
+
+/*******************************************************************************
+* Register      : <REGISTER_L> - <REGISTER_H>
+* Output Type   : GetGyroData
+* Permission    : RO 
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_GetRawGyroData(void *handle, u8_t *buff); 
+mems_status_t LSM6DSL_ACC_Get_AngularRate(void *handle, int *buff, u8_t from_fifo);
+
+/*******************************************************************************
+* Register      : CTRL1_XL
+* Address       : 0X10
+* Bit Group Name: BW_SEL
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_BW_SEL_ODR2         =0x00,
+    LSM6DSL_ACC_GYRO_BW_SEL_ODR4         =0x02,
+} LSM6DSL_ACC_GYRO_BW_SEL_t;
+
+#define       LSM6DSL_ACC_GYRO_BW_SEL_MASK    0x02
+mems_status_t LSM6DSL_ACC_GYRO_W_BW_SEL(void *handle, LSM6DSL_ACC_GYRO_BW_SEL_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_BW_SEL(void *handle, LSM6DSL_ACC_GYRO_BW_SEL_t *value);
+
+/*******************************************************************************
+* Register      : CTRL2_G
+* Address       : 0X11
+* Bit Group Name: FS_125
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_FS_125_DISABLED         =0x00,
+    LSM6DSL_ACC_GYRO_FS_125_ENABLED          =0x02,
+} LSM6DSL_ACC_GYRO_FS_125_t;
+
+#define       LSM6DSL_ACC_GYRO_FS_125_MASK    0x02
+mems_status_t LSM6DSL_ACC_GYRO_W_FS_125(void *handle, LSM6DSL_ACC_GYRO_FS_125_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_FS_125(void *handle, LSM6DSL_ACC_GYRO_FS_125_t *value);
+
+/**************** Advanced Function  *******************/
+
+/*******************************************************************************
+* Register      : CTRL3_C
+* Address       : 0X12
+* Bit Group Name: BLE
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_BLE_LSB         =0x00,
+    LSM6DSL_ACC_GYRO_BLE_MSB         =0x02,
+} LSM6DSL_ACC_GYRO_BLE_t;
+
+#define       LSM6DSL_ACC_GYRO_BLE_MASK   0x02
+mems_status_t LSM6DSL_ACC_GYRO_W_BLE(void *handle, LSM6DSL_ACC_GYRO_BLE_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_BLE(void *handle, LSM6DSL_ACC_GYRO_BLE_t *value);
+
+/*******************************************************************************
+* Register      : FUNC_CFG_ACCESS
+* Address       : 0X01
+* Bit Group Name: EMB_ACC
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_EMBEDDED_ACCESS_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_EMBEDDED_ACCESS_ENABLED         =0x80,
+} LSM6DSL_ACC_GYRO_EMB_ACC_t;
+
+#define       LSM6DSL_ACC_GYRO_EMB_ACC_MASK   0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_EmbeddedAccess(void *handle, LSM6DSL_ACC_GYRO_EMB_ACC_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_EmbeddedAccess(void *handle, LSM6DSL_ACC_GYRO_EMB_ACC_t *value);
+
+/*******************************************************************************
+* Register      : SENSOR_SYNC_TIME
+* Address       : 0X04
+* Bit Group Name: TPH
+* Permission    : RW
+*******************************************************************************/
+#define       LSM6DSL_ACC_GYRO_TPH_MASK   0xFF
+#define       LSM6DSL_ACC_GYRO_TPH_POSITION   0
+mems_status_t LSM6DSL_ACC_GYRO_W_Stamping_Time_Frame(void *handle, u8_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_Stamping_Time_Frame(void *handle, u8_t *value);
+
+/*******************************************************************************
+* Register      : SENSOR_SYNC_RES_RATIO
+* Address       : 0X05
+* Bit Group Name: RR
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_TIM_RATIO_2_11          =0x00,
+    LSM6DSL_ACC_GYRO_TIM_RATIO_2_12          =0x01,
+    LSM6DSL_ACC_GYRO_TIM_RATIO_2_13          =0x02,
+    LSM6DSL_ACC_GYRO_TIM_RATIO_2_14          =0x03,
+} LSM6DSL_ACC_GYRO_SYNC_RES_RATIO_t;
+
+#define       LSM6DSL_ACC_GYRO_SYNC_RES_RATIO_MASK    0x03
+mems_status_t LSM6DSL_ACC_GYRO_W_SYNC_RES_RATIO(void *handle, LSM6DSL_ACC_GYRO_SYNC_RES_RATIO_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SYNC_RES_RATIO(void *handle, LSM6DSL_ACC_GYRO_SYNC_RES_RATIO_t *value);
+
+
+/*******************************************************************************
+* Register      : FIFO_CTRL1
+* Address       : 0X06
+* Bit Group Name: WTM_FIFO
+* Permission    : RW
+*******************************************************************************/
+#define       LSM6DSL_ACC_GYRO_WTM_FIFO_CTRL1_MASK    0xFF
+#define       LSM6DSL_ACC_GYRO_WTM_FIFO_CTRL1_POSITION    0
+#define       LSM6DSL_ACC_GYRO_WTM_FIFO_CTRL2_MASK    0x07
+#define       LSM6DSL_ACC_GYRO_WTM_FIFO_CTRL2_POSITION    0
+mems_status_t LSM6DSL_ACC_GYRO_W_FIFO_Watermark(void *handle, u16_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFO_Watermark(void *handle, u16_t *value);
+
+/*******************************************************************************
+* Register      : FIFO_CTRL2
+* Address       : 0X07
+* Bit Group Name: FIFO_TEMP_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_FIFO_TEMP_DISABLE       =0x00,
+    LSM6DSL_ACC_GYRO_FIFO_TEMP_ENABLE        =0x08,
+} LSM6DSL_ACC_GYRO_FIFO_TEMP_t;
+
+#define       LSM6DSL_ACC_GYRO_FIFO_TEMP_MASK     0x08
+mems_status_t LSM6DSL_ACC_GYRO_W_FIFO_TEMP(void *handle, LSM6DSL_ACC_GYRO_FIFO_TEMP_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFO_TEMP(void *handle, LSM6DSL_ACC_GYRO_FIFO_TEMP_t *value);
+
+
+/*******************************************************************************
+* Register      : FIFO_CTRL2
+* Address       : 0X07
+* Bit Group Name: TIM_PEDO_FIFO_DRDY
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_DRDY_DISABLED         =0x00,
+    LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_DRDY_ENABLED          =0x40,
+} LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_DRDY_t;
+
+#define       LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_DRDY_MASK    0x40
+mems_status_t LSM6DSL_ACC_GYRO_W_TIM_PEDO_FIFO_Write_En(void *handle, LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_DRDY_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_TIM_PEDO_FIFO_Write_En(void *handle, LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_DRDY_t *value);
+
+/*******************************************************************************
+* Register      : FIFO_CTRL2
+* Address       : 0X07
+* Bit Group Name: TIM_PEDO_FIFO_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_EN_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_EN_ENABLED        =0x80,
+} LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_EN_t;
+
+#define       LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_EN_MASK      0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_TIM_PEDO_FIFO_En(void *handle, LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_EN_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_TIM_PEDO_FIFO_En(void *handle, LSM6DSL_ACC_GYRO_TIM_PEDO_FIFO_EN_t *value);
+
+/*******************************************************************************
+* Register      : FIFO_CTRL3
+* Address       : 0X08
+* Bit Group Name: DEC_FIFO_XL
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DEC_FIFO_XL_DATA_NOT_IN_FIFO        =0x00,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_XL_NO_DECIMATION       =0x01,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_XL_DECIMATION_BY_2         =0x02,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_XL_DECIMATION_BY_3         =0x03,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_XL_DECIMATION_BY_4         =0x04,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_XL_DECIMATION_BY_8         =0x05,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_XL_DECIMATION_BY_16        =0x06,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_XL_DECIMATION_BY_32        =0x07,
+} LSM6DSL_ACC_GYRO_DEC_FIFO_XL_t;
+
+#define       LSM6DSL_ACC_GYRO_DEC_FIFO_XL_MASK   0x07
+mems_status_t LSM6DSL_ACC_GYRO_W_DEC_FIFO_XL(void *handle, LSM6DSL_ACC_GYRO_DEC_FIFO_XL_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_W_DEC_FIFO_XL_val(void *handle, u16_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DEC_FIFO_XL(void *handle, LSM6DSL_ACC_GYRO_DEC_FIFO_XL_t *value);
+
+/*******************************************************************************
+* Register      : FIFO_CTRL3
+* Address       : 0X08
+* Bit Group Name: DEC_FIFO_G
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DEC_FIFO_G_DATA_NOT_IN_FIFO         =0x00,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_G_NO_DECIMATION        =0x08,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_G_DECIMATION_BY_2          =0x10,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_G_DECIMATION_BY_3          =0x18,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_G_DECIMATION_BY_4          =0x20,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_G_DECIMATION_BY_8          =0x28,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_G_DECIMATION_BY_16         =0x30,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_G_DECIMATION_BY_32         =0x38,
+} LSM6DSL_ACC_GYRO_DEC_FIFO_G_t;
+
+#define       LSM6DSL_ACC_GYRO_DEC_FIFO_G_MASK    0x38
+mems_status_t LSM6DSL_ACC_GYRO_W_DEC_FIFO_G(void *handle, LSM6DSL_ACC_GYRO_DEC_FIFO_G_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_W_DEC_FIFO_G_val(void *handle, u16_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DEC_FIFO_G(void *handle, LSM6DSL_ACC_GYRO_DEC_FIFO_G_t *value);
+
+/*******************************************************************************
+* Register      : FIFO_CTRL4
+* Address       : 0X09
+* Bit Group Name: DEC_DS3_FIFO
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_DATA_NOT_IN_FIFO       =0x00,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_NO_DECIMATION          =0x01,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_DECIMATION_BY_2        =0x02,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_DECIMATION_BY_3        =0x03,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_DECIMATION_BY_4        =0x04,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_DECIMATION_BY_8        =0x05,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_DECIMATION_BY_16       =0x06,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_DECIMATION_BY_32       =0x07,
+} LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_t;
+
+#define       LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_MASK      0x07
+mems_status_t LSM6DSL_ACC_GYRO_W_DEC_FIFO_DS3(void *handle, LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DEC_FIFO_DS3(void *handle, LSM6DSL_ACC_GYRO_DEC_FIFO_DS3_t *value);
+
+/*******************************************************************************
+* Register      : FIFO_CTRL4
+* Address       : 0X09
+* Bit Group Name: DEC_DS4_FIFO
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_DATA_NOT_IN_FIFO       =0x00,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_NO_DECIMATION          =0x08,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_DECIMATION_BY_2        =0x10,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_DECIMATION_BY_3        =0x18,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_DECIMATION_BY_4        =0x20,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_DECIMATION_BY_8        =0x28,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_DECIMATION_BY_16       =0x30,
+    LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_DECIMATION_BY_32       =0x38,
+} LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_t;
+
+#define       LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_MASK      0x38
+mems_status_t LSM6DSL_ACC_GYRO_W_DEC_FIFO_DS4(void *handle, LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DEC_FIFO_DS4(void *handle, LSM6DSL_ACC_GYRO_DEC_FIFO_DS4_t *value);
+
+/*******************************************************************************
+* Register      : FIFO_CTRL4
+* Address       : 0X09
+* Bit Group Name: HI_DATA_ONLY
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_HI_DATA_ONLY_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_HI_DATA_ONLY_ENABLED        =0x40,
+} LSM6DSL_ACC_GYRO_HI_DATA_ONLY_t;
+
+#define       LSM6DSL_ACC_GYRO_HI_DATA_ONLY_MASK      0x40
+mems_status_t LSM6DSL_ACC_GYRO_W_HI_DATA_ONLY(void *handle, LSM6DSL_ACC_GYRO_HI_DATA_ONLY_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_HI_DATA_ONLY(void *handle, LSM6DSL_ACC_GYRO_HI_DATA_ONLY_t *value);
+
+/*******************************************************************************
+* Register      : FIFO_CTRL4
+* Address       : 0X09
+* Bit Group Name: STOP_ON_FTH
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_STOP_ON_FTH_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_STOP_ON_FTH_ENABLED         =0x80,
+} LSM6DSL_ACC_GYRO_STOP_ON_FTH_t;
+
+#define       LSM6DSL_ACC_GYRO_STOP_ON_FTH_MASK   0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_STOP_ON_FTH(void *handle, LSM6DSL_ACC_GYRO_STOP_ON_FTH_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_STOP_ON_FTH(void *handle, LSM6DSL_ACC_GYRO_STOP_ON_FTH_t *value);
+
+/*******************************************************************************
+* Register      : FIFO_CTRL5
+* Address       : 0X0A
+* Bit Group Name: FIFO_MODE
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_FIFO_MODE_BYPASS        =0x00,
+    LSM6DSL_ACC_GYRO_FIFO_MODE_FIFO          =0x01,
+    LSM6DSL_ACC_GYRO_FIFO_MODE_STREAM        =0x02,
+    LSM6DSL_ACC_GYRO_FIFO_MODE_STF       =0x03,
+    LSM6DSL_ACC_GYRO_FIFO_MODE_BTS       =0x04,
+    LSM6DSL_ACC_GYRO_FIFO_MODE_DYN_STREAM        =0x05,
+    LSM6DSL_ACC_GYRO_FIFO_MODE_DYN_STREAM_2          =0x06,
+    LSM6DSL_ACC_GYRO_FIFO_MODE_BTF       =0x07,
+} LSM6DSL_ACC_GYRO_FIFO_MODE_t;
+
+#define       LSM6DSL_ACC_GYRO_FIFO_MODE_MASK     0x07
+mems_status_t LSM6DSL_ACC_GYRO_W_FIFO_MODE(void *handle, LSM6DSL_ACC_GYRO_FIFO_MODE_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFO_MODE(void *handle, LSM6DSL_ACC_GYRO_FIFO_MODE_t *value);
+
+/*******************************************************************************
+* Register      : FIFO_CTRL5
+* Address       : 0X0A
+* Bit Group Name: ODR_FIFO
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_ODR_FIFO_10Hz       =0x08,
+    LSM6DSL_ACC_GYRO_ODR_FIFO_25Hz       =0x10,
+    LSM6DSL_ACC_GYRO_ODR_FIFO_50Hz       =0x18,
+    LSM6DSL_ACC_GYRO_ODR_FIFO_100Hz          =0x20,
+    LSM6DSL_ACC_GYRO_ODR_FIFO_200Hz          =0x28,
+    LSM6DSL_ACC_GYRO_ODR_FIFO_400Hz          =0x30,
+    LSM6DSL_ACC_GYRO_ODR_FIFO_800Hz          =0x38,
+    LSM6DSL_ACC_GYRO_ODR_FIFO_1600Hz         =0x40,
+    LSM6DSL_ACC_GYRO_ODR_FIFO_3300Hz         =0x48,
+    LSM6DSL_ACC_GYRO_ODR_FIFO_6600Hz         =0x50,
+    LSM6DSL_ACC_GYRO_ODR_FIFO_13300Hz        =0x58,
+} LSM6DSL_ACC_GYRO_ODR_FIFO_t;
+
+#define       LSM6DSL_ACC_GYRO_ODR_FIFO_MASK      0x78
+mems_status_t LSM6DSL_ACC_GYRO_W_ODR_FIFO(void *handle, LSM6DSL_ACC_GYRO_ODR_FIFO_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_ODR_FIFO(void *handle, LSM6DSL_ACC_GYRO_ODR_FIFO_t *value);
+
+/*******************************************************************************
+* Register      : DRDY_PULSE_CFG_G
+* Address       : 0X0B
+* Bit Group Name: DRDY_PULSE
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DRDY_LATCH          =0x00,
+    LSM6DSL_ACC_GYRO_DRDY_PULSE          =0x80,
+} LSM6DSL_ACC_GYRO_DRDY_PULSE_t;
+
+#define       LSM6DSL_ACC_GYRO_DRDY_PULSE_MASK    0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_DRDY_PULSE(void *handle, LSM6DSL_ACC_GYRO_DRDY_PULSE_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DRDY_PULSE(void *handle, LSM6DSL_ACC_GYRO_DRDY_PULSE_t *value);
+
+/*******************************************************************************
+* Register      : INT1_CTRL
+* Address       : 0X0D
+* Bit Group Name: INT1_DRDY_XL
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT1_DRDY_XL_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_INT1_DRDY_XL_ENABLED        =0x01,
+} LSM6DSL_ACC_GYRO_INT1_DRDY_XL_t;
+
+#define       LSM6DSL_ACC_GYRO_INT1_DRDY_XL_MASK      0x01
+mems_status_t LSM6DSL_ACC_GYRO_W_DRDY_XL_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_DRDY_XL_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DRDY_XL_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_DRDY_XL_t *value);
+
+/*******************************************************************************
+* Register      : INT1_CTRL
+* Address       : 0X0D
+* Bit Group Name: INT1_DRDY_G
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT1_DRDY_G_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_INT1_DRDY_G_ENABLED         =0x02,
+} LSM6DSL_ACC_GYRO_INT1_DRDY_G_t;
+
+#define       LSM6DSL_ACC_GYRO_INT1_DRDY_G_MASK   0x02
+mems_status_t LSM6DSL_ACC_GYRO_W_DRDY_G_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_DRDY_G_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DRDY_G_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_DRDY_G_t *value);
+
+/*******************************************************************************
+* Register      : INT1_CTRL
+* Address       : 0X0D
+* Bit Group Name: INT1_BOOT
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT1_BOOT_DISABLED          =0x00,
+    LSM6DSL_ACC_GYRO_INT1_BOOT_ENABLED       =0x04,
+} LSM6DSL_ACC_GYRO_INT1_BOOT_t;
+
+#define       LSM6DSL_ACC_GYRO_INT1_BOOT_MASK     0x04
+mems_status_t LSM6DSL_ACC_GYRO_W_BOOT_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_BOOT_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_BOOT_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_BOOT_t *value);
+
+/*******************************************************************************
+* Register      : INT1_CTRL
+* Address       : 0X0D
+* Bit Group Name: INT1_FTH
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT1_FTH_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_INT1_FTH_ENABLED        =0x08,
+} LSM6DSL_ACC_GYRO_INT1_FTH_t;
+
+#define       LSM6DSL_ACC_GYRO_INT1_FTH_MASK      0x08
+mems_status_t LSM6DSL_ACC_GYRO_W_FIFO_TSHLD_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_FTH_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFO_TSHLD_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_FTH_t *value);
+
+/*******************************************************************************
+* Register      : INT1_CTRL
+* Address       : 0X0D
+* Bit Group Name: INT1_OVR
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT1_OVR_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_INT1_OVR_ENABLED        =0x10,
+} LSM6DSL_ACC_GYRO_INT1_OVR_t;
+
+#define       LSM6DSL_ACC_GYRO_INT1_OVR_MASK      0x10
+mems_status_t LSM6DSL_ACC_GYRO_W_OVERRUN_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_OVR_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_OVERRUN_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_OVR_t *value);
+
+/*******************************************************************************
+* Register      : INT1_CTRL
+* Address       : 0X0D
+* Bit Group Name: INT1_FULL_FLAG
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT1_FULL_FLAG_DISABLED         =0x00,
+    LSM6DSL_ACC_GYRO_INT1_FULL_FLAG_ENABLED          =0x20,
+} LSM6DSL_ACC_GYRO_INT1_FULL_FLAG_t;
+
+#define       LSM6DSL_ACC_GYRO_INT1_FULL_FLAG_MASK    0x20
+mems_status_t LSM6DSL_ACC_GYRO_W_FULL_FLAG_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_FULL_FLAG_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_FULL_FLAG_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_FULL_FLAG_t *value);
+
+/*******************************************************************************
+* Register      : INT1_CTRL
+* Address       : 0X0D
+* Bit Group Name: INT1_SIGN_MOT
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT1_SIGN_MOT_DISABLED          =0x00,
+    LSM6DSL_ACC_GYRO_INT1_SIGN_MOT_ENABLED       =0x40,
+} LSM6DSL_ACC_GYRO_INT1_SIGN_MOT_t;
+
+#define       LSM6DSL_ACC_GYRO_INT1_SIGN_MOT_MASK     0x40
+mems_status_t LSM6DSL_ACC_GYRO_W_SIGN_MOT_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_SIGN_MOT_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SIGN_MOT_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_SIGN_MOT_t *value);
+
+/*******************************************************************************
+* Register      : INT1_CTRL
+* Address       : 0X0D
+* Bit Group Name: INT1_STEP_DETECTOR
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT1_PEDO_DISABLED          =0x00,
+    LSM6DSL_ACC_GYRO_INT1_PEDO_ENABLED       =0x80,
+} LSM6DSL_ACC_GYRO_INT1_PEDO_t;
+
+#define       LSM6DSL_ACC_GYRO_INT1_PEDO_MASK     0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_STEP_DET_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_PEDO_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_STEP_DET_on_INT1(void *handle, LSM6DSL_ACC_GYRO_INT1_PEDO_t *value);
+
+/*******************************************************************************
+* Register      : INT2_CTRL
+* Address       : 0X0E
+* Bit Group Name: INT2_DRDY_XL
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_DRDY_XL_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_INT2_DRDY_XL_ENABLED        =0x01,
+} LSM6DSL_ACC_GYRO_INT2_DRDY_XL_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_DRDY_XL_MASK      0x01
+mems_status_t LSM6DSL_ACC_GYRO_W_DRDY_XL_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_DRDY_XL_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DRDY_XL_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_DRDY_XL_t *value);
+
+/*******************************************************************************
+* Register      : INT2_CTRL
+* Address       : 0X0E
+* Bit Group Name: INT2_DRDY_G
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_DRDY_G_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_INT2_DRDY_G_ENABLED         =0x02,
+} LSM6DSL_ACC_GYRO_INT2_DRDY_G_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_DRDY_G_MASK   0x02
+mems_status_t LSM6DSL_ACC_GYRO_W_DRDY_G_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_DRDY_G_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DRDY_G_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_DRDY_G_t *value);
+
+/*******************************************************************************
+* Register      : INT2_CTRL
+* Address       : 0X0E
+* Bit Group Name: INT2_DRDY_TEMP
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_DRDY_TEMP_DISABLED         =0x00,
+    LSM6DSL_ACC_GYRO_INT2_DRDY_TEMP_ENABLED          =0x04,
+} LSM6DSL_ACC_GYRO_INT2_DRDY_TEMP_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_DRDY_TEMP_MASK    0x04
+mems_status_t LSM6DSL_ACC_GYRO_W_DRDY_TEMP_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_DRDY_TEMP_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DRDY_TEMP_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_DRDY_TEMP_t *value);
+
+
+/*******************************************************************************
+* Register      : INT2_CTRL
+* Address       : 0X0E
+* Bit Group Name: INT2_FTH
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_FTH_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_INT2_FTH_ENABLED        =0x08,
+} LSM6DSL_ACC_GYRO_INT2_FTH_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_FTH_MASK      0x08
+mems_status_t LSM6DSL_ACC_GYRO_W_FIFO_TSHLD_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_FTH_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFO_TSHLD_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_FTH_t *value);
+
+/*******************************************************************************
+* Register      : INT2_CTRL
+* Address       : 0X0E
+* Bit Group Name: INT2_OVR
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_OVR_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_INT2_OVR_ENABLED        =0x10,
+} LSM6DSL_ACC_GYRO_INT2_OVR_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_OVR_MASK      0x10
+mems_status_t LSM6DSL_ACC_GYRO_W_OVERRUN_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_OVR_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_OVERRUN_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_OVR_t *value);
+
+/*******************************************************************************
+* Register      : INT2_CTRL
+* Address       : 0X0E
+* Bit Group Name: INT2_FULL_FLAG
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_FULL_FLAG_DISABLED         =0x00,
+    LSM6DSL_ACC_GYRO_INT2_FULL_FLAG_ENABLED          =0x20,
+} LSM6DSL_ACC_GYRO_INT2_FULL_FLAG_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_FULL_FLAG_MASK    0x20
+mems_status_t LSM6DSL_ACC_GYRO_W_FULL_FLAG_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_FULL_FLAG_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_FULL_FLAG_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_FULL_FLAG_t *value);
+
+/*******************************************************************************
+* Register      : INT2_CTRL
+* Address       : 0X0E
+* Bit Group Name: INT2_STEP_COUNT_OV
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_STEP_COUNT_OV_DISABLED         =0x00,
+    LSM6DSL_ACC_GYRO_INT2_STEP_COUNT_OV_ENABLED          =0x40,
+} LSM6DSL_ACC_GYRO_INT2_STEP_COUNT_OV_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_STEP_COUNT_OV_MASK    0x40
+mems_status_t LSM6DSL_ACC_GYRO_W_STEP_COUNT_OV_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_STEP_COUNT_OV_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_STEP_COUNT_OV_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_STEP_COUNT_OV_t *value);
+
+/*******************************************************************************
+* Register      : INT2_CTRL
+* Address       : 0X0E
+* Bit Group Name: INT2_STEP_DELTA
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_STEP_DELTA_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_INT2_STEP_DELTA_ENABLED         =0x80,
+} LSM6DSL_ACC_GYRO_INT2_STEP_DELTA_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_STEP_DELTA_MASK   0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_STEP_DELTA_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_STEP_DELTA_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_STEP_DELTA_on_INT2(void *handle, LSM6DSL_ACC_GYRO_INT2_STEP_DELTA_t *value);
+
+/*******************************************************************************
+* Register      : CTRL3_C
+* Address       : 0X12
+* Bit Group Name: SW_RESET
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_SW_RESET_NORMAL_MODE        =0x00,
+    LSM6DSL_ACC_GYRO_SW_RESET_RESET_DEVICE       =0x01,
+} LSM6DSL_ACC_GYRO_SW_RESET_t;
+
+#define       LSM6DSL_ACC_GYRO_SW_RESET_MASK      0x01
+mems_status_t LSM6DSL_ACC_GYRO_W_SW_RESET(void *handle, LSM6DSL_ACC_GYRO_SW_RESET_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SW_RESET(void *handle, LSM6DSL_ACC_GYRO_SW_RESET_t *value);
+
+
+/*******************************************************************************
+* Register      : CTRL3_C
+* Address       : 0X12
+* Bit Group Name: IF_INC
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_IF_INC_DISABLED         =0x00,
+    LSM6DSL_ACC_GYRO_IF_INC_ENABLED          =0x04,
+} LSM6DSL_ACC_GYRO_IF_INC_t;
+
+#define       LSM6DSL_ACC_GYRO_IF_INC_MASK    0x04
+mems_status_t LSM6DSL_ACC_GYRO_W_IF_Addr_Incr(void *handle, LSM6DSL_ACC_GYRO_IF_INC_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_IF_Addr_Incr(void *handle, LSM6DSL_ACC_GYRO_IF_INC_t *value);
+
+/*******************************************************************************
+* Register      : CTRL3_C
+* Address       : 0X12
+* Bit Group Name: SIM
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_SIM_4_WIRE          =0x00,
+    LSM6DSL_ACC_GYRO_SIM_3_WIRE          =0x08,
+} LSM6DSL_ACC_GYRO_SIM_t;
+
+#define       LSM6DSL_ACC_GYRO_SIM_MASK   0x08
+mems_status_t LSM6DSL_ACC_GYRO_W_SPI_Mode(void *handle, LSM6DSL_ACC_GYRO_SIM_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SPI_Mode(void *handle, LSM6DSL_ACC_GYRO_SIM_t *value);
+
+/*******************************************************************************
+* Register      : CTRL3_C
+* Address       : 0X12
+* Bit Group Name: PP_OD
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_PP_OD_PUSH_PULL         =0x00,
+    LSM6DSL_ACC_GYRO_PP_OD_OPEN_DRAIN        =0x10,
+} LSM6DSL_ACC_GYRO_PP_OD_t;
+
+#define       LSM6DSL_ACC_GYRO_PP_OD_MASK     0x10
+mems_status_t LSM6DSL_ACC_GYRO_W_PadSel(void *handle, LSM6DSL_ACC_GYRO_PP_OD_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_PadSel(void *handle, LSM6DSL_ACC_GYRO_PP_OD_t *value);
+
+/*******************************************************************************
+* Register      : CTRL3_C
+* Address       : 0X12
+* Bit Group Name: H_LACTIVE
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT_ACT_LEVEL_ACTIVE_HI         =0x00,
+    LSM6DSL_ACC_GYRO_INT_ACT_LEVEL_ACTIVE_LO         =0x20,
+} LSM6DSL_ACC_GYRO_INT_ACT_LEVEL_t;
+
+#define       LSM6DSL_ACC_GYRO_INT_ACT_LEVEL_MASK     0x20
+mems_status_t LSM6DSL_ACC_GYRO_W_INT_ACT_LEVEL(void *handle, LSM6DSL_ACC_GYRO_INT_ACT_LEVEL_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_INT_ACT_LEVEL(void *handle, LSM6DSL_ACC_GYRO_INT_ACT_LEVEL_t *value);
+
+
+/*******************************************************************************
+* Register      : CTRL3_C
+* Address       : 0X12
+* Bit Group Name: BOOT
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_BOOT_NORMAL_MODE        =0x00,
+    LSM6DSL_ACC_GYRO_BOOT_REBOOT_MODE        =0x80,
+} LSM6DSL_ACC_GYRO_BOOT_t;
+
+#define       LSM6DSL_ACC_GYRO_BOOT_MASK      0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_BOOT(void *handle, LSM6DSL_ACC_GYRO_BOOT_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_BOOT(void *handle, LSM6DSL_ACC_GYRO_BOOT_t *value);
+
+/*******************************************************************************
+* Register      : CTRL4_C
+* Address       : 0X13
+* Bit Group Name: LPF1_SEL_G
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_MODE3_LPF1_G_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_MODE3_LPF1_G_ENABLED        =0x02,
+} LSM6DSL_ACC_GYRO_LPF1_SEL_G_t;
+
+#define       LSM6DSL_ACC_GYRO_LPF1_SEL_G_MASK    0x02
+mems_status_t LSM6DSL_ACC_GYRO_W_LPF1_SEL_G(void *handle, LSM6DSL_ACC_GYRO_LPF1_SEL_G_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_LPF1_SEL_G(void *handle, LSM6DSL_ACC_GYRO_LPF1_SEL_G_t *value);
+
+/*******************************************************************************
+* Register      : CTRL4_C
+* Address       : 0X13
+* Bit Group Name: I2C_DISABLE
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_I2C_DISABLE_I2C_AND_SPI         =0x00,
+    LSM6DSL_ACC_GYRO_I2C_DISABLE_SPI_ONLY        =0x04,
+} LSM6DSL_ACC_GYRO_I2C_DISABLE_t;
+
+#define       LSM6DSL_ACC_GYRO_I2C_DISABLE_MASK   0x04
+mems_status_t LSM6DSL_ACC_GYRO_W_I2C_DISABLE(void *handle, LSM6DSL_ACC_GYRO_I2C_DISABLE_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_I2C_DISABLE(void *handle, LSM6DSL_ACC_GYRO_I2C_DISABLE_t *value);
+
+/*******************************************************************************
+* Register      : CTRL4_C
+* Address       : 0X13
+* Bit Group Name: DRDY_MSK
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DRDY_MSK_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_DRDY_MSK_ENABLED        =0x08,
+} LSM6DSL_ACC_GYRO_DRDY_MSK_t;
+
+#define       LSM6DSL_ACC_GYRO_DRDY_MSK_MASK      0x08
+mems_status_t LSM6DSL_ACC_GYRO_W_DRDY_MSK(void *handle, LSM6DSL_ACC_GYRO_DRDY_MSK_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DRDY_MSK(void *handle, LSM6DSL_ACC_GYRO_DRDY_MSK_t *value);
+
+/*******************************************************************************
+* Register      : CTRL4_C
+* Address       : 0X13
+* Bit Group Name: INT2_ON_INT1
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_ON_INT1_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_INT2_ON_INT1_ENABLED        =0x20,
+} LSM6DSL_ACC_GYRO_INT2_ON_INT1_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_ON_INT1_MASK      0x20
+mems_status_t LSM6DSL_ACC_GYRO_W_INT2_ON_INT1(void *handle, LSM6DSL_ACC_GYRO_INT2_ON_INT1_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_INT2_ON_INT1(void *handle, LSM6DSL_ACC_GYRO_INT2_ON_INT1_t *value);
+
+/*******************************************************************************
+* Register      : CTRL4_C
+* Address       : 0X13
+* Bit Group Name: SLEEP_G
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_SLEEP_G_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_SLEEP_G_ENABLED         =0x40,
+} LSM6DSL_ACC_GYRO_SLEEP_G_t;
+
+#define       LSM6DSL_ACC_GYRO_SLEEP_G_MASK   0x40
+mems_status_t LSM6DSL_ACC_GYRO_W_SleepMode_G(void *handle, LSM6DSL_ACC_GYRO_SLEEP_G_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SleepMode_G(void *handle, LSM6DSL_ACC_GYRO_SLEEP_G_t *value);
+
+/*******************************************************************************
+* Register      : CTRL5_C
+* Address       : 0X14
+* Bit Group Name: ST_XL
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_ST_XL_NORMAL_MODE       =0x00,
+    LSM6DSL_ACC_GYRO_ST_XL_POS_SIGN_TEST         =0x01,
+    LSM6DSL_ACC_GYRO_ST_XL_NEG_SIGN_TEST         =0x02,
+    LSM6DSL_ACC_GYRO_ST_XL_NA        =0x03,
+} LSM6DSL_ACC_GYRO_ST_XL_t;
+
+#define       LSM6DSL_ACC_GYRO_ST_XL_MASK     0x03
+mems_status_t LSM6DSL_ACC_GYRO_W_SelfTest_XL(void *handle, LSM6DSL_ACC_GYRO_ST_XL_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SelfTest_XL(void *handle, LSM6DSL_ACC_GYRO_ST_XL_t *value);
+
+/*******************************************************************************
+* Register      : CTRL5_C
+* Address       : 0X14
+* Bit Group Name: ST_G
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_ST_G_NORMAL_MODE        =0x00,
+    LSM6DSL_ACC_GYRO_ST_G_POS_SIGN_TEST          =0x04,
+    LSM6DSL_ACC_GYRO_ST_G_NA         =0x08,
+    LSM6DSL_ACC_GYRO_ST_G_NEG_SIGN_TEST          =0x0C,
+} LSM6DSL_ACC_GYRO_ST_G_t;
+
+#define       LSM6DSL_ACC_GYRO_ST_G_MASK      0x0C
+mems_status_t LSM6DSL_ACC_GYRO_W_SelfTest_G(void *handle, LSM6DSL_ACC_GYRO_ST_G_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SelfTest_G(void *handle, LSM6DSL_ACC_GYRO_ST_G_t *value);
+
+/*******************************************************************************
+* Register      : CTRL5_C
+* Address       : 0X14
+* Bit Group Name: DEN_LH
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DEN_LOW         =0x00,
+    LSM6DSL_ACC_GYRO_DEN_HIGH        =0x10,
+} LSM6DSL_ACC_GYRO_DEN_LH_t;
+
+#define       LSM6DSL_ACC_GYRO_DEN_LH_MASK    0x10
+mems_status_t LSM6DSL_ACC_GYRO_W_DEN_Polarity(void *handle, LSM6DSL_ACC_GYRO_DEN_LH_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DEN_Polarity(void *handle, LSM6DSL_ACC_GYRO_DEN_LH_t *value);
+
+/*******************************************************************************
+* Register      : CTRL5_C
+* Address       : 0X14
+* Bit Group Name: ST_ROUNDING
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_NO_ROUNDING         =0x00,
+    LSM6DSL_ACC_GYRO_ACC_ONLY        =0x20,
+    LSM6DSL_ACC_GYRO_GYRO_ONLY       =0x40,
+    LSM6DSL_ACC_GYRO_ACC_GYRO        =0x60,
+    LSM6DSL_ACC_GYRO_SH1_SH6         =0x80,
+    LSM6DSL_ACC_GYRO_ACC_SH1_SH6         =0xA0,
+    LSM6DSL_ACC_GYRO_ACC_GYRO_SH1_SH6_SH7_SH12       =0xC0,
+    LSM6DSL_ACC_GYRO_ACC_GYRO_SH1_SH6    =0xE0,
+} LSM6DSL_ACC_GYRO_ROUNDING_t;
+
+#define       LSM6DSL_ACC_GYRO_LSM6DSL_ACC_GYRO_ROUNDING_t_MASK   0xE0
+mems_status_t LSM6DSL_ACC_GYRO_W_CircularBurstMode(void *handle, LSM6DSL_ACC_GYRO_ROUNDING_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_CircularBurstMode(void *handle, LSM6DSL_ACC_GYRO_ROUNDING_t *value);
+
+/*******************************************************************************
+* Register      : CTRL6_G
+* Address       : 0X15
+* Bit Group Name: FTYPE
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_LP_G_NORMAL         =0x00,
+    LSM6DSL_ACC_GYRO_LP_G_NARROW         =0x01,
+    LSM6DSL_ACC_GYRO_LP_G_VERY_NARROW        =0x02,
+    LSM6DSL_ACC_GYRO_LP_G_WIDE       =0x03,
+} LSM6DSL_ACC_GYRO_FTYPE_t;
+
+#define       LSM6DSL_ACC_GYRO_FTYPE_MASK     0x03
+mems_status_t LSM6DSL_ACC_GYRO_W_LP_BW_G(void *handle, LSM6DSL_ACC_GYRO_FTYPE_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_LP_BW_G(void *handle, LSM6DSL_ACC_GYRO_FTYPE_t *value);
+
+/*******************************************************************************
+* Register      : CTRL6_G
+* Address       : 0X15
+* Bit Group Name: USR_OFF_W
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_2Emin10         =0x00,
+    LSM6DSL_ACC_GYRO_2Emin6          =0x08,
+} LSM6DSL_ACC_GYRO_USR_OFF_W_t;
+
+#define       LSM6DSL_ACC_GYRO_USR_OFF_W_MASK     0x08
+mems_status_t LSM6DSL_ACC_GYRO_W_UserOffsetWeight(void *handle, LSM6DSL_ACC_GYRO_USR_OFF_W_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_UserOffsetWeight(void *handle, LSM6DSL_ACC_GYRO_USR_OFF_W_t *value);
+
+
+/*******************************************************************************
+* Register      : CTRL6_G
+* Address       : 0X15
+* Bit Group Name: LP_XL
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_LP_XL_DISABLED          =0x00,
+    LSM6DSL_ACC_GYRO_LP_XL_ENABLED       =0x10,
+} LSM6DSL_ACC_GYRO_LP_XL_t;
+
+#define       LSM6DSL_ACC_GYRO_LP_XL_MASK     0x10
+mems_status_t LSM6DSL_ACC_GYRO_W_LowPower_XL(void *handle, LSM6DSL_ACC_GYRO_LP_XL_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_LowPower_XL(void *handle, LSM6DSL_ACC_GYRO_LP_XL_t *value);
+
+/*******************************************************************************
+* Register      : CTRL6_G
+* Address       : 0X15
+* Bit Group Name: DEN_LVL2_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DEN_LVL2_EN_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_DEN_LVL2_EN_ENABLED         =0x20,
+} LSM6DSL_ACC_GYRO_DEN_LVL2_EN_t;
+
+#define       LSM6DSL_ACC_GYRO_DEN_LVL2_EN_MASK   0x20
+mems_status_t LSM6DSL_ACC_GYRO_W_DEN_LVL2_EN(void *handle, LSM6DSL_ACC_GYRO_DEN_LVL2_EN_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DEN_LVL2_EN(void *handle, LSM6DSL_ACC_GYRO_DEN_LVL2_EN_t *value);
+
+/*******************************************************************************
+* Register      : CTRL6_G
+* Address       : 0X15
+* Bit Group Name: DEN_LVL_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DEN_LVL_EN_DISABLED         =0x00,
+    LSM6DSL_ACC_GYRO_DEN_LVL_EN_ENABLED          =0x40,
+} LSM6DSL_ACC_GYRO_DEN_LVL_EN_t;
+
+#define       LSM6DSL_ACC_GYRO_DEN_LVL_EN_MASK    0x40
+mems_status_t LSM6DSL_ACC_GYRO_W_DEN_LVL_EN(void *handle, LSM6DSL_ACC_GYRO_DEN_LVL_EN_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DEN_LVL_EN(void *handle, LSM6DSL_ACC_GYRO_DEN_LVL_EN_t *value);
+
+/*******************************************************************************
+* Register      : CTRL6_G
+* Address       : 0X15
+* Bit Group Name: TRIG_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DEN_EDGE_EN_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_DEN_EDGE_EN_ENABLED         =0x80,
+} LSM6DSL_ACC_GYRO_DEN_EDGE_EN_t;
+
+#define       LSM6DSL_ACC_GYRO_DEN_EDGE_EN_MASK   0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_ExternalTrigger(void *handle, LSM6DSL_ACC_GYRO_DEN_EDGE_EN_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_ExternalTrigger(void *handle, LSM6DSL_ACC_GYRO_DEN_EDGE_EN_t *value);
+
+/*******************************************************************************
+* Register      : CTRL7_G
+* Address       : 0X16
+* Bit Group Name: ROUNDING_STATUS
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_RND_DISABLE         =0x00,
+    LSM6DSL_ACC_GYRO_RND_ENABLE          =0x04,
+} LSM6DSL_ACC_GYRO_RND_STATUS_t;
+
+#define       LSM6DSL_ACC_GYRO_RND_STATUS_MASK    0x04
+mems_status_t LSM6DSL_ACC_GYRO_W_RoundingOnStatusRegisters(void *handle, LSM6DSL_ACC_GYRO_RND_STATUS_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_RoundingOnStatusRegisters(void *handle, LSM6DSL_ACC_GYRO_RND_STATUS_t *value);
+
+
+/*******************************************************************************
+* Register      : CTRL7_G
+* Address       : 0X16
+* Bit Group Name: HPM_G
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_HPM_G_0Hz016        =0x00,
+    LSM6DSL_ACC_GYRO_HPM_G_0Hz065        =0x10,
+    LSM6DSL_ACC_GYRO_HPM_G_2Hz260        =0x20,
+    LSM6DSL_ACC_GYRO_HPM_G_1Hz04         =0x30,
+} LSM6DSL_ACC_GYRO_HPM_G_t;
+
+#define       LSM6DSL_ACC_GYRO_HPM_G_MASK     0x30
+mems_status_t LSM6DSL_ACC_GYRO_W_HPM_G(void *handle, LSM6DSL_ACC_GYRO_HPM_G_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_HPM_G(void *handle, LSM6DSL_ACC_GYRO_HPM_G_t *value);
+
+/*******************************************************************************
+* Register      : CTRL7_G
+* Address       : 0X16
+* Bit Group Name: HP_EN_G
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_HP_EN_DISABLED          =0x00,
+    LSM6DSL_ACC_GYRO_HP_EN_ENABLED       =0x40,
+} LSM6DSL_ACC_GYRO_HP_EN_t;
+
+#define       LSM6DSL_ACC_GYRO_HP_EN_MASK     0x40
+mems_status_t LSM6DSL_ACC_GYRO_W_HPFilter_En(void *handle, LSM6DSL_ACC_GYRO_HP_EN_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_HPFilter_En(void *handle, LSM6DSL_ACC_GYRO_HP_EN_t *value);
+
+/*******************************************************************************
+* Register      : CTRL7_G
+* Address       : 0X16
+* Bit Group Name: LP_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_LP_EN_DISABLED          =0x00,
+    LSM6DSL_ACC_GYRO_LP_EN_ENABLED       =0x80,
+} LSM6DSL_ACC_GYRO_LP_EN_t;
+
+#define       LSM6DSL_ACC_GYRO_LP_EN_MASK     0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_LP_Mode(void *handle, LSM6DSL_ACC_GYRO_LP_EN_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_LP_Mode(void *handle, LSM6DSL_ACC_GYRO_LP_EN_t *value);
+
+/*******************************************************************************
+* Register      : CTRL7_G
+* Address       : 0X16
+* Bit Group Name: ROUNDING_STATUS
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_ROUNDING_STATUS_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_ROUNDING_STATUS_ENABLED         =0x04,
+} LSM6DSL_ACC_GYRO_ROUNDING_STATUS_t;
+
+#define       LSM6DSL_ACC_GYRO_ROUNDING_STATUS_MASK   0x04
+mems_status_t LSM6DSL_ACC_GYRO_W_ROUNDING_STATUS(void *handle, LSM6DSL_ACC_GYRO_ROUNDING_STATUS_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_ROUNDING_STATUS(void *handle, LSM6DSL_ACC_GYRO_ROUNDING_STATUS_t *value);
+
+/*******************************************************************************
+* Register      : CTRL7_G
+* Address       : 0X16
+* Bit Group Name: HP_G_RST
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_HP_G_RST_OFF        =0x00,
+    LSM6DSL_ACC_GYRO_HP_G_RST_ON         =0x08,
+} LSM6DSL_ACC_GYRO_HP_G_RST_t;
+
+#define       LSM6DSL_ACC_GYRO_HP_G_RST_MASK      0x08
+mems_status_t LSM6DSL_ACC_GYRO_W_HP_G_RST(void *handle, LSM6DSL_ACC_GYRO_HP_G_RST_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_HP_G_RST(void *handle, LSM6DSL_ACC_GYRO_HP_G_RST_t *value);
+
+/*******************************************************************************
+* Register      : CTRL8_XL
+* Address       : 0X17
+* Bit Group Name: LOW_PASS_ON_6D
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_LOW_PASS_ON_6D_OFF          =0x00,
+    LSM6DSL_ACC_GYRO_LOW_PASS_ON_6D_ON       =0x01,
+} LSM6DSL_ACC_GYRO_LOW_PASS_ON_6D_t;
+
+#define       LSM6DSL_ACC_GYRO_LOW_PASS_ON_6D_MASK    0x01
+mems_status_t LSM6DSL_ACC_GYRO_W_LOW_PASS_ON_6D(void *handle, LSM6DSL_ACC_GYRO_LOW_PASS_ON_6D_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_LOW_PASS_ON_6D(void *handle, LSM6DSL_ACC_GYRO_LOW_PASS_ON_6D_t *value);
+
+/*******************************************************************************
+* Register      : CTRL8_XL
+* Address       : 0X17
+* Bit Group Name: HP_SLOPE_XL_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_HP_SLOPE_XL_EN          =0x00,
+    LSM6DSL_ACC_GYRO_HP_SLOPE_XL_DIS         =0x04,
+} LSM6DSL_ACC_GYRO_HP_SLOPE_XL_t;
+
+#define       LSM6DSL_ACC_GYRO_HP_SLOPE_XL_MASK   0x04
+mems_status_t LSM6DSL_ACC_GYRO_W_HP_SLOPE_XL(void *handle, LSM6DSL_ACC_GYRO_HP_SLOPE_XL_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_HP_SLOPE_XL(void *handle, LSM6DSL_ACC_GYRO_HP_SLOPE_XL_t *value);
+
+/*******************************************************************************
+* Register      : CTRL8_XL
+* Address       : 0X17
+* Bit Group Name: INPUT_COMPOSITE
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_IN_ODR_DIV_2        =0x00,
+    LSM6DSL_ACC_GYRO_IN_ODR_DIV_4        =0x80,
+} LSM6DSL_ACC_GYRO_IN_COMP_t;
+
+#define       LSM6DSL_ACC_GYRO_IN_COMP_MASK   0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_InComposit(void *handle, LSM6DSL_ACC_GYRO_IN_COMP_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_InComposit(void *handle, LSM6DSL_ACC_GYRO_IN_COMP_t *value);
+
+/*******************************************************************************
+* Register      : CTRL8_XL
+* Address       : 0X17
+* Bit Group Name: HP_REF_MODE
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_HP_REF_DISABLE          =0x00,
+    LSM6DSL_ACC_GYRO_HP_REF_ENABLE       =0x10,
+} LSM6DSL_ACC_GYRO_HP_REF_MODE_t;
+
+#define       LSM6DSL_ACC_GYRO_HP_REF_MODE_MASK   0x10
+mems_status_t LSM6DSL_ACC_GYRO_W_HPfilterReference(void *handle, LSM6DSL_ACC_GYRO_HP_REF_MODE_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_HPfilterReference(void *handle, LSM6DSL_ACC_GYRO_HP_REF_MODE_t *value);
+
+/*******************************************************************************
+* Register      : CTRL8_XL
+* Address       : 0X17
+* Bit Group Name: HPCF_XL
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_HPCF_XL_DIV4        =0x00,
+    LSM6DSL_ACC_GYRO_HPCF_XL_DIV100          =0x20,
+    LSM6DSL_ACC_GYRO_HPCF_XL_DIV9        =0x40,
+    LSM6DSL_ACC_GYRO_HPCF_XL_DIV400          =0x60,
+} LSM6DSL_ACC_GYRO_HPCF_XL_t;
+
+#define       LSM6DSL_ACC_GYRO_HPCF_XL_MASK   0x60
+mems_status_t LSM6DSL_ACC_GYRO_W_HPCF_XL(void *handle, LSM6DSL_ACC_GYRO_HPCF_XL_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_HPCF_XL(void *handle, LSM6DSL_ACC_GYRO_HPCF_XL_t *value);
+
+/*******************************************************************************
+* Register      : CTRL8_XL
+* Address       : 0X17
+* Bit Group Name: LPF2_XL_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_LPF2_XL_DISABLE         =0x00,
+    LSM6DSL_ACC_GYRO_LPF2_XL_ENABLE          =0x80,
+} LSM6DSL_ACC_GYRO_LPF2_XL_t;
+
+#define       LSM6DSL_ACC_GYRO_LPF2_XL_MASK   0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_LowPassFiltSel_XL(void *handle, LSM6DSL_ACC_GYRO_LPF2_XL_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_LowPassFiltSel_XL(void *handle, LSM6DSL_ACC_GYRO_LPF2_XL_t *value);
+
+
+/*******************************************************************************
+* Register      : CTRL9_XL
+* Address       : 0X18
+* Bit Group Name: SOFT_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_SOFT_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_SOFT_ENABLE         =0x04,
+} LSM6DSL_ACC_GYRO_SOFT_t;
+
+#define       LSM6DSL_ACC_GYRO_SOFT_MASK      0x04
+mems_status_t LSM6DSL_ACC_GYRO_W_SOFT(void *handle, LSM6DSL_ACC_GYRO_SOFT_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SOFT(void *handle, LSM6DSL_ACC_GYRO_SOFT_t *value);
+
+/*******************************************************************************
+* Register      : CTRL10_C
+* Address       : 0X19
+* Bit Group Name: SIGN_MOTION_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_SIGN_MOTION_EN_DISABLED         =0x00,
+    LSM6DSL_ACC_GYRO_SIGN_MOTION_EN_ENABLED          =0x01,
+} LSM6DSL_ACC_GYRO_SIGN_MOTION_EN_t;
+
+#define       LSM6DSL_ACC_GYRO_SIGN_MOTION_EN_MASK    0x01
+mems_status_t LSM6DSL_ACC_GYRO_W_SignifcantMotion(void *handle, LSM6DSL_ACC_GYRO_SIGN_MOTION_EN_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SignifcantMotion(void *handle, LSM6DSL_ACC_GYRO_SIGN_MOTION_EN_t *value);
+
+/*******************************************************************************
+* Register      : CTRL10_C
+* Address       : 0X19
+* Bit Group Name: PEDO_RST_STEP
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_PEDO_RST_STEP_DISABLED          =0x00,
+    LSM6DSL_ACC_GYRO_PEDO_RST_STEP_ENABLED       =0x02,
+} LSM6DSL_ACC_GYRO_PEDO_RST_STEP_t;
+
+#define       LSM6DSL_ACC_GYRO_PEDO_RST_STEP_MASK     0x02
+mems_status_t LSM6DSL_ACC_GYRO_W_PedoStepReset(void *handle, LSM6DSL_ACC_GYRO_PEDO_RST_STEP_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_PedoStepReset(void *handle, LSM6DSL_ACC_GYRO_PEDO_RST_STEP_t *value);
+
+/*******************************************************************************
+* Register      : CTRL10_C
+* Address       : 0X19
+* Bit Group Name: FUNC_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_FUNC_EN_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_FUNC_EN_ENABLED         =0x04,
+} LSM6DSL_ACC_GYRO_FUNC_EN_t;
+
+#define       LSM6DSL_ACC_GYRO_FUNC_EN_MASK   0x04
+mems_status_t LSM6DSL_ACC_GYRO_W_FUNC_EN(void *handle, LSM6DSL_ACC_GYRO_FUNC_EN_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_FUNC_EN(void *handle, LSM6DSL_ACC_GYRO_FUNC_EN_t *value);
+
+/*******************************************************************************
+* Register      : CTRL10_C
+* Address       : 0X19
+* Bit Group Name: TILT_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_TILT_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_TILT_ENABLED        =0x08,
+} LSM6DSL_ACC_GYRO_TILT_G_t;
+
+#define       LSM6DSL_ACC_GYRO_TILT_MASK      0x08
+mems_status_t LSM6DSL_ACC_GYRO_W_TILT(void *handle, LSM6DSL_ACC_GYRO_TILT_G_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_TILT(void *handle, LSM6DSL_ACC_GYRO_TILT_G_t *value);
+
+/*******************************************************************************
+* Register      : CTRL10_C
+* Address       : 0X19
+* Bit Group Name: PEDO_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_PEDO_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_PEDO_ENABLED        =0x10,
+} LSM6DSL_ACC_GYRO_PEDO_t;
+
+#define       LSM6DSL_ACC_GYRO_PEDO_MASK      0x10
+mems_status_t LSM6DSL_ACC_GYRO_W_PEDO(void *handle, LSM6DSL_ACC_GYRO_PEDO_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_PEDO(void *handle, LSM6DSL_ACC_GYRO_PEDO_t *value);
+
+/*******************************************************************************
+* Register      : CTRL10_C
+* Address       : 0X19
+* Bit Group Name: TIMER_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_TIMER_DISABLED          =0x00,
+    LSM6DSL_ACC_GYRO_TIMER_ENABLED       =0x20,
+} LSM6DSL_ACC_GYRO_TIMER_t;
+
+#define       LSM6DSL_ACC_GYRO_TIMER_MASK     0x20
+mems_status_t LSM6DSL_ACC_GYRO_W_TIMER(void *handle, LSM6DSL_ACC_GYRO_TIMER_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_TIMER(void *handle, LSM6DSL_ACC_GYRO_TIMER_t *value);
+
+
+/*******************************************************************************
+* Register      : MASTER_CONFIG
+* Address       : 0X1A
+* Bit Group Name: MASTER_ON
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_MASTER_ON_DISABLED          =0x00,
+    LSM6DSL_ACC_GYRO_MASTER_ON_ENABLED       =0x01,
+} LSM6DSL_ACC_GYRO_MASTER_ON_t;
+
+#define       LSM6DSL_ACC_GYRO_MASTER_ON_MASK     0x01
+mems_status_t LSM6DSL_ACC_GYRO_W_I2C_MASTER_Enable(void *handle, LSM6DSL_ACC_GYRO_MASTER_ON_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_I2C_MASTER_Enable(void *handle, LSM6DSL_ACC_GYRO_MASTER_ON_t *value);
+
+/*******************************************************************************
+* Register      : MASTER_CONFIG
+* Address       : 0X1A
+* Bit Group Name: IRON_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_IRON_EN_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_IRON_EN_ENABLED         =0x02,
+} LSM6DSL_ACC_GYRO_IRON_EN_t;
+
+#define       LSM6DSL_ACC_GYRO_IRON_EN_MASK   0x02
+mems_status_t LSM6DSL_ACC_GYRO_W_IronCorrection_EN(void *handle, LSM6DSL_ACC_GYRO_IRON_EN_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_IronCorrection_EN(void *handle, LSM6DSL_ACC_GYRO_IRON_EN_t *value);
+
+/*******************************************************************************
+* Register      : MASTER_CONFIG
+* Address       : 0X1A
+* Bit Group Name: PASS_THRU_MODE
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_PASS_THRU_MODE_DISABLED         =0x00,
+    LSM6DSL_ACC_GYRO_PASS_THRU_MODE_ENABLED          =0x04,
+} LSM6DSL_ACC_GYRO_PASS_THRU_MODE_t;
+
+#define       LSM6DSL_ACC_GYRO_PASS_THRU_MODE_MASK    0x04
+mems_status_t LSM6DSL_ACC_GYRO_W_PASS_THRU_MODE(void *handle, LSM6DSL_ACC_GYRO_PASS_THRU_MODE_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_PASS_THRU_MODE(void *handle, LSM6DSL_ACC_GYRO_PASS_THRU_MODE_t *value);
+
+/*******************************************************************************
+* Register      : MASTER_CONFIG
+* Address       : 0X1A
+* Bit Group Name: PULL_UP_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_PULL_UP_EN_DISABLED         =0x00,
+    LSM6DSL_ACC_GYRO_PULL_UP_EN_ENABLED          =0x08,
+} LSM6DSL_ACC_GYRO_PULL_UP_EN_t;
+
+#define       LSM6DSL_ACC_GYRO_PULL_UP_EN_MASK    0x08
+mems_status_t LSM6DSL_ACC_GYRO_W_PULL_UP_EN(void *handle, LSM6DSL_ACC_GYRO_PULL_UP_EN_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_PULL_UP_EN(void *handle, LSM6DSL_ACC_GYRO_PULL_UP_EN_t *value);
+
+/*******************************************************************************
+* Register      : MASTER_CONFIG
+* Address       : 0X1A
+* Bit Group Name: START_CONFIG
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_START_CONFIG_XL_G_DRDY          =0x00,
+    LSM6DSL_ACC_GYRO_START_CONFIG_EXT_INT2       =0x10,
+} LSM6DSL_ACC_GYRO_START_CONFIG_t;
+
+#define       LSM6DSL_ACC_GYRO_START_CONFIG_MASK      0x10
+mems_status_t LSM6DSL_ACC_GYRO_W_SensorHUB_Trigger_Sel(void *handle, LSM6DSL_ACC_GYRO_START_CONFIG_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SensorHUB_Trigger_Sel(void *handle, LSM6DSL_ACC_GYRO_START_CONFIG_t *value);
+
+/*******************************************************************************
+* Register      : MASTER_CONFIG
+* Address       : 0X1A
+* Bit Group Name: DATA_VAL_SEL_FIFO
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DATA_VAL_SEL_FIFO_XL_G_DRDY         =0x00,
+    LSM6DSL_ACC_GYRO_DATA_VAL_SEL_FIFO_SHUB_DRDY         =0x40,
+} LSM6DSL_ACC_GYRO_DATA_VAL_SEL_FIFO_t;
+
+#define       LSM6DSL_ACC_GYRO_DATA_VAL_SEL_FIFO_MASK     0x40
+mems_status_t LSM6DSL_ACC_GYRO_W_DATA_VAL_SEL_FIFO(void *handle, LSM6DSL_ACC_GYRO_DATA_VAL_SEL_FIFO_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DATA_VAL_SEL_FIFO(void *handle, LSM6DSL_ACC_GYRO_DATA_VAL_SEL_FIFO_t *value);
+
+/*******************************************************************************
+* Register      : MASTER_CONFIG
+* Address       : 0X1A
+* Bit Group Name: DRDY_ON_INT1
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DRDY_ON_INT1_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_DRDY_ON_INT1_ENABLED        =0x80,
+} LSM6DSL_ACC_GYRO_DRDY_ON_INT1_t;
+
+#define       LSM6DSL_ACC_GYRO_DRDY_ON_INT1_MASK      0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_DRDY_ON_INT1(void *handle, LSM6DSL_ACC_GYRO_DRDY_ON_INT1_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DRDY_ON_INT1(void *handle, LSM6DSL_ACC_GYRO_DRDY_ON_INT1_t *value);
+
+/*******************************************************************************
+* Register      : WAKE_UP_SRC
+* Address       : 0X1B
+* Bit Group Name: Z_WU
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_Z_WU_NOT_DETECTED       =0x00,
+    LSM6DSL_ACC_GYRO_Z_WU_DETECTED       =0x01,
+} LSM6DSL_ACC_GYRO_Z_WU_t;
+
+#define       LSM6DSL_ACC_GYRO_Z_WU_MASK      0x01
+mems_status_t LSM6DSL_ACC_GYRO_R_Z_WU(void *handle, LSM6DSL_ACC_GYRO_Z_WU_t *value);
+
+/*******************************************************************************
+* Register      : WAKE_UP_SRC
+* Address       : 0X1B
+* Bit Group Name: Y_WU
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_Y_WU_NOT_DETECTED       =0x00,
+    LSM6DSL_ACC_GYRO_Y_WU_DETECTED       =0x02,
+} LSM6DSL_ACC_GYRO_Y_WU_t;
+
+#define       LSM6DSL_ACC_GYRO_Y_WU_MASK      0x02
+mems_status_t LSM6DSL_ACC_GYRO_R_Y_WU(void *handle, LSM6DSL_ACC_GYRO_Y_WU_t *value);
+
+/*******************************************************************************
+* Register      : WAKE_UP_SRC
+* Address       : 0X1B
+* Bit Group Name: X_WU
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_X_WU_NOT_DETECTED       =0x00,
+    LSM6DSL_ACC_GYRO_X_WU_DETECTED       =0x04,
+} LSM6DSL_ACC_GYRO_X_WU_t;
+
+#define       LSM6DSL_ACC_GYRO_X_WU_MASK      0x04
+mems_status_t LSM6DSL_ACC_GYRO_R_X_WU(void *handle, LSM6DSL_ACC_GYRO_X_WU_t *value);
+
+/*******************************************************************************
+* Register      : WAKE_UP_SRC
+* Address       : 0X1B
+* Bit Group Name: WU_EV_STATUS
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_WU_EV_STATUS_NOT_DETECTED       =0x00,
+    LSM6DSL_ACC_GYRO_WU_EV_STATUS_DETECTED       =0x08,
+} LSM6DSL_ACC_GYRO_WU_EV_STATUS_t;
+
+#define       LSM6DSL_ACC_GYRO_WU_EV_STATUS_MASK      0x08
+mems_status_t LSM6DSL_ACC_GYRO_R_WU_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_WU_EV_STATUS_t *value);
+
+/*******************************************************************************
+* Register      : WAKE_UP_SRC
+* Address       : 0X1B
+* Bit Group Name: SLEEP_EV_STATUS
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_SLEEP_EV_STATUS_NOT_DETECTED        =0x00,
+    LSM6DSL_ACC_GYRO_SLEEP_EV_STATUS_DETECTED        =0x10,
+} LSM6DSL_ACC_GYRO_SLEEP_EV_STATUS_t;
+
+#define       LSM6DSL_ACC_GYRO_SLEEP_EV_STATUS_MASK   0x10
+mems_status_t LSM6DSL_ACC_GYRO_R_SLEEP_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_SLEEP_EV_STATUS_t *value);
+
+/*******************************************************************************
+* Register      : WAKE_UP_SRC
+* Address       : 0X1B
+* Bit Group Name: FF_EV_STATUS
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_FF_EV_STATUS_NOT_DETECTED       =0x00,
+    LSM6DSL_ACC_GYRO_FF_EV_STATUS_DETECTED       =0x20,
+} LSM6DSL_ACC_GYRO_FF_EV_STATUS_t;
+
+#define       LSM6DSL_ACC_GYRO_FF_EV_STATUS_MASK      0x20
+mems_status_t LSM6DSL_ACC_GYRO_R_FF_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_FF_EV_STATUS_t *value);
+
+/*******************************************************************************
+* Register      : TAP_SRC
+* Address       : 0X1C
+* Bit Group Name: Z_TAP
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_Z_TAP_NOT_DETECTED          =0x00,
+    LSM6DSL_ACC_GYRO_Z_TAP_DETECTED          =0x01,
+} LSM6DSL_ACC_GYRO_Z_TAP_t;
+
+#define       LSM6DSL_ACC_GYRO_Z_TAP_MASK     0x01
+mems_status_t LSM6DSL_ACC_GYRO_R_Z_TAP(void *handle, LSM6DSL_ACC_GYRO_Z_TAP_t *value);
+
+/*******************************************************************************
+* Register      : TAP_SRC
+* Address       : 0X1C
+* Bit Group Name: Y_TAP
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_Y_TAP_NOT_DETECTED          =0x00,
+    LSM6DSL_ACC_GYRO_Y_TAP_DETECTED          =0x02,
+} LSM6DSL_ACC_GYRO_Y_TAP_t;
+
+#define       LSM6DSL_ACC_GYRO_Y_TAP_MASK     0x02
+mems_status_t LSM6DSL_ACC_GYRO_R_Y_TAP(void *handle, LSM6DSL_ACC_GYRO_Y_TAP_t *value);
+
+/*******************************************************************************
+* Register      : TAP_SRC
+* Address       : 0X1C
+* Bit Group Name: X_TAP
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_X_TAP_NOT_DETECTED          =0x00,
+    LSM6DSL_ACC_GYRO_X_TAP_DETECTED          =0x04,
+} LSM6DSL_ACC_GYRO_X_TAP_t;
+
+#define       LSM6DSL_ACC_GYRO_X_TAP_MASK     0x04
+mems_status_t LSM6DSL_ACC_GYRO_R_X_TAP(void *handle, LSM6DSL_ACC_GYRO_X_TAP_t *value);
+
+/*******************************************************************************
+* Register      : TAP_SRC
+* Address       : 0X1C
+* Bit Group Name: TAP_SIGN
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_TAP_SIGN_POS_SIGN       =0x00,
+    LSM6DSL_ACC_GYRO_TAP_SIGN_NEG_SIGN       =0x08,
+} LSM6DSL_ACC_GYRO_TAP_SIGN_t;
+
+#define       LSM6DSL_ACC_GYRO_TAP_SIGN_MASK      0x08
+mems_status_t LSM6DSL_ACC_GYRO_R_TAP_SIGN(void *handle, LSM6DSL_ACC_GYRO_TAP_SIGN_t *value);
+
+/*******************************************************************************
+* Register      : TAP_SRC
+* Address       : 0X1C
+* Bit Group Name: DOUBLE_TAP_EV_STATUS
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DOUBLE_TAP_EV_STATUS_NOT_DETECTED       =0x00,
+    LSM6DSL_ACC_GYRO_DOUBLE_TAP_EV_STATUS_DETECTED       =0x10,
+} LSM6DSL_ACC_GYRO_DOUBLE_TAP_EV_STATUS_t;
+
+#define       LSM6DSL_ACC_GYRO_DOUBLE_TAP_EV_STATUS_MASK      0x10
+mems_status_t LSM6DSL_ACC_GYRO_R_DOUBLE_TAP_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_DOUBLE_TAP_EV_STATUS_t *value);
+
+/*******************************************************************************
+* Register      : TAP_SRC
+* Address       : 0X1C
+* Bit Group Name: SINGLE_TAP_EV_STATUS
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_SINGLE_TAP_EV_STATUS_NOT_DETECTED       =0x00,
+    LSM6DSL_ACC_GYRO_SINGLE_TAP_EV_STATUS_DETECTED       =0x20,
+} LSM6DSL_ACC_GYRO_SINGLE_TAP_EV_STATUS_t;
+
+#define       LSM6DSL_ACC_GYRO_SINGLE_TAP_EV_STATUS_MASK      0x20
+mems_status_t LSM6DSL_ACC_GYRO_R_SINGLE_TAP_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_SINGLE_TAP_EV_STATUS_t *value);
+
+/*******************************************************************************
+* Register      : TAP_SRC
+* Address       : 0X1C
+* Bit Group Name: TAP_EV_STATUS
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_TAP_EV_STATUS_NOT_DETECTED          =0x00,
+    LSM6DSL_ACC_GYRO_TAP_EV_STATUS_DETECTED          =0x40,
+} LSM6DSL_ACC_GYRO_TAP_EV_STATUS_t;
+
+#define       LSM6DSL_ACC_GYRO_TAP_EV_STATUS_MASK     0x40
+mems_status_t LSM6DSL_ACC_GYRO_R_TAP_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_TAP_EV_STATUS_t *value);
+
+/*******************************************************************************
+* Register      : D6D_SRC
+* Address       : 0X1D
+* Bit Group Name: DSD_XL
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DSD_XL_NOT_DETECTED         =0x00,
+    LSM6DSL_ACC_GYRO_DSD_XL_DETECTED         =0x01,
+} LSM6DSL_ACC_GYRO_DSD_XL_t;
+
+#define       LSM6DSL_ACC_GYRO_DSD_XL_MASK    0x01
+mems_status_t LSM6DSL_ACC_GYRO_R_DSD_XL(void *handle, LSM6DSL_ACC_GYRO_DSD_XL_t *value);
+
+/*******************************************************************************
+* Register      : D6D_SRC
+* Address       : 0X1D
+* Bit Group Name: DSD_XH
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DSD_XH_NOT_DETECTED         =0x00,
+    LSM6DSL_ACC_GYRO_DSD_XH_DETECTED         =0x02,
+} LSM6DSL_ACC_GYRO_DSD_XH_t;
+
+#define       LSM6DSL_ACC_GYRO_DSD_XH_MASK    0x02
+mems_status_t LSM6DSL_ACC_GYRO_R_DSD_XH(void *handle, LSM6DSL_ACC_GYRO_DSD_XH_t *value);
+
+/*******************************************************************************
+* Register      : D6D_SRC
+* Address       : 0X1D
+* Bit Group Name: DSD_YL
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DSD_YL_NOT_DETECTED         =0x00,
+    LSM6DSL_ACC_GYRO_DSD_YL_DETECTED         =0x04,
+} LSM6DSL_ACC_GYRO_DSD_YL_t;
+
+#define       LSM6DSL_ACC_GYRO_DSD_YL_MASK    0x04
+mems_status_t LSM6DSL_ACC_GYRO_R_DSD_YL(void *handle, LSM6DSL_ACC_GYRO_DSD_YL_t *value);
+
+/*******************************************************************************
+* Register      : D6D_SRC
+* Address       : 0X1D
+* Bit Group Name: DSD_YH
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DSD_YH_NOT_DETECTED         =0x00,
+    LSM6DSL_ACC_GYRO_DSD_YH_DETECTED         =0x08,
+} LSM6DSL_ACC_GYRO_DSD_YH_t;
+
+#define       LSM6DSL_ACC_GYRO_DSD_YH_MASK    0x08
+mems_status_t LSM6DSL_ACC_GYRO_R_DSD_YH(void *handle, LSM6DSL_ACC_GYRO_DSD_YH_t *value);
+
+/*******************************************************************************
+* Register      : D6D_SRC
+* Address       : 0X1D
+* Bit Group Name: DSD_ZL
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DSD_ZL_NOT_DETECTED         =0x00,
+    LSM6DSL_ACC_GYRO_DSD_ZL_DETECTED         =0x10,
+} LSM6DSL_ACC_GYRO_DSD_ZL_t;
+
+#define       LSM6DSL_ACC_GYRO_DSD_ZL_MASK    0x10
+mems_status_t LSM6DSL_ACC_GYRO_R_DSD_ZL(void *handle, LSM6DSL_ACC_GYRO_DSD_ZL_t *value);
+
+/*******************************************************************************
+* Register      : D6D_SRC
+* Address       : 0X1D
+* Bit Group Name: DSD_ZH
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_DSD_ZH_NOT_DETECTED         =0x00,
+    LSM6DSL_ACC_GYRO_DSD_ZH_DETECTED         =0x20,
+} LSM6DSL_ACC_GYRO_DSD_ZH_t;
+
+#define       LSM6DSL_ACC_GYRO_DSD_ZH_MASK    0x20
+mems_status_t LSM6DSL_ACC_GYRO_R_DSD_ZH(void *handle, LSM6DSL_ACC_GYRO_DSD_ZH_t *value);
+
+/*******************************************************************************
+* Register      : D6D_SRC
+* Address       : 0X1D
+* Bit Group Name: D6D_EV_STATUS
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_D6D_EV_STATUS_NOT_DETECTED          =0x00,
+    LSM6DSL_ACC_GYRO_D6D_EV_STATUS_DETECTED          =0x40,
+} LSM6DSL_ACC_GYRO_D6D_EV_STATUS_t;
+
+#define       LSM6DSL_ACC_GYRO_D6D_EV_STATUS_MASK     0x40
+mems_status_t LSM6DSL_ACC_GYRO_R_D6D_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_D6D_EV_STATUS_t *value);
+
+/*******************************************************************************
+* Register      : STATUS_REG
+* Address       : 0X1E
+* Bit Group Name: XLDA
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_XLDA_NO_DATA_AVAIL          =0x00,
+    LSM6DSL_ACC_GYRO_XLDA_DATA_AVAIL         =0x01,
+} LSM6DSL_ACC_GYRO_XLDA_t;
+
+#define       LSM6DSL_ACC_GYRO_XLDA_MASK      0x01
+mems_status_t LSM6DSL_ACC_GYRO_R_XLDA(void *handle, LSM6DSL_ACC_GYRO_XLDA_t *value);
+
+/*******************************************************************************
+* Register      : STATUS_REG
+* Address       : 0X1E
+* Bit Group Name: GDA
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_GDA_NO_DATA_AVAIL       =0x00,
+    LSM6DSL_ACC_GYRO_GDA_DATA_AVAIL          =0x02,
+} LSM6DSL_ACC_GYRO_GDA_t;
+
+#define       LSM6DSL_ACC_GYRO_GDA_MASK   0x02
+mems_status_t LSM6DSL_ACC_GYRO_R_GDA(void *handle, LSM6DSL_ACC_GYRO_GDA_t *value);
+
+/*******************************************************************************
+* Register      : STATUS_REG
+* Address       : 0X1E
+* Bit Group Name: TDA
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_TDA_NO_DATA_AVAIL       =0x00,
+    LSM6DSL_ACC_GYRO_TDA_DATA_AVAIL          =0x04,
+} LSM6DSL_ACC_GYRO_TDA_t;
+
+#define       LSM6DSL_ACC_GYRO_TDA_MASK   0x04
+mems_status_t LSM6DSL_ACC_GYRO_R_TDA(void *handle, LSM6DSL_ACC_GYRO_TDA_t *value);
+
+/*******************************************************************************
+* Register      : FIFO_STATUS1
+* Address       : 0X3A
+* Bit Group Name: DIFF_FIFO
+* Permission    : RO
+*******************************************************************************/
+#define       LSM6DSL_ACC_GYRO_DIFF_FIFO_STATUS1_MASK     0xFF
+#define       LSM6DSL_ACC_GYRO_DIFF_FIFO_STATUS1_POSITION     0
+#define       LSM6DSL_ACC_GYRO_DIFF_FIFO_STATUS2_MASK  0xF
+#define       LSM6DSL_ACC_GYRO_DIFF_FIFO_STATUS2_POSITION     0
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFONumOfEntries(void *handle, u16_t *value);
+
+/*******************************************************************************
+* Register      : FIFO_STATUS2
+* Address       : 0X3B
+* Bit Group Name: FIFO_EMPTY
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_FIFO_EMPTY_FIFO_NOT_EMPTY       =0x00,
+    LSM6DSL_ACC_GYRO_FIFO_EMPTY_FIFO_EMPTY       =0x10,
+} LSM6DSL_ACC_GYRO_FIFO_EMPTY_t;
+
+#define       LSM6DSL_ACC_GYRO_FIFO_EMPTY_MASK    0x10
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFOEmpty(void *handle, LSM6DSL_ACC_GYRO_FIFO_EMPTY_t *value);
+
+/*******************************************************************************
+* Register      : FIFO_STATUS2
+* Address       : 0X3B
+* Bit Group Name: FIFO_FULL
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_FIFO_FULL_FIFO_NOT_FULL         =0x00,
+    LSM6DSL_ACC_GYRO_FIFO_FULL_FIFO_FULL         =0x20,
+} LSM6DSL_ACC_GYRO_FIFO_FULL_t;
+
+#define       LSM6DSL_ACC_GYRO_FIFO_FULL_MASK     0x20
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFOFull(void *handle, LSM6DSL_ACC_GYRO_FIFO_FULL_t *value);
+
+/*******************************************************************************
+* Register      : FIFO_STATUS2
+* Address       : 0X3B
+* Bit Group Name: OVERRUN
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_OVERRUN_NO_OVERRUN          =0x00,
+    LSM6DSL_ACC_GYRO_OVERRUN_OVERRUN         =0x40,
+} LSM6DSL_ACC_GYRO_OVERRUN_t;
+
+#define       LSM6DSL_ACC_GYRO_OVERRUN_MASK   0x40
+mems_status_t LSM6DSL_ACC_GYRO_R_OVERRUN(void *handle, LSM6DSL_ACC_GYRO_OVERRUN_t *value);
+
+/*******************************************************************************
+* Register      : FIFO_STATUS2
+* Address       : 0X3B
+* Bit Group Name: WTM
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_WTM_BELOW_WTM       =0x00,
+    LSM6DSL_ACC_GYRO_WTM_ABOVE_OR_EQUAL_WTM          =0x80,
+} LSM6DSL_ACC_GYRO_WTM_t;
+
+#define       LSM6DSL_ACC_GYRO_WTM_MASK   0x80
+mems_status_t LSM6DSL_ACC_GYRO_R_WaterMark(void *handle, LSM6DSL_ACC_GYRO_WTM_t *value);
+
+/*******************************************************************************
+* Register      : FIFO_STATUS3
+* Address       : 0X3C
+* Bit Group Name: FIFO_PATTERN
+* Permission    : RO
+*******************************************************************************/
+#define       LSM6DSL_ACC_GYRO_FIFO_STATUS3_PATTERN_MASK      0xFF
+#define       LSM6DSL_ACC_GYRO_FIFO_STATUS3_PATTERN_POSITION      0
+#define       LSM6DSL_ACC_GYRO_FIFO_STATUS4_PATTERN_MASK      0x03
+#define       LSM6DSL_ACC_GYRO_FIFO_STATUS4_PATTERN_POSITION      0
+mems_status_t LSM6DSL_ACC_GYRO_R_FIFOPattern(void *handle, u16_t *value);
+
+/*******************************************************************************
+* Register      : FUNC_SRC
+* Address       : 0X53
+* Bit Group Name: SENS_HUB_END
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_SENS_HUB_END_STILL_ONGOING          =0x00,
+    LSM6DSL_ACC_GYRO_SENS_HUB_END_OP_COMPLETED       =0x01,
+} LSM6DSL_ACC_GYRO_SENS_HUB_END_t;
+
+#define       LSM6DSL_ACC_GYRO_SENS_HUB_END_MASK      0x01
+mems_status_t LSM6DSL_ACC_GYRO_R_SENS_HUB_END(void *handle, LSM6DSL_ACC_GYRO_SENS_HUB_END_t *value);
+
+/*******************************************************************************
+* Register      : FUNC_SRC
+* Address       : 0X53
+* Bit Group Name: SOFT_IRON_END
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_SOFT_IRON_END_NOT_COMPLETED         =0x00,
+    LSM6DSL_ACC_GYRO_SOFT_IRON_END_COMPLETED         =0x02,
+} LSM6DSL_ACC_GYRO_SOFT_IRON_END_t;
+
+#define       LSM6DSL_ACC_GYRO_SOFT_IRON_END_MASK     0x02
+mems_status_t LSM6DSL_ACC_GYRO_R_SOFT_IRON_END(void *handle, LSM6DSL_ACC_GYRO_SOFT_IRON_END_t *value);
+
+/*******************************************************************************
+* Register      : FUNC_SRC
+* Address       : 0X53
+* Bit Group Name: HI_FAIL
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_HARD_IRON_NORMAL        =0x00,
+    LSM6DSL_ACC_GYRO_HARD_IRON_FAIL          =0x04,
+} LSM6DSL_ACC_GYRO_SOFT_HARD_IRON_STAT_t;
+
+#define       LSM6DSL_ACC_GYRO_HARD_IRON_STAT_MASK    0x04
+mems_status_t LSM6DSL_ACC_GYRO_R_HardIron(void *handle, LSM6DSL_ACC_GYRO_SOFT_HARD_IRON_STAT_t *value);
+
+/*******************************************************************************
+* Register      : FUNC_SRC
+* Address       : 0X53
+* Bit Group Name: STEP_OVERFLOW
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_PEDO_STEP_IN_RANGE          =0x00,
+    LSM6DSL_ACC_GYRO_PEDO_ESTEP_OVERFLOW         =0x08,
+} LSM6DSL_ACC_GYRO_STEP_OVERFLOW_t;
+
+#define       LSM6DSL_ACC_GYRO_STEP_OVERFLOW_MASK     0x08
+mems_status_t LSM6DSL_ACC_GYRO_R_STEP_OVERFLOW(void *handle, LSM6DSL_ACC_GYRO_STEP_OVERFLOW_t *value);
+
+/*******************************************************************************
+* Register      : FUNC_SRC
+* Address       : 0X53
+* Bit Group Name: PEDO_EV_STATUS
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_PEDO_EV_STATUS_NOT_DETECTED         =0x00,
+    LSM6DSL_ACC_GYRO_PEDO_EV_STATUS_DETECTED         =0x10,
+} LSM6DSL_ACC_GYRO_PEDO_EV_STATUS_t;
+
+#define       LSM6DSL_ACC_GYRO_PEDO_EV_STATUS_MASK    0x10
+mems_status_t LSM6DSL_ACC_GYRO_R_PEDO_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_PEDO_EV_STATUS_t *value);
+
+/*******************************************************************************
+* Register      : FUNC_SRC
+* Address       : 0X53
+* Bit Group Name: TILT_EV_STATUS
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_TILT_EV_STATUS_NOT_DETECTED         =0x00,
+    LSM6DSL_ACC_GYRO_TILT_EV_STATUS_DETECTED         =0x20,
+} LSM6DSL_ACC_GYRO_TILT_EV_STATUS_t;
+
+#define       LSM6DSL_ACC_GYRO_TILT_EV_STATUS_MASK    0x20
+mems_status_t LSM6DSL_ACC_GYRO_R_TILT_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_TILT_EV_STATUS_t *value);
+
+/*******************************************************************************
+* Register      : FUNC_SRC
+* Address       : 0X53
+* Bit Group Name: SIGN_MOT_EV_STATUS
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_SIGN_MOT_EV_STATUS_NOT_DETECTED         =0x00,
+    LSM6DSL_ACC_GYRO_SIGN_MOT_EV_STATUS_DETECTED         =0x40,
+} LSM6DSL_ACC_GYRO_SIGN_MOT_EV_STATUS_t;
+
+#define       LSM6DSL_ACC_GYRO_SIGN_MOT_EV_STATUS_MASK    0x40
+mems_status_t LSM6DSL_ACC_GYRO_R_SIGN_MOT_EV_STATUS(void *handle, LSM6DSL_ACC_GYRO_SIGN_MOT_EV_STATUS_t *value);
+
+/*******************************************************************************
+* Register      : FUNC_SRC
+* Address       : 0X53
+* Bit Group Name: STEP_COUNT_DELTA_IA
+* Permission    : RO
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_NO_STEP_COUNT_IN_DELTA          =0x00,
+    LSM6DSL_ACC_GYRO_STEP_COUNT_IN_DELTA         =0x80,
+} LSM6DSL_ACC_GYRO_STEP_COUNT_DELTA_t;
+
+#define       LSM6DSL_ACC_GYRO_STEP_COUNT_DELTA_MASK      0x80
+mems_status_t LSM6DSL_ACC_GYRO_R_STEP_COUNT_DELTA(void *handle, LSM6DSL_ACC_GYRO_STEP_COUNT_DELTA_t *value);
+
+/*******************************************************************************
+* Register      : TAP_CFG1
+* Address       : 0X58
+* Bit Group Name: LIR
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_LIR_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_LIR_ENABLED         =0x01,
+} LSM6DSL_ACC_GYRO_LIR_t;
+
+#define       LSM6DSL_ACC_GYRO_LIR_MASK   0x01
+mems_status_t LSM6DSL_ACC_GYRO_W_LIR(void *handle, LSM6DSL_ACC_GYRO_LIR_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_LIR(void *handle, LSM6DSL_ACC_GYRO_LIR_t *value);
+
+/*******************************************************************************
+* Register      : TAP_CFG1
+* Address       : 0X58
+* Bit Group Name: TAP_Z_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_TAP_Z_EN_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_TAP_Z_EN_ENABLED        =0x02,
+} LSM6DSL_ACC_GYRO_TAP_Z_EN_t;
+
+#define       LSM6DSL_ACC_GYRO_TAP_Z_EN_MASK      0x02
+mems_status_t LSM6DSL_ACC_GYRO_W_TAP_Z_EN(void *handle, LSM6DSL_ACC_GYRO_TAP_Z_EN_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_TAP_Z_EN(void *handle, LSM6DSL_ACC_GYRO_TAP_Z_EN_t *value);
+
+/*******************************************************************************
+* Register      : TAP_CFG1
+* Address       : 0X58
+* Bit Group Name: TAP_Y_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_TAP_Y_EN_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_TAP_Y_EN_ENABLED        =0x04,
+} LSM6DSL_ACC_GYRO_TAP_Y_EN_t;
+
+#define       LSM6DSL_ACC_GYRO_TAP_Y_EN_MASK      0x04
+mems_status_t LSM6DSL_ACC_GYRO_W_TAP_Y_EN(void *handle, LSM6DSL_ACC_GYRO_TAP_Y_EN_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_TAP_Y_EN(void *handle, LSM6DSL_ACC_GYRO_TAP_Y_EN_t *value);
+
+/*******************************************************************************
+* Register      : TAP_CFG1
+* Address       : 0X58
+* Bit Group Name: TAP_X_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_TAP_X_EN_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_TAP_X_EN_ENABLED        =0x08,
+} LSM6DSL_ACC_GYRO_TAP_X_EN_t;
+
+#define       LSM6DSL_ACC_GYRO_TAP_X_EN_MASK      0x08
+mems_status_t LSM6DSL_ACC_GYRO_W_TAP_X_EN(void *handle, LSM6DSL_ACC_GYRO_TAP_X_EN_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_TAP_X_EN(void *handle, LSM6DSL_ACC_GYRO_TAP_X_EN_t *value);
+/*******************************************************************************
+* Register      : TAP_CFG1
+* Address       : 0X58
+* Bit Group Name: SLOPE_FDS
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_SLOPE_FDS_DISABLED          =0x00,
+    LSM6DSL_ACC_GYRO_SLOPE_FDS_ENABLED       =0x10,
+} LSM6DSL_ACC_GYRO_SLOPE_FDS_t;
+
+#define       LSM6DSL_ACC_GYRO_SLOPE_FDS_MASK     0x10
+mems_status_t LSM6DSL_ACC_GYRO_W_SLOPE_FDS(void *handle, LSM6DSL_ACC_GYRO_SLOPE_FDS_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SLOPE_FDS(void *handle, LSM6DSL_ACC_GYRO_SLOPE_FDS_t *value);
+
+/*******************************************************************************
+* Register      : TAP_CFG1
+* Address       : 0X58
+* Bit Group Name: INTERRUPTS_ENABLE
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_BASIC_INT_DISABLED          =0x00,
+    LSM6DSL_ACC_GYRO_BASIC_INT_ENABLED       =0x80,
+} LSM6DSL_ACC_GYRO_INT_EN_t;
+
+#define       LSM6DSL_ACC_GYRO_INT_EN_MASK    0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_BASIC_INT(void *handle, LSM6DSL_ACC_GYRO_INT_EN_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_BASIC_INT(void *handle, LSM6DSL_ACC_GYRO_INT_EN_t *value);
+
+/*******************************************************************************
+* Register      : TAP_THS_6D
+* Address       : 0X59
+* Bit Group Name: TAP_THS
+* Permission    : RW
+*******************************************************************************/
+#define       LSM6DSL_ACC_GYRO_TAP_THS_MASK   0x1F
+#define       LSM6DSL_ACC_GYRO_TAP_THS_POSITION   0
+mems_status_t LSM6DSL_ACC_GYRO_W_TAP_THS(void *handle, u8_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_TAP_THS(void *handle, u8_t *value);
+
+/*******************************************************************************
+* Register      : TAP_THS_6D
+* Address       : 0X59
+* Bit Group Name: SIXD_THS
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_SIXD_THS_80_degree          =0x00,
+    LSM6DSL_ACC_GYRO_SIXD_THS_70_degree          =0x20,
+    LSM6DSL_ACC_GYRO_SIXD_THS_60_degree          =0x40,
+    LSM6DSL_ACC_GYRO_SIXD_THS_50_degree          =0x60,
+} LSM6DSL_ACC_GYRO_SIXD_THS_t;
+
+#define       LSM6DSL_ACC_GYRO_SIXD_THS_MASK      0x60
+mems_status_t LSM6DSL_ACC_GYRO_W_SIXD_THS(void *handle, LSM6DSL_ACC_GYRO_SIXD_THS_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SIXD_THS(void *handle, LSM6DSL_ACC_GYRO_SIXD_THS_t *value);
+
+/*******************************************************************************
+* Register      : TAP_THS_6D
+* Address       : 0X59
+* Bit Group Name: D4D_EN
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_D4D_DIS         =0x00,
+    LSM6DSL_ACC_GYRO_D4D_EN          =0x80,
+} LSM6DSL_ACC_GYRO_D4D_t;
+
+#define       LSM6DSL_ACC_GYRO_D4D_MASK   0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_D4D(void *handle, LSM6DSL_ACC_GYRO_D4D_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_D4D(void *handle, LSM6DSL_ACC_GYRO_D4D_t *value);
+
+/*******************************************************************************
+* Register      : INT_DUR2
+* Address       : 0X5A
+* Bit Group Name: SHOCK
+* Permission    : RW
+*******************************************************************************/
+#define       LSM6DSL_ACC_GYRO_SHOCK_MASK     0x03
+#define       LSM6DSL_ACC_GYRO_SHOCK_POSITION     0
+mems_status_t LSM6DSL_ACC_GYRO_W_SHOCK_Duration(void *handle, u8_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SHOCK_Duration(void *handle, u8_t *value);
+
+/*******************************************************************************
+* Register      : INT_DUR2
+* Address       : 0X5A
+* Bit Group Name: QUIET
+* Permission    : RW
+*******************************************************************************/
+#define       LSM6DSL_ACC_GYRO_QUIET_MASK     0x0C
+#define       LSM6DSL_ACC_GYRO_QUIET_POSITION     2
+mems_status_t LSM6DSL_ACC_GYRO_W_QUIET_Duration(void *handle, u8_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_QUIET_Duration(void *handle, u8_t *value);
+
+/*******************************************************************************
+* Register      : INT_DUR2
+* Address       : 0X5A
+* Bit Group Name: DUR
+* Permission    : RW
+*******************************************************************************/
+#define       LSM6DSL_ACC_GYRO_DUR_MASK   0xF0
+#define       LSM6DSL_ACC_GYRO_DUR_POSITION   4
+mems_status_t LSM6DSL_ACC_GYRO_W_DUR(void *handle, u8_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_DUR(void *handle, u8_t *value);
+
+/*******************************************************************************
+* Register      : WAKE_UP_THS
+* Address       : 0X5B
+* Bit Group Name: WK_THS
+* Permission    : RW
+*******************************************************************************/
+#define       LSM6DSL_ACC_GYRO_WK_THS_MASK    0x3F
+#define       LSM6DSL_ACC_GYRO_WK_THS_POSITION    0
+mems_status_t LSM6DSL_ACC_GYRO_W_WK_THS(void *handle, u8_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_WK_THS(void *handle, u8_t *value);
+
+/*******************************************************************************
+* Register      : WAKE_UP_THS
+* Address       : 0X5B
+* Bit Group Name: SINGLE_DOUBLE_TAP
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_SINGLE_DOUBLE_TAP_SINGLE_TAP        =0x00,
+    LSM6DSL_ACC_GYRO_SINGLE_DOUBLE_TAP_DOUBLE_TAP        =0x80,
+} LSM6DSL_ACC_GYRO_SINGLE_DOUBLE_TAP_t;
+
+#define       LSM6DSL_ACC_GYRO_SINGLE_DOUBLE_TAP_MASK     0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_SINGLE_DOUBLE_TAP_EV(void *handle, LSM6DSL_ACC_GYRO_SINGLE_DOUBLE_TAP_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SINGLE_DOUBLE_TAP_EV(void *handle, LSM6DSL_ACC_GYRO_SINGLE_DOUBLE_TAP_t *value);
+
+/*******************************************************************************
+* Register      : WAKE_UP_DUR
+* Address       : 0X5C
+* Bit Group Name: SLEEP_DUR
+* Permission    : RW
+*******************************************************************************/
+#define       LSM6DSL_ACC_GYRO_SLEEP_DUR_MASK     0x0F
+#define       LSM6DSL_ACC_GYRO_SLEEP_DUR_POSITION     0
+mems_status_t LSM6DSL_ACC_GYRO_W_SLEEP_DUR(void *handle, u8_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SLEEP_DUR(void *handle, u8_t *value);
+
+/*******************************************************************************
+* Register      : WAKE_UP_DUR
+* Address       : 0X5C
+* Bit Group Name: TIMER_HR
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_TIMER_HR_6_4ms          =0x00,
+    LSM6DSL_ACC_GYRO_TIMER_HR_25us       =0x10,
+} LSM6DSL_ACC_GYRO_TIMER_HR_t;
+
+#define       LSM6DSL_ACC_GYRO_TIMER_HR_MASK      0x10
+mems_status_t LSM6DSL_ACC_GYRO_W_TIMER_HR(void *handle, LSM6DSL_ACC_GYRO_TIMER_HR_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_TIMER_HR(void *handle, LSM6DSL_ACC_GYRO_TIMER_HR_t *value);
+
+/*******************************************************************************
+* Register      : WAKE_UP_DUR
+* Address       : 0X5C
+* Bit Group Name: WAKE_DUR
+* Permission    : RW
+*******************************************************************************/
+#define       LSM6DSL_ACC_GYRO_WAKE_DUR_MASK      0x60
+#define       LSM6DSL_ACC_GYRO_WAKE_DUR_POSITION      5
+mems_status_t LSM6DSL_ACC_GYRO_W_WAKE_DUR(void *handle, u8_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_WAKE_DUR(void *handle, u8_t *value);
+
+/*******************************************************************************
+* Register      : FREE_FALL
+* Address       : 0X5D
+* Bit Group Name: FF_DUR
+* Permission    : RW
+*******************************************************************************/
+#define       LSM6DSL_ACC_GYRO_FF_FREE_FALL_DUR_MASK      0xF8
+#define       LSM6DSL_ACC_GYRO_FF_FREE_FALL_DUR_POSITION      3
+#define       LSM6DSL_ACC_GYRO_FF_WAKE_UP_DUR_MASK    0x80
+#define       LSM6DSL_ACC_GYRO_FF_WAKE_UP_DUR_POSITION    7
+mems_status_t LSM6DSL_ACC_GYRO_W_FF_Duration(void *handle, u8_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_FF_Duration(void *handle, u8_t *value);
+
+
+/*******************************************************************************
+* Register      : FREE_FALL
+* Address       : 0X5D
+* Bit Group Name: FF_THS
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_FF_THS_156mg        =0x00,
+    LSM6DSL_ACC_GYRO_FF_THS_219mg        =0x01,
+    LSM6DSL_ACC_GYRO_FF_THS_250mg        =0x02,
+    LSM6DSL_ACC_GYRO_FF_THS_312mg        =0x03,
+    LSM6DSL_ACC_GYRO_FF_THS_344mg        =0x04,
+    LSM6DSL_ACC_GYRO_FF_THS_406mg        =0x05,
+    LSM6DSL_ACC_GYRO_FF_THS_469mg        =0x06,
+    LSM6DSL_ACC_GYRO_FF_THS_500mg        =0x07,
+} LSM6DSL_ACC_GYRO_FF_THS_t;
+
+#define       LSM6DSL_ACC_GYRO_FF_THS_MASK    0x07
+mems_status_t LSM6DSL_ACC_GYRO_W_FF_THS(void *handle, LSM6DSL_ACC_GYRO_FF_THS_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_FF_THS(void *handle, LSM6DSL_ACC_GYRO_FF_THS_t *value);
+
+/*******************************************************************************
+* Register      : MD1_CFG
+* Address       : 0X5E
+* Bit Group Name: INT1_TIMER
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT1_TIMER_DISABLED         =0x00,
+    LSM6DSL_ACC_GYRO_INT1_TIMER_ENABLED          =0x01,
+} LSM6DSL_ACC_GYRO_INT1_TIMER_t;
+
+#define       LSM6DSL_ACC_GYRO_INT1_TIMER_MASK    0x01
+mems_status_t LSM6DSL_ACC_GYRO_W_TimerEvRouteInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_TIMER_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_TimerEvRouteInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_TIMER_t *value);
+
+/*******************************************************************************
+* Register      : MD1_CFG
+* Address       : 0X5E
+* Bit Group Name: INT1_TILT
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT1_TILT_DISABLED          =0x00,
+    LSM6DSL_ACC_GYRO_INT1_TILT_ENABLED       =0x02,
+} LSM6DSL_ACC_GYRO_INT1_TILT_t;
+
+#define       LSM6DSL_ACC_GYRO_INT1_TILT_MASK     0x02
+mems_status_t LSM6DSL_ACC_GYRO_W_TiltEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_TILT_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_TiltEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_TILT_t *value);
+
+/*******************************************************************************
+* Register      : MD1_CFG
+* Address       : 0X5E
+* Bit Group Name: INT1_6D
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT1_6D_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_INT1_6D_ENABLED         =0x04,
+} LSM6DSL_ACC_GYRO_INT1_6D_t;
+
+#define       LSM6DSL_ACC_GYRO_INT1_6D_MASK   0x04
+mems_status_t LSM6DSL_ACC_GYRO_W_6DEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_6D_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_6DEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_6D_t *value);
+
+/*******************************************************************************
+* Register      : MD1_CFG
+* Address       : 0X5E
+* Bit Group Name: INT1_TAP
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT1_TAP_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_INT1_TAP_ENABLED        =0x08,
+} LSM6DSL_ACC_GYRO_INT1_TAP_t;
+
+#define       LSM6DSL_ACC_GYRO_INT1_TAP_MASK      0x08
+mems_status_t LSM6DSL_ACC_GYRO_W_TapEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_TAP_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_TapEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_TAP_t *value);
+
+/*******************************************************************************
+* Register      : MD1_CFG
+* Address       : 0X5E
+* Bit Group Name: INT1_FF
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT1_FF_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_INT1_FF_ENABLED         =0x10,
+} LSM6DSL_ACC_GYRO_INT1_FF_t;
+
+#define       LSM6DSL_ACC_GYRO_INT1_FF_MASK   0x10
+mems_status_t LSM6DSL_ACC_GYRO_W_FFEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_FF_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_FFEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_FF_t *value);
+
+/*******************************************************************************
+* Register      : MD1_CFG
+* Address       : 0X5E
+* Bit Group Name: INT1_WU
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT1_WU_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_INT1_WU_ENABLED         =0x20,
+} LSM6DSL_ACC_GYRO_INT1_WU_t;
+
+#define       LSM6DSL_ACC_GYRO_INT1_WU_MASK   0x20
+mems_status_t LSM6DSL_ACC_GYRO_W_WUEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_WU_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_WUEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_WU_t *value);
+
+/*******************************************************************************
+* Register      : MD1_CFG
+* Address       : 0X5E
+* Bit Group Name: INT1_SINGLE_TAP
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_ENABLED         =0x40,
+} LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_t;
+
+#define       LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_MASK   0x40
+mems_status_t LSM6DSL_ACC_GYRO_W_SingleTapOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SingleTapOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_SINGLE_TAP_t *value);
+
+/*******************************************************************************
+* Register      : MD1_CFG
+* Address       : 0X5E
+* Bit Group Name: INT1_INACT_STATE
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT1_SLEEP_DISABLED         =0x00,
+    LSM6DSL_ACC_GYRO_INT1_SLEEP_ENABLED          =0x80,
+} LSM6DSL_ACC_GYRO_INT1_SLEEP_t;
+
+#define       LSM6DSL_ACC_GYRO_INT1_SLEEP_MASK    0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_SleepEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_SLEEP_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SleepEvOnInt1(void *handle, LSM6DSL_ACC_GYRO_INT1_SLEEP_t *value);
+
+/*******************************************************************************
+* Register      : MD2_CFG
+* Address       : 0X5F
+* Bit Group Name: INT2_IRON
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_IRON_DISABLED          =0x00,
+    LSM6DSL_ACC_GYRO_INT2_IRON_ENABLED       =0x01,
+} LSM6DSL_ACC_GYRO_INT2_IRON_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_IRON_MASK     0x01
+mems_status_t LSM6DSL_ACC_GYRO_W_MagCorrection_Int2(void *handle, LSM6DSL_ACC_GYRO_INT2_IRON_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_MagCorrection_Int2(void *handle, LSM6DSL_ACC_GYRO_INT2_IRON_t *value);
+
+/*******************************************************************************
+* Register      : MD2_CFG
+* Address       : 0X5F
+* Bit Group Name: INT2_TILT
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_TILT_DISABLED          =0x00,
+    LSM6DSL_ACC_GYRO_INT2_TILT_ENABLED       =0x02,
+} LSM6DSL_ACC_GYRO_INT2_TILT_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_TILT_MASK     0x02
+mems_status_t LSM6DSL_ACC_GYRO_W_TiltEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_TILT_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_TiltEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_TILT_t *value);
+
+/*******************************************************************************
+* Register      : MD2_CFG
+* Address       : 0X5F
+* Bit Group Name: INT2_6D
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_6D_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_INT2_6D_ENABLED         =0x04,
+} LSM6DSL_ACC_GYRO_INT2_6D_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_6D_MASK   0x04
+mems_status_t LSM6DSL_ACC_GYRO_W_6DEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_6D_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_6DEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_6D_t *value);
+
+/*******************************************************************************
+* Register      : MD2_CFG
+* Address       : 0X5F
+* Bit Group Name: INT2_TAP
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_TAP_DISABLED       =0x00,
+    LSM6DSL_ACC_GYRO_INT2_TAP_ENABLED        =0x08,
+} LSM6DSL_ACC_GYRO_INT2_TAP_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_TAP_MASK      0x08
+mems_status_t LSM6DSL_ACC_GYRO_W_TapEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_TAP_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_TapEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_TAP_t *value);
+
+/*******************************************************************************
+* Register      : MD2_CFG
+* Address       : 0X5F
+* Bit Group Name: INT2_FF
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_FF_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_INT2_FF_ENABLED         =0x10,
+} LSM6DSL_ACC_GYRO_INT2_FF_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_FF_MASK   0x10
+mems_status_t LSM6DSL_ACC_GYRO_W_FFEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_FF_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_FFEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_FF_t *value);
+
+/*******************************************************************************
+* Register      : MD2_CFG
+* Address       : 0X5F
+* Bit Group Name: INT2_WU
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_WU_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_INT2_WU_ENABLED         =0x20,
+} LSM6DSL_ACC_GYRO_INT2_WU_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_WU_MASK   0x20
+mems_status_t LSM6DSL_ACC_GYRO_W_WUEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_WU_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_WUEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_WU_t *value);
+
+/*******************************************************************************
+* Register      : MD2_CFG
+* Address       : 0X5F
+* Bit Group Name: INT2_SINGLE_TAP
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_DISABLED        =0x00,
+    LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_ENABLED         =0x40,
+} LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_MASK   0x40
+mems_status_t LSM6DSL_ACC_GYRO_W_SingleTapOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SingleTapOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_SINGLE_TAP_t *value);
+
+/*******************************************************************************
+* Register      : MD2_CFG
+* Address       : 0X5F
+* Bit Group Name: INT2_INACT_STATE
+* Permission    : RW
+*******************************************************************************/
+typedef enum {
+    LSM6DSL_ACC_GYRO_INT2_SLEEP_DISABLED         =0x00,
+    LSM6DSL_ACC_GYRO_INT2_SLEEP_ENABLED          =0x80,
+} LSM6DSL_ACC_GYRO_INT2_SLEEP_t;
+
+#define       LSM6DSL_ACC_GYRO_INT2_SLEEP_MASK    0x80
+mems_status_t LSM6DSL_ACC_GYRO_W_SleepEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_SLEEP_t newValue);
+mems_status_t LSM6DSL_ACC_GYRO_R_SleepEvOnInt2(void *handle, LSM6DSL_ACC_GYRO_INT2_SLEEP_t *value);
+
+/*******************************************************************************
+* Register      : <REGISTER_L> - <REGISTER_H>
+* Output Type   : GetAccData
+* Permission    : RO 
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_GetRawAccData(void *handle, u8_t *buff);
+mems_status_t LSM6DSL_ACC_Get_Acceleration(void *handle, int *buff, u8_t from_fifo);
+
+/*******************************************************************************
+* Register      : <REGISTER_L> - <REGISTER_H>
+* Output Type   : GetFIFOData
+* Permission    : RO 
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_Get_GetFIFOData(void *handle, u8_t *buff); 
+/*******************************************************************************
+* Register      : <REGISTER_L> - <REGISTER_H>
+* Output Type   : GetTimestamp
+* Permission    : RO 
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_Get_GetTimestamp(void *handle, u8_t *buff); 
+/*******************************************************************************
+* Register      : <REGISTER_L> - <REGISTER_H>
+* Output Type   : GetStepCounter
+* Permission    : RO 
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_Get_GetStepCounter(void *handle, u8_t *buff); 
+
+/*******************************************************************************
+* Register      : <REGISTER_L> - <REGISTER_H>
+* Output Type   : Pedometer Threshold
+* Permission    : RO 
+*******************************************************************************/
+mems_status_t LSM6DSL_ACC_GYRO_W_PedoThreshold(void *handle, u8_t newValue);
+
+/************** Use Sensor Hub  *******************/
+
+/* program to .... */
+mems_status_t LSM6DSL_ACC_GYRO_SH0_Program(void *handle, u8_t SlvAddr, u8_t Reg, u8_t len);
+
+/* Program the six Soft Iron Matrix coefficients. */
+mems_status_t LSM6DSL_ACC_GYRO_SH_init_SI_Matrix(void *handle, u8_t *SI_matrix);
+
+/* Read a remote device through I2C Sensor Hub Slave 0 */
+mems_status_t LSM6DSL_ACC_GYRO_SH0_ReadMem(void *handle, u8_t SlvAddr, u8_t Reg, u8_t *Bufp, u8_t len, u8_t stop);
+
+/* Write a remote device through I2C Sensor Hub Slave 0 */
+mems_status_t LSM6DSL_ACC_GYRO_SH0_WriteByte(void *handle, u8_t SlvAddr, u8_t Reg, u8_t Bufp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- a/sensors/VL53L0X.lib	Sun Dec 16 13:29:53 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://os.mbed.com/teams/ST/code/VL53L0X/#e9269ff624ed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/VL53L0X/STMPE1600/Stmpe1600.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,339 @@
+/**
+ ******************************************************************************
+ * @file    Stmpe1600.h
+ * @author  AST / EST
+ * @version V0.0.1
+ * @date    14-April-2015
+ * @brief   Header file for component stmpe1600
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+*/
+#ifndef     __STMPE1600_CLASS
+#define     __STMPE1600_CLASS
+/* Includes ------------------------------------------------------------------*/
+#include    "DevI2C.h"
+
+#define STMPE1600_DEF_DEVICE_ADDRESS  (uint8_t)0x42*2
+#define STMPE1600_DEF_DIGIOUT_LVL      1
+
+/**  STMPE1600 registr map **/
+#define CHIP_ID_0_7       (uint8_t)0x00
+#define CHIP_ID_8_15      (uint8_t)0x01
+#define VERSION_ID        (uint8_t)0x02
+#define SYS_CTRL          (uint8_t)0x03
+#define IEGPIOR_0_7       (uint8_t)0x08
+#define IEGPIOR_8_15	  (uint8_t)0x09
+#define ISGPIOR_0_7       (uint8_t)0x0A
+#define ISGPIOR_8_15	  (uint8_t)0x0B
+#define GPMR_0_7	      (uint8_t)0x10
+#define GPMR_8_15	      (uint8_t)0x11
+#define GPSR_0_7	      (uint8_t)0x12
+#define GPSR_8_15	      (uint8_t)0x13
+#define GPDR_0_7	      (uint8_t)0x14
+#define GPDR_8_15	      (uint8_t)0x15
+#define GPIR_0_7	      (uint8_t)0x16
+#define GPIR_8_15	      (uint8_t)0x17
+
+#define SOFT_RESET        (uint8_t)0x80
+
+typedef enum {
+    // GPIO Expander pin names
+    GPIO_0 = 0,
+    GPIO_1,
+    GPIO_2,
+    GPIO_3,
+    GPIO_4,
+    GPIO_5,
+    GPIO_6,
+    GPIO_7,
+    GPIO_8,
+    GPIO_9,
+    GPIO_10,
+    GPIO_11,
+    GPIO_12,
+    GPIO_13,
+    GPIO_14,
+    GPIO_15,
+    NOT_CON
+} ExpGpioPinName;
+
+typedef enum {
+    INPUT = 0,
+    OUTPUT,
+    NOT_CONNECTED
+} ExpGpioPinDirection;
+
+/* Classes -------------------------------------------------------------------*/
+/** Class representing a single stmpe1600 GPIO expander output pin
+ */
+class Stmpe1600DigiOut
+{
+
+public:
+    /** Constructor
+     * @param[in] &i2c device I2C to be used for communication
+     * @param[in] outpinname the desired out pin name to be created
+     * @param[in] DevAddr the stmpe1600 I2C device address (deft STMPE1600_DEF_DEVICE_ADDRESS)
+     * @param[in] lvl the default ot pin level
+     */
+    Stmpe1600DigiOut(DevI2C *i2c, ExpGpioPinName out_pin_name, uint8_t dev_addr = STMPE1600_DEF_DEVICE_ADDRESS,
+                     bool lvl = STMPE1600_DEF_DIGIOUT_LVL) : _dev_i2c(i2c), exp_dev_addr(dev_addr), exp_pin_name(out_pin_name)
+    {
+        uint8_t data[2];
+
+        if (exp_pin_name == NOT_CON) {
+            return;
+        }
+        /* set the exp_pin_name as output */
+        _dev_i2c->i2c_read(data, exp_dev_addr, GPDR_0_7, 1);
+        _dev_i2c->i2c_read(&data[1], exp_dev_addr, GPDR_8_15, 1);
+        * (uint16_t *) data = * (uint16_t *) data | (1 << (uint16_t) exp_pin_name);         // set gpio as out
+        _dev_i2c->i2c_write(data, exp_dev_addr, GPDR_0_7, 1);
+        _dev_i2c->i2c_write(&data[1], exp_dev_addr, GPDR_8_15, 1);
+        write(lvl);
+    }
+
+    /**
+     * @brief       Write on the out pin
+     * @param[in]   lvl level to write
+     * @return      0 on Success
+     */
+    void write(int lvl)
+    {
+        uint8_t data[2];
+
+        if (exp_pin_name == NOT_CON) {
+            return;
+        }
+        /* set the exp_pin_name state to lvl */
+        _dev_i2c->i2c_read(data, exp_dev_addr, GPSR_0_7, 2);
+        * (uint16_t *) data = * (uint16_t *) data & (uint16_t)(~(1 << (uint16_t) exp_pin_name));               // set pin mask
+        if (lvl) {
+            * (uint16_t *) data = * (uint16_t *) data | (uint16_t)(1 << (uint16_t) exp_pin_name);
+        }
+        _dev_i2c->i2c_write(data, exp_dev_addr, GPSR_0_7, 2);
+    }
+
+    /**
+     * @brief       Overload assignement operator
+     */
+    Stmpe1600DigiOut &operator= (int lvl)
+    {
+        write(lvl);
+        return *this;
+    }
+
+private:
+    DevI2C *_dev_i2c;
+    uint8_t exp_dev_addr;
+    ExpGpioPinName exp_pin_name;
+};
+
+/* Classes -------------------------------------------------------------------*/
+/** Class representing a single stmpe1600 GPIO expander input pin
+ */
+class Stmpe1600DigiIn
+{
+public:
+    /** Constructor
+    * @param[in] &i2c device I2C to be used for communication
+    * @param[in] inpinname the desired input pin name to be created
+    * @param[in] DevAddr the stmpe1600 I2C device addres (deft STMPE1600_DEF_DEVICE_ADDRESS)
+    */
+    Stmpe1600DigiIn(DevI2C *i2c, ExpGpioPinName in_pin_name,
+                    uint8_t dev_addr = STMPE1600_DEF_DEVICE_ADDRESS) : _dev_i2c(i2c), exp_dev_addr(dev_addr),
+        exp_pin_name(in_pin_name)
+    {
+        uint8_t data[2];
+
+        if (exp_pin_name == NOT_CON) {
+            return;
+        }
+        /* set the exp_pin_name as input pin direction */
+        _dev_i2c->i2c_read(data, exp_dev_addr, GPDR_0_7, 2);
+        * (uint16_t *) data = * (uint16_t *) data & (uint16_t)(~(1 << (uint16_t) exp_pin_name));               // set gpio as in
+        _dev_i2c->i2c_write(data, exp_dev_addr, GPDR_0_7, 2);
+    }
+
+    /**
+     * @brief       Read the input pin
+     * @return      The pin logical state 0 or 1
+     */
+    bool read()
+    {
+        uint8_t data[2];
+
+        if (exp_pin_name == NOT_CON) {
+            return false;
+        }
+        /* read the exp_pin_name */
+        _dev_i2c->i2c_read(data, exp_dev_addr, GPMR_0_7, 2);
+        * (uint16_t *) data = * (uint16_t *) data & (uint16_t)(1 << (uint16_t) exp_pin_name);            // mask the in gpio
+        if (data[0] || data[1]) {
+            return true;
+        }
+        return false;
+    }
+
+    operator int()
+    {
+        return read();
+    }
+
+private:
+    DevI2C *_dev_i2c;
+    uint8_t exp_dev_addr;
+    ExpGpioPinName exp_pin_name;
+};
+
+/* Classes -------------------------------------------------------------------*/
+/** Class representing a whole stmpe1600 component (16 gpio)
+ */
+class Stmpe1600
+{
+
+public:
+    /** Constructor
+    * @param[in] &i2c device I2C to be used for communication
+    * @param[in] DevAddr the stmpe1600 I2C device addres (deft STMPE1600_DEF_DEVICE_ADDRESS)
+    */
+    Stmpe1600(DevI2C *i2c, uint8_t dev_addr = STMPE1600_DEF_DEVICE_ADDRESS) : _dev_i2c(i2c)
+    {
+        exp_dev_addr = dev_addr;
+        write_sys_ctrl(SOFT_RESET);
+
+        gpdr0_15 = (uint16_t) 0;	// gpio dir all IN
+        write_16bit_reg(GPDR_0_7, &gpdr0_15);
+        gpsr0_15 = (uint16_t) 0x0ffff;   // gpio status all 1
+        write_16bit_reg(GPSR_0_7, &gpsr0_15);
+    }
+
+    /**
+     * @brief       Write the SYS_CTRL register
+     * @param[in]   Data to be written (bit fields)
+     */
+    void write_sys_ctrl(uint8_t data)      // data = SOFT_RESET reset the device
+    {
+        _dev_i2c->i2c_write(&data, exp_dev_addr, SYS_CTRL, 1);
+    }
+
+    /**
+     * @brief       Set the out pin
+     * @param[in]   The pin name
+     * @return      0 on Success
+     */
+    bool set_gpio(ExpGpioPinName pin_name)
+    {
+        if (pin_name == NOT_CON) {
+            return true;
+        }
+        gpsr0_15 = gpsr0_15 | ((uint16_t) 0x0001 << pin_name);
+        write_16bit_reg(GPSR_0_7, &gpsr0_15);
+        return false;
+    }
+
+    /**
+     * @brief       Clear the out pin
+     * @param[in]   The pin name
+     * @return      0 on Success
+     */
+    bool clear_gpio(ExpGpioPinName pin_name)
+    {
+        if (pin_name == NOT_CON) {
+            return true;
+        }
+        gpsr0_15 = gpsr0_15 & (~((uint16_t) 0x0001 << pin_name));
+        write_16bit_reg(GPSR_0_7, &gpsr0_15);
+        return false;
+    }
+
+    /**
+     * @brief       Read the input pin
+     * @param[in]   The pin name
+     * @return      The logical pin level
+     */
+    bool read_gpio(ExpGpioPinName pin_name)
+    {
+        uint16_t gpmr0_15;
+        if (pin_name == NOT_CON) {
+            return true;
+        }
+        read_16bit_reg(GPMR_0_7, &gpmr0_15);
+        gpmr0_15 = gpmr0_15 & ((uint16_t) 0x0001 << pin_name);
+        if (gpmr0_15) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * @brief       Set the pin direction
+     * @param[in]   The pin name
+     * @param[in]   The pin direction
+     * @return      0 on success
+     */
+    bool set_gpio_dir(ExpGpioPinName pin_name, ExpGpioPinDirection pin_dir)
+    {
+        if (pin_name == NOT_CON || pin_dir == NOT_CONNECTED) {
+            return true;
+        }
+        gpdr0_15 = gpdr0_15 & (~((uint16_t) 0x0001 << pin_name));        // clear the Pin
+        gpdr0_15 = gpdr0_15 | ((uint16_t) pin_dir << pin_name);
+        write_16bit_reg(GPDR_0_7, &gpdr0_15);
+        return false;
+    }
+
+    /**
+     * @brief       Read a 16 bits register
+     * @param[in]   The register address
+     * @param[in]   The pointer to the read data
+     */
+    void read_16bit_reg(uint8_t reg16_addr, uint16_t *reg16_data)
+    {
+        _dev_i2c->i2c_read((uint8_t *) reg16_data, exp_dev_addr, reg16_addr, 2);
+    }
+
+    /**
+     * @brief       Write a 16 bits register
+     * @param[in]   The register address
+     * @param[in]   The pointer to the data to be written
+     */
+    void write_16bit_reg(uint8_t reg16_addr, uint16_t *reg16_data)
+    {
+        _dev_i2c->i2c_write((uint8_t *) reg16_data, exp_dev_addr, reg16_addr, 2);
+    }
+
+private:
+    DevI2C *_dev_i2c;
+    uint16_t gpdr0_15;  // local copy of bit direction reg
+    uint16_t gpsr0_15;  // local copy of bit status reg
+    uint8_t exp_dev_addr; // expander device i2c addr
+};
+
+#endif // __STMPE1600_CLASS
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/VL53L0X/VL53L0X.cpp	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,5512 @@
+/**
+ ******************************************************************************
+ * @file    VL53L0X_class.cpp
+ * @author  IMG
+ * @version V0.0.1
+ * @date    28-June-2016
+ * @brief   Implementation file for the VL53L0X driver class
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+*/
+
+/* Includes */
+#include <stdlib.h>
+
+#include "VL53L0X.h"
+
+//#include "VL53L0X_api_core.h"
+//#include "VL53L0X_api_calibration.h"
+//#include "VL53L0X_api_strings.h"
+#include "VL53L0X_interrupt_threshold_settings.h"
+#include "VL53L0X_tuning.h"
+#include "VL53L0X_types.h"
+
+
+/****************** define for i2c configuration *******************************/
+
+#define TEMP_BUF_SIZE   64
+
+/** Maximum buffer size to be used in i2c */
+#define VL53L0X_MAX_I2C_XFER_SIZE   64 /* Maximum buffer size to be used in i2c */
+#define VL53L0X_I2C_USER_VAR         /* none but could be for a flag var to get/pass to mutex interruptible  return flags and try again */
+
+
+#define LOG_FUNCTION_START(fmt, ...) \
+	_LOG_FUNCTION_START(TRACE_MODULE_API, fmt, ##__VA_ARGS__)
+#define LOG_FUNCTION_END(status, ...) \
+	_LOG_FUNCTION_END(TRACE_MODULE_API, status, ##__VA_ARGS__)
+#define LOG_FUNCTION_END_FMT(status, fmt, ...) \
+	_LOG_FUNCTION_END_FMT(TRACE_MODULE_API, status, fmt, ##__VA_ARGS__)
+
+#ifdef VL53L0X_LOG_ENABLE
+#define trace_print(level, ...) trace_print_module_function(TRACE_MODULE_API, \
+	level, TRACE_FUNCTION_NONE, ##__VA_ARGS__)
+#endif
+
+#define REF_ARRAY_SPAD_0  0
+#define REF_ARRAY_SPAD_5  5
+#define REF_ARRAY_SPAD_10 10
+
+uint32_t refArrayQuadrants[4] = {REF_ARRAY_SPAD_10, REF_ARRAY_SPAD_5,
+                                 REF_ARRAY_SPAD_0, REF_ARRAY_SPAD_5
+                                };
+
+
+
+
+VL53L0X_Error VL53L0X::VL53L0X_device_read_strobe(VL53L0X_DEV dev)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t strobe;
+    uint32_t loop_nb;
+    LOG_FUNCTION_START("");
+
+    status |= VL53L0X_write_byte(dev, 0x83, 0x00);
+
+    /* polling
+     * use timeout to avoid deadlock*/
+    if (status == VL53L0X_ERROR_NONE) {
+        loop_nb = 0;
+        do {
+            status = VL53L0X_read_byte(dev, 0x83, &strobe);
+            if ((strobe != 0x00) || status != VL53L0X_ERROR_NONE) {
+                break;
+            }
+
+            loop_nb = loop_nb + 1;
+        } while (loop_nb < VL53L0X_DEFAULT_MAX_LOOP);
+
+        if (loop_nb >= VL53L0X_DEFAULT_MAX_LOOP) {
+            status = VL53L0X_ERROR_TIME_OUT;
+        }
+    }
+
+    status |= VL53L0X_write_byte(dev, 0x83, 0x01);
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_info_from_device(VL53L0X_DEV dev, uint8_t option)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t byte;
+    uint32_t tmp_dword;
+    uint8_t module_id;
+    uint8_t revision;
+    uint8_t reference_spad_count = 0;
+    uint8_t reference_spad_type = 0;
+    uint32_t part_uid_upper = 0;
+    uint32_t part_uid_lower = 0;
+    uint32_t offset_fixed1104_mm = 0;
+    int16_t offset_micro_meters = 0;
+    uint32_t dist_meas_tgt_fixed1104_mm = 400 << 4;
+    uint32_t dist_meas_fixed1104_400_mm = 0;
+    uint32_t signal_rate_meas_fixed1104_400_mm = 0;
+    char product_id[19];
+    char *product_id_tmp;
+    uint8_t read_data_from_device_done;
+    FixPoint1616_t signal_rate_meas_fixed400_mm_fix = 0;
+    uint8_t nvm_ref_good_spad_map[VL53L0X_REF_SPAD_BUFFER_SIZE];
+    int i;
+
+
+    LOG_FUNCTION_START("");
+
+    read_data_from_device_done = VL53L0X_GETDEVICESPECIFICPARAMETER(dev,
+                                 ReadDataFromDeviceDone);
+
+    /* This access is done only once after that a GetDeviceInfo or
+     * datainit is done*/
+    if (read_data_from_device_done != 7) {
+
+        status |= VL53L0X_write_byte(dev, 0x80, 0x01);
+        status |= VL53L0X_write_byte(dev, 0xFF, 0x01);
+        status |= VL53L0X_write_byte(dev, 0x00, 0x00);
+
+        status |= VL53L0X_write_byte(dev, 0xFF, 0x06);
+        status |= VL53L0X_read_byte(dev, 0x83, &byte);
+        status |= VL53L0X_write_byte(dev, 0x83, byte | 4);
+        status |= VL53L0X_write_byte(dev, 0xFF, 0x07);
+        status |= VL53L0X_write_byte(dev, 0x81, 0x01);
+
+        status |= VL53L0X_polling_delay(dev);
+
+        status |= VL53L0X_write_byte(dev, 0x80, 0x01);
+
+        if (((option & 1) == 1) &&
+                ((read_data_from_device_done & 1) == 0)) {
+            status |= VL53L0X_write_byte(dev, 0x94, 0x6b);
+            status |= VL53L0X_device_read_strobe(dev);
+            status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword);
+
+            reference_spad_count = (uint8_t)((tmp_dword >> 8) & 0x07f);
+            reference_spad_type  = (uint8_t)((tmp_dword >> 15) & 0x01);
+
+            status |= VL53L0X_write_byte(dev, 0x94, 0x24);
+            status |= VL53L0X_device_read_strobe(dev);
+            status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword);
+
+
+            nvm_ref_good_spad_map[0] = (uint8_t)((tmp_dword >> 24)
+                                                 & 0xff);
+            nvm_ref_good_spad_map[1] = (uint8_t)((tmp_dword >> 16)
+                                                 & 0xff);
+            nvm_ref_good_spad_map[2] = (uint8_t)((tmp_dword >> 8)
+                                                 & 0xff);
+            nvm_ref_good_spad_map[3] = (uint8_t)(tmp_dword & 0xff);
+
+            status |= VL53L0X_write_byte(dev, 0x94, 0x25);
+            status |= VL53L0X_device_read_strobe(dev);
+            status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword);
+
+            nvm_ref_good_spad_map[4] = (uint8_t)((tmp_dword >> 24)
+                                                 & 0xff);
+            nvm_ref_good_spad_map[5] = (uint8_t)((tmp_dword >> 16)
+                                                 & 0xff);
+        }
+
+        if (((option & 2) == 2) &&
+                ((read_data_from_device_done & 2) == 0)) {
+
+            status |= VL53L0X_write_byte(dev, 0x94, 0x02);
+            status |= VL53L0X_device_read_strobe(dev);
+            status |= VL53L0X_read_byte(dev, 0x90, &module_id);
+
+            status |= VL53L0X_write_byte(dev, 0x94, 0x7B);
+            status |= VL53L0X_device_read_strobe(dev);
+            status |= VL53L0X_read_byte(dev, 0x90, &revision);
+
+            status |= VL53L0X_write_byte(dev, 0x94, 0x77);
+            status |= VL53L0X_device_read_strobe(dev);
+            status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword);
+
+            product_id[0] = (char)((tmp_dword >> 25) & 0x07f);
+            product_id[1] = (char)((tmp_dword >> 18) & 0x07f);
+            product_id[2] = (char)((tmp_dword >> 11) & 0x07f);
+            product_id[3] = (char)((tmp_dword >> 4) & 0x07f);
+
+            byte = (uint8_t)((tmp_dword & 0x00f) << 3);
+
+            status |= VL53L0X_write_byte(dev, 0x94, 0x78);
+            status |= VL53L0X_device_read_strobe(dev);
+            status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword);
+
+            product_id[4] = (char)(byte +
+                                   ((tmp_dword >> 29) & 0x07f));
+            product_id[5] = (char)((tmp_dword >> 22) & 0x07f);
+            product_id[6] = (char)((tmp_dword >> 15) & 0x07f);
+            product_id[7] = (char)((tmp_dword >> 8) & 0x07f);
+            product_id[8] = (char)((tmp_dword >> 1) & 0x07f);
+
+            byte = (uint8_t)((tmp_dword & 0x001) << 6);
+
+            status |= VL53L0X_write_byte(dev, 0x94, 0x79);
+
+            status |= VL53L0X_device_read_strobe(dev);
+
+            status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword);
+
+            product_id[9] = (char)(byte +
+                                   ((tmp_dword >> 26) & 0x07f));
+            product_id[10] = (char)((tmp_dword >> 19) & 0x07f);
+            product_id[11] = (char)((tmp_dword >> 12) & 0x07f);
+            product_id[12] = (char)((tmp_dword >> 5) & 0x07f);
+
+            byte = (uint8_t)((tmp_dword & 0x01f) << 2);
+
+            status |= VL53L0X_write_byte(dev, 0x94, 0x7A);
+
+            status |= VL53L0X_device_read_strobe(dev);
+
+            status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword);
+
+            product_id[13] = (char)(byte +
+                                    ((tmp_dword >> 30) & 0x07f));
+            product_id[14] = (char)((tmp_dword >> 23) & 0x07f);
+            product_id[15] = (char)((tmp_dword >> 16) & 0x07f);
+            product_id[16] = (char)((tmp_dword >> 9) & 0x07f);
+            product_id[17] = (char)((tmp_dword >> 2) & 0x07f);
+            product_id[18] = '\0';
+
+        }
+
+        if (((option & 4) == 4) &&
+                ((read_data_from_device_done & 4) == 0)) {
+
+            status |= VL53L0X_write_byte(dev, 0x94, 0x7B);
+            status |= VL53L0X_device_read_strobe(dev);
+            status |= VL53L0X_read_dword(dev, 0x90, &part_uid_upper);
+
+            status |= VL53L0X_write_byte(dev, 0x94, 0x7C);
+            status |= VL53L0X_device_read_strobe(dev);
+            status |= VL53L0X_read_dword(dev, 0x90, &part_uid_lower);
+
+            status |= VL53L0X_write_byte(dev, 0x94, 0x73);
+            status |= VL53L0X_device_read_strobe(dev);
+            status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword);
+
+            signal_rate_meas_fixed1104_400_mm = (tmp_dword &
+                                                 0x0000000ff) << 8;
+
+            status |= VL53L0X_write_byte(dev, 0x94, 0x74);
+            status |= VL53L0X_device_read_strobe(dev);
+            status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword);
+
+            signal_rate_meas_fixed1104_400_mm |= ((tmp_dword &
+                                                   0xff000000) >> 24);
+
+            status |= VL53L0X_write_byte(dev, 0x94, 0x75);
+            status |= VL53L0X_device_read_strobe(dev);
+            status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword);
+
+            dist_meas_fixed1104_400_mm = (tmp_dword & 0x0000000ff)
+                                         << 8;
+
+            status |= VL53L0X_write_byte(dev, 0x94, 0x76);
+            status |= VL53L0X_device_read_strobe(dev);
+            status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword);
+
+            dist_meas_fixed1104_400_mm |= ((tmp_dword & 0xff000000)
+                                           >> 24);
+        }
+
+        status |= VL53L0X_write_byte(dev, 0x81, 0x00);
+        status |= VL53L0X_write_byte(dev, 0xFF, 0x06);
+        status |= VL53L0X_read_byte(dev, 0x83, &byte);
+        status |= VL53L0X_write_byte(dev, 0x83, byte & 0xfb);
+        status |= VL53L0X_write_byte(dev, 0xFF, 0x01);
+        status |= VL53L0X_write_byte(dev, 0x00, 0x01);
+
+        status |= VL53L0X_write_byte(dev, 0xFF, 0x00);
+        status |= VL53L0X_write_byte(dev, 0x80, 0x00);
+    }
+
+    if ((status == VL53L0X_ERROR_NONE) &&
+            (read_data_from_device_done != 7)) {
+        /* Assign to variable if status is ok */
+        if (((option & 1) == 1) &&
+                ((read_data_from_device_done & 1) == 0)) {
+            VL53L0X_SETDEVICESPECIFICPARAMETER(dev,
+                                               ReferenceSpadCount, reference_spad_count);
+
+            VL53L0X_SETDEVICESPECIFICPARAMETER(dev,
+                                               ReferenceSpadType, reference_spad_type);
+
+            for (i = 0; i < VL53L0X_REF_SPAD_BUFFER_SIZE; i++) {
+                dev->Data.SpadData.RefGoodSpadMap[i] =
+                    nvm_ref_good_spad_map[i];
+            }
+        }
+
+        if (((option & 2) == 2) &&
+                ((read_data_from_device_done & 2) == 0)) {
+            VL53L0X_SETDEVICESPECIFICPARAMETER(dev,
+                                               ModuleId, module_id);
+
+            VL53L0X_SETDEVICESPECIFICPARAMETER(dev,
+                                               Revision, revision);
+
+            product_id_tmp = VL53L0X_GETDEVICESPECIFICPARAMETER(dev,
+                             ProductId);
+            VL53L0X_COPYSTRING(product_id_tmp, product_id);
+
+        }
+
+        if (((option & 4) == 4) &&
+                ((read_data_from_device_done & 4) == 0)) {
+            VL53L0X_SETDEVICESPECIFICPARAMETER(dev,
+                                               PartUIDUpper, part_uid_upper);
+
+            VL53L0X_SETDEVICESPECIFICPARAMETER(dev,
+                                               PartUIDLower, part_uid_lower);
+
+            signal_rate_meas_fixed400_mm_fix =
+                VL53L0X_FIXPOINT97TOFIXPOINT1616(
+                    signal_rate_meas_fixed1104_400_mm);
+
+            VL53L0X_SETDEVICESPECIFICPARAMETER(dev,
+                                               SignalRateMeasFixed400mm,
+                                               signal_rate_meas_fixed400_mm_fix);
+
+            offset_micro_meters = 0;
+            if (dist_meas_fixed1104_400_mm != 0) {
+                offset_fixed1104_mm =
+                    dist_meas_fixed1104_400_mm -
+                    dist_meas_tgt_fixed1104_mm;
+                offset_micro_meters = (offset_fixed1104_mm
+                                       * 1000) >> 4;
+                offset_micro_meters *= -1;
+            }
+
+            PALDevDataSet(dev,
+                          Part2PartOffsetAdjustmentNVMMicroMeter,
+                          offset_micro_meters);
+        }
+        byte = (uint8_t)(read_data_from_device_done | option);
+        VL53L0X_SETDEVICESPECIFICPARAMETER(dev, ReadDataFromDeviceDone,
+                                           byte);
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::wrapped_VL53L0X_get_offset_calibration_data_micro_meter(VL53L0X_DEV dev,
+        int32_t *p_offset_calibration_data_micro_meter)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint16_t range_offset_register;
+    int16_t c_max_offset = 2047;
+    int16_t c_offset_range = 4096;
+
+    /* Note that offset has 10.2 format */
+
+    status = VL53L0X_read_word(dev,
+                               VL53L0X_REG_ALGO_PART_TO_PART_RANGE_OFFSET_MM,
+                               &range_offset_register);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        range_offset_register = (range_offset_register & 0x0fff);
+
+        /* Apply 12 bit 2's compliment conversion */
+        if (range_offset_register > c_max_offset) {
+            *p_offset_calibration_data_micro_meter =
+                (int16_t)(range_offset_register - c_offset_range)
+                * 250;
+        } else {
+            *p_offset_calibration_data_micro_meter =
+                (int16_t)range_offset_register * 250;
+        }
+
+    }
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_offset_calibration_data_micro_meter(VL53L0X_DEV dev,
+        int32_t *p_offset_calibration_data_micro_meter)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    LOG_FUNCTION_START("");
+
+    status = wrapped_VL53L0X_get_offset_calibration_data_micro_meter(dev,
+             p_offset_calibration_data_micro_meter);
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::wrapped_VL53L0X_set_offset_calibration_data_micro_meter(VL53L0X_DEV dev,
+        int32_t offset_calibration_data_micro_meter)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    int32_t c_max_offset_micro_meter = 511000;
+    int32_t c_min_offset_micro_meter = -512000;
+    int16_t c_offset_range = 4096;
+    uint32_t encoded_offset_val;
+
+    LOG_FUNCTION_START("");
+
+    if (offset_calibration_data_micro_meter > c_max_offset_micro_meter) {
+        offset_calibration_data_micro_meter = c_max_offset_micro_meter;
+    } else {
+        if (offset_calibration_data_micro_meter < c_min_offset_micro_meter) {
+            offset_calibration_data_micro_meter = c_min_offset_micro_meter;
+        }
+    }
+
+    /* The offset register is 10.2 format and units are mm
+     * therefore conversion is applied by a division of
+     * 250.
+     */
+    if (offset_calibration_data_micro_meter >= 0) {
+        encoded_offset_val =
+            offset_calibration_data_micro_meter / 250;
+    } else {
+        encoded_offset_val =
+            c_offset_range +
+            offset_calibration_data_micro_meter / 250;
+    }
+
+    status = VL53L0X_write_word(dev,
+                                VL53L0X_REG_ALGO_PART_TO_PART_RANGE_OFFSET_MM,
+                                encoded_offset_val);
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_set_offset_calibration_data_micro_meter(VL53L0X_DEV dev,
+        int32_t offset_calibration_data_micro_meter)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    LOG_FUNCTION_START("");
+
+    status = wrapped_VL53L0X_set_offset_calibration_data_micro_meter(dev,
+             offset_calibration_data_micro_meter);
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_apply_offset_adjustment(VL53L0X_DEV dev)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    int32_t corrected_offset_micro_meters;
+    int32_t current_offset_micro_meters;
+
+    /* if we run on this function we can read all the NVM info
+     * used by the API */
+    status = VL53L0X_get_info_from_device(dev, 7);
+
+    /* Read back current device offset */
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_get_offset_calibration_data_micro_meter(dev,
+                 &current_offset_micro_meters);
+    }
+
+    /* Apply Offset Adjustment derived from 400mm measurements */
+    if (status == VL53L0X_ERROR_NONE) {
+
+        /* Store initial device offset */
+        PALDevDataSet(dev, Part2PartOffsetNVMMicroMeter,
+                      current_offset_micro_meters);
+
+        corrected_offset_micro_meters = current_offset_micro_meters +
+                                        (int32_t)PALDevDataGet(dev,
+                                                Part2PartOffsetAdjustmentNVMMicroMeter);
+
+        status = VL53L0X_set_offset_calibration_data_micro_meter(dev,
+                 corrected_offset_micro_meters);
+
+        /* store current, adjusted offset */
+        if (status == VL53L0X_ERROR_NONE) {
+            VL53L0X_SETPARAMETERFIELD(dev, RangeOffsetMicroMeters,
+                                      corrected_offset_micro_meters);
+        }
+    }
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_device_mode(VL53L0X_DEV dev,
+        VL53L0X_DeviceModes *p_device_mode)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    LOG_FUNCTION_START("");
+
+    VL53L0X_GETPARAMETERFIELD(dev, DeviceMode, *p_device_mode);
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_inter_measurement_period_milli_seconds(VL53L0X_DEV dev,
+        uint32_t *p_inter_measurement_period_milli_seconds)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint16_t osc_calibrate_val;
+    uint32_t im_period_milli_seconds;
+
+    LOG_FUNCTION_START("");
+
+    status = VL53L0X_read_word(dev, VL53L0X_REG_OSC_CALIBRATE_VAL,
+                               &osc_calibrate_val);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_read_dword(dev,
+                                    VL53L0X_REG_SYSTEM_INTERMEASUREMENT_PERIOD,
+                                    &im_period_milli_seconds);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        if (osc_calibrate_val != 0) {
+            *p_inter_measurement_period_milli_seconds =
+                im_period_milli_seconds / osc_calibrate_val;
+        }
+        VL53L0X_SETPARAMETERFIELD(dev,
+                                  InterMeasurementPeriodMilliSeconds,
+                                  *p_inter_measurement_period_milli_seconds);
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_x_talk_compensation_rate_mega_cps(VL53L0X_DEV dev,
+        FixPoint1616_t *p_xtalk_compensation_rate_mega_cps)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint16_t value;
+    FixPoint1616_t temp_fix1616;
+
+    LOG_FUNCTION_START("");
+
+    status = VL53L0X_read_word(dev,
+                               VL53L0X_REG_CROSSTALK_COMPENSATION_PEAK_RATE_MCPS, (uint16_t *)&value);
+    if (status == VL53L0X_ERROR_NONE) {
+        if (value == 0) {
+            /* the Xtalk is disabled return value from memory */
+            VL53L0X_GETPARAMETERFIELD(dev,
+                                      XTalkCompensationRateMegaCps, temp_fix1616);
+            *p_xtalk_compensation_rate_mega_cps = temp_fix1616;
+            VL53L0X_SETPARAMETERFIELD(dev, XTalkCompensationEnable,
+                                      0);
+        } else {
+            temp_fix1616 = VL53L0X_FIXPOINT313TOFIXPOINT1616(value);
+            *p_xtalk_compensation_rate_mega_cps = temp_fix1616;
+            VL53L0X_SETPARAMETERFIELD(dev,
+                                      XTalkCompensationRateMegaCps, temp_fix1616);
+            VL53L0X_SETPARAMETERFIELD(dev, XTalkCompensationEnable,
+                                      1);
+        }
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_limit_check_value(VL53L0X_DEV dev, uint16_t limit_check_id,
+        FixPoint1616_t *p_limit_check_value)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t enable_zero_value = 0;
+    uint16_t temp16;
+    FixPoint1616_t temp_fix1616;
+
+    LOG_FUNCTION_START("");
+
+    switch (limit_check_id) {
+
+        case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE:
+            /* internal computation: */
+            VL53L0X_GETARRAYPARAMETERFIELD(dev, LimitChecksValue,
+                                           VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, temp_fix1616);
+            enable_zero_value = 0;
+            break;
+
+        case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
+            status = VL53L0X_read_word(dev,
+                                       VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT,
+                                       &temp16);
+            if (status == VL53L0X_ERROR_NONE) {
+                temp_fix1616 = VL53L0X_FIXPOINT97TOFIXPOINT1616(temp16);
+            }
+
+
+            enable_zero_value = 1;
+            break;
+
+        case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP:
+            /* internal computation: */
+            VL53L0X_GETARRAYPARAMETERFIELD(dev, LimitChecksValue,
+                                           VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, temp_fix1616);
+            enable_zero_value = 0;
+            break;
+
+        case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD:
+            /* internal computation: */
+            VL53L0X_GETARRAYPARAMETERFIELD(dev, LimitChecksValue,
+                                           VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, temp_fix1616);
+            enable_zero_value = 0;
+            break;
+
+        case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC:
+        case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE:
+            status = VL53L0X_read_word(dev,
+                                       VL53L0X_REG_PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT,
+                                       &temp16);
+            if (status == VL53L0X_ERROR_NONE) {
+                temp_fix1616 = VL53L0X_FIXPOINT97TOFIXPOINT1616(temp16);
+            }
+
+
+            enable_zero_value = 0;
+            break;
+
+        default:
+            status = VL53L0X_ERROR_INVALID_PARAMS;
+
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+
+        if (enable_zero_value == 1) {
+
+            if (temp_fix1616 == 0) {
+                /* disabled: return value from memory */
+                VL53L0X_GETARRAYPARAMETERFIELD(dev,
+                                               LimitChecksValue, limit_check_id,
+                                               temp_fix1616);
+                *p_limit_check_value = temp_fix1616;
+                VL53L0X_SETARRAYPARAMETERFIELD(dev,
+                                               LimitChecksEnable, limit_check_id, 0);
+            } else {
+                *p_limit_check_value = temp_fix1616;
+                VL53L0X_SETARRAYPARAMETERFIELD(dev,
+                                               LimitChecksValue, limit_check_id,
+                                               temp_fix1616);
+                VL53L0X_SETARRAYPARAMETERFIELD(dev,
+                                               LimitChecksEnable, limit_check_id, 1);
+            }
+        } else {
+            *p_limit_check_value = temp_fix1616;
+        }
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_limit_check_enable(VL53L0X_DEV dev, uint16_t limit_check_id,
+        uint8_t *p_limit_check_enable)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t temp8;
+
+    LOG_FUNCTION_START("");
+
+    if (limit_check_id >= VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS) {
+        status = VL53L0X_ERROR_INVALID_PARAMS;
+        *p_limit_check_enable = 0;
+    } else {
+        VL53L0X_GETARRAYPARAMETERFIELD(dev, LimitChecksEnable,
+                                       limit_check_id, temp8);
+        *p_limit_check_enable = temp8;
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_wrap_around_check_enable(VL53L0X_DEV dev,
+        uint8_t *p_wrap_around_check_enable)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t data;
+
+    LOG_FUNCTION_START("");
+
+    status = VL53L0X_read_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, &data);
+    if (status == VL53L0X_ERROR_NONE) {
+        PALDevDataSet(dev, SequenceConfig, data);
+        if (data & (0x01 << 7)) {
+            *p_wrap_around_check_enable = 0x01;
+        } else {
+            *p_wrap_around_check_enable = 0x00;
+        }
+    }
+    if (status == VL53L0X_ERROR_NONE) {
+        VL53L0X_SETPARAMETERFIELD(dev, WrapAroundCheckEnable,
+                                  *p_wrap_around_check_enable);
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::sequence_step_enabled(VL53L0X_DEV dev,
+        VL53L0X_SequenceStepId sequence_step_id, uint8_t sequence_config,
+        uint8_t *p_sequence_step_enabled)
+{
+    VL53L0X_Error Status = VL53L0X_ERROR_NONE;
+    *p_sequence_step_enabled = 0;
+    LOG_FUNCTION_START("");
+
+    switch (sequence_step_id) {
+        case VL53L0X_SEQUENCESTEP_TCC:
+            *p_sequence_step_enabled = (sequence_config & 0x10) >> 4;
+            break;
+        case VL53L0X_SEQUENCESTEP_DSS:
+            *p_sequence_step_enabled = (sequence_config & 0x08) >> 3;
+            break;
+        case VL53L0X_SEQUENCESTEP_MSRC:
+            *p_sequence_step_enabled = (sequence_config & 0x04) >> 2;
+            break;
+        case VL53L0X_SEQUENCESTEP_PRE_RANGE:
+            *p_sequence_step_enabled = (sequence_config & 0x40) >> 6;
+            break;
+        case VL53L0X_SEQUENCESTEP_FINAL_RANGE:
+            *p_sequence_step_enabled = (sequence_config & 0x80) >> 7;
+            break;
+        default:
+            Status = VL53L0X_ERROR_INVALID_PARAMS;
+    }
+
+    LOG_FUNCTION_END(status);
+    return Status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_sequence_step_enables(VL53L0X_DEV dev,
+        VL53L0X_SchedulerSequenceSteps_t *p_scheduler_sequence_steps)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t sequence_config = 0;
+    LOG_FUNCTION_START("");
+
+    status = VL53L0X_read_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
+                               &sequence_config);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = sequence_step_enabled(dev,
+                                       VL53L0X_SEQUENCESTEP_TCC, sequence_config,
+                                       &p_scheduler_sequence_steps->TccOn);
+    }
+    if (status == VL53L0X_ERROR_NONE) {
+        status = sequence_step_enabled(dev,
+                                       VL53L0X_SEQUENCESTEP_DSS, sequence_config,
+                                       &p_scheduler_sequence_steps->DssOn);
+    }
+    if (status == VL53L0X_ERROR_NONE) {
+        status = sequence_step_enabled(dev,
+                                       VL53L0X_SEQUENCESTEP_MSRC, sequence_config,
+                                       &p_scheduler_sequence_steps->MsrcOn);
+    }
+    if (status == VL53L0X_ERROR_NONE) {
+        status = sequence_step_enabled(dev,
+                                       VL53L0X_SEQUENCESTEP_PRE_RANGE, sequence_config,
+                                       &p_scheduler_sequence_steps->PreRangeOn);
+    }
+    if (status == VL53L0X_ERROR_NONE) {
+        status = sequence_step_enabled(dev,
+                                       VL53L0X_SEQUENCESTEP_FINAL_RANGE, sequence_config,
+                                       &p_scheduler_sequence_steps->FinalRangeOn);
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+uint8_t VL53L0X::VL53L0X_decode_vcsel_period(uint8_t vcsel_period_reg)
+{
+    /*!
+     * Converts the encoded VCSEL period register value into the real
+     * period in PLL clocks
+     */
+
+    uint8_t vcsel_period_pclks = 0;
+
+    vcsel_period_pclks = (vcsel_period_reg + 1) << 1;
+
+    return vcsel_period_pclks;
+}
+
+uint8_t VL53L0X::lv53l0x_encode_vcsel_period(uint8_t vcsel_period_pclks)
+{
+    /*!
+     * Converts the encoded VCSEL period register value into the real period
+     * in PLL clocks
+     */
+
+    uint8_t vcsel_period_reg = 0;
+
+    vcsel_period_reg = (vcsel_period_pclks >> 1) - 1;
+
+    return vcsel_period_reg;
+}
+
+
+VL53L0X_Error VL53L0X::wrapped_VL53L0X_set_vcsel_pulse_period(VL53L0X_DEV dev,
+        VL53L0X_VcselPeriod vcsel_period_type, uint8_t vcsel_pulse_period_pclk)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t vcsel_period_reg;
+    uint8_t min_pre_vcsel_period_pclk = 12;
+    uint8_t max_pre_vcsel_period_pclk = 18;
+    uint8_t min_final_vcsel_period_pclk = 8;
+    uint8_t max_final_vcsel_period_pclk = 14;
+    uint32_t measurement_timing_budget_micro_seconds;
+    uint32_t final_range_timeout_micro_seconds;
+    uint32_t pre_range_timeout_micro_seconds;
+    uint32_t msrc_timeout_micro_seconds;
+    uint8_t phase_cal_int = 0;
+
+    /* Check if valid clock period requested */
+
+    if ((vcsel_pulse_period_pclk % 2) != 0) {
+        /* Value must be an even number */
+        status = VL53L0X_ERROR_INVALID_PARAMS;
+    } else if (vcsel_period_type == VL53L0X_VCSEL_PERIOD_PRE_RANGE &&
+               (vcsel_pulse_period_pclk < min_pre_vcsel_period_pclk ||
+                vcsel_pulse_period_pclk > max_pre_vcsel_period_pclk)) {
+        status = VL53L0X_ERROR_INVALID_PARAMS;
+    } else if (vcsel_period_type == VL53L0X_VCSEL_PERIOD_FINAL_RANGE &&
+               (vcsel_pulse_period_pclk < min_final_vcsel_period_pclk ||
+                vcsel_pulse_period_pclk > max_final_vcsel_period_pclk)) {
+
+        status = VL53L0X_ERROR_INVALID_PARAMS;
+    }
+
+    /* Apply specific settings for the requested clock period */
+
+    if (status != VL53L0X_ERROR_NONE) {
+        return status;
+    }
+
+
+    if (vcsel_period_type == VL53L0X_VCSEL_PERIOD_PRE_RANGE) {
+
+        /* Set phase check limits */
+        if (vcsel_pulse_period_pclk == 12) {
+
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH,
+                                        0x18);
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW,
+                                        0x08);
+        } else if (vcsel_pulse_period_pclk == 14) {
+
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH,
+                                        0x30);
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW,
+                                        0x08);
+        } else if (vcsel_pulse_period_pclk == 16) {
+
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH,
+                                        0x40);
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW,
+                                        0x08);
+        } else if (vcsel_pulse_period_pclk == 18) {
+
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH,
+                                        0x50);
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW,
+                                        0x08);
+        }
+    } else if (vcsel_period_type == VL53L0X_VCSEL_PERIOD_FINAL_RANGE) {
+
+        if (vcsel_pulse_period_pclk == 8) {
+
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH,
+                                        0x10);
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW,
+                                        0x08);
+
+            status |= VL53L0X_write_byte(dev,
+                                         VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x02);
+            status |= VL53L0X_write_byte(dev,
+                                         VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x0C);
+
+            status |= VL53L0X_write_byte(dev, 0xff, 0x01);
+            status |= VL53L0X_write_byte(dev,
+                                         VL53L0X_REG_ALGO_PHASECAL_LIM,
+                                         0x30);
+            status |= VL53L0X_write_byte(dev, 0xff, 0x00);
+        } else if (vcsel_pulse_period_pclk == 10) {
+
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH,
+                                        0x28);
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW,
+                                        0x08);
+
+            status |= VL53L0X_write_byte(dev,
+                                         VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x03);
+            status |= VL53L0X_write_byte(dev,
+                                         VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x09);
+
+            status |= VL53L0X_write_byte(dev, 0xff, 0x01);
+            status |= VL53L0X_write_byte(dev,
+                                         VL53L0X_REG_ALGO_PHASECAL_LIM,
+                                         0x20);
+            status |= VL53L0X_write_byte(dev, 0xff, 0x00);
+        } else if (vcsel_pulse_period_pclk == 12) {
+
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH,
+                                        0x38);
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW,
+                                        0x08);
+
+            status |= VL53L0X_write_byte(dev,
+                                         VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x03);
+            status |= VL53L0X_write_byte(dev,
+                                         VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x08);
+
+            status |= VL53L0X_write_byte(dev, 0xff, 0x01);
+            status |= VL53L0X_write_byte(dev,
+                                         VL53L0X_REG_ALGO_PHASECAL_LIM,
+                                         0x20);
+            status |= VL53L0X_write_byte(dev, 0xff, 0x00);
+        } else if (vcsel_pulse_period_pclk == 14) {
+
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH,
+                                        0x048);
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW,
+                                        0x08);
+
+            status |= VL53L0X_write_byte(dev,
+                                         VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x03);
+            status |= VL53L0X_write_byte(dev,
+                                         VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x07);
+
+            status |= VL53L0X_write_byte(dev, 0xff, 0x01);
+            status |= VL53L0X_write_byte(dev,
+                                         VL53L0X_REG_ALGO_PHASECAL_LIM,
+                                         0x20);
+            status |= VL53L0X_write_byte(dev, 0xff, 0x00);
+        }
+    }
+
+
+    /* Re-calculate and apply timeouts, in macro periods */
+
+    if (status == VL53L0X_ERROR_NONE) {
+        vcsel_period_reg = lv53l0x_encode_vcsel_period((uint8_t)
+                           vcsel_pulse_period_pclk);
+
+        /* When the VCSEL period for the pre or final range is changed,
+        * the corresponding timeout must be read from the device using
+        * the current VCSEL period, then the new VCSEL period can be
+        * applied. The timeout then must be written back to the device
+        * using the new VCSEL period.
+        *
+        * For the MSRC timeout, the same applies - this timeout being
+        * dependant on the pre-range vcsel period.
+        */
+        switch (vcsel_period_type) {
+            case VL53L0X_VCSEL_PERIOD_PRE_RANGE:
+                status = get_sequence_step_timeout(dev,
+                                                   VL53L0X_SEQUENCESTEP_PRE_RANGE,
+                                                   &pre_range_timeout_micro_seconds);
+
+                if (status == VL53L0X_ERROR_NONE)
+                    status = get_sequence_step_timeout(dev,
+                                                       VL53L0X_SEQUENCESTEP_MSRC,
+                                                       &msrc_timeout_micro_seconds);
+
+                if (status == VL53L0X_ERROR_NONE)
+                    status = VL53L0X_write_byte(dev,
+                                                VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD,
+                                                vcsel_period_reg);
+
+
+                if (status == VL53L0X_ERROR_NONE)
+                    status = set_sequence_step_timeout(dev,
+                                                       VL53L0X_SEQUENCESTEP_PRE_RANGE,
+                                                       pre_range_timeout_micro_seconds);
+
+
+                if (status == VL53L0X_ERROR_NONE)
+                    status = set_sequence_step_timeout(dev,
+                                                       VL53L0X_SEQUENCESTEP_MSRC,
+                                                       msrc_timeout_micro_seconds);
+
+                VL53L0X_SETDEVICESPECIFICPARAMETER(
+                    dev,
+                    PreRangeVcselPulsePeriod,
+                    vcsel_pulse_period_pclk);
+                break;
+            case VL53L0X_VCSEL_PERIOD_FINAL_RANGE:
+                status = get_sequence_step_timeout(dev,
+                                                   VL53L0X_SEQUENCESTEP_FINAL_RANGE,
+                                                   &final_range_timeout_micro_seconds);
+
+                if (status == VL53L0X_ERROR_NONE)
+                    status = VL53L0X_write_byte(dev,
+                                                VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD,
+                                                vcsel_period_reg);
+
+
+                if (status == VL53L0X_ERROR_NONE)
+                    status = set_sequence_step_timeout(dev,
+                                                       VL53L0X_SEQUENCESTEP_FINAL_RANGE,
+                                                       final_range_timeout_micro_seconds);
+
+                VL53L0X_SETDEVICESPECIFICPARAMETER(
+                    dev,
+                    FinalRangeVcselPulsePeriod,
+                    vcsel_pulse_period_pclk);
+                break;
+            default:
+                status = VL53L0X_ERROR_INVALID_PARAMS;
+        }
+    }
+
+    /* Finally, the timing budget must be re-applied */
+    if (status == VL53L0X_ERROR_NONE) {
+        VL53L0X_GETPARAMETERFIELD(dev,
+                                  MeasurementTimingBudgetMicroSeconds,
+                                  measurement_timing_budget_micro_seconds);
+
+        status = VL53L0X_set_measurement_timing_budget_micro_seconds(dev,
+                 measurement_timing_budget_micro_seconds);
+    }
+
+    /* Perform the phase calibration. This is needed after changing on
+     * vcsel period.
+     * get_data_enable = 0, restore_config = 1 */
+    if (status == VL53L0X_ERROR_NONE)
+        status = VL53L0X_perform_phase_calibration(
+                     dev, &phase_cal_int, 0, 1);
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_set_vcsel_pulse_period(VL53L0X_DEV dev,
+        VL53L0X_VcselPeriod vcsel_period_type, uint8_t vcsel_pulse_period)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    LOG_FUNCTION_START("");
+
+    status = wrapped_VL53L0X_set_vcsel_pulse_period(dev, vcsel_period_type,
+             vcsel_pulse_period);
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::wrapped_VL53L0X_get_vcsel_pulse_period(VL53L0X_DEV dev,
+        VL53L0X_VcselPeriod vcsel_period_type, uint8_t *p_vcsel_pulse_period_pclk)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t vcsel_period_reg;
+
+    switch (vcsel_period_type) {
+        case VL53L0X_VCSEL_PERIOD_PRE_RANGE:
+            status = VL53L0X_read_byte(dev,
+                                       VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD,
+                                       &vcsel_period_reg);
+            break;
+        case VL53L0X_VCSEL_PERIOD_FINAL_RANGE:
+            status = VL53L0X_read_byte(dev,
+                                       VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD,
+                                       &vcsel_period_reg);
+            break;
+        default:
+            status = VL53L0X_ERROR_INVALID_PARAMS;
+    }
+
+    if (status == VL53L0X_ERROR_NONE)
+        *p_vcsel_pulse_period_pclk =
+            VL53L0X_decode_vcsel_period(vcsel_period_reg);
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_vcsel_pulse_period(VL53L0X_DEV dev,
+        VL53L0X_VcselPeriod vcsel_period_type, uint8_t *p_vcsel_pulse_period_pclk)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    LOG_FUNCTION_START("");
+
+    status = wrapped_VL53L0X_get_vcsel_pulse_period(dev, vcsel_period_type,
+             p_vcsel_pulse_period_pclk);
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+uint32_t VL53L0X::VL53L0X_decode_timeout(uint16_t encoded_timeout)
+{
+    /*!
+     * Decode 16-bit timeout register value - format (LSByte * 2^MSByte) + 1
+     */
+
+    uint32_t timeout_macro_clks = 0;
+
+    timeout_macro_clks = ((uint32_t)(encoded_timeout & 0x00FF)
+                          << (uint32_t)((encoded_timeout & 0xFF00) >> 8)) + 1;
+
+    return timeout_macro_clks;
+}
+
+uint32_t VL53L0X::VL53L0X_calc_macro_period_ps(VL53L0X_DEV dev, uint8_t vcsel_period_pclks)
+{
+    uint64_t pll_period_ps;
+    uint32_t macro_period_vclks;
+    uint32_t macro_period_ps;
+
+    LOG_FUNCTION_START("");
+
+    /* The above calculation will produce rounding errors,
+       therefore set fixed value
+    */
+    pll_period_ps = 1655;
+
+    macro_period_vclks = 2304;
+    macro_period_ps = (uint32_t)(macro_period_vclks
+                                 * vcsel_period_pclks * pll_period_ps);
+
+    LOG_FUNCTION_END("");
+    return macro_period_ps;
+}
+
+/* To convert register value into us */
+uint32_t VL53L0X::VL53L0X_calc_timeout_us(VL53L0X_DEV dev,
+        uint16_t timeout_period_mclks,
+        uint8_t vcsel_period_pclks)
+{
+    uint32_t macro_period_ps;
+    uint32_t macro_period_ns;
+    uint32_t actual_timeout_period_us = 0;
+
+    macro_period_ps = VL53L0X_calc_macro_period_ps(dev, vcsel_period_pclks);
+    macro_period_ns = (macro_period_ps + 500) / 1000;
+
+    actual_timeout_period_us =
+        ((timeout_period_mclks * macro_period_ns) + 500) / 1000;
+
+    return actual_timeout_period_us;
+}
+
+VL53L0X_Error VL53L0X::get_sequence_step_timeout(VL53L0X_DEV dev,
+        VL53L0X_SequenceStepId sequence_step_id,
+        uint32_t *p_time_out_micro_secs)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t current_vcsel_pulse_period_p_clk;
+    uint8_t encoded_time_out_byte = 0;
+    uint32_t timeout_micro_seconds = 0;
+    uint16_t pre_range_encoded_time_out = 0;
+    uint16_t msrc_time_out_m_clks;
+    uint16_t pre_range_time_out_m_clks;
+    uint16_t final_range_time_out_m_clks = 0;
+    uint16_t final_range_encoded_time_out;
+    VL53L0X_SchedulerSequenceSteps_t scheduler_sequence_steps;
+
+    if ((sequence_step_id == VL53L0X_SEQUENCESTEP_TCC)	 ||
+            (sequence_step_id == VL53L0X_SEQUENCESTEP_DSS)	 ||
+            (sequence_step_id == VL53L0X_SEQUENCESTEP_MSRC)) {
+
+        status = VL53L0X_get_vcsel_pulse_period(dev,
+                                                VL53L0X_VCSEL_PERIOD_PRE_RANGE,
+                                                &current_vcsel_pulse_period_p_clk);
+        if (status == VL53L0X_ERROR_NONE) {
+            status = VL53L0X_read_byte(dev,
+                                       VL53L0X_REG_MSRC_CONFIG_TIMEOUT_MACROP,
+                                       &encoded_time_out_byte);
+        }
+        msrc_time_out_m_clks = VL53L0X_decode_timeout(encoded_time_out_byte);
+
+        timeout_micro_seconds = VL53L0X_calc_timeout_us(dev,
+                                msrc_time_out_m_clks,
+                                current_vcsel_pulse_period_p_clk);
+    } else if (sequence_step_id == VL53L0X_SEQUENCESTEP_PRE_RANGE) {
+        /* Retrieve PRE-RANGE VCSEL Period */
+        status = VL53L0X_get_vcsel_pulse_period(dev,
+                                                VL53L0X_VCSEL_PERIOD_PRE_RANGE,
+                                                &current_vcsel_pulse_period_p_clk);
+
+        /* Retrieve PRE-RANGE Timeout in Macro periods (MCLKS) */
+        if (status == VL53L0X_ERROR_NONE) {
+
+            /* Retrieve PRE-RANGE VCSEL Period */
+            status = VL53L0X_get_vcsel_pulse_period(dev,
+                                                    VL53L0X_VCSEL_PERIOD_PRE_RANGE,
+                                                    &current_vcsel_pulse_period_p_clk);
+
+            if (status == VL53L0X_ERROR_NONE) {
+                status = VL53L0X_read_word(dev,
+                                           VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI,
+                                           &pre_range_encoded_time_out);
+            }
+
+            pre_range_time_out_m_clks = VL53L0X_decode_timeout(
+                                            pre_range_encoded_time_out);
+
+            timeout_micro_seconds = VL53L0X_calc_timeout_us(dev,
+                                    pre_range_time_out_m_clks,
+                                    current_vcsel_pulse_period_p_clk);
+        }
+    } else if (sequence_step_id == VL53L0X_SEQUENCESTEP_FINAL_RANGE) {
+
+        VL53L0X_get_sequence_step_enables(dev, &scheduler_sequence_steps);
+        pre_range_time_out_m_clks = 0;
+
+        if (scheduler_sequence_steps.PreRangeOn) {
+            /* Retrieve PRE-RANGE VCSEL Period */
+            status = VL53L0X_get_vcsel_pulse_period(dev,
+                                                    VL53L0X_VCSEL_PERIOD_PRE_RANGE,
+                                                    &current_vcsel_pulse_period_p_clk);
+
+            /* Retrieve PRE-RANGE Timeout in Macro periods
+             * (MCLKS) */
+            if (status == VL53L0X_ERROR_NONE) {
+                status = VL53L0X_read_word(dev,
+                                           VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI,
+                                           &pre_range_encoded_time_out);
+                pre_range_time_out_m_clks = VL53L0X_decode_timeout(
+                                                pre_range_encoded_time_out);
+            }
+        }
+
+        if (status == VL53L0X_ERROR_NONE) {
+            /* Retrieve FINAL-RANGE VCSEL Period */
+            status = VL53L0X_get_vcsel_pulse_period(dev,
+                                                    VL53L0X_VCSEL_PERIOD_FINAL_RANGE,
+                                                    &current_vcsel_pulse_period_p_clk);
+        }
+
+        /* Retrieve FINAL-RANGE Timeout in Macro periods (MCLKS) */
+        if (status == VL53L0X_ERROR_NONE) {
+            status = VL53L0X_read_word(dev,
+                                       VL53L0X_REG_FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI,
+                                       &final_range_encoded_time_out);
+            final_range_time_out_m_clks = VL53L0X_decode_timeout(
+                                              final_range_encoded_time_out);
+        }
+
+        final_range_time_out_m_clks -= pre_range_time_out_m_clks;
+        timeout_micro_seconds = VL53L0X_calc_timeout_us(dev,
+                                final_range_time_out_m_clks,
+                                current_vcsel_pulse_period_p_clk);
+    }
+
+    *p_time_out_micro_secs = timeout_micro_seconds;
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::wrapped_VL53L0X_get_measurement_timing_budget_micro_seconds(VL53L0X_DEV dev,
+        uint32_t *p_measurement_timing_budget_micro_seconds)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    VL53L0X_SchedulerSequenceSteps_t scheduler_sequence_steps;
+    uint32_t final_range_timeout_micro_seconds;
+    uint32_t msrc_dcc_tcc_timeout_micro_seconds	= 2000;
+    uint32_t start_overhead_micro_seconds		= 1910;
+    uint32_t end_overhead_micro_seconds		= 960;
+    uint32_t msrc_overhead_micro_seconds		= 660;
+    uint32_t tcc_overhead_micro_seconds		= 590;
+    uint32_t dss_overhead_micro_seconds		= 690;
+    uint32_t pre_range_overhead_micro_seconds	= 660;
+    uint32_t final_range_overhead_micro_seconds = 550;
+    uint32_t pre_range_timeout_micro_seconds	= 0;
+
+    LOG_FUNCTION_START("");
+
+    /* Start and end overhead times always present */
+    *p_measurement_timing_budget_micro_seconds
+        = start_overhead_micro_seconds + end_overhead_micro_seconds;
+
+    status = VL53L0X_get_sequence_step_enables(dev, &scheduler_sequence_steps);
+
+    if (status != VL53L0X_ERROR_NONE) {
+        LOG_FUNCTION_END(status);
+        return status;
+    }
+
+
+    if (scheduler_sequence_steps.TccOn  ||
+            scheduler_sequence_steps.MsrcOn ||
+            scheduler_sequence_steps.DssOn) {
+
+        status = get_sequence_step_timeout(dev,
+                                           VL53L0X_SEQUENCESTEP_MSRC,
+                                           &msrc_dcc_tcc_timeout_micro_seconds);
+
+        if (status == VL53L0X_ERROR_NONE) {
+            if (scheduler_sequence_steps.TccOn) {
+                *p_measurement_timing_budget_micro_seconds +=
+                    msrc_dcc_tcc_timeout_micro_seconds +
+                    tcc_overhead_micro_seconds;
+            }
+
+            if (scheduler_sequence_steps.DssOn) {
+                *p_measurement_timing_budget_micro_seconds +=
+                    2 * (msrc_dcc_tcc_timeout_micro_seconds +
+                         dss_overhead_micro_seconds);
+            } else if (scheduler_sequence_steps.MsrcOn) {
+                *p_measurement_timing_budget_micro_seconds +=
+                    msrc_dcc_tcc_timeout_micro_seconds +
+                    msrc_overhead_micro_seconds;
+            }
+        }
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        if (scheduler_sequence_steps.PreRangeOn) {
+            status = get_sequence_step_timeout(dev,
+                                               VL53L0X_SEQUENCESTEP_PRE_RANGE,
+                                               &pre_range_timeout_micro_seconds);
+            *p_measurement_timing_budget_micro_seconds +=
+                pre_range_timeout_micro_seconds +
+                pre_range_overhead_micro_seconds;
+        }
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        if (scheduler_sequence_steps.FinalRangeOn) {
+            status = get_sequence_step_timeout(dev,
+                                               VL53L0X_SEQUENCESTEP_FINAL_RANGE,
+                                               &final_range_timeout_micro_seconds);
+            *p_measurement_timing_budget_micro_seconds +=
+                (final_range_timeout_micro_seconds +
+                 final_range_overhead_micro_seconds);
+        }
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        VL53L0X_SETPARAMETERFIELD(dev,
+                                  MeasurementTimingBudgetMicroSeconds,
+                                  *p_measurement_timing_budget_micro_seconds);
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_measurement_timing_budget_micro_seconds(VL53L0X_DEV dev,
+        uint32_t *p_measurement_timing_budget_micro_seconds)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    LOG_FUNCTION_START("");
+
+    status = wrapped_VL53L0X_get_measurement_timing_budget_micro_seconds(dev,
+             p_measurement_timing_budget_micro_seconds);
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_device_parameters(VL53L0X_DEV dev,
+        VL53L0X_DeviceParameters_t *p_device_parameters)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    int i;
+
+    LOG_FUNCTION_START("");
+
+    status = VL53L0X_get_device_mode(dev, &(p_device_parameters->DeviceMode));
+
+    if (status == VL53L0X_ERROR_NONE)
+        status = VL53L0X_get_inter_measurement_period_milli_seconds(dev,
+                 &(p_device_parameters->InterMeasurementPeriodMilliSeconds));
+
+
+    if (status == VL53L0X_ERROR_NONE) {
+        p_device_parameters->XTalkCompensationEnable = 0;
+    }
+
+    if (status == VL53L0X_ERROR_NONE)
+        status = VL53L0X_get_x_talk_compensation_rate_mega_cps(dev,
+                 &(p_device_parameters->XTalkCompensationRateMegaCps));
+
+
+    if (status == VL53L0X_ERROR_NONE)
+        status = VL53L0X_get_offset_calibration_data_micro_meter(dev,
+                 &(p_device_parameters->RangeOffsetMicroMeters));
+
+
+    if (status == VL53L0X_ERROR_NONE) {
+        for (i = 0; i < VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS; i++) {
+            /* get first the values, then the enables.
+             * VL53L0X_GetLimitCheckValue will modify the enable
+             * flags
+             */
+            if (status == VL53L0X_ERROR_NONE) {
+                status |= VL53L0X_get_limit_check_value(dev, i,
+                                                        &(p_device_parameters->LimitChecksValue[i]));
+            } else {
+                break;
+            }
+            if (status == VL53L0X_ERROR_NONE) {
+                status |= VL53L0X_get_limit_check_enable(dev, i,
+                          &(p_device_parameters->LimitChecksEnable[i]));
+            } else {
+                break;
+            }
+        }
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_get_wrap_around_check_enable(dev,
+                 &(p_device_parameters->WrapAroundCheckEnable));
+    }
+
+    /* Need to be done at the end as it uses VCSELPulsePeriod */
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_get_measurement_timing_budget_micro_seconds(dev,
+                 &(p_device_parameters->MeasurementTimingBudgetMicroSeconds));
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_set_limit_check_value(VL53L0X_DEV dev, uint16_t limit_check_id,
+        FixPoint1616_t limit_check_value)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t temp8;
+
+    LOG_FUNCTION_START("");
+
+    VL53L0X_GETARRAYPARAMETERFIELD(dev, LimitChecksEnable, limit_check_id,
+                                   temp8);
+
+    if (temp8 == 0) { /* disabled write only internal value */
+        VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksValue,
+                                       limit_check_id, limit_check_value);
+    } else {
+
+        switch (limit_check_id) {
+
+            case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE:
+                /* internal computation: */
+                VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksValue,
+                                               VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,
+                                               limit_check_value);
+                break;
+
+            case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
+
+                status = VL53L0X_write_word(dev,
+                                            VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT,
+                                            VL53L0X_FIXPOINT1616TOFIXPOINT97(
+                                                limit_check_value));
+
+                break;
+
+            case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP:
+
+                /* internal computation: */
+                VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksValue,
+                                               VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP,
+                                               limit_check_value);
+
+                break;
+
+            case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD:
+
+                /* internal computation: */
+                VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksValue,
+                                               VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD,
+                                               limit_check_value);
+
+                break;
+
+            case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC:
+            case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE:
+
+                status = VL53L0X_write_word(dev,
+                                            VL53L0X_REG_PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT,
+                                            VL53L0X_FIXPOINT1616TOFIXPOINT97(
+                                                limit_check_value));
+
+                break;
+
+            default:
+                status = VL53L0X_ERROR_INVALID_PARAMS;
+
+        }
+
+        if (status == VL53L0X_ERROR_NONE) {
+            VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksValue,
+                                           limit_check_id, limit_check_value);
+        }
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_data_init(VL53L0X_DEV dev)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    VL53L0X_DeviceParameters_t CurrentParameters;
+    int i;
+    uint8_t StopVariable;
+
+    LOG_FUNCTION_START("");
+
+    /* by default the I2C is running at 1V8 if you want to change it you
+     * need to include this define at compilation level. */
+#ifdef USE_I2C_2V8
+    Status = VL53L0X_UpdateByte(Dev,
+                                VL53L0X_REG_VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV,
+                                0xFE,
+                                0x01);
+#endif
+
+    /* Set I2C standard mode */
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev, 0x88, 0x00);
+    }
+
+    VL53L0X_SETDEVICESPECIFICPARAMETER(dev, ReadDataFromDeviceDone, 0);
+
+#ifdef USE_IQC_STATION
+    if (Status == VL53L0X_ERROR_NONE) {
+        Status = VL53L0X_apply_offset_adjustment(Dev);
+    }
+#endif
+
+    /* Default value is 1000 for Linearity Corrective Gain */
+    PALDevDataSet(dev, LinearityCorrectiveGain, 1000);
+
+    /* Dmax default Parameter */
+    PALDevDataSet(dev, DmaxCalRangeMilliMeter, 400);
+    PALDevDataSet(dev, DmaxCalSignalRateRtnMegaCps,
+                  (FixPoint1616_t)((0x00016B85))); /* 1.42 No Cover Glass*/
+
+    /* Set Default static parameters
+     *set first temporary values 9.44MHz * 65536 = 618660 */
+    VL53L0X_SETDEVICESPECIFICPARAMETER(dev, OscFrequencyMHz, 618660);
+
+    /* Set Default XTalkCompensationRateMegaCps to 0  */
+    VL53L0X_SETPARAMETERFIELD(dev, XTalkCompensationRateMegaCps, 0);
+
+    /* Get default parameters */
+    status = VL53L0X_get_device_parameters(dev, &CurrentParameters);
+    if (status == VL53L0X_ERROR_NONE) {
+        /* initialize PAL values */
+        CurrentParameters.DeviceMode = VL53L0X_DEVICEMODE_SINGLE_RANGING;
+        CurrentParameters.HistogramMode = VL53L0X_HISTOGRAMMODE_DISABLED;
+        PALDevDataSet(dev, CurrentParameters, CurrentParameters);
+    }
+
+    /* Sigma estimator variable */
+    PALDevDataSet(dev, SigmaEstRefArray, 100);
+    PALDevDataSet(dev, SigmaEstEffPulseWidth, 900);
+    PALDevDataSet(dev, SigmaEstEffAmbWidth, 500);
+    PALDevDataSet(dev, targetRefRate, 0x0A00); /* 20 MCPS in 9:7 format */
+
+    /* Use internal default settings */
+    PALDevDataSet(dev, UseInternalTuningSettings, 1);
+
+    status |= VL53L0X_write_byte(dev, 0x80, 0x01);
+    status |= VL53L0X_write_byte(dev, 0xFF, 0x01);
+    status |= VL53L0X_write_byte(dev, 0x00, 0x00);
+    status |= VL53L0X_read_byte(dev, 0x91, &StopVariable);
+    PALDevDataSet(dev, StopVariable, StopVariable);
+    status |= VL53L0X_write_byte(dev, 0x00, 0x01);
+    status |= VL53L0X_write_byte(dev, 0xFF, 0x00);
+    status |= VL53L0X_write_byte(dev, 0x80, 0x00);
+
+    /* Enable all check */
+    for (i = 0; i < VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS; i++) {
+        if (status == VL53L0X_ERROR_NONE) {
+            status |= VL53L0X_set_limit_check_enable(dev, i, 1);
+        } else {
+            break;
+        }
+
+    }
+
+    /* Disable the following checks */
+    if (status == VL53L0X_ERROR_NONE)
+        status = VL53L0X_set_limit_check_enable(dev,
+                                                VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, 0);
+
+    if (status == VL53L0X_ERROR_NONE)
+        status = VL53L0X_set_limit_check_enable(dev,
+                                                VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, 0);
+
+    if (status == VL53L0X_ERROR_NONE)
+        status = VL53L0X_set_limit_check_enable(dev,
+                                                VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC, 0);
+
+    if (status == VL53L0X_ERROR_NONE)
+        status = VL53L0X_set_limit_check_enable(dev,
+                                                VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE, 0);
+
+    /* Limit default values */
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_set_limit_check_value(dev,
+                                               VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,
+                                               (FixPoint1616_t)(18 * 65536));
+    }
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_set_limit_check_value(dev,
+                                               VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
+                                               (FixPoint1616_t)(25 * 65536 / 100));
+        /* 0.25 * 65536 */
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_set_limit_check_value(dev,
+                                               VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP,
+                                               (FixPoint1616_t)(35 * 65536));
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_set_limit_check_value(dev,
+                                               VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD,
+                                               (FixPoint1616_t)(0 * 65536));
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+
+        PALDevDataSet(dev, SequenceConfig, 0xFF);
+        status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
+                                    0xFF);
+
+        /* Set PAL state to tell that we are waiting for call to
+         * VL53L0X_StaticInit */
+        PALDevDataSet(dev, PalState, VL53L0X_STATE_WAIT_STATICINIT);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        VL53L0X_SETDEVICESPECIFICPARAMETER(dev, RefSpadsInitialised, 0);
+    }
+
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_check_part_used(VL53L0X_DEV dev,
+        uint8_t *revision,
+        VL53L0X_DeviceInfo_t *p_VL53L0X_device_info)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t module_id_int;
+    char *product_id_tmp;
+
+    LOG_FUNCTION_START("");
+
+    status = VL53L0X_get_info_from_device(dev, 2);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        module_id_int = VL53L0X_GETDEVICESPECIFICPARAMETER(dev, ModuleId);
+
+        if (module_id_int == 0) {
+            *revision = 0;
+            VL53L0X_COPYSTRING(p_VL53L0X_device_info->ProductId, "");
+        } else {
+            *revision = VL53L0X_GETDEVICESPECIFICPARAMETER(dev, Revision);
+            product_id_tmp = VL53L0X_GETDEVICESPECIFICPARAMETER(dev,
+                             ProductId);
+            VL53L0X_COPYSTRING(p_VL53L0X_device_info->ProductId, product_id_tmp);
+        }
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::wrapped_VL53L0X_get_device_info(VL53L0X_DEV dev,
+        VL53L0X_DeviceInfo_t *p_VL53L0X_device_info)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t revision_id;
+    uint8_t revision;
+
+    status = VL53L0X_check_part_used(dev, &revision, p_VL53L0X_device_info);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        if (revision == 0) {
+            VL53L0X_COPYSTRING(p_VL53L0X_device_info->Name,
+                               VL53L0X_STRING_DEVICE_INFO_NAME_TS0);
+        } else if ((revision <= 34) && (revision != 32)) {
+            VL53L0X_COPYSTRING(p_VL53L0X_device_info->Name,
+                               VL53L0X_STRING_DEVICE_INFO_NAME_TS1);
+        } else if (revision < 39) {
+            VL53L0X_COPYSTRING(p_VL53L0X_device_info->Name,
+                               VL53L0X_STRING_DEVICE_INFO_NAME_TS2);
+        } else {
+            VL53L0X_COPYSTRING(p_VL53L0X_device_info->Name,
+                               VL53L0X_STRING_DEVICE_INFO_NAME_ES1);
+        }
+
+        VL53L0X_COPYSTRING(p_VL53L0X_device_info->Type,
+                           VL53L0X_STRING_DEVICE_INFO_TYPE);
+
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_read_byte(dev, VL53L0X_REG_IDENTIFICATION_MODEL_ID,
+                                   &p_VL53L0X_device_info->ProductType);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_read_byte(dev,
+                                   VL53L0X_REG_IDENTIFICATION_REVISION_ID,
+                                   &revision_id);
+        p_VL53L0X_device_info->ProductRevisionMajor = 1;
+        p_VL53L0X_device_info->ProductRevisionMinor =
+            (revision_id & 0xF0) >> 4;
+    }
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_device_info(VL53L0X_DEV dev,
+        VL53L0X_DeviceInfo_t *p_VL53L0X_device_info)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    LOG_FUNCTION_START("");
+
+    status = wrapped_VL53L0X_get_device_info(dev, p_VL53L0X_device_info);
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_interrupt_mask_status(VL53L0X_DEV dev,
+        uint32_t *p_interrupt_mask_status)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t byte;
+    LOG_FUNCTION_START("");
+
+    status = VL53L0X_read_byte(dev, VL53L0X_REG_RESULT_INTERRUPT_STATUS, &byte);
+    *p_interrupt_mask_status = byte & 0x07;
+
+    if (byte & 0x18) {
+        status = VL53L0X_ERROR_RANGE_ERROR;
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_measurement_data_ready(VL53L0X_DEV dev,
+        uint8_t *p_measurement_data_ready)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t sys_range_status_register;
+    uint8_t interrupt_config;
+    uint32_t interrupt_mask;
+    LOG_FUNCTION_START("");
+
+    interrupt_config = VL53L0X_GETDEVICESPECIFICPARAMETER(dev,
+                       Pin0GpioFunctionality);
+
+    if (interrupt_config ==
+            VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY) {
+        status = VL53L0X_get_interrupt_mask_status(dev, &interrupt_mask);
+        if (interrupt_mask ==
+                VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY) {
+            *p_measurement_data_ready = 1;
+        } else {
+            *p_measurement_data_ready = 0;
+        }
+    } else {
+        status = VL53L0X_read_byte(dev, VL53L0X_REG_RESULT_RANGE_STATUS,
+                                   &sys_range_status_register);
+        if (status == VL53L0X_ERROR_NONE) {
+            if (sys_range_status_register & 0x01) {
+                *p_measurement_data_ready = 1;
+            } else {
+                *p_measurement_data_ready = 0;
+            }
+        }
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_polling_delay(VL53L0X_DEV dev)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+
+    // do nothing
+    VL53L0X_OsDelay();
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_measurement_poll_for_completion(VL53L0X_DEV dev)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t new_data_ready = 0;
+    uint32_t loop_nb;
+
+    LOG_FUNCTION_START("");
+
+    loop_nb = 0;
+
+    do {
+        status = VL53L0X_get_measurement_data_ready(dev, &new_data_ready);
+        if (status != 0) {
+            break; /* the error is set */
+        }
+
+        if (new_data_ready == 1) {
+            break; /* done note that status == 0 */
+        }
+
+        loop_nb++;
+        if (loop_nb >= VL53L0X_DEFAULT_MAX_LOOP) {
+            status = VL53L0X_ERROR_TIME_OUT;
+            break;
+        }
+
+        VL53L0X_polling_delay(dev);
+    } while (1);
+
+    LOG_FUNCTION_END(status);
+
+    return status;
+}
+
+/* Group PAL Interrupt Functions */
+VL53L0X_Error VL53L0X::VL53L0X_clear_interrupt_mask(VL53L0X_DEV dev, uint32_t interrupt_mask)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t loop_count;
+    uint8_t byte;
+    LOG_FUNCTION_START("");
+
+    /* clear bit 0 range interrupt, bit 1 error interrupt */
+    loop_count = 0;
+    do {
+        status = VL53L0X_write_byte(dev,
+                                    VL53L0X_REG_SYSTEM_INTERRUPT_CLEAR, 0x01);
+        status |= VL53L0X_write_byte(dev,
+                                     VL53L0X_REG_SYSTEM_INTERRUPT_CLEAR, 0x00);
+        status |= VL53L0X_read_byte(dev,
+                                    VL53L0X_REG_RESULT_INTERRUPT_STATUS, &byte);
+        loop_count++;
+    } while (((byte & 0x07) != 0x00)
+             && (loop_count < 3)
+             && (status == VL53L0X_ERROR_NONE));
+
+
+    if (loop_count >= 3) {
+        status = VL53L0X_ERROR_INTERRUPT_NOT_CLEARED;
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_perform_single_ref_calibration(VL53L0X_DEV dev,
+        uint8_t vhv_init_byte)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSRANGE_START,
+                                    VL53L0X_REG_SYSRANGE_MODE_START_STOP |
+                                    vhv_init_byte);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_measurement_poll_for_completion(dev);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_clear_interrupt_mask(dev, 0);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSRANGE_START, 0x00);
+    }
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_ref_calibration_io(VL53L0X_DEV dev, uint8_t read_not_write,
+        uint8_t vhv_settings, uint8_t phase_cal,
+        uint8_t *p_vhv_settings, uint8_t *p_phase_cal,
+        const uint8_t vhv_enable, const uint8_t phase_enable)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t phase_calint = 0;
+
+    /* Read VHV from device */
+    status |= VL53L0X_write_byte(dev, 0xFF, 0x01);
+    status |= VL53L0X_write_byte(dev, 0x00, 0x00);
+    status |= VL53L0X_write_byte(dev, 0xFF, 0x00);
+
+    if (read_not_write) {
+        if (vhv_enable) {
+            status |= VL53L0X_read_byte(dev, 0xCB, p_vhv_settings);
+        }
+        if (phase_enable) {
+            status |= VL53L0X_read_byte(dev, 0xEE, &phase_calint);
+        }
+    } else {
+        if (vhv_enable) {
+            status |= VL53L0X_write_byte(dev, 0xCB, vhv_settings);
+        }
+        if (phase_enable) {
+            status |= VL53L0X_update_byte(dev, 0xEE, 0x80, phase_cal);
+        }
+    }
+
+    status |= VL53L0X_write_byte(dev, 0xFF, 0x01);
+    status |= VL53L0X_write_byte(dev, 0x00, 0x01);
+    status |= VL53L0X_write_byte(dev, 0xFF, 0x00);
+
+    *p_phase_cal = (uint8_t)(phase_calint & 0xEF);
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_perform_vhv_calibration(VL53L0X_DEV dev,
+        uint8_t *p_vhv_settings, const uint8_t get_data_enable,
+        const uint8_t restore_config)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t sequence_config = 0;
+    uint8_t vhv_settings = 0;
+    uint8_t phase_cal = 0;
+    uint8_t phase_cal_int = 0;
+
+    /* store the value of the sequence config,
+     * this will be reset before the end of the function
+     */
+
+    if (restore_config) {
+        sequence_config = PALDevDataGet(dev, SequenceConfig);
+    }
+
+    /* Run VHV */
+    status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, 0x01);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_perform_single_ref_calibration(dev, 0x40);
+    }
+
+    /* Read VHV from device */
+    if ((status == VL53L0X_ERROR_NONE) && (get_data_enable == 1)) {
+        status = VL53L0X_ref_calibration_io(dev, 1,
+                                            vhv_settings, phase_cal, /* Not used here */
+                                            p_vhv_settings, &phase_cal_int,
+                                            1, 0);
+    } else {
+        *p_vhv_settings = 0;
+    }
+
+
+    if ((status == VL53L0X_ERROR_NONE) && restore_config) {
+        /* restore the previous Sequence Config */
+        status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
+                                    sequence_config);
+        if (status == VL53L0X_ERROR_NONE) {
+            PALDevDataSet(dev, SequenceConfig, sequence_config);
+        }
+
+    }
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_perform_phase_calibration(VL53L0X_DEV dev,
+        uint8_t *p_phase_cal, const uint8_t get_data_enable,
+        const uint8_t restore_config)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t sequence_config = 0;
+    uint8_t vhv_settings = 0;
+    uint8_t phase_cal = 0;
+    uint8_t vhv_settingsint;
+
+    /* store the value of the sequence config,
+     * this will be reset before the end of the function
+     */
+
+    if (restore_config) {
+        sequence_config = PALDevDataGet(dev, SequenceConfig);
+    }
+
+    /* Run PhaseCal */
+    status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, 0x02);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_perform_single_ref_calibration(dev, 0x0);
+    }
+
+    /* Read PhaseCal from device */
+    if ((status == VL53L0X_ERROR_NONE) && (get_data_enable == 1)) {
+        status = VL53L0X_ref_calibration_io(dev, 1,
+                                            vhv_settings, phase_cal, /* Not used here */
+                                            &vhv_settingsint, p_phase_cal,
+                                            0, 1);
+    } else {
+        *p_phase_cal = 0;
+    }
+
+
+    if ((status == VL53L0X_ERROR_NONE) && restore_config) {
+        /* restore the previous Sequence Config */
+        status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
+                                    sequence_config);
+        if (status == VL53L0X_ERROR_NONE) {
+            PALDevDataSet(dev, SequenceConfig, sequence_config);
+        }
+
+    }
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_perform_ref_calibration(VL53L0X_DEV dev,
+        uint8_t *p_vhv_settings, uint8_t *p_phase_cal, uint8_t get_data_enable)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t sequence_config = 0;
+
+    /* store the value of the sequence config,
+     * this will be reset before the end of the function
+     */
+
+    sequence_config = PALDevDataGet(dev, SequenceConfig);
+
+    /* In the following function we don't save the config to optimize
+     * writes on device. Config is saved and restored only once. */
+    status = VL53L0X_perform_vhv_calibration(
+                 dev, p_vhv_settings, get_data_enable, 0);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_perform_phase_calibration(
+                     dev, p_phase_cal, get_data_enable, 0);
+    }
+
+
+    if (status == VL53L0X_ERROR_NONE) {
+        /* restore the previous Sequence Config */
+        status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
+                                    sequence_config);
+        if (status == VL53L0X_ERROR_NONE) {
+            PALDevDataSet(dev, SequenceConfig, sequence_config);
+        }
+
+    }
+
+    return status;
+}
+
+void VL53L0X::get_next_good_spad(uint8_t good_spad_array[], uint32_t size,
+                                 uint32_t curr, int32_t *p_next)
+{
+    uint32_t start_index;
+    uint32_t fine_offset;
+    uint32_t c_spads_per_byte = 8;
+    uint32_t coarse_index;
+    uint32_t fine_index;
+    uint8_t data_byte;
+    uint8_t success = 0;
+
+    /*
+     * Starting with the current good spad, loop through the array to find
+     * the next. i.e. the next bit set in the sequence.
+     *
+     * The coarse index is the byte index of the array and the fine index is
+     * the index of the bit within each byte.
+     */
+
+    *p_next = -1;
+
+    start_index = curr / c_spads_per_byte;
+    fine_offset = curr % c_spads_per_byte;
+
+    for (coarse_index = start_index; ((coarse_index < size) && !success);
+            coarse_index++) {
+        fine_index = 0;
+        data_byte = good_spad_array[coarse_index];
+
+        if (coarse_index == start_index) {
+            /* locate the bit position of the provided current
+             * spad bit before iterating */
+            data_byte >>= fine_offset;
+            fine_index = fine_offset;
+        }
+
+        while (fine_index < c_spads_per_byte) {
+            if ((data_byte & 0x1) == 1) {
+                success = 1;
+                *p_next = coarse_index * c_spads_per_byte + fine_index;
+                break;
+            }
+            data_byte >>= 1;
+            fine_index++;
+        }
+    }
+}
+
+uint8_t VL53L0X::is_aperture(uint32_t spad_index)
+{
+    /*
+     * This function reports if a given spad index is an aperture SPAD by
+     * deriving the quadrant.
+     */
+    uint32_t quadrant;
+    uint8_t is_aperture = 1;
+    quadrant = spad_index >> 6;
+    if (refArrayQuadrants[quadrant] == REF_ARRAY_SPAD_0) {
+        is_aperture = 0;
+    }
+
+    return is_aperture;
+}
+
+VL53L0X_Error VL53L0X::enable_spad_bit(uint8_t spad_array[], uint32_t size,
+                                       uint32_t spad_index)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint32_t c_spads_per_byte = 8;
+    uint32_t coarse_index;
+    uint32_t fine_index;
+
+    coarse_index = spad_index / c_spads_per_byte;
+    fine_index = spad_index % c_spads_per_byte;
+    if (coarse_index >= size) {
+        status = VL53L0X_ERROR_REF_SPAD_INIT;
+    } else {
+        spad_array[coarse_index] |= (1 << fine_index);
+    }
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::set_ref_spad_map(VL53L0X_DEV dev, uint8_t *p_ref_spad_array)
+{
+    VL53L0X_Error status = VL53L0X_write_multi(dev,
+                           VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0,
+                           p_ref_spad_array, 6);
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::get_ref_spad_map(VL53L0X_DEV dev, uint8_t *p_ref_spad_array)
+{
+    VL53L0X_Error status = VL53L0X_read_multi(dev,
+                           VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0,
+                           p_ref_spad_array,
+                           6);
+//	VL53L0X_Error status = VL53L0X_ERROR_NONE;
+//	uint8_t count=0;
+
+//	for (count = 0; count < 6; count++)
+//        status = VL53L0X_RdByte(Dev, (VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0 + count), &refSpadArray[count]);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::enable_ref_spads(VL53L0X_DEV dev,
+                                        uint8_t aperture_spads,
+                                        uint8_t good_spad_array[],
+                                        uint8_t spad_array[],
+                                        uint32_t size,
+                                        uint32_t start,
+                                        uint32_t offset,
+                                        uint32_t spad_count,
+                                        uint32_t *p_last_spad)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint32_t index;
+    uint32_t i;
+    int32_t next_good_spad = offset;
+    uint32_t current_spad;
+    uint8_t check_spad_array[6];
+
+    /*
+     * This function takes in a spad array which may or may not have SPADS
+     * already enabled and appends from a given offset a requested number
+     * of new SPAD enables. The 'good spad map' is applied to
+     * determine the next SPADs to enable.
+     *
+     * This function applies to only aperture or only non-aperture spads.
+     * Checks are performed to ensure this.
+     */
+
+    current_spad = offset;
+    for (index = 0; index < spad_count; index++) {
+        get_next_good_spad(good_spad_array, size, current_spad,
+                           &next_good_spad);
+
+        if (next_good_spad == -1) {
+            status = VL53L0X_ERROR_REF_SPAD_INIT;
+            break;
+        }
+
+        /* Confirm that the next good SPAD is non-aperture */
+        if (is_aperture(start + next_good_spad) != aperture_spads) {
+            /* if we can't get the required number of good aperture
+             * spads from the current quadrant then this is an error
+             */
+            status = VL53L0X_ERROR_REF_SPAD_INIT;
+            break;
+        }
+        current_spad = (uint32_t)next_good_spad;
+        enable_spad_bit(spad_array, size, current_spad);
+        current_spad++;
+    }
+    *p_last_spad = current_spad;
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = set_ref_spad_map(dev, spad_array);
+    }
+
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = get_ref_spad_map(dev, check_spad_array);
+
+        i = 0;
+
+        /* Compare spad maps. If not equal report error. */
+        while (i < size) {
+            if (spad_array[i] != check_spad_array[i]) {
+                status = VL53L0X_ERROR_REF_SPAD_INIT;
+                break;
+            }
+            i++;
+        }
+    }
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_set_device_mode(VL53L0X_DEV dev, VL53L0X_DeviceModes device_mode)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+
+    LOG_FUNCTION_START("%d", (int)DeviceMode);
+
+    switch (device_mode) {
+        case VL53L0X_DEVICEMODE_SINGLE_RANGING:
+        case VL53L0X_DEVICEMODE_CONTINUOUS_RANGING:
+        case VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING:
+        case VL53L0X_DEVICEMODE_GPIO_DRIVE:
+        case VL53L0X_DEVICEMODE_GPIO_OSC:
+            /* Supported modes */
+            VL53L0X_SETPARAMETERFIELD(dev, DeviceMode, device_mode);
+            break;
+        default:
+            /* Unsupported mode */
+            status = VL53L0X_ERROR_MODE_NOT_SUPPORTED;
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_set_interrupt_thresholds(VL53L0X_DEV dev,
+        VL53L0X_DeviceModes device_mode, FixPoint1616_t threshold_low,
+        FixPoint1616_t threshold_high)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint16_t threshold16;
+    LOG_FUNCTION_START("");
+
+    /* no dependency on DeviceMode for Ewok */
+    /* Need to divide by 2 because the FW will apply a x2 */
+    threshold16 = (uint16_t)((threshold_low >> 17) & 0x00fff);
+    status = VL53L0X_write_word(dev, VL53L0X_REG_SYSTEM_THRESH_LOW, threshold16);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        /* Need to divide by 2 because the FW will apply a x2 */
+        threshold16 = (uint16_t)((threshold_high >> 17) & 0x00fff);
+        status = VL53L0X_write_word(dev, VL53L0X_REG_SYSTEM_THRESH_HIGH,
+                                    threshold16);
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_interrupt_thresholds(VL53L0X_DEV dev,
+        VL53L0X_DeviceModes device_mode, FixPoint1616_t *p_threshold_low,
+        FixPoint1616_t *p_threshold_high)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint16_t threshold16;
+    LOG_FUNCTION_START("");
+
+    /* no dependency on DeviceMode for Ewok */
+
+    status = VL53L0X_read_word(dev, VL53L0X_REG_SYSTEM_THRESH_LOW, &threshold16);
+    /* Need to multiply by 2 because the FW will apply a x2 */
+    *p_threshold_low = (FixPoint1616_t)((0x00fff & threshold16) << 17);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_read_word(dev, VL53L0X_REG_SYSTEM_THRESH_HIGH,
+                                   &threshold16);
+        /* Need to multiply by 2 because the FW will apply a x2 */
+        *p_threshold_high =
+            (FixPoint1616_t)((0x00fff & threshold16) << 17);
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_load_tuning_settings(VL53L0X_DEV dev,
+        uint8_t *p_tuning_setting_buffer)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    int i;
+    int index;
+    uint8_t msb;
+    uint8_t lsb;
+    uint8_t select_param;
+    uint8_t number_of_writes;
+    uint8_t address;
+    uint8_t local_buffer[4]; /* max */
+    uint16_t temp16;
+
+    LOG_FUNCTION_START("");
+
+    index = 0;
+
+    while ((*(p_tuning_setting_buffer + index) != 0) &&
+            (status == VL53L0X_ERROR_NONE)) {
+        number_of_writes = *(p_tuning_setting_buffer + index);
+        index++;
+        if (number_of_writes == 0xFF) {
+            /* internal parameters */
+            select_param = *(p_tuning_setting_buffer + index);
+            index++;
+            switch (select_param) {
+                case 0: /* uint16_t SigmaEstRefArray -> 2 bytes */
+                    msb = *(p_tuning_setting_buffer + index);
+                    index++;
+                    lsb = *(p_tuning_setting_buffer + index);
+                    index++;
+                    temp16 = VL53L0X_MAKEUINT16(lsb, msb);
+                    PALDevDataSet(dev, SigmaEstRefArray, temp16);
+                    break;
+                case 1: /* uint16_t SigmaEstEffPulseWidth -> 2 bytes */
+                    msb = *(p_tuning_setting_buffer + index);
+                    index++;
+                    lsb = *(p_tuning_setting_buffer + index);
+                    index++;
+                    temp16 = VL53L0X_MAKEUINT16(lsb, msb);
+                    PALDevDataSet(dev, SigmaEstEffPulseWidth,
+                                  temp16);
+                    break;
+                case 2: /* uint16_t SigmaEstEffAmbWidth -> 2 bytes */
+                    msb = *(p_tuning_setting_buffer + index);
+                    index++;
+                    lsb = *(p_tuning_setting_buffer + index);
+                    index++;
+                    temp16 = VL53L0X_MAKEUINT16(lsb, msb);
+                    PALDevDataSet(dev, SigmaEstEffAmbWidth, temp16);
+                    break;
+                case 3: /* uint16_t targetRefRate -> 2 bytes */
+                    msb = *(p_tuning_setting_buffer + index);
+                    index++;
+                    lsb = *(p_tuning_setting_buffer + index);
+                    index++;
+                    temp16 = VL53L0X_MAKEUINT16(lsb, msb);
+                    PALDevDataSet(dev, targetRefRate, temp16);
+                    break;
+                default: /* invalid parameter */
+                    status = VL53L0X_ERROR_INVALID_PARAMS;
+            }
+
+        } else if (number_of_writes <= 4) {
+            address = *(p_tuning_setting_buffer + index);
+            index++;
+
+            for (i = 0; i < number_of_writes; i++) {
+                local_buffer[i] = *(p_tuning_setting_buffer +
+                                    index);
+                index++;
+            }
+
+            status = VL53L0X_write_multi(dev, address, local_buffer,
+                                         number_of_writes);
+
+        } else {
+            status = VL53L0X_ERROR_INVALID_PARAMS;
+        }
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_check_and_load_interrupt_settings(VL53L0X_DEV dev,
+        uint8_t start_not_stopflag)
+{
+    uint8_t interrupt_config;
+    FixPoint1616_t threshold_low;
+    FixPoint1616_t threshold_high;
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+
+    interrupt_config = VL53L0X_GETDEVICESPECIFICPARAMETER(dev,
+                       Pin0GpioFunctionality);
+
+    if ((interrupt_config ==
+            VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW) ||
+            (interrupt_config ==
+             VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH) ||
+            (interrupt_config ==
+             VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT)) {
+
+        status = VL53L0X_get_interrupt_thresholds(dev,
+                 VL53L0X_DEVICEMODE_CONTINUOUS_RANGING,
+                 &threshold_low, &threshold_high);
+
+        if (((threshold_low > 255 * 65536) ||
+                (threshold_high > 255 * 65536)) &&
+                (status == VL53L0X_ERROR_NONE)) {
+
+            if (start_not_stopflag != 0) {
+                status = VL53L0X_load_tuning_settings(dev,
+                                                      InterruptThresholdSettings);
+            } else {
+                status |= VL53L0X_write_byte(dev, 0xFF, 0x04);
+                status |= VL53L0X_write_byte(dev, 0x70, 0x00);
+                status |= VL53L0X_write_byte(dev, 0xFF, 0x00);
+                status |= VL53L0X_write_byte(dev, 0x80, 0x00);
+            }
+
+        }
+
+
+    }
+
+    return status;
+
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_start_measurement(VL53L0X_DEV dev)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    VL53L0X_DeviceModes device_mode;
+    uint8_t byte;
+    uint8_t start_stop_byte = VL53L0X_REG_SYSRANGE_MODE_START_STOP;
+    uint32_t loop_nb;
+    LOG_FUNCTION_START("");
+
+    /* Get Current DeviceMode */
+    VL53L0X_get_device_mode(dev, &device_mode);
+
+    status = VL53L0X_write_byte(dev, 0x80, 0x01);
+    status = VL53L0X_write_byte(dev, 0xFF, 0x01);
+    status = VL53L0X_write_byte(dev, 0x00, 0x00);
+    status = VL53L0X_write_byte(dev, 0x91, PALDevDataGet(dev, StopVariable));
+    status = VL53L0X_write_byte(dev, 0x00, 0x01);
+    status = VL53L0X_write_byte(dev, 0xFF, 0x00);
+    status = VL53L0X_write_byte(dev, 0x80, 0x00);
+
+    switch (device_mode) {
+        case VL53L0X_DEVICEMODE_SINGLE_RANGING:
+            status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSRANGE_START, 0x01);
+
+            byte = start_stop_byte;
+            if (status == VL53L0X_ERROR_NONE) {
+                /* Wait until start bit has been cleared */
+                loop_nb = 0;
+                do {
+                    if (loop_nb > 0)
+                        status = VL53L0X_read_byte(dev,
+                                                   VL53L0X_REG_SYSRANGE_START, &byte);
+                    loop_nb = loop_nb + 1;
+                } while (((byte & start_stop_byte) == start_stop_byte)
+                         && (status == VL53L0X_ERROR_NONE)
+                         && (loop_nb < VL53L0X_DEFAULT_MAX_LOOP));
+
+                if (loop_nb >= VL53L0X_DEFAULT_MAX_LOOP) {
+                    status = VL53L0X_ERROR_TIME_OUT;
+                }
+
+            }
+
+            break;
+        case VL53L0X_DEVICEMODE_CONTINUOUS_RANGING:
+            /* Back-to-back mode */
+
+            /* Check if need to apply interrupt settings */
+            if (status == VL53L0X_ERROR_NONE) {
+                status = VL53L0X_check_and_load_interrupt_settings(dev, 1);
+            }
+
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_SYSRANGE_START,
+                                        VL53L0X_REG_SYSRANGE_MODE_BACKTOBACK);
+            if (status == VL53L0X_ERROR_NONE) {
+                /* Set PAL State to Running */
+                PALDevDataSet(dev, PalState, VL53L0X_STATE_RUNNING);
+            }
+            break;
+        case VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING:
+            /* Continuous mode */
+            /* Check if need to apply interrupt settings */
+            if (status == VL53L0X_ERROR_NONE) {
+                status = VL53L0X_check_and_load_interrupt_settings(dev, 1);
+            }
+
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_SYSRANGE_START,
+                                        VL53L0X_REG_SYSRANGE_MODE_TIMED);
+
+            if (status == VL53L0X_ERROR_NONE) {
+                /* Set PAL State to Running */
+                PALDevDataSet(dev, PalState, VL53L0X_STATE_RUNNING);
+            }
+            break;
+        default:
+            /* Selected mode not supported */
+            status = VL53L0X_ERROR_MODE_NOT_SUPPORTED;
+    }
+
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+/* Group PAL Measurement Functions */
+VL53L0X_Error VL53L0X::VL53L0X_perform_single_measurement(VL53L0X_DEV dev)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    VL53L0X_DeviceModes device_mode;
+
+    LOG_FUNCTION_START("");
+
+    /* Get Current DeviceMode */
+    status = VL53L0X_get_device_mode(dev, &device_mode);
+
+    /* Start immediately to run a single ranging measurement in case of
+     * single ranging or single histogram */
+    if (status == VL53L0X_ERROR_NONE
+            && device_mode == VL53L0X_DEVICEMODE_SINGLE_RANGING) {
+        status = VL53L0X_start_measurement(dev);
+    }
+
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_measurement_poll_for_completion(dev);
+    }
+
+
+    /* Change PAL State in case of single ranging or single histogram */
+    if (status == VL53L0X_ERROR_NONE
+            && device_mode == VL53L0X_DEVICEMODE_SINGLE_RANGING) {
+        PALDevDataSet(dev, PalState, VL53L0X_STATE_IDLE);
+    }
+
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_x_talk_compensation_enable(VL53L0X_DEV dev,
+        uint8_t *p_x_talk_compensation_enable)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t temp8;
+    LOG_FUNCTION_START("");
+
+    VL53L0X_GETPARAMETERFIELD(dev, XTalkCompensationEnable, temp8);
+    *p_x_talk_compensation_enable = temp8;
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_total_xtalk_rate(VL53L0X_DEV dev,
+        VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data,
+        FixPoint1616_t *p_total_xtalk_rate_mcps)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+
+    uint8_t xtalk_comp_enable;
+    FixPoint1616_t total_xtalk_mega_cps;
+    FixPoint1616_t xtalk_per_spad_mega_cps;
+
+    *p_total_xtalk_rate_mcps = 0;
+
+    status = VL53L0X_get_x_talk_compensation_enable(dev, &xtalk_comp_enable);
+    if (status == VL53L0X_ERROR_NONE) {
+
+        if (xtalk_comp_enable) {
+
+            VL53L0X_GETPARAMETERFIELD(
+                dev,
+                XTalkCompensationRateMegaCps,
+                xtalk_per_spad_mega_cps);
+
+            /* FixPoint1616 * FixPoint 8:8 = FixPoint0824 */
+            total_xtalk_mega_cps =
+                p_ranging_measurement_data->EffectiveSpadRtnCount *
+                xtalk_per_spad_mega_cps;
+
+            /* FixPoint0824 >> 8 = FixPoint1616 */
+            *p_total_xtalk_rate_mcps =
+                (total_xtalk_mega_cps + 0x80) >> 8;
+        }
+    }
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_total_signal_rate(VL53L0X_DEV dev,
+        VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data,
+        FixPoint1616_t *p_total_signal_rate_mcps)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    FixPoint1616_t total_xtalk_mega_cps;
+
+    LOG_FUNCTION_START("");
+
+    *p_total_signal_rate_mcps =
+        p_ranging_measurement_data->SignalRateRtnMegaCps;
+
+    status = VL53L0X_get_total_xtalk_rate(
+                 dev, p_ranging_measurement_data, &total_xtalk_mega_cps);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        *p_total_signal_rate_mcps += total_xtalk_mega_cps;
+    }
+
+    return status;
+}
+
+/* To convert ms into register value */
+uint32_t VL53L0X::VL53L0X_calc_timeout_mclks(VL53L0X_DEV dev,
+        uint32_t timeout_period_us,
+        uint8_t vcsel_period_pclks)
+{
+    uint32_t macro_period_ps;
+    uint32_t macro_period_ns;
+    uint32_t timeout_period_mclks = 0;
+
+    macro_period_ps = VL53L0X_calc_macro_period_ps(dev, vcsel_period_pclks);
+    macro_period_ns = (macro_period_ps + 500) / 1000;
+
+    timeout_period_mclks =
+        (uint32_t)(((timeout_period_us * 1000)
+                    + (macro_period_ns / 2)) / macro_period_ns);
+
+    return timeout_period_mclks;
+}
+
+uint32_t VL53L0X::VL53L0X_isqrt(uint32_t num)
+{
+    /*
+     * Implements an integer square root
+     *
+     * From: http://en.wikipedia.org/wiki/Methods_of_computing_square_roots
+     */
+
+    uint32_t  res = 0;
+    uint32_t  bit = 1 << 30;
+    /* The second-to-top bit is set:
+     *	1 << 14 for 16-bits, 1 << 30 for 32 bits */
+
+    /* "bit" starts at the highest power of four <= the argument. */
+    while (bit > num) {
+        bit >>= 2;
+    }
+
+
+    while (bit != 0) {
+        if (num >= res + bit) {
+            num -= res + bit;
+            res = (res >> 1) + bit;
+        } else {
+            res >>= 1;
+        }
+
+        bit >>= 2;
+    }
+
+    return res;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_calc_dmax(
+    VL53L0X_DEV dev,
+    FixPoint1616_t total_signal_rate_mcps,
+    FixPoint1616_t total_corr_signal_rate_mcps,
+    FixPoint1616_t pw_mult,
+    uint32_t sigma_estimate_p1,
+    FixPoint1616_t sigma_estimate_p2,
+    uint32_t peak_vcsel_duration_us,
+    uint32_t *pd_max_mm)
+{
+    const uint32_t c_sigma_limit		= 18;
+    const FixPoint1616_t c_signal_limit	= 0x4000; /* 0.25 */
+    const FixPoint1616_t c_sigma_est_ref	= 0x00000042; /* 0.001 */
+    const uint32_t c_amb_eff_width_sigma_est_ns = 6;
+    const uint32_t c_amb_eff_width_d_max_ns	   = 7;
+    uint32_t dmax_cal_range_mm;
+    FixPoint1616_t dmax_cal_signal_rate_rtn_mcps;
+    FixPoint1616_t min_signal_needed;
+    FixPoint1616_t min_signal_needed_p1;
+    FixPoint1616_t min_signal_needed_p2;
+    FixPoint1616_t min_signal_needed_p3;
+    FixPoint1616_t min_signal_needed_p4;
+    FixPoint1616_t sigma_limit_tmp;
+    FixPoint1616_t sigma_est_sq_tmp;
+    FixPoint1616_t signal_limit_tmp;
+    FixPoint1616_t signal_at0_mm;
+    FixPoint1616_t dmax_dark;
+    FixPoint1616_t dmax_ambient;
+    FixPoint1616_t dmax_dark_tmp;
+    FixPoint1616_t sigma_est_p2_tmp;
+    uint32_t signal_rate_temp_mcps;
+
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+
+    LOG_FUNCTION_START("");
+
+    dmax_cal_range_mm =
+        PALDevDataGet(dev, DmaxCalRangeMilliMeter);
+
+    dmax_cal_signal_rate_rtn_mcps =
+        PALDevDataGet(dev, DmaxCalSignalRateRtnMegaCps);
+
+    /* uint32 * FixPoint1616 = FixPoint1616 */
+    signal_at0_mm = dmax_cal_range_mm * dmax_cal_signal_rate_rtn_mcps;
+
+    /* FixPoint1616 >> 8 = FixPoint2408 */
+    signal_at0_mm = (signal_at0_mm + 0x80) >> 8;
+    signal_at0_mm *= dmax_cal_range_mm;
+
+    min_signal_needed_p1 = 0;
+    if (total_corr_signal_rate_mcps > 0) {
+
+        /* Shift by 10 bits to increase resolution prior to the
+         * division */
+        signal_rate_temp_mcps = total_signal_rate_mcps << 10;
+
+        /* Add rounding value prior to division */
+        min_signal_needed_p1 = signal_rate_temp_mcps +
+                               (total_corr_signal_rate_mcps / 2);
+
+        /* FixPoint0626/FixPoint1616 = FixPoint2210 */
+        min_signal_needed_p1 /= total_corr_signal_rate_mcps;
+
+        /* Apply a factored version of the speed of light.
+         Correction to be applied at the end */
+        min_signal_needed_p1 *= 3;
+
+        /* FixPoint2210 * FixPoint2210 = FixPoint1220 */
+        min_signal_needed_p1 *= min_signal_needed_p1;
+
+        /* FixPoint1220 >> 16 = FixPoint2804 */
+        min_signal_needed_p1 = (min_signal_needed_p1 + 0x8000) >> 16;
+    }
+
+    min_signal_needed_p2 = pw_mult * sigma_estimate_p1;
+
+    /* FixPoint1616 >> 16 =	 uint32 */
+    min_signal_needed_p2 = (min_signal_needed_p2 + 0x8000) >> 16;
+
+    /* uint32 * uint32	=  uint32 */
+    min_signal_needed_p2 *= min_signal_needed_p2;
+
+    /* Check sigmaEstimateP2
+     * If this value is too high there is not enough signal rate
+     * to calculate dmax value so set a suitable value to ensure
+     * a very small dmax.
+     */
+    sigma_est_p2_tmp = (sigma_estimate_p2 + 0x8000) >> 16;
+    sigma_est_p2_tmp = (sigma_est_p2_tmp + c_amb_eff_width_sigma_est_ns / 2) /
+                       c_amb_eff_width_sigma_est_ns;
+    sigma_est_p2_tmp *= c_amb_eff_width_d_max_ns;
+
+    if (sigma_est_p2_tmp > 0xffff) {
+        min_signal_needed_p3 = 0xfff00000;
+    } else {
+
+        /* DMAX uses a different ambient width from sigma, so apply
+         * correction.
+         * Perform division before multiplication to prevent overflow.
+         */
+        sigma_estimate_p2 = (sigma_estimate_p2 + c_amb_eff_width_sigma_est_ns / 2) /
+                            c_amb_eff_width_sigma_est_ns;
+        sigma_estimate_p2 *= c_amb_eff_width_d_max_ns;
+
+        /* FixPoint1616 >> 16 = uint32 */
+        min_signal_needed_p3 = (sigma_estimate_p2 + 0x8000) >> 16;
+
+        min_signal_needed_p3 *= min_signal_needed_p3;
+
+    }
+
+    /* FixPoint1814 / uint32 = FixPoint1814 */
+    sigma_limit_tmp = ((c_sigma_limit << 14) + 500) / 1000;
+
+    /* FixPoint1814 * FixPoint1814 = FixPoint3628 := FixPoint0428 */
+    sigma_limit_tmp *= sigma_limit_tmp;
+
+    /* FixPoint1616 * FixPoint1616 = FixPoint3232 */
+    sigma_est_sq_tmp = c_sigma_est_ref * c_sigma_est_ref;
+
+    /* FixPoint3232 >> 4 = FixPoint0428 */
+    sigma_est_sq_tmp = (sigma_est_sq_tmp + 0x08) >> 4;
+
+    /* FixPoint0428 - FixPoint0428	= FixPoint0428 */
+    sigma_limit_tmp -=  sigma_est_sq_tmp;
+
+    /* uint32_t * FixPoint0428 = FixPoint0428 */
+    min_signal_needed_p4 = 4 * 12 * sigma_limit_tmp;
+
+    /* FixPoint0428 >> 14 = FixPoint1814 */
+    min_signal_needed_p4 = (min_signal_needed_p4 + 0x2000) >> 14;
+
+    /* uint32 + uint32 = uint32 */
+    min_signal_needed = (min_signal_needed_p2 + min_signal_needed_p3);
+
+    /* uint32 / uint32 = uint32 */
+    min_signal_needed += (peak_vcsel_duration_us / 2);
+    min_signal_needed /= peak_vcsel_duration_us;
+
+    /* uint32 << 14 = FixPoint1814 */
+    min_signal_needed <<= 14;
+
+    /* FixPoint1814 / FixPoint1814 = uint32 */
+    min_signal_needed += (min_signal_needed_p4 / 2);
+    min_signal_needed /= min_signal_needed_p4;
+
+    /* FixPoint3200 * FixPoint2804 := FixPoint2804*/
+    min_signal_needed *= min_signal_needed_p1;
+
+    /* Apply correction by dividing by 1000000.
+     * This assumes 10E16 on the numerator of the equation
+     * and 10E-22 on the denominator.
+     * We do this because 32bit fix point calculation can't
+     * handle the larger and smaller elements of this equation,
+     * i.e. speed of light and pulse widths.
+     */
+    min_signal_needed = (min_signal_needed + 500) / 1000;
+    min_signal_needed <<= 4;
+
+    min_signal_needed = (min_signal_needed + 500) / 1000;
+
+    /* FixPoint1616 >> 8 = FixPoint2408 */
+    signal_limit_tmp = (c_signal_limit + 0x80) >> 8;
+
+    /* FixPoint2408/FixPoint2408 = uint32 */
+    if (signal_limit_tmp != 0) {
+        dmax_dark_tmp = (signal_at0_mm + (signal_limit_tmp / 2))
+                        / signal_limit_tmp;
+    } else {
+        dmax_dark_tmp = 0;
+    }
+
+    dmax_dark = VL53L0X_isqrt(dmax_dark_tmp);
+
+    /* FixPoint2408/FixPoint2408 = uint32 */
+    if (min_signal_needed != 0) {
+        dmax_ambient = (signal_at0_mm + min_signal_needed / 2)
+                       / min_signal_needed;
+    } else {
+        dmax_ambient = 0;
+    }
+
+    dmax_ambient = VL53L0X_isqrt(dmax_ambient);
+
+    *pd_max_mm = dmax_dark;
+    if (dmax_dark > dmax_ambient) {
+        *pd_max_mm = dmax_ambient;
+    }
+
+    LOG_FUNCTION_END(status);
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_calc_sigma_estimate(VL53L0X_DEV dev,
+        VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data,
+        FixPoint1616_t *p_sigma_estimate,
+        uint32_t *p_dmax_mm)
+{
+    /* Expressed in 100ths of a ns, i.e. centi-ns */
+    const uint32_t c_pulse_effective_width_centi_ns   = 800;
+    /* Expressed in 100ths of a ns, i.e. centi-ns */
+    const uint32_t c_ambient_effective_width_centi_ns = 600;
+    const FixPoint1616_t c_dflt_final_range_integration_time_milli_secs	= 0x00190000; /* 25ms */
+    const uint32_t c_vcsel_pulse_width_ps	= 4700; /* pico secs */
+    const FixPoint1616_t c_sigma_est_max	= 0x028F87AE;
+    const FixPoint1616_t c_sigma_est_rtn_max	= 0xF000;
+    const FixPoint1616_t c_amb_to_signal_ratio_max = 0xF0000000 /
+            c_ambient_effective_width_centi_ns;
+    /* Time Of Flight per mm (6.6 pico secs) */
+    const FixPoint1616_t c_tof_per_mm_ps		= 0x0006999A;
+    const uint32_t c_16bit_rounding_param		= 0x00008000;
+    const FixPoint1616_t c_max_x_talk_kcps		= 0x00320000;
+    const uint32_t c_pll_period_ps			= 1655;
+
+    uint32_t vcsel_total_events_rtn;
+    uint32_t final_range_timeout_micro_secs;
+    uint32_t pre_range_timeout_micro_secs;
+    uint32_t final_range_integration_time_milli_secs;
+    FixPoint1616_t sigma_estimate_p1;
+    FixPoint1616_t sigma_estimate_p2;
+    FixPoint1616_t sigma_estimate_p3;
+    FixPoint1616_t delta_t_ps;
+    FixPoint1616_t pw_mult;
+    FixPoint1616_t sigma_est_rtn;
+    FixPoint1616_t sigma_estimate;
+    FixPoint1616_t x_talk_correction;
+    FixPoint1616_t ambient_rate_kcps;
+    FixPoint1616_t peak_signal_rate_kcps;
+    FixPoint1616_t x_talk_comp_rate_mcps;
+    uint32_t x_talk_comp_rate_kcps;
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    FixPoint1616_t diff1_mcps;
+    FixPoint1616_t diff2_mcps;
+    FixPoint1616_t sqr1;
+    FixPoint1616_t sqr2;
+    FixPoint1616_t sqr_sum;
+    FixPoint1616_t sqrt_result_centi_ns;
+    FixPoint1616_t sqrt_result;
+    FixPoint1616_t total_signal_rate_mcps;
+    FixPoint1616_t corrected_signal_rate_mcps;
+    FixPoint1616_t sigma_est_ref;
+    uint32_t vcsel_width;
+    uint32_t final_range_macro_pclks;
+    uint32_t pre_range_macro_pclks;
+    uint32_t peak_vcsel_duration_us;
+    uint8_t final_range_vcsel_pclks;
+    uint8_t pre_range_vcsel_pclks;
+    /*! \addtogroup calc_sigma_estimate
+     * @{
+     *
+     * Estimates the range sigma
+     */
+
+    LOG_FUNCTION_START("");
+
+    VL53L0X_GETPARAMETERFIELD(dev, XTalkCompensationRateMegaCps,
+                              x_talk_comp_rate_mcps);
+
+    /*
+     * We work in kcps rather than mcps as this helps keep within the
+     * confines of the 32 Fix1616 type.
+     */
+
+    ambient_rate_kcps =
+        (p_ranging_measurement_data->AmbientRateRtnMegaCps * 1000) >> 16;
+
+    corrected_signal_rate_mcps =
+        p_ranging_measurement_data->SignalRateRtnMegaCps;
+
+
+    status = VL53L0X_get_total_signal_rate(
+                 dev, p_ranging_measurement_data, &total_signal_rate_mcps);
+    status = VL53L0X_get_total_xtalk_rate(
+                 dev, p_ranging_measurement_data, &x_talk_comp_rate_mcps);
+
+
+    /* Signal rate measurement provided by device is the
+     * peak signal rate, not average.
+     */
+    peak_signal_rate_kcps = (total_signal_rate_mcps * 1000);
+    peak_signal_rate_kcps = (peak_signal_rate_kcps + 0x8000) >> 16;
+
+    x_talk_comp_rate_kcps = x_talk_comp_rate_mcps * 1000;
+
+    if (x_talk_comp_rate_kcps > c_max_x_talk_kcps) {
+        x_talk_comp_rate_kcps = c_max_x_talk_kcps;
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+
+        /* Calculate final range macro periods */
+        final_range_timeout_micro_secs = VL53L0X_GETDEVICESPECIFICPARAMETER(
+                                             dev, FinalRangeTimeoutMicroSecs);
+
+        final_range_vcsel_pclks = VL53L0X_GETDEVICESPECIFICPARAMETER(
+                                      dev, FinalRangeVcselPulsePeriod);
+
+        final_range_macro_pclks = VL53L0X_calc_timeout_mclks(
+                                      dev, final_range_timeout_micro_secs, final_range_vcsel_pclks);
+
+        /* Calculate pre-range macro periods */
+        pre_range_timeout_micro_secs = VL53L0X_GETDEVICESPECIFICPARAMETER(
+                                           dev, PreRangeTimeoutMicroSecs);
+
+        pre_range_vcsel_pclks = VL53L0X_GETDEVICESPECIFICPARAMETER(
+                                    dev, PreRangeVcselPulsePeriod);
+
+        pre_range_macro_pclks = VL53L0X_calc_timeout_mclks(
+                                    dev, pre_range_timeout_micro_secs, pre_range_vcsel_pclks);
+
+        vcsel_width = 3;
+        if (final_range_vcsel_pclks == 8) {
+            vcsel_width = 2;
+        }
+
+
+        peak_vcsel_duration_us = vcsel_width * 2048 *
+                                 (pre_range_macro_pclks + final_range_macro_pclks);
+        peak_vcsel_duration_us = (peak_vcsel_duration_us + 500) / 1000;
+        peak_vcsel_duration_us *= c_pll_period_ps;
+        peak_vcsel_duration_us = (peak_vcsel_duration_us + 500) / 1000;
+
+        /* Fix1616 >> 8 = Fix2408 */
+        total_signal_rate_mcps = (total_signal_rate_mcps + 0x80) >> 8;
+
+        /* Fix2408 * uint32 = Fix2408 */
+        vcsel_total_events_rtn = total_signal_rate_mcps *
+                                 peak_vcsel_duration_us;
+
+        /* Fix2408 >> 8 = uint32 */
+        vcsel_total_events_rtn = (vcsel_total_events_rtn + 0x80) >> 8;
+
+        /* Fix2408 << 8 = Fix1616 = */
+        total_signal_rate_mcps <<= 8;
+    }
+
+    if (status != VL53L0X_ERROR_NONE) {
+        LOG_FUNCTION_END(status);
+        return status;
+    }
+
+    if (peak_signal_rate_kcps == 0) {
+        *p_sigma_estimate = c_sigma_est_max;
+        PALDevDataSet(dev, SigmaEstimate, c_sigma_est_max);
+        *p_dmax_mm = 0;
+    } else {
+        if (vcsel_total_events_rtn < 1) {
+            vcsel_total_events_rtn = 1;
+        }
+
+        sigma_estimate_p1 = c_pulse_effective_width_centi_ns;
+
+        /* ((FixPoint1616 << 16)* uint32)/uint32 = FixPoint1616 */
+        sigma_estimate_p2 = (ambient_rate_kcps << 16) / peak_signal_rate_kcps;
+        if (sigma_estimate_p2 > c_amb_to_signal_ratio_max) {
+            /* Clip to prevent overflow. Will ensure safe
+             * max result. */
+            sigma_estimate_p2 = c_amb_to_signal_ratio_max;
+        }
+        sigma_estimate_p2 *= c_ambient_effective_width_centi_ns;
+
+        sigma_estimate_p3 = 2 * VL53L0X_isqrt(vcsel_total_events_rtn * 12);
+
+        /* uint32 * FixPoint1616 = FixPoint1616 */
+        delta_t_ps = p_ranging_measurement_data->RangeMilliMeter *
+                     c_tof_per_mm_ps;
+
+        /*
+         * vcselRate - xtalkCompRate
+         * (uint32 << 16) - FixPoint1616 = FixPoint1616.
+         * Divide result by 1000 to convert to mcps.
+         * 500 is added to ensure rounding when integer division
+         * truncates.
+         */
+        diff1_mcps = (((peak_signal_rate_kcps << 16) -
+                       2 * x_talk_comp_rate_kcps) + 500) / 1000;
+
+        /* vcselRate + xtalkCompRate */
+        diff2_mcps = ((peak_signal_rate_kcps << 16) + 500) / 1000;
+
+        /* Shift by 8 bits to increase resolution prior to the
+         * division */
+        diff1_mcps <<= 8;
+
+        /* FixPoint0824/FixPoint1616 = FixPoint2408 */
+//		xTalkCorrection	 = abs(diff1_mcps/diff2_mcps);
+// abs is causing compiler overloading isue in C++, but unsigned types. So, redundant call anyway!
+        x_talk_correction	 = diff1_mcps / diff2_mcps;
+
+        /* FixPoint2408 << 8 = FixPoint1616 */
+        x_talk_correction <<= 8;
+
+        if (p_ranging_measurement_data->RangeStatus != 0) {
+            pw_mult = 1 << 16;
+        } else {
+            /* FixPoint1616/uint32 = FixPoint1616 */
+            pw_mult = delta_t_ps / c_vcsel_pulse_width_ps; /* smaller than 1.0f */
+
+            /*
+             * FixPoint1616 * FixPoint1616 = FixPoint3232, however both
+             * values are small enough such that32 bits will not be
+             * exceeded.
+             */
+            pw_mult *= ((1 << 16) - x_talk_correction);
+
+            /* (FixPoint3232 >> 16) = FixPoint1616 */
+            pw_mult = (pw_mult + c_16bit_rounding_param) >> 16;
+
+            /* FixPoint1616 + FixPoint1616 = FixPoint1616 */
+            pw_mult += (1 << 16);
+
+            /*
+             * At this point the value will be 1.xx, therefore if we square
+             * the value this will exceed 32 bits. To address this perform
+             * a single shift to the right before the multiplication.
+             */
+            pw_mult >>= 1;
+            /* FixPoint1715 * FixPoint1715 = FixPoint3430 */
+            pw_mult = pw_mult * pw_mult;
+
+            /* (FixPoint3430 >> 14) = Fix1616 */
+            pw_mult >>= 14;
+        }
+
+        /* FixPoint1616 * uint32 = FixPoint1616 */
+        sqr1 = pw_mult * sigma_estimate_p1;
+
+        /* (FixPoint1616 >> 16) = FixPoint3200 */
+        sqr1 = (sqr1 + 0x8000) >> 16;
+
+        /* FixPoint3200 * FixPoint3200 = FixPoint6400 */
+        sqr1 *= sqr1;
+
+        sqr2 = sigma_estimate_p2;
+
+        /* (FixPoint1616 >> 16) = FixPoint3200 */
+        sqr2 = (sqr2 + 0x8000) >> 16;
+
+        /* FixPoint3200 * FixPoint3200 = FixPoint6400 */
+        sqr2 *= sqr2;
+
+        /* FixPoint64000 + FixPoint6400 = FixPoint6400 */
+        sqr_sum = sqr1 + sqr2;
+
+        /* SQRT(FixPoin6400) = FixPoint3200 */
+        sqrt_result_centi_ns = VL53L0X_isqrt(sqr_sum);
+
+        /* (FixPoint3200 << 16) = FixPoint1616 */
+        sqrt_result_centi_ns <<= 16;
+
+        /*
+         * Note that the Speed Of Light is expressed in um per 1E-10
+         * seconds (2997) Therefore to get mm/ns we have to divide by
+         * 10000
+         */
+        sigma_est_rtn = (((sqrt_result_centi_ns + 50) / 100) /
+                         sigma_estimate_p3);
+        sigma_est_rtn		 *= VL53L0X_SPEED_OF_LIGHT_IN_AIR;
+
+        /* Add 5000 before dividing by 10000 to ensure rounding. */
+        sigma_est_rtn		 += 5000;
+        sigma_est_rtn		 /= 10000;
+
+        if (sigma_est_rtn > c_sigma_est_rtn_max) {
+            /* Clip to prevent overflow. Will ensure safe
+             * max result. */
+            sigma_est_rtn = c_sigma_est_rtn_max;
+        }
+        final_range_integration_time_milli_secs =
+            (final_range_timeout_micro_secs + pre_range_timeout_micro_secs + 500) / 1000;
+
+        /* sigmaEstRef = 1mm * 25ms/final range integration time (inc pre-range)
+         * sqrt(FixPoint1616/int) = FixPoint2408)
+         */
+        sigma_est_ref =
+            VL53L0X_isqrt((c_dflt_final_range_integration_time_milli_secs +
+                           final_range_integration_time_milli_secs / 2) /
+                          final_range_integration_time_milli_secs);
+
+        /* FixPoint2408 << 8 = FixPoint1616 */
+        sigma_est_ref <<= 8;
+        sigma_est_ref = (sigma_est_ref + 500) / 1000;
+
+        /* FixPoint1616 * FixPoint1616 = FixPoint3232 */
+        sqr1 = sigma_est_rtn * sigma_est_rtn;
+        /* FixPoint1616 * FixPoint1616 = FixPoint3232 */
+        sqr2 = sigma_est_ref * sigma_est_ref;
+
+        /* sqrt(FixPoint3232) = FixPoint1616 */
+        sqrt_result = VL53L0X_isqrt((sqr1 + sqr2));
+        /*
+         * Note that the Shift by 4 bits increases resolution prior to
+         * the sqrt, therefore the result must be shifted by 2 bits to
+         * the right to revert back to the FixPoint1616 format.
+         */
+
+        sigma_estimate	 = 1000 * sqrt_result;
+
+        if ((peak_signal_rate_kcps < 1) || (vcsel_total_events_rtn < 1) ||
+                (sigma_estimate > c_sigma_est_max)) {
+            sigma_estimate = c_sigma_est_max;
+        }
+
+        *p_sigma_estimate = (uint32_t)(sigma_estimate);
+        PALDevDataSet(dev, SigmaEstimate, *p_sigma_estimate);
+        status = VL53L0X_calc_dmax(
+                     dev,
+                     total_signal_rate_mcps,
+                     corrected_signal_rate_mcps,
+                     pw_mult,
+                     sigma_estimate_p1,
+                     sigma_estimate_p2,
+                     peak_vcsel_duration_us,
+                     p_dmax_mm);
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_pal_range_status(VL53L0X_DEV dev,
+        uint8_t device_range_status,
+        FixPoint1616_t signal_rate,
+        uint16_t effective_spad_rtn_count,
+        VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data,
+        uint8_t *p_pal_range_status)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t none_flag;
+    uint8_t sigma_limitflag = 0;
+    uint8_t signal_ref_clipflag = 0;
+    uint8_t range_ignore_thresholdflag = 0;
+    uint8_t sigma_limit_check_enable = 0;
+    uint8_t signal_rate_final_range_limit_check_enable = 0;
+    uint8_t signal_ref_clip_limit_check_enable = 0;
+    uint8_t range_ignore_threshold_limit_check_enable = 0;
+    FixPoint1616_t sigma_estimate;
+    FixPoint1616_t sigma_limit_value;
+    FixPoint1616_t signal_ref_clip_value;
+    FixPoint1616_t range_ignore_threshold_value;
+    FixPoint1616_t signal_rate_per_spad;
+    uint8_t device_range_status_internal = 0;
+    uint16_t tmp_word = 0;
+    uint8_t temp8;
+    uint32_t dmax_mm = 0;
+    FixPoint1616_t last_signal_ref_mcps;
+
+    LOG_FUNCTION_START("");
+
+
+    /*
+     * VL53L0X has a good ranging when the value of the
+     * DeviceRangeStatus = 11. This function will replace the value 0 with
+     * the value 11 in the DeviceRangeStatus.
+     * In addition, the SigmaEstimator is not included in the VL53L0X
+     * DeviceRangeStatus, this will be added in the PalRangeStatus.
+     */
+
+    device_range_status_internal = ((device_range_status & 0x78) >> 3);
+
+    if (device_range_status_internal == 0 ||
+            device_range_status_internal == 5 ||
+            device_range_status_internal == 7 ||
+            device_range_status_internal == 12 ||
+            device_range_status_internal == 13 ||
+            device_range_status_internal == 14 ||
+            device_range_status_internal == 15
+       ) {
+        none_flag = 1;
+    } else {
+        none_flag = 0;
+    }
+
+    /*
+     * Check if Sigma limit is enabled, if yes then do comparison with limit
+     * value and put the result back into pPalRangeStatus.
+     */
+    if (status == VL53L0X_ERROR_NONE) {
+        status =  VL53L0X_get_limit_check_enable(dev,
+                  VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,
+                  &sigma_limit_check_enable);
+    }
+
+    if ((sigma_limit_check_enable != 0) && (status == VL53L0X_ERROR_NONE)) {
+        /*
+        * compute the Sigma and check with limit
+        */
+        status = VL53L0X_calc_sigma_estimate(
+                     dev,
+                     p_ranging_measurement_data,
+                     &sigma_estimate,
+                     &dmax_mm);
+        if (status == VL53L0X_ERROR_NONE) {
+            p_ranging_measurement_data->RangeDMaxMilliMeter = dmax_mm;
+        }
+
+        if (status == VL53L0X_ERROR_NONE) {
+            status = VL53L0X_get_limit_check_value(dev,
+                                                   VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,
+                                                   &sigma_limit_value);
+
+            if ((sigma_limit_value > 0) &&
+                    (sigma_estimate > sigma_limit_value)) {
+                /* Limit Fail */
+                sigma_limitflag = 1;
+            }
+        }
+    }
+
+    /*
+     * Check if Signal ref clip limit is enabled, if yes then do comparison
+     * with limit value and put the result back into pPalRangeStatus.
+     */
+    if (status == VL53L0X_ERROR_NONE) {
+        status =  VL53L0X_get_limit_check_enable(dev,
+                  VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP,
+                  &signal_ref_clip_limit_check_enable);
+    }
+
+    if ((signal_ref_clip_limit_check_enable != 0) &&
+            (status == VL53L0X_ERROR_NONE)) {
+
+        status = VL53L0X_get_limit_check_value(dev,
+                                               VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP,
+                                               &signal_ref_clip_value);
+
+        /* Read LastSignalRefMcps from device */
+        if (status == VL53L0X_ERROR_NONE) {
+            status = VL53L0X_write_byte(dev, 0xFF, 0x01);
+        }
+
+        if (status == VL53L0X_ERROR_NONE) {
+            status = VL53L0X_read_word(dev,
+                                       VL53L0X_REG_RESULT_PEAK_SIGNAL_RATE_REF,
+                                       &tmp_word);
+        }
+
+        if (status == VL53L0X_ERROR_NONE) {
+            status = VL53L0X_write_byte(dev, 0xFF, 0x00);
+        }
+
+        last_signal_ref_mcps = VL53L0X_FIXPOINT97TOFIXPOINT1616(tmp_word);
+        PALDevDataSet(dev, LastSignalRefMcps, last_signal_ref_mcps);
+
+        if ((signal_ref_clip_value > 0) &&
+                (last_signal_ref_mcps > signal_ref_clip_value)) {
+            /* Limit Fail */
+            signal_ref_clipflag = 1;
+        }
+    }
+
+    /*
+     * Check if Signal ref clip limit is enabled, if yes then do comparison
+     * with limit value and put the result back into pPalRangeStatus.
+     * EffectiveSpadRtnCount has a format 8.8
+     * If (Return signal rate < (1.5 x Xtalk x number of Spads)) : FAIL
+     */
+    if (status == VL53L0X_ERROR_NONE) {
+        status =  VL53L0X_get_limit_check_enable(dev,
+                  VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD,
+                  &range_ignore_threshold_limit_check_enable);
+    }
+
+    if ((range_ignore_threshold_limit_check_enable != 0) &&
+            (status == VL53L0X_ERROR_NONE)) {
+
+        /* Compute the signal rate per spad */
+        if (effective_spad_rtn_count == 0) {
+            signal_rate_per_spad = 0;
+        } else {
+            signal_rate_per_spad = (FixPoint1616_t)((256 * signal_rate)
+                                                    / effective_spad_rtn_count);
+        }
+
+        status = VL53L0X_get_limit_check_value(dev,
+                                               VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD,
+                                               &range_ignore_threshold_value);
+
+        if ((range_ignore_threshold_value > 0) &&
+                (signal_rate_per_spad < range_ignore_threshold_value)) {
+            /* Limit Fail add 2^6 to range status */
+            range_ignore_thresholdflag = 1;
+        }
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        if (none_flag == 1) {
+            *p_pal_range_status = 255;	 /* NONE */
+        } else if (device_range_status_internal == 1 ||
+                   device_range_status_internal == 2 ||
+                   device_range_status_internal == 3) {
+            *p_pal_range_status = 5; /* HW fail */
+        } else if (device_range_status_internal == 6 ||
+                   device_range_status_internal == 9) {
+            *p_pal_range_status = 4;  /* Phase fail */
+        } else if (device_range_status_internal == 8 ||
+                   device_range_status_internal == 10 ||
+                   signal_ref_clipflag == 1) {
+            *p_pal_range_status = 3;  /* Min range */
+        } else if (device_range_status_internal == 4 ||
+                   range_ignore_thresholdflag == 1) {
+            *p_pal_range_status = 2;  /* Signal Fail */
+        } else if (sigma_limitflag == 1) {
+            *p_pal_range_status = 1;  /* Sigma	 Fail */
+        } else {
+            *p_pal_range_status = 0; /* Range Valid */
+        }
+    }
+
+    /* DMAX only relevant during range error */
+    if (*p_pal_range_status == 0) {
+        p_ranging_measurement_data->RangeDMaxMilliMeter = 0;
+    }
+
+    /* fill the Limit Check Status */
+
+    status =  VL53L0X_get_limit_check_enable(dev,
+              VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
+              &signal_rate_final_range_limit_check_enable);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        if ((sigma_limit_check_enable == 0) || (sigma_limitflag == 1)) {
+            temp8 = 1;
+        } else {
+            temp8 = 0;
+        }
+        VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksStatus,
+                                       VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, temp8);
+
+        if ((device_range_status_internal == 4) ||
+                (signal_rate_final_range_limit_check_enable == 0)) {
+            temp8 = 1;
+        } else {
+            temp8 = 0;
+        }
+        VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksStatus,
+                                       VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
+                                       temp8);
+
+        if ((signal_ref_clip_limit_check_enable == 0) ||
+                (signal_ref_clipflag == 1)) {
+            temp8 = 1;
+        } else {
+            temp8 = 0;
+        }
+
+        VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksStatus,
+                                       VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, temp8);
+
+        if ((range_ignore_threshold_limit_check_enable == 0) ||
+                (range_ignore_thresholdflag == 1)) {
+            temp8 = 1;
+        } else {
+            temp8 = 0;
+        }
+
+        VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksStatus,
+                                       VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD,
+                                       temp8);
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_ranging_measurement_data(VL53L0X_DEV dev,
+        VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t device_range_status;
+    uint8_t range_fractional_enable;
+    uint8_t pal_range_status;
+    uint8_t x_talk_compensation_enable;
+    uint16_t ambient_rate;
+    FixPoint1616_t signal_rate;
+    uint16_t x_talk_compensation_rate_mega_cps;
+    uint16_t effective_spad_rtn_count;
+    uint16_t tmpuint16;
+    uint16_t xtalk_range_milli_meter;
+    uint16_t linearity_corrective_gain;
+    uint8_t localBuffer[12];
+    VL53L0X_RangingMeasurementData_t last_range_data_buffer;
+
+    LOG_FUNCTION_START("");
+
+    /*
+     * use multi read even if some registers are not useful, result will
+     * be more efficient
+     * start reading at 0x14 dec20
+     * end reading at 0x21 dec33 total 14 bytes to read
+     */
+    status = VL53L0X_read_multi(dev, 0x14, localBuffer, 12);
+
+    if (status == VL53L0X_ERROR_NONE) {
+
+        p_ranging_measurement_data->ZoneId = 0; /* Only one zone */
+        p_ranging_measurement_data->TimeStamp = 0; /* Not Implemented */
+
+        tmpuint16 = VL53L0X_MAKEUINT16(localBuffer[11], localBuffer[10]);
+        /* cut1.1 if SYSTEM__RANGE_CONFIG if 1 range is 2bits fractional
+         *(format 11.2) else no fractional
+         */
+
+        p_ranging_measurement_data->MeasurementTimeUsec = 0;
+
+        signal_rate = VL53L0X_FIXPOINT97TOFIXPOINT1616(
+                          VL53L0X_MAKEUINT16(localBuffer[7], localBuffer[6]));
+        /* peak_signal_count_rate_rtn_mcps */
+        p_ranging_measurement_data->SignalRateRtnMegaCps = signal_rate;
+
+        ambient_rate = VL53L0X_MAKEUINT16(localBuffer[9], localBuffer[8]);
+        p_ranging_measurement_data->AmbientRateRtnMegaCps =
+            VL53L0X_FIXPOINT97TOFIXPOINT1616(ambient_rate);
+
+        effective_spad_rtn_count = VL53L0X_MAKEUINT16(localBuffer[3],
+                                   localBuffer[2]);
+        /* EffectiveSpadRtnCount is 8.8 format */
+        p_ranging_measurement_data->EffectiveSpadRtnCount =
+            effective_spad_rtn_count;
+
+        device_range_status = localBuffer[0];
+
+        /* Get Linearity Corrective Gain */
+        linearity_corrective_gain = PALDevDataGet(dev,
+                                    LinearityCorrectiveGain);
+
+        /* Get ranging configuration */
+        range_fractional_enable = PALDevDataGet(dev,
+                                                RangeFractionalEnable);
+
+        if (linearity_corrective_gain != 1000) {
+
+            tmpuint16 = (uint16_t)((linearity_corrective_gain
+                                    * tmpuint16 + 500) / 1000);
+
+            /* Implement Xtalk */
+            VL53L0X_GETPARAMETERFIELD(dev,
+                                      XTalkCompensationRateMegaCps,
+                                      x_talk_compensation_rate_mega_cps);
+            VL53L0X_GETPARAMETERFIELD(dev, XTalkCompensationEnable,
+                                      x_talk_compensation_enable);
+
+            if (x_talk_compensation_enable) {
+
+                if ((signal_rate
+                        - ((x_talk_compensation_rate_mega_cps
+                            * effective_spad_rtn_count) >> 8))
+                        <= 0) {
+                    if (range_fractional_enable) {
+                        xtalk_range_milli_meter = 8888;
+                    } else {
+                        xtalk_range_milli_meter = 8888 << 2;
+                    }
+                } else {
+                    xtalk_range_milli_meter =
+                        (tmpuint16 * signal_rate)
+                        / (signal_rate
+                           - ((x_talk_compensation_rate_mega_cps
+                               * effective_spad_rtn_count)
+                              >> 8));
+                }
+
+                tmpuint16 = xtalk_range_milli_meter;
+            }
+
+        }
+
+        if (range_fractional_enable) {
+            p_ranging_measurement_data->RangeMilliMeter =
+                (uint16_t)((tmpuint16) >> 2);
+            p_ranging_measurement_data->RangeFractionalPart =
+                (uint8_t)((tmpuint16 & 0x03) << 6);
+        } else {
+            p_ranging_measurement_data->RangeMilliMeter = tmpuint16;
+            p_ranging_measurement_data->RangeFractionalPart = 0;
+        }
+
+        /*
+         * For a standard definition of RangeStatus, this should
+         * return 0 in case of good result after a ranging
+         * The range status depends on the device so call a device
+         * specific function to obtain the right Status.
+         */
+        status |= VL53L0X_get_pal_range_status(dev, device_range_status,
+                                               signal_rate, effective_spad_rtn_count,
+                                               p_ranging_measurement_data, &pal_range_status);
+
+        if (status == VL53L0X_ERROR_NONE) {
+            p_ranging_measurement_data->RangeStatus = pal_range_status;
+        }
+
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        /* Copy last read data into Dev buffer */
+        last_range_data_buffer = PALDevDataGet(dev, LastRangeMeasure);
+
+        last_range_data_buffer.RangeMilliMeter =
+            p_ranging_measurement_data->RangeMilliMeter;
+        last_range_data_buffer.RangeFractionalPart =
+            p_ranging_measurement_data->RangeFractionalPart;
+        last_range_data_buffer.RangeDMaxMilliMeter =
+            p_ranging_measurement_data->RangeDMaxMilliMeter;
+        last_range_data_buffer.MeasurementTimeUsec =
+            p_ranging_measurement_data->MeasurementTimeUsec;
+        last_range_data_buffer.SignalRateRtnMegaCps =
+            p_ranging_measurement_data->SignalRateRtnMegaCps;
+        last_range_data_buffer.AmbientRateRtnMegaCps =
+            p_ranging_measurement_data->AmbientRateRtnMegaCps;
+        last_range_data_buffer.EffectiveSpadRtnCount =
+            p_ranging_measurement_data->EffectiveSpadRtnCount;
+        last_range_data_buffer.RangeStatus =
+            p_ranging_measurement_data->RangeStatus;
+
+        PALDevDataSet(dev, LastRangeMeasure, last_range_data_buffer);
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_perform_single_ranging_measurement(VL53L0X_DEV dev,
+        VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+
+    LOG_FUNCTION_START("");
+
+    /* This function will do a complete single ranging
+     * Here we fix the mode! */
+    status = VL53L0X_set_device_mode(dev, VL53L0X_DEVICEMODE_SINGLE_RANGING);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_perform_single_measurement(dev);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_get_ranging_measurement_data(dev,
+                 p_ranging_measurement_data);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_clear_interrupt_mask(dev, 0);
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::perform_ref_signal_measurement(VL53L0X_DEV dev,
+        uint16_t *p_ref_signal_rate)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    VL53L0X_RangingMeasurementData_t ranging_measurement_data;
+
+    uint8_t sequence_config = 0;
+
+    /* store the value of the sequence config,
+     * this will be reset before the end of the function
+     */
+
+    sequence_config = PALDevDataGet(dev, SequenceConfig);
+
+    /*
+     * This function performs a reference signal rate measurement.
+     */
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev,
+                                    VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, 0xC0);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_perform_single_ranging_measurement(dev,
+                 &ranging_measurement_data);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev, 0xFF, 0x01);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_read_word(dev,
+                                   VL53L0X_REG_RESULT_PEAK_SIGNAL_RATE_REF,
+                                   p_ref_signal_rate);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev, 0xFF, 0x00);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        /* restore the previous Sequence Config */
+        status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
+                                    sequence_config);
+        if (status == VL53L0X_ERROR_NONE) {
+            PALDevDataSet(dev, SequenceConfig, sequence_config);
+        }
+    }
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::wrapped_VL53L0X_perform_ref_spad_management(VL53L0X_DEV dev,
+        uint32_t *ref_spad_count,
+        uint8_t *is_aperture_spads)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t last_spad_array[6];
+    uint8_t start_select = 0xB4;
+    uint32_t minimum_spad_count = 3;
+    uint32_t max_spad_count = 44;
+    uint32_t current_spad_index = 0;
+    uint32_t last_spad_index = 0;
+    int32_t next_good_spad = 0;
+    uint16_t target_ref_rate = 0x0A00; /* 20 MCPS in 9:7 format */
+    uint16_t peak_signal_rate_ref;
+    uint32_t need_apt_spads = 0;
+    uint32_t index = 0;
+    uint32_t spad_array_size = 6;
+    uint32_t signal_rate_diff = 0;
+    uint32_t last_signal_rate_diff = 0;
+    uint8_t complete = 0;
+    uint8_t vhv_settings = 0;
+    uint8_t phase_cal = 0;
+    uint32_t ref_spad_count_int = 0;
+    uint8_t	 is_aperture_spads_int = 0;
+
+    /*
+     * The reference SPAD initialization procedure determines the minimum
+     * amount of reference spads to be enables to achieve a target reference
+     * signal rate and should be performed once during initialization.
+     *
+     * Either aperture or non-aperture spads are applied but never both.
+     * Firstly non-aperture spads are set, begining with 5 spads, and
+     * increased one spad at a time until the closest measurement to the
+     * target rate is achieved.
+     *
+     * If the target rate is exceeded when 5 non-aperture spads are enabled,
+     * initialization is performed instead with aperture spads.
+     *
+     * When setting spads, a 'Good Spad Map' is applied.
+     *
+     * This procedure operates within a SPAD window of interest of a maximum
+     * 44 spads.
+     * The start point is currently fixed to 180, which lies towards the end
+     * of the non-aperture quadrant and runs in to the adjacent aperture
+     * quadrant.
+     */
+    target_ref_rate = PALDevDataGet(dev, targetRefRate);
+
+    /*
+     * Initialize Spad arrays.
+     * Currently the good spad map is initialised to 'All good'.
+     * This is a short term implementation. The good spad map will be
+     * provided as an input.
+     * Note that there are 6 bytes. Only the first 44 bits will be used to
+     * represent spads.
+     */
+    for (index = 0; index < spad_array_size; index++) {
+        dev->Data.SpadData.RefSpadEnables[index] = 0;
+    }
+
+
+    status = VL53L0X_write_byte(dev, 0xFF, 0x01);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev,
+                                    VL53L0X_REG_DYNAMIC_SPAD_REF_EN_START_OFFSET, 0x00);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev,
+                                    VL53L0X_REG_DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD, 0x2C);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev, 0xFF, 0x00);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev,
+                                    VL53L0X_REG_GLOBAL_CONFIG_REF_EN_START_SELECT,
+                                    start_select);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev,
+                                    VL53L0X_REG_POWER_MANAGEMENT_GO1_POWER_FORCE, 0);
+    }
+
+    /* Perform ref calibration */
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_perform_ref_calibration(dev, &vhv_settings,
+                 &phase_cal, 0);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        /* Enable Minimum NON-APERTURE Spads */
+        current_spad_index = 0;
+        last_spad_index = current_spad_index;
+        need_apt_spads = 0;
+        status = enable_ref_spads(dev,
+                                  need_apt_spads,
+                                  dev->Data.SpadData.RefGoodSpadMap,
+                                  dev->Data.SpadData.RefSpadEnables,
+                                  spad_array_size,
+                                  start_select,
+                                  current_spad_index,
+                                  minimum_spad_count,
+                                  &last_spad_index);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        current_spad_index = last_spad_index;
+
+        status = perform_ref_signal_measurement(dev,
+                                                &peak_signal_rate_ref);
+        if ((status == VL53L0X_ERROR_NONE) &&
+                (peak_signal_rate_ref > target_ref_rate)) {
+            /* Signal rate measurement too high,
+             * switch to APERTURE SPADs */
+
+            for (index = 0; index < spad_array_size; index++) {
+                dev->Data.SpadData.RefSpadEnables[index] = 0;
+            }
+
+
+            /* Increment to the first APERTURE spad */
+            while ((is_aperture(start_select + current_spad_index)
+                    == 0) && (current_spad_index < max_spad_count)) {
+                current_spad_index++;
+            }
+
+            need_apt_spads = 1;
+
+            status = enable_ref_spads(dev,
+                                      need_apt_spads,
+                                      dev->Data.SpadData.RefGoodSpadMap,
+                                      dev->Data.SpadData.RefSpadEnables,
+                                      spad_array_size,
+                                      start_select,
+                                      current_spad_index,
+                                      minimum_spad_count,
+                                      &last_spad_index);
+
+            if (status == VL53L0X_ERROR_NONE) {
+                current_spad_index = last_spad_index;
+                status = perform_ref_signal_measurement(dev,
+                                                        &peak_signal_rate_ref);
+
+                if ((status == VL53L0X_ERROR_NONE) &&
+                        (peak_signal_rate_ref > target_ref_rate)) {
+                    /* Signal rate still too high after
+                     * setting the minimum number of
+                     * APERTURE spads. Can do no more
+                     * therefore set the min number of
+                     * aperture spads as the result.
+                     */
+                    is_aperture_spads_int = 1;
+                    ref_spad_count_int = minimum_spad_count;
+                }
+            }
+        } else {
+            need_apt_spads = 0;
+        }
+    }
+
+    if ((status == VL53L0X_ERROR_NONE) &&
+            (peak_signal_rate_ref < target_ref_rate)) {
+        /* At this point, the minimum number of either aperture
+         * or non-aperture spads have been set. Proceed to add
+         * spads and perform measurements until the target
+         * reference is reached.
+         */
+        is_aperture_spads_int = need_apt_spads;
+        ref_spad_count_int	= minimum_spad_count;
+
+        memcpy(last_spad_array, dev->Data.SpadData.RefSpadEnables,
+               spad_array_size);
+        last_signal_rate_diff = abs(peak_signal_rate_ref -
+                                    target_ref_rate);
+        complete = 0;
+
+        while (!complete) {
+            get_next_good_spad(
+                dev->Data.SpadData.RefGoodSpadMap,
+                spad_array_size, current_spad_index,
+                &next_good_spad);
+
+            if (next_good_spad == -1) {
+                status = VL53L0X_ERROR_REF_SPAD_INIT;
+                break;
+            }
+
+            /* Cannot combine Aperture and Non-Aperture spads, so
+             * ensure the current spad is of the correct type.
+             */
+            if (is_aperture((uint32_t)start_select + next_good_spad) !=
+                    need_apt_spads) {
+                /* At this point we have enabled the maximum
+                 * number of Aperture spads.
+                 */
+                complete = 1;
+                break;
+            }
+
+            (ref_spad_count_int)++;
+
+            current_spad_index = next_good_spad;
+            status = enable_spad_bit(
+                         dev->Data.SpadData.RefSpadEnables,
+                         spad_array_size, current_spad_index);
+
+            if (status == VL53L0X_ERROR_NONE) {
+                current_spad_index++;
+                /* Proceed to apply the additional spad and
+                 * perform measurement. */
+                status = set_ref_spad_map(dev,
+                                          dev->Data.SpadData.RefSpadEnables);
+            }
+
+            if (status != VL53L0X_ERROR_NONE) {
+                break;
+            }
+
+            status = perform_ref_signal_measurement(dev,
+                                                    &peak_signal_rate_ref);
+
+            if (status != VL53L0X_ERROR_NONE) {
+                break;
+            }
+
+            signal_rate_diff = abs(peak_signal_rate_ref - target_ref_rate);
+
+            if (peak_signal_rate_ref > target_ref_rate) {
+                /* Select the spad map that provides the
+                 * measurement closest to the target rate,
+                 * either above or below it.
+                 */
+                if (signal_rate_diff > last_signal_rate_diff) {
+                    /* Previous spad map produced a closer
+                     * measurement, so choose this. */
+                    status = set_ref_spad_map(dev,
+                                              last_spad_array);
+                    memcpy(
+                        dev->Data.SpadData.RefSpadEnables,
+                        last_spad_array, spad_array_size);
+
+                    (ref_spad_count_int)--;
+                }
+                complete = 1;
+            } else {
+                /* Continue to add spads */
+                last_signal_rate_diff = signal_rate_diff;
+                memcpy(last_spad_array,
+                       dev->Data.SpadData.RefSpadEnables,
+                       spad_array_size);
+            }
+
+        } /* while */
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        *ref_spad_count = ref_spad_count_int;
+        *is_aperture_spads = is_aperture_spads_int;
+
+        VL53L0X_SETDEVICESPECIFICPARAMETER(dev, RefSpadsInitialised, 1);
+        VL53L0X_SETDEVICESPECIFICPARAMETER(dev,
+                                           ReferenceSpadCount, (uint8_t)(*ref_spad_count));
+        VL53L0X_SETDEVICESPECIFICPARAMETER(dev,
+                                           ReferenceSpadType, *is_aperture_spads);
+    }
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_set_reference_spads(VL53L0X_DEV dev,
+        uint32_t count, uint8_t is_aperture_spads)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint32_t current_spad_index = 0;
+    uint8_t start_select = 0xB4;
+    uint32_t spad_array_size = 6;
+    uint32_t max_spad_count = 44;
+    uint32_t last_spad_index;
+    uint32_t index;
+
+    /*
+     * This function applies a requested number of reference spads, either
+     * aperture or
+     * non-aperture, as requested.
+     * The good spad map will be applied.
+     */
+
+    status = VL53L0X_write_byte(dev, 0xFF, 0x01);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev,
+                                    VL53L0X_REG_DYNAMIC_SPAD_REF_EN_START_OFFSET, 0x00);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev,
+                                    VL53L0X_REG_DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD, 0x2C);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev, 0xFF, 0x00);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev,
+                                    VL53L0X_REG_GLOBAL_CONFIG_REF_EN_START_SELECT,
+                                    start_select);
+    }
+
+    for (index = 0; index < spad_array_size; index++) {
+        dev->Data.SpadData.RefSpadEnables[index] = 0;
+    }
+
+    if (is_aperture_spads) {
+        /* Increment to the first APERTURE spad */
+        while ((is_aperture(start_select + current_spad_index) == 0) &&
+                (current_spad_index < max_spad_count)) {
+            current_spad_index++;
+        }
+    }
+    status = enable_ref_spads(dev,
+                              is_aperture_spads,
+                              dev->Data.SpadData.RefGoodSpadMap,
+                              dev->Data.SpadData.RefSpadEnables,
+                              spad_array_size,
+                              start_select,
+                              current_spad_index,
+                              count,
+                              &last_spad_index);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        VL53L0X_SETDEVICESPECIFICPARAMETER(dev, RefSpadsInitialised, 1);
+        VL53L0X_SETDEVICESPECIFICPARAMETER(dev,
+                                           ReferenceSpadCount, (uint8_t)(count));
+        VL53L0X_SETDEVICESPECIFICPARAMETER(dev,
+                                           ReferenceSpadType, is_aperture_spads);
+    }
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_wait_device_booted(VL53L0X_DEV dev)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NOT_IMPLEMENTED;
+    LOG_FUNCTION_START("");
+
+    /* not implemented on VL53L0X */
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_perform_ref_calibration(VL53L0X_DEV dev, uint8_t *p_vhv_settings,
+        uint8_t *p_phase_cal)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    LOG_FUNCTION_START("");
+
+    status = VL53L0X_perform_ref_calibration(dev, p_vhv_settings,
+             p_phase_cal, 1);
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_perform_ref_spad_management(VL53L0X_DEV dev,
+        uint32_t *ref_spad_count, uint8_t *is_aperture_spads)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    LOG_FUNCTION_START("");
+
+    status = wrapped_VL53L0X_perform_ref_spad_management(dev, ref_spad_count,
+             is_aperture_spads);
+
+    LOG_FUNCTION_END(status);
+
+    return status;
+}
+
+/* Group PAL Init Functions */
+VL53L0X_Error VL53L0X::VL53L0X_set_device_address(VL53L0X_DEV dev, uint8_t device_address)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    LOG_FUNCTION_START("");
+
+    status = VL53L0X_write_byte(dev, VL53L0X_REG_I2C_SLAVE_DEVICE_ADDRESS,
+                                device_address / 2);
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_set_gpio_config(VL53L0X_DEV dev, uint8_t pin,
+        VL53L0X_DeviceModes device_mode, VL53L0X_GpioFunctionality functionality,
+        VL53L0X_InterruptPolarity polarity)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t data;
+
+    LOG_FUNCTION_START("");
+
+    if (pin != 0) {
+        status = VL53L0X_ERROR_GPIO_NOT_EXISTING;
+    } else if (device_mode == VL53L0X_DEVICEMODE_GPIO_DRIVE) {
+        if (polarity == VL53L0X_INTERRUPTPOLARITY_LOW) {
+            data = 0x10;
+        } else {
+            data = 1;
+        }
+
+        status = VL53L0X_write_byte(dev,
+                                    VL53L0X_REG_GPIO_HV_MUX_ACTIVE_HIGH, data);
+
+    } else {
+        if (device_mode == VL53L0X_DEVICEMODE_GPIO_OSC) {
+
+            status |= VL53L0X_write_byte(dev, 0xff, 0x01);
+            status |= VL53L0X_write_byte(dev, 0x00, 0x00);
+
+            status |= VL53L0X_write_byte(dev, 0xff, 0x00);
+            status |= VL53L0X_write_byte(dev, 0x80, 0x01);
+            status |= VL53L0X_write_byte(dev, 0x85, 0x02);
+
+            status |= VL53L0X_write_byte(dev, 0xff, 0x04);
+            status |= VL53L0X_write_byte(dev, 0xcd, 0x00);
+            status |= VL53L0X_write_byte(dev, 0xcc, 0x11);
+
+            status |= VL53L0X_write_byte(dev, 0xff, 0x07);
+            status |= VL53L0X_write_byte(dev, 0xbe, 0x00);
+
+            status |= VL53L0X_write_byte(dev, 0xff, 0x06);
+            status |= VL53L0X_write_byte(dev, 0xcc, 0x09);
+
+            status |= VL53L0X_write_byte(dev, 0xff, 0x00);
+            status |= VL53L0X_write_byte(dev, 0xff, 0x01);
+            status |= VL53L0X_write_byte(dev, 0x00, 0x00);
+
+        } else {
+
+            if (status == VL53L0X_ERROR_NONE) {
+                switch (functionality) {
+                    case VL53L0X_GPIOFUNCTIONALITY_OFF:
+                        data = 0x00;
+                        break;
+                    case VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW:
+                        data = 0x01;
+                        break;
+                    case VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH:
+                        data = 0x02;
+                        break;
+                    case VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT:
+                        data = 0x03;
+                        break;
+                    case VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY:
+                        data = 0x04;
+                        break;
+                    default:
+                        status =
+                            VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED;
+                }
+            }
+
+            if (status == VL53L0X_ERROR_NONE) {
+                status = VL53L0X_write_byte(dev,
+                                            VL53L0X_REG_SYSTEM_INTERRUPT_CONFIG_GPIO, data);
+            }
+
+            if (status == VL53L0X_ERROR_NONE) {
+                if (polarity == VL53L0X_INTERRUPTPOLARITY_LOW) {
+                    data = 0;
+                } else {
+                    data = (uint8_t)(1 << 4);
+                }
+                status = VL53L0X_update_byte(dev,
+                                             VL53L0X_REG_GPIO_HV_MUX_ACTIVE_HIGH, 0xEF, data);
+            }
+
+            if (status == VL53L0X_ERROR_NONE) {
+                VL53L0X_SETDEVICESPECIFICPARAMETER(dev,
+                                                   Pin0GpioFunctionality, functionality);
+            }
+
+            if (status == VL53L0X_ERROR_NONE) {
+                status = VL53L0X_clear_interrupt_mask(dev, 0);
+            }
+        }
+    }
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_fraction_enable(VL53L0X_DEV dev, uint8_t *p_enabled)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    LOG_FUNCTION_START("");
+
+    status = VL53L0X_read_byte(dev, VL53L0X_REG_SYSTEM_RANGE_CONFIG, p_enabled);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        *p_enabled = (*p_enabled & 1);
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+uint16_t VL53L0X::VL53L0X_encode_timeout(uint32_t timeout_macro_clks)
+{
+    /*!
+     * Encode timeout in macro periods in (LSByte * 2^MSByte) + 1 format
+     */
+
+    uint16_t encoded_timeout = 0;
+    uint32_t ls_byte = 0;
+    uint16_t ms_byte = 0;
+
+    if (timeout_macro_clks > 0) {
+        ls_byte = timeout_macro_clks - 1;
+
+        while ((ls_byte & 0xFFFFFF00) > 0) {
+            ls_byte = ls_byte >> 1;
+            ms_byte++;
+        }
+
+        encoded_timeout = (ms_byte << 8)
+                          + (uint16_t)(ls_byte & 0x000000FF);
+    }
+
+    return encoded_timeout;
+
+}
+
+VL53L0X_Error VL53L0X::set_sequence_step_timeout(VL53L0X_DEV dev,
+        VL53L0X_SequenceStepId sequence_step_id,
+        uint32_t timeout_micro_secs)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t current_vcsel_pulse_period_p_clk;
+    uint8_t msrc_encoded_time_out;
+    uint16_t pre_range_encoded_time_out;
+    uint16_t pre_range_time_out_m_clks;
+    uint16_t msrc_range_time_out_m_clks;
+    uint32_t final_range_time_out_m_clks;
+    uint16_t final_range_encoded_time_out;
+    VL53L0X_SchedulerSequenceSteps_t scheduler_sequence_steps;
+
+    if ((sequence_step_id == VL53L0X_SEQUENCESTEP_TCC)	 ||
+            (sequence_step_id == VL53L0X_SEQUENCESTEP_DSS)	 ||
+            (sequence_step_id == VL53L0X_SEQUENCESTEP_MSRC)) {
+
+        status = VL53L0X_get_vcsel_pulse_period(dev,
+                                                VL53L0X_VCSEL_PERIOD_PRE_RANGE,
+                                                &current_vcsel_pulse_period_p_clk);
+
+        if (status == VL53L0X_ERROR_NONE) {
+            msrc_range_time_out_m_clks = VL53L0X_calc_timeout_mclks(dev,
+                                         timeout_micro_secs,
+                                         (uint8_t)current_vcsel_pulse_period_p_clk);
+
+            if (msrc_range_time_out_m_clks > 256) {
+                msrc_encoded_time_out = 255;
+            } else {
+                msrc_encoded_time_out =
+                    (uint8_t)msrc_range_time_out_m_clks - 1;
+            }
+
+            VL53L0X_SETDEVICESPECIFICPARAMETER(dev,
+                                               LastEncodedTimeout,
+                                               msrc_encoded_time_out);
+        }
+
+        if (status == VL53L0X_ERROR_NONE) {
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_MSRC_CONFIG_TIMEOUT_MACROP,
+                                        msrc_encoded_time_out);
+        }
+    } else {
+
+        if (sequence_step_id == VL53L0X_SEQUENCESTEP_PRE_RANGE) {
+
+            if (status == VL53L0X_ERROR_NONE) {
+                status = VL53L0X_get_vcsel_pulse_period(dev,
+                                                        VL53L0X_VCSEL_PERIOD_PRE_RANGE,
+                                                        &current_vcsel_pulse_period_p_clk);
+                pre_range_time_out_m_clks =
+                    VL53L0X_calc_timeout_mclks(dev,
+                                               timeout_micro_secs,
+                                               (uint8_t)current_vcsel_pulse_period_p_clk);
+                pre_range_encoded_time_out = VL53L0X_encode_timeout(
+                                                 pre_range_time_out_m_clks);
+
+                VL53L0X_SETDEVICESPECIFICPARAMETER(dev,
+                                                   LastEncodedTimeout,
+                                                   pre_range_encoded_time_out);
+            }
+
+            if (status == VL53L0X_ERROR_NONE) {
+                status = VL53L0X_write_word(dev,
+                                            VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI,
+                                            pre_range_encoded_time_out);
+            }
+
+            if (status == VL53L0X_ERROR_NONE) {
+                VL53L0X_SETDEVICESPECIFICPARAMETER(
+                    dev,
+                    PreRangeTimeoutMicroSecs,
+                    timeout_micro_secs);
+            }
+        } else if (sequence_step_id == VL53L0X_SEQUENCESTEP_FINAL_RANGE) {
+
+            /* For the final range timeout, the pre-range timeout
+             * must be added. To do this both final and pre-range
+             * timeouts must be expressed in macro periods MClks
+             * because they have different vcsel periods.
+             */
+
+            VL53L0X_get_sequence_step_enables(dev,
+                                              &scheduler_sequence_steps);
+            pre_range_time_out_m_clks = 0;
+            if (scheduler_sequence_steps.PreRangeOn) {
+
+                /* Retrieve PRE-RANGE VCSEL Period */
+                status = VL53L0X_get_vcsel_pulse_period(dev,
+                                                        VL53L0X_VCSEL_PERIOD_PRE_RANGE,
+                                                        &current_vcsel_pulse_period_p_clk);
+
+                /* Retrieve PRE-RANGE Timeout in Macro periods
+                 * (MCLKS) */
+                if (status == VL53L0X_ERROR_NONE) {
+                    status = VL53L0X_read_word(dev, 0x51,
+                                               &pre_range_encoded_time_out);
+                    pre_range_time_out_m_clks =
+                        VL53L0X_decode_timeout(
+                            pre_range_encoded_time_out);
+                }
+            }
+
+            /* Calculate FINAL RANGE Timeout in Macro Periods
+             * (MCLKS) and add PRE-RANGE value
+             */
+            if (status == VL53L0X_ERROR_NONE) {
+                status = VL53L0X_get_vcsel_pulse_period(dev,
+                                                        VL53L0X_VCSEL_PERIOD_FINAL_RANGE,
+                                                        &current_vcsel_pulse_period_p_clk);
+            }
+            if (status == VL53L0X_ERROR_NONE) {
+                final_range_time_out_m_clks =
+                    VL53L0X_calc_timeout_mclks(dev,
+                                               timeout_micro_secs,
+                                               (uint8_t) current_vcsel_pulse_period_p_clk);
+
+                final_range_time_out_m_clks += pre_range_time_out_m_clks;
+
+                final_range_encoded_time_out =
+                    VL53L0X_encode_timeout(final_range_time_out_m_clks);
+
+                if (status == VL53L0X_ERROR_NONE) {
+                    status = VL53L0X_write_word(dev, 0x71,
+                                                final_range_encoded_time_out);
+                }
+
+                if (status == VL53L0X_ERROR_NONE) {
+                    VL53L0X_SETDEVICESPECIFICPARAMETER(
+                        dev,
+                        FinalRangeTimeoutMicroSecs,
+                        timeout_micro_secs);
+                }
+            }
+        } else {
+            status = VL53L0X_ERROR_INVALID_PARAMS;
+        }
+
+    }
+    return status;
+}
+
+VL53L0X_Error VL53L0X::wrapped_VL53L0X_set_measurement_timing_budget_micro_seconds(VL53L0X_DEV dev,
+        uint32_t measurement_timing_budget_micro_seconds)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint32_t final_range_timing_budget_micro_seconds;
+    VL53L0X_SchedulerSequenceSteps_t scheduler_sequence_steps;
+    uint32_t msrc_dcc_tcc_timeout_micro_seconds	= 2000;
+    uint32_t start_overhead_micro_seconds		= 1910;
+    uint32_t end_overhead_micro_seconds		= 960;
+    uint32_t msrc_overhead_micro_seconds		= 660;
+    uint32_t tcc_overhead_micro_seconds		= 590;
+    uint32_t dss_overhead_micro_seconds		= 690;
+    uint32_t pre_range_overhead_micro_seconds	= 660;
+    uint32_t final_range_overhead_micro_seconds = 550;
+    uint32_t pre_range_timeout_micro_seconds	= 0;
+    uint32_t c_min_timing_budget_micro_seconds	= 20000;
+    uint32_t sub_timeout = 0;
+
+    LOG_FUNCTION_START("");
+
+    if (measurement_timing_budget_micro_seconds
+            < c_min_timing_budget_micro_seconds) {
+        status = VL53L0X_ERROR_INVALID_PARAMS;
+        return status;
+    }
+
+    final_range_timing_budget_micro_seconds =
+        measurement_timing_budget_micro_seconds -
+        (start_overhead_micro_seconds + end_overhead_micro_seconds);
+
+    status = VL53L0X_get_sequence_step_enables(dev, &scheduler_sequence_steps);
+
+    if (status == VL53L0X_ERROR_NONE &&
+            (scheduler_sequence_steps.TccOn  ||
+             scheduler_sequence_steps.MsrcOn ||
+             scheduler_sequence_steps.DssOn)) {
+
+        /* TCC, MSRC and DSS all share the same timeout */
+        status = get_sequence_step_timeout(dev,
+                                           VL53L0X_SEQUENCESTEP_MSRC,
+                                           &msrc_dcc_tcc_timeout_micro_seconds);
+
+        /* Subtract the TCC, MSRC and DSS timeouts if they are
+         * enabled. */
+
+        if (status != VL53L0X_ERROR_NONE) {
+            return status;
+        }
+
+        /* TCC */
+        if (scheduler_sequence_steps.TccOn) {
+
+            sub_timeout = msrc_dcc_tcc_timeout_micro_seconds
+                          + tcc_overhead_micro_seconds;
+
+            if (sub_timeout <
+                    final_range_timing_budget_micro_seconds) {
+                final_range_timing_budget_micro_seconds -=
+                    sub_timeout;
+            } else {
+                /* Requested timeout too big. */
+                status = VL53L0X_ERROR_INVALID_PARAMS;
+            }
+        }
+
+        if (status != VL53L0X_ERROR_NONE) {
+            LOG_FUNCTION_END(status);
+            return status;
+        }
+
+        /* DSS */
+        if (scheduler_sequence_steps.DssOn) {
+
+            sub_timeout = 2 * (msrc_dcc_tcc_timeout_micro_seconds +
+                               dss_overhead_micro_seconds);
+
+            if (sub_timeout < final_range_timing_budget_micro_seconds) {
+                final_range_timing_budget_micro_seconds
+                -= sub_timeout;
+            } else {
+                /* Requested timeout too big. */
+                status = VL53L0X_ERROR_INVALID_PARAMS;
+            }
+        } else if (scheduler_sequence_steps.MsrcOn) {
+            /* MSRC */
+            sub_timeout = msrc_dcc_tcc_timeout_micro_seconds +
+                          msrc_overhead_micro_seconds;
+
+            if (sub_timeout < final_range_timing_budget_micro_seconds) {
+                final_range_timing_budget_micro_seconds
+                -= sub_timeout;
+            } else {
+                /* Requested timeout too big. */
+                status = VL53L0X_ERROR_INVALID_PARAMS;
+            }
+        }
+
+    }
+
+    if (status != VL53L0X_ERROR_NONE) {
+        LOG_FUNCTION_END(status);
+        return status;
+    }
+
+    if (scheduler_sequence_steps.PreRangeOn) {
+
+        /* Subtract the Pre-range timeout if enabled. */
+
+        status = get_sequence_step_timeout(dev,
+                                           VL53L0X_SEQUENCESTEP_PRE_RANGE,
+                                           &pre_range_timeout_micro_seconds);
+
+        sub_timeout = pre_range_timeout_micro_seconds +
+                      pre_range_overhead_micro_seconds;
+
+        if (sub_timeout < final_range_timing_budget_micro_seconds) {
+            final_range_timing_budget_micro_seconds -= sub_timeout;
+        } else {
+            /* Requested timeout too big. */
+            status = VL53L0X_ERROR_INVALID_PARAMS;
+        }
+    }
+
+
+    if (status == VL53L0X_ERROR_NONE &&
+            scheduler_sequence_steps.FinalRangeOn) {
+
+        final_range_timing_budget_micro_seconds -=
+            final_range_overhead_micro_seconds;
+
+        /* Final Range Timeout
+         * Note that the final range timeout is determined by the timing
+         * budget and the sum of all other timeouts within the sequence.
+         * If there is no room for the final range timeout, then an error
+         * will be set. Otherwise the remaining time will be applied to
+         * the final range.
+         */
+        status = set_sequence_step_timeout(dev,
+                                           VL53L0X_SEQUENCESTEP_FINAL_RANGE,
+                                           final_range_timing_budget_micro_seconds);
+
+        VL53L0X_SETPARAMETERFIELD(dev,
+                                  MeasurementTimingBudgetMicroSeconds,
+                                  measurement_timing_budget_micro_seconds);
+    }
+
+    LOG_FUNCTION_END(status);
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_set_measurement_timing_budget_micro_seconds(VL53L0X_DEV dev,
+        uint32_t measurement_timing_budget_micro_seconds)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    LOG_FUNCTION_START("");
+
+    status = wrapped_VL53L0X_set_measurement_timing_budget_micro_seconds(dev,
+             measurement_timing_budget_micro_seconds);
+
+    LOG_FUNCTION_END(status);
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_set_sequence_step_enable(VL53L0X_DEV dev,
+        VL53L0X_SequenceStepId sequence_step_id, uint8_t sequence_step_enabled)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t sequence_config = 0;
+    uint8_t sequence_config_new = 0;
+    uint32_t measurement_timing_budget_micro_seconds;
+    LOG_FUNCTION_START("");
+
+    status = VL53L0X_read_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
+                               &sequence_config);
+
+    sequence_config_new = sequence_config;
+
+    if (status == VL53L0X_ERROR_NONE) {
+        if (sequence_step_enabled == 1) {
+
+            /* Enable requested sequence step
+             */
+            switch (sequence_step_id) {
+                case VL53L0X_SEQUENCESTEP_TCC:
+                    sequence_config_new |= 0x10;
+                    break;
+                case VL53L0X_SEQUENCESTEP_DSS:
+                    sequence_config_new |= 0x28;
+                    break;
+                case VL53L0X_SEQUENCESTEP_MSRC:
+                    sequence_config_new |= 0x04;
+                    break;
+                case VL53L0X_SEQUENCESTEP_PRE_RANGE:
+                    sequence_config_new |= 0x40;
+                    break;
+                case VL53L0X_SEQUENCESTEP_FINAL_RANGE:
+                    sequence_config_new |= 0x80;
+                    break;
+                default:
+                    status = VL53L0X_ERROR_INVALID_PARAMS;
+            }
+        } else {
+            /* Disable requested sequence step
+             */
+            switch (sequence_step_id) {
+                case VL53L0X_SEQUENCESTEP_TCC:
+                    sequence_config_new &= 0xef;
+                    break;
+                case VL53L0X_SEQUENCESTEP_DSS:
+                    sequence_config_new &= 0xd7;
+                    break;
+                case VL53L0X_SEQUENCESTEP_MSRC:
+                    sequence_config_new &= 0xfb;
+                    break;
+                case VL53L0X_SEQUENCESTEP_PRE_RANGE:
+                    sequence_config_new &= 0xbf;
+                    break;
+                case VL53L0X_SEQUENCESTEP_FINAL_RANGE:
+                    sequence_config_new &= 0x7f;
+                    break;
+                default:
+                    status = VL53L0X_ERROR_INVALID_PARAMS;
+            }
+        }
+    }
+
+    if (sequence_config_new != sequence_config) {
+        /* Apply New Setting */
+        if (status == VL53L0X_ERROR_NONE) {
+            status = VL53L0X_write_byte(dev,
+                                        VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, sequence_config_new);
+        }
+        if (status == VL53L0X_ERROR_NONE) {
+            PALDevDataSet(dev, SequenceConfig, sequence_config_new);
+        }
+
+
+        /* Recalculate timing budget */
+        if (status == VL53L0X_ERROR_NONE) {
+            VL53L0X_GETPARAMETERFIELD(dev,
+                                      MeasurementTimingBudgetMicroSeconds,
+                                      measurement_timing_budget_micro_seconds);
+
+            VL53L0X_set_measurement_timing_budget_micro_seconds(dev,
+                    measurement_timing_budget_micro_seconds);
+        }
+    }
+
+    LOG_FUNCTION_END(status);
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_set_limit_check_enable(VL53L0X_DEV dev, uint16_t limit_check_id,
+        uint8_t limit_check_enable)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    FixPoint1616_t temp_fix1616 = 0;
+    uint8_t limit_check_enable_int = 0;
+    uint8_t limit_check_disable = 0;
+    uint8_t temp8;
+
+    LOG_FUNCTION_START("");
+
+    if (limit_check_id >= VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS) {
+        status = VL53L0X_ERROR_INVALID_PARAMS;
+    } else {
+        if (limit_check_enable == 0) {
+            temp_fix1616 = 0;
+            limit_check_enable_int = 0;
+            limit_check_disable = 1;
+
+        } else {
+            VL53L0X_GETARRAYPARAMETERFIELD(dev, LimitChecksValue,
+                                           limit_check_id, temp_fix1616);
+            limit_check_disable = 0;
+            /* this to be sure to have either 0 or 1 */
+            limit_check_enable_int = 1;
+        }
+
+        switch (limit_check_id) {
+
+            case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE:
+                /* internal computation: */
+                VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksEnable,
+                                               VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,
+                                               limit_check_enable_int);
+
+                break;
+
+            case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
+
+                status = VL53L0X_write_word(dev,
+                                            VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT,
+                                            VL53L0X_FIXPOINT1616TOFIXPOINT97(temp_fix1616));
+
+                break;
+
+            case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP:
+
+                /* internal computation: */
+                VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksEnable,
+                                               VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP,
+                                               limit_check_enable_int);
+
+                break;
+
+            case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD:
+
+                /* internal computation: */
+                VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksEnable,
+                                               VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD,
+                                               limit_check_enable_int);
+
+                break;
+
+            case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC:
+
+                temp8 = (uint8_t)(limit_check_disable << 1);
+                status = VL53L0X_update_byte(dev,
+                                             VL53L0X_REG_MSRC_CONFIG_CONTROL,
+                                             0xFE, temp8);
+
+                break;
+
+            case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE:
+
+                temp8 = (uint8_t)(limit_check_disable << 4);
+                status = VL53L0X_update_byte(dev,
+                                             VL53L0X_REG_MSRC_CONFIG_CONTROL,
+                                             0xEF, temp8);
+
+                break;
+
+
+            default:
+                status = VL53L0X_ERROR_INVALID_PARAMS;
+
+        }
+
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        if (limit_check_enable == 0) {
+            VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksEnable,
+                                           limit_check_id, 0);
+        } else {
+            VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksEnable,
+                                           limit_check_id, 1);
+        }
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_static_init(VL53L0X_DEV dev)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    VL53L0X_DeviceParameters_t current_parameters = {0};
+    uint8_t *p_tuning_setting_buffer;
+    uint16_t tempword = 0;
+    uint8_t tempbyte = 0;
+    uint8_t use_internal_tuning_settings = 0;
+    uint32_t count = 0;
+    uint8_t is_aperture_spads = 0;
+    uint32_t ref_spad_count = 0;
+    uint8_t aperture_spads = 0;
+    uint8_t vcsel_pulse_period_pclk;
+    uint32_t seq_timeout_micro_secs;
+
+    LOG_FUNCTION_START("");
+
+    status = VL53L0X_get_info_from_device(dev, 1);
+
+    /* set the ref spad from NVM */
+    count	= (uint32_t)VL53L0X_GETDEVICESPECIFICPARAMETER(dev,
+              ReferenceSpadCount);
+    aperture_spads = VL53L0X_GETDEVICESPECIFICPARAMETER(dev,
+                     ReferenceSpadType);
+
+    /* NVM value invalid */
+    if ((aperture_spads > 1) ||
+            ((aperture_spads == 1) && (count > 32)) ||
+            ((aperture_spads == 0) && (count > 12))) {
+        status = wrapped_VL53L0X_perform_ref_spad_management(dev, &ref_spad_count,
+                 &is_aperture_spads);
+    } else {
+        status = VL53L0X_set_reference_spads(dev, count, aperture_spads);
+    }
+
+
+    /* Initialize tuning settings buffer to prevent compiler warning. */
+    p_tuning_setting_buffer = DefaultTuningSettings;
+
+    if (status == VL53L0X_ERROR_NONE) {
+        use_internal_tuning_settings = PALDevDataGet(dev,
+                                       UseInternalTuningSettings);
+
+        if (use_internal_tuning_settings == 0) {
+            p_tuning_setting_buffer = PALDevDataGet(dev,
+                                                    pTuningSettingsPointer);
+        } else {
+            p_tuning_setting_buffer = DefaultTuningSettings;
+        }
+
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_load_tuning_settings(dev, p_tuning_setting_buffer);
+    }
+
+
+    /* Set interrupt config to new sample ready */
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_set_gpio_config(dev, 0, 0,
+                                         VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY,
+                                         VL53L0X_INTERRUPTPOLARITY_LOW);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev, 0xFF, 0x01);
+        status |= VL53L0X_read_word(dev, 0x84, &tempword);
+        status |= VL53L0X_write_byte(dev, 0xFF, 0x00);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        VL53L0X_SETDEVICESPECIFICPARAMETER(dev, OscFrequencyMHz,
+                                           VL53L0X_FIXPOINT412TOFIXPOINT1616(tempword));
+    }
+
+    /* After static init, some device parameters may be changed,
+     * so update them */
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_get_device_parameters(dev, &current_parameters);
+    }
+
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_get_fraction_enable(dev, &tempbyte);
+        if (status == VL53L0X_ERROR_NONE) {
+            PALDevDataSet(dev, RangeFractionalEnable, tempbyte);
+        }
+
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        PALDevDataSet(dev, CurrentParameters, current_parameters);
+    }
+
+
+    /* read the sequence config and save it */
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_read_byte(dev,
+                                   VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, &tempbyte);
+        if (status == VL53L0X_ERROR_NONE) {
+            PALDevDataSet(dev, SequenceConfig, tempbyte);
+        }
+    }
+
+    /* Disable MSRC and TCC by default */
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_set_sequence_step_enable(dev,
+                 VL53L0X_SEQUENCESTEP_TCC, 0);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_set_sequence_step_enable(dev,
+                 VL53L0X_SEQUENCESTEP_MSRC, 0);
+    }
+
+    /* Set PAL State to standby */
+    if (status == VL53L0X_ERROR_NONE) {
+        PALDevDataSet(dev, PalState, VL53L0X_STATE_IDLE);
+    }
+
+    /* Store pre-range vcsel period */
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_get_vcsel_pulse_period(
+                     dev,
+                     VL53L0X_VCSEL_PERIOD_PRE_RANGE,
+                     &vcsel_pulse_period_pclk);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        VL53L0X_SETDEVICESPECIFICPARAMETER(
+            dev,
+            PreRangeVcselPulsePeriod,
+            vcsel_pulse_period_pclk);
+    }
+
+    /* Store final-range vcsel period */
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_get_vcsel_pulse_period(
+                     dev,
+                     VL53L0X_VCSEL_PERIOD_FINAL_RANGE,
+                     &vcsel_pulse_period_pclk);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        VL53L0X_SETDEVICESPECIFICPARAMETER(
+            dev,
+            FinalRangeVcselPulsePeriod,
+            vcsel_pulse_period_pclk);
+    }
+
+    /* Store pre-range timeout */
+    if (status == VL53L0X_ERROR_NONE) {
+        status = get_sequence_step_timeout(
+                     dev,
+                     VL53L0X_SEQUENCESTEP_PRE_RANGE,
+                     &seq_timeout_micro_secs);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        VL53L0X_SETDEVICESPECIFICPARAMETER(
+            dev,
+            PreRangeTimeoutMicroSecs,
+            seq_timeout_micro_secs);
+    }
+
+    /* Store final-range timeout */
+    if (status == VL53L0X_ERROR_NONE) {
+        status = get_sequence_step_timeout(
+                     dev,
+                     VL53L0X_SEQUENCESTEP_FINAL_RANGE,
+                     &seq_timeout_micro_secs);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        VL53L0X_SETDEVICESPECIFICPARAMETER(
+            dev,
+            FinalRangeTimeoutMicroSecs,
+            seq_timeout_micro_secs);
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+
+VL53L0X_Error VL53L0X::VL53L0X_stop_measurement(VL53L0X_DEV dev)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    LOG_FUNCTION_START("");
+
+    status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSRANGE_START,
+                                VL53L0X_REG_SYSRANGE_MODE_SINGLESHOT);
+
+    status = VL53L0X_write_byte(dev, 0xFF, 0x01);
+    status = VL53L0X_write_byte(dev, 0x00, 0x00);
+    status = VL53L0X_write_byte(dev, 0x91, 0x00);
+    status = VL53L0X_write_byte(dev, 0x00, 0x01);
+    status = VL53L0X_write_byte(dev, 0xFF, 0x00);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        /* Set PAL State to Idle */
+        PALDevDataSet(dev, PalState, VL53L0X_STATE_IDLE);
+    }
+
+    /* Check if need to apply interrupt settings */
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_check_and_load_interrupt_settings(dev, 0);
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_get_stop_completed_status(VL53L0X_DEV dev,
+        uint32_t *p_stop_status)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t byte = 0;
+    LOG_FUNCTION_START("");
+
+    status = VL53L0X_write_byte(dev, 0xFF, 0x01);
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_read_byte(dev, 0x04, &byte);
+    }
+
+    if (status == VL53L0X_ERROR_NONE) {
+        status = VL53L0X_write_byte(dev, 0xFF, 0x0);
+    }
+
+    *p_stop_status = byte;
+
+    if (byte == 0) {
+        status = VL53L0X_write_byte(dev, 0x80, 0x01);
+        status = VL53L0X_write_byte(dev, 0xFF, 0x01);
+        status = VL53L0X_write_byte(dev, 0x00, 0x00);
+        status = VL53L0X_write_byte(dev, 0x91,
+                                    PALDevDataGet(dev, StopVariable));
+        status = VL53L0X_write_byte(dev, 0x00, 0x01);
+        status = VL53L0X_write_byte(dev, 0xFF, 0x00);
+        status = VL53L0X_write_byte(dev, 0x80, 0x00);
+    }
+
+    LOG_FUNCTION_END(status);
+    return status;
+}
+
+/****************** Write and read functions from I2C *************************/
+
+VL53L0X_Error VL53L0X::VL53L0X_write_multi(VL53L0X_DEV dev, uint8_t index, uint8_t *p_data, uint32_t count)
+{
+    int  status;
+
+    status = VL53L0X_i2c_write(dev->I2cDevAddr, index, p_data, (uint16_t)count);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_read_multi(VL53L0X_DEV dev, uint8_t index, uint8_t *p_data, uint32_t count)
+{
+    int status;
+
+    if (count >= VL53L0X_MAX_I2C_XFER_SIZE) {
+        status = VL53L0X_ERROR_INVALID_PARAMS;
+    }
+
+    status = VL53L0X_i2c_read(dev->I2cDevAddr, index, p_data, (uint16_t)count);
+
+    return status;
+}
+
+
+VL53L0X_Error VL53L0X::VL53L0X_write_byte(VL53L0X_DEV Dev, uint8_t index, uint8_t data)
+{
+    int  status;
+
+    status = VL53L0X_i2c_write(Dev->I2cDevAddr, index, &data, 1);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_write_word(VL53L0X_DEV dev, uint8_t index, uint16_t data)
+{
+    int  status;
+    uint8_t buffer[2];
+
+    buffer[0] = data >> 8;
+    buffer[1] = data & 0x00FF;
+    status = VL53L0X_i2c_write(dev->I2cDevAddr, index, (uint8_t *)buffer, 2);
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_write_dword(VL53L0X_DEV Dev, uint8_t index, uint32_t data)
+{
+    int  status;
+    uint8_t buffer[4];
+
+    buffer[0] = (data >> 24) & 0xFF;
+    buffer[1] = (data >> 16) & 0xFF;
+    buffer[2] = (data >>  8) & 0xFF;
+    buffer[3] = (data >>  0) & 0xFF;
+    status = VL53L0X_i2c_write(Dev->I2cDevAddr, index, (uint8_t *)buffer, 4);
+    return status;
+}
+
+
+VL53L0X_Error VL53L0X::VL53L0X_read_byte(VL53L0X_DEV Dev, uint8_t index, uint8_t *p_data)
+{
+    int  status;
+
+    status = VL53L0X_i2c_read(Dev->I2cDevAddr, index, p_data, 1);
+
+    if (status) {
+        return -1;
+    }
+
+    return 0;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_read_word(VL53L0X_DEV Dev, uint8_t index, uint16_t *p_data)
+{
+    int  status;
+    uint8_t buffer[2] = {0, 0};
+
+    status = VL53L0X_i2c_read(Dev->I2cDevAddr, index, buffer, 2);
+    if (!status) {
+        *p_data = (buffer[0] << 8) + buffer[1];
+    }
+    return status;
+
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_read_dword(VL53L0X_DEV Dev, uint8_t index, uint32_t *p_data)
+{
+    int status;
+    uint8_t buffer[4] = {0, 0, 0, 0};
+
+    status = VL53L0X_i2c_read(Dev->I2cDevAddr, index, buffer, 4);
+    if (!status) {
+        *p_data = (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3];
+    }
+    return status;
+
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_update_byte(VL53L0X_DEV Dev, uint8_t index, uint8_t and_data, uint8_t or_data)
+{
+    int  status;
+    uint8_t buffer = 0;
+
+    /* read data direct onto buffer */
+    status = VL53L0X_i2c_read(Dev->I2cDevAddr, index, &buffer, 1);
+    if (!status) {
+        buffer = (buffer & and_data) | or_data;
+        status = VL53L0X_i2c_write(Dev->I2cDevAddr, index, &buffer, (uint8_t)1);
+    }
+    return status;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_i2c_write(uint8_t DeviceAddr, uint8_t RegisterAddr, uint8_t *p_data,
+        uint16_t NumByteToWrite)
+{
+    int ret;
+
+    ret = _dev_i2c->i2c_write(p_data, DeviceAddr, RegisterAddr, NumByteToWrite);
+
+    if (ret) {
+        return -1;
+    }
+    return 0;
+}
+
+VL53L0X_Error VL53L0X::VL53L0X_i2c_read(uint8_t DeviceAddr, uint8_t RegisterAddr, uint8_t *p_data,
+                                        uint16_t NumByteToRead)
+{
+    int ret;
+
+    ret = _dev_i2c->i2c_read(p_data, DeviceAddr, RegisterAddr, NumByteToRead);
+
+    if (ret) {
+        return -1;
+    }
+    return 0;
+}
+
+int VL53L0X::read_id(uint8_t *id)
+{
+    int status = 0;
+    uint16_t rl_id = 0;
+
+    status = VL53L0X_read_word(_device, VL53L0X_REG_IDENTIFICATION_MODEL_ID, &rl_id);
+    if (rl_id == 0xEEAA) {
+        return status;
+    }
+
+    return -1;
+}
+
+
+VL53L0X_Error VL53L0X::wait_measurement_data_ready(VL53L0X_DEV dev)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint8_t new_dat_ready = 0;
+    uint32_t loop_nb;
+
+    // Wait until it finished
+    // use timeout to avoid deadlock
+    if (status == VL53L0X_ERROR_NONE) {
+        loop_nb = 0;
+        do {
+            status = VL53L0X_get_measurement_data_ready(dev, &new_dat_ready);
+            if ((new_dat_ready == 0x01) || status != VL53L0X_ERROR_NONE) {
+                break;
+            }
+            loop_nb = loop_nb + 1;
+            VL53L0X_polling_delay(dev);
+        } while (loop_nb < VL53L0X_DEFAULT_MAX_LOOP);
+
+        if (loop_nb >= VL53L0X_DEFAULT_MAX_LOOP) {
+            status = VL53L0X_ERROR_TIME_OUT;
+        }
+    }
+
+    return status;
+}
+
+VL53L0X_Error VL53L0X::wait_stop_completed(VL53L0X_DEV dev)
+{
+    VL53L0X_Error status = VL53L0X_ERROR_NONE;
+    uint32_t stop_completed = 0;
+    uint32_t loop_nb;
+
+    // Wait until it finished
+    // use timeout to avoid deadlock
+    if (status == VL53L0X_ERROR_NONE) {
+        loop_nb = 0;
+        do {
+            status = VL53L0X_get_stop_completed_status(dev, &stop_completed);
+            if ((stop_completed == 0x00) || status != VL53L0X_ERROR_NONE) {
+                break;
+            }
+            loop_nb = loop_nb + 1;
+            VL53L0X_polling_delay(dev);
+        } while (loop_nb < VL53L0X_DEFAULT_MAX_LOOP);
+
+        if (loop_nb >= VL53L0X_DEFAULT_MAX_LOOP) {
+            status = VL53L0X_ERROR_TIME_OUT;
+        }
+
+    }
+
+    return status;
+}
+
+
+int VL53L0X::init_sensor(uint8_t new_addr)
+{
+    int status;
+
+    VL53L0X_off();
+    VL53L0X_on();
+
+//   status=VL53L0X_WaitDeviceBooted(Device);
+//   if(status)
+//      printf("WaitDeviceBooted fail\n\r");
+    status = is_present();
+    if (!status) {
+        status = init(&_my_device);
+        if (status != VL53L0X_ERROR_NONE) {
+            printf("Failed to init VL53L0X sensor!\n\r");
+            return status;
+        }
+
+        // deduce silicon version
+        status = VL53L0X_get_device_info(&_my_device, &_device_info);
+
+        status = prepare();
+        if (status != VL53L0X_ERROR_NONE) {
+            printf("Failed to prepare VL53L0X!\n\r");
+            return status;
+        }
+
+        if (new_addr != VL53L0X_DEFAULT_ADDRESS) {
+            status = set_device_address(new_addr);
+            if (status) {
+                printf("Failed to change I2C address!\n\r");
+                return status;
+            }
+        } else {
+            printf("Invalid new address!\n\r");
+            return VL53L0X_ERROR_INVALID_PARAMS;
+        }
+    }
+    return status;
+}
+
+int VL53L0X::range_meas_int_continuous_mode(void (*fptr)(void))
+{
+    int status, clr_status;
+
+    status = VL53L0X_stop_measurement(_device); // it is safer to do this while sensor is stopped
+
+//   status = VL53L0X_SetInterruptThresholds(Device, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING, 0, 300);
+
+    status = VL53L0X_set_gpio_config(_device, 0, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING,
+                                     VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY,
+                                     VL53L0X_INTERRUPTPOLARITY_HIGH);
+
+    if (!status) {
+        attach_interrupt_measure_detection_irq(fptr);
+        enable_interrupt_measure_detection_irq();
+    }
+
+    clr_status = clear_interrupt(VL53L0X_REG_RESULT_INTERRUPT_STATUS | VL53L0X_REG_RESULT_RANGE_STATUS);
+    if (clr_status) {
+        VL53L0X_ErrLog("VL53L0X_ClearErrorInterrupt fail\r\n");
+    }
+
+    if (!status) {
+        status = range_start_continuous_mode();
+    }
+    return status;
+}
+
+
+int VL53L0X::start_measurement(OperatingMode operating_mode, void (*fptr)(void))
+{
+    int Status = VL53L0X_ERROR_NONE;
+    int ClrStatus;
+
+    uint8_t VhvSettings;
+    uint8_t PhaseCal;
+    // *** from mass market cube expansion v1.1, ranging with satellites.
+    // default settings, for normal range.
+    FixPoint1616_t signalLimit = (FixPoint1616_t)(0.25 * 65536);
+    FixPoint1616_t sigmaLimit = (FixPoint1616_t)(18 * 65536);
+    uint32_t timingBudget = 33000;
+    uint8_t preRangeVcselPeriod = 14;
+    uint8_t finalRangeVcselPeriod = 10;
+
+    if (operating_mode == range_continuous_interrupt) {
+        if (_gpio1Int == NULL) {
+            printf("GPIO1 Error\r\n");
+            return 1;
+        }
+
+        Status = VL53L0X_stop_measurement(_device); // it is safer to do this while sensor is stopped
+
+//        Status = VL53L0X_SetInterruptThresholds(Device, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING, 0, 300);
+
+        Status = VL53L0X_set_gpio_config(_device, 0, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING,
+                                         VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY,
+                                         VL53L0X_INTERRUPTPOLARITY_HIGH);
+
+        if (Status == VL53L0X_ERROR_NONE) {
+            attach_interrupt_measure_detection_irq(fptr);
+            enable_interrupt_measure_detection_irq();
+        }
+
+        ClrStatus = clear_interrupt(VL53L0X_REG_RESULT_INTERRUPT_STATUS | VL53L0X_REG_RESULT_RANGE_STATUS);
+        if (ClrStatus) {
+            VL53L0X_ErrLog("VL53L0X_ClearErrorInterrupt fail\r\n");
+        }
+
+        if (Status == VL53L0X_ERROR_NONE) {
+            Status = VL53L0X_set_device_mode(_device, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING); // Setup in continuous ranging mode
+        }
+
+        if (Status == VL53L0X_ERROR_NONE) {
+            Status = VL53L0X_start_measurement(_device);
+        }
+    }
+
+    if (operating_mode == range_single_shot_polling) {
+        // singelshot, polled ranging
+        if (Status == VL53L0X_ERROR_NONE) {
+            // no need to do this when we use VL53L0X_PerformSingleRangingMeasurement
+            Status = VL53L0X_set_device_mode(_device, VL53L0X_DEVICEMODE_SINGLE_RANGING); // Setup in single ranging mode
+        }
+
+        // Enable/Disable Sigma and Signal check
+        if (Status == VL53L0X_ERROR_NONE) {
+            Status = VL53L0X_set_limit_check_enable(_device,
+                                                    VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, 1);
+        }
+        if (Status == VL53L0X_ERROR_NONE) {
+            Status = VL53L0X_set_limit_check_enable(_device,
+                                                    VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, 1);
+        }
+
+// *** from mass market cube expansion v1.1, ranging with satellites.
+        /* Ranging configuration */
+//*
+//        switch(rangingConfig) {
+//        case LONG_RANGE:
+        signalLimit = (FixPoint1616_t)(0.1 * 65536);
+        sigmaLimit = (FixPoint1616_t)(60 * 65536);
+        timingBudget = 33000;
+        preRangeVcselPeriod = 18;
+        finalRangeVcselPeriod = 14;
+        /*        	break;
+                case HIGH_ACCURACY:
+        			signalLimit = (FixPoint1616_t)(0.25*65536);
+        			sigmaLimit = (FixPoint1616_t)(18*65536);
+        			timingBudget = 200000;
+        			preRangeVcselPeriod = 14;
+        			finalRangeVcselPeriod = 10;
+        			break;
+                case HIGH_SPEED:
+        			signalLimit = (FixPoint1616_t)(0.25*65536);
+        			sigmaLimit = (FixPoint1616_t)(32*65536);
+        			timingBudget = 20000;
+        			preRangeVcselPeriod = 14;
+        			finalRangeVcselPeriod = 10;
+         			break;
+                default:
+                	debug_printf("Not Supported");
+                }
+        */
+
+        if (Status == VL53L0X_ERROR_NONE) {
+            Status = VL53L0X_set_limit_check_value(_device,
+                                                   VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, signalLimit);
+        }
+
+        if (Status == VL53L0X_ERROR_NONE) {
+            Status = VL53L0X_set_limit_check_value(_device,
+                                                   VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, sigmaLimit);
+        }
+
+        if (Status == VL53L0X_ERROR_NONE) {
+            Status = VL53L0X_set_measurement_timing_budget_micro_seconds(_device, timingBudget);
+        }
+
+        if (Status == VL53L0X_ERROR_NONE) {
+            Status = VL53L0X_set_vcsel_pulse_period(_device,
+                                                    VL53L0X_VCSEL_PERIOD_PRE_RANGE, preRangeVcselPeriod);
+        }
+
+        if (Status == VL53L0X_ERROR_NONE) {
+            Status = VL53L0X_set_vcsel_pulse_period(_device,
+                                                    VL53L0X_VCSEL_PERIOD_FINAL_RANGE, finalRangeVcselPeriod);
+        }
+
+        if (Status == VL53L0X_ERROR_NONE) {
+            Status = VL53L0X_perform_ref_calibration(_device, &VhvSettings, &PhaseCal);
+        }
+
+    }
+
+    if (operating_mode == range_continuous_polling) {
+        if (Status == VL53L0X_ERROR_NONE) {
+            //printf("Call of VL53L0X_SetDeviceMode\n");
+            Status = VL53L0X_set_device_mode(_device, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING); // Setup in continuous ranging mode
+        }
+
+        if (Status == VL53L0X_ERROR_NONE) {
+            //printf("Call of VL53L0X_StartMeasurement\n");
+            Status = VL53L0X_start_measurement(_device);
+        }
+    }
+
+    return Status;
+}
+
+
+int VL53L0X::get_measurement(OperatingMode operating_mode, VL53L0X_RangingMeasurementData_t *p_data)
+{
+    int Status = VL53L0X_ERROR_NONE;
+
+    if (operating_mode == range_single_shot_polling) {
+        Status = VL53L0X_perform_single_ranging_measurement(_device, p_data);
+    }
+
+    if (operating_mode == range_continuous_polling) {
+        if (Status == VL53L0X_ERROR_NONE) {
+            Status = VL53L0X_measurement_poll_for_completion(_device);
+        }
+
+        if (Status == VL53L0X_ERROR_NONE) {
+            Status = VL53L0X_get_ranging_measurement_data(_device, p_data);
+
+            // Clear the interrupt
+            VL53L0X_clear_interrupt_mask(_device, VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY);
+            VL53L0X_polling_delay(_device);
+        }
+    }
+
+    if (operating_mode == range_continuous_interrupt) {
+        Status = VL53L0X_get_ranging_measurement_data(_device, p_data);
+        VL53L0X_clear_interrupt_mask(_device, VL53L0X_REG_SYSTEM_INTERRUPT_CLEAR | VL53L0X_REG_RESULT_INTERRUPT_STATUS);
+    }
+
+    return Status;
+}
+
+
+int VL53L0X::stop_measurement(OperatingMode operating_mode)
+{
+    int status = VL53L0X_ERROR_NONE;
+
+
+    // don't need to stop for a singleshot range!
+    if (operating_mode == range_single_shot_polling) {
+    }
+
+    if (operating_mode == range_continuous_interrupt || operating_mode == range_continuous_polling) {
+        // continuous mode
+        if (status == VL53L0X_ERROR_NONE) {
+            //printf("Call of VL53L0X_StopMeasurement\n");
+            status = VL53L0X_stop_measurement(_device);
+        }
+
+        if (status == VL53L0X_ERROR_NONE) {
+            //printf("Wait Stop to be competed\n");
+            status = wait_stop_completed(_device);
+        }
+
+        if (status == VL53L0X_ERROR_NONE)
+            status = VL53L0X_clear_interrupt_mask(_device,
+                                                  VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY);
+    }
+
+    return status;
+}
+
+
+int VL53L0X::handle_irq(OperatingMode operating_mode, VL53L0X_RangingMeasurementData_t *data)
+{
+    int status;
+    status = get_measurement(operating_mode, data);
+    enable_interrupt_measure_detection_irq();
+    return status;
+}
+
+
+/******************************************************************************/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/VL53L0X/VL53L0X.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,2773 @@
+/*******************************************************************************
+ Copyright © 2016, STMicroelectronics International N.V.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of STMicroelectronics nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
+ NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
+ IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef __VL53L0X_CLASS_H
+#define __VL53L0X_CLASS_H
+
+
+#ifdef _MSC_VER
+#   ifdef VL53L0X_API_EXPORTS
+#       define VL53L0X_API  __declspec(dllexport)
+#   else
+#       define VL53L0X_API
+#   endif
+#else
+#   define VL53L0X_API
+#endif
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "mbed.h"
+#include "RangeSensor.h"
+#include "DevI2C.h"
+#include "PinNames.h"
+#include "VL53L0X_def.h"
+#include "VL53L0X_platform.h"
+#include "Stmpe1600.h"
+
+
+/**
+ * The device model ID
+ */
+#define IDENTIFICATION_MODEL_ID                 0x000
+
+
+#define STATUS_OK              0x00
+#define STATUS_FAIL            0x01
+
+#define VL53L0X_OsDelay(...) wait_ms(2) // 2 msec delay. can also use wait(float secs)/wait_us(int)
+
+#ifdef USE_EMPTY_STRING
+#define  VL53L0X_STRING_DEVICE_INFO_NAME                             ""
+#define  VL53L0X_STRING_DEVICE_INFO_NAME_TS0                         ""
+#define  VL53L0X_STRING_DEVICE_INFO_NAME_TS1                         ""
+#define  VL53L0X_STRING_DEVICE_INFO_NAME_TS2                         ""
+#define  VL53L0X_STRING_DEVICE_INFO_NAME_ES1                         ""
+#define  VL53L0X_STRING_DEVICE_INFO_TYPE                             ""
+
+/* PAL ERROR strings */
+#define  VL53L0X_STRING_ERROR_NONE                                   ""
+#define  VL53L0X_STRING_ERROR_CALIBRATION_WARNING                    ""
+#define  VL53L0X_STRING_ERROR_MIN_CLIPPED                            ""
+#define  VL53L0X_STRING_ERROR_UNDEFINED                              ""
+#define  VL53L0X_STRING_ERROR_INVALID_PARAMS                         ""
+#define  VL53L0X_STRING_ERROR_NOT_SUPPORTED                          ""
+#define  VL53L0X_STRING_ERROR_RANGE_ERROR                            ""
+#define  VL53L0X_STRING_ERROR_TIME_OUT                               ""
+#define  VL53L0X_STRING_ERROR_MODE_NOT_SUPPORTED                     ""
+#define  VL53L0X_STRING_ERROR_BUFFER_TOO_SMALL                       ""
+#define  VL53L0X_STRING_ERROR_GPIO_NOT_EXISTING                      ""
+#define  VL53L0X_STRING_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED       ""
+#define  VL53L0X_STRING_ERROR_CONTROL_INTERFACE                      ""
+#define  VL53L0X_STRING_ERROR_INVALID_COMMAND                        ""
+#define  VL53L0X_STRING_ERROR_DIVISION_BY_ZERO                       ""
+#define  VL53L0X_STRING_ERROR_REF_SPAD_INIT                          ""
+#define  VL53L0X_STRING_ERROR_NOT_IMPLEMENTED                        ""
+
+#define  VL53L0X_STRING_UNKNOW_ERROR_CODE                            ""
+
+
+
+/* Range Status */
+#define  VL53L0X_STRING_RANGESTATUS_NONE                             ""
+#define  VL53L0X_STRING_RANGESTATUS_RANGEVALID                       ""
+#define  VL53L0X_STRING_RANGESTATUS_SIGMA                            ""
+#define  VL53L0X_STRING_RANGESTATUS_SIGNAL                           ""
+#define  VL53L0X_STRING_RANGESTATUS_MINRANGE                         ""
+#define  VL53L0X_STRING_RANGESTATUS_PHASE                            ""
+#define  VL53L0X_STRING_RANGESTATUS_HW                               ""
+
+
+/* Range Status */
+#define  VL53L0X_STRING_STATE_POWERDOWN                              ""
+#define  VL53L0X_STRING_STATE_WAIT_STATICINIT                        ""
+#define  VL53L0X_STRING_STATE_STANDBY                                ""
+#define  VL53L0X_STRING_STATE_IDLE                                   ""
+#define  VL53L0X_STRING_STATE_RUNNING                                ""
+#define  VL53L0X_STRING_STATE_UNKNOWN                                ""
+#define  VL53L0X_STRING_STATE_ERROR                                  ""
+
+
+/* Device Specific */
+#define  VL53L0X_STRING_DEVICEERROR_NONE                             ""
+#define  VL53L0X_STRING_DEVICEERROR_VCSELCONTINUITYTESTFAILURE       ""
+#define  VL53L0X_STRING_DEVICEERROR_VCSELWATCHDOGTESTFAILURE         ""
+#define  VL53L0X_STRING_DEVICEERROR_NOVHVVALUEFOUND                  ""
+#define  VL53L0X_STRING_DEVICEERROR_MSRCNOTARGET                     ""
+#define  VL53L0X_STRING_DEVICEERROR_SNRCHECK                         ""
+#define  VL53L0X_STRING_DEVICEERROR_RANGEPHASECHECK                  ""
+#define  VL53L0X_STRING_DEVICEERROR_SIGMATHRESHOLDCHECK              ""
+#define  VL53L0X_STRING_DEVICEERROR_TCC                              ""
+#define  VL53L0X_STRING_DEVICEERROR_PHASECONSISTENCY                 ""
+#define  VL53L0X_STRING_DEVICEERROR_MINCLIP                          ""
+#define  VL53L0X_STRING_DEVICEERROR_RANGECOMPLETE                    ""
+#define  VL53L0X_STRING_DEVICEERROR_ALGOUNDERFLOW                    ""
+#define  VL53L0X_STRING_DEVICEERROR_ALGOOVERFLOW                     ""
+#define  VL53L0X_STRING_DEVICEERROR_RANGEIGNORETHRESHOLD             ""
+#define  VL53L0X_STRING_DEVICEERROR_UNKNOWN                          ""
+
+/* Check Enable */
+#define  VL53L0X_STRING_CHECKENABLE_SIGMA_FINAL_RANGE                ""
+#define  VL53L0X_STRING_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE          ""
+#define  VL53L0X_STRING_CHECKENABLE_SIGNAL_REF_CLIP                  ""
+#define  VL53L0X_STRING_CHECKENABLE_RANGE_IGNORE_THRESHOLD           ""
+
+/* Sequence Step */
+#define  VL53L0X_STRING_SEQUENCESTEP_TCC                             ""
+#define  VL53L0X_STRING_SEQUENCESTEP_DSS                             ""
+#define  VL53L0X_STRING_SEQUENCESTEP_MSRC                            ""
+#define  VL53L0X_STRING_SEQUENCESTEP_PRE_RANGE                       ""
+#define  VL53L0X_STRING_SEQUENCESTEP_FINAL_RANGE                     ""
+#else
+#define  VL53L0X_STRING_DEVICE_INFO_NAME          "VL53L0X cut1.0"
+#define  VL53L0X_STRING_DEVICE_INFO_NAME_TS0      "VL53L0X TS0"
+#define  VL53L0X_STRING_DEVICE_INFO_NAME_TS1      "VL53L0X TS1"
+#define  VL53L0X_STRING_DEVICE_INFO_NAME_TS2      "VL53L0X TS2"
+#define  VL53L0X_STRING_DEVICE_INFO_NAME_ES1      "VL53L0X ES1 or later"
+#define  VL53L0X_STRING_DEVICE_INFO_TYPE          "VL53L0X"
+
+/* PAL ERROR strings */
+#define  VL53L0X_STRING_ERROR_NONE \
+			"No Error"
+#define  VL53L0X_STRING_ERROR_CALIBRATION_WARNING \
+			"Calibration Warning Error"
+#define  VL53L0X_STRING_ERROR_MIN_CLIPPED \
+			"Min clipped error"
+#define  VL53L0X_STRING_ERROR_UNDEFINED \
+			"Undefined error"
+#define  VL53L0X_STRING_ERROR_INVALID_PARAMS \
+			"Invalid parameters error"
+#define  VL53L0X_STRING_ERROR_NOT_SUPPORTED \
+			"Not supported error"
+#define  VL53L0X_STRING_ERROR_RANGE_ERROR \
+			"Range error"
+#define  VL53L0X_STRING_ERROR_TIME_OUT \
+			"Time out error"
+#define  VL53L0X_STRING_ERROR_MODE_NOT_SUPPORTED \
+			"Mode not supported error"
+#define  VL53L0X_STRING_ERROR_BUFFER_TOO_SMALL \
+			"Buffer too small"
+#define  VL53L0X_STRING_ERROR_GPIO_NOT_EXISTING \
+			"GPIO not existing"
+#define  VL53L0X_STRING_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED \
+			"GPIO funct not supported"
+#define  VL53L0X_STRING_ERROR_INTERRUPT_NOT_CLEARED \
+			"Interrupt not Cleared"
+#define  VL53L0X_STRING_ERROR_CONTROL_INTERFACE \
+			"Control Interface Error"
+#define  VL53L0X_STRING_ERROR_INVALID_COMMAND \
+			"Invalid Command Error"
+#define  VL53L0X_STRING_ERROR_DIVISION_BY_ZERO \
+			"Division by zero Error"
+#define  VL53L0X_STRING_ERROR_REF_SPAD_INIT \
+			"Reference Spad Init Error"
+#define  VL53L0X_STRING_ERROR_NOT_IMPLEMENTED \
+			"Not implemented error"
+
+#define  VL53L0X_STRING_UNKNOW_ERROR_CODE \
+			"Unknown Error Code"
+
+
+
+/* Range Status */
+#define  VL53L0X_STRING_RANGESTATUS_NONE                 "No Update"
+#define  VL53L0X_STRING_RANGESTATUS_RANGEVALID           "Range Valid"
+#define  VL53L0X_STRING_RANGESTATUS_SIGMA                "Sigma Fail"
+#define  VL53L0X_STRING_RANGESTATUS_SIGNAL               "Signal Fail"
+#define  VL53L0X_STRING_RANGESTATUS_MINRANGE             "Min Range Fail"
+#define  VL53L0X_STRING_RANGESTATUS_PHASE                "Phase Fail"
+#define  VL53L0X_STRING_RANGESTATUS_HW                   "Hardware Fail"
+
+
+/* Range Status */
+#define  VL53L0X_STRING_STATE_POWERDOWN               "POWERDOWN State"
+#define  VL53L0X_STRING_STATE_WAIT_STATICINIT \
+			"Wait for staticinit State"
+#define  VL53L0X_STRING_STATE_STANDBY                 "STANDBY State"
+#define  VL53L0X_STRING_STATE_IDLE                    "IDLE State"
+#define  VL53L0X_STRING_STATE_RUNNING                 "RUNNING State"
+#define  VL53L0X_STRING_STATE_UNKNOWN                 "UNKNOWN State"
+#define  VL53L0X_STRING_STATE_ERROR                   "ERROR State"
+
+
+/* Device Specific */
+#define  VL53L0X_STRING_DEVICEERROR_NONE              "No Update"
+#define  VL53L0X_STRING_DEVICEERROR_VCSELCONTINUITYTESTFAILURE \
+			"VCSEL Continuity Test Failure"
+#define  VL53L0X_STRING_DEVICEERROR_VCSELWATCHDOGTESTFAILURE \
+			"VCSEL Watchdog Test Failure"
+#define  VL53L0X_STRING_DEVICEERROR_NOVHVVALUEFOUND \
+			"No VHV Value found"
+#define  VL53L0X_STRING_DEVICEERROR_MSRCNOTARGET \
+			"MSRC No Target Error"
+#define  VL53L0X_STRING_DEVICEERROR_SNRCHECK \
+			"SNR Check Exit"
+#define  VL53L0X_STRING_DEVICEERROR_RANGEPHASECHECK \
+			"Range Phase Check Error"
+#define  VL53L0X_STRING_DEVICEERROR_SIGMATHRESHOLDCHECK \
+			"Sigma Threshold Check Error"
+#define  VL53L0X_STRING_DEVICEERROR_TCC \
+			"TCC Error"
+#define  VL53L0X_STRING_DEVICEERROR_PHASECONSISTENCY \
+			"Phase Consistency Error"
+#define  VL53L0X_STRING_DEVICEERROR_MINCLIP \
+			"Min Clip Error"
+#define  VL53L0X_STRING_DEVICEERROR_RANGECOMPLETE \
+			"Range Complete"
+#define  VL53L0X_STRING_DEVICEERROR_ALGOUNDERFLOW \
+			"Range Algo Underflow Error"
+#define  VL53L0X_STRING_DEVICEERROR_ALGOOVERFLOW \
+			"Range Algo Overlow Error"
+#define  VL53L0X_STRING_DEVICEERROR_RANGEIGNORETHRESHOLD \
+			"Range Ignore Threshold Error"
+#define  VL53L0X_STRING_DEVICEERROR_UNKNOWN \
+			"Unknown error code"
+
+/* Check Enable */
+#define  VL53L0X_STRING_CHECKENABLE_SIGMA_FINAL_RANGE \
+			"SIGMA FINAL RANGE"
+#define  VL53L0X_STRING_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE \
+			"SIGNAL RATE FINAL RANGE"
+#define  VL53L0X_STRING_CHECKENABLE_SIGNAL_REF_CLIP \
+			"SIGNAL REF CLIP"
+#define  VL53L0X_STRING_CHECKENABLE_RANGE_IGNORE_THRESHOLD \
+			"RANGE IGNORE THRESHOLD"
+#define  VL53L0X_STRING_CHECKENABLE_SIGNAL_RATE_MSRC \
+			"SIGNAL RATE MSRC"
+#define  VL53L0X_STRING_CHECKENABLE_SIGNAL_RATE_PRE_RANGE \
+			"SIGNAL RATE PRE RANGE"
+
+/* Sequence Step */
+#define  VL53L0X_STRING_SEQUENCESTEP_TCC                   "TCC"
+#define  VL53L0X_STRING_SEQUENCESTEP_DSS                   "DSS"
+#define  VL53L0X_STRING_SEQUENCESTEP_MSRC                  "MSRC"
+#define  VL53L0X_STRING_SEQUENCESTEP_PRE_RANGE             "PRE RANGE"
+#define  VL53L0X_STRING_SEQUENCESTEP_FINAL_RANGE           "FINAL RANGE"
+#endif /* USE_EMPTY_STRING */
+
+/* sensor operating modes */
+typedef enum {
+    range_single_shot_polling = 1,
+    range_continuous_polling,
+    range_continuous_interrupt,
+    range_continuous_polling_low_threshold,
+    range_continuous_polling_high_threshold,
+    range_continuous_polling_out_of_window,
+    range_continuous_interrupt_low_threshold,
+    range_continuous_interrupt_high_threshold,
+    range_continuous_interrupt_out_of_window,
+} OperatingMode;
+
+/** default device address */
+#define VL53L0X_DEFAULT_ADDRESS		0x52 /* (8-bit) */
+
+/* Classes -------------------------------------------------------------------*/
+/** Class representing a VL53L0 sensor component
+ */
+class VL53L0X : public RangeSensor
+{
+public:
+    /** Constructor
+     * @param[in] &i2c device I2C to be used for communication
+     * @param[in] &pin_gpio1 pin Mbed InterruptIn PinName to be used as component GPIO_1 INT
+     * @param[in] dev_addr device address, 0x29 by default
+     */
+    VL53L0X(DevI2C *i2c, DigitalOut *pin, PinName pin_gpio1, uint8_t dev_addr = VL53L0X_DEFAULT_ADDRESS) : _dev_i2c(i2c),
+        _gpio0(pin)
+    {
+        _my_device.I2cDevAddr = dev_addr;
+        _my_device.comms_type = 1; // VL53L0X_COMMS_I2C
+        _my_device.comms_speed_khz = 400;
+        _device = &_my_device;
+        _expgpio0 = NULL;
+        if (pin_gpio1 != NC) {
+            _gpio1Int = new InterruptIn(pin_gpio1);
+        } else {
+            _gpio1Int = NULL;
+        }
+    }
+
+    /** Constructor 2 (STMPE1600DigiOut)
+     * @param[in] i2c device I2C to be used for communication
+     * @param[in] &pin Gpio Expander STMPE1600DigiOut pin to be used as component GPIO_0 CE
+     * @param[in] pin_gpio1 pin Mbed InterruptIn PinName to be used as component GPIO_1 INT
+     * @param[in] device address, 0x29 by default
+     */
+    VL53L0X(DevI2C *i2c, Stmpe1600DigiOut *pin, PinName pin_gpio1,
+            uint8_t dev_addr = VL53L0X_DEFAULT_ADDRESS) : _dev_i2c(i2c), _expgpio0(pin)
+    {
+        _my_device.I2cDevAddr = dev_addr;
+        _my_device.comms_type = 1; // VL53L0X_COMMS_I2C
+        _my_device.comms_speed_khz = 400;
+        _device = &_my_device;
+        _gpio0 = NULL;
+        if (pin_gpio1 != NC) {
+            _gpio1Int = new InterruptIn(pin_gpio1);
+        } else {
+            _gpio1Int = NULL;
+        }
+    }
+
+    /** Destructor
+     */
+    virtual ~VL53L0X()
+    {
+        if (_gpio1Int != NULL) {
+            delete _gpio1Int;
+        }
+    }
+
+    /*** Interface Methods ***/
+    /*** High level API ***/
+    /**
+     * @brief       PowerOn the sensor
+     * @return      void
+     */
+    /* turns on the sensor */
+    void VL53L0X_on(void)
+    {
+        if (_gpio0) {
+            *_gpio0 = 1;
+        } else {
+            if (_expgpio0) {
+                *_expgpio0 = 1;
+            }
+        }
+        wait_ms(10);
+    }
+
+    /**
+     * @brief       PowerOff the sensor
+     * @return      void
+     */
+    /* turns off the sensor */
+    void VL53L0X_off(void)
+    {
+        if (_gpio0) {
+            *_gpio0 = 0;
+        } else {
+            if (_expgpio0) {
+                *_expgpio0 = 0;
+            }
+        }
+        wait_ms(10);
+    }
+
+
+    /**
+     * @brief       Initialize the sensor with default values
+     * @return      "0" on success
+     */
+    int init_sensor(uint8_t new_addr);
+
+    /**
+     * @brief       Start the measure indicated by operating mode
+     * @param[in]   operating_mode specifies requested measure
+     * @param[in]   fptr specifies call back function must be !NULL in case of interrupt measure
+     * @return      "0" on success
+     */
+    int start_measurement(OperatingMode operating_mode, void (*fptr)(void));
+
+    /**
+     * @brief       Get results for the measure indicated by operating mode
+     * @param[in]   operating_mode specifies requested measure results
+     * @param[out]  p_data pointer to the MeasureData_t structure to read data in to
+     * @return      "0" on success
+     */
+    int get_measurement(OperatingMode operating_mode, VL53L0X_RangingMeasurementData_t *p_data);
+
+    /**
+     * @brief       Stop the currently running measure indicate by operating_mode
+     * @param[in]   operating_mode specifies requested measure to stop
+     * @return      "0" on success
+     */
+    int stop_measurement(OperatingMode operating_mode);
+
+    /**
+     * @brief       Interrupt handling func to be called by user after an INT is occourred
+     * @param[in]   opeating_mode indicating the in progress measure
+     * @param[out]  Data pointer to the MeasureData_t structure to read data in to
+     * @return      "0" on success
+     */
+    int handle_irq(OperatingMode operating_mode, VL53L0X_RangingMeasurementData_t *data);
+
+    /**
+     * @brief       Enable interrupt measure IRQ
+     * @return      "0" on success
+     */
+    void enable_interrupt_measure_detection_irq(void)
+    {
+        if (_gpio1Int != NULL) {
+            _gpio1Int->enable_irq();
+        }
+    }
+
+    /**
+     * @brief       Disable interrupt measure IRQ
+     * @return      "0" on success
+     */
+    void disable_interrupt_measure_detection_irq(void)
+    {
+        if (_gpio1Int != NULL) {
+            _gpio1Int->disable_irq();
+        }
+    }
+
+    /**
+     * @brief       Attach a function to call when an interrupt is detected, i.e. measurement is ready
+     * @param[in]   fptr pointer to call back function to be called whenever an interrupt occours
+     * @return      "0" on success
+     */
+    void attach_interrupt_measure_detection_irq(void (*fptr)(void))
+    {
+        if (_gpio1Int != NULL) {
+            _gpio1Int->rise(fptr);
+        }
+    }
+
+    /** Wrapper functions */
+    /** @defgroup api_init Init functions
+     *  @brief    API init functions
+     *  @ingroup  api_hl
+     *  @{
+     */
+
+    /**
+     *
+     * @brief One time device initialization
+     *
+     * To be called once and only once after device is brought out of reset (Chip enable) and booted.
+     *
+     * @par Function Description
+     * When not used after a fresh device "power up" or reset, it may return @a #CALIBRATION_WARNING
+     * meaning wrong calibration data may have been fetched from device that can result in ranging offset error\n
+     * If application cannot execute device reset or need to run VL53L0X_data_init  multiple time
+     * then it  must ensure proper offset calibration saving and restore on its own
+     * by using @a VL53L0X_get_offset_calibration_data_micro_meter() on first power up and then @a VL53L0X_set_offset_calibration_data_micro_meter() all all subsequent init
+     *
+     * @param void
+     * @return     "0" on success,  @a #CALIBRATION_WARNING if failed
+     */
+    virtual int init(void *init)
+    {
+        return VL53L0X_data_init(_device);
+    }
+
+    /**
+      * @brief  Prepare device for operation
+      * @par Function Description
+      * Does static initialization and reprogram common default settings \n
+      * Device is prepared for new measure, ready single shot ranging or ALS typical polling operation\n
+      * After prepare user can : \n
+      * @li Call other API function to set other settings\n
+      * @li Configure the interrupt pins, etc... \n
+      * @li Then start ranging or ALS operations in single shot or continuous mode
+      *
+      * @param void
+      * @return  "0" on success
+      */
+    int prepare()
+    {
+        VL53L0X_Error status = VL53L0X_ERROR_NONE;
+        uint32_t ref_spad_count;
+        uint8_t is_aperture_spads;
+        uint8_t vhv_settings;
+        uint8_t phase_cal;
+
+        if (status == VL53L0X_ERROR_NONE) {
+            //printf("Call of VL53L0X_StaticInit\r\n");
+            status = VL53L0X_static_init(_device);   // Device Initialization
+        }
+
+        if (status == VL53L0X_ERROR_NONE) {
+            //printf("Call of VL53L0X_PerformRefCalibration\r\n");
+            status = VL53L0X_perform_ref_calibration(_device,
+                     &vhv_settings, &phase_cal);  // Device Initialization
+        }
+
+        if (status == VL53L0X_ERROR_NONE) {
+            //printf("Call of VL53L0X_PerformRefSpadManagement\r\n");
+            status = VL53L0X_perform_ref_spad_management(_device,
+                     &ref_spad_count, &is_aperture_spads);  // Device Initialization
+//            printf ("refSpadCount = %d, isApertureSpads = %d\r\n", refSpadCount, isApertureSpads);
+        }
+
+        return status;
+    }
+
+    /**
+    * @brief Start continuous ranging mode
+    *
+    * @details End user should ensure device is in idle state and not already running
+    * @return  "0" on success
+    */
+    int range_start_continuous_mode()
+    {
+        int status;
+        status = VL53L0X_set_device_mode(_device, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING);
+
+        if (status == VL53L0X_ERROR_NONE) {
+            //printf ("Call of VL53L0X_StartMeasurement\r\n");
+            status = VL53L0X_start_measurement(_device);
+        }
+
+        return status;
+    }
+
+    /**
+     * @brief Get ranging result and only that
+     *
+     * @par Function Description
+     * Unlike @a VL53L0X_get_ranging_measurement_data() this function only retrieves the range in millimeter \n
+     * It does any required up-scale translation\n
+     * It can be called after success status polling or in interrupt mode \n
+     * @warning these function is not doing wrap around filtering \n
+     * This function doesn't perform any data ready check!
+     *
+     * @param p_data  Pointer to range distance
+     * @return        "0" on success
+     */
+    virtual int get_distance(uint32_t *p_data)
+    {
+        int status = 0;
+        VL53L0X_RangingMeasurementData_t p_ranging_measurement_data;
+
+        status = start_measurement(range_single_shot_polling, NULL);
+        if (!status) {
+            status = get_measurement(range_single_shot_polling, &p_ranging_measurement_data);
+        }
+        if (p_ranging_measurement_data.RangeStatus == 0) {
+            // we have a valid range.
+            *p_data = p_ranging_measurement_data.RangeMilliMeter;
+        } else {
+            *p_data = 0;
+            status = VL53L0X_ERROR_RANGE_ERROR;
+        }
+        stop_measurement(range_single_shot_polling);
+        return status;
+    }
+
+    /** @}  */
+
+    /**
+     * @brief Set new device i2c address
+     *
+     * After completion the device will answer to the new address programmed.
+     *
+     * @param new_addr  The new i2c address (7bit)
+     * @return          "0" on success
+     */
+    int set_device_address(int new_addr)
+    {
+        int status;
+
+        status = VL53L0X_set_device_address(_device, new_addr);
+        if (!status) {
+            _device->I2cDevAddr = new_addr;
+        }
+        return status;
+
+    }
+
+    /**
+     * @brief Clear given system interrupt condition
+     *
+     * @par Function Description
+     * Clear given interrupt cause by writing into register #SYSTEM_INTERRUPT_CLEAR register.
+     * @param dev        The device
+     * @param int_clear  Which interrupt source to clear. Use any combinations of #INTERRUPT_CLEAR_RANGING , #INTERRUPT_CLEAR_ALS , #INTERRUPT_CLEAR_ERROR.
+     * @return           "0" on success
+     */
+    int clear_interrupt(uint8_t int_clear)
+    {
+        return VL53L0X_clear_interrupt_mask(_device, int_clear);
+    }
+
+    /**
+     *
+     * @brief One time device initialization
+     *
+     * To be called once and only once after device is brought out of reset
+     * (Chip enable) and booted see @a VL53L0X_WaitDeviceBooted()
+     *
+     * @par Function Description
+     * When not used after a fresh device "power up" or reset, it may return
+     * @a #VL53L0X_ERROR_CALIBRATION_WARNING meaning wrong calibration data
+     * may have been fetched from device that can result in ranging offset error\n
+     * If application cannot execute device reset or need to run VL53L0X_DataInit
+     * multiple time then it  must ensure proper offset calibration saving and
+     * restore on its own by using @a VL53L0X_GetOffsetCalibrationData() on first
+     * power up and then @a VL53L0X_SetOffsetCalibrationData() in all subsequent init
+     * This function will change the VL53L0X_State from VL53L0X_STATE_POWERDOWN to
+     * VL53L0X_STATE_WAIT_STATICINIT.
+     *
+     * @note This function accesses to the device
+     *
+     * @param   dev                   Device Handle
+     * @return  VL53L0X_ERROR_NONE    Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_data_init(VL53L0X_DEV dev);
+
+    /**
+     * @brief Do basic device init (and eventually patch loading)
+     * This function will change the VL53L0X_State from
+     * VL53L0X_STATE_WAIT_STATICINIT to VL53L0X_STATE_IDLE.
+     * In this stage all default setting will be applied.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                   Device Handle
+     * @return  VL53L0X_ERROR_NONE    Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_static_init(VL53L0X_DEV dev);
+
+    /**
+     * @brief Perform Reference Calibration
+     *
+     * @details Perform a reference calibration of the Device.
+     * This function should be run from time to time before doing
+     * a ranging measurement.
+     * This function will launch a special ranging measurement, so
+     * if interrupt are enable an interrupt will be done.
+     * This function will clear the interrupt generated automatically.
+     *
+     * @warning This function is a blocking function
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                  Device Handle
+     * @param   p_vhv_settings       Pointer to vhv settings parameter.
+     * @param   p_phase_cal          Pointer to PhaseCal parameter.
+     * @return  VL53L0X_ERROR_NONE   Success
+     * @return  "Other error code"   See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_perform_ref_calibration(VL53L0X_DEV dev, uint8_t *p_vhv_settings,
+            uint8_t *p_phase_cal);
+
+    /**
+     * @brief Get Reference Calibration Parameters
+     *
+     * @par Function Description
+     * Get Reference Calibration Parameters.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                            Device Handle
+     * @param   p_vhv_settings                 Pointer to VHV parameter
+     * @param   p_phase_cal                    Pointer to PhaseCal Parameter
+     * @return  VL53L0X_ERROR_NONE             Success
+     * @return  "Other error code"             See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_ref_calibration(VL53L0X_DEV dev,
+            uint8_t *p_vhv_settings, uint8_t *p_phase_cal);
+
+    VL53L0X_Error VL53L0X_set_ref_calibration(VL53L0X_DEV dev,
+            uint8_t vhv_settings, uint8_t phase_cal);
+
+    /**
+     * @brief Performs Reference Spad Management
+     *
+     * @par Function Description
+     * The reference SPAD initialization procedure determines the minimum amount
+     * of reference spads to be enables to achieve a target reference signal rate
+     * and should be performed once during initialization.
+     *
+     * @note This function Access to the device
+     *
+     * @note This function change the device mode to
+     * VL53L0X_DEVICEMODE_SINGLE_RANGING
+     *
+     * @param   dev                          Device Handle
+     * @param   ref_spad_count               Reports ref Spad Count
+     * @param   is_aperture_spads            Reports if spads are of type
+     *                                       aperture or non-aperture.
+     *                                       1:=aperture, 0:=Non-Aperture
+     * @return  VL53L0X_ERROR_NONE           Success
+     * @return  VL53L0X_ERROR_REF_SPAD_INIT  Error in the Ref Spad procedure.
+     * @return  "Other error code"           See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_perform_ref_spad_management(VL53L0X_DEV dev,
+            uint32_t *ref_spad_count, uint8_t *is_aperture_spads);
+
+    /**
+     * @brief Applies Reference SPAD configuration
+     *
+     * @par Function Description
+     * This function applies a given number of reference spads, identified as
+     * either Aperture or Non-Aperture.
+     * The requested spad count and type are stored within the device specific
+     * parameters data for access by the host.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                          Device Handle
+     * @param   refSpadCount                 Number of ref spads.
+     * @param   is_aperture_spads            Defines if spads are of type
+     *                                       aperture or non-aperture.
+     *                                       1:=aperture, 0:=Non-Aperture
+     * @return  VL53L0X_ERROR_NONE           Success
+     * @return  VL53L0X_ERROR_REF_SPAD_INIT  Error in the in the reference
+     *                                       spad configuration.
+     * @return  "Other error code"           See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_reference_spads(VL53L0X_DEV dev,
+            uint32_t refSpadCount, uint8_t is_aperture_spads);
+
+    /**
+     * @brief Retrieves SPAD configuration
+     *
+     * @par Function Description
+     * This function retrieves the current number of applied reference spads
+     * and also their type : Aperture or Non-Aperture.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                          Device Handle
+     * @param   p_spad_count                 Number ref Spad Count
+     * @param   p_is_aperture_spads          Reports if spads are of type
+     *                                       aperture or non-aperture.
+     *                                       1:=aperture, 0:=Non-Aperture
+     * @return  VL53L0X_ERROR_NONE           Success
+     * @return  VL53L0X_ERROR_REF_SPAD_INIT  Error in the in the reference
+     *                                       spad configuration.
+     * @return  "Other error code"           See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_reference_spads(VL53L0X_DEV dev,
+            uint32_t *p_spad_count, uint8_t *p_is_aperture_spads);
+
+    /**
+     * @brief Get part to part calibration offset
+     *
+     * @par Function Description
+     * Should only be used after a successful call to @a VL53L0X_DataInit to backup
+     * device NVM value
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                                     Device Handle
+     * @param   p_offset_calibration_data_micro_meter   Return part to part
+     * calibration offset from device (microns)
+     * @return  VL53L0X_ERROR_NONE                      Success
+     * @return  "Other error code"                      See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_offset_calibration_data_micro_meter(VL53L0X_DEV dev,
+            int32_t *p_offset_calibration_data_micro_meter);
+    /**
+     * Set or over-hide part to part calibration offset
+     * \sa VL53L0X_DataInit()   VL53L0X_GetOffsetCalibrationDataMicroMeter()
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                                      Device Handle
+     * @param   p_offset_calibration_data_micro_meter    Offset (microns)
+     * @return  VL53L0X_ERROR_NONE                       Success
+     * @return  "Other error code"                       See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_offset_calibration_data_micro_meter(VL53L0X_DEV dev,
+            int32_t offset_calibration_data_micro_meter);
+
+    VL53L0X_Error VL53L0X_perform_offset_calibration(VL53L0X_DEV dev,
+            FixPoint1616_t cal_distance_milli_meter,
+            int32_t *p_offset_micro_meter);
+
+    VL53L0X_Error VL53L0X_perform_xtalk_calibration(VL53L0X_DEV dev,
+            FixPoint1616_t xtalk_cal_distance,
+            FixPoint1616_t *p_xtalk_compensation_rate_mega_cps);
+
+    /**
+     * @brief Perform XTalk Measurement
+     *
+     * @details Measures the current cross talk from glass in front
+     * of the sensor.
+     * This functions performs a histogram measurement and uses the results
+     * to measure the crosstalk. For the function to be successful, there
+     * must be no target in front of the sensor.
+     *
+     * @warning This function is a blocking function
+     *
+     * @warning This function is not supported when the final range
+     * vcsel clock period is set below 10 PCLKS.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                    Device Handle
+     * @param   timeout_ms             Histogram measurement duration.
+     * @param   p_xtalk_per_spad       Output parameter containing the crosstalk
+     *                                 measurement result, in MCPS/Spad.
+     *                                 Format fixpoint 16:16.
+     * @param   p_ambient_too_high     Output parameter which indicate that
+     *                                 pXtalkPerSpad is not good if the Ambient
+     *                                 is too high.
+     * @return  VL53L0X_ERROR_NONE     Success
+     * @return  VL53L0X_ERROR_INVALID_PARAMS vcsel clock period not supported
+     *                                 for this operation.
+     *                                 Must not be less than 10PCLKS.
+     * @return  "Other error code"     See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_perform_xtalk_measurement(VL53L0X_DEV dev,
+            uint32_t timeout_ms, FixPoint1616_t *p_xtalk_per_spad,
+            uint8_t *p_ambient_too_high);
+
+    /**
+     * @brief Enable/Disable Cross talk compensation feature
+     *
+     * @note This function is not Implemented.
+     * Enable/Disable Cross Talk by set to zero the Cross Talk value
+     * by using @a VL53L0X_SetXTalkCompensationRateMegaCps().
+     *
+     * @param  dev                           Device Handle
+     * @param  x_talk_compensation_enable    Cross talk compensation
+     *                                       to be set 0=disabled else = enabled
+     * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented
+     */
+    VL53L0X_Error VL53L0X_set_x_talk_compensation_enable(VL53L0X_DEV dev,
+            uint8_t x_talk_compensation_enable);
+
+    /**
+     * @brief Get Cross talk compensation rate
+     *
+     * @note This function is not Implemented.
+     * Enable/Disable Cross Talk by set to zero the Cross Talk value by
+     * using @a VL53L0X_SetXTalkCompensationRateMegaCps().
+     *
+     * @param   dev                           Device Handle
+     * @param   p_x_talk_compensation_enable  Pointer to the Cross talk compensation
+     *                                        state 0=disabled or 1 = enabled
+     * @return  VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented
+     */
+    VL53L0X_Error VL53L0X_get_x_talk_compensation_enable(VL53L0X_DEV dev,
+            uint8_t *p_x_talk_compensation_enable);
+    /**
+     * @brief Set Cross talk compensation rate
+     *
+     * @par Function Description
+     * Set Cross talk compensation rate.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                                 Device Handle
+     * @param   x_talk_compensation_rate_mega_cps   Compensation rate in
+     *                                              Mega counts per second
+     *                                              (16.16 fix point) see
+     *                                              datasheet for details
+     * @return  VL53L0X_ERROR_NONE                  Success
+     * @return  "Other error code"                  See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_x_talk_compensation_rate_mega_cps(VL53L0X_DEV dev,
+            FixPoint1616_t x_talk_compensation_rate_mega_cps);
+
+    /**
+     * @brief Get Cross talk compensation rate
+     *
+     * @par Function Description
+     * Get Cross talk compensation rate.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                                 Device Handle
+     * @param   p_xtalk_compensation_rate_mega_cps  Pointer to Compensation rate
+     *                                              in Mega counts per second
+     *                                              (16.16 fix point) see
+     *                                              datasheet for details
+     * @return  VL53L0X_ERROR_NONE                  Success
+     * @return  "Other error code"                  See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_x_talk_compensation_rate_mega_cps(VL53L0X_DEV dev,
+            FixPoint1616_t *p_xtalk_compensation_rate_mega_cps);
+
+    /**
+     * @brief  Set a new device mode
+     * @par Function Description
+     * Set device to a new mode (ranging, histogram ...)
+     *
+     * @note This function doesn't Access to the device
+     *
+     * @param   dev                   Device Handle
+     * @param   device_mode           New device mode to apply
+     *                                Valid values are:
+     *                                VL53L0X_DEVICEMODE_SINGLE_RANGING
+     *                                VL53L0X_DEVICEMODE_CONTINUOUS_RANGING
+     *                                VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING
+     *                                VL53L0X_DEVICEMODE_SINGLE_HISTOGRAM
+     *                                VL53L0X_HISTOGRAMMODE_REFERENCE_ONLY
+     *                                VL53L0X_HISTOGRAMMODE_RETURN_ONLY
+     *                                VL53L0X_HISTOGRAMMODE_BOTH
+     *
+     *
+     * @return  VL53L0X_ERROR_NONE               Success
+     * @return  VL53L0X_ERROR_MODE_NOT_SUPPORTED This error occurs when
+     *                                           DeviceMode is not in the
+     *                                           supported list
+     */
+    VL53L0X_Error VL53L0X_set_device_mode(VL53L0X_DEV dev, VL53L0X_DeviceModes device_mode);
+
+    /**
+     * @brief  Get current new device mode
+     * @par Function Description
+     * Get actual mode of the device(ranging, histogram ...)
+     *
+     * @note This function doesn't Access to the device
+     *
+     * @param   dev                   Device Handle
+     * @param   p_device_mode         Pointer to current apply mode value
+     *                                Valid values are:
+     *                                VL53L0X_DEVICEMODE_SINGLE_RANGING
+     *                                VL53L0X_DEVICEMODE_CONTINUOUS_RANGING
+     *                                VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING
+     *                                VL53L0X_DEVICEMODE_SINGLE_HISTOGRAM
+     *                                VL53L0X_HISTOGRAMMODE_REFERENCE_ONLY
+     *                                VL53L0X_HISTOGRAMMODE_RETURN_ONLY
+     *                                VL53L0X_HISTOGRAMMODE_BOTH
+     *
+     * @return  VL53L0X_ERROR_NONE                   Success
+     * @return  VL53L0X_ERROR_MODE_NOT_SUPPORTED     This error occurs when
+     *                                               DeviceMode is not in the
+     *                                               supported list
+     */
+    VL53L0X_Error VL53L0X_get_device_mode(VL53L0X_DEV dev,
+                                          VL53L0X_DeviceModes *p_device_mode);
+
+    /**
+    * @brief Get current configuration for GPIO pin for a given device
+    *
+    * @note This function Access to the device
+    *
+    * @param   dev                   Device Handle
+    * @param   pin                   ID of the GPIO Pin
+    * @param   p_device_mode         Pointer to Device Mode associated to the Gpio.
+    * @param   p_functionality       Pointer to Pin functionality.
+    *                                Refer to ::VL53L0X_GpioFunctionality
+    * @param   p_polarity            Pointer to interrupt polarity.
+    *                                Active high or active low see
+    *                                ::VL53L0X_InterruptPolarity
+    * @return  VL53L0X_ERROR_NONE    Success
+    * @return  VL53L0X_ERROR_GPIO_NOT_EXISTING           Only Pin=0 is accepted.
+    * @return  VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED
+    *          This error occurs
+    *          when Funcionality programmed is not in the supported list:
+    *                      Supported value are:
+    *                      VL53L0X_GPIOFUNCTIONALITY_OFF,
+    *                      VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW,
+    *                      VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH,
+    *                      VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT,
+    *                      VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY
+    * @return  "Other error code"    See ::VL53L0X_Error
+    */
+    VL53L0X_Error VL53L0X_get_gpio_config(VL53L0X_DEV dev, uint8_t pin,
+                                          VL53L0X_DeviceModes *p_device_mode,
+                                          VL53L0X_GpioFunctionality *p_functionality,
+                                          VL53L0X_InterruptPolarity *p_polarity);
+
+    /**
+     * @brief Set the configuration of GPIO pin for a given device
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                   Device Handle
+     * @param   pin                   ID of the GPIO Pin
+     * @param   functionality         Select Pin functionality.
+     *  Refer to ::VL53L0X_GpioFunctionality
+     * @param   device_mode            Device Mode associated to the Gpio.
+     * @param   polarity              Set interrupt polarity. Active high
+     *   or active low see ::VL53L0X_InterruptPolarity
+     * @return  VL53L0X_ERROR_NONE                            Success
+     * @return  VL53L0X_ERROR_GPIO_NOT_EXISTING               Only Pin=0 is accepted.
+     * @return  VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED    This error occurs
+     * when Functionality programmed is not in the supported list:
+     *                             Supported value are:
+     *                             VL53L0X_GPIOFUNCTIONALITY_OFF,
+     *                             VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW,
+     *                             VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH,
+     VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT,
+     *                               VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_gpio_config(VL53L0X_DEV dev, uint8_t pin,
+                                          VL53L0X_DeviceModes device_mode, VL53L0X_GpioFunctionality functionality,
+                                          VL53L0X_InterruptPolarity polarity);
+
+    /**
+     * @brief Start device measurement
+     *
+     * @details Started measurement will depend on device parameters set through
+     * @a VL53L0X_SetParameters()
+     * This is a non-blocking function.
+     * This function will change the VL53L0X_State from VL53L0X_STATE_IDLE to
+     * VL53L0X_STATE_RUNNING.
+     *
+     * @note This function Access to the device
+     *
+
+     * @param   dev                  Device Handle
+     * @return  VL53L0X_ERROR_NONE                  Success
+     * @return  VL53L0X_ERROR_MODE_NOT_SUPPORTED    This error occurs when
+     * DeviceMode programmed with @a VL53L0X_SetDeviceMode is not in the supported
+     * list:
+     *                                   Supported mode are:
+     *                                   VL53L0X_DEVICEMODE_SINGLE_RANGING,
+     *                                   VL53L0X_DEVICEMODE_CONTINUOUS_RANGING,
+     *                                   VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING
+     * @return  VL53L0X_ERROR_TIME_OUT    Time out on start measurement
+     * @return  "Other error code"   See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_start_measurement(VL53L0X_DEV dev);
+
+    /**
+     * @brief Stop device measurement
+     *
+     * @details Will set the device in standby mode at end of current measurement\n
+     *          Not necessary in single mode as device shall return automatically
+     *          in standby mode at end of measurement.
+     *          This function will change the VL53L0X_State from VL53L0X_STATE_RUNNING
+     *          to VL53L0X_STATE_IDLE.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                  Device Handle
+     * @return  VL53L0X_ERROR_NONE    Success
+     * @return  "Other error code"   See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_stop_measurement(VL53L0X_DEV dev);
+
+    /**
+     * @brief Return device stop completion status
+     *
+     * @par Function Description
+     * Returns stop completiob status.
+     * User shall call this function after a stop command
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                    Device Handle
+     * @param   p_stop_status            Pointer to status variable to update
+     * @return  VL53L0X_ERROR_NONE      Success
+     * @return  "Other error code"     See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_stop_completed_status(VL53L0X_DEV dev,
+            uint32_t *p_stop_status);
+
+    /**
+     * @brief Return Measurement Data Ready
+     *
+     * @par Function Description
+     * This function indicate that a measurement data is ready.
+     * This function check if interrupt mode is used then check is done accordingly.
+     * If perform function clear the interrupt, this function will not work,
+     * like in case of @a VL53L0X_PerformSingleRangingMeasurement().
+     * The previous function is blocking function, VL53L0X_GetMeasurementDataReady
+     * is used for non-blocking capture.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                    Device Handle
+     * @param   p_measurement_data_ready  Pointer to Measurement Data Ready.
+     *  0=data not ready, 1 = data ready
+     * @return  VL53L0X_ERROR_NONE      Success
+     * @return  "Other error code"     See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_measurement_data_ready(VL53L0X_DEV dev,
+            uint8_t *p_measurement_data_ready);
+
+    /**
+     * @brief Retrieve the measurements from device for a given setup
+     *
+     * @par Function Description
+     * Get data from last successful Ranging measurement
+     * @warning USER should take care about  @a VL53L0X_GetNumberOfROIZones()
+     * before get data.
+     * PAL will fill a NumberOfROIZones times the corresponding data
+     * structure used in the measurement function.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                      Device Handle
+     * @param   p_ranging_measurement_data  Pointer to the data structure to fill up.
+     * @return  VL53L0X_ERROR_NONE        Success
+     * @return  "Other error code"       See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_ranging_measurement_data(VL53L0X_DEV dev,
+            VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data);
+
+    /**
+     * @brief Clear given system interrupt condition
+     *
+     * @par Function Description
+     * Clear given interrupt(s).
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                  Device Handle
+     * @param   interrupt_mask        Mask of interrupts to clear
+     * @return  VL53L0X_ERROR_NONE    Success
+     * @return  VL53L0X_ERROR_INTERRUPT_NOT_CLEARED    Cannot clear interrupts
+     *
+     * @return  "Other error code"   See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_clear_interrupt_mask(VL53L0X_DEV dev, uint32_t interrupt_mask);
+
+    /**
+     * @brief Return device interrupt status
+     *
+     * @par Function Description
+     * Returns currently raised interrupts by the device.
+     * User shall be able to activate/deactivate interrupts through
+     * @a VL53L0X_SetGpioConfig()
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                    Device Handle
+     * @param   p_interrupt_mask_status   Pointer to status variable to update
+     * @return  VL53L0X_ERROR_NONE      Success
+     * @return  "Other error code"     See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_interrupt_mask_status(VL53L0X_DEV dev,
+            uint32_t *p_interrupt_mask_status);
+
+    /**
+     * @brief Performs a single ranging measurement and retrieve the ranging
+     * measurement data
+     *
+     * @par Function Description
+     * This function will change the device mode to VL53L0X_DEVICEMODE_SINGLE_RANGING
+     * with @a VL53L0X_SetDeviceMode(),
+     * It performs measurement with @a VL53L0X_PerformSingleMeasurement()
+     * It get data from last successful Ranging measurement with
+     * @a VL53L0X_GetRangingMeasurementData.
+     * Finally it clear the interrupt with @a VL53L0X_ClearInterruptMask().
+     *
+     * @note This function Access to the device
+     *
+     * @note This function change the device mode to
+     * VL53L0X_DEVICEMODE_SINGLE_RANGING
+     *
+     * @param   dev                       Device Handle
+     * @param   p_ranging_measurement_data   Pointer to the data structure to fill up.
+     * @return  VL53L0X_ERROR_NONE         Success
+     * @return  "Other error code"        See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_perform_single_ranging_measurement(VL53L0X_DEV dev,
+            VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data);
+
+    /**
+     * @brief Single shot measurement.
+     *
+     * @par Function Description
+     * Perform simple measurement sequence (Start measure, Wait measure to end,
+     * and returns when measurement is done).
+     * Once function returns, user can get valid data by calling
+     * VL53L0X_GetRangingMeasurement or VL53L0X_GetHistogramMeasurement
+     * depending on defined measurement mode
+     * User should Clear the interrupt in case this are enabled by using the
+     * function VL53L0X_ClearInterruptMask().
+     *
+     * @warning This function is a blocking function
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                  Device Handle
+     * @return  VL53L0X_ERROR_NONE    Success
+     * @return  "Other error code"   See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_perform_single_measurement(VL53L0X_DEV dev);
+
+    /**
+    * @brief Read current status of the error register for the selected device
+    *
+    * @note This function Access to the device
+    *
+    * @param   dev                   Device Handle
+    * @param   p_device_error_status    Pointer to current error code of the device
+    * @return  VL53L0X_ERROR_NONE     Success
+    * @return  "Other error code"    See ::VL53L0X_Error
+    */
+    VL53L0X_Error VL53L0X_get_device_error_status(VL53L0X_DEV dev,
+            VL53L0X_DeviceError *p_device_error_status);
+
+    /**
+    * @brief Human readable error string for a given Error Code
+    *
+    * @note This function doesn't access to the device
+    *
+    * @param   error_code           The error code as stored on ::VL53L0X_DeviceError
+    * @param   p_device_error_string  The error string corresponding to the ErrorCode
+    * @return  VL53L0X_ERROR_NONE   Success
+    * @return  "Other error code"  See ::VL53L0X_Error
+    */
+    VL53L0X_Error VL53L0X_get_device_error_string(
+        VL53L0X_DeviceError error_code, char *p_device_error_string);
+
+    /**
+     * @brief Human readable Range Status string for a given RangeStatus
+     *
+     * @note This function doesn't access to the device
+     *
+     * @param   range_status         The RangeStatus code as stored on
+     * @a VL53L0X_RangingMeasurementData_t
+     * @param   p_range_status_string  The returned RangeStatus string.
+     * @return  VL53L0X_ERROR_NONE   Success
+     * @return  "Other error code"  See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_range_status_string(uint8_t range_status,
+            char *p_range_status_string);
+
+    VL53L0X_Error VL53L0X_get_total_signal_rate(VL53L0X_DEV dev,
+            VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data,
+            FixPoint1616_t *p_total_signal_rate_mcps);
+
+    VL53L0X_Error VL53L0X_get_total_xtalk_rate(VL53L0X_DEV dev,
+            VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data,
+            FixPoint1616_t *p_total_xtalk_rate_mcps);
+
+    /**
+     * @brief Get Ranging Timing Budget in microseconds
+     *
+     * @par Function Description
+     * Returns the programmed the maximum time allowed by the user to the
+     * device to run a full ranging sequence for the current mode
+     * (ranging, histogram, ASL ...)
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                                    Device Handle
+     * @param   p_measurement_timing_budget_micro_seconds   Max measurement time in
+     * microseconds.
+     *                                   Valid values are:
+     *                                   >= 17000 microsecs when wraparound enabled
+     *                                   >= 12000 microsecs when wraparound disabled
+     * @return  VL53L0X_ERROR_NONE                      Success
+     * @return  "Other error code"                     See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_measurement_timing_budget_micro_seconds(VL53L0X_DEV dev,
+            uint32_t *p_measurement_timing_budget_micro_seconds);
+
+    /**
+     * @brief Set Ranging Timing Budget in microseconds
+     *
+     * @par Function Description
+     * Defines the maximum time allowed by the user to the device to run a
+     * full ranging sequence for the current mode (ranging, histogram, ASL ...)
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                                Device Handle
+     * @param measurement_timing_budget_micro_seconds  Max measurement time in
+     * microseconds.
+     *                                   Valid values are:
+     *                                   >= 17000 microsecs when wraparound enabled
+     *                                   >= 12000 microsecs when wraparound disabled
+     * @return  VL53L0X_ERROR_NONE             Success
+     * @return  VL53L0X_ERROR_INVALID_PARAMS   This error is returned if
+     MeasurementTimingBudgetMicroSeconds out of range
+     * @return  "Other error code"            See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_measurement_timing_budget_micro_seconds(VL53L0X_DEV dev,
+            uint32_t measurement_timing_budget_micro_seconds);
+
+    /**
+     * @brief  Get specific limit check enable state
+     *
+     * @par Function Description
+     * This function get the enable state of a specific limit check.
+     * The limit check is identified with the LimitCheckId.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                           Device Handle
+     * @param   limit_check_id                  Limit Check ID
+     *  (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ).
+     * @param   p_limit_check_enable             Pointer to the check limit enable
+     * value.
+     *  if 1 the check limit
+     *        corresponding to LimitCheckId is Enabled
+     *  if 0 the check limit
+     *        corresponding to LimitCheckId is disabled
+     * @return  VL53L0X_ERROR_NONE             Success
+     * @return  VL53L0X_ERROR_INVALID_PARAMS   This error is returned
+     *  when LimitCheckId value is out of range.
+     * @return  "Other error code"            See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_limit_check_enable(VL53L0X_DEV dev, uint16_t limit_check_id,
+            uint8_t *p_limit_check_enable);
+
+    /**
+     * @brief  Enable/Disable a specific limit check
+     *
+     * @par Function Description
+     * This function Enable/Disable a specific limit check.
+     * The limit check is identified with the LimitCheckId.
+     *
+     * @note This function doesn't Access to the device
+     *
+     * @param   dev                           Device Handle
+     * @param   limit_check_id                  Limit Check ID
+     *  (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ).
+     * @param   limit_check_enable              if 1 the check limit
+     *  corresponding to LimitCheckId is Enabled
+     *                                        if 0 the check limit
+     *  corresponding to LimitCheckId is disabled
+     * @return  VL53L0X_ERROR_NONE             Success
+     * @return  VL53L0X_ERROR_INVALID_PARAMS   This error is returned
+     *  when LimitCheckId value is out of range.
+     * @return  "Other error code"            See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_limit_check_enable(VL53L0X_DEV dev, uint16_t limit_check_id,
+            uint8_t limit_check_enable);
+
+    /**
+     * @brief  Get a specific limit check value
+     *
+     * @par Function Description
+     * This function get a specific limit check value from device then it updates
+     * internal values and check enables.
+     * The limit check is identified with the LimitCheckId.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                           Device Handle
+     * @param   limit_check_id                  Limit Check ID
+     *  (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ).
+     * @param   p_limit_check_value              Pointer to Limit
+     *  check Value for a given LimitCheckId.
+     * @return  VL53L0X_ERROR_NONE             Success
+     * @return  VL53L0X_ERROR_INVALID_PARAMS   This error is returned
+     *  when LimitCheckId value is out of range.
+     * @return  "Other error code"            See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_limit_check_value(VL53L0X_DEV dev, uint16_t limit_check_id,
+            FixPoint1616_t *p_limit_check_value);
+
+    /**
+     * @brief  Set a specific limit check value
+     *
+     * @par Function Description
+     * This function set a specific limit check value.
+     * The limit check is identified with the LimitCheckId.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                           Device Handle
+     * @param   limit_check_id                  Limit Check ID
+     *  (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ).
+     * @param   limit_check_value               Limit check Value for a given
+     * LimitCheckId
+     * @return  VL53L0X_ERROR_NONE             Success
+     * @return  VL53L0X_ERROR_INVALID_PARAMS   This error is returned when either
+     *  LimitCheckId or LimitCheckValue value is out of range.
+     * @return  "Other error code"            See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_limit_check_value(VL53L0X_DEV dev, uint16_t limit_check_id,
+            FixPoint1616_t limit_check_value);
+
+    /**
+     * @brief  Get the current value of the signal used for the limit check
+     *
+     * @par Function Description
+     * This function get a the current value of the signal used for the limit check.
+     * To obtain the latest value you should run a ranging before.
+     * The value reported is linked to the limit check identified with the
+     * LimitCheckId.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                           Device Handle
+     * @param   limit_check_id                  Limit Check ID
+     *  (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ).
+     * @param   p_limit_check_current            Pointer to current Value for a
+     * given LimitCheckId.
+     * @return  VL53L0X_ERROR_NONE             Success
+     * @return  VL53L0X_ERROR_INVALID_PARAMS   This error is returned when
+     * LimitCheckId value is out of range.
+     * @return  "Other error code"            See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_limit_check_current(VL53L0X_DEV dev, uint16_t limit_check_id,
+            FixPoint1616_t *p_limit_check_current);
+
+    /**
+     * @brief  Return a the Status of the specified check limit
+     *
+     * @par Function Description
+     * This function returns the Status of the specified check limit.
+     * The value indicate if the check is fail or not.
+     * The limit check is identified with the LimitCheckId.
+     *
+     * @note This function doesn't Access to the device
+     *
+     * @param   dev                           Device Handle
+     * @param   limit_check_id                  Limit Check ID
+     (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ).
+     * @param   p_limit_check_status             Pointer to the
+     Limit Check Status of the given check limit.
+     * LimitCheckStatus :
+     * 0 the check is not fail
+     * 1 the check if fail or not enabled
+     *
+     * @return  VL53L0X_ERROR_NONE             Success
+     * @return  VL53L0X_ERROR_INVALID_PARAMS   This error is
+     returned when LimitCheckId value is out of range.
+     * @return  "Other error code"            See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_limit_check_status(VL53L0X_DEV dev,
+            uint16_t limit_check_id, uint8_t *p_limit_check_status);
+
+    /**
+     * Get continuous mode Inter-Measurement period in milliseconds
+     *
+     * @par Function Description
+     * When trying to set too short time return  INVALID_PARAMS minimal value
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                                  Device Handle
+     * @param   p_inter_measurement_period_milli_seconds  Pointer to programmed
+     *  Inter-Measurement Period in milliseconds.
+     * @return  VL53L0X_ERROR_NONE                    Success
+     * @return  "Other error code"                   See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_inter_measurement_period_milli_seconds(VL53L0X_DEV dev,
+            uint32_t *p_inter_measurement_period_milli_seconds);
+
+    /**
+     * Program continuous mode Inter-Measurement period in milliseconds
+     *
+     * @par Function Description
+     * When trying to set too short time return  INVALID_PARAMS minimal value
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                                  Device Handle
+     * @param   inter_measurement_period_milli_seconds   Inter-Measurement Period in ms.
+     * @return  VL53L0X_ERROR_NONE                    Success
+     * @return  "Other error code"                   See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_inter_measurement_period_milli_seconds(
+        VL53L0X_DEV dev, uint32_t inter_measurement_period_milli_seconds);
+
+    /**
+     * @brief Set new device address
+     *
+     * After completion the device will answer to the new address programmed.
+     * This function should be called when several devices are used in parallel
+     * before start programming the sensor.
+     * When a single device us used, there is no need to call this function.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                   Device Handle
+     * @param   device_address         The new Device address
+     * @return  VL53L0X_ERROR_NONE     Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_device_address(VL53L0X_DEV dev, uint8_t device_address);
+
+    /**
+     * @brief Do an hard reset or soft reset (depending on implementation) of the
+     * device \nAfter call of this function, device must be in same state as right
+     * after a power-up sequence.This function will change the VL53L0X_State to
+     * VL53L0X_STATE_POWERDOWN.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                   Device Handle
+     * @return  VL53L0X_ERROR_NONE     Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_reset_device(VL53L0X_DEV dev);
+
+    /**
+     * @brief  Get setup of Wrap around Check
+     *
+     * @par Function Description
+     * This function get the wrapAround check enable parameters
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                     Device Handle
+     * @param   p_wrap_around_check_enable  Pointer to the Wrap around Check state
+     *                                  0=disabled or 1 = enabled
+     * @return  VL53L0X_ERROR_NONE       Success
+     * @return  "Other error code"      See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_wrap_around_check_enable(VL53L0X_DEV dev,
+            uint8_t *p_wrap_around_check_enable);
+
+    /**
+     * @brief  Enable (or disable) Wrap around Check
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                    Device Handle
+     * @param   wrap_around_check_enable  Wrap around Check to be set
+     *                                 0=disabled, other = enabled
+     * @return  VL53L0X_ERROR_NONE      Success
+     * @return  "Other error code"     See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_wrap_around_check_enable(VL53L0X_DEV dev,
+            uint8_t wrap_around_check_enable);
+
+    /**
+     * @brief Gets the VCSEL pulse period.
+     *
+     * @par Function Description
+     * This function retrieves the VCSEL pulse period for the given period type.
+     *
+     * @note This function Accesses the device
+     *
+     * @param   dev                      Device Handle
+     * @param   vcsel_period_type          VCSEL period identifier (pre-range|final).
+     * @param   p_vcsel_pulse_period_pclk        Pointer to VCSEL period value.
+     * @return  VL53L0X_ERROR_NONE        Success
+     * @return  VL53L0X_ERROR_INVALID_PARAMS  Error VcselPeriodType parameter not
+     *                                       supported.
+     * @return  "Other error code"           See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_vcsel_pulse_period(VL53L0X_DEV dev,
+            VL53L0X_VcselPeriod vcsel_period_type, uint8_t *p_vcsel_pulse_period_pclk);
+
+    /**
+     * @brief Sets the VCSEL pulse period.
+     *
+     * @par Function Description
+     * This function retrieves the VCSEL pulse period for the given period type.
+     *
+     * @note This function Accesses the device
+     *
+     * @param   dev                       Device Handle
+     * @param   vcsel_period_type	      VCSEL period identifier (pre-range|final).
+     * @param   vcsel_pulse_period          VCSEL period value
+     * @return  VL53L0X_ERROR_NONE            Success
+     * @return  VL53L0X_ERROR_INVALID_PARAMS  Error VcselPeriodType parameter not
+     *                                       supported.
+     * @return  "Other error code"           See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_vcsel_pulse_period(VL53L0X_DEV dev,
+            VL53L0X_VcselPeriod vcsel_period_type, uint8_t vcsel_pulse_period);
+
+    /**
+     * @brief Set low and high Interrupt thresholds for a given mode
+     * (ranging, ALS, ...) for a given device
+     *
+     * @par Function Description
+     * Set low and high Interrupt thresholds for a given mode (ranging, ALS, ...)
+     * for a given device
+     *
+     * @note This function Access to the device
+     *
+     * @note DeviceMode is ignored for the current device
+     *
+     * @param   dev              Device Handle
+     * @param   device_mode       Device Mode for which change thresholds
+     * @param   threshold_low     Low threshold (mm, lux ..., depending on the mode)
+     * @param   threshold_high    High threshold (mm, lux ..., depending on the mode)
+     * @return  VL53L0X_ERROR_NONE    Success
+     * @return  "Other error code"   See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_interrupt_thresholds(VL53L0X_DEV dev,
+            VL53L0X_DeviceModes device_mode, FixPoint1616_t threshold_low,
+            FixPoint1616_t threshold_high);
+
+    /**
+     * @brief  Get high and low Interrupt thresholds for a given mode
+     *  (ranging, ALS, ...) for a given device
+     *
+     * @par Function Description
+     * Get high and low Interrupt thresholds for a given mode (ranging, ALS, ...)
+     * for a given device
+     *
+     * @note This function Access to the device
+     *
+     * @note DeviceMode is ignored for the current device
+     *
+     * @param   dev              Device Handle
+     * @param   device_mode       Device Mode from which read thresholds
+     * @param   p_threshold_low    Low threshold (mm, lux ..., depending on the mode)
+     * @param   p_threshold_high   High threshold (mm, lux ..., depending on the mode)
+     * @return  VL53L0X_ERROR_NONE   Success
+     * @return  "Other error code"  See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_interrupt_thresholds(VL53L0X_DEV dev,
+            VL53L0X_DeviceModes device_mode, FixPoint1616_t *p_threshold_low,
+            FixPoint1616_t *p_threshold_high);
+
+    /**
+     * @brief Reads the Device information for given Device
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                 Device Handle
+     * @param   p_VL53L0X_device_info  Pointer to current device info for a given
+     *  Device
+     * @return  VL53L0X_ERROR_NONE   Success
+     * @return  "Other error code"  See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_device_info(VL53L0X_DEV dev,
+                                          VL53L0X_DeviceInfo_t *p_VL53L0X_device_info);
+
+    /**
+     * @brief Gets the (on/off) state of all sequence steps.
+     *
+     * @par Function Description
+     * This function retrieves the state of all sequence step in the scheduler.
+     *
+     * @note This function Accesses the device
+     *
+     * @param   dev                          Device Handle
+     * @param   p_scheduler_sequence_steps      Pointer to struct containing result.
+     * @return  VL53L0X_ERROR_NONE            Success
+     * @return  "Other error code"           See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_sequence_step_enables(VL53L0X_DEV dev,
+            VL53L0X_SchedulerSequenceSteps_t *p_scheduler_sequence_steps);
+
+    /**
+     * @brief Sets the (on/off) state of a requested sequence step.
+     *
+     * @par Function Description
+     * This function enables/disables a requested sequence step.
+     *
+     * @note This function Accesses the device
+     *
+     * @param   dev                          Device Handle
+     * @param   sequence_step_id	         Sequence step identifier.
+     * @param   sequence_step_enabled          Demanded state {0=Off,1=On}
+     *                                       is enabled.
+     * @return  VL53L0X_ERROR_NONE            Success
+     * @return  VL53L0X_ERROR_INVALID_PARAMS  Error SequenceStepId parameter not
+     *                                       supported.
+     * @return  "Other error code"           See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_sequence_step_enable(VL53L0X_DEV dev,
+            VL53L0X_SequenceStepId sequence_step_id, uint8_t sequence_step_enabled);
+
+    /**
+     * @brief  Gets the fraction enable parameter indicating the resolution of
+     * range measurements.
+     *
+     * @par Function Description
+     * Gets the fraction enable state, which translates to the resolution of
+     * range measurements as follows :Enabled:=0.25mm resolution,
+     * Not Enabled:=1mm resolution.
+     *
+     * @note This function Accesses the device
+     *
+     * @param   dev               Device Handle
+     * @param   p_enabled           Output Parameter reporting the fraction enable state.
+     *
+     * @return  VL53L0X_ERROR_NONE                   Success
+     * @return  "Other error code"                  See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_fraction_enable(VL53L0X_DEV dev, uint8_t *p_enabled);
+
+    /**
+     * @brief  Sets the resolution of range measurements.
+     * @par Function Description
+     * Set resolution of range measurements to either 0.25mm if
+     * fraction enabled or 1mm if not enabled.
+     *
+     * @note This function Accesses the device
+     *
+     * @param   dev               Device Handle
+     * @param   enable            Enable high resolution
+     *
+     * @return  VL53L0X_ERROR_NONE               Success
+     * @return  "Other error code"              See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_range_fraction_enable(VL53L0X_DEV dev,
+            uint8_t enable);
+
+    /**
+    * @brief Return the VL53L0X PAL Implementation Version
+    *
+    * @note This function doesn't access to the device
+    *
+    * @param   p_version              Pointer to current PAL Implementation Version
+    * @return  VL53L0X_ERROR_NONE     Success
+    * @return  "Other error code"    See ::VL53L0X_Error
+    */
+    VL53L0X_Error VL53L0X_get_version(VL53L0X_Version_t *p_version);
+
+    /**
+     * @brief Reads the Product Revision for a for given Device
+     * This function can be used to distinguish cut1.0 from cut1.1.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                 Device Handle
+     * @param   p_product_revision_major  Pointer to Product Revision Major
+     * for a given Device
+     * @param   p_product_revision_minor  Pointer to Product Revision Minor
+     * for a given Device
+     * @return  VL53L0X_ERROR_NONE      Success
+     * @return  "Other error code"  See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_product_revision(VL53L0X_DEV dev,
+            uint8_t *p_product_revision_major, uint8_t *p_product_revision_minor);
+
+    /**
+     * @brief  Retrieve current device parameters
+     * @par Function Description
+     * Get actual parameters of the device
+     * @li Then start ranging operation.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                   Device Handle
+     * @param   p_device_parameters     Pointer to store current device parameters.
+     * @return  VL53L0X_ERROR_NONE     Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_device_parameters(VL53L0X_DEV dev,
+            VL53L0X_DeviceParameters_t *p_device_parameters);
+
+    /**
+     * @brief Human readable error string for current PAL error status
+     *
+     * @note This function doesn't access to the device
+     *
+     * @param   pal_error_code       The error code as stored on @a VL53L0X_Error
+     * @param   p_pal_error_string    The error string corresponding to the
+     * PalErrorCode
+     * @return  VL53L0X_ERROR_NONE  Success
+     * @return  "Other error code" See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_pal_error_string(VL53L0X_Error pal_error_code,
+            char *p_pal_error_string);
+
+    /**
+     * @brief Return the PAL Specification Version used for the current
+     * implementation.
+     *
+     * @note This function doesn't access to the device
+     *
+     * @param   p_pal_spec_version       Pointer to current PAL Specification Version
+     * @return  VL53L0X_ERROR_NONE        Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_pal_spec_version(
+        VL53L0X_Version_t *p_pal_spec_version);
+
+    /**
+     * @brief Reads the internal state of the PAL for a given Device
+     *
+     * @note This function doesn't access to the device
+     *
+     * @param   dev                   Device Handle
+     * @param   p_pal_state             Pointer to current state of the PAL for a
+     * given Device
+     * @return  VL53L0X_ERROR_NONE     Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_pal_state(VL53L0X_DEV dev,
+                                        VL53L0X_State *p_pal_state);
+
+    /**
+     * @brief Human readable PAL State string
+     *
+     * @note This function doesn't access to the device
+     *
+     * @param   pal_state_code          The State code as stored on @a VL53L0X_State
+     * @param   p_pal_state_string       The State string corresponding to the
+     * PalStateCode
+     * @return  VL53L0X_ERROR_NONE     Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_pal_state_string(VL53L0X_State pal_state_code,
+            char *p_pal_state_string);
+
+    /*** End High level API ***/
+private:
+    /* api.h functions */
+
+    /**
+     * @brief Wait for device booted after chip enable (hardware standby)
+     * This function can be run only when VL53L0X_State is VL53L0X_STATE_POWERDOWN.
+     *
+     * @note This function is not Implemented
+     *
+     * @param   dev      Device Handle
+     * @return  VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented
+     *
+     */
+    VL53L0X_Error VL53L0X_wait_device_booted(VL53L0X_DEV dev);
+
+
+    VL53L0X_Error sequence_step_enabled(VL53L0X_DEV dev,
+                                        VL53L0X_SequenceStepId sequence_step_id, uint8_t sequence_config,
+                                        uint8_t *p_sequence_step_enabled);
+
+    VL53L0X_Error VL53L0X_check_and_load_interrupt_settings(VL53L0X_DEV dev,
+            uint8_t start_not_stopflag);
+
+
+    /* api_core.h functions */
+
+    VL53L0X_Error VL53L0X_get_info_from_device(VL53L0X_DEV dev, uint8_t option);
+
+    VL53L0X_Error VL53L0X_device_read_strobe(VL53L0X_DEV dev);
+
+    VL53L0X_Error wrapped_VL53L0X_get_measurement_timing_budget_micro_seconds(VL53L0X_DEV dev,
+            uint32_t *p_measurement_timing_budget_micro_seconds);
+
+    VL53L0X_Error wrapped_VL53L0X_get_vcsel_pulse_period(VL53L0X_DEV dev,
+            VL53L0X_VcselPeriod vcsel_period_type, uint8_t *p_vcsel_pulse_period_pclk);
+
+    uint8_t VL53L0X_decode_vcsel_period(uint8_t vcsel_period_reg);
+
+    uint32_t VL53L0X_decode_timeout(uint16_t encoded_timeout);
+
+    uint32_t VL53L0X_calc_timeout_us(VL53L0X_DEV dev,
+                                     uint16_t timeout_period_mclks,
+                                     uint8_t vcsel_period_pclks);
+
+    uint32_t VL53L0X_calc_macro_period_ps(VL53L0X_DEV dev, uint8_t vcsel_period_pclks);
+
+    VL53L0X_Error VL53L0X_measurement_poll_for_completion(VL53L0X_DEV dev);
+
+    VL53L0X_Error VL53L0X_load_tuning_settings(VL53L0X_DEV dev,
+            uint8_t *p_tuning_setting_buffer);
+
+    VL53L0X_Error VL53L0X_get_pal_range_status(VL53L0X_DEV dev,
+            uint8_t device_range_status,
+            FixPoint1616_t signal_rate,
+            uint16_t effective_spad_rtn_count,
+            VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data,
+            uint8_t *p_pal_range_status);
+    VL53L0X_Error VL53L0X_calc_sigma_estimate(VL53L0X_DEV dev,
+            VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data,
+            FixPoint1616_t *p_sigma_estimate,
+            uint32_t *p_dmax_mm);
+    uint32_t VL53L0X_calc_timeout_mclks(VL53L0X_DEV dev,
+                                        uint32_t timeout_period_us,
+                                        uint8_t vcsel_period_pclks);
+    uint32_t VL53L0X_isqrt(uint32_t num);
+
+    uint32_t VL53L0X_quadrature_sum(uint32_t a, uint32_t b);
+
+    VL53L0X_Error VL53L0X_calc_dmax(
+        VL53L0X_DEV dev,
+        FixPoint1616_t total_signal_rate_mcps,
+        FixPoint1616_t total_corr_signal_rate_mcps,
+        FixPoint1616_t pw_mult,
+        uint32_t sigma_estimate_p1,
+        FixPoint1616_t sigma_estimate_p2,
+        uint32_t peak_vcsel_duration_us,
+        uint32_t *pd_max_mm);
+    VL53L0X_Error wrapped_VL53L0X_set_measurement_timing_budget_micro_seconds(VL53L0X_DEV dev,
+            uint32_t measurement_timing_budget_micro_seconds);
+    VL53L0X_Error get_sequence_step_timeout(VL53L0X_DEV dev,
+                                            VL53L0X_SequenceStepId sequence_step_id,
+                                            uint32_t *p_time_out_micro_secs);
+    VL53L0X_Error set_sequence_step_timeout(VL53L0X_DEV dev,
+                                            VL53L0X_SequenceStepId sequence_step_id,
+                                            uint32_t timeout_micro_secs);
+    uint16_t VL53L0X_encode_timeout(uint32_t timeout_macro_clks);
+    VL53L0X_Error wrapped_VL53L0X_set_vcsel_pulse_period(VL53L0X_DEV dev,
+            VL53L0X_VcselPeriod vcsel_period_type, uint8_t vcsel_pulse_period_pclk);
+    uint8_t lv53l0x_encode_vcsel_period(uint8_t vcsel_period_pclks);
+
+    /* api_calibration.h functions */
+    VL53L0X_Error VL53L0X_apply_offset_adjustment(VL53L0X_DEV dev);
+    VL53L0X_Error wrapped_VL53L0X_get_offset_calibration_data_micro_meter(VL53L0X_DEV dev,
+            int32_t *p_offset_calibration_data_micro_meter);
+    VL53L0X_Error wrapped_VL53L0X_set_offset_calibration_data_micro_meter(VL53L0X_DEV dev,
+            int32_t offset_calibration_data_micro_meter);
+    VL53L0X_Error wrapped_VL53L0X_perform_ref_spad_management(VL53L0X_DEV dev,
+            uint32_t *ref_spad_count,
+            uint8_t *is_aperture_spads);
+    VL53L0X_Error VL53L0X_perform_ref_calibration(VL53L0X_DEV dev,
+            uint8_t *p_vhv_settings, uint8_t *p_phase_cal, uint8_t get_data_enable);
+    VL53L0X_Error VL53L0X_perform_vhv_calibration(VL53L0X_DEV dev,
+            uint8_t *p_vhv_settings, const uint8_t get_data_enable,
+            const uint8_t restore_config);
+    VL53L0X_Error VL53L0X_perform_single_ref_calibration(VL53L0X_DEV dev,
+            uint8_t vhv_init_byte);
+    VL53L0X_Error VL53L0X_ref_calibration_io(VL53L0X_DEV dev, uint8_t read_not_write,
+            uint8_t vhv_settings, uint8_t phase_cal,
+            uint8_t *p_vhv_settings, uint8_t *p_phase_cal,
+            const uint8_t vhv_enable, const uint8_t phase_enable);
+    VL53L0X_Error VL53L0X_perform_phase_calibration(VL53L0X_DEV dev,
+            uint8_t *p_phase_cal, const uint8_t get_data_enable,
+            const uint8_t restore_config);
+    VL53L0X_Error enable_ref_spads(VL53L0X_DEV dev,
+                                   uint8_t aperture_spads,
+                                   uint8_t good_spad_array[],
+                                   uint8_t spad_array[],
+                                   uint32_t size,
+                                   uint32_t start,
+                                   uint32_t offset,
+                                   uint32_t spad_count,
+                                   uint32_t *p_last_spad);
+    void get_next_good_spad(uint8_t good_spad_array[], uint32_t size,
+                            uint32_t curr, int32_t *p_next);
+    uint8_t is_aperture(uint32_t spad_index);
+    VL53L0X_Error enable_spad_bit(uint8_t spad_array[], uint32_t size,
+                                  uint32_t spad_index);
+    VL53L0X_Error set_ref_spad_map(VL53L0X_DEV dev, uint8_t *p_ref_spad_array);
+    VL53L0X_Error get_ref_spad_map(VL53L0X_DEV dev, uint8_t *p_ref_spad_array);
+    VL53L0X_Error perform_ref_signal_measurement(VL53L0X_DEV dev,
+            uint16_t *p_ref_signal_rate);
+    VL53L0X_Error wrapped_VL53L0X_set_reference_spads(VL53L0X_DEV dev,
+            uint32_t count, uint8_t is_aperture_spads);
+
+    /* api_strings.h functions */
+    VL53L0X_Error wrapped_VL53L0X_get_device_info(VL53L0X_DEV dev,
+            VL53L0X_DeviceInfo_t *p_VL53L0X_device_info);
+    VL53L0X_Error VL53L0X_check_part_used(VL53L0X_DEV dev,
+                                          uint8_t *revision,
+                                          VL53L0X_DeviceInfo_t *p_VL53L0X_device_info);
+
+    /* Read function of the ID device */
+    //   virtual int read_id();
+    virtual int read_id(uint8_t *id);
+
+    VL53L0X_Error wait_measurement_data_ready(VL53L0X_DEV dev);
+
+    VL53L0X_Error wait_stop_completed(VL53L0X_DEV dev);
+
+    /* Write and read functions from I2C */
+    /**
+     * Write single byte register
+     * @param   dev       Device Handle
+     * @param   index     The register index
+     * @param   data      8 bit register data
+     * @return  VL53L0X_ERROR_NONE        Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_write_byte(VL53L0X_DEV dev, uint8_t index, uint8_t data);
+    /**
+     * Write word register
+     * @param   dev       Device Handle
+     * @param   index     The register index
+     * @param   data      16 bit register data
+     * @return  VL53L0X_ERROR_NONE        Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_write_word(VL53L0X_DEV dev, uint8_t index, uint16_t data);
+    /**
+     * Write double word (4 byte) register
+     * @param   dev       Device Handle
+     * @param   index     The register index
+     * @param   data      32 bit register data
+     * @return  VL53L0X_ERROR_NONE        Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_write_dword(VL53L0X_DEV dev, uint8_t index, uint32_t data);
+    /**
+     * Read single byte register
+     * @param   dev       Device Handle
+     * @param   index     The register index
+     * @param   data      pointer to 8 bit data
+     * @return  VL53L0X_ERROR_NONE        Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_read_byte(VL53L0X_DEV dev, uint8_t index, uint8_t *p_data);
+    /**
+     * Read word (2byte) register
+     * @param   dev       Device Handle
+     * @param   index     The register index
+     * @param   data      pointer to 16 bit data
+     * @return  VL53L0X_ERROR_NONE        Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_read_word(VL53L0X_DEV dev, uint8_t index, uint16_t *p_data);
+    /**
+     * Read dword (4byte) register
+     * @param   dev       Device Handle
+     * @param   index     The register index
+     * @param   data      pointer to 32 bit data
+     * @return  VL53L0X_ERROR_NONE        Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_read_dword(VL53L0X_DEV dev, uint8_t index, uint32_t *p_data);
+    /**
+     * Threat safe Update (read/modify/write) single byte register
+     *
+     * Final_reg = (Initial_reg & and_data) |or_data
+     *
+     * @param   dev        Device Handle
+     * @param   index      The register index
+     * @param   and_data    8 bit and data
+     * @param   or_data     8 bit or data
+     * @return  VL53L0X_ERROR_NONE        Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_update_byte(VL53L0X_DEV dev, uint8_t index, uint8_t and_data, uint8_t or_data);
+    /**
+     * Writes the supplied byte buffer to the device
+     * @param   dev       Device Handle
+     * @param   index     The register index
+     * @param   p_data     Pointer to uint8_t buffer containing the data to be written
+     * @param   count     Number of bytes in the supplied byte buffer
+     * @return  VL53L0X_ERROR_NONE        Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_write_multi(VL53L0X_DEV dev, uint8_t index, uint8_t *p_data, uint32_t count);
+    /**
+     * Reads the requested number of bytes from the device
+     * @param   dev       Device Handle
+     * @param   index     The register index
+     * @param   p_data     Pointer to the uint8_t buffer to store read data
+     * @param   count     Number of uint8_t's to read
+     * @return  VL53L0X_ERROR_NONE        Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_read_multi(VL53L0X_DEV dev, uint8_t index, uint8_t *p_data, uint32_t count);
+
+    /**
+     * @brief  Writes a buffer towards the I2C peripheral device.
+     * @param  dev       Device Handle
+     * @param  p_data pointer to the byte-array data to send
+     * @param  number_of_bytes number of bytes to be written.
+     * @retval 0 if ok,
+     * @retval -1 if an I2C error has occured
+     * @note   On some devices if NumByteToWrite is greater
+     *         than one, the RegisterAddr must be masked correctly!
+     */
+    VL53L0X_Error VL53L0X_i2c_write(uint8_t dev, uint8_t index, uint8_t *p_data, uint16_t number_of_bytes);
+
+    /**
+     * @brief  Reads a buffer from the I2C peripheral device.
+     * @param  dev       Device Handle
+     * @param  p_data pointer to the byte-array to read data in to
+     * @param  number_of_bytes number of bytes to be read.
+     * @retval 0 if ok,
+     * @retval -1 if an I2C error has occured
+     * @note   On some devices if NumByteToWrite is greater
+     *         than one, the RegisterAddr must be masked correctly!
+     */
+    VL53L0X_Error VL53L0X_i2c_read(uint8_t dev, uint8_t index, uint8_t *p_data, uint16_t number_of_bytes);
+
+    /**
+     * @brief execute delay in all polling API call
+     *
+     * A typical multi-thread or RTOs implementation is to sleep the task for some 5ms (with 100Hz max rate faster polling is not needed)
+     * if nothing specific is need you can define it as an empty/void macro
+     * @code
+     * #define VL53L0X_PollingDelay(...) (void)0
+     * @endcode
+     * @param dev       Device Handle
+     * @return  VL53L0X_ERROR_NONE        Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_polling_delay(VL53L0X_DEV dev);   /* usually best implemented as a real function */
+
+    int is_present()
+    {
+        int status;
+        uint8_t id = 0;
+
+        status = read_id(&id);
+        if (status) {
+            VL53L0X_ErrLog("Failed to read ID device. Device not present!\n\r");
+        }
+        return status;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////////////////////////
+    //Added functions                                                                                    //
+    ///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * @brief  Cycle Power to Device
+     *
+     * @return status - status 0 = ok, 1 = error
+     *
+     */
+    int32_t VL53L0X_cycle_power(void);
+
+    uint8_t VL53L0X_encode_vcsel_period(uint8_t vcsel_period_pclks);
+
+    VL53L0X_Error wrapped_VL53L0X_get_device_error_string(VL53L0X_DeviceError error_code,
+            char *p_device_error_string);
+
+    VL53L0X_Error wrapped_VL53L0X_get_limit_check_info(VL53L0X_DEV dev, uint16_t limit_check_id,
+            char *p_limit_check_string);
+
+    VL53L0X_Error wrapped_VL53L0X_get_pal_error_string(VL53L0X_Error pal_error_code,
+            char *p_pal_error_string);
+
+    VL53L0X_Error wrapped_VL53L0X_get_pal_state_string(VL53L0X_State pal_state_code,
+            char *p_pal_state_string);
+
+    VL53L0X_Error wrapped_VL53L0X_get_range_status_string(uint8_t range_status,
+            char *p_range_status_string);
+
+    VL53L0X_Error wrapped_VL53L0X_get_ref_calibration(VL53L0X_DEV dev,
+            uint8_t *p_vhv_settings, uint8_t *p_phase_cal);
+
+
+    VL53L0X_Error count_enabled_spads(uint8_t spad_array[],
+                                      uint32_t byte_count, uint32_t max_spads,
+                                      uint32_t *p_total_spads_enabled, uint8_t *p_is_aperture);
+
+    VL53L0X_Error wrapped_VL53L0X_get_sequence_steps_info(VL53L0X_SequenceStepId sequence_step_id,
+            char *p_sequence_steps_string);
+
+
+    /**
+     * @brief Gets the name of a given sequence step.
+     *
+     * @par Function Description
+     * This function retrieves the name of sequence steps corresponding to
+     * SequenceStepId.
+     *
+     * @note This function doesn't Accesses the device
+     *
+     * @param   sequence_step_id               Sequence step identifier.
+     * @param   p_sequence_steps_string         Pointer to Info string
+     *
+     * @return  VL53L0X_ERROR_NONE            Success
+     * @return  "Other error code"           See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_sequence_steps_info(VL53L0X_SequenceStepId sequence_step_id,
+            char *p_sequence_steps_string);
+
+    /**
+    * @brief Get the frequency of the timer used for ranging results time stamps
+    *
+    * @param[out] p_timer_freq_hz : pointer for timer frequency
+    *
+    * @return status : 0 = ok, 1 = error
+    *
+    */
+    int32_t VL53L0X_get_timer_frequency(int32_t *p_timer_freq_hz);
+
+    /**
+    * @brief Get the timer value in units of timer_freq_hz (see VL53L0X_get_timestamp_frequency())
+    *
+    * @param[out] p_timer_count : pointer for timer count value
+    *
+    * @return status : 0 = ok, 1 = error
+    *
+    */
+    int32_t VL53L0X_get_timer_value(int32_t *p_timer_count);
+
+    /**
+    * @brief Configure ranging interrupt reported to system
+    *
+    * @note This function is not Implemented
+    *
+    * @param   dev                  Device Handle
+    * @param   interrupt_mask         Mask of interrupt to Enable/disable
+    *  (0:interrupt disabled or 1: interrupt enabled)
+    * @return  VL53L0X_ERROR_NOT_IMPLEMENTED   Not implemented
+    */
+    VL53L0X_Error VL53L0X_enable_interrupt_mask(VL53L0X_DEV dev,
+            uint32_t interrupt_mask);
+
+    /**
+     * @brief  Get Dmax Calibration Parameters for a given device
+     *
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                     Device Handle
+     * @param   p_range_milli_meter        Pointer to Calibration Distance
+     * @param   p_signal_rate_rtn_mega_cps   Pointer to Signal rate return
+     * @return  VL53L0X_ERROR_NONE       Success
+     * @return  "Other error code"      See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_dmax_cal_parameters(VL53L0X_DEV dev,
+            uint16_t *p_range_milli_meter, FixPoint1616_t *p_signal_rate_rtn_mega_cps);
+
+    /**
+    * @brief   Set Dmax Calibration Parameters for a given device
+    * When one of the parameter is zero, this function will get parameter
+    * from NVM.
+    * @note This function doesn't Access to the device
+    *
+    * @param   dev                    Device Handle
+    * @param   range_milli_meter        Calibration Distance
+    * @param   signal_rate_rtn_mega_cps   Signal rate return read at CalDistance
+    * @return  VL53L0X_ERROR_NONE      Success
+    * @return  "Other error code"     See ::VL53L0X_Error
+    */
+    VL53L0X_Error VL53L0X_get_dmax_cal_parameters(VL53L0X_DEV dev,
+            uint16_t range_milli_meter, FixPoint1616_t signal_rate_rtn_mega_cps);
+
+    /**
+    * @brief Retrieve the measurements from device for a given setup
+    *
+    * @par Function Description
+    * Get data from last successful Histogram measurement
+    * @warning USER should take care about  @a VL53L0X_GetNumberOfROIZones()
+    * before get data.
+    * PAL will fill a NumberOfROIZones times the corresponding data structure
+    * used in the measurement function.
+    *
+    * @note This function is not Implemented
+    *
+    * @param   dev                         Device Handle
+    * @param   p_histogram_measurement_data   Pointer to the histogram data structure.
+    * @return  VL53L0X_ERROR_NOT_IMPLEMENTED   Not implemented
+    */
+    VL53L0X_Error VL53L0X_get_histogram_measurement_data(VL53L0X_DEV dev,
+            VL53L0X_HistogramMeasurementData_t *p_histogram_measurement_data);
+
+    /**
+    * @brief  Get current new device mode
+    * @par Function Description
+    * Get current Histogram mode of a Device
+    *
+    * @note This function doesn't Access to the device
+    *
+    * @param   dev                   Device Handle
+    * @param   p_histogram_mode        Pointer to current Histogram Mode value
+    *                                Valid values are:
+    *                                VL53L0X_HISTOGRAMMODE_DISABLED
+    *                                VL53L0X_DEVICEMODE_SINGLE_HISTOGRAM
+    *                                VL53L0X_HISTOGRAMMODE_REFERENCE_ONLY
+    *                                VL53L0X_HISTOGRAMMODE_RETURN_ONLY
+    *                                VL53L0X_HISTOGRAMMODE_BOTH
+    * @return  VL53L0X_ERROR_NONE     Success
+    * @return  "Other error code"    See ::VL53L0X_Error
+    */
+    VL53L0X_Error VL53L0X_get_histogram_mode(VL53L0X_DEV dev,
+            VL53L0X_HistogramModes *p_histogram_mode);
+
+    /**
+     * @brief  Set a new Histogram mode
+     * @par Function Description
+     * Set device to a new Histogram mode
+     *
+     * @note This function doesn't Access to the device
+     *
+     * @param   dev                   Device Handle
+     * @param   histogram_mode         New device mode to apply
+     *                                Valid values are:
+     *                                VL53L0X_HISTOGRAMMODE_DISABLED
+     *                                VL53L0X_DEVICEMODE_SINGLE_HISTOGRAM
+     *                                VL53L0X_HISTOGRAMMODE_REFERENCE_ONLY
+     *                                VL53L0X_HISTOGRAMMODE_RETURN_ONLY
+     *                                VL53L0X_HISTOGRAMMODE_BOTH
+     *
+     * @return  VL53L0X_ERROR_NONE                   Success
+     * @return  VL53L0X_ERROR_MODE_NOT_SUPPORTED     This error occurs when
+     * HistogramMode is not in the supported list
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_histogram_mode(VL53L0X_DEV dev,
+            VL53L0X_HistogramModes histogram_mode);
+
+    /**
+     * @brief  Return a description string for a given limit check number
+     *
+     * @par Function Description
+     * This function returns a description string for a given limit check number.
+     * The limit check is identified with the LimitCheckId.
+     *
+     * @note This function doesn't Access to the device
+     *
+     * @param   dev                           Device Handle
+     * @param   limit_check_id                  Limit Check ID
+     (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ).
+     * @param   p_limit_check_string             Pointer to the
+     description string of the given check limit.
+     * @return  VL53L0X_ERROR_NONE             Success
+     * @return  VL53L0X_ERROR_INVALID_PARAMS   This error is
+     returned when LimitCheckId value is out of range.
+     * @return  "Other error code"            See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_limit_check_info(VL53L0X_DEV dev,
+            uint16_t limit_check_id, char *p_limit_check_string);
+
+    /**
+     * @brief Get the linearity corrective gain
+     *
+     * @par Function Description
+     * Should only be used after a successful call to @a VL53L0X_DataInit to backup
+     * device NVM value
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                                Device Handle
+     * @param   p_linearity_corrective_gain           Pointer to the linearity
+     * corrective gain in x1000
+     * if value is 1000 then no modification is applied.
+     * @return  VL53L0X_ERROR_NONE                  Success
+     * @return  "Other error code"                 See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_linearity_corrective_gain(VL53L0X_DEV dev,
+            uint16_t *p_linearity_corrective_gain);
+
+    /**
+     * Set the linearity corrective gain
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                                Device Handle
+     * @param   linearity_corrective_gain            Linearity corrective
+     * gain in x1000
+     * if value is 1000 then no modification is applied.
+     * @return  VL53L0X_ERROR_NONE                  Success
+     * @return  "Other error code"                 See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_linearity_corrective_gain(VL53L0X_DEV dev,
+            int16_t linearity_corrective_gain);
+
+    /**
+     * @brief Get the Maximum number of ROI Zones managed by the Device
+     *
+     * @par Function Description
+     * Get Maximum number of ROI Zones managed by the Device.
+     *
+     * @note This function doesn't Access to the device
+     *
+     * @param   dev                    Device Handle
+     * @param   p_max_number_of_roi_zones   Pointer to the Maximum Number
+     *  of ROI Zones value.
+     * @return  VL53L0X_ERROR_NONE      Success
+     */
+    VL53L0X_Error VL53L0X_get_max_number_of_roi_zones(VL53L0X_DEV dev,
+            uint8_t *p_max_number_of_roi_zones);
+
+    /**
+     * @brief Retrieve the Reference Signal after a measurements
+     *
+     * @par Function Description
+     * Get Reference Signal from last successful Ranging measurement
+     * This function return a valid value after that you call the
+     * @a VL53L0X_GetRangingMeasurementData().
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                      Device Handle
+     * @param   p_measurement_ref_signal    Pointer to the Ref Signal to fill up.
+     * @return  VL53L0X_ERROR_NONE        Success
+     * @return  "Other error code"       See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_measurement_ref_signal(VL53L0X_DEV dev,
+            FixPoint1616_t *p_measurement_ref_signal);
+
+    /**
+     * @brief  Get the number of the check limit managed by a given Device
+     *
+     * @par Function Description
+     * This function give the number of the check limit managed by the Device
+     *
+     * @note This function doesn't Access to the device
+     *
+     * @param   p_number_of_limit_check           Pointer to the number of check limit.
+     * @return  VL53L0X_ERROR_NONE             Success
+     * @return  "Other error code"            See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_number_of_limit_check(
+        uint16_t *p_number_of_limit_check);
+
+    /**
+     * @brief Get the number of ROI Zones managed by the Device
+     *
+     * @par Function Description
+     * Get number of ROI Zones managed by the Device
+     * USER should take care about  @a VL53L0X_GetNumberOfROIZones()
+     * before get data after a perform measurement.
+     * PAL will fill a NumberOfROIZones times the corresponding data
+     * structure used in the measurement function.
+     *
+     * @note This function doesn't Access to the device
+     *
+     * @param   dev                   Device Handle
+     * @param   p_number_of_roi_zones     Pointer to the Number of ROI Zones value.
+     * @return  VL53L0X_ERROR_NONE     Success
+     */
+    VL53L0X_Error VL53L0X_get_number_of_roi_zones(VL53L0X_DEV dev,
+            uint8_t *p_number_of_roi_zones);
+
+    /**
+     * @brief Set the number of ROI Zones to be used for a specific Device
+     *
+     * @par Function Description
+     * Set the number of ROI Zones to be used for a specific Device.
+     * The programmed value should be less than the max number of ROI Zones given
+     * with @a VL53L0X_GetMaxNumberOfROIZones().
+     * This version of API manage only one zone.
+     *
+     * @param   dev                           Device Handle
+     * @param   number_of_roi_zones              Number of ROI Zones to be used for a
+     *  specific Device.
+     * @return  VL53L0X_ERROR_NONE             Success
+     * @return  VL53L0X_ERROR_INVALID_PARAMS   This error is returned if
+     * NumberOfROIZones != 1
+     */
+    VL53L0X_Error VL53L0X_set_number_of_roi_zones(VL53L0X_DEV dev,
+            uint8_t number_of_roi_zones);
+
+    /**
+     * @brief Gets number of sequence steps managed by the API.
+     *
+     * @par Function Description
+     * This function retrieves the number of sequence steps currently managed
+     * by the API
+     *
+     * @note This function Accesses the device
+     *
+     * @param   dev                          Device Handle
+     * @param   p_number_of_sequence_steps       Out parameter reporting the number of
+     *                                       sequence steps.
+     * @return  VL53L0X_ERROR_NONE            Success
+     * @return  "Other error code"           See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_number_of_sequence_steps(VL53L0X_DEV dev,
+            uint8_t *p_number_of_sequence_steps);
+    /**
+     * @brief Get the power mode for a given Device
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                   Device Handle
+     * @param   p_power_mode            Pointer to the current value of the power
+     * mode. see ::VL53L0X_PowerModes
+     *                                Valid values are:
+     *                                VL53L0X_POWERMODE_STANDBY_LEVEL1,
+     *                                VL53L0X_POWERMODE_IDLE_LEVEL1
+     * @return  VL53L0X_ERROR_NONE     Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_power_mode(VL53L0X_DEV dev,
+                                         VL53L0X_PowerModes *p_power_mode);
+
+    /**
+     * @brief Set the power mode for a given Device
+     * The power mode can be Standby or Idle. Different level of both Standby and
+     * Idle can exists.
+     * This function should not be used when device is in Ranging state.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                   Device Handle
+     * @param   power_mode             The value of the power mode to set.
+     * see ::VL53L0X_PowerModes
+     *                                Valid values are:
+     *                                VL53L0X_POWERMODE_STANDBY_LEVEL1,
+     *                                VL53L0X_POWERMODE_IDLE_LEVEL1
+     * @return  VL53L0X_ERROR_NONE                  Success
+     * @return  VL53L0X_ERROR_MODE_NOT_SUPPORTED    This error occurs when PowerMode
+     * is not in the supported list
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_power_mode(VL53L0X_DEV dev,
+                                         VL53L0X_PowerModes power_mode);
+
+    /**
+     * @brief Retrieves SPAD configuration
+     *
+     * @par Function Description
+     * This function retrieves the current number of applied reference spads
+     * and also their type : Aperture or Non-Aperture.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                          Device Handle
+     * @param   p_spad_count                 Number ref Spad Count
+     * @param   p_is_aperture_spads              Reports if spads are of type
+     *                                       aperture or non-aperture.
+     *                                       1:=aperture, 0:=Non-Aperture
+     * @return  VL53L0X_ERROR_NONE            Success
+     * @return  VL53L0X_ERROR_REF_SPAD_INIT   Error in the in the reference
+     *                                       spad configuration.
+     * @return  "Other error code"           See ::VL53L0X_Error
+     */
+    VL53L0X_Error wrapped_VL53L0X_get_reference_spads(VL53L0X_DEV dev,
+            uint32_t *p_spad_count, uint8_t *p_is_aperture_spads);
+
+    /**
+     * @brief Gets the (on/off) state of a requested sequence step.
+     *
+     * @par Function Description
+     * This function retrieves the state of a requested sequence step, i.e. on/off.
+     *
+     * @note This function Accesses the device
+     *
+     * @param   dev                    Device Handle
+     * @param   sequence_step_id         Sequence step identifier.
+     * @param   p_sequence_step_enabled   Out parameter reporting if the sequence step
+     *                                 is enabled {0=Off,1=On}.
+     * @return  VL53L0X_ERROR_NONE            Success
+     * @return  VL53L0X_ERROR_INVALID_PARAMS  Error SequenceStepId parameter not
+     *                                       supported.
+     * @return  "Other error code"           See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_sequence_step_enable(VL53L0X_DEV dev,
+            VL53L0X_SequenceStepId sequence_step_id, uint8_t *p_sequence_step_enabled);
+
+
+    /**
+     * @brief Gets the timeout of a requested sequence step.
+     *
+     * @par Function Description
+     * This function retrieves the timeout of a requested sequence step.
+     *
+     * @note This function Accesses the device
+     *
+     * @param   dev                          Device Handle
+     * @param   sequence_step_id               Sequence step identifier.
+     * @param   p_time_out_milli_secs            Timeout value.
+     * @return  VL53L0X_ERROR_NONE            Success
+     * @return  VL53L0X_ERROR_INVALID_PARAMS  Error SequenceStepId parameter not
+     *                                       supported.
+     * @return  "Other error code"           See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_sequence_step_timeout(VL53L0X_DEV dev,
+            VL53L0X_SequenceStepId sequence_step_id,
+            FixPoint1616_t *p_time_out_milli_secs);
+
+    /**
+     * @brief Sets the timeout of a requested sequence step.
+     *
+     * @par Function Description
+     * This function sets the timeout of a requested sequence step.
+     *
+     * @note This function Accesses the device
+     *
+     * @param   dev                          Device Handle
+     * @param   sequence_step_id               Sequence step identifier.
+     * @param   time_out_milli_secs             Demanded timeout
+     * @return  VL53L0X_ERROR_NONE            Success
+     * @return  VL53L0X_ERROR_INVALID_PARAMS  Error SequenceStepId parameter not
+     *                                       supported.
+     * @return  "Other error code"           See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_sequence_step_timeout(VL53L0X_DEV dev,
+            VL53L0X_SequenceStepId sequence_step_id, FixPoint1616_t time_out_milli_secs);
+
+    /**
+    * @brief  Get the current SPAD Ambient Damper Factor value
+    *
+    * @par Function Description
+    * This function get the SPAD Ambient Damper Factor value
+    *
+    * @note This function Access to the device
+    *
+    * @param   dev                           Device Handle
+    * @param   p_spad_ambient_damper_factor      Pointer to programmed SPAD Ambient
+    * Damper Factor value
+    * @return  VL53L0X_ERROR_NONE             Success
+    * @return  "Other error code"            See ::VL53L0X_Error
+    */
+    VL53L0X_Error VL53L0X_get_spad_ambient_damper_factor(VL53L0X_DEV dev,
+            uint16_t *p_spad_ambient_damper_factor);
+    /**
+    * @brief  Set the SPAD Ambient Damper Factor value
+    *
+    * @par Function Description
+    * This function set the SPAD Ambient Damper Factor value
+    *
+    * @note This function Access to the device
+    *
+    * @param   dev                           Device Handle
+    * @param   spad_ambient_damper_factor       SPAD Ambient Damper Factor value
+    * @return  VL53L0X_ERROR_NONE             Success
+    * @return  "Other error code"            See ::VL53L0X_Error
+    */
+    VL53L0X_Error VL53L0X_set_spad_ambient_damper_factor(VL53L0X_DEV dev,
+            uint16_t spad_ambient_damper_factor);
+
+    /**
+     * @brief  Get the current SPAD Ambient Damper Threshold value
+     *
+     * @par Function Description
+     * This function get the SPAD Ambient Damper Threshold value
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                           Device Handle
+     * @param   p_spad_ambient_damper_threshold   Pointer to programmed
+     *                                        SPAD Ambient Damper Threshold value
+     * @return  VL53L0X_ERROR_NONE             Success
+     * @return  "Other error code"            See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_get_spad_ambient_damper_threshold(VL53L0X_DEV dev,
+            uint16_t *p_spad_ambient_damper_threshold);
+
+    /**
+     * @brief  Set the SPAD Ambient Damper Threshold value
+     *
+     * @par Function Description
+     * This function set the SPAD Ambient Damper Threshold value
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                           Device Handle
+     * @param   spad_ambient_damper_threshold    SPAD Ambient Damper Threshold value
+     * @return  VL53L0X_ERROR_NONE             Success
+     * @return  "Other error code"            See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_spad_ambient_damper_threshold(VL53L0X_DEV dev,
+            uint16_t spad_ambient_damper_threshold);
+
+    /**
+     * @brief Get the maximal distance for actual setup
+     * @par Function Description
+     * Device must be initialized through @a VL53L0X_SetParameters() prior calling
+     * this function.
+     *
+     * Any range value more than the value returned is to be considered as
+     * "no target detected" or
+     * "no target in detectable range"\n
+     * @warning The maximal distance depends on the setup
+     *
+     * @note This function is not Implemented
+     *
+     * @param   dev      Device Handle
+     * @param   p_upper_limit_milli_meter   The maximal range limit for actual setup
+     * (in millimeter)
+     * @return  VL53L0X_ERROR_NOT_IMPLEMENTED        Not implemented
+     */
+    VL53L0X_Error VL53L0X_get_upper_limit_milli_meter(VL53L0X_DEV dev,
+            uint16_t *p_upper_limit_milli_meter);
+
+    /**
+    * @brief Get the tuning settings pointer and the internal external switch
+    * value.
+    *
+    * This function is used to get the Tuning settings buffer pointer and the
+    * value.
+    * of the switch to select either external or internal tuning settings.
+    *
+    * @note This function Access to the device
+    *
+    * @param   dev                        Device Handle
+    * @param   pp_tuning_setting_buffer      Pointer to tuning settings buffer.
+    * @param   p_use_internal_tuning_settings Pointer to store Use internal tuning
+    *                                     settings value.
+    * @return  VL53L0X_ERROR_NONE          Success
+    * @return  "Other error code"         See ::VL53L0X_Error
+    */
+    VL53L0X_Error VL53L0X_get_tuning_setting_buffer(VL53L0X_DEV dev,
+            uint8_t **pp_tuning_setting_buffer, uint8_t *p_use_internal_tuning_settings);
+
+    /**
+     * @brief Set the tuning settings pointer
+     *
+     * This function is used to specify the Tuning settings buffer to be used
+     * for a given device. The buffer contains all the necessary data to permit
+     * the API to write tuning settings.
+     * This function permit to force the usage of either external or internal
+     * tuning settings.
+     *
+     * @note This function Access to the device
+     *
+     * @param   dev                             Device Handle
+     * @param   p_tuning_setting_buffer            Pointer to tuning settings buffer.
+     * @param   use_internal_tuning_settings       Use internal tuning settings value.
+     * @return  VL53L0X_ERROR_NONE     Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_set_tuning_setting_buffer(VL53L0X_DEV dev,
+            uint8_t *p_tuning_setting_buffer, uint8_t use_internal_tuning_settings);
+
+    /**
+     * @defgroup VL53L0X_registerAccess_group PAL Register Access Functions
+     * @brief    PAL Register Access Functions
+     *  @{
+     */
+
+    /**
+     * Lock comms interface to serialize all commands to a shared I2C interface for a specific device
+     * @param   dev       Device Handle
+     * @return  VL53L0X_ERROR_NONE        Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_lock_sequence_access(VL53L0X_DEV dev);
+
+    /**
+     * Unlock comms interface to serialize all commands to a shared I2C interface for a specific device
+     * @param   dev       Device Handle
+     * @return  VL53L0X_ERROR_NONE        Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error VL53L0X_unlock_sequence_access(VL53L0X_DEV dev);
+
+    /**
+     * @brief  Prepare device for operation
+     * @par Function Description
+     * Update device with provided parameters
+     * @li Then start ranging operation.
+     *
+     * @note This function Access to the device
+     *
+     * @param   Dev                   Device Handle
+     * @param   pDeviceParameters     Pointer to store current device parameters.
+     * @return  VL53L0X_ERROR_NONE     Success
+     * @return  "Other error code"    See ::VL53L0X_Error
+     */
+    VL53L0X_Error vl53L0x_set_device_parameters(VL53L0X_DEV Dev,
+            const VL53L0X_DeviceParameters_t *pDeviceParameters);
+
+    /**
+     * Set Group parameter Hold state
+     *
+     * @par Function Description
+     * Set or remove device internal group parameter hold
+     *
+     * @note This function is not Implemented
+     *
+     * @param   dev      Device Handle
+     * @param   group_param_hold   Group parameter Hold state to be set (on/off)
+     * @return  VL53L0X_ERROR_NOT_IMPLEMENTED        Not implemented
+     */
+    VL53L0X_Error VL53L0X_set_group_param_hold(VL53L0X_DEV dev,
+            uint8_t group_param_hold);
+
+
+    /**
+     * @brief Wait for device ready for a new measurement command.
+     * Blocking function.
+     *
+     * @note This function is not Implemented
+     *
+     * @param   dev      Device Handle
+     * @param   max_loop    Max Number of polling loop (timeout).
+     * @return  VL53L0X_ERROR_NOT_IMPLEMENTED   Not implemented
+     */
+    VL53L0X_Error VL53L0X_wait_device_ready_for_new_measurement(VL53L0X_DEV dev,
+            uint32_t max_loop);
+
+    VL53L0X_Error VL53L0X_reverse_bytes(uint8_t *data, uint32_t size);
+
+    int range_meas_int_continuous_mode(void (*fptr)(void));
+
+
+    VL53L0X_DeviceInfo_t _device_info;
+
+    /* IO Device */
+    DevI2C *_dev_i2c;
+    /* Digital out pin */
+    DigitalOut *_gpio0;
+    /* GPIO expander */
+    Stmpe1600DigiOut *_expgpio0;
+    /* Measure detection IRQ */
+    InterruptIn *_gpio1Int;
+    /* Device data */
+    VL53L0X_Dev_t _my_device;
+    VL53L0X_DEV _device;
+};
+
+
+#endif /* _VL53L0X_CLASS_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/VL53L0X/VL53L0X_def.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,640 @@
+/*******************************************************************************
+Copyright © 2016, STMicroelectronics International N.V.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+	* Redistributions of source code must retain the above copyright
+	  notice, this list of conditions and the following disclaimer.
+	* Redistributions in binary form must reproduce the above copyright
+	  notice, this list of conditions and the following disclaimer in the
+	  documentation and/or other materials provided with the distribution.
+	* Neither the name of STMicroelectronics nor the
+	  names of its contributors may be used to endorse or promote products
+	  derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
+NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
+IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+
+/**
+ * @file VL53L0X_def.h
+ *
+ * @brief Type definitions for VL53L0X API.
+ *
+ */
+
+
+#ifndef _VL53L0X_DEF_H_
+#define _VL53L0X_DEF_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup VL53L0X_globaldefine_group VL53L0X Defines
+ *	@brief	  VL53L0X Defines
+ *	@{
+ */
+
+
+/** PAL SPECIFICATION major version */
+#define VL53L0X10_SPECIFICATION_VER_MAJOR   1
+/** PAL SPECIFICATION minor version */
+#define VL53L0X10_SPECIFICATION_VER_MINOR   2
+/** PAL SPECIFICATION sub version */
+#define VL53L0X10_SPECIFICATION_VER_SUB	   7
+/** PAL SPECIFICATION sub version */
+#define VL53L0X10_SPECIFICATION_VER_REVISION 1440
+
+/** VL53L0X PAL IMPLEMENTATION major version */
+#define VL53L0X10_IMPLEMENTATION_VER_MAJOR	1
+/** VL53L0X PAL IMPLEMENTATION minor version */
+#define VL53L0X10_IMPLEMENTATION_VER_MINOR	0
+/** VL53L0X PAL IMPLEMENTATION sub version */
+#define VL53L0X10_IMPLEMENTATION_VER_SUB		9
+/** VL53L0X PAL IMPLEMENTATION sub version */
+#define VL53L0X10_IMPLEMENTATION_VER_REVISION	3673
+
+/** PAL SPECIFICATION major version */
+#define VL53L0X_SPECIFICATION_VER_MAJOR	 1
+/** PAL SPECIFICATION minor version */
+#define VL53L0X_SPECIFICATION_VER_MINOR	 2
+/** PAL SPECIFICATION sub version */
+#define VL53L0X_SPECIFICATION_VER_SUB	 7
+/** PAL SPECIFICATION sub version */
+#define VL53L0X_SPECIFICATION_VER_REVISION 1440
+
+/** VL53L0X PAL IMPLEMENTATION major version */
+#define VL53L0X_IMPLEMENTATION_VER_MAJOR	  1
+/** VL53L0X PAL IMPLEMENTATION minor version */
+#define VL53L0X_IMPLEMENTATION_VER_MINOR	  1
+/** VL53L0X PAL IMPLEMENTATION sub version */
+#define VL53L0X_IMPLEMENTATION_VER_SUB	  21
+/** VL53L0X PAL IMPLEMENTATION sub version */
+#define VL53L0X_IMPLEMENTATION_VER_REVISION	  4823
+#define VL53L0X_DEFAULT_MAX_LOOP 2000
+#define VL53L0X_MAX_STRING_LENGTH 32
+
+
+#include "VL53L0X_device.h"
+#include "VL53L0X_types.h"
+
+
+/****************************************
+ * PRIVATE define do not edit
+ ****************************************/
+
+/** @brief Defines the parameters of the Get Version Functions
+ */
+typedef struct {
+    uint32_t	 revision; /*!< revision number */
+    uint8_t		 major;	   /*!< major number */
+    uint8_t		 minor;	   /*!< minor number */
+    uint8_t		 build;	   /*!< build number */
+} VL53L0X_Version_t;
+
+
+/** @brief Defines the parameters of the Get Device Info Functions
+ */
+typedef struct {
+    char Name[VL53L0X_MAX_STRING_LENGTH];
+    /*!< Name of the Device e.g. Left_Distance */
+    char Type[VL53L0X_MAX_STRING_LENGTH];
+    /*!< Type of the Device e.g VL53L0X */
+    char ProductId[VL53L0X_MAX_STRING_LENGTH];
+    /*!< Product Identifier String	*/
+    uint8_t ProductType;
+    /*!< Product Type, VL53L0X = 1, VL53L1 = 2 */
+    uint8_t ProductRevisionMajor;
+    /*!< Product revision major */
+    uint8_t ProductRevisionMinor;
+    /*!< Product revision minor */
+} VL53L0X_DeviceInfo_t;
+
+
+/** @defgroup VL53L0X_define_Error_group Error and Warning code returned by API
+ *	The following DEFINE are used to identify the PAL ERROR
+ *	@{
+ */
+
+typedef int8_t VL53L0X_Error;
+
+#define VL53L0X_ERROR_NONE		((VL53L0X_Error)	0)
+#define VL53L0X_ERROR_CALIBRATION_WARNING	((VL53L0X_Error) -1)
+/*!< Warning invalid calibration data may be in used
+	\a	VL53L0X_InitData()
+	\a VL53L0X_GetOffsetCalibrationData
+	\a VL53L0X_SetOffsetCalibrationData */
+#define VL53L0X_ERROR_MIN_CLIPPED			((VL53L0X_Error) -2)
+/*!< Warning parameter passed was clipped to min before to be applied */
+
+#define VL53L0X_ERROR_UNDEFINED				((VL53L0X_Error) -3)
+/*!< Unqualified error */
+#define VL53L0X_ERROR_INVALID_PARAMS			((VL53L0X_Error) -4)
+/*!< Parameter passed is invalid or out of range */
+#define VL53L0X_ERROR_NOT_SUPPORTED			((VL53L0X_Error) -5)
+/*!< Function is not supported in current mode or configuration */
+#define VL53L0X_ERROR_RANGE_ERROR			((VL53L0X_Error) -6)
+/*!< Device report a ranging error interrupt status */
+#define VL53L0X_ERROR_TIME_OUT				((VL53L0X_Error) -7)
+/*!< Aborted due to time out */
+#define VL53L0X_ERROR_MODE_NOT_SUPPORTED			((VL53L0X_Error) -8)
+/*!< Asked mode is not supported by the device */
+#define VL53L0X_ERROR_BUFFER_TOO_SMALL			((VL53L0X_Error) -9)
+/*!< ... */
+#define VL53L0X_ERROR_GPIO_NOT_EXISTING			((VL53L0X_Error) -10)
+/*!< User tried to setup a non-existing GPIO pin */
+#define VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED  ((VL53L0X_Error) -11)
+/*!< unsupported GPIO functionality */
+#define VL53L0X_ERROR_INTERRUPT_NOT_CLEARED		((VL53L0X_Error) -12)
+/*!< Error during interrupt clear */
+#define VL53L0X_ERROR_CONTROL_INTERFACE			((VL53L0X_Error) -20)
+/*!< error reported from IO functions */
+#define VL53L0X_ERROR_INVALID_COMMAND			((VL53L0X_Error) -30)
+/*!< The command is not allowed in the current device state
+ *	(power down) */
+#define VL53L0X_ERROR_DIVISION_BY_ZERO			((VL53L0X_Error) -40)
+/*!< In the function a division by zero occurs */
+#define VL53L0X_ERROR_REF_SPAD_INIT			((VL53L0X_Error) -50)
+/*!< Error during reference SPAD initialization */
+#define VL53L0X_ERROR_NOT_IMPLEMENTED			((VL53L0X_Error) -99)
+/*!< Tells requested functionality has not been implemented yet or
+ * not compatible with the device */
+/** @} VL53L0X_define_Error_group */
+
+
+/** @defgroup VL53L0X_define_DeviceModes_group Defines Device modes
+ *	Defines all possible modes for the device
+ *	@{
+ */
+typedef uint8_t VL53L0X_DeviceModes;
+
+#define VL53L0X_DEVICEMODE_SINGLE_RANGING	((VL53L0X_DeviceModes)  0)
+#define VL53L0X_DEVICEMODE_CONTINUOUS_RANGING	((VL53L0X_DeviceModes)  1)
+#define VL53L0X_DEVICEMODE_SINGLE_HISTOGRAM	((VL53L0X_DeviceModes)  2)
+#define VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING ((VL53L0X_DeviceModes) 3)
+#define VL53L0X_DEVICEMODE_SINGLE_ALS		((VL53L0X_DeviceModes) 10)
+#define VL53L0X_DEVICEMODE_GPIO_DRIVE		((VL53L0X_DeviceModes) 20)
+#define VL53L0X_DEVICEMODE_GPIO_OSC		((VL53L0X_DeviceModes) 21)
+/* ... Modes to be added depending on device */
+/** @} VL53L0X_define_DeviceModes_group */
+
+
+
+/** @defgroup VL53L0X_define_HistogramModes_group Defines Histogram modes
+ *	Defines all possible Histogram modes for the device
+ *	@{
+ */
+typedef uint8_t VL53L0X_HistogramModes;
+
+#define VL53L0X_HISTOGRAMMODE_DISABLED		((VL53L0X_HistogramModes) 0)
+/*!< Histogram Disabled */
+#define VL53L0X_HISTOGRAMMODE_REFERENCE_ONLY	((VL53L0X_HistogramModes) 1)
+/*!< Histogram Reference array only */
+#define VL53L0X_HISTOGRAMMODE_RETURN_ONLY	((VL53L0X_HistogramModes) 2)
+/*!< Histogram Return array only */
+#define VL53L0X_HISTOGRAMMODE_BOTH		((VL53L0X_HistogramModes) 3)
+/*!< Histogram both Reference and Return Arrays */
+/* ... Modes to be added depending on device */
+/** @} VL53L0X_define_HistogramModes_group */
+
+
+/** @defgroup VL53L0X_define_PowerModes_group List of available Power Modes
+ *	List of available Power Modes
+ *	@{
+ */
+
+typedef uint8_t VL53L0X_PowerModes;
+
+#define VL53L0X_POWERMODE_STANDBY_LEVEL1 ((VL53L0X_PowerModes) 0)
+/*!< Standby level 1 */
+#define VL53L0X_POWERMODE_STANDBY_LEVEL2 ((VL53L0X_PowerModes) 1)
+/*!< Standby level 2 */
+#define VL53L0X_POWERMODE_IDLE_LEVEL1	((VL53L0X_PowerModes) 2)
+/*!< Idle level 1 */
+#define VL53L0X_POWERMODE_IDLE_LEVEL2	((VL53L0X_PowerModes) 3)
+/*!< Idle level 2 */
+
+/** @} VL53L0X_define_PowerModes_group */
+
+
+/** @brief Defines all parameters for the device
+ */
+typedef struct {
+    VL53L0X_DeviceModes DeviceMode;
+    /*!< Defines type of measurement to be done for the next measure */
+    VL53L0X_HistogramModes HistogramMode;
+    /*!< Defines type of histogram measurement to be done for the next
+     *	measure */
+    uint32_t MeasurementTimingBudgetMicroSeconds;
+    /*!< Defines the allowed total time for a single measurement */
+    uint32_t InterMeasurementPeriodMilliSeconds;
+    /*!< Defines time between two consecutive measurements (between two
+     *	measurement starts). If set to 0 means back-to-back mode */
+    uint8_t XTalkCompensationEnable;
+    /*!< Tells if Crosstalk compensation shall be enable or not	 */
+    uint16_t XTalkCompensationRangeMilliMeter;
+    /*!< CrossTalk compensation range in millimeter	 */
+    FixPoint1616_t XTalkCompensationRateMegaCps;
+    /*!< CrossTalk compensation rate in Mega counts per seconds.
+     *	Expressed in 16.16 fixed point format.	*/
+    int32_t RangeOffsetMicroMeters;
+    /*!< Range offset adjustment (mm).	*/
+
+    uint8_t LimitChecksEnable[VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS];
+    /*!< This Array store all the Limit Check enable for this device. */
+    uint8_t LimitChecksStatus[VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS];
+    /*!< This Array store all the Status of the check linked to last
+    * measurement. */
+    FixPoint1616_t LimitChecksValue[VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS];
+    /*!< This Array store all the Limit Check value for this device */
+
+    uint8_t WrapAroundCheckEnable;
+    /*!< Tells if Wrap Around Check shall be enable or not */
+} VL53L0X_DeviceParameters_t;
+
+
+/** @defgroup VL53L0X_define_State_group Defines the current status of the device
+ *	Defines the current status of the device
+ *	@{
+ */
+
+typedef uint8_t VL53L0X_State;
+
+#define VL53L0X_STATE_POWERDOWN		 ((VL53L0X_State)  0)
+/*!< Device is in HW reset	*/
+#define VL53L0X_STATE_WAIT_STATICINIT ((VL53L0X_State)  1)
+/*!< Device is initialized and wait for static initialization  */
+#define VL53L0X_STATE_STANDBY		 ((VL53L0X_State)  2)
+/*!< Device is in Low power Standby mode   */
+#define VL53L0X_STATE_IDLE			 ((VL53L0X_State)  3)
+/*!< Device has been initialized and ready to do measurements  */
+#define VL53L0X_STATE_RUNNING		 ((VL53L0X_State)  4)
+/*!< Device is performing measurement */
+#define VL53L0X_STATE_UNKNOWN		 ((VL53L0X_State)  98)
+/*!< Device is in unknown state and need to be rebooted	 */
+#define VL53L0X_STATE_ERROR			 ((VL53L0X_State)  99)
+/*!< Device is in error state and need to be rebooted  */
+
+/** @} VL53L0X_define_State_group */
+
+
+/** @brief Structure containing the Dmax computation parameters and data
+ */
+typedef struct {
+    int32_t AmbTuningWindowFactor_K;
+    /*!<  internal algo tuning (*1000) */
+    int32_t RetSignalAt0mm;
+    /*!< intermediate dmax computation value caching */
+} VL53L0X_DMaxData_t;
+
+/**
+ * @struct VL53L0X_RangeData_t
+ * @brief Range measurement data.
+ */
+typedef struct {
+    uint32_t TimeStamp;		/*!< 32-bit time stamp. */
+    uint32_t MeasurementTimeUsec;
+    /*!< Give the Measurement time needed by the device to do the
+     * measurement.*/
+
+
+    uint16_t RangeMilliMeter;	/*!< range distance in millimeter. */
+
+    uint16_t RangeDMaxMilliMeter;
+    /*!< Tells what is the maximum detection distance of the device
+     * in current setup and environment conditions (Filled when
+     *	applicable) */
+
+    FixPoint1616_t SignalRateRtnMegaCps;
+    /*!< Return signal rate (MCPS)\n these is a 16.16 fix point
+     *	value, which is effectively a measure of target
+     *	 reflectance.*/
+    FixPoint1616_t AmbientRateRtnMegaCps;
+    /*!< Return ambient rate (MCPS)\n these is a 16.16 fix point
+     *	value, which is effectively a measure of the ambien
+     *	t light.*/
+
+    uint16_t EffectiveSpadRtnCount;
+    /*!< Return the effective SPAD count for the return signal.
+     *	To obtain Real value it should be divided by 256 */
+
+    uint8_t ZoneId;
+    /*!< Denotes which zone and range scheduler stage the range
+     *	data relates to. */
+    uint8_t RangeFractionalPart;
+    /*!< Fractional part of range distance. Final value is a
+     *	FixPoint168 value. */
+    uint8_t RangeStatus;
+    /*!< Range Status for the current measurement. This is device
+     *	dependent. Value = 0 means value is valid.
+     *	See \ref RangeStatusPage */
+} VL53L0X_RangingMeasurementData_t;
+
+
+#define VL53L0X_HISTOGRAM_BUFFER_SIZE 24
+
+/**
+ * @struct VL53L0X_HistogramData_t
+ * @brief Histogram measurement data.
+ */
+typedef struct {
+    /* Histogram Measurement data */
+    uint32_t HistogramData[VL53L0X_HISTOGRAM_BUFFER_SIZE];
+    /*!< Histogram data */
+    uint8_t HistogramType; /*!< Indicate the types of histogram data :
+	Return only, Reference only, both Return and Reference */
+    uint8_t FirstBin; /*!< First Bin value */
+    uint8_t BufferSize; /*!< Buffer Size - Set by the user.*/
+    uint8_t NumberOfBins;
+    /*!< Number of bins filled by the histogram measurement */
+
+    VL53L0X_DeviceError ErrorStatus;
+    /*!< Error status of the current measurement. \n
+    see @a ::VL53L0X_DeviceError @a VL53L0X_GetStatusErrorString() */
+} VL53L0X_HistogramMeasurementData_t;
+
+#define VL53L0X_REF_SPAD_BUFFER_SIZE 6
+
+/**
+ * @struct VL53L0X_SpadData_t
+ * @brief Spad Configuration Data.
+ */
+typedef struct {
+    uint8_t RefSpadEnables[VL53L0X_REF_SPAD_BUFFER_SIZE];
+    /*!< Reference Spad Enables */
+    uint8_t RefGoodSpadMap[VL53L0X_REF_SPAD_BUFFER_SIZE];
+    /*!< Reference Spad Good Spad Map */
+} VL53L0X_SpadData_t;
+
+typedef struct {
+    FixPoint1616_t OscFrequencyMHz; /* Frequency used */
+
+    uint16_t LastEncodedTimeout;
+    /* last encoded Time out used for timing budget*/
+
+    VL53L0X_GpioFunctionality Pin0GpioFunctionality;
+    /* store the functionality of the GPIO: pin0 */
+
+    uint32_t FinalRangeTimeoutMicroSecs;
+    /*!< Execution time of the final range*/
+    uint8_t FinalRangeVcselPulsePeriod;
+    /*!< Vcsel pulse period (pll clocks) for the final range measurement*/
+    uint32_t PreRangeTimeoutMicroSecs;
+    /*!< Execution time of the final range*/
+    uint8_t PreRangeVcselPulsePeriod;
+    /*!< Vcsel pulse period (pll clocks) for the pre-range measurement*/
+
+    uint16_t SigmaEstRefArray;
+    /*!< Reference array sigma value in 1/100th of [mm] e.g. 100 = 1mm */
+    uint16_t SigmaEstEffPulseWidth;
+    /*!< Effective Pulse width for sigma estimate in 1/100th
+     * of ns e.g. 900 = 9.0ns */
+    uint16_t SigmaEstEffAmbWidth;
+    /*!< Effective Ambient width for sigma estimate in 1/100th of ns
+     * e.g. 500 = 5.0ns */
+
+
+    uint8_t ReadDataFromDeviceDone; /* Indicate if read from device has
+	been done (==1) or not (==0) */
+    uint8_t ModuleId; /* Module ID */
+    uint8_t Revision; /* test Revision */
+    char ProductId[VL53L0X_MAX_STRING_LENGTH];
+    /* Product Identifier String  */
+    uint8_t ReferenceSpadCount; /* used for ref spad management */
+    uint8_t ReferenceSpadType;	/* used for ref spad management */
+    uint8_t RefSpadsInitialised; /* reports if ref spads are initialised. */
+    uint32_t PartUIDUpper; /*!< Unique Part ID Upper */
+    uint32_t PartUIDLower; /*!< Unique Part ID Lower */
+    FixPoint1616_t SignalRateMeasFixed400mm; /*!< Peek Signal rate
+	at 400 mm*/
+
+} VL53L0X_DeviceSpecificParameters_t;
+
+/**
+ * @struct VL53L0X_DevData_t
+ *
+ * @brief VL53L0X PAL device ST private data structure \n
+ * End user should never access any of these field directly
+ *
+ * These must never access directly but only via macro
+ */
+typedef struct {
+    VL53L0X_DMaxData_t DMaxData;
+    /*!< Dmax Data */
+    int32_t	 Part2PartOffsetNVMMicroMeter;
+    /*!< backed up NVM value */
+    int32_t	 Part2PartOffsetAdjustmentNVMMicroMeter;
+    /*!< backed up NVM value representing additional offset adjustment */
+    VL53L0X_DeviceParameters_t CurrentParameters;
+    /*!< Current Device Parameter */
+    VL53L0X_RangingMeasurementData_t LastRangeMeasure;
+    /*!< Ranging Data */
+    VL53L0X_HistogramMeasurementData_t LastHistogramMeasure;
+    /*!< Histogram Data */
+    VL53L0X_DeviceSpecificParameters_t DeviceSpecificParameters;
+    /*!< Parameters specific to the device */
+    VL53L0X_SpadData_t SpadData;
+    /*!< Spad Data */
+    uint8_t SequenceConfig;
+    /*!< Internal value for the sequence config */
+    uint8_t RangeFractionalEnable;
+    /*!< Enable/Disable fractional part of ranging data */
+    VL53L0X_State PalState;
+    /*!< Current state of the PAL for this device */
+    VL53L0X_PowerModes PowerMode;
+    /*!< Current Power Mode	 */
+    uint16_t SigmaEstRefArray;
+    /*!< Reference array sigma value in 1/100th of [mm] e.g. 100 = 1mm */
+    uint16_t SigmaEstEffPulseWidth;
+    /*!< Effective Pulse width for sigma estimate in 1/100th
+    * of ns e.g. 900 = 9.0ns */
+    uint16_t SigmaEstEffAmbWidth;
+    /*!< Effective Ambient width for sigma estimate in 1/100th of ns
+    * e.g. 500 = 5.0ns */
+    uint8_t StopVariable;
+    /*!< StopVariable used during the stop sequence */
+    uint16_t targetRefRate;
+    /*!< Target Ambient Rate for Ref spad management */
+    FixPoint1616_t SigmaEstimate;
+    /*!< Sigma Estimate - based on ambient & VCSEL rates and
+    * signal_total_events */
+    FixPoint1616_t SignalEstimate;
+    /*!< Signal Estimate - based on ambient & VCSEL rates and cross talk */
+    FixPoint1616_t LastSignalRefMcps;
+    /*!< Latest Signal ref in Mcps */
+    uint8_t *pTuningSettingsPointer;
+    /*!< Pointer for Tuning Settings table */
+    uint8_t UseInternalTuningSettings;
+    /*!< Indicate if we use	 Tuning Settings table */
+    uint16_t LinearityCorrectiveGain;
+    /*!< Linearity Corrective Gain value in x1000 */
+    uint16_t DmaxCalRangeMilliMeter;
+    /*!< Dmax Calibration Range millimeter */
+    FixPoint1616_t DmaxCalSignalRateRtnMegaCps;
+    /*!< Dmax Calibration Signal Rate Return MegaCps */
+
+} VL53L0X_DevData_t;
+
+
+/** @defgroup VL53L0X_define_InterruptPolarity_group Defines the Polarity
+ * of the Interrupt
+ *	Defines the Polarity of the Interrupt
+ *	@{
+ */
+typedef uint8_t VL53L0X_InterruptPolarity;
+
+#define VL53L0X_INTERRUPTPOLARITY_LOW	   ((VL53L0X_InterruptPolarity)	0)
+/*!< Set active low polarity best setup for falling edge. */
+#define VL53L0X_INTERRUPTPOLARITY_HIGH	   ((VL53L0X_InterruptPolarity)	1)
+/*!< Set active high polarity best setup for rising edge. */
+
+/** @} VL53L0X_define_InterruptPolarity_group */
+
+
+/** @defgroup VL53L0X_define_VcselPeriod_group Vcsel Period Defines
+ *	Defines the range measurement for which to access the vcsel period.
+ *	@{
+ */
+typedef uint8_t VL53L0X_VcselPeriod;
+
+#define VL53L0X_VCSEL_PERIOD_PRE_RANGE	((VL53L0X_VcselPeriod) 0)
+/*!<Identifies the pre-range vcsel period. */
+#define VL53L0X_VCSEL_PERIOD_FINAL_RANGE ((VL53L0X_VcselPeriod) 1)
+/*!<Identifies the final range vcsel period. */
+
+/** @} VL53L0X_define_VcselPeriod_group */
+
+/** @defgroup VL53L0X_define_SchedulerSequence_group Defines the steps
+ * carried out by the scheduler during a range measurement.
+ *	@{
+ *	Defines the states of all the steps in the scheduler
+ *	i.e. enabled/disabled.
+ */
+typedef struct {
+    uint8_t		 TccOn;	   /*!<Reports if Target Centre Check On  */
+    uint8_t		 MsrcOn;	   /*!<Reports if MSRC On  */
+    uint8_t		 DssOn;		   /*!<Reports if DSS On  */
+    uint8_t		 PreRangeOn;   /*!<Reports if Pre-Range On	*/
+    uint8_t		 FinalRangeOn; /*!<Reports if Final-Range On  */
+} VL53L0X_SchedulerSequenceSteps_t;
+
+/** @} VL53L0X_define_SchedulerSequence_group */
+
+/** @defgroup VL53L0X_define_SequenceStepId_group Defines the Polarity
+ *	of the Interrupt
+ *	Defines the the sequence steps performed during ranging..
+ *	@{
+ */
+typedef uint8_t VL53L0X_SequenceStepId;
+
+#define	 VL53L0X_SEQUENCESTEP_TCC		 ((VL53L0X_VcselPeriod) 0)
+/*!<Target CentreCheck identifier. */
+#define	 VL53L0X_SEQUENCESTEP_DSS		 ((VL53L0X_VcselPeriod) 1)
+/*!<Dynamic Spad Selection function Identifier. */
+#define	 VL53L0X_SEQUENCESTEP_MSRC		 ((VL53L0X_VcselPeriod) 2)
+/*!<Minimum Signal Rate Check function Identifier. */
+#define	 VL53L0X_SEQUENCESTEP_PRE_RANGE	 ((VL53L0X_VcselPeriod) 3)
+/*!<Pre-Range check Identifier. */
+#define	 VL53L0X_SEQUENCESTEP_FINAL_RANGE ((VL53L0X_VcselPeriod) 4)
+/*!<Final Range Check Identifier. */
+
+#define	 VL53L0X_SEQUENCESTEP_NUMBER_OF_CHECKS			 5
+/*!<Number of Sequence Step Managed by the API. */
+
+/** @} VL53L0X_define_SequenceStepId_group */
+
+
+/* MACRO Definitions */
+/** @defgroup VL53L0X_define_GeneralMacro_group General Macro Defines
+ *	General Macro Defines
+ *	@{
+ */
+
+/* Defines */
+#define VL53L0X_SETPARAMETERFIELD(Dev, field, value) \
+	PALDevDataSet(Dev, CurrentParameters.field, value)
+
+#define VL53L0X_GETPARAMETERFIELD(Dev, field, variable) \
+	variable = PALDevDataGet(Dev, CurrentParameters).field
+
+
+#define VL53L0X_SETARRAYPARAMETERFIELD(Dev, field, index, value) \
+	PALDevDataSet(Dev, CurrentParameters.field[index], value)
+
+#define VL53L0X_GETARRAYPARAMETERFIELD(Dev, field, index, variable) \
+	variable = PALDevDataGet(Dev, CurrentParameters).field[index]
+
+
+#define VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, field, value) \
+		PALDevDataSet(Dev, DeviceSpecificParameters.field, value)
+
+#define VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, field) \
+		PALDevDataGet(Dev, DeviceSpecificParameters).field
+
+
+#define VL53L0X_FIXPOINT1616TOFIXPOINT97(Value) \
+	(uint16_t)((Value>>9)&0xFFFF)
+#define VL53L0X_FIXPOINT97TOFIXPOINT1616(Value) \
+	(FixPoint1616_t)(Value<<9)
+
+#define VL53L0X_FIXPOINT1616TOFIXPOINT88(Value) \
+	(uint16_t)((Value>>8)&0xFFFF)
+#define VL53L0X_FIXPOINT88TOFIXPOINT1616(Value) \
+	(FixPoint1616_t)(Value<<8)
+
+#define VL53L0X_FIXPOINT1616TOFIXPOINT412(Value) \
+	(uint16_t)((Value>>4)&0xFFFF)
+#define VL53L0X_FIXPOINT412TOFIXPOINT1616(Value) \
+	(FixPoint1616_t)(Value<<4)
+
+#define VL53L0X_FIXPOINT1616TOFIXPOINT313(Value) \
+	(uint16_t)((Value>>3)&0xFFFF)
+#define VL53L0X_FIXPOINT313TOFIXPOINT1616(Value) \
+	(FixPoint1616_t)(Value<<3)
+
+#define VL53L0X_FIXPOINT1616TOFIXPOINT08(Value) \
+	(uint8_t)((Value>>8)&0x00FF)
+#define VL53L0X_FIXPOINT08TOFIXPOINT1616(Value) \
+	(FixPoint1616_t)(Value<<8)
+
+#define VL53L0X_FIXPOINT1616TOFIXPOINT53(Value) \
+	(uint8_t)((Value>>13)&0x00FF)
+#define VL53L0X_FIXPOINT53TOFIXPOINT1616(Value) \
+	(FixPoint1616_t)(Value<<13)
+
+#define VL53L0X_FIXPOINT1616TOFIXPOINT102(Value) \
+	(uint16_t)((Value>>14)&0x0FFF)
+#define VL53L0X_FIXPOINT102TOFIXPOINT1616(Value) \
+	(FixPoint1616_t)(Value<<12)
+
+#define VL53L0X_MAKEUINT16(lsb, msb) (uint16_t)((((uint16_t)msb)<<8) + \
+		(uint16_t)lsb)
+
+/** @} VL53L0X_define_GeneralMacro_group */
+
+/** @} VL53L0X_globaldefine_group */
+
+
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _VL53L0X_DEF_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/VL53L0X/VL53L0X_device.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,257 @@
+/*******************************************************************************
+Copyright © 2016, STMicroelectronics International N.V.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of STMicroelectronics nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
+NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
+IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+
+/**
+ * Device specific defines. To be adapted by implementer for the targeted
+ * device.
+ */
+
+#ifndef _VL53L0X_DEVICE_H_
+#define _VL53L0X_DEVICE_H_
+
+#include "VL53L0X_types.h"
+
+
+/** @defgroup VL53L0X_DevSpecDefines_group VL53L0X cut1.1 Device Specific Defines
+ *  @brief VL53L0X cut1.1 Device Specific Defines
+ *  @{
+ */
+
+
+/** @defgroup VL53L0X_DeviceError_group Device Error
+ *  @brief Device Error code
+ *
+ *  This enum is Device specific it should be updated in the implementation
+ *  Use @a VL53L0X_GetStatusErrorString() to get the string.
+ *  It is related to Status Register of the Device.
+ *  @{
+ */
+typedef uint8_t VL53L0X_DeviceError;
+
+#define VL53L0X_DEVICEERROR_NONE                        ((VL53L0X_DeviceError) 0)
+/*!< 0  NoError  */
+#define VL53L0X_DEVICEERROR_VCSELCONTINUITYTESTFAILURE  ((VL53L0X_DeviceError) 1)
+#define VL53L0X_DEVICEERROR_VCSELWATCHDOGTESTFAILURE    ((VL53L0X_DeviceError) 2)
+#define VL53L0X_DEVICEERROR_NOVHVVALUEFOUND             ((VL53L0X_DeviceError) 3)
+#define VL53L0X_DEVICEERROR_MSRCNOTARGET                ((VL53L0X_DeviceError) 4)
+#define VL53L0X_DEVICEERROR_SNRCHECK                    ((VL53L0X_DeviceError) 5)
+#define VL53L0X_DEVICEERROR_RANGEPHASECHECK             ((VL53L0X_DeviceError) 6)
+#define VL53L0X_DEVICEERROR_SIGMATHRESHOLDCHECK         ((VL53L0X_DeviceError) 7)
+#define VL53L0X_DEVICEERROR_TCC                         ((VL53L0X_DeviceError) 8)
+#define VL53L0X_DEVICEERROR_PHASECONSISTENCY            ((VL53L0X_DeviceError) 9)
+#define VL53L0X_DEVICEERROR_MINCLIP                     ((VL53L0X_DeviceError) 10)
+#define VL53L0X_DEVICEERROR_RANGECOMPLETE               ((VL53L0X_DeviceError) 11)
+#define VL53L0X_DEVICEERROR_ALGOUNDERFLOW               ((VL53L0X_DeviceError) 12)
+#define VL53L0X_DEVICEERROR_ALGOOVERFLOW                ((VL53L0X_DeviceError) 13)
+#define VL53L0X_DEVICEERROR_RANGEIGNORETHRESHOLD        ((VL53L0X_DeviceError) 14)
+
+/** @} end of VL53L0X_DeviceError_group */
+
+
+/** @defgroup VL53L0X_CheckEnable_group Check Enable list
+ *  @brief Check Enable code
+ *
+ *  Define used to specify the LimitCheckId.
+ *  Use @a VL53L0X_GetLimitCheckInfo() to get the string.
+ *  @{
+ */
+
+#define VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE           0
+#define VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE     1
+#define VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP             2
+#define VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD      3
+#define VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC            4
+#define VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE       5
+
+#define VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS            6
+
+/** @}  end of VL53L0X_CheckEnable_group */
+
+
+/** @defgroup VL53L0X_GpioFunctionality_group Gpio Functionality
+ *  @brief Defines the different functionalities for the device GPIO(s)
+ *  @{
+ */
+typedef uint8_t VL53L0X_GpioFunctionality;
+
+#define VL53L0X_GPIOFUNCTIONALITY_OFF                     \
+	((VL53L0X_GpioFunctionality)  0) /*!< NO Interrupt  */
+#define VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW   \
+	((VL53L0X_GpioFunctionality)  1) /*!< Level Low (value < thresh_low)  */
+#define VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH   \
+	((VL53L0X_GpioFunctionality)  2) /*!< Level High (value > thresh_high) */
+#define VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT    \
+	((VL53L0X_GpioFunctionality)  3)
+/*!< Out Of Window (value < thresh_low OR value > thresh_high)  */
+#define VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY        \
+	((VL53L0X_GpioFunctionality)  4) /*!< New Sample Ready  */
+
+/** @} end of VL53L0X_GpioFunctionality_group */
+
+
+/* Device register map */
+
+/** @defgroup VL53L0X_DefineRegisters_group Define Registers
+ *  @brief List of all the defined registers
+ *  @{
+ */
+#define VL53L0X_REG_SYSRANGE_START                        0x000
+/** mask existing bit in #VL53L0X_REG_SYSRANGE_START*/
+#define VL53L0X_REG_SYSRANGE_MODE_MASK          0x0F
+/** bit 0 in #VL53L0X_REG_SYSRANGE_START write 1 toggle state in
+ * continuous mode and arm next shot in single shot mode */
+#define VL53L0X_REG_SYSRANGE_MODE_START_STOP    0x01
+/** bit 1 write 0 in #VL53L0X_REG_SYSRANGE_START set single shot mode */
+#define VL53L0X_REG_SYSRANGE_MODE_SINGLESHOT    0x00
+/** bit 1 write 1 in #VL53L0X_REG_SYSRANGE_START set back-to-back
+ *  operation mode */
+#define VL53L0X_REG_SYSRANGE_MODE_BACKTOBACK    0x02
+/** bit 2 write 1 in #VL53L0X_REG_SYSRANGE_START set timed operation
+ *  mode */
+#define VL53L0X_REG_SYSRANGE_MODE_TIMED         0x04
+/** bit 3 write 1 in #VL53L0X_REG_SYSRANGE_START set histogram operation
+ *  mode */
+#define VL53L0X_REG_SYSRANGE_MODE_HISTOGRAM     0x08
+
+
+#define VL53L0X_REG_SYSTEM_THRESH_HIGH               0x000C
+#define VL53L0X_REG_SYSTEM_THRESH_LOW                0x000E
+
+
+#define VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG			0x0001
+#define VL53L0X_REG_SYSTEM_RANGE_CONFIG				0x0009
+#define VL53L0X_REG_SYSTEM_INTERMEASUREMENT_PERIOD	0x0004
+
+
+#define VL53L0X_REG_SYSTEM_INTERRUPT_CONFIG_GPIO            0x000A
+#define VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_DISABLED			0x00
+#define VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_LEVEL_LOW			0x01
+#define VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_LEVEL_HIGH		0x02
+#define VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_OUT_OF_WINDOW		0x03
+#define VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY	0x04
+
+#define VL53L0X_REG_GPIO_HV_MUX_ACTIVE_HIGH          0x0084
+
+
+#define VL53L0X_REG_SYSTEM_INTERRUPT_CLEAR           0x000B
+
+/* Result registers */
+#define VL53L0X_REG_RESULT_INTERRUPT_STATUS          0x0013
+#define VL53L0X_REG_RESULT_RANGE_STATUS              0x0014
+
+#define VL53L0X_REG_RESULT_CORE_PAGE  1
+#define VL53L0X_REG_RESULT_CORE_AMBIENT_WINDOW_EVENTS_RTN   0x00BC
+#define VL53L0X_REG_RESULT_CORE_RANGING_TOTAL_EVENTS_RTN    0x00C0
+#define VL53L0X_REG_RESULT_CORE_AMBIENT_WINDOW_EVENTS_REF   0x00D0
+#define VL53L0X_REG_RESULT_CORE_RANGING_TOTAL_EVENTS_REF    0x00D4
+#define VL53L0X_REG_RESULT_PEAK_SIGNAL_RATE_REF             0x00B6
+
+/* Algo register */
+
+#define VL53L0X_REG_ALGO_PART_TO_PART_RANGE_OFFSET_MM       0x0028
+
+#define VL53L0X_REG_I2C_SLAVE_DEVICE_ADDRESS                0x008a
+
+/* Check Limit registers */
+#define VL53L0X_REG_MSRC_CONFIG_CONTROL                     0x0060
+
+#define VL53L0X_REG_PRE_RANGE_CONFIG_MIN_SNR                      0X0027
+#define VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW              0x0056
+#define VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH             0x0057
+#define VL53L0X_REG_PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT            0x0064
+
+#define VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_SNR                    0X0067
+#define VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW            0x0047
+#define VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH           0x0048
+#define VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT   0x0044
+
+
+#define VL53L0X_REG_PRE_RANGE_CONFIG_SIGMA_THRESH_HI              0X0061
+#define VL53L0X_REG_PRE_RANGE_CONFIG_SIGMA_THRESH_LO              0X0062
+
+/* PRE RANGE registers */
+#define VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD                 0x0050
+#define VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI            0x0051
+#define VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_LO            0x0052
+
+#define VL53L0X_REG_SYSTEM_HISTOGRAM_BIN                          0x0081
+#define VL53L0X_REG_HISTOGRAM_CONFIG_INITIAL_PHASE_SELECT         0x0033
+#define VL53L0X_REG_HISTOGRAM_CONFIG_READOUT_CTRL                 0x0055
+
+#define VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD               0x0070
+#define VL53L0X_REG_FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI          0x0071
+#define VL53L0X_REG_FINAL_RANGE_CONFIG_TIMEOUT_MACROP_LO          0x0072
+#define VL53L0X_REG_CROSSTALK_COMPENSATION_PEAK_RATE_MCPS         0x0020
+
+#define VL53L0X_REG_MSRC_CONFIG_TIMEOUT_MACROP                    0x0046
+
+
+#define VL53L0X_REG_SOFT_RESET_GO2_SOFT_RESET_N	                  0x00bf
+#define VL53L0X_REG_IDENTIFICATION_MODEL_ID                       0x00c0
+#define VL53L0X_REG_IDENTIFICATION_REVISION_ID                    0x00c2
+
+#define VL53L0X_REG_OSC_CALIBRATE_VAL                             0x00f8
+
+
+#define VL53L0X_SIGMA_ESTIMATE_MAX_VALUE                          65535
+/* equivalent to a range sigma of 655.35mm */
+
+#define VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH          0x032
+#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0   0x0B0
+#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_1   0x0B1
+#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_2   0x0B2
+#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_3   0x0B3
+#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_4   0x0B4
+#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_5   0x0B5
+
+#define VL53L0X_REG_GLOBAL_CONFIG_REF_EN_START_SELECT   0xB6
+#define VL53L0X_REG_DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD 0x4E /* 0x14E */
+#define VL53L0X_REG_DYNAMIC_SPAD_REF_EN_START_OFFSET    0x4F /* 0x14F */
+#define VL53L0X_REG_POWER_MANAGEMENT_GO1_POWER_FORCE    0x80
+
+/*
+ * Speed of light in um per 1E-10 Seconds
+ */
+
+#define VL53L0X_SPEED_OF_LIGHT_IN_AIR 2997
+
+#define VL53L0X_REG_VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV     	  0x0089
+
+#define VL53L0X_REG_ALGO_PHASECAL_LIM                         0x0030 /* 0x130 */
+#define VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT              0x0030
+
+/** @} VL53L0X_DefineRegisters_group */
+
+/** @} VL53L0X_DevSpecDefines_group */
+
+
+#endif
+
+/* _VL53L0X_DEVICE_H_ */
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/VL53L0X/VL53L0X_i2c_platform.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,417 @@
+/*
+ * COPYRIGHT (C) STMicroelectronics 2014. All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * STMicroelectronics ("Confidential Information").  You shall not
+ * disclose such Confidential Information and shall use it only in
+ * accordance with the terms of the license agreement you entered into
+ * with STMicroelectronics
+ *
+ * Programming Golden Rule: Keep it Simple!
+ *
+ */
+
+/**
+ * @file   VL53L0X_platform.h
+ * @brief  Function prototype definitions for Ewok Platform layer.
+ *
+ */
+
+
+#ifndef _VL53L0X_I2C_PLATFORM_H_
+#define _VL53L0X_I2C_PLATFORM_H_
+
+#include "VL53L0X_def.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Include uint8_t, unit16_t  etc definitions
+
+#include <stdint.h>
+#include <stdarg.h>
+
+
+/**
+ *  @brief Typedef defining .\n
+ * The developer shoud modify this to suit the platform being deployed.
+ *
+ */
+
+// enum  {TRUE = true, FALSE = false};
+
+/**
+ * @brief Typedef defining 8 bit unsigned char type.\n
+ * The developer shoud modify this to suit the platform being deployed.
+ *
+ */
+
+#ifndef bool_t
+typedef unsigned char bool_t;
+#endif
+
+
+#define	   I2C                0x01
+#define	   SPI                0x00
+
+#define    COMMS_BUFFER_SIZE    64  // MUST be the same size as the SV task buffer
+
+#define    BYTES_PER_WORD        2
+#define    BYTES_PER_DWORD       4
+
+#define    VL53L0X_MAX_STRING_LENGTH_PLT       256
+
+/**
+ * @brief  Initialise platform comms.
+ *
+ * @param  comms_type      - selects between I2C and SPI
+ * @param  comms_speed_khz - unsigned short containing the I2C speed in kHz
+ *
+ * @return status - status 0 = ok, 1 = error
+ *
+ */
+
+int32_t VL53L0X_comms_initialise(uint8_t  comms_type,
+                                 uint16_t comms_speed_khz);
+
+/**
+* @brief  Initialise platform serial comms.
+*
+* @param  comPortStr   - String to indicate the comm port
+* @param  baudRate     - Bau rate
+*
+* @return status - status 0 = ok, 1 = error
+*
+*/
+int VL53L0_i2c_init(char *comPortStr, unsigned int baudRate);
+
+
+/**
+ * @brief  Close platform comms.
+ *
+ * @return status - status 0 = ok, 1 = error
+ *
+ */
+
+int32_t VL53L0X_comms_close(void);
+
+/**
+ * @brief  Cycle Power to Device
+ *
+ * @return status - status 0 = ok, 1 = error
+ *
+ */
+
+int32_t VL53L0X_cycle_power(void);
+
+
+/**
+ * @brief Writes the supplied byte buffer to the device
+ *
+ * Wrapper for SystemVerilog Write Multi task
+ *
+ * @code
+ *
+ * Example:
+ *
+ * uint8_t *spad_enables;
+ *
+ * int status = VL53L0X_write_multi(RET_SPAD_EN_0, spad_enables, 36);
+ *
+ * @endcode
+ *
+ * @param  address - uint8_t device address value
+ * @param  index - uint8_t register index value
+ * @param  pdata - pointer to uint8_t buffer containing the data to be written
+ * @param  count - number of bytes in the supplied byte buffer
+ *
+ * @return status - SystemVerilog status 0 = ok, 1 = error
+ *
+ */
+
+int32_t VL53L0X_write_multi(uint8_t address, uint8_t index, uint8_t  *pdata, int32_t count);
+
+
+/**
+ * @brief  Reads the requested number of bytes from the device
+ *
+ * Wrapper for SystemVerilog Read Multi task
+ *
+ * @code
+ *
+ * Example:
+ *
+ * uint8_t buffer[COMMS_BUFFER_SIZE];
+ *
+ * int status = status  = VL53L0X_read_multi(DEVICE_ID, buffer, 2)
+ *
+ * @endcode
+ *
+ * @param  address - uint8_t device address value
+ * @param  index - uint8_t register index value
+ * @param  pdata - pointer to the uint8_t buffer to store read data
+ * @param  count - number of uint8_t's to read
+ *
+ * @return status - SystemVerilog status 0 = ok, 1 = error
+ *
+ */
+
+int32_t VL53L0X_read_multi(uint8_t address,  uint8_t index, uint8_t  *pdata, int32_t count);
+
+
+/**
+ * @brief  Writes a single byte to the device
+ *
+ * Wrapper for SystemVerilog Write Byte task
+ *
+ * @code
+ *
+ * Example:
+ *
+ * uint8_t page_number = MAIN_SELECT_PAGE;
+ *
+ * int status = VL53L0X_write_byte(PAGE_SELECT, page_number);
+ *
+ * @endcode
+ *
+ * @param  address - uint8_t device address value
+ * @param  index - uint8_t register index value
+ * @param  data  - uint8_t data value to write
+ *
+ * @return status - SystemVerilog status 0 = ok, 1 = error
+ *
+ */
+
+int32_t VL53L0X_write_byte(uint8_t address,  uint8_t index, uint8_t   data);
+
+
+/**
+ * @brief  Writes a single word (16-bit unsigned) to the device
+ *
+ * Manages the big-endian nature of the device (first byte written is the MS byte).
+ * Uses SystemVerilog Write Multi task.
+ *
+ * @code
+ *
+ * Example:
+ *
+ * uint16_t nvm_ctrl_pulse_width = 0x0004;
+ *
+ * int status = VL53L0X_write_word(NVM_CTRL__PULSE_WIDTH_MSB, nvm_ctrl_pulse_width);
+ *
+ * @endcode
+ *
+ * @param  address - uint8_t device address value
+ * @param  index - uint8_t register index value
+ * @param  data  - uin16_t data value write
+ *
+ * @return status - SystemVerilog status 0 = ok, 1 = error
+ *
+ */
+
+int32_t VL53L0X_write_word(uint8_t address,  uint8_t index, uint16_t  data);
+
+
+/**
+ * @brief  Writes a single dword (32-bit unsigned) to the device
+ *
+ * Manages the big-endian nature of the device (first byte written is the MS byte).
+ * Uses SystemVerilog Write Multi task.
+ *
+ * @code
+ *
+ * Example:
+ *
+ * uint32_t nvm_data = 0x0004;
+ *
+ * int status = VL53L0X_write_dword(NVM_CTRL__DATAIN_MMM, nvm_data);
+ *
+ * @endcode
+ *
+ * @param  address - uint8_t device address value
+ * @param  index - uint8_t register index value
+ * @param  data  - uint32_t data value to write
+ *
+ * @return status - SystemVerilog status 0 = ok, 1 = error
+ *
+ */
+
+int32_t VL53L0X_write_dword(uint8_t address, uint8_t index, uint32_t  data);
+
+
+
+/**
+ * @brief  Reads a single byte from the device
+ *
+ * Uses SystemVerilog Read Byte task.
+ *
+ * @code
+ *
+ * Example:
+ *
+ * uint8_t device_status = 0;
+ *
+ * int status = VL53L0X_read_byte(STATUS, &device_status);
+ *
+ * @endcode
+ *
+ * @param  address - uint8_t device address value
+ * @param  index  - uint8_t register index value
+ * @param  pdata  - pointer to uint8_t data value
+ *
+ * @return status - SystemVerilog status 0 = ok, 1 = error
+ *
+ */
+
+int32_t VL53L0X_read_byte(uint8_t address,  uint8_t index, uint8_t  *pdata);
+
+
+/**
+ * @brief  Reads a single word (16-bit unsigned) from the device
+ *
+ * Manages the big-endian nature of the device (first byte read is the MS byte).
+ * Uses SystemVerilog Read Multi task.
+ *
+ * @code
+ *
+ * Example:
+ *
+ * uint16_t timeout = 0;
+ *
+ * int status = VL53L0X_read_word(TIMEOUT_OVERALL_PERIODS_MSB, &timeout);
+ *
+ * @endcode
+ *
+ * @param  address - uint8_t device address value
+ * @param  index  - uint8_t register index value
+ * @param  pdata  - pointer to uint16_t data value
+ *
+ * @return status - SystemVerilog status 0 = ok, 1 = error
+ *
+ */
+
+int32_t VL53L0X_read_word(uint8_t address,  uint8_t index, uint16_t *pdata);
+
+
+/**
+ * @brief  Reads a single dword (32-bit unsigned) from the device
+ *
+ * Manages the big-endian nature of the device (first byte read is the MS byte).
+ * Uses SystemVerilog Read Multi task.
+ *
+ * @code
+ *
+ * Example:
+ *
+ * uint32_t range_1 = 0;
+ *
+ * int status = VL53L0X_read_dword(RANGE_1_MMM, &range_1);
+ *
+ * @endcode
+ *
+ * @param  address - uint8_t device address value
+ * @param  index - uint8_t register index value
+ * @param  pdata - pointer to uint32_t data value
+ *
+ * @return status - SystemVerilog status 0 = ok, 1 = error
+ *
+ */
+
+int32_t VL53L0X_read_dword(uint8_t address, uint8_t index, uint32_t *pdata);
+
+
+/**
+ * @brief  Implements a programmable wait in us
+ *
+ * Wrapper for SystemVerilog Wait in micro seconds task
+ *
+ * @param  wait_us - integer wait in micro seconds
+ *
+ * @return status - SystemVerilog status 0 = ok, 1 = error
+ *
+ */
+
+int32_t VL53L0X_platform_wait_us(int32_t wait_us);
+
+
+/**
+ * @brief  Implements a programmable wait in ms
+ *
+ * Wrapper for SystemVerilog Wait in milli seconds task
+ *
+ * @param  wait_ms - integer wait in milli seconds
+ *
+ * @return status - SystemVerilog status 0 = ok, 1 = error
+ *
+ */
+
+int32_t VL53L0X_wait_ms(int32_t wait_ms);
+
+
+/**
+ * @brief Set GPIO value
+ *
+ * @param  level  - input  level - either 0 or 1
+ *
+ * @return status - SystemVerilog status 0 = ok, 1 = error
+ *
+ */
+
+int32_t VL53L0X_set_gpio(uint8_t  level);
+
+
+/**
+ * @brief Get GPIO value
+ *
+ * @param  plevel - uint8_t pointer to store GPIO level (0 or 1)
+ *
+ * @return status - SystemVerilog status 0 = ok, 1 = error
+ *
+ */
+
+int32_t VL53L0X_get_gpio(uint8_t *plevel);
+
+/**
+ * @brief Release force on GPIO
+ *
+ * @return status - SystemVerilog status 0 = ok, 1 = error
+ *
+ */
+
+int32_t VL53L0X_release_gpio(void);
+
+
+/**
+* @brief Get the frequency of the timer used for ranging results time stamps
+*
+* @param[out] ptimer_freq_hz : pointer for timer frequency
+*
+* @return status : 0 = ok, 1 = error
+*
+*/
+
+int32_t VL53L0X_get_timer_frequency(int32_t *ptimer_freq_hz);
+
+/**
+* @brief Get the timer value in units of timer_freq_hz (see VL53L0X_get_timestamp_frequency())
+*
+* @param[out] ptimer_count : pointer for timer count value
+*
+* @return status : 0 = ok, 1 = error
+*
+*/
+
+int32_t VL53L0X_get_timer_value(int32_t *ptimer_count);
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_VL53L0X_I2C_PLATFORM_H_
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/VL53L0X/VL53L0X_interrupt_threshold_settings.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,195 @@
+/*******************************************************************************
+Copyright © 2016, STMicroelectronics International N.V.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+	* Redistributions of source code must retain the above copyright
+	  notice, this list of conditions and the following disclaimer.
+	* Redistributions in binary form must reproduce the above copyright
+	  notice, this list of conditions and the following disclaimer in the
+	  documentation and/or other materials provided with the distribution.
+	* Neither the name of STMicroelectronics nor the
+	  names of its contributors may be used to endorse or promote products
+	  derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
+NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
+IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+
+
+#ifndef _VL53L0X_INTERRUPT_THRESHOLD_SETTINGS_H_
+#define _VL53L0X_INTERRUPT_THRESHOLD_SETTINGS_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+uint8_t InterruptThresholdSettings[] = {
+
+    /* Start of Interrupt Threshold Settings */
+    0x1, 0xff, 0x00,
+    0x1, 0x80, 0x01,
+    0x1, 0xff, 0x01,
+    0x1, 0x00, 0x00,
+    0x1, 0xff, 0x01,
+    0x1, 0x4f, 0x02,
+    0x1, 0xFF, 0x0E,
+    0x1, 0x00, 0x03,
+    0x1, 0x01, 0x84,
+    0x1, 0x02, 0x0A,
+    0x1, 0x03, 0x03,
+    0x1, 0x04, 0x08,
+    0x1, 0x05, 0xC8,
+    0x1, 0x06, 0x03,
+    0x1, 0x07, 0x8D,
+    0x1, 0x08, 0x08,
+    0x1, 0x09, 0xC6,
+    0x1, 0x0A, 0x01,
+    0x1, 0x0B, 0x02,
+    0x1, 0x0C, 0x00,
+    0x1, 0x0D, 0xD5,
+    0x1, 0x0E, 0x18,
+    0x1, 0x0F, 0x12,
+    0x1, 0x10, 0x01,
+    0x1, 0x11, 0x82,
+    0x1, 0x12, 0x00,
+    0x1, 0x13, 0xD5,
+    0x1, 0x14, 0x18,
+    0x1, 0x15, 0x13,
+    0x1, 0x16, 0x03,
+    0x1, 0x17, 0x86,
+    0x1, 0x18, 0x0A,
+    0x1, 0x19, 0x09,
+    0x1, 0x1A, 0x08,
+    0x1, 0x1B, 0xC2,
+    0x1, 0x1C, 0x03,
+    0x1, 0x1D, 0x8F,
+    0x1, 0x1E, 0x0A,
+    0x1, 0x1F, 0x06,
+    0x1, 0x20, 0x01,
+    0x1, 0x21, 0x02,
+    0x1, 0x22, 0x00,
+    0x1, 0x23, 0xD5,
+    0x1, 0x24, 0x18,
+    0x1, 0x25, 0x22,
+    0x1, 0x26, 0x01,
+    0x1, 0x27, 0x82,
+    0x1, 0x28, 0x00,
+    0x1, 0x29, 0xD5,
+    0x1, 0x2A, 0x18,
+    0x1, 0x2B, 0x0B,
+    0x1, 0x2C, 0x28,
+    0x1, 0x2D, 0x78,
+    0x1, 0x2E, 0x28,
+    0x1, 0x2F, 0x91,
+    0x1, 0x30, 0x00,
+    0x1, 0x31, 0x0B,
+    0x1, 0x32, 0x00,
+    0x1, 0x33, 0x0B,
+    0x1, 0x34, 0x00,
+    0x1, 0x35, 0xA1,
+    0x1, 0x36, 0x00,
+    0x1, 0x37, 0xA0,
+    0x1, 0x38, 0x00,
+    0x1, 0x39, 0x04,
+    0x1, 0x3A, 0x28,
+    0x1, 0x3B, 0x30,
+    0x1, 0x3C, 0x0C,
+    0x1, 0x3D, 0x04,
+    0x1, 0x3E, 0x0F,
+    0x1, 0x3F, 0x79,
+    0x1, 0x40, 0x28,
+    0x1, 0x41, 0x1E,
+    0x1, 0x42, 0x2F,
+    0x1, 0x43, 0x87,
+    0x1, 0x44, 0x00,
+    0x1, 0x45, 0x0B,
+    0x1, 0x46, 0x00,
+    0x1, 0x47, 0x0B,
+    0x1, 0x48, 0x00,
+    0x1, 0x49, 0xA7,
+    0x1, 0x4A, 0x00,
+    0x1, 0x4B, 0xA6,
+    0x1, 0x4C, 0x00,
+    0x1, 0x4D, 0x04,
+    0x1, 0x4E, 0x01,
+    0x1, 0x4F, 0x00,
+    0x1, 0x50, 0x00,
+    0x1, 0x51, 0x80,
+    0x1, 0x52, 0x09,
+    0x1, 0x53, 0x08,
+    0x1, 0x54, 0x01,
+    0x1, 0x55, 0x00,
+    0x1, 0x56, 0x0F,
+    0x1, 0x57, 0x79,
+    0x1, 0x58, 0x09,
+    0x1, 0x59, 0x05,
+    0x1, 0x5A, 0x00,
+    0x1, 0x5B, 0x60,
+    0x1, 0x5C, 0x05,
+    0x1, 0x5D, 0xD1,
+    0x1, 0x5E, 0x0C,
+    0x1, 0x5F, 0x3C,
+    0x1, 0x60, 0x00,
+    0x1, 0x61, 0xD0,
+    0x1, 0x62, 0x0B,
+    0x1, 0x63, 0x03,
+    0x1, 0x64, 0x28,
+    0x1, 0x65, 0x10,
+    0x1, 0x66, 0x2A,
+    0x1, 0x67, 0x39,
+    0x1, 0x68, 0x0B,
+    0x1, 0x69, 0x02,
+    0x1, 0x6A, 0x28,
+    0x1, 0x6B, 0x10,
+    0x1, 0x6C, 0x2A,
+    0x1, 0x6D, 0x61,
+    0x1, 0x6E, 0x0C,
+    0x1, 0x6F, 0x00,
+    0x1, 0x70, 0x0F,
+    0x1, 0x71, 0x79,
+    0x1, 0x72, 0x00,
+    0x1, 0x73, 0x0B,
+    0x1, 0x74, 0x00,
+    0x1, 0x75, 0x0B,
+    0x1, 0x76, 0x00,
+    0x1, 0x77, 0xA1,
+    0x1, 0x78, 0x00,
+    0x1, 0x79, 0xA0,
+    0x1, 0x7A, 0x00,
+    0x1, 0x7B, 0x04,
+    0x1, 0xFF, 0x04,
+    0x1, 0x79, 0x1D,
+    0x1, 0x7B, 0x27,
+    0x1, 0x96, 0x0E,
+    0x1, 0x97, 0xFE,
+    0x1, 0x98, 0x03,
+    0x1, 0x99, 0xEF,
+    0x1, 0x9A, 0x02,
+    0x1, 0x9B, 0x44,
+    0x1, 0x73, 0x07,
+    0x1, 0x70, 0x01,
+    0x1, 0xff, 0x01,
+    0x1, 0x00, 0x01,
+    0x1, 0xff, 0x00,
+    0x00, 0x00, 0x00
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _VL53L0X_INTERRUPT_THRESHOLD_SETTINGS_H_ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/VL53L0X/VL53L0X_platform.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,242 @@
+/*******************************************************************************
+Copyright © 2015, STMicroelectronics International N.V.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of STMicroelectronics nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
+NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
+IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+********************************************************************************/
+
+
+#ifndef _VL53L0X_PLATFORM_H_
+#define _VL53L0X_PLATFORM_H_
+
+#include "VL53L0X_def.h"
+#include "VL53L0X_platform_log.h"
+#include "VL53L0X_i2c_platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file vl53l0_platform.h
+ *
+ * @brief All end user OS/platform/application porting
+ */
+
+/**
+ * @defgroup VL53L0X_platform_group VL53L0 Platform Functions
+ * @brief    VL53L0 Platform Functions
+ *  @{
+ */
+
+/**
+ * @struct  VL53L0X_Dev_t
+ * @brief    Generic PAL device type that does link between API and platform abstraction layer
+ *
+ */
+typedef struct {
+    VL53L0X_DevData_t Data;               /*!< embed ST Ewok Dev  data as "Data"*/
+
+    /*!< user specific field */
+    uint8_t   I2cDevAddr;                /*!< i2c device address user specific field */
+    uint8_t   comms_type;                /*!< Type of comms : VL53L0X_COMMS_I2C or VL53L0X_COMMS_SPI */
+    uint16_t  comms_speed_khz;           /*!< Comms speed [kHz] : typically 400kHz for I2C           */
+
+} VL53L0X_Dev_t;
+
+
+/**
+ * @brief   Declare the device Handle as a pointer of the structure @a VL53L0X_Dev_t.
+ *
+ */
+typedef VL53L0X_Dev_t *VL53L0X_DEV;
+
+/**
+ * @def PALDevDataGet
+ * @brief Get ST private structure @a VL53L0X_DevData_t data access
+ *
+ * @param Dev       Device Handle
+ * @param field     ST structure field name
+ * It maybe used and as real data "ref" not just as "get" for sub-structure item
+ * like PALDevDataGet(FilterData.field)[i] or PALDevDataGet(FilterData.MeasurementIndex)++
+ */
+#define PALDevDataGet(Dev, field) (Dev->Data.field)
+
+/**
+ * @def PALDevDataSet(Dev, field, data)
+ * @brief  Set ST private structure @a VL53L0X_DevData_t data field
+ * @param Dev       Device Handle
+ * @param field     ST structure field name
+ * @param data      Data to be set
+ */
+#define PALDevDataSet(Dev, field, data) (Dev->Data.field)=(data)
+
+
+/**
+ * @defgroup VL53L0X_registerAccess_group PAL Register Access Functions
+ * @brief    PAL Register Access Functions
+ *  @{
+ */
+
+/**
+ * Lock comms interface to serialize all commands to a shared I2C interface for a specific device
+ * @param   Dev       Device Handle
+ * @return  VL53L0X_ERROR_NONE        Success
+ * @return  "Other error code"    See ::VL53L0X_Error
+ */
+VL53L0X_Error VL53L0X_LockSequenceAccess(VL53L0X_DEV Dev);
+
+/**
+ * Unlock comms interface to serialize all commands to a shared I2C interface for a specific device
+ * @param   Dev       Device Handle
+ * @return  VL53L0X_ERROR_NONE        Success
+ * @return  "Other error code"    See ::VL53L0X_Error
+ */
+VL53L0X_Error VL53L0X_UnlockSequenceAccess(VL53L0X_DEV Dev);
+
+
+/**
+ * Writes the supplied byte buffer to the device
+ * @param   Dev       Device Handle
+ * @param   index     The register index
+ * @param   pdata     Pointer to uint8_t buffer containing the data to be written
+ * @param   count     Number of bytes in the supplied byte buffer
+ * @return  VL53L0X_ERROR_NONE        Success
+ * @return  "Other error code"    See ::VL53L0X_Error
+ */
+VL53L0X_Error VL53L0X_WriteMulti(VL53L0X_DEV Dev, uint8_t index, uint8_t *pdata, uint32_t count);
+
+/**
+ * Reads the requested number of bytes from the device
+ * @param   Dev       Device Handle
+ * @param   index     The register index
+ * @param   pdata     Pointer to the uint8_t buffer to store read data
+ * @param   count     Number of uint8_t's to read
+ * @return  VL53L0X_ERROR_NONE        Success
+ * @return  "Other error code"    See ::VL53L0X_Error
+ */
+VL53L0X_Error VL53L0X_ReadMulti(VL53L0X_DEV Dev, uint8_t index, uint8_t *pdata, uint32_t count);
+
+/**
+ * Write single byte register
+ * @param   Dev       Device Handle
+ * @param   index     The register index
+ * @param   data      8 bit register data
+ * @return  VL53L0X_ERROR_NONE        Success
+ * @return  "Other error code"    See ::VL53L0X_Error
+ */
+VL53L0X_Error VL53L0X_WrByte(VL53L0X_DEV Dev, uint8_t index, uint8_t data);
+
+/**
+ * Write word register
+ * @param   Dev       Device Handle
+ * @param   index     The register index
+ * @param   data      16 bit register data
+ * @return  VL53L0X_ERROR_NONE        Success
+ * @return  "Other error code"    See ::VL53L0X_Error
+ */
+VL53L0X_Error VL53L0X_WrWord(VL53L0X_DEV Dev, uint8_t index, uint16_t data);
+
+/**
+ * Write double word (4 byte) register
+ * @param   Dev       Device Handle
+ * @param   index     The register index
+ * @param   data      32 bit register data
+ * @return  VL53L0X_ERROR_NONE        Success
+ * @return  "Other error code"    See ::VL53L0X_Error
+ */
+VL53L0X_Error VL53L0X_WrDWord(VL53L0X_DEV Dev, uint8_t index, uint32_t data);
+
+/**
+ * Read single byte register
+ * @param   Dev       Device Handle
+ * @param   index     The register index
+ * @param   data      pointer to 8 bit data
+ * @return  VL53L0X_ERROR_NONE        Success
+ * @return  "Other error code"    See ::VL53L0X_Error
+ */
+VL53L0X_Error VL53L0X_RdByte(VL53L0X_DEV Dev, uint8_t index, uint8_t *data);
+
+/**
+ * Read word (2byte) register
+ * @param   Dev       Device Handle
+ * @param   index     The register index
+ * @param   data      pointer to 16 bit data
+ * @return  VL53L0X_ERROR_NONE        Success
+ * @return  "Other error code"    See ::VL53L0X_Error
+ */
+VL53L0X_Error VL53L0X_RdWord(VL53L0X_DEV Dev, uint8_t index, uint16_t *data);
+
+/**
+ * Read dword (4byte) register
+ * @param   Dev       Device Handle
+ * @param   index     The register index
+ * @param   data      pointer to 32 bit data
+ * @return  VL53L0X_ERROR_NONE        Success
+ * @return  "Other error code"    See ::VL53L0X_Error
+ */
+VL53L0X_Error VL53L0X_RdDWord(VL53L0X_DEV Dev, uint8_t index, uint32_t *data);
+
+/**
+ * Threat safe Update (read/modify/write) single byte register
+ *
+ * Final_reg = (Initial_reg & and_data) |or_data
+ *
+ * @param   Dev        Device Handle
+ * @param   index      The register index
+ * @param   AndData    8 bit and data
+ * @param   OrData     8 bit or data
+ * @return  VL53L0X_ERROR_NONE        Success
+ * @return  "Other error code"    See ::VL53L0X_Error
+ */
+VL53L0X_Error VL53L0X_UpdateByte(VL53L0X_DEV Dev, uint8_t index, uint8_t AndData, uint8_t OrData);
+
+/** @} end of VL53L0X_registerAccess_group */
+
+
+/**
+ * @brief execute delay in all polling API call
+ *
+ * A typical multi-thread or RTOs implementation is to sleep the task for some 5ms (with 100Hz max rate faster polling is not needed)
+ * if nothing specific is need you can define it as an empty/void macro
+ * @code
+ * #define VL53L0X_PollingDelay(...) (void)0
+ * @endcode
+ * @param Dev       Device Handle
+ * @return  VL53L0X_ERROR_NONE        Success
+ * @return  "Other error code"    See ::VL53L0X_Error
+ */
+VL53L0X_Error VL53L0X_PollingDelay(VL53L0X_DEV Dev); /* usually best implemented as a real function */
+
+/** @} end of VL53L0X_platform_group */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _VL53L0X_PLATFORM_H_ */
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/VL53L0X/VL53L0X_platform_log.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,119 @@
+/*******************************************************************************
+Copyright © 2015, STMicroelectronics International N.V.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of STMicroelectronics nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
+NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
+IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+********************************************************************************/
+
+
+#ifndef _VL53L0X_PLATFORM_LOG_H_
+#define _VL53L0X_PLATFORM_LOG_H_
+
+#include <stdio.h>
+#include <string.h>
+/* LOG Functions */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file vl53l0_platform_log.h
+ *
+ * @brief platform log function definition
+ */
+
+//#define VL53L0X_LOG_ENABLE 0
+
+enum {
+    TRACE_LEVELS_NONE,
+    TRACE_LEVELS_ERRORS,
+    TRACE_LEVELS_WARNING,
+    TRACE_LEVELS_INFO,
+    TRACE_LEVELS_DEBUG,
+    TRACE_LEVELS_ALL,
+    TRACE_LEVELS_IGNORE
+};
+
+enum {
+    TRACE_FUNCTION_NONE = 0,
+    TRACE_FUNCTION_I2C  = 1,
+    TRACE_FUNCTION_ALL  = 0x7fffffff //all bits except sign
+};
+
+enum {
+    TRACE_MODULE_NONE              = 0x0,
+    TRACE_MODULE_API               = 0x1,
+    TRACE_MODULE_PLATFORM          = 0x2,
+    TRACE_MODULE_ALL               = 0x7fffffff //all bits except sign
+};
+
+
+#ifdef VL53L0X_LOG_ENABLE
+
+#include <sys/time.h>
+
+extern uint32_t _trace_level;
+
+
+
+int32_t VL53L0X_trace_config(char *filename, uint32_t modules, uint32_t level, uint32_t functions);
+
+void trace_print_module_function(uint32_t module, uint32_t level, uint32_t function, const char *format, ...);
+
+
+//extern FILE * log_file;
+
+#define LOG_GET_TIME() (int)clock()
+
+#define _LOG_FUNCTION_START(module, fmt, ... ) \
+        trace_print_module_function(module, _trace_level, TRACE_FUNCTION_ALL, "%ld <START> %s "fmt"\n", LOG_GET_TIME(), __FUNCTION__, ##__VA_ARGS__);
+
+#define _LOG_FUNCTION_END(module, status, ... )\
+        trace_print_module_function(module, _trace_level, TRACE_FUNCTION_ALL, "%ld <END> %s %d\n", LOG_GET_TIME(), __FUNCTION__, (int)status, ##__VA_ARGS__)
+
+#define _LOG_FUNCTION_END_FMT(module, status, fmt, ... )\
+        trace_print_module_function(module, _trace_level, TRACE_FUNCTION_ALL, "%ld <END> %s %d "fmt"\n", LOG_GET_TIME(),  __FUNCTION__, (int)status,##__VA_ARGS__)
+
+// __func__ is gcc only
+#define VL53L0X_ErrLog( fmt, ...)  fprintf(stderr, "VL53L0X_ErrLog %s" fmt "\n", __func__, ##__VA_ARGS__)
+
+#else /* VL53L0X_LOG_ENABLE no logging */
+#define VL53L0X_ErrLog(...) (void)0
+#define _LOG_FUNCTION_START(module, fmt, ... ) (void)0
+#define _LOG_FUNCTION_END(module, status, ... ) (void)0
+#define _LOG_FUNCTION_END_FMT(module, status, fmt, ... ) (void)0
+#endif /* else */
+
+#define VL53L0X_COPYSTRING(str, ...) strcpy(str, ##__VA_ARGS__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _VL53L0X_PLATFORM_LOG_H_ */
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/VL53L0X/VL53L0X_tuning.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,147 @@
+/*******************************************************************************
+Copyright © 2016, STMicroelectronics International N.V.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+	* Redistributions of source code must retain the above copyright
+	  notice, this list of conditions and the following disclaimer.
+	* Redistributions in binary form must reproduce the above copyright
+	  notice, this list of conditions and the following disclaimer in the
+	  documentation and/or other materials provided with the distribution.
+	* Neither the name of STMicroelectronics nor the
+	  names of its contributors may be used to endorse or promote products
+	  derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
+NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
+IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+
+
+#ifndef _VL53L0X_TUNING_H_
+#define _VL53L0X_TUNING_H_
+
+#include "VL53L0X_def.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+uint8_t DefaultTuningSettings[] = {
+
+    /* update 02/11/2015_v36 */
+    0x01, 0xFF, 0x01,
+    0x01, 0x00, 0x00,
+
+    0x01, 0xFF, 0x00,
+    0x01, 0x09, 0x00,
+    0x01, 0x10, 0x00,
+    0x01, 0x11, 0x00,
+
+    0x01, 0x24, 0x01,
+    0x01, 0x25, 0xff,
+    0x01, 0x75, 0x00,
+
+    0x01, 0xFF, 0x01,
+    0x01, 0x4e, 0x2c,
+    0x01, 0x48, 0x00,
+    0x01, 0x30, 0x20,
+
+    0x01, 0xFF, 0x00,
+    0x01, 0x30, 0x09, /* mja changed from 0x64. */
+    0x01, 0x54, 0x00,
+    0x01, 0x31, 0x04,
+    0x01, 0x32, 0x03,
+    0x01, 0x40, 0x83,
+    0x01, 0x46, 0x25,
+    0x01, 0x60, 0x00,
+    0x01, 0x27, 0x00,
+    0x01, 0x50, 0x06,
+    0x01, 0x51, 0x00,
+    0x01, 0x52, 0x96,
+    0x01, 0x56, 0x08,
+    0x01, 0x57, 0x30,
+    0x01, 0x61, 0x00,
+    0x01, 0x62, 0x00,
+    0x01, 0x64, 0x00,
+    0x01, 0x65, 0x00,
+    0x01, 0x66, 0xa0,
+
+    0x01, 0xFF, 0x01,
+    0x01, 0x22, 0x32,
+    0x01, 0x47, 0x14,
+    0x01, 0x49, 0xff,
+    0x01, 0x4a, 0x00,
+
+    0x01, 0xFF, 0x00,
+    0x01, 0x7a, 0x0a,
+    0x01, 0x7b, 0x00,
+    0x01, 0x78, 0x21,
+
+    0x01, 0xFF, 0x01,
+    0x01, 0x23, 0x34,
+    0x01, 0x42, 0x00,
+    0x01, 0x44, 0xff,
+    0x01, 0x45, 0x26,
+    0x01, 0x46, 0x05,
+    0x01, 0x40, 0x40,
+    0x01, 0x0E, 0x06,
+    0x01, 0x20, 0x1a,
+    0x01, 0x43, 0x40,
+
+    0x01, 0xFF, 0x00,
+    0x01, 0x34, 0x03,
+    0x01, 0x35, 0x44,
+
+    0x01, 0xFF, 0x01,
+    0x01, 0x31, 0x04,
+    0x01, 0x4b, 0x09,
+    0x01, 0x4c, 0x05,
+    0x01, 0x4d, 0x04,
+
+
+    0x01, 0xFF, 0x00,
+    0x01, 0x44, 0x00,
+    0x01, 0x45, 0x20,
+    0x01, 0x47, 0x08,
+    0x01, 0x48, 0x28,
+    0x01, 0x67, 0x00,
+    0x01, 0x70, 0x04,
+    0x01, 0x71, 0x01,
+    0x01, 0x72, 0xfe,
+    0x01, 0x76, 0x00,
+    0x01, 0x77, 0x00,
+
+    0x01, 0xFF, 0x01,
+    0x01, 0x0d, 0x01,
+
+    0x01, 0xFF, 0x00,
+    0x01, 0x80, 0x01,
+    0x01, 0x01, 0xF8,
+
+    0x01, 0xFF, 0x01,
+    0x01, 0x8e, 0x01,
+    0x01, 0x00, 0x01,
+    0x01, 0xFF, 0x00,
+    0x01, 0x80, 0x00,
+
+    0x00, 0x00, 0x00
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _VL53L0X_TUNING_H_ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/VL53L0X/VL53L0X_types.h	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,112 @@
+/*******************************************************************************
+Copyright © 2015, STMicroelectronics International N.V.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of STMicroelectronics nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
+NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
+IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+********************************************************************************/
+/**
+ * @file  vl53l0_types.h
+ * @brief VL53L0 types definition
+ */
+
+#ifndef VL53L0X_TYPES_H_
+#define VL53L0X_TYPES_H_
+
+/** @defgroup porting_type  Basic type definition
+ *  @ingroup  VL53L0X_platform_group
+ *
+ *  @brief  file vl53l0_types.h files hold basic type definition that may requires porting
+ *
+ *  contains type that must be defined for the platform\n
+ *  when target platform and compiler provide stdint.h and stddef.h it is enough to include it.\n
+ *  If stdint.h is not available review and adapt all signed and unsigned 8/16/32 bits basic types. \n
+ *  If stddef.h is not available review and adapt NULL definition .
+ */
+#include <stdint.h>
+#include <stddef.h>
+
+#ifndef NULL
+#error "Error NULL definition should be done. Please add required include "
+#endif
+
+
+#if ! defined(STDINT_H) &&  !defined(_GCC_STDINT_H) &&!defined(__STDINT_DECLS) && !defined(_GCC_WRAP_STDINT_H)
+
+#pragma message("Please review  type definition of STDINT define for your platform and add to list above ")
+
+/*
+ *  target platform do not provide stdint or use a different #define than above
+ *  to avoid seeing the message below addapt the #define list above or implement
+ *  all type and delete these pragma
+ */
+
+/** \ingroup VL53L0X_portingType_group
+ * @{
+ */
+
+
+typedef unsigned long long uint64_t;
+
+
+/** @brief Typedef defining 32 bit unsigned int type.\n
+ * The developer should modify this to suit the platform being deployed.
+ */
+typedef unsigned int uint32_t;
+
+/** @brief Typedef defining 32 bit int type.\n
+ * The developer should modify this to suit the platform being deployed.
+ */
+typedef int int32_t;
+
+/** @brief Typedef defining 16 bit unsigned short type.\n
+ * The developer should modify this to suit the platform being deployed.
+ */
+typedef unsigned short uint16_t;
+
+/** @brief Typedef defining 16 bit short type.\n
+ * The developer should modify this to suit the platform being deployed.
+ */
+typedef short int16_t;
+
+/** @brief Typedef defining 8 bit unsigned char type.\n
+ * The developer should modify this to suit the platform being deployed.
+ */
+typedef unsigned char uint8_t;
+
+/** @brief Typedef defining 8 bit char type.\n
+ * The developer should modify this to suit the platform being deployed.
+ */
+typedef signed char int8_t;
+
+/** @}  */
+#endif /* _STDINT_H */
+
+
+/** use where fractional values are expected
+ *
+ * Given a floating point value f it's .16 bit point is (int)(f*(1<<16))*/
+typedef uint32_t FixPoint1616_t;
+
+#endif /* VL53L0X_TYPES_H_ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/common/ST_INTERFACES.lib	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/ST/code/ST_INTERFACES/#8f70f7159316
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensors/common/X_NUCLEO_COMMON.lib	Sun Dec 16 13:53:42 2018 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/ST/code/X_NUCLEO_COMMON/#21096473f63e