Garage Door Monitor and Opener

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Introduction

This system implements a simple garage door opener and environmental monitor. The hardware connects to the internet using Wi-Fi then on to the Pelion Device Management Platform which provides device monitoring and secure firmware updates over the air (FOTA). Pelion Device Management provides a flexible set of REST APIs which we will use to communicate to a web application running on an EC-2 instance in AWS. The web application will serve a web page where we can monitor and control our garage..

This project is intended to work on the DISCO-L475VG-IOT01A from ST Microelectronics It implements a simple actuator to drive a relay to simulate pushing the "open" button on older style garage doors which do not use a rolling code interface.

The system is designed to be mounted over the door so that the on board time of flight sensor can be used to detect if the door is open or closed.

The system also monitors temperature, humidity and barometric pressure.

https://os.mbed.com/media/uploads/JimCarver/garageopener.jpg

Hardware Requirements:

DISCO-L475G-IOT01A https://os.mbed.com/platforms/ST-Discovery-L475E-IOT01A/

Seeed Studio Grove Relay module https://www.seeedstudio.com/Grove-Relay.html

Seeed Studio Grove cable, I used this one: https://www.seeedstudio.com/Grove-4-pin-Male-Jumper-to-Grove-4-pin-Conversion-Cable-5-PCs-per-Pack.html

Connect to the PMOD connector like this:

https://os.mbed.com/media/uploads/JimCarver/opener.jpg

This shows how I installed so that the time of flight sensor can detect when the door is open

https://os.mbed.com/media/uploads/JimCarver/opener1.jpg https://os.mbed.com/media/uploads/JimCarver/opener2.jpg

To use the project:

You will also need a Pelion developers account.

I suggest you first use the Pelion quick state to become familiar with Pelion Device Management. https://os.mbed.com/guides/connect-device-to-pelion/1/?board=ST-Discovery-L475E-IOT01A

Web Interface

For my web interface I am running node-red under Ubuntu in an EC2 instance on AWS. This can run for 12 month within the constraints of their free tier. Here is a tutorial: https://nodered.org/docs/getting-started/aws

You will also need to install several node-red add ons:

sudo npm install -g node-red-dashboard

sudo npm install -g node-red-contrib-mbed-cloud

sudo npm istall -g node-red-contrib-moment

After starting node-red import the contents of GarageFlow.txt from the project, pin the flow into the page.

To enable your web app to access your Pelion account you need an API key.

First you will neet to use your Pelion account to create an API key.

https://os.mbed.com/media/uploads/JimCarver/api_portal.jpg

Now we need to apply that API key to your Node-Red flow.

https://os.mbed.com/media/uploads/JimCarver/api_node-red.jpg

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