iNEMO inertial module: 3D accelerometer and 3D gyroscope.

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Dependents:   X_NUCLEO_IKS01A3 X_NUCLEO_IKS01A3

Files at this revision

API Documentation at this revision

Comitter:
cparata
Date:
Tue Mar 05 16:26:47 2019 +0000
Child:
1:888ac5f8d970
Commit message:
First version of the LSM6DSO library

Changed in this revision

LSM6DSOSensor.cpp Show annotated file Show diff for this revision Revisions of this file
LSM6DSOSensor.h Show annotated file Show diff for this revision Revisions of this file
ST_INTERFACES.lib Show annotated file Show diff for this revision Revisions of this file
X_NUCLEO_COMMON.lib Show annotated file Show diff for this revision Revisions of this file
lsm6dso_reg.c Show annotated file Show diff for this revision Revisions of this file
lsm6dso_reg.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LSM6DSOSensor.cpp	Tue Mar 05 16:26:47 2019 +0000
@@ -0,0 +1,2667 @@
+/**
+ ******************************************************************************
+ * @file    LSM6DSOSensor.cpp
+ * @author  SRA
+ * @version V1.0.0
+ * @date    February 2019
+ * @brief   Implementation of an LSM6DSO Inertial Measurement Unit (IMU) 6 axes
+ *          sensor.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2019 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 "LSM6DSOSensor.h"
+
+
+/* Class Implementation ------------------------------------------------------*/
+
+/** Constructor
+ * @param spi object of an helper class which handles the SPI peripheral
+ * @param cs_pin the chip select pin
+ * @param int1_pin the interrupt 1 pin
+ * @param int2_pin the interrupt 2 pin
+ * @param spi_type the SPI type
+ */
+LSM6DSOSensor::LSM6DSOSensor(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 LSM6DSO CS MUST NOT BE NC\n\r");       
+    _dev_spi = NULL;
+    _dev_i2c = NULL;
+    return;
+  }
+
+  _reg_ctx.write_reg = LSM6DSO_io_write;
+  _reg_ctx.read_reg = LSM6DSO_io_read;
+  _reg_ctx.handle = (void *)this;
+  _cs_pin = 1;    
+  _dev_i2c = NULL;
+  _address = 0;
+    
+  if (_spi_type == SPI3W)
+  {
+    /* Enable SPI 3-Wires on the component */
+    uint8_t data = 0x0C;
+    lsm6dso_write_reg(&_reg_ctx, LSM6DSO_CTRL3_C, &data, 1);
+  }
+}
+
+
+/** Constructor
+ * @param i2c object of an helper class which handles the I2C peripheral
+ * @param address the address of the component's instance
+ * @param int1_pin the interrupt 1 pin
+ * @param int2_pin the interrupt 2 pin
+ */
+LSM6DSOSensor::LSM6DSOSensor(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;
+  _reg_ctx.write_reg = LSM6DSO_io_write;
+  _reg_ctx.read_reg = LSM6DSO_io_read;
+  _reg_ctx.handle = (void *)this;
+}
+
+/**
+ * @brief  Initializing the component
+ * @param  init pointer to device specific initalization structure
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::init(void *init)
+{
+  /* Enable register address automatically incremented during a multiple byte
+  access with a serial interface. */
+  if (lsm6dso_auto_increment_set(&_reg_ctx, PROPERTY_ENABLE) != 0)
+  {
+    return 1;
+  }
+
+  /* Enable BDU */
+  if (lsm6dso_block_data_update_set(&_reg_ctx, PROPERTY_ENABLE) != 0)
+  {
+    return 1;
+  }
+
+  /* FIFO mode selection */
+  if (lsm6dso_fifo_mode_set(&_reg_ctx, LSM6DSO_BYPASS_MODE) != 0)
+  {
+    return 1;
+  }
+
+  /* Output data rate selection - power down. */
+  if (lsm6dso_xl_data_rate_set(&_reg_ctx, LSM6DSO_XL_ODR_OFF) != 0)
+  {
+    return 1;
+  }
+
+  /* Full scale selection. */
+  if (lsm6dso_xl_full_scale_set(&_reg_ctx, LSM6DSO_2g) != 0)
+  {
+    return 1;
+  }
+
+  /* Output data rate selection - power down. */
+  if (lsm6dso_gy_data_rate_set(&_reg_ctx, LSM6DSO_GY_ODR_OFF) != 0)
+  {
+    return 1;
+  }
+
+  /* Full scale selection. */
+  if (lsm6dso_gy_full_scale_set(&_reg_ctx, LSM6DSO_2000dps) != 0)
+  {
+    return 1;
+  }
+
+  /* Select default output data rate. */
+  _x_last_odr = LSM6DSO_XL_ODR_104Hz;
+
+  /* Select default output data rate. */
+  _g_last_odr = LSM6DSO_GY_ODR_104Hz;
+
+  _x_is_enabled = 0;
+
+  _g_is_enabled = 0;
+
+  return 0;
+}
+
+/**
+ * @brief  Read component ID
+ * @param  id the WHO_AM_I value
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::read_id(uint8_t *id)
+{
+  if (lsm6dso_device_id_get(&_reg_ctx, id) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Enable the LSM6DSO accelerometer sensor
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::enable_x()
+{
+  /* Check if the component is already enabled */
+  if (_x_is_enabled == 1U)
+  {
+    return 0;
+  }
+
+  /* Output data rate selection. */
+  if (lsm6dso_xl_data_rate_set(&_reg_ctx, _x_last_odr) != 0)
+  {
+    return 1;
+  }
+
+  _x_is_enabled = 1;
+
+  return 0;
+}
+
+/**
+ * @brief  Disable the LSM6DSO accelerometer sensor
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::disable_x()
+{
+  /* Check if the component is already disabled */
+  if (_x_is_enabled == 0U)
+  {
+    return 0;
+  }
+
+  /* Get current output data rate. */
+  if (lsm6dso_xl_data_rate_get(&_reg_ctx, &_x_last_odr) != 0)
+  {
+    return 1;
+  }
+
+  /* Output data rate selection - power down. */
+  if (lsm6dso_xl_data_rate_set(&_reg_ctx, LSM6DSO_XL_ODR_OFF) != 0)
+  {
+    return 1;
+  }
+
+  _x_is_enabled = 0;
+
+  return 0;
+}
+
+/**
+ * @brief  Get the LSM6DSO accelerometer sensor sensitivity
+ * @param  sensitivity pointer where the sensitivity is written
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_x_sensitivity(float *sensitivity)
+{
+  int ret = 0;
+  lsm6dso_fs_xl_t full_scale;
+
+  /* Read actual full scale selection from sensor. */
+  if (lsm6dso_xl_full_scale_get(&_reg_ctx, &full_scale) != 0)
+  {
+    return 1;
+  }
+
+  /* Store the sensitivity based on actual full scale. */
+  switch (full_scale)
+  {
+    case LSM6DSO_2g:
+      *sensitivity = LSM6DSO_ACC_SENSITIVITY_FS_2G;
+      break;
+
+    case LSM6DSO_4g:
+      *sensitivity = LSM6DSO_ACC_SENSITIVITY_FS_4G;
+      break;
+
+    case LSM6DSO_8g:
+      *sensitivity = LSM6DSO_ACC_SENSITIVITY_FS_8G;
+      break;
+
+    case LSM6DSO_16g:
+      *sensitivity = LSM6DSO_ACC_SENSITIVITY_FS_16G;
+      break;
+
+    default:
+      ret = 1;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+ * @brief  Get the LSM6DSO accelerometer sensor output data rate
+ * @param  odr pointer where the output data rate is written
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_x_odr(float *odr)
+{
+  int ret = 0;
+  lsm6dso_odr_xl_t odr_low_level;
+
+  /* Get current output data rate. */
+  if (lsm6dso_xl_data_rate_get(&_reg_ctx, &odr_low_level) != 0)
+  {
+    return 1;
+  }
+
+  switch (odr_low_level)
+  {
+    case LSM6DSO_XL_ODR_OFF:
+      *odr = 0.0f;
+      break;
+
+    case LSM6DSO_XL_ODR_6Hz5:
+      *odr = 6.5f;
+      break;
+
+    case LSM6DSO_XL_ODR_12Hz5:
+      *odr = 12.5f;
+      break;
+
+    case LSM6DSO_XL_ODR_26Hz:
+      *odr = 26.0f;
+      break;
+
+    case LSM6DSO_XL_ODR_52Hz:
+      *odr = 52.0f;
+      break;
+
+    case LSM6DSO_XL_ODR_104Hz:
+      *odr = 104.0f;
+      break;
+
+    case LSM6DSO_XL_ODR_208Hz:
+      *odr = 208.0f;
+      break;
+
+    case LSM6DSO_XL_ODR_417Hz:
+      *odr = 417.0f;
+      break;
+
+    case LSM6DSO_XL_ODR_833Hz:
+      *odr = 833.0f;
+      break;
+
+    case LSM6DSO_XL_ODR_1667Hz:
+      *odr = 1667.0f;
+      break;
+
+    case LSM6DSO_XL_ODR_3333Hz:
+      *odr = 3333.0f;
+      break;
+
+    case LSM6DSO_XL_ODR_6667Hz:
+      *odr = 6667.0f;
+      break;
+
+    default:
+      ret = 1;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+ * @brief  Set the LSM6DSO accelerometer sensor output data rate
+ * @param  odr the output data rate value to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_x_odr(float odr)
+{
+  /* Check if the component is enabled */
+  if (_x_is_enabled == 1U)
+  {
+    return set_x_odr_when_enabled(odr);
+  }
+  else
+  {
+    return set_x_odr_when_disabled(odr);
+  }
+}
+
+/**
+ * @brief  Set the LSM6DSO accelerometer sensor output data rate when enabled
+ * @param  odr the functional output data rate to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_x_odr_when_enabled(float odr)
+{
+  lsm6dso_odr_xl_t new_odr;
+
+  new_odr = (odr <=   12.5f) ? LSM6DSO_XL_ODR_12Hz5
+          : (odr <=   26.0f) ? LSM6DSO_XL_ODR_26Hz
+          : (odr <=   52.0f) ? LSM6DSO_XL_ODR_52Hz
+          : (odr <=  104.0f) ? LSM6DSO_XL_ODR_104Hz
+          : (odr <=  208.0f) ? LSM6DSO_XL_ODR_208Hz
+          : (odr <=  417.0f) ? LSM6DSO_XL_ODR_417Hz
+          : (odr <=  833.0f) ? LSM6DSO_XL_ODR_833Hz
+          : (odr <= 1667.0f) ? LSM6DSO_XL_ODR_1667Hz
+          : (odr <= 3333.0f) ? LSM6DSO_XL_ODR_3333Hz
+          :                    LSM6DSO_XL_ODR_6667Hz;
+
+  /* Output data rate selection. */
+  if (lsm6dso_xl_data_rate_set(&_reg_ctx, new_odr) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set the LSM6DSO accelerometer sensor output data rate when disabled
+ * @param  odr the functional output data rate to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_x_odr_when_disabled(float odr)
+{
+  _x_last_odr = (odr <=   12.5f) ? LSM6DSO_XL_ODR_12Hz5
+              : (odr <=   26.0f) ? LSM6DSO_XL_ODR_26Hz
+              : (odr <=   52.0f) ? LSM6DSO_XL_ODR_52Hz
+              : (odr <=  104.0f) ? LSM6DSO_XL_ODR_104Hz
+              : (odr <=  208.0f) ? LSM6DSO_XL_ODR_208Hz
+              : (odr <=  417.0f) ? LSM6DSO_XL_ODR_417Hz
+              : (odr <=  833.0f) ? LSM6DSO_XL_ODR_833Hz
+              : (odr <= 1667.0f) ? LSM6DSO_XL_ODR_1667Hz
+              : (odr <= 3333.0f) ? LSM6DSO_XL_ODR_3333Hz
+              :                    LSM6DSO_XL_ODR_6667Hz;
+
+  return 0;
+}
+
+
+/**
+ * @brief  Get the LSM6DSO accelerometer sensor full scale
+ * @param  full_scale pointer where the full scale is written
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_x_fs(float *full_scale)
+{
+  int ret = 0;
+  lsm6dso_fs_xl_t fs_low_level;
+
+  /* Read actual full scale selection from sensor. */
+  if (lsm6dso_xl_full_scale_get(&_reg_ctx, &fs_low_level) != 0)
+  {
+    return 1;
+  }
+
+  switch (fs_low_level)
+  {
+    case LSM6DSO_2g:
+      *full_scale =  2.0f;
+      break;
+
+    case LSM6DSO_4g:
+      *full_scale =  4.0f;
+      break;
+
+    case LSM6DSO_8g:
+      *full_scale =  8.0f;
+      break;
+
+    case LSM6DSO_16g:
+      *full_scale = 16.0f;
+      break;
+
+    default:
+      ret = 1;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+ * @brief  Set the LSM6DSO accelerometer sensor full scale
+ * @param  full_scale the functional full scale to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_x_fs(float full_scale)
+{
+  lsm6dso_fs_xl_t new_fs;
+
+  /* Seems like MISRA C-2012 rule 14.3a violation but only from single file statical analysis point of view because
+     the parameter passed to the function is not known at the moment of analysis */
+  new_fs = (full_scale <= 2.0f) ? LSM6DSO_2g
+         : (full_scale <= 4.0f) ? LSM6DSO_4g
+         : (full_scale <= 8.0f) ? LSM6DSO_8g
+         :                        LSM6DSO_16g;
+
+  if (lsm6dso_xl_full_scale_set(&_reg_ctx, new_fs) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Get the LSM6DSO accelerometer sensor raw axes
+ * @param  value pointer where the raw values of the axes are written
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_x_axes_raw(int16_t *value)
+{
+  axis3bit16_t data_raw;
+
+  /* Read raw data values. */
+  if (lsm6dso_acceleration_raw_get(&_reg_ctx, data_raw.u8bit) != 0)
+  {
+    return 1;
+  }
+
+  /* Format the data. */
+  value[0] = data_raw.i16bit[0];
+  value[1] = data_raw.i16bit[1];
+  value[2] = data_raw.i16bit[2];
+
+  return 0;
+}
+
+
+/**
+ * @brief  Get the LSM6DSO accelerometer sensor axes
+ * @param  acceleration pointer where the values of the axes are written
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_x_axes(int32_t *acceleration)
+{
+  axis3bit16_t data_raw;
+  float sensitivity = 0.0f;
+
+  /* Read raw data values. */
+  if (lsm6dso_acceleration_raw_get(&_reg_ctx, data_raw.u8bit) != 0)
+  {
+    return 1;
+  }
+
+  /* Get LSM6DSO actual sensitivity. */
+  if (get_x_sensitivity(&sensitivity) != 0)
+  {
+    return 1;
+  }
+
+  /* Calculate the data. */
+  acceleration[0] = (int32_t)((float)((float)data_raw.i16bit[0] * sensitivity));
+  acceleration[1] = (int32_t)((float)((float)data_raw.i16bit[1] * sensitivity));
+  acceleration[2] = (int32_t)((float)((float)data_raw.i16bit[2] * sensitivity));
+
+  return 0;
+}
+
+
+/**
+ * @brief  Enable the LSM6DSO gyroscope sensor
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::enable_g()
+{
+  /* Check if the component is already enabled */
+  if (_g_is_enabled == 1U)
+  {
+    return 0;
+  }
+
+  /* Output data rate selection. */
+  if (lsm6dso_gy_data_rate_set(&_reg_ctx, _g_last_odr) != 0)
+  {
+    return 1;
+  }
+
+  _g_is_enabled = 1;
+
+  return 0;
+}
+
+
+/**
+ * @brief  Disable the LSM6DSO gyroscope sensor
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::disable_g()
+{
+  /* Check if the component is already disabled */
+  if (_g_is_enabled == 0U)
+  {
+    return 0;
+  }
+
+  /* Get current output data rate. */
+  if (lsm6dso_gy_data_rate_get(&_reg_ctx, &_g_last_odr) != 0)
+  {
+    return 1;
+  }
+
+  /* Output data rate selection - power down. */
+  if (lsm6dso_gy_data_rate_set(&_reg_ctx, LSM6DSO_GY_ODR_OFF) != 0)
+  {
+    return 1;
+  }
+
+  _g_is_enabled = 0;
+
+  return 0;
+}
+
+/**
+ * @brief  Get the LSM6DSO gyroscope sensor sensitivity
+ * @param  sensitivity pointer where the sensitivity is written
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_g_sensitivity(float *sensitivity)
+{
+  int ret = 0;
+  lsm6dso_fs_g_t full_scale;
+
+  /* Read actual full scale selection from sensor. */
+  if (lsm6dso_gy_full_scale_get(&_reg_ctx, &full_scale) != 0)
+  {
+    return 1;
+  }
+
+  /* Store the sensitivity based on actual full scale. */
+  switch (full_scale)
+  {
+    case LSM6DSO_125dps:
+      *sensitivity = LSM6DSO_GYRO_SENSITIVITY_FS_125DPS;
+      break;
+
+    case LSM6DSO_250dps:
+      *sensitivity = LSM6DSO_GYRO_SENSITIVITY_FS_250DPS;
+      break;
+
+    case LSM6DSO_500dps:
+      *sensitivity = LSM6DSO_GYRO_SENSITIVITY_FS_500DPS;
+      break;
+
+    case LSM6DSO_1000dps:
+      *sensitivity = LSM6DSO_GYRO_SENSITIVITY_FS_1000DPS;
+      break;
+
+    case LSM6DSO_2000dps:
+      *sensitivity = LSM6DSO_GYRO_SENSITIVITY_FS_2000DPS;
+      break;
+
+    default:
+      ret = 1;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+ * @brief  Get the LSM6DSO gyroscope sensor output data rate
+ * @param  odr pointer where the output data rate is written
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_g_odr(float *odr)
+{
+  int ret = 0;
+  lsm6dso_odr_g_t odr_low_level;
+
+  /* Get current output data rate. */
+  if (lsm6dso_gy_data_rate_get(&_reg_ctx, &odr_low_level) != 0)
+  {
+    return 1;
+  }
+
+  switch (odr_low_level)
+  {
+    case LSM6DSO_GY_ODR_OFF:
+      *odr = 0.0f;
+      break;
+
+    case LSM6DSO_GY_ODR_12Hz5:
+      *odr = 12.5f;
+      break;
+
+    case LSM6DSO_GY_ODR_26Hz:
+      *odr = 26.0f;
+      break;
+
+    case LSM6DSO_GY_ODR_52Hz:
+      *odr = 52.0f;
+      break;
+
+    case LSM6DSO_GY_ODR_104Hz:
+      *odr = 104.0f;
+      break;
+
+    case LSM6DSO_GY_ODR_208Hz:
+      *odr = 208.0f;
+      break;
+
+    case LSM6DSO_GY_ODR_417Hz:
+      *odr = 417.0f;
+      break;
+
+    case LSM6DSO_GY_ODR_833Hz:
+      *odr = 833.0f;
+      break;
+
+    case LSM6DSO_GY_ODR_1667Hz:
+      *odr =  1667.0f;
+      break;
+
+    case LSM6DSO_GY_ODR_3333Hz:
+      *odr =  3333.0f;
+      break;
+
+    case LSM6DSO_GY_ODR_6667Hz:
+      *odr =  6667.0f;
+      break;
+
+    default:
+      ret = 1;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+ * @brief  Set the LSM6DSO gyroscope sensor output data rate
+ * @param  odr the output data rate value to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_g_odr(float odr)
+{
+  /* Check if the component is enabled */
+  if (_g_is_enabled == 1U)
+  {
+    return set_g_odr_when_enabled(odr);
+  }
+  else
+  {
+    return set_g_odr_when_disabled(odr);
+  }
+}
+
+/**
+ * @brief  Set the LSM6DSO gyroscope sensor output data rate when enabled
+ * @param  odr the functional output data rate to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_g_odr_when_enabled(float odr)
+{
+  lsm6dso_odr_g_t new_odr;
+
+  new_odr = (odr <=   12.5f) ? LSM6DSO_GY_ODR_12Hz5
+          : (odr <=   26.0f) ? LSM6DSO_GY_ODR_26Hz
+          : (odr <=   52.0f) ? LSM6DSO_GY_ODR_52Hz
+          : (odr <=  104.0f) ? LSM6DSO_GY_ODR_104Hz
+          : (odr <=  208.0f) ? LSM6DSO_GY_ODR_208Hz
+          : (odr <=  417.0f) ? LSM6DSO_GY_ODR_417Hz
+          : (odr <=  833.0f) ? LSM6DSO_GY_ODR_833Hz
+          : (odr <= 1667.0f) ? LSM6DSO_GY_ODR_1667Hz
+          : (odr <= 3333.0f) ? LSM6DSO_GY_ODR_3333Hz
+          :                    LSM6DSO_GY_ODR_6667Hz;
+
+  /* Output data rate selection. */
+  if (lsm6dso_gy_data_rate_set(&_reg_ctx, new_odr) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set the LSM6DSO gyroscope sensor output data rate when disabled
+ * @param  odr the functional output data rate to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_g_odr_when_disabled(float odr)
+{
+  _g_last_odr = (odr <=   12.5f) ? LSM6DSO_GY_ODR_12Hz5
+              : (odr <=   26.0f) ? LSM6DSO_GY_ODR_26Hz
+              : (odr <=   52.0f) ? LSM6DSO_GY_ODR_52Hz
+              : (odr <=  104.0f) ? LSM6DSO_GY_ODR_104Hz
+              : (odr <=  208.0f) ? LSM6DSO_GY_ODR_208Hz
+              : (odr <=  417.0f) ? LSM6DSO_GY_ODR_417Hz
+              : (odr <=  833.0f) ? LSM6DSO_GY_ODR_833Hz
+              : (odr <= 1667.0f) ? LSM6DSO_GY_ODR_1667Hz
+              : (odr <= 3333.0f) ? LSM6DSO_GY_ODR_3333Hz
+              :                    LSM6DSO_GY_ODR_6667Hz;
+
+  return 0;
+}
+
+
+/**
+ * @brief  Get the LSM6DSO gyroscope sensor full scale
+ * @param  full_scale pointer where the full scale is written
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_g_fs(float *full_scale)
+{
+  int ret = 0;
+  lsm6dso_fs_g_t fs_low_level;
+
+  /* Read actual full scale selection from sensor. */
+  if (lsm6dso_gy_full_scale_get(&_reg_ctx, &fs_low_level) != 0)
+  {
+    return 1;
+  }
+
+  switch (fs_low_level)
+  {
+    case LSM6DSO_125dps:
+      *full_scale =  125.0f;
+      break;
+
+    case LSM6DSO_250dps:
+      *full_scale =  250.0f;
+      break;
+
+    case LSM6DSO_500dps:
+      *full_scale =  500.0f;
+      break;
+
+    case LSM6DSO_1000dps:
+      *full_scale = 1000.0f;
+      break;
+
+    case LSM6DSO_2000dps:
+      *full_scale = 2000.0f;
+      break;
+
+    default:
+      ret = 1;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+ * @brief  Set the LSM6DSO gyroscope sensor full scale
+ * @param  full_scale the functional full scale to be set
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_g_fs(float full_scale)
+{
+  lsm6dso_fs_g_t new_fs;
+
+  new_fs = (full_scale <= 125.0f)  ? LSM6DSO_125dps
+         : (full_scale <= 250.0f)  ? LSM6DSO_250dps
+         : (full_scale <= 500.0f)  ? LSM6DSO_500dps
+         : (full_scale <= 1000.0f) ? LSM6DSO_1000dps
+         :                           LSM6DSO_2000dps;
+
+  if (lsm6dso_gy_full_scale_set(&_reg_ctx, new_fs) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Get the LSM6DSO gyroscope sensor raw axes
+ * @param  value pointer where the raw values of the axes are written
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_g_axes_raw(int16_t *value)
+{
+  axis3bit16_t data_raw;
+
+  /* Read raw data values. */
+  if (lsm6dso_angular_rate_raw_get(&_reg_ctx, data_raw.u8bit) != 0)
+  {
+    return 1;
+  }
+
+  /* Format the data. */
+  value[0] = data_raw.i16bit[0];
+  value[1] = data_raw.i16bit[1];
+  value[2] = data_raw.i16bit[2];
+
+  return 0;
+}
+
+
+/**
+ * @brief  Get the LSM6DSO gyroscope sensor axes
+ * @param  angular_rate pointer where the values of the axes are written
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_g_axes(int32_t *angular_rate)
+{
+  axis3bit16_t data_raw;
+  float sensitivity;
+
+  /* Read raw data values. */
+  if (lsm6dso_angular_rate_raw_get(&_reg_ctx, data_raw.u8bit) != 0)
+  {
+    return 1;
+  }
+
+  /* Get LSM6DSO actual sensitivity. */
+  if (get_g_sensitivity(&sensitivity) != 0)
+  {
+    return 1;
+  }
+
+  /* Calculate the data. */
+  angular_rate[0] = (int32_t)((float)((float)data_raw.i16bit[0] * sensitivity));
+  angular_rate[1] = (int32_t)((float)((float)data_raw.i16bit[1] * sensitivity));
+  angular_rate[2] = (int32_t)((float)((float)data_raw.i16bit[2] * sensitivity));
+
+  return 0;
+}
+
+
+/**
+ * @brief  Get the LSM6DSO register value
+ * @param  reg address to be read
+ * @param  data pointer where the value is written
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::read_reg(uint8_t reg, uint8_t *data)
+{
+  if (lsm6dso_read_reg(&_reg_ctx, reg, data, 1) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+
+/**
+ * @brief  Set the LSM6DSO register value
+ * @param  reg address to be written
+ * @param  data value to be written
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::write_reg(uint8_t reg, uint8_t data)
+{
+  if (lsm6dso_write_reg(&_reg_ctx, reg, &data, 1) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set the interrupt latch
+ * @param  status value to be written
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_interrupt_latch(uint8_t status)
+{
+  if (status > 1U)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_int_notification_set(&_reg_ctx, (lsm6dso_lir_t)status) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Enable free fall detection
+ * @param  int_pin interrupt pin line to be used
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::enable_free_fall_detection(LSM6DSO_Interrupt_Pin_t int_pin)
+{
+  int ret = 0;
+  lsm6dso_pin_int1_route_t val1;
+  lsm6dso_pin_int2_route_t val2;
+
+  /* Output Data Rate selection */
+  if (set_x_odr(416.0f) != 0)
+  {
+    return 1;
+  }
+
+  /* Full scale selection */
+  if (set_x_fs(2.0f) != 0)
+  {
+    return 1;
+  }
+
+  /* FF_DUR setting */
+  if (lsm6dso_ff_dur_set(&_reg_ctx, 0x06) != 0)
+  {
+    return 1;
+  }
+
+  /* WAKE_DUR setting */
+  if (lsm6dso_wkup_dur_set(&_reg_ctx, 0x00) != 0)
+  {
+    return 1;
+  }
+
+  /* SLEEP_DUR setting */
+  if (lsm6dso_act_sleep_dur_set(&_reg_ctx, 0x00) != 0)
+  {
+    return 1;
+  }
+
+  /* FF_THS setting */
+  if (lsm6dso_ff_threshold_set(&_reg_ctx, LSM6DSO_FF_TSH_312mg) != 0)
+  {
+    return 1;
+  }
+
+  /* Enable free fall event on either INT1 or INT2 pin */
+  switch (int_pin)
+  {
+    case LSM6DSO_INT1_PIN:
+      if (lsm6dso_pin_int1_route_get(&_reg_ctx, &val1) != 0)
+      {
+        return 1;
+      }
+
+      val1.md1_cfg.int1_ff = PROPERTY_ENABLE;
+
+      if (lsm6dso_pin_int1_route_set(&_reg_ctx, &val1) != 0)
+      {
+        return 1;
+      }
+      break;
+
+    case LSM6DSO_INT2_PIN:
+      if (lsm6dso_pin_int2_route_get(&_reg_ctx, &val2) != 0)
+      {
+        return 1;
+      }
+
+      val2.md2_cfg.int2_ff = PROPERTY_ENABLE;
+
+      if (lsm6dso_pin_int2_route_set(&_reg_ctx, &val2) != 0)
+      {
+        return 1;
+      }
+      break;
+
+    default:
+      ret = 1;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+ * @brief  Disable free fall detection
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::disable_free_fall_detection()
+{
+  lsm6dso_pin_int1_route_t val1;
+  lsm6dso_pin_int2_route_t val2;
+
+  /* Disable free fall event on both INT1 and INT2 pins */
+  if (lsm6dso_pin_int1_route_get(&_reg_ctx, &val1) != 0)
+  {
+    return 1;
+  }
+
+  val1.md1_cfg.int1_ff = PROPERTY_DISABLE;
+
+  if (lsm6dso_pin_int1_route_set(&_reg_ctx, &val1) != 0)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_pin_int2_route_get(&_reg_ctx, &val2) != 0)
+  {
+    return 1;
+  }
+
+  val2.md2_cfg.int2_ff = PROPERTY_DISABLE;
+
+  if (lsm6dso_pin_int2_route_set(&_reg_ctx, &val2) != 0)
+  {
+    return 1;
+  }
+
+  /* FF_DUR setting */
+  if (lsm6dso_ff_dur_set(&_reg_ctx, 0x00) != 0)
+  {
+    return 1;
+  }
+
+  /* FF_THS setting */
+  if (lsm6dso_ff_threshold_set(&_reg_ctx, LSM6DSO_FF_TSH_156mg) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set free fall threshold
+ * @param  thr free fall detection threshold
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_free_fall_threshold(uint8_t thr)
+{
+  if (lsm6dso_ff_threshold_set(&_reg_ctx, (lsm6dso_ff_ths_t)thr) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+
+/**
+ * @brief  Set free fall duration
+ * @param  dur free fall detection duration
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_free_fall_duration(uint8_t dur)
+{
+  if (lsm6dso_ff_dur_set(&_reg_ctx, dur) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+
+/**
+ * @brief  Enable pedometer
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::enable_pedometer()
+{
+    lsm6dso_pin_int1_route_t val;
+
+  /* Output Data Rate selection */
+  if (set_x_odr(26.0f) != 0)
+  {
+    return 1;
+  }
+
+  /* Full scale selection */
+  if (set_x_fs(2.0f) != 0)
+  {
+    return 1;
+  }
+
+  /* Enable pedometer algorithm. */
+  if (lsm6dso_pedo_sens_set(&_reg_ctx, LSM6DSO_PEDO_BASE_MODE) != 0)
+  {
+    return 1;
+  }
+
+  /* Enable step detector on INT1 pin */
+  if (lsm6dso_pin_int1_route_get(&_reg_ctx, &val) != 0)
+  {
+    return 1;
+  }
+
+  val.emb_func_int1.int1_step_detector = PROPERTY_ENABLE;
+
+  if (lsm6dso_pin_int1_route_set(&_reg_ctx, &val) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Disable pedometer
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::disable_pedometer()
+{
+  lsm6dso_pin_int1_route_t val1;
+
+  /* Disable step detector on INT1 pin */
+  if (lsm6dso_pin_int1_route_get(&_reg_ctx, &val1) != 0)
+  {
+    return 1;
+  }
+
+  val1.emb_func_int1.int1_step_detector = PROPERTY_DISABLE;
+
+  if (lsm6dso_pin_int1_route_set(&_reg_ctx, &val1) != 0)
+  {
+    return 1;
+  }
+
+  /* Disable pedometer algorithm. */
+  if (lsm6dso_pedo_sens_set(&_reg_ctx, LSM6DSO_PEDO_DISABLE) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Get step count
+ * @param  step_count step counter
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_step_counter(uint16_t *step_count)
+{
+  if (lsm6dso_number_of_steps_get(&_reg_ctx, (uint8_t *)step_count) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Enable step counter reset
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::reset_step_counter()
+{
+  if (lsm6dso_steps_reset(&_reg_ctx) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Enable tilt detection
+ * @param  int_pin interrupt pin line to be used
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::enable_tilt_detection(LSM6DSO_Interrupt_Pin_t int_pin)
+{
+  int ret = 0;
+  lsm6dso_pin_int1_route_t val1;
+  lsm6dso_pin_int2_route_t val2;
+
+  /* Output Data Rate selection */
+  if (set_x_odr(26.0f) != 0)
+  {
+    return 1;
+  }
+
+  /* Full scale selection */
+  if (set_x_fs(2.0f) != 0)
+  {
+    return 1;
+  }
+
+  /* Enable tilt calculation. */
+  if (lsm6dso_tilt_sens_set(&_reg_ctx, PROPERTY_ENABLE) != 0)
+  {
+    return 1;
+  }
+
+  /* Enable tilt event on either INT1 or INT2 pin */
+  switch (int_pin)
+  {
+    case LSM6DSO_INT1_PIN:
+      if (lsm6dso_pin_int1_route_get(&_reg_ctx, &val1) != 0)
+      {
+        return 1;
+      }
+
+      val1.emb_func_int1.int1_tilt = PROPERTY_ENABLE;
+
+      if (lsm6dso_pin_int1_route_set(&_reg_ctx, &val1) != 0)
+      {
+        return 1;
+      }
+      break;
+
+    case LSM6DSO_INT2_PIN:
+      if (lsm6dso_pin_int2_route_get(&_reg_ctx, &val2) != 0)
+      {
+        return 1;
+      }
+
+      val2.emb_func_int2.int2_tilt = PROPERTY_ENABLE;
+
+      if (lsm6dso_pin_int2_route_set(&_reg_ctx, &val2) != 0)
+      {
+        return 1;
+      }
+      break;
+
+    default:
+      ret = 1;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+ * @brief  Disable tilt detection
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::disable_tilt_detection()
+{
+  lsm6dso_pin_int1_route_t val1;
+  lsm6dso_pin_int2_route_t val2;
+
+  /* Disable tilt event on both INT1 and INT2 pins */
+  if (lsm6dso_pin_int1_route_get(&_reg_ctx, &val1) != 0)
+  {
+    return 1;
+  }
+
+  val1.emb_func_int1.int1_tilt = PROPERTY_DISABLE;
+
+  if (lsm6dso_pin_int1_route_set(&_reg_ctx, &val1) != 0)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_pin_int2_route_get(&_reg_ctx, &val2) != 0)
+  {
+    return 1;
+  }
+
+  val2.emb_func_int2.int2_tilt = PROPERTY_DISABLE;
+
+  if (lsm6dso_pin_int2_route_set(&_reg_ctx, &val2) != 0)
+  {
+    return 1;
+  }
+
+  /* Disable tilt calculation. */
+  if (lsm6dso_tilt_sens_set(&_reg_ctx, PROPERTY_DISABLE) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Enable wake up detection
+ * @param  int_pin interrupt pin line to be used
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::enable_wake_up_detection(LSM6DSO_Interrupt_Pin_t int_pin)
+{
+  int ret = 0;
+  lsm6dso_pin_int1_route_t val1;
+  lsm6dso_pin_int2_route_t val2;
+
+  /* Output Data Rate selection */
+  if (set_x_odr(416.0f) != 0)
+  {
+    return 1;
+  }
+
+  /* Full scale selection */
+  if (set_x_fs(2.0f) != 0)
+  {
+    return 1;
+  }
+
+  /* WAKE_DUR setting */
+  if (lsm6dso_wkup_dur_set(&_reg_ctx, 0x00) != 0)
+  {
+    return 1;
+  }
+
+  /* Set wake up threshold. */
+  if (lsm6dso_wkup_threshold_set(&_reg_ctx, 0x02) != 0)
+  {
+    return 1;
+  }
+
+  /* Enable wake up event on either INT1 or INT2 pin */
+  switch (int_pin)
+  {
+    case LSM6DSO_INT1_PIN:
+      if (lsm6dso_pin_int1_route_get(&_reg_ctx, &val1) != 0)
+      {
+        return 1;
+      }
+
+      val1.md1_cfg.int1_wu = PROPERTY_ENABLE;
+
+      if (lsm6dso_pin_int1_route_set(&_reg_ctx, &val1) != 0)
+      {
+        return 1;
+      }
+      break;
+
+    case LSM6DSO_INT2_PIN:
+      if (lsm6dso_pin_int2_route_get(&_reg_ctx, &val2) != 0)
+      {
+        return 1;
+      }
+
+      val2.md2_cfg.int2_wu = PROPERTY_ENABLE;
+
+      if (lsm6dso_pin_int2_route_set(&_reg_ctx, &val2) != 0)
+      {
+        return 1;
+      }
+      break;
+
+    default:
+      ret = 1;
+      break;
+  }
+
+  return ret;
+}
+
+
+/**
+ * @brief  Disable wake up detection
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::disable_wake_up_detection()
+{
+    lsm6dso_pin_int1_route_t val1;
+    lsm6dso_pin_int2_route_t val2;
+
+  /* Disable wake up event on both INT1 and INT2 pins */
+  if (lsm6dso_pin_int1_route_get(&_reg_ctx, &val1) != 0)
+  {
+    return 1;
+  }
+
+  val1.md1_cfg.int1_wu = PROPERTY_DISABLE;
+
+  if (lsm6dso_pin_int1_route_set(&_reg_ctx, &val1) != 0)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_pin_int2_route_get(&_reg_ctx, &val2) != 0)
+  {
+    return 1;
+  }
+
+  val2.md2_cfg.int2_wu = PROPERTY_DISABLE;
+
+  if (lsm6dso_pin_int2_route_set(&_reg_ctx, &val2) != 0)
+  {
+    return 1;
+  }
+
+  /* Reset wake up threshold. */
+  if (lsm6dso_wkup_threshold_set(&_reg_ctx, 0x00) != 0)
+  {
+    return 1;
+  }
+
+  /* WAKE_DUR setting */
+  if (lsm6dso_wkup_dur_set(&_reg_ctx, 0x00) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set wake up threshold
+ * @param  thr wake up detection threshold
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_wake_up_threshold(uint8_t thr)
+{
+  /* Set wake up threshold. */
+  if (lsm6dso_wkup_threshold_set(&_reg_ctx, thr) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set wake up duration
+ * @param  dur wake up detection duration
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_wake_up_duration(uint8_t dur)
+{
+  /* Set wake up duration. */
+  if (lsm6dso_wkup_dur_set(&_reg_ctx, dur) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Enable single tap detection
+ * @param  int_pin interrupt pin line to be used
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::enable_single_tap_detection(LSM6DSO_Interrupt_Pin_t int_pin)
+{
+  int ret = 0;
+  lsm6dso_pin_int1_route_t val1;
+  lsm6dso_pin_int2_route_t val2;
+
+  /* Output Data Rate selection */
+  if (set_x_odr(416.0f) != 0)
+  {
+    return 1;
+  }
+
+  /* Full scale selection */
+  if (set_x_fs(2.0f) != 0)
+  {
+    return 1;
+  }
+
+  /* Enable X direction in tap recognition. */
+  if (lsm6dso_tap_detection_on_x_set(&_reg_ctx, PROPERTY_ENABLE) != 0)
+  {
+    return 1;
+  }
+
+  /* Enable Y direction in tap recognition. */
+  if (lsm6dso_tap_detection_on_y_set(&_reg_ctx, PROPERTY_ENABLE) != 0)
+  {
+    return 1;
+  }
+
+  /* Enable Z direction in tap recognition. */
+  if (lsm6dso_tap_detection_on_z_set(&_reg_ctx, PROPERTY_ENABLE) != 0)
+  {
+    return 1;
+  }
+
+  /* Set tap threshold. */
+  if (lsm6dso_tap_threshold_x_set(&_reg_ctx, 0x08) != 0)
+  {
+    return 1;
+  }
+
+  /* Set tap shock time window. */
+  if (lsm6dso_tap_shock_set(&_reg_ctx, 0x02) != 0)
+  {
+    return 1;
+  }
+
+  /* Set tap quiet time window. */
+  if (lsm6dso_tap_quiet_set(&_reg_ctx, 0x01) != 0)
+  {
+    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 single tap event on either INT1 or INT2 pin */
+  switch (int_pin)
+  {
+    case LSM6DSO_INT1_PIN:
+      if (lsm6dso_pin_int1_route_get(&_reg_ctx, &val1) != 0)
+      {
+        return 1;
+      }
+
+      val1.md1_cfg.int1_single_tap = PROPERTY_ENABLE;
+
+      if (lsm6dso_pin_int1_route_set(&_reg_ctx, &val1) != 0)
+      {
+        return 1;
+      }
+      break;
+
+    case LSM6DSO_INT2_PIN:
+      if (lsm6dso_pin_int2_route_get(&_reg_ctx, &val2) != 0)
+      {
+        return 1;
+      }
+
+      val2.md2_cfg.int2_single_tap = PROPERTY_ENABLE;
+
+      if (lsm6dso_pin_int2_route_set(&_reg_ctx, &val2) != 0)
+      {
+        return 1;
+      }
+      break;
+
+    default:
+      ret = 1;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+ * @brief  Disable single tap detection
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::disable_single_tap_detection()
+{
+    lsm6dso_pin_int1_route_t val1;
+    lsm6dso_pin_int2_route_t val2;
+
+  /* Disable single tap event on both INT1 and INT2 pins */
+  if (lsm6dso_pin_int1_route_get(&_reg_ctx, &val1) != 0)
+  {
+    return 1;
+  }
+
+  val1.md1_cfg.int1_single_tap = PROPERTY_DISABLE;
+
+  if (lsm6dso_pin_int1_route_set(&_reg_ctx, &val1) != 0)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_pin_int2_route_get(&_reg_ctx, &val2) != 0)
+  {
+    return 1;
+  }
+
+  val2.md2_cfg.int2_single_tap = PROPERTY_DISABLE;
+
+  if (lsm6dso_pin_int2_route_set(&_reg_ctx, &val2) != 0)
+  {
+    return 1;
+  }
+
+  /* Reset tap quiet time window. */
+  if (lsm6dso_tap_quiet_set(&_reg_ctx, 0x00) != 0)
+  {
+    return 1;
+  }
+
+  /* Reset tap shock time window. */
+  if (lsm6dso_tap_shock_set(&_reg_ctx, 0x00) != 0)
+  {
+    return 1;
+  }
+
+  /* Reset tap threshold. */
+  if (lsm6dso_tap_threshold_x_set(&_reg_ctx, 0x00) != 0)
+  {
+    return 1;
+  }
+
+  /* Disable Z direction in tap recognition. */
+  if (lsm6dso_tap_detection_on_z_set(&_reg_ctx, PROPERTY_DISABLE) != 0)
+  {
+    return 1;
+  }
+
+  /* Disable Y direction in tap recognition. */
+  if (lsm6dso_tap_detection_on_y_set(&_reg_ctx, PROPERTY_DISABLE) != 0)
+  {
+    return 1;
+  }
+
+  /* Disable X direction in tap recognition. */
+  if (lsm6dso_tap_detection_on_x_set(&_reg_ctx, PROPERTY_DISABLE) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Enable double tap detection
+ * @param  int_pin interrupt pin line to be used
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::enable_double_tap_detection(LSM6DSO_Interrupt_Pin_t int_pin)
+{
+  int ret = 0;
+  lsm6dso_pin_int1_route_t val1;
+  lsm6dso_pin_int2_route_t val2;
+
+  /* Output Data Rate selection */
+  if (set_x_odr(416.0f) != 0)
+  {
+    return 1;
+  }
+
+  /* Full scale selection */
+  if (set_x_fs(2.0f) != 0)
+  {
+    return 1;
+  }
+
+  /* Enable X direction in tap recognition. */
+  if (lsm6dso_tap_detection_on_x_set(&_reg_ctx, PROPERTY_ENABLE) != 0)
+  {
+    return 1;
+  }
+
+  /* Enable Y direction in tap recognition. */
+  if (lsm6dso_tap_detection_on_y_set(&_reg_ctx, PROPERTY_ENABLE) != 0)
+  {
+    return 1;
+  }
+
+  /* Enable Z direction in tap recognition. */
+  if (lsm6dso_tap_detection_on_z_set(&_reg_ctx, PROPERTY_ENABLE) != 0)
+  {
+    return 1;
+  }
+
+  /* Set tap threshold. */
+  if (lsm6dso_tap_threshold_x_set(&_reg_ctx, 0x08) != 0)
+  {
+    return 1;
+  }
+
+  /* Set tap shock time window. */
+  if (lsm6dso_tap_shock_set(&_reg_ctx, 0x03) != 0)
+  {
+    return 1;
+  }
+
+  /* Set tap quiet time window. */
+  if (lsm6dso_tap_quiet_set(&_reg_ctx, 0x03) != 0)
+  {
+    return 1;
+  }
+
+  /* Set tap duration time window. */
+  if (lsm6dso_tap_dur_set(&_reg_ctx, 0x08) != 0)
+  {
+    return 1;
+  }
+
+  /* Single and double tap enabled. */
+  if (lsm6dso_tap_mode_set(&_reg_ctx, LSM6DSO_BOTH_SINGLE_DOUBLE) != 0)
+  {
+    return 1;
+  }
+
+  /* Enable double tap event on either INT1 or INT2 pin */
+  switch (int_pin)
+  {
+    case LSM6DSO_INT1_PIN:
+      if (lsm6dso_pin_int1_route_get(&_reg_ctx, &val1) != 0)
+      {
+        return 1;
+      }
+
+      val1.md1_cfg.int1_double_tap = PROPERTY_ENABLE;
+
+      if (lsm6dso_pin_int1_route_set(&_reg_ctx, &val1) != 0)
+      {
+        return 1;
+      }
+      break;
+
+    case LSM6DSO_INT2_PIN:
+      if (lsm6dso_pin_int2_route_get(&_reg_ctx, &val2) != 0)
+      {
+        return 1;
+      }
+
+      val2.md2_cfg.int2_double_tap = PROPERTY_ENABLE;
+
+      if (lsm6dso_pin_int2_route_set(&_reg_ctx, &val2) != 0)
+      {
+        return 1;
+      }
+      break;
+
+    default:
+      ret = 1;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+ * @brief  Disable double tap detection
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::disable_double_tap_detection()
+{
+  lsm6dso_pin_int1_route_t val1;
+  lsm6dso_pin_int2_route_t val2;
+
+  /* Disable double tap event on both INT1 and INT2 pins */
+  if (lsm6dso_pin_int1_route_get(&_reg_ctx, &val1) != 0)
+  {
+    return 1;
+  }
+
+  val1.md1_cfg.int1_double_tap = PROPERTY_DISABLE;
+
+  if (lsm6dso_pin_int1_route_set(&_reg_ctx, &val1) != 0)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_pin_int2_route_get(&_reg_ctx, &val2) != 0)
+  {
+    return 1;
+  }
+
+  val2.md2_cfg.int2_double_tap = PROPERTY_DISABLE;
+
+  if (lsm6dso_pin_int2_route_set(&_reg_ctx, &val2) != 0)
+  {
+    return 1;
+  }
+
+  /* Only single tap enabled. */
+  if (lsm6dso_tap_mode_set(&_reg_ctx, LSM6DSO_ONLY_SINGLE) != 0)
+  {
+    return 1;
+  }
+
+  /* Reset tap duration time window. */
+  if (lsm6dso_tap_dur_set(&_reg_ctx, 0x00) != 0)
+  {
+    return 1;
+  }
+
+  /* Reset tap quiet time window. */
+  if (lsm6dso_tap_quiet_set(&_reg_ctx, 0x00) != 0)
+  {
+    return 1;
+  }
+
+  /* Reset tap shock time window. */
+  if (lsm6dso_tap_shock_set(&_reg_ctx, 0x00) != 0)
+  {
+    return 1;
+  }
+
+  /* Reset tap threshold. */
+  if (lsm6dso_tap_threshold_x_set(&_reg_ctx, 0x00) != 0)
+  {
+    return 1;
+  }
+
+  /* Disable Z direction in tap recognition. */
+  if (lsm6dso_tap_detection_on_z_set(&_reg_ctx, PROPERTY_DISABLE) != 0)
+  {
+    return 1;
+  }
+
+  /* Disable Y direction in tap recognition. */
+  if (lsm6dso_tap_detection_on_y_set(&_reg_ctx, PROPERTY_DISABLE) != 0)
+  {
+    return 1;
+  }
+
+  /* Disable X direction in tap recognition. */
+  if (lsm6dso_tap_detection_on_x_set(&_reg_ctx, PROPERTY_DISABLE) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set tap threshold
+ * @param  thr tap threshold
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_tap_threshold(uint8_t thr)
+{
+  /* Set tap threshold. */
+  if (lsm6dso_tap_threshold_x_set(&_reg_ctx, thr) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set tap shock time
+ * @param  time tap shock time
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_tap_shock_time(uint8_t time)
+{
+  /* Set tap shock time window. */
+  if (lsm6dso_tap_shock_set(&_reg_ctx, time) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set tap quiet time
+ * @param  time tap quiet time
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_tap_quiet_time(uint8_t time)
+{
+  /* Set tap quiet time window. */
+  if (lsm6dso_tap_quiet_set(&_reg_ctx, time) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set tap duration time
+ * @param  time tap duration time
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_tap_duration_time(uint8_t time)
+{
+  /* Set tap duration time window. */
+  if (lsm6dso_tap_dur_set(&_reg_ctx, time) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Enable 6D orientation detection
+ * @param  int_pin interrupt pin line to be used
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::enable_6d_orientation(LSM6DSO_Interrupt_Pin_t int_pin)
+{
+  int ret = 0;
+  lsm6dso_pin_int1_route_t val1;
+  lsm6dso_pin_int2_route_t val2;
+
+  /* Output Data Rate selection */
+  if (set_x_odr(416.0f) != 0)
+  {
+    return 1;
+  }
+
+  /* Full scale selection */
+  if (set_x_fs(2.0f) != 0)
+  {
+    return 1;
+  }
+
+  /* 6D orientation enabled. */
+  if (lsm6dso_6d_threshold_set(&_reg_ctx, LSM6DSO_DEG_60) != 0)
+  {
+    return 1;
+  }
+
+  /* Enable 6D orientation event on either INT1 or INT2 pin */
+  switch (int_pin)
+  {
+    case LSM6DSO_INT1_PIN:
+      if (lsm6dso_pin_int1_route_get(&_reg_ctx, &val1) != 0)
+      {
+        return 1;
+      }
+
+      val1.md1_cfg.int1_6d = PROPERTY_ENABLE;
+
+      if (lsm6dso_pin_int1_route_set(&_reg_ctx, &val1) != 0)
+      {
+        return 1;
+      }
+      break;
+
+    case LSM6DSO_INT2_PIN:
+      if (lsm6dso_pin_int2_route_get(&_reg_ctx, &val2) != 0)
+      {
+        return 1;
+      }
+
+      val2.md2_cfg.int2_6d = PROPERTY_ENABLE;
+
+      if (lsm6dso_pin_int2_route_set(&_reg_ctx, &val2) != 0)
+      {
+        return 1;
+      }
+      break;
+
+    default:
+      ret = 1;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+ * @brief  Disable 6D orientation detection
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::disable_6d_orientation()
+{
+  lsm6dso_pin_int1_route_t val1;
+  lsm6dso_pin_int2_route_t val2;
+
+  /* Disable 6D orientation event on both INT1 and INT2 pins */
+  if (lsm6dso_pin_int1_route_get(&_reg_ctx, &val1) != 0)
+  {
+    return 1;
+  }
+
+  val1.md1_cfg.int1_6d = PROPERTY_DISABLE;
+
+  if (lsm6dso_pin_int1_route_set(&_reg_ctx, &val1) != 0)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_pin_int2_route_get(&_reg_ctx, &val2) != 0)
+  {
+    return 1;
+  }
+
+  val2.md2_cfg.int2_6d = PROPERTY_DISABLE;
+
+  if (lsm6dso_pin_int2_route_set(&_reg_ctx, &val2) != 0)
+  {
+    return 1;
+  }
+
+  /* Reset 6D orientation. */
+  if (lsm6dso_6d_threshold_set(&_reg_ctx, LSM6DSO_DEG_80) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set 6D orientation threshold
+ * @param  thr 6D Orientation detection threshold
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_6d_orientation_threshold(uint8_t thr)
+{
+  if (lsm6dso_6d_threshold_set(&_reg_ctx, (lsm6dso_sixd_ths_t)thr) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Get the status of XLow orientation
+ * @param  xl the status of XLow orientation
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_6d_orientation_xl(uint8_t *xl)
+{
+  lsm6dso_d6d_src_t data;
+
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_D6D_SRC, (uint8_t *)&data, 1) != 0)
+  {
+    return 1;
+  }
+
+  *xl = data.xl;
+
+  return 0;
+}
+
+/**
+ * @brief  Get the status of XHigh orientation
+ * @param  xh the status of XHigh orientation
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_6d_orientation_xh(uint8_t *xh)
+{
+  lsm6dso_d6d_src_t data;
+
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_D6D_SRC, (uint8_t *)&data, 1) != 0)
+  {
+    return 1;
+  }
+
+  *xh = data.xh;
+
+  return 0;
+}
+
+/**
+ * @brief  Get the status of YLow orientation
+ * @param  yl the status of YLow orientation
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_6d_orientation_yl(uint8_t *yl)
+{
+  lsm6dso_d6d_src_t data;
+
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_D6D_SRC, (uint8_t *)&data, 1) != 0)
+  {
+    return 1;
+  }
+
+  *yl = data.yl;
+
+  return 0;
+}
+
+/**
+ * @brief  Get the status of YHigh orientation
+ * @param  yh the status of YHigh orientation
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_6d_orientation_yh(uint8_t *yh)
+{
+  lsm6dso_d6d_src_t data;
+
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_D6D_SRC, (uint8_t *)&data, 1) != 0)
+  {
+    return 1;
+  }
+
+  *yh = data.yh;
+
+  return 0;
+}
+
+/**
+ * @brief  Get the status of ZLow orientation
+ * @param  zl the status of ZLow orientation
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_6d_orientation_zl(uint8_t *zl)
+{
+  lsm6dso_d6d_src_t data;
+
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_D6D_SRC, (uint8_t *)&data, 1) != 0)
+  {
+    return 1;
+  }
+
+  *zl = data.zl;
+
+  return 0;
+}
+
+/**
+ * @brief  Get the status of ZHigh orientation
+ * @param  zh the status of ZHigh orientation
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_6d_orientation_zh(uint8_t *zh)
+{
+  lsm6dso_d6d_src_t data;
+
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_D6D_SRC, (uint8_t *)&data, 1) != 0)
+  {
+    return 1;
+  }
+
+  *zh = data.zh;
+
+  return 0;
+}
+
+/**
+ * @brief  Get the LSM6DSO ACC data ready bit value
+ * @param  status the status of data ready bit
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_x_drdy_status(uint8_t *status)
+{
+  if (lsm6dso_xl_flag_data_ready_get(&_reg_ctx, status) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Get the status of all hardware events
+ * @param  status the status of all hardware events
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_event_status(LSM6DSO_Event_Status_t *status)
+{
+  uint8_t tilt_ia = 0U;
+  lsm6dso_wake_up_src_t wake_up_src;
+  lsm6dso_tap_src_t tap_src;
+  lsm6dso_d6d_src_t d6d_src;
+  lsm6dso_emb_func_src_t func_src;
+  lsm6dso_md1_cfg_t md1_cfg;
+  lsm6dso_md2_cfg_t md2_cfg;
+  lsm6dso_emb_func_int1_t int1_ctrl;
+  lsm6dso_emb_func_int2_t int2_ctrl;
+
+  (void)memset((void *)status, 0x0, sizeof(LSM6DSO_Event_Status_t));
+
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_WAKE_UP_SRC, (uint8_t *)&wake_up_src, 1) != 0)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_TAP_SRC, (uint8_t *)&tap_src, 1) != 0)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_D6D_SRC, (uint8_t *)&d6d_src, 1) != 0)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_mem_bank_set(&_reg_ctx, LSM6DSO_EMBEDDED_FUNC_BANK) != 0)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_EMB_FUNC_SRC, (uint8_t *)&func_src, 1) != 0)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_EMB_FUNC_INT1, (uint8_t *)&int1_ctrl, 1) != 0)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_EMB_FUNC_INT2, (uint8_t *)&int2_ctrl, 1) != 0)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_mem_bank_set(&_reg_ctx, LSM6DSO_USER_BANK) != 0)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_MD1_CFG, (uint8_t *)&md1_cfg, 1) != 0)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_MD2_CFG, (uint8_t *)&md2_cfg, 1) != 0)
+  {
+    return 1;
+  }
+
+  if (lsm6dso_tilt_flag_data_ready_get(&_reg_ctx, &tilt_ia) != 0)
+  {
+    return 1;
+  }
+
+  if ((md1_cfg.int1_ff == 1U) || (md2_cfg.int2_ff == 1U))
+  {
+    if (wake_up_src.ff_ia == 1U)
+    {
+      status->FreeFallStatus = 1;
+    }
+  }
+
+  if ((md1_cfg.int1_wu == 1U) || (md2_cfg.int2_wu == 1U))
+  {
+    if (wake_up_src.wu_ia == 1U)
+    {
+      status->WakeUpStatus = 1;
+    }
+  }
+
+  if ((md1_cfg.int1_single_tap == 1U) || (md2_cfg.int2_single_tap == 1U))
+  {
+    if (tap_src.single_tap == 1U)
+    {
+      status->TapStatus = 1;
+    }
+  }
+
+  if ((md1_cfg.int1_double_tap == 1U) || (md2_cfg.int2_double_tap == 1U))
+  {
+    if (tap_src.double_tap == 1U)
+    {
+      status->DoubleTapStatus = 1;
+    }
+  }
+
+  if ((md1_cfg.int1_6d == 1U) || (md2_cfg.int2_6d == 1U))
+  {
+    if (d6d_src.d6d_ia == 1U)
+    {
+      status->D6DOrientationStatus = 1;
+    }
+  }
+
+  if (int1_ctrl.int1_step_detector == 1U)
+  {
+    if (func_src.step_detected == 1U)
+    {
+      status->StepStatus = 1;
+    }
+  }
+
+  if ((int1_ctrl.int1_tilt == 1U) || (int2_ctrl.int2_tilt == 1U))
+  {
+    if (tilt_ia == 1U)
+    {
+      status->TiltStatus = 1;
+    }
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set self test
+ * @param  val the value of st_xl in reg CTRL5_C
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_x_self_test(uint8_t val)
+{
+  lsm6dso_st_xl_t reg;
+
+  reg = (val == 0U)  ? LSM6DSO_XL_ST_DISABLE
+      : (val == 1U)  ? LSM6DSO_XL_ST_POSITIVE
+      : (val == 2U)  ? LSM6DSO_XL_ST_NEGATIVE
+      :                LSM6DSO_XL_ST_DISABLE;
+
+  if (lsm6dso_xl_self_test_set(&_reg_ctx, reg) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Get the LSM6DSO GYRO data ready bit value
+ * @param  status the status of data ready bit
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_g_drdy_status(uint8_t *status)
+{
+  if (lsm6dso_gy_flag_data_ready_get(&_reg_ctx, status) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set self test
+ * @param  val the value of st_xl in reg CTRL5_C
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_g_self_test(uint8_t val)
+{
+  lsm6dso_st_g_t reg;
+
+  reg = (val == 0U)  ? LSM6DSO_GY_ST_DISABLE
+      : (val == 1U)  ? LSM6DSO_GY_ST_POSITIVE
+      : (val == 2U)  ? LSM6DSO_GY_ST_NEGATIVE
+      :                LSM6DSO_GY_ST_DISABLE;
+
+
+  if (lsm6dso_gy_self_test_set(&_reg_ctx, reg) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Get the LSM6DSO FIFO number of samples
+ * @param  num_samples number of samples
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_fifo_num_samples(uint16_t *num_samples)
+{
+  if (lsm6dso_fifo_data_level_get(&_reg_ctx, num_samples) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Get the LSM6DSO FIFO full status
+ * @param  status FIFO full status
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_fifo_full_status(uint8_t *status)
+{
+  lsm6dso_reg_t reg;
+
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_FIFO_STATUS2, &reg.byte, 1) != 0)
+  {
+    return 1;
+  }
+
+  *status = reg.fifo_status2.fifo_full_ia;
+
+  return 0;
+}
+
+/**
+ * @brief  Set the LSM6DSO FIFO full interrupt on INT1 pin
+ * @param  status FIFO full interrupt on INT1 pin status
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_fifo_int1_fifo_full(uint8_t status)
+{
+  lsm6dso_reg_t reg;
+
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_INT1_CTRL, &reg.byte, 1) != 0)
+  {
+    return 1;
+  }
+
+  reg.int1_ctrl.int1_fifo_full = status;
+
+  if (lsm6dso_write_reg(&_reg_ctx, LSM6DSO_INT1_CTRL, &reg.byte, 1) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set the LSM6DSO FIFO watermark level
+ * @param  watermark FIFO watermark level
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_fifo_watermark_level(uint16_t watermark)
+{
+  if (lsm6dso_fifo_watermark_set(&_reg_ctx, watermark) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set the LSM6DSO FIFO stop on watermark
+ * @param  status FIFO stop on watermark status
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_fifo_stop_on_fth(uint8_t status)
+{
+  if (lsm6dso_fifo_stop_on_wtm_set(&_reg_ctx, status) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Set the LSM6DSO FIFO mode
+ * @param  mode FIFO mode
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_fifo_mode(uint8_t mode)
+{
+  int ret = 0;
+
+  /* Verify that the passed parameter contains one of the valid values. */
+  switch ((lsm6dso_fifo_mode_t)mode)
+  {
+    case LSM6DSO_BYPASS_MODE:
+    case LSM6DSO_FIFO_MODE:
+    case LSM6DSO_STREAM_TO_FIFO_MODE:
+    case LSM6DSO_BYPASS_TO_STREAM_MODE:
+    case LSM6DSO_STREAM_MODE:
+      break;
+
+    default:
+      ret = 1;
+      break;
+  }
+
+  if (ret == 1)
+  {
+    return ret;
+  }
+
+  if (lsm6dso_fifo_mode_set(&_reg_ctx, (lsm6dso_fifo_mode_t)mode) != 0)
+  {
+    return 1;
+  }
+
+  return ret;
+}
+
+/**
+ * @brief  Get the LSM6DSO FIFO tag
+ * @param  tag FIFO tag
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_fifo_tag(uint8_t *tag)
+{
+  lsm6dso_fifo_tag_t tag_local;
+
+  if (lsm6dso_fifo_sensor_tag_get(&_reg_ctx, &tag_local) != 0)
+  {
+    return 1;
+  }
+
+  *tag = (uint8_t)tag_local;
+
+  return 0;
+}
+
+/**
+ * @brief  Get the LSM6DSO FIFO raw data
+ * @param  data FIFO raw data array [6]
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_fifo_data(uint8_t *data)
+{
+  if (lsm6dso_read_reg(&_reg_ctx, LSM6DSO_FIFO_DATA_OUT_X_L, data, 6) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Get the LSM6DSO FIFO accelero single sample (16-bit data per 3 axes) and calculate acceleration [mg]
+ * @param  acceleration FIFO accelero axes [mg]
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_fifo_x_axes(int32_t *acceleration)
+{
+  uint8_t data[6];
+  int16_t data_raw[3];
+  float sensitivity = 0.0f;
+  float acceleration_float[3];
+
+  if (get_fifo_data(data) != 0)
+  {
+    return 1;
+  }
+
+  data_raw[0] = ((int16_t)data[1] << 8) | data[0];
+  data_raw[1] = ((int16_t)data[3] << 8) | data[2];
+  data_raw[2] = ((int16_t)data[5] << 8) | data[4];
+
+  if (get_x_sensitivity(&sensitivity) != 0)
+  {
+    return 1;
+  }
+
+  acceleration_float[0] = (float)data_raw[0] * sensitivity;
+  acceleration_float[1] = (float)data_raw[1] * sensitivity;
+  acceleration_float[2] = (float)data_raw[2] * sensitivity;
+
+  acceleration[0] = (int32_t)acceleration_float[0];
+  acceleration[1] = (int32_t)acceleration_float[1];
+  acceleration[2] = (int32_t)acceleration_float[2];
+
+  return 0;
+}
+
+/**
+ * @brief  Set the LSM6DSO FIFO accelero BDR value
+ * @param  bdr FIFO accelero BDR value
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_fifo_x_bdr(float bdr)
+{
+  lsm6dso_bdr_xl_t new_bdr;
+
+  new_bdr = (bdr <=    0.0f) ? LSM6DSO_XL_NOT_BATCHED
+          : (bdr <=   12.5f) ? LSM6DSO_XL_BATCHED_AT_12Hz5
+          : (bdr <=   26.0f) ? LSM6DSO_XL_BATCHED_AT_26Hz
+          : (bdr <=   52.0f) ? LSM6DSO_XL_BATCHED_AT_52Hz
+          : (bdr <=  104.0f) ? LSM6DSO_XL_BATCHED_AT_104Hz
+          : (bdr <=  208.0f) ? LSM6DSO_XL_BATCHED_AT_208Hz
+          : (bdr <=  416.0f) ? LSM6DSO_XL_BATCHED_AT_417Hz
+          : (bdr <=  833.0f) ? LSM6DSO_XL_BATCHED_AT_833Hz
+          : (bdr <= 1660.0f) ? LSM6DSO_XL_BATCHED_AT_1667Hz
+          : (bdr <= 3330.0f) ? LSM6DSO_XL_BATCHED_AT_3333Hz
+          :                    LSM6DSO_XL_BATCHED_AT_6667Hz;
+
+  if (lsm6dso_fifo_xl_batch_set(&_reg_ctx, new_bdr) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+ * @brief  Get the LSM6DSO FIFO gyro single sample (16-bit data per 3 axes) and calculate angular velocity [mDPS]
+ * @param  angular_velocity FIFO gyro axes [mDPS]
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::get_fifo_g_axes(int32_t *angular_velocity)
+{
+  uint8_t data[6];
+  int16_t data_raw[3];
+  float sensitivity = 0.0f;
+  float angular_velocity_float[3];
+
+  if (get_fifo_data(data) != 0)
+  {
+    return 1;
+  }
+
+  data_raw[0] = ((int16_t)data[1] << 8) | data[0];
+  data_raw[1] = ((int16_t)data[3] << 8) | data[2];
+  data_raw[2] = ((int16_t)data[5] << 8) | data[4];
+
+  if (get_g_sensitivity(&sensitivity) != 0)
+  {
+    return 1;
+  }
+
+  angular_velocity_float[0] = (float)data_raw[0] * sensitivity;
+  angular_velocity_float[1] = (float)data_raw[1] * sensitivity;
+  angular_velocity_float[2] = (float)data_raw[2] * sensitivity;
+
+  angular_velocity[0] = (int32_t)angular_velocity_float[0];
+  angular_velocity[1] = (int32_t)angular_velocity_float[1];
+  angular_velocity[2] = (int32_t)angular_velocity_float[2];
+
+  return 0;
+}
+
+/**
+ * @brief  Set the LSM6DSO FIFO gyro BDR value
+ * @param  bdr FIFO gyro BDR value
+ * @retval 0 in case of success, an error code otherwise
+ */
+int LSM6DSOSensor::set_fifo_g_bdr(float bdr)
+{
+  lsm6dso_bdr_gy_t new_bdr;
+
+  new_bdr = (bdr <=    0.0f) ? LSM6DSO_GY_NOT_BATCHED
+          : (bdr <=   12.5f) ? LSM6DSO_GY_BATCHED_AT_12Hz5
+          : (bdr <=   26.0f) ? LSM6DSO_GY_BATCHED_AT_26Hz
+          : (bdr <=   52.0f) ? LSM6DSO_GY_BATCHED_AT_52Hz
+          : (bdr <=  104.0f) ? LSM6DSO_GY_BATCHED_AT_104Hz
+          : (bdr <=  208.0f) ? LSM6DSO_GY_BATCHED_AT_208Hz
+          : (bdr <=  416.0f) ? LSM6DSO_GY_BATCHED_AT_417Hz
+          : (bdr <=  833.0f) ? LSM6DSO_GY_BATCHED_AT_833Hz
+          : (bdr <= 1660.0f) ? LSM6DSO_GY_BATCHED_AT_1667Hz
+          : (bdr <= 3330.0f) ? LSM6DSO_GY_BATCHED_AT_3333Hz
+          :                    LSM6DSO_GY_BATCHED_AT_6667Hz;
+
+  if (lsm6dso_fifo_gy_batch_set(&_reg_ctx, new_bdr) != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
+
+
+
+int32_t LSM6DSO_io_write(void *handle, uint8_t WriteAddr, uint8_t *pBuffer, uint16_t nBytesToWrite)
+{
+  return ((LSM6DSOSensor *)handle)->io_write(pBuffer, WriteAddr, nBytesToWrite);
+}
+
+int32_t LSM6DSO_io_read(void *handle, uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead)
+{
+  return ((LSM6DSOSensor *)handle)->io_read(pBuffer, ReadAddr, nBytesToRead);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LSM6DSOSensor.h	Tue Mar 05 16:26:47 2019 +0000
@@ -0,0 +1,319 @@
+/**
+ ******************************************************************************
+ * @file    LSM6DSOSensor.h
+ * @author  SRA
+ * @version V1.0.0
+ * @date    February 2019
+ * @brief   Abstract Class of an LSM6DSO Inertial Measurement Unit (IMU) 6 axes
+ *          sensor.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2019 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 __LSM6DSOSensor_H__
+#define __LSM6DSOSensor_H__
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "DevI2C.h"
+#include "lsm6dso_reg.h"
+#include "MotionSensor.h"
+#include "GyroSensor.h"
+#include <assert.h>
+
+/* Defines -------------------------------------------------------------------*/
+
+#define LSM6DSO_ACC_SENSITIVITY_FS_2G   0.061f
+#define LSM6DSO_ACC_SENSITIVITY_FS_4G   0.122f
+#define LSM6DSO_ACC_SENSITIVITY_FS_8G   0.244f
+#define LSM6DSO_ACC_SENSITIVITY_FS_16G  0.488f
+
+#define LSM6DSO_GYRO_SENSITIVITY_FS_125DPS    4.375f
+#define LSM6DSO_GYRO_SENSITIVITY_FS_250DPS    8.750f
+#define LSM6DSO_GYRO_SENSITIVITY_FS_500DPS   17.500f
+#define LSM6DSO_GYRO_SENSITIVITY_FS_1000DPS  35.000f
+#define LSM6DSO_GYRO_SENSITIVITY_FS_2000DPS  70.000f
+
+
+/* Typedefs ------------------------------------------------------------------*/
+
+typedef enum
+{
+  LSM6DSO_INT1_PIN,
+  LSM6DSO_INT2_PIN,
+} LSM6DSO_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;
+  unsigned int SleepStatus : 1;
+} LSM6DSO_Event_Status_t;
+
+
+/* Class Declaration ---------------------------------------------------------*/
+   
+/**
+ * Abstract class of an LSM6DSO Inertial Measurement Unit (IMU) 6 axes
+ * sensor.
+ */
+class LSM6DSOSensor : public MotionSensor, public GyroSensor
+{
+  public:
+    enum SPI_type_t {SPI3W, SPI4W};
+    LSM6DSOSensor(SPI *spi, PinName cs_pin, PinName int1_pin=NC, PinName int2_pin=NC, SPI_type_t spi_type=SPI4W);
+    LSM6DSOSensor(DevI2C *i2c, uint8_t address=LSM6DSO_I2C_ADD_H, 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 *acceleration);
+    virtual int get_g_axes(int32_t *angular_rate);
+    virtual int get_x_sensitivity(float *sensitivity);
+    virtual int get_g_sensitivity(float *sensitivity);
+    virtual int get_x_axes_raw(int16_t *value);
+    virtual int get_g_axes_raw(int16_t *value);
+    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 *full_scale);
+    virtual int get_g_fs(float *full_scale);
+    virtual int set_x_fs(float full_scale);
+    virtual int set_g_fs(float full_scale);
+    int enable_x(void);
+    int enable_g(void);
+    int disable_x(void);
+    int disable_g(void);
+    int enable_free_fall_detection(LSM6DSO_Interrupt_Pin_t pin = LSM6DSO_INT1_PIN);
+    int disable_free_fall_detection(void);
+    int set_free_fall_threshold(uint8_t thr);
+    int set_free_fall_duration(uint8_t dur);
+    int enable_pedometer(void);
+    int disable_pedometer(void);
+    int get_step_counter(uint16_t *step_count);
+    int reset_step_counter(void);
+    int enable_tilt_detection(LSM6DSO_Interrupt_Pin_t pin = LSM6DSO_INT1_PIN);
+    int disable_tilt_detection(void);
+    int enable_wake_up_detection(LSM6DSO_Interrupt_Pin_t pin = LSM6DSO_INT2_PIN);
+    int disable_wake_up_detection(void);
+    int set_wake_up_threshold(uint8_t thr);
+    int set_wake_up_duration(uint8_t dur);
+    int enable_single_tap_detection(LSM6DSO_Interrupt_Pin_t pin = LSM6DSO_INT1_PIN);
+    int disable_single_tap_detection(void);
+    int enable_double_tap_detection(LSM6DSO_Interrupt_Pin_t pin = LSM6DSO_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(LSM6DSO_Interrupt_Pin_t pin = LSM6DSO_INT1_PIN);
+    int disable_6d_orientation(void);
+    int set_6d_orientation_threshold(uint8_t thr);
+    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(LSM6DSO_Event_Status_t *status);
+    int read_reg(uint8_t reg, uint8_t *data);
+    int write_reg(uint8_t reg, uint8_t data);
+    int set_interrupt_latch(uint8_t status);
+    int get_x_drdy_status(uint8_t *status);
+    int set_x_self_test(uint8_t status);
+    int get_g_drdy_status(uint8_t *status);
+    int set_g_self_test(uint8_t status);
+    int get_fifo_num_samples(uint16_t *num_samples);
+    int get_fifo_full_status(uint8_t *status);
+    int set_fifo_int1_fifo_full(uint8_t status);
+    int set_fifo_watermark_level(uint16_t watermark);
+    int set_fifo_stop_on_fth(uint8_t status);
+    int set_fifo_mode(uint8_t mode);
+    int get_fifo_tag(uint8_t *tag);
+    int get_fifo_data(uint8_t *data);
+    int get_fifo_x_axes(int32_t *acceleration);
+    int set_fifo_x_bdr(float bdr);
+    int get_fifo_g_axes(int32_t *angular_velocity);
+    int set_fifo_g_bdr(float bdr);
+    
+    /**
+     * @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)
+    {
+        if (_dev_spi) { 
+            _dev_spi->lock();
+            _cs_pin = 0;
+            _dev_spi->write(RegisterAddr);                    
+            _dev_spi->write((char *)pBuffer, (int) NumByteToWrite, NULL, 0);                     
+            _cs_pin = 1;                    
+            _dev_spi->unlock();
+            return 0;                    
+        }        
+        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;
+
+    /* Configuration */
+    uint8_t _address;
+    DigitalOut  _cs_pin;        
+    InterruptIn _int1_irq;
+    InterruptIn _int2_irq;
+    SPI_type_t _spi_type;
+    
+    uint8_t _x_is_enabled;
+    lsm6dso_odr_xl_t _x_last_odr;
+    uint8_t _g_is_enabled;
+    lsm6dso_odr_g_t _g_last_odr;
+
+    lsm6dso_ctx_t _reg_ctx;
+};
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+int32_t LSM6DSO_io_write( void *handle, uint8_t WriteAddr, uint8_t *pBuffer, uint16_t nBytesToWrite );
+int32_t LSM6DSO_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/ST_INTERFACES.lib	Tue Mar 05 16:26:47 2019 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/ST/code/ST_INTERFACES/#d3c9b33b992c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/X_NUCLEO_COMMON.lib	Tue Mar 05 16:26:47 2019 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/ST/code/X_NUCLEO_COMMON/#21096473f63e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lsm6dso_reg.c	Tue Mar 05 16:26:47 2019 +0000
@@ -0,0 +1,8897 @@
+/*
+  ******************************************************************************
+  * @file    lsm6dso_reg.c
+  * @author  Sensor Solutions Software Team
+  * @brief   LSM6DSO driver file
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2018 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.
+  *
+  */
+
+#include "lsm6dso_reg.h"
+
+/**
+  * @defgroup  LSM6DSO
+  * @brief     This file provides a set of functions needed to drive the
+  *            lsm6dso enhanced inertial module.
+  * @{
+  *
+*/
+
+/**
+  * @defgroup  LSM6DSO_Interfaces_Functions
+  * @brief     This section provide a set of functions used to read and
+  *            write a generic register of the device.
+  *            MANDATORY: return 0 -> no Error.
+  * @{
+  *
+*/
+
+/**
+  * @brief  Read generic device register
+  *
+  * @param  ctx   read / write interface definitions(ptr)
+  * @param  reg   register to read
+  * @param  data  pointer to buffer that store the data read(ptr)
+  * @param  len   number of consecutive register to read
+  * @retval          interface status (MANDATORY: return 0 -> no Error)
+  *
+  */
+int32_t lsm6dso_read_reg(lsm6dso_ctx_t* ctx, uint8_t reg, uint8_t* data,
+                         uint16_t len)
+{
+  int32_t ret;
+  ret = ctx->read_reg(ctx->handle, reg, data, len);
+  return ret;
+}
+
+/**
+  * @brief  Write generic device register
+  *
+  * @param  ctx   read / write interface definitions(ptr)
+  * @param  reg   register to write
+  * @param  data  pointer to data to write in register reg(ptr)
+  * @param  len   number of consecutive register to write
+  * @retval          interface status (MANDATORY: return 0 -> no Error)
+  *
+  */
+int32_t lsm6dso_write_reg(lsm6dso_ctx_t* ctx, uint8_t reg, uint8_t* data,
+                          uint16_t len)
+{
+  int32_t ret;
+  ret = ctx->write_reg(ctx->handle, reg, data, len);
+  return ret;
+}
+
+/**
+  * @}
+  *
+*/
+
+/**
+  * @defgroup  LSM6DSO_Sensitivity
+  * @brief     These functions convert raw-data into engineering units.
+  * @{
+  *
+*/
+float lsm6dso_from_fs2_to_mg(int16_t lsb)
+{
+  return ((float)lsb) * 0.061f;
+}
+
+float lsm6dso_from_fs4_to_mg(int16_t lsb)
+{
+  return ((float)lsb) * 0.122f;
+}
+
+float lsm6dso_from_fs8_to_mg(int16_t lsb)
+{
+  return ((float)lsb) * 0.244f;
+}
+
+float lsm6dso_from_fs16_to_mg(int16_t lsb)
+{
+  return ((float)lsb) *0.488f;
+}
+
+float lsm6dso_from_fs125_to_mdps(int16_t lsb)
+{
+  return ((float)lsb) *4.375f;
+}
+
+float lsm6dso_from_fs500_to_mdps(int16_t lsb)
+{
+  return ((float)lsb) *1.750f;
+}
+
+float lsm6dso_from_fs250_to_mdps(int16_t lsb)
+{
+  return ((float)lsb) *0.875f;
+}
+
+float lsm6dso_from_fs1000_to_mdps(int16_t lsb)
+{
+  return ((float)lsb) *0.035f;
+}
+
+float lsm6dso_from_fs2000_to_mdps(int16_t lsb)
+{
+  return ((float)lsb) *0.070f;
+}
+
+float lsm6dso_from_lsb_to_celsius(int16_t lsb)
+{
+  return (((float)lsb / 256.0f) + 25.0f);
+}
+
+float lsm6dso_from_lsb_to_nsec(int16_t lsb)
+{
+  return ((float)lsb * 25000.0f);
+}
+
+/**
+  * @}
+  *
+*/
+
+/**
+  * @defgroup  LSM6DSO_Data_Generation
+  * @brief     This section groups all the functions concerning
+  *            data generation.
+  *
+*/
+
+/**
+  * @brief  Accelerometer full-scale selection.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of fs_xl in reg CTRL1_XL
+  *
+  */
+int32_t lsm6dso_xl_full_scale_set(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_fs_xl_t val)
+{
+  lsm6dso_ctrl1_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.fs_xl = (uint8_t) val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer full-scale selection.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of fs_xl in reg CTRL1_XL
+  *
+  */
+int32_t lsm6dso_xl_full_scale_get(lsm6dso_ctx_t *ctx, lsm6dso_fs_xl_t *val)
+{
+  lsm6dso_ctrl1_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t*)&reg, 1);
+  switch (reg.fs_xl) {
+    case LSM6DSO_2g:
+      *val = LSM6DSO_2g;
+      break;
+    case LSM6DSO_16g:
+      *val = LSM6DSO_16g;
+      break;
+    case LSM6DSO_4g:
+      *val = LSM6DSO_4g;
+      break;
+    case LSM6DSO_8g:
+      *val = LSM6DSO_8g;
+      break;
+    default:
+      *val = LSM6DSO_2g;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer UI data rate selection.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of odr_xl in reg CTRL1_XL
+  *
+  */
+int32_t lsm6dso_xl_data_rate_set(lsm6dso_ctx_t *ctx, lsm6dso_odr_xl_t val)
+{
+  lsm6dso_ctrl1_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.odr_xl = (uint8_t) val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer UI data rate selection.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of odr_xl in reg CTRL1_XL
+  *
+  */
+int32_t lsm6dso_xl_data_rate_get(lsm6dso_ctx_t *ctx, lsm6dso_odr_xl_t *val)
+{
+  lsm6dso_ctrl1_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t*)&reg, 1);
+
+  switch (reg.odr_xl) {
+    case LSM6DSO_XL_ODR_OFF:
+      *val = LSM6DSO_XL_ODR_OFF;
+      break;
+    case LSM6DSO_XL_ODR_12Hz5:
+      *val = LSM6DSO_XL_ODR_12Hz5;
+      break;
+    case LSM6DSO_XL_ODR_26Hz:
+      *val = LSM6DSO_XL_ODR_26Hz;
+      break;
+    case LSM6DSO_XL_ODR_52Hz:
+      *val = LSM6DSO_XL_ODR_52Hz;
+      break;
+    case LSM6DSO_XL_ODR_104Hz:
+      *val = LSM6DSO_XL_ODR_104Hz;
+      break;
+    case LSM6DSO_XL_ODR_208Hz:
+      *val = LSM6DSO_XL_ODR_208Hz;
+      break;
+    case LSM6DSO_XL_ODR_417Hz:
+      *val = LSM6DSO_XL_ODR_417Hz;
+      break;
+    case LSM6DSO_XL_ODR_833Hz:
+      *val = LSM6DSO_XL_ODR_833Hz;
+      break;
+    case LSM6DSO_XL_ODR_1667Hz:
+      *val = LSM6DSO_XL_ODR_1667Hz;
+      break;
+    case LSM6DSO_XL_ODR_3333Hz:
+      *val = LSM6DSO_XL_ODR_3333Hz;
+      break;
+    case LSM6DSO_XL_ODR_6667Hz:
+      *val = LSM6DSO_XL_ODR_6667Hz;
+      break;
+    case LSM6DSO_XL_ODR_6Hz5:
+      *val = LSM6DSO_XL_ODR_6Hz5;
+      break;
+    default:
+      *val = LSM6DSO_XL_ODR_OFF;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Gyroscope UI chain full-scale selection.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of fs_g in reg CTRL2_G
+  *
+  */
+int32_t lsm6dso_gy_full_scale_set(lsm6dso_ctx_t *ctx, lsm6dso_fs_g_t val)
+{
+  lsm6dso_ctrl2_g_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_G, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.fs_g = (uint8_t) val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL2_G, (uint8_t*)&reg, 1);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Gyroscope UI chain full-scale selection.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of fs_g in reg CTRL2_G
+  *
+  */
+int32_t lsm6dso_gy_full_scale_get(lsm6dso_ctx_t *ctx, lsm6dso_fs_g_t *val)
+{
+  lsm6dso_ctrl2_g_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_G, (uint8_t*)&reg, 1);
+  switch (reg.fs_g) {
+    case LSM6DSO_250dps:
+      *val = LSM6DSO_250dps;
+      break;
+    case LSM6DSO_125dps:
+      *val = LSM6DSO_125dps;
+      break;
+    case LSM6DSO_500dps:
+      *val = LSM6DSO_500dps;
+      break;
+    case LSM6DSO_1000dps:
+      *val = LSM6DSO_1000dps;
+      break;
+    case LSM6DSO_2000dps:
+      *val = LSM6DSO_2000dps;
+      break;
+    default:
+      *val = LSM6DSO_250dps;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Gyroscope UI data rate selection.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of odr_g in reg CTRL2_G
+  *
+  */
+int32_t lsm6dso_gy_data_rate_set(lsm6dso_ctx_t *ctx, lsm6dso_odr_g_t val)
+{
+  lsm6dso_ctrl2_g_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_G, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.odr_g = (uint8_t) val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL2_G, (uint8_t*)&reg, 1);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Gyroscope UI data rate selection.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of odr_g in reg CTRL2_G
+  *
+  */
+int32_t lsm6dso_gy_data_rate_get(lsm6dso_ctx_t *ctx, lsm6dso_odr_g_t *val)
+{
+  lsm6dso_ctrl2_g_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_G, (uint8_t*)&reg, 1);
+  switch (reg.odr_g) {
+    case LSM6DSO_GY_ODR_OFF:
+      *val = LSM6DSO_GY_ODR_OFF;
+      break;
+    case LSM6DSO_GY_ODR_12Hz5:
+      *val = LSM6DSO_GY_ODR_12Hz5;
+      break;
+    case LSM6DSO_GY_ODR_26Hz:
+      *val = LSM6DSO_GY_ODR_26Hz;
+      break;
+    case LSM6DSO_GY_ODR_52Hz:
+      *val = LSM6DSO_GY_ODR_52Hz;
+      break;
+    case LSM6DSO_GY_ODR_104Hz:
+      *val = LSM6DSO_GY_ODR_104Hz;
+      break;
+    case LSM6DSO_GY_ODR_208Hz:
+      *val = LSM6DSO_GY_ODR_208Hz;
+      break;
+    case LSM6DSO_GY_ODR_417Hz:
+      *val = LSM6DSO_GY_ODR_417Hz;
+      break;
+    case LSM6DSO_GY_ODR_833Hz:
+      *val = LSM6DSO_GY_ODR_833Hz;
+      break;
+    case LSM6DSO_GY_ODR_1667Hz:
+      *val = LSM6DSO_GY_ODR_1667Hz;
+      break;
+    case LSM6DSO_GY_ODR_3333Hz:
+      *val = LSM6DSO_GY_ODR_3333Hz;
+      break;
+    case LSM6DSO_GY_ODR_6667Hz:
+      *val = LSM6DSO_GY_ODR_6667Hz;
+      break;
+    default:
+      *val = LSM6DSO_GY_ODR_OFF;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Block data update.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of bdu in reg CTRL3_C
+  *
+  */
+int32_t lsm6dso_block_data_update_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_ctrl3_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.bdu = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Block data update.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of bdu in reg CTRL3_C
+  *
+  */
+int32_t lsm6dso_block_data_update_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_ctrl3_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  *val = reg.bdu;
+
+  return ret;
+}
+
+/**
+  * @brief  Weight of XL user offset bits of registers X_OFS_USR (73h),
+  *         Y_OFS_USR (74h), Z_OFS_USR (75h).[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of usr_off_w in reg CTRL6_C
+  *
+  */
+int32_t lsm6dso_xl_offset_weight_set(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_usr_off_w_t val)
+{
+  lsm6dso_ctrl6_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.usr_off_w = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief    Weight of XL user offset bits of registers X_OFS_USR (73h),
+  *           Y_OFS_USR (74h), Z_OFS_USR (75h).[get]
+  *
+  * @param    ctx      read / write interface definitions
+  * @param    val      Get the values of usr_off_w in reg CTRL6_C
+  *
+  */
+int32_t lsm6dso_xl_offset_weight_get(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_usr_off_w_t *val)
+{
+  lsm6dso_ctrl6_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t*)&reg, 1);
+
+  switch (reg.usr_off_w) {
+    case LSM6DSO_LSb_1mg:
+      *val = LSM6DSO_LSb_1mg;
+      break;
+    case LSM6DSO_LSb_16mg:
+      *val = LSM6DSO_LSb_16mg;
+      break;
+    default:
+      *val = LSM6DSO_LSb_1mg;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer power mode.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of xl_hm_mode in
+  *                               reg CTRL6_C
+  *
+  */
+int32_t lsm6dso_xl_power_mode_set(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_xl_hm_mode_t val)
+{
+  lsm6dso_ctrl5_c_t ctrl5_c;
+  lsm6dso_ctrl6_c_t ctrl6_c;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t*) &ctrl5_c, 1);
+  if (ret == 0) {
+    ctrl5_c.xl_ulp_en = ((uint8_t)val & 0x02U) >> 1;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t*) &ctrl5_c, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t*) &ctrl6_c, 1);
+  }
+  if (ret == 0) {
+    ctrl6_c.xl_hm_mode = (uint8_t)val & 0x01U;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t*) &ctrl6_c, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer power mode.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of xl_hm_mode in reg CTRL6_C
+  *
+  */
+int32_t lsm6dso_xl_power_mode_get(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_xl_hm_mode_t *val)
+{
+  lsm6dso_ctrl5_c_t ctrl5_c;
+  lsm6dso_ctrl6_c_t ctrl6_c;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t*) &ctrl5_c, 1);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t*) &ctrl6_c, 1);
+    switch ( (ctrl5_c.xl_ulp_en << 1) | ctrl6_c.xl_hm_mode) {
+      case LSM6DSO_HIGH_PERFORMANCE_MD:
+        *val = LSM6DSO_HIGH_PERFORMANCE_MD;
+        break;
+      case LSM6DSO_LOW_NORMAL_POWER_MD:
+        *val = LSM6DSO_LOW_NORMAL_POWER_MD;
+        break;
+      case LSM6DSO_ULTRA_LOW_POWER_MD:
+        *val = LSM6DSO_ULTRA_LOW_POWER_MD;
+        break;
+      default:
+        *val = LSM6DSO_HIGH_PERFORMANCE_MD;
+        break;
+    }
+  }
+  return ret;
+}
+
+/**
+  * @brief  Operating mode for gyroscope.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of g_hm_mode in reg CTRL7_G
+  *
+  */
+int32_t lsm6dso_gy_power_mode_set(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_g_hm_mode_t val)
+{
+  lsm6dso_ctrl7_g_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.g_hm_mode = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Operating mode for gyroscope.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of g_hm_mode in reg CTRL7_G
+  *
+  */
+int32_t lsm6dso_gy_power_mode_get(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_g_hm_mode_t *val)
+{
+  lsm6dso_ctrl7_g_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t*)&reg, 1);
+  switch (reg.g_hm_mode) {
+    case LSM6DSO_GY_HIGH_PERFORMANCE:
+      *val = LSM6DSO_GY_HIGH_PERFORMANCE;
+      break;
+    case LSM6DSO_GY_NORMAL:
+      *val = LSM6DSO_GY_NORMAL;
+      break;
+    default:
+      *val = LSM6DSO_GY_HIGH_PERFORMANCE;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Read all the interrupt flag of the device.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      registers ALL_INT_SRC; WAKE_UP_SRC;
+  *                              TAP_SRC; D6D_SRC; STATUS_REG;
+  *                              EMB_FUNC_STATUS; FSM_STATUS_A/B
+  *
+  */
+int32_t lsm6dso_all_sources_get(lsm6dso_ctx_t *ctx,
+                                lsm6dso_all_sources_t *val)
+{
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_ALL_INT_SRC,
+                         (uint8_t*)&val->all_int_src, 1);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_SRC,
+                           (uint8_t*)&val->wake_up_src, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_SRC,
+                           (uint8_t*)&val->tap_src, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_D6D_SRC,
+                           (uint8_t*)&val->d6d_src, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_REG,
+                           (uint8_t*)&val->status_reg, 1);
+  }
+  if (ret == 0) {
+
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_STATUS,
+                           (uint8_t*)&val->emb_func_status, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_STATUS_A,
+                           (uint8_t*)&val->fsm_status_a, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_STATUS_B,
+                           (uint8_t*)&val->fsm_status_b, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  The STATUS_REG register is read by the primary interface.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      register STATUS_REG
+  *
+  */
+int32_t lsm6dso_status_reg_get(lsm6dso_ctx_t *ctx, lsm6dso_status_reg_t *val)
+{
+  int32_t ret;
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_REG, (uint8_t*) val, 1);
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer new data available.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of xlda in reg STATUS_REG
+  *
+  */
+int32_t lsm6dso_xl_flag_data_ready_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_status_reg_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_REG, (uint8_t*)&reg, 1);
+  *val = reg.xlda;
+
+  return ret;
+}
+
+/**
+  * @brief  Gyroscope new data available.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of gda in reg STATUS_REG
+  *
+  */
+int32_t lsm6dso_gy_flag_data_ready_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_status_reg_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_REG, (uint8_t*)&reg, 1);
+  *val = reg.gda;
+
+  return ret;
+}
+
+/**
+  * @brief  Temperature new data available.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tda in reg STATUS_REG
+  *
+  */
+int32_t lsm6dso_temp_flag_data_ready_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_status_reg_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_REG, (uint8_t*)&reg, 1);
+  *val = reg.tda;
+
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer X-axis user offset correction expressed in
+  *         two’s complement, weight depends on USR_OFF_W in CTRL6_C (15h).
+  *         The value must be in the range [-127 127].[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that contains data to write
+  *
+  */
+int32_t lsm6dso_xl_usr_offset_x_set(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  ret = lsm6dso_write_reg(ctx, LSM6DSO_X_OFS_USR, buff, 1);
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer X-axis user offset correction expressed in two’s
+  *         complement, weight depends on USR_OFF_W in CTRL6_C (15h).
+  *         The value must be in the range [-127 127].[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_xl_usr_offset_x_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_X_OFS_USR, buff, 1);
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer Y-axis user offset correction expressed in two’s
+  *         complement, weight depends on USR_OFF_W in CTRL6_C (15h).
+  *         The value must be in the range [-127 127].[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that contains data to write
+  *
+  */
+int32_t lsm6dso_xl_usr_offset_y_set(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  ret = lsm6dso_write_reg(ctx, LSM6DSO_Y_OFS_USR, buff, 1);
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer Y-axis user offset correction expressed in two’s
+  *         complement, weight depends on USR_OFF_W in CTRL6_C (15h).
+  *         The value must be in the range [-127 127].[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_xl_usr_offset_y_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_Y_OFS_USR, buff, 1);
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer Z-axis user offset correction expressed in two’s
+  *         complement, weight depends on USR_OFF_W in CTRL6_C (15h).
+  *         The value must be in the range [-127 127].[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that contains data to write
+  *
+  */
+int32_t lsm6dso_xl_usr_offset_z_set(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  ret = lsm6dso_write_reg(ctx, LSM6DSO_Z_OFS_USR, buff, 1);
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer Z-axis user offset correction expressed in two’s
+  *         complement, weight depends on USR_OFF_W in CTRL6_C (15h).
+  *         The value must be in the range [-127 127].[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_xl_usr_offset_z_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_Z_OFS_USR, buff, 1);
+  return ret;
+}
+
+/**
+  * @brief  Enables user offset on out.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of usr_off_on_out in reg CTRL7_G
+  *
+  */
+int32_t lsm6dso_xl_usr_offset_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_ctrl7_g_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.usr_off_on_out = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  User offset on out flag.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      values of usr_off_on_out in reg CTRL7_G
+  *
+  */
+int32_t lsm6dso_xl_usr_offset_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_ctrl7_g_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t*)&reg, 1);
+  *val = reg.usr_off_on_out;
+
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_Timestamp
+  * @brief     This section groups all the functions that manage the
+  *            timestamp generation.
+  * @{
+  *
+*/
+
+/**
+  * @brief  Enables timestamp counter.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of timestamp_en in reg CTRL10_C
+  *
+  */
+int32_t lsm6dso_timestamp_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_ctrl10_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL10_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.timestamp_en = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL10_C, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enables timestamp counter.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of timestamp_en in reg CTRL10_C
+  *
+  */
+int32_t lsm6dso_timestamp_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_ctrl10_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL10_C, (uint8_t*)&reg, 1);
+  *val = reg.timestamp_en;
+
+  return ret;
+}
+
+/**
+  * @brief  Timestamp first data output register (r).
+  *         The value is expressed as a 32-bit word and the bit
+  *         resolution is 25 μs.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_timestamp_raw_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TIMESTAMP0, buff, 4);
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_Data output
+  * @brief     This section groups all the data output functions.
+  * @{
+  *
+*/
+
+/**
+  * @brief  Circular burst-mode (rounding) read of the output
+  *         registers.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of rounding in reg CTRL5_C
+  *
+  */
+int32_t lsm6dso_rounding_mode_set(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_rounding_t val)
+{
+  lsm6dso_ctrl5_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.rounding = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Gyroscope UI chain full-scale selection.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of rounding in reg CTRL5_C
+  *
+  */
+int32_t lsm6dso_rounding_mode_get(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_rounding_t *val)
+{
+  lsm6dso_ctrl5_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t*)&reg, 1);
+  switch (reg.rounding) {
+    case LSM6DSO_NO_ROUND:
+      *val = LSM6DSO_NO_ROUND;
+      break;
+    case LSM6DSO_ROUND_XL:
+      *val = LSM6DSO_ROUND_XL;
+      break;
+    case LSM6DSO_ROUND_GY:
+      *val = LSM6DSO_ROUND_GY;
+      break;
+    case LSM6DSO_ROUND_GY_XL:
+      *val = LSM6DSO_ROUND_GY_XL;
+      break;
+    default:
+      *val = LSM6DSO_NO_ROUND;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Temperature data output register (r).
+  *         L and H registers together express a 16-bit word in two’s
+  *         complement.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_temperature_raw_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_OUT_TEMP_L, buff, 2);
+  return ret;
+}
+
+/**
+  * @brief  Angular rate sensor. The value is expressed as a 16-bit
+  *         word in two’s complement.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_angular_rate_raw_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_OUTX_L_G, buff, 6);
+  return ret;
+}
+
+/**
+  * @brief  Linear acceleration output register.
+  *         The value is expressed as a 16-bit word in two’s complement.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_acceleration_raw_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_OUTX_L_A, buff, 6);
+  return ret;
+}
+
+/**
+  * @brief  FIFO data output [get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_fifo_out_raw_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_DATA_OUT_X_L, buff, 6);
+  return ret;
+}
+
+/**
+  * @brief  Step counter output register.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_number_of_steps_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_STEP_COUNTER_L, buff, 2);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Reset step counter register.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  *
+  */
+int32_t lsm6dso_steps_reset(lsm6dso_ctx_t *ctx)
+{
+  lsm6dso_emb_func_src_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_SRC, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.pedo_rst_step = PROPERTY_ENABLE;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_SRC, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_common
+  * @brief   This section groups common usefull functions.
+  * @{
+  *
+*/
+
+/**
+  * @brief  Difference in percentage of the effective ODR(and timestamp rate)
+  *         with respect to the typical.
+  *         Step:  0.15%. 8-bit format, 2's complement.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of freq_fine in reg
+  *                      INTERNAL_FREQ_FINE
+  *
+  */
+int32_t lsm6dso_odr_cal_reg_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_internal_freq_fine_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_INTERNAL_FREQ_FINE, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.freq_fine = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_INTERNAL_FREQ_FINE,
+                            (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Difference in percentage of the effective ODR(and timestamp rate)
+  *         with respect to the typical.
+  *         Step:  0.15%. 8-bit format, 2's complement.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of freq_fine in reg INTERNAL_FREQ_FINE
+  *
+  */
+int32_t lsm6dso_odr_cal_reg_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_internal_freq_fine_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_INTERNAL_FREQ_FINE, (uint8_t*)&reg, 1);
+  *val = reg.freq_fine;
+
+  return ret;
+}
+
+
+/**
+  * @brief  Enable access to the embedded functions/sensor
+  *         hub configuration registers.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of reg_access in
+  *                               reg FUNC_CFG_ACCESS
+  *
+  */
+int32_t lsm6dso_mem_bank_set(lsm6dso_ctx_t *ctx, lsm6dso_reg_access_t val)
+{
+  lsm6dso_func_cfg_access_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FUNC_CFG_ACCESS, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.reg_access = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FUNC_CFG_ACCESS, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable access to the embedded functions/sensor
+  *         hub configuration registers.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of reg_access in
+  *                               reg FUNC_CFG_ACCESS
+  *
+  */
+int32_t lsm6dso_mem_bank_get(lsm6dso_ctx_t *ctx, lsm6dso_reg_access_t *val)
+{
+  lsm6dso_func_cfg_access_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FUNC_CFG_ACCESS, (uint8_t*)&reg, 1);
+  switch (reg.reg_access) {
+    case LSM6DSO_USER_BANK:
+      *val = LSM6DSO_USER_BANK;
+      break;
+    case LSM6DSO_SENSOR_HUB_BANK:
+      *val = LSM6DSO_SENSOR_HUB_BANK;
+      break;
+    case LSM6DSO_EMBEDDED_FUNC_BANK:
+      *val = LSM6DSO_EMBEDDED_FUNC_BANK;
+      break;
+    default:
+      *val = LSM6DSO_USER_BANK;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Write a line(byte) in a page.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  uint8_t address: page line address
+  * @param  val      value to write
+  *
+  */
+int32_t lsm6dso_ln_pg_write_byte(lsm6dso_ctx_t *ctx, uint16_t address,
+                                 uint8_t *val)
+{
+  lsm6dso_page_rw_t page_rw;
+  lsm6dso_page_sel_t page_sel;
+  lsm6dso_page_address_t page_address;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t*) &page_rw, 1);
+  }
+  if (ret == 0) {
+    page_rw.page_rw = 0x02; /* page_write enable */
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t*) &page_rw, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_SEL, (uint8_t*) &page_sel, 1);
+  }
+
+  if (ret == 0) {
+    page_sel.page_sel = (((uint8_t)address >> 8) & 0x0FU);
+    page_sel.not_used_01 = 1;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_SEL, (uint8_t*) &page_sel, 1);
+  }
+  if (ret == 0) {
+    page_address.page_addr = (uint8_t)address & 0xFFU;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_ADDRESS,
+                            (uint8_t*)&page_address, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_VALUE, val, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t*) &page_rw, 1);
+  }
+  if (ret == 0) {
+    page_rw.page_rw = 0x00; /* page_write disable */
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t*) &page_rw, 1);
+  }
+  if (ret == 0) {
+
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Write buffer in a page.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  uint8_t address: page line address
+  * @param  uint8_t *buf: buffer to write
+  * @param  uint8_t len: buffer len
+  *
+  */
+int32_t lsm6dso_ln_pg_write(lsm6dso_ctx_t *ctx, uint16_t address,
+                            uint8_t *buf, uint8_t len)
+{
+  lsm6dso_page_rw_t page_rw;
+  lsm6dso_page_sel_t page_sel;
+  lsm6dso_page_address_t  page_address;
+  int32_t ret;
+  uint8_t msb, lsb;
+  uint8_t i ;
+
+  msb = (((uint8_t)address >> 8) & 0x0fU);
+  lsb = (uint8_t)address & 0xFFU;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t*) &page_rw, 1);
+  }
+  if (ret == 0) {
+    page_rw.page_rw = 0x02; /* page_write enable*/
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t*) &page_rw, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_SEL, (uint8_t*) &page_sel, 1);
+  }
+  if (ret == 0) {
+    page_sel.page_sel = msb;
+    page_sel.not_used_01 = 1;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_SEL, (uint8_t*) &page_sel, 1);
+  }
+  if (ret == 0) {
+    page_address.page_addr = lsb;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_ADDRESS,
+                            (uint8_t*)&page_address, 1);
+  }
+
+  if (ret == 0) {
+
+    for (i = 0; ( (i < len) && (ret == 0) ); i++)
+    {
+      ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_VALUE, &buf[i], 1);
+
+      /* Check if page wrap */
+      if ( (lsb == 0x00U) && (ret == 0) ) {
+        lsb++;
+        msb++;
+        ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_SEL, (uint8_t*)&page_sel, 1);
+        if (ret == 0) {
+          page_sel.page_sel = msb;
+          page_sel.not_used_01 = 1;
+          ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_SEL,
+                                  (uint8_t*)&page_sel, 1);
+        }
+      }
+    }
+    page_sel.page_sel = 0;
+    page_sel.not_used_01 = 1;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_SEL, (uint8_t*) &page_sel, 1);
+  }
+  if (ret == 0) {
+
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t*) &page_rw, 1);
+  }
+  if (ret == 0) {
+    page_rw.page_rw = 0x00; /* page_write disable */
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t*) &page_rw, 1);
+  }
+
+  if (ret == 0) {
+
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Read a line(byte) in a page.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  uint8_t address: page line address
+  * @param  val      read value
+  *
+  */
+int32_t lsm6dso_ln_pg_read_byte(lsm6dso_ctx_t *ctx, uint16_t address,
+                                uint8_t *val)
+{
+  lsm6dso_page_rw_t page_rw;
+  lsm6dso_page_sel_t page_sel;
+  lsm6dso_page_address_t  page_address;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t*) &page_rw, 1);
+  }
+  if (ret == 0) {
+    page_rw.page_rw = 0x01; /* page_read enable*/
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t*) &page_rw, 1);
+  }
+  if (ret == 0) {
+
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_SEL, (uint8_t*) &page_sel, 1);
+  }
+  if (ret == 0) {
+    page_sel.page_sel = (((uint8_t)address >> 8) & 0x0FU);
+    page_sel.not_used_01 = 1;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_SEL, (uint8_t*) &page_sel, 1);
+  }
+  if (ret == 0) {
+    page_address.page_addr = (uint8_t)address & 0x00FFU;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_ADDRESS,
+                            (uint8_t*)&page_address, 1);
+  }
+  if (ret == 0) {
+
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_VALUE, val, 2);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t*) &page_rw, 1);
+  }
+  if (ret == 0) {
+    page_rw.page_rw = 0x00; /* page_read disable */
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t*) &page_rw, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Data-ready pulsed / letched mode.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of
+  *                                     dataready_pulsed in
+  *                                     reg COUNTER_BDR_REG1
+  *
+  */
+int32_t lsm6dso_data_ready_mode_set(lsm6dso_ctx_t *ctx,
+                                    lsm6dso_dataready_pulsed_t val)
+{
+  lsm6dso_counter_bdr_reg1_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.dataready_pulsed = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Data-ready pulsed / letched mode.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of
+  *                                     dataready_pulsed in
+  *                                     reg COUNTER_BDR_REG1
+  *
+  */
+int32_t lsm6dso_data_ready_mode_get(lsm6dso_ctx_t *ctx,
+                                    lsm6dso_dataready_pulsed_t *val)
+{
+  lsm6dso_counter_bdr_reg1_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, (uint8_t*)&reg, 1);
+  switch (reg.dataready_pulsed) {
+    case LSM6DSO_DRDY_LATCHED:
+      *val = LSM6DSO_DRDY_LATCHED;
+      break;
+    case LSM6DSO_DRDY_PULSED:
+      *val = LSM6DSO_DRDY_PULSED;
+      break;
+    default:
+      *val = LSM6DSO_DRDY_LATCHED;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Device "Who am I".[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_device_id_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_WHO_AM_I, buff, 1);
+  return ret;
+}
+
+/**
+  * @brief  Software reset. Restore the default values
+  *         in user registers[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of sw_reset in reg CTRL3_C
+  *
+  */
+int32_t lsm6dso_reset_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_ctrl3_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.sw_reset = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Software reset. Restore the default values in user registers.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of sw_reset in reg CTRL3_C
+  *
+  */
+int32_t lsm6dso_reset_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_ctrl3_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  *val = reg.sw_reset;
+
+  return ret;
+}
+
+/**
+  * @brief  Register address automatically incremented during a multiple byte
+  *         access with a serial interface.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of if_inc in reg CTRL3_C
+  *
+  */
+int32_t lsm6dso_auto_increment_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_ctrl3_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.if_inc = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Register address automatically incremented during a multiple byte
+  *         access with a serial interface.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of if_inc in reg CTRL3_C
+  *
+  */
+int32_t lsm6dso_auto_increment_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_ctrl3_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  *val = reg.if_inc;
+
+  return ret;
+}
+
+/**
+  * @brief  Reboot memory content. Reload the calibration parameters.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of boot in reg CTRL3_C
+  *
+  */
+int32_t lsm6dso_boot_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_ctrl3_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.boot = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Reboot memory content. Reload the calibration parameters.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of boot in reg CTRL3_C
+  *
+  */
+int32_t lsm6dso_boot_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_ctrl3_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  *val = reg.boot;
+
+  return ret;
+}
+
+/**
+  * @brief  Linear acceleration sensor self-test enable.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of st_xl in reg CTRL5_C
+  *
+  */
+int32_t lsm6dso_xl_self_test_set(lsm6dso_ctx_t *ctx, lsm6dso_st_xl_t val)
+{
+  lsm6dso_ctrl5_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.st_xl = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Linear acceleration sensor self-test enable.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of st_xl in reg CTRL5_C
+  *
+  */
+int32_t lsm6dso_xl_self_test_get(lsm6dso_ctx_t *ctx, lsm6dso_st_xl_t *val)
+{
+  lsm6dso_ctrl5_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t*)&reg, 1);
+  switch (reg.st_xl) {
+    case LSM6DSO_XL_ST_DISABLE:
+      *val = LSM6DSO_XL_ST_DISABLE;
+      break;
+    case LSM6DSO_XL_ST_POSITIVE:
+      *val = LSM6DSO_XL_ST_POSITIVE;
+      break;
+    case LSM6DSO_XL_ST_NEGATIVE:
+      *val = LSM6DSO_XL_ST_NEGATIVE;
+      break;
+    default:
+      *val = LSM6DSO_XL_ST_DISABLE;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Angular rate sensor self-test enable.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of st_g in reg CTRL5_C
+  *
+  */
+int32_t lsm6dso_gy_self_test_set(lsm6dso_ctx_t *ctx, lsm6dso_st_g_t val)
+{
+  lsm6dso_ctrl5_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.st_g = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Angular rate sensor self-test enable.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of st_g in reg CTRL5_C
+  *
+  */
+int32_t lsm6dso_gy_self_test_get(lsm6dso_ctx_t *ctx, lsm6dso_st_g_t *val)
+{
+  lsm6dso_ctrl5_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t*)&reg, 1);
+  switch (reg.st_g) {
+    case LSM6DSO_GY_ST_DISABLE:
+      *val = LSM6DSO_GY_ST_DISABLE;
+      break;
+    case LSM6DSO_GY_ST_POSITIVE:
+      *val = LSM6DSO_GY_ST_POSITIVE;
+      break;
+    case LSM6DSO_GY_ST_NEGATIVE:
+      *val = LSM6DSO_GY_ST_NEGATIVE;
+      break;
+    default:
+      *val = LSM6DSO_GY_ST_DISABLE;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_filters
+  * @brief     This section group all the functions concerning the
+  *            filters configuration
+  * @{
+  *
+*/
+
+/**
+  * @brief  Accelerometer output from LPF2 filtering stage selection.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of lpf2_xl_en in reg CTRL1_XL
+  *
+  */
+int32_t lsm6dso_xl_filter_lp2_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_ctrl1_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.lpf2_xl_en = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer output from LPF2 filtering stage selection.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of lpf2_xl_en in reg CTRL1_XL
+  *
+  */
+int32_t lsm6dso_xl_filter_lp2_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_ctrl1_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t*)&reg, 1);
+  *val = reg.lpf2_xl_en;
+
+  return ret;
+}
+
+/**
+  * @brief  Enables gyroscope digital LPF1 if auxiliary SPI is disabled;
+  *         the bandwidth can be selected through FTYPE [2:0]
+  *         in CTRL6_C (15h).[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of lpf1_sel_g in reg CTRL4_C
+  *
+  */
+int32_t lsm6dso_gy_filter_lp1_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_ctrl4_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.lpf1_sel_g = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enables gyroscope digital LPF1 if auxiliary SPI is disabled;
+  *         the bandwidth can be selected through FTYPE [2:0]
+  *         in CTRL6_C (15h).[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of lpf1_sel_g in reg CTRL4_C
+  *
+  */
+int32_t lsm6dso_gy_filter_lp1_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_ctrl4_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t*)&reg, 1);
+  *val = reg.lpf1_sel_g;
+
+  return ret;
+}
+
+/**
+  * @brief  Mask DRDY on pin (both XL & Gyro) until filter settling ends
+  *         (XL and Gyro independently masked).[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of drdy_mask in reg CTRL4_C
+  *
+  */
+int32_t lsm6dso_filter_settling_mask_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_ctrl4_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.drdy_mask = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Mask DRDY on pin (both XL & Gyro) until filter settling ends
+  *         (XL and Gyro independently masked).[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of drdy_mask in reg CTRL4_C
+  *
+  */
+int32_t lsm6dso_filter_settling_mask_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_ctrl4_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t*)&reg, 1);
+  *val = reg.drdy_mask;
+
+  return ret;
+}
+
+/**
+  * @brief  Gyroscope lp1 bandwidth.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of ftype in reg CTRL6_C
+  *
+  */
+int32_t lsm6dso_gy_lp1_bandwidth_set(lsm6dso_ctx_t *ctx, lsm6dso_ftype_t val)
+{
+  lsm6dso_ctrl6_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.ftype = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Gyroscope lp1 bandwidth.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val       Get the values of ftype in reg CTRL6_C
+  *
+  */
+int32_t lsm6dso_gy_lp1_bandwidth_get(lsm6dso_ctx_t *ctx, lsm6dso_ftype_t *val)
+{
+  lsm6dso_ctrl6_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t*)&reg, 1);
+  switch (reg.ftype) {
+    case LSM6DSO_ULTRA_LIGHT:
+      *val = LSM6DSO_ULTRA_LIGHT;
+      break;
+    case LSM6DSO_VERY_LIGHT:
+      *val = LSM6DSO_VERY_LIGHT;
+      break;
+    case LSM6DSO_LIGHT:
+      *val = LSM6DSO_LIGHT;
+      break;
+    case LSM6DSO_MEDIUM:
+      *val = LSM6DSO_MEDIUM;
+      break;
+    case LSM6DSO_STRONG:
+      *val = LSM6DSO_STRONG;
+      break;
+    case LSM6DSO_VERY_STRONG:
+      *val = LSM6DSO_VERY_STRONG;
+      break;
+    case LSM6DSO_AGGRESSIVE:
+      *val = LSM6DSO_AGGRESSIVE;
+      break;
+    case LSM6DSO_XTREME:
+      *val = LSM6DSO_XTREME;
+      break;
+    default:
+      *val = LSM6DSO_ULTRA_LIGHT;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Low pass filter 2 on 6D function selection.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of low_pass_on_6d in reg CTRL8_XL
+  *
+  */
+int32_t lsm6dso_xl_lp2_on_6d_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_ctrl8_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.low_pass_on_6d = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Low pass filter 2 on 6D function selection.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of low_pass_on_6d in reg CTRL8_XL
+  *
+  */
+int32_t lsm6dso_xl_lp2_on_6d_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_ctrl8_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t*)&reg, 1);
+  *val = reg.low_pass_on_6d;
+
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer slope filter / high-pass filter selection
+  *         on output.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of hp_slope_xl_en
+  *                                   in reg CTRL8_XL
+  *
+  */
+int32_t lsm6dso_xl_hp_path_on_out_set(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_hp_slope_xl_en_t val)
+{
+  lsm6dso_ctrl8_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.hp_slope_xl_en = ((uint8_t)val & 0x10U) >> 4;
+    reg.hp_ref_mode_xl = ((uint8_t)val & 0x20U) >> 5;
+    reg.hpcf_xl = (uint8_t)val & 0x07U;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer slope filter / high-pass filter selection
+  *         on output.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of hp_slope_xl_en
+  *                                   in reg CTRL8_XL
+  *
+  */
+int32_t lsm6dso_xl_hp_path_on_out_get(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_hp_slope_xl_en_t *val)
+{
+  lsm6dso_ctrl8_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t*)&reg, 1);
+  switch ((reg.hp_ref_mode_xl << 5) | (reg.hp_slope_xl_en << 4) |
+          reg.hpcf_xl) {
+    case LSM6DSO_HP_PATH_DISABLE_ON_OUT:
+      *val = LSM6DSO_HP_PATH_DISABLE_ON_OUT;
+      break;
+    case LSM6DSO_SLOPE_ODR_DIV_4:
+      *val = LSM6DSO_SLOPE_ODR_DIV_4;
+      break;
+    case LSM6DSO_HP_ODR_DIV_10:
+      *val = LSM6DSO_HP_ODR_DIV_10;
+      break;
+    case LSM6DSO_HP_ODR_DIV_20:
+      *val = LSM6DSO_HP_ODR_DIV_20;
+      break;
+    case LSM6DSO_HP_ODR_DIV_45:
+      *val = LSM6DSO_HP_ODR_DIV_45;
+      break;
+    case LSM6DSO_HP_ODR_DIV_100:
+      *val = LSM6DSO_HP_ODR_DIV_100;
+      break;
+    case LSM6DSO_HP_ODR_DIV_200:
+      *val = LSM6DSO_HP_ODR_DIV_200;
+      break;
+    case LSM6DSO_HP_ODR_DIV_400:
+      *val = LSM6DSO_HP_ODR_DIV_400;
+      break;
+    case LSM6DSO_HP_ODR_DIV_800:
+      *val = LSM6DSO_HP_ODR_DIV_800;
+      break;
+    case LSM6DSO_HP_REF_MD_ODR_DIV_10:
+      *val = LSM6DSO_HP_REF_MD_ODR_DIV_10;
+      break;
+    case LSM6DSO_HP_REF_MD_ODR_DIV_20:
+      *val = LSM6DSO_HP_REF_MD_ODR_DIV_20;
+      break;
+    case LSM6DSO_HP_REF_MD_ODR_DIV_45:
+      *val = LSM6DSO_HP_REF_MD_ODR_DIV_45;
+      break;
+    case LSM6DSO_HP_REF_MD_ODR_DIV_100:
+      *val = LSM6DSO_HP_REF_MD_ODR_DIV_100;
+      break;
+    case LSM6DSO_HP_REF_MD_ODR_DIV_200:
+      *val = LSM6DSO_HP_REF_MD_ODR_DIV_200;
+      break;
+    case LSM6DSO_HP_REF_MD_ODR_DIV_400:
+      *val = LSM6DSO_HP_REF_MD_ODR_DIV_400;
+      break;
+    case LSM6DSO_HP_REF_MD_ODR_DIV_800:
+      *val = LSM6DSO_HP_REF_MD_ODR_DIV_800;
+      break;
+    case LSM6DSO_LP_ODR_DIV_10:
+      *val = LSM6DSO_LP_ODR_DIV_10;
+      break;
+    case LSM6DSO_LP_ODR_DIV_20:
+      *val = LSM6DSO_LP_ODR_DIV_20;
+      break;
+    case LSM6DSO_LP_ODR_DIV_45:
+      *val = LSM6DSO_LP_ODR_DIV_45;
+      break;
+    case LSM6DSO_LP_ODR_DIV_100:
+      *val = LSM6DSO_LP_ODR_DIV_100;
+      break;
+    case LSM6DSO_LP_ODR_DIV_200:
+      *val = LSM6DSO_LP_ODR_DIV_200;
+      break;
+    case LSM6DSO_LP_ODR_DIV_400:
+      *val = LSM6DSO_LP_ODR_DIV_400;
+      break;
+    case LSM6DSO_LP_ODR_DIV_800:
+      *val = LSM6DSO_LP_ODR_DIV_800;
+      break;
+    default:
+      *val = LSM6DSO_HP_PATH_DISABLE_ON_OUT;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Enables accelerometer LPF2 and HPF fast-settling mode.
+  *         The filter sets the second samples after writing this bit.
+  *         Active only during device exit from power-down mode.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of fastsettl_mode_xl in
+  *                  reg CTRL8_XL
+  *
+  */
+int32_t lsm6dso_xl_fast_settling_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_ctrl8_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.fastsettl_mode_xl = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enables accelerometer LPF2 and HPF fast-settling mode.
+  *         The filter sets the second samples after writing this bit.
+  *         Active only during device exit from power-down mode.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of fastsettl_mode_xl in reg CTRL8_XL
+  *
+  */
+int32_t lsm6dso_xl_fast_settling_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_ctrl8_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t*)&reg, 1);
+  *val = reg.fastsettl_mode_xl;
+
+  return ret;
+}
+
+/**
+  * @brief  HPF or SLOPE filter selection on wake-up and Activity/Inactivity
+  *         functions.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of slope_fds in reg TAP_CFG0
+  *
+  */
+int32_t lsm6dso_xl_hp_path_internal_set(lsm6dso_ctx_t *ctx,
+                                        lsm6dso_slope_fds_t val)
+{
+  lsm6dso_tap_cfg0_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.slope_fds = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  HPF or SLOPE filter selection on wake-up and Activity/Inactivity
+  *         functions.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of slope_fds in reg TAP_CFG0
+  *
+  */
+int32_t lsm6dso_xl_hp_path_internal_get(lsm6dso_ctx_t *ctx,
+                                        lsm6dso_slope_fds_t *val)
+{
+  lsm6dso_tap_cfg0_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*)&reg, 1);
+  switch (reg.slope_fds) {
+    case LSM6DSO_USE_SLOPE:
+      *val = LSM6DSO_USE_SLOPE;
+      break;
+    case LSM6DSO_USE_HPF:
+      *val = LSM6DSO_USE_HPF;
+      break;
+    default:
+      *val = LSM6DSO_USE_SLOPE;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enables gyroscope digital high-pass filter. The filter is
+  *         enabled only if the gyro is in HP mode.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of hp_en_g and hp_en_g
+  *                            in reg CTRL7_G
+  *
+  */
+int32_t lsm6dso_gy_hp_path_internal_set(lsm6dso_ctx_t *ctx,
+                                        lsm6dso_hpm_g_t val)
+{
+  lsm6dso_ctrl7_g_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.hp_en_g = ((uint8_t)val & 0x80U) >> 7;
+    reg.hpm_g = (uint8_t)val & 0x03U;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enables gyroscope digital high-pass filter. The filter is
+  *         enabled only if the gyro is in HP mode.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of hp_en_g and hp_en_g
+  *                            in reg CTRL7_G
+  *
+  */
+int32_t lsm6dso_gy_hp_path_internal_get(lsm6dso_ctx_t *ctx,
+                                        lsm6dso_hpm_g_t *val)
+{
+  lsm6dso_ctrl7_g_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t*)&reg, 1);
+  switch ((reg.hp_en_g << 7) + reg.hpm_g) {
+    case LSM6DSO_HP_FILTER_NONE:
+      *val = LSM6DSO_HP_FILTER_NONE;
+      break;
+    case LSM6DSO_HP_FILTER_16mHz:
+      *val = LSM6DSO_HP_FILTER_16mHz;
+      break;
+    case LSM6DSO_HP_FILTER_65mHz:
+      *val = LSM6DSO_HP_FILTER_65mHz;
+      break;
+    case LSM6DSO_HP_FILTER_260mHz:
+      *val = LSM6DSO_HP_FILTER_260mHz;
+      break;
+    case LSM6DSO_HP_FILTER_1Hz04:
+      *val = LSM6DSO_HP_FILTER_1Hz04;
+      break;
+    default:
+      *val = LSM6DSO_HP_FILTER_NONE;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_ Auxiliary_interface
+  * @brief     This section groups all the functions concerning
+  *            auxiliary interface.
+  * @{
+  *
+*/
+
+/**
+  * @brief  aOn auxiliary interface connect/disconnect SDO and OCS
+  *         internal pull-up.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of ois_pu_dis in
+  *                               reg PIN_CTRL
+  *
+  */
+int32_t lsm6dso_aux_sdo_ocs_mode_set(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_ois_pu_dis_t val)
+{
+  lsm6dso_pin_ctrl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_PIN_CTRL, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.ois_pu_dis = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PIN_CTRL, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  On auxiliary interface connect/disconnect SDO and OCS
+  *         internal pull-up.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of ois_pu_dis in reg PIN_CTRL
+  *
+  */
+int32_t lsm6dso_aux_sdo_ocs_mode_get(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_ois_pu_dis_t *val)
+{
+  lsm6dso_pin_ctrl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_PIN_CTRL, (uint8_t*)&reg, 1);
+  switch (reg.ois_pu_dis) {
+    case LSM6DSO_AUX_PULL_UP_DISC:
+      *val = LSM6DSO_AUX_PULL_UP_DISC;
+      break;
+    case LSM6DSO_AUX_PULL_UP_CONNECT:
+      *val = LSM6DSO_AUX_PULL_UP_CONNECT;
+      break;
+    default:
+      *val = LSM6DSO_AUX_PULL_UP_DISC;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  OIS chain on aux interface power on mode.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of ois_on in reg CTRL7_G
+  *
+  */
+int32_t lsm6dso_aux_pw_on_ctrl_set(lsm6dso_ctx_t *ctx, lsm6dso_ois_on_t val)
+{
+  lsm6dso_ctrl7_g_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.ois_on_en = (uint8_t)val & 0x01U;
+    reg.ois_on = (uint8_t)val & 0x01U;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  aux_pw_on_ctrl: [get]  OIS chain on aux interface power on mode
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of ois_on in reg CTRL7_G
+  *
+  */
+int32_t lsm6dso_aux_pw_on_ctrl_get(lsm6dso_ctx_t *ctx, lsm6dso_ois_on_t *val)
+{
+  lsm6dso_ctrl7_g_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t*)&reg, 1);
+  switch (reg.ois_on) {
+    case LSM6DSO_AUX_ON:
+      *val = LSM6DSO_AUX_ON;
+      break;
+    case LSM6DSO_AUX_ON_BY_AUX_INTERFACE:
+      *val = LSM6DSO_AUX_ON_BY_AUX_INTERFACE;
+      break;
+    default:
+      *val = LSM6DSO_AUX_ON;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer full-scale management between UI chain and
+  *         OIS chain. When XL UI is on, the full scale is the same
+  *         between UI/OIS and is chosen by the UI CTRL registers;
+  *         when XL UI is in PD, the OIS can choose the FS.
+  *         Full scales are independent between the UI/OIS chain
+  *         but both bound to 8 g.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of xl_fs_mode in
+  *                               reg CTRL8_XL
+  *
+  */
+int32_t lsm6dso_aux_xl_fs_mode_set(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_xl_fs_mode_t val)
+{
+  lsm6dso_ctrl8_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.xl_fs_mode = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Accelerometer full-scale management between UI chain and
+  *         OIS chain. When XL UI is on, the full scale is the same
+  *         between UI/OIS and is chosen by the UI CTRL registers;
+  *         when XL UI is in PD, the OIS can choose the FS.
+  *         Full scales are independent between the UI/OIS chain
+  *         but both bound to 8 g.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of xl_fs_mode in reg CTRL8_XL
+  *
+  */
+int32_t lsm6dso_aux_xl_fs_mode_get(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_xl_fs_mode_t *val)
+{
+  lsm6dso_ctrl8_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t*)&reg, 1);
+  switch (reg.xl_fs_mode) {
+    case LSM6DSO_USE_SAME_XL_FS:
+      *val = LSM6DSO_USE_SAME_XL_FS;
+      break;
+    case LSM6DSO_USE_DIFFERENT_XL_FS:
+      *val = LSM6DSO_USE_DIFFERENT_XL_FS;
+      break;
+    default:
+      *val = LSM6DSO_USE_SAME_XL_FS;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  The STATUS_SPIAux register is read by the auxiliary SPI.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  lsm6dso_status_spiaux_t: registers STATUS_SPIAUX
+  *
+  */
+int32_t lsm6dso_aux_status_reg_get(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_status_spiaux_t *val)
+{
+  int32_t ret;
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_SPIAUX, (uint8_t*) val, 1);
+  return ret;
+}
+
+/**
+  * @brief  aux_xl_flag_data_ready: [get]  AUX accelerometer data available
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of xlda in reg STATUS_SPIAUX
+  *
+  */
+int32_t lsm6dso_aux_xl_flag_data_ready_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_status_spiaux_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_SPIAUX, (uint8_t*)&reg, 1);
+  *val = reg.xlda;
+
+  return ret;
+}
+
+/**
+  * @brief  aux_gy_flag_data_ready: [get]  AUX gyroscope data available.
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of gda in reg STATUS_SPIAUX
+  *
+  */
+int32_t lsm6dso_aux_gy_flag_data_ready_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_status_spiaux_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_SPIAUX, (uint8_t*)&reg, 1);
+  *val = reg.gda;
+
+  return ret;
+}
+
+/**
+  * @brief  High when the gyroscope output is in the settling phase.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of gyro_settling in reg STATUS_SPIAUX
+  *
+  */
+int32_t lsm6dso_aux_gy_flag_settling_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_status_spiaux_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_SPIAUX, (uint8_t*)&reg, 1);
+  *val = reg.gyro_settling;
+
+  return ret;
+}
+
+/**
+  * @brief  Selects accelerometer self-test. Effective only if XL OIS
+  *         chain is enabled.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of st_xl_ois in reg INT_OIS
+  *
+  */
+int32_t lsm6dso_aux_xl_self_test_set(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_st_xl_ois_t val)
+{
+  lsm6dso_int_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_OIS, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.st_xl_ois = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_INT_OIS, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects accelerometer self-test. Effective only if XL OIS
+  *         chain is enabled.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of st_xl_ois in reg INT_OIS
+  *
+  */
+int32_t lsm6dso_aux_xl_self_test_get(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_st_xl_ois_t *val)
+{
+  lsm6dso_int_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_OIS, (uint8_t*)&reg, 1);
+  switch (reg.st_xl_ois) {
+    case LSM6DSO_AUX_XL_DISABLE:
+      *val = LSM6DSO_AUX_XL_DISABLE;
+      break;
+    case LSM6DSO_AUX_XL_POS:
+      *val = LSM6DSO_AUX_XL_POS;
+      break;
+    case LSM6DSO_AUX_XL_NEG:
+      *val = LSM6DSO_AUX_XL_NEG;
+      break;
+    default:
+      *val = LSM6DSO_AUX_XL_DISABLE;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Indicates polarity of DEN signal on OIS chain.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of den_lh_ois in
+  *                  reg INT_OIS
+  *
+  */
+int32_t lsm6dso_aux_den_polarity_set(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_den_lh_ois_t val)
+{
+  lsm6dso_int_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_OIS, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.den_lh_ois = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_INT_OIS, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Indicates polarity of DEN signal on OIS chain.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of den_lh_ois in reg INT_OIS
+  *
+  */
+int32_t lsm6dso_aux_den_polarity_get(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_den_lh_ois_t *val)
+{
+  lsm6dso_int_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_OIS, (uint8_t*)&reg, 1);
+  switch (reg.den_lh_ois) {
+    case LSM6DSO_AUX_DEN_ACTIVE_LOW:
+      *val = LSM6DSO_AUX_DEN_ACTIVE_LOW;
+      break;
+    case LSM6DSO_AUX_DEN_ACTIVE_HIGH:
+      *val = LSM6DSO_AUX_DEN_ACTIVE_HIGH;
+      break;
+    default:
+      *val = LSM6DSO_AUX_DEN_ACTIVE_LOW;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Configure DEN mode on the OIS chain.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of lvl2_ois in reg INT_OIS
+  *
+  */
+int32_t lsm6dso_aux_den_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_lvl2_ois_t val)
+{
+  lsm6dso_ctrl1_ois_t ctrl1_ois;
+  lsm6dso_int_ois_t int_ois;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_OIS, (uint8_t*) &int_ois, 1);
+  if (ret == 0) {
+    int_ois.lvl2_ois = (uint8_t)val & 0x01U;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_INT_OIS, (uint8_t*) &int_ois, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t*) &ctrl1_ois, 1);
+  }
+  if (ret == 0) {
+    ctrl1_ois.lvl1_ois = ((uint8_t)val & 0x02U) >> 1;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t*) &ctrl1_ois, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Configure DEN mode on the OIS chain.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of lvl2_ois in reg INT_OIS
+  *
+  */
+int32_t lsm6dso_aux_den_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_lvl2_ois_t *val)
+{
+  lsm6dso_ctrl1_ois_t ctrl1_ois;
+  lsm6dso_int_ois_t int_ois;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_OIS, (uint8_t*) &int_ois, 1);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t*) &ctrl1_ois, 1);
+    switch ((ctrl1_ois.lvl1_ois << 1) + int_ois.lvl2_ois) {
+      case LSM6DSO_AUX_DEN_DISABLE:
+        *val = LSM6DSO_AUX_DEN_DISABLE;
+        break;
+      case LSM6DSO_AUX_DEN_LEVEL_LATCH:
+        *val = LSM6DSO_AUX_DEN_LEVEL_LATCH;
+        break;
+      case LSM6DSO_AUX_DEN_LEVEL_TRIG:
+        *val = LSM6DSO_AUX_DEN_LEVEL_TRIG;
+        break;
+      default:
+        *val = LSM6DSO_AUX_DEN_DISABLE;
+        break;
+    }
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enables/Disable OIS chain DRDY on INT2 pin.
+  *         This setting has priority over all other INT2 settings.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of int2_drdy_ois in reg INT_OIS
+  *
+  */
+int32_t lsm6dso_aux_drdy_on_int2_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_int_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_OIS, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.int2_drdy_ois = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_INT_OIS, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enables/Disable OIS chain DRDY on INT2 pin.
+  *         This setting has priority over all other INT2 settings.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of int2_drdy_ois in reg INT_OIS
+  *
+  */
+int32_t lsm6dso_aux_drdy_on_int2_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_int_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_OIS, (uint8_t*)&reg, 1);
+  *val = reg.int2_drdy_ois;
+
+  return ret;
+}
+
+/**
+  * @brief  Enables OIS chain data processing for gyro in Mode 3 and Mode 4
+  *         (mode4_en = 1) and accelerometer data in and Mode 4 (mode4_en = 1).
+  *         When the OIS chain is enabled, the OIS outputs are available
+  *         through the SPI2 in registers OUTX_L_G (22h) through
+  *         OUTZ_H_G (27h) and STATUS_REG (1Eh) / STATUS_SPIAux, and
+  *         LPF1 is dedicated to this chain.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of ois_en_spi2 in
+  *                                reg CTRL1_OIS
+  *
+  */
+int32_t lsm6dso_aux_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_ois_en_spi2_t val)
+{
+  lsm6dso_ctrl1_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.ois_en_spi2 = (uint8_t)val & 0x01U;
+    reg.mode4_en = ((uint8_t)val & 0x02U) >> 1;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enables OIS chain data processing for gyro in Mode 3 and Mode 4
+  *         (mode4_en = 1) and accelerometer data in and Mode 4 (mode4_en = 1).
+  *         When the OIS chain is enabled, the OIS outputs are available
+  *         through the SPI2 in registers OUTX_L_G (22h) through
+  *         OUTZ_H_G (27h) and STATUS_REG (1Eh) / STATUS_SPIAux, and
+  *         LPF1 is dedicated to this chain.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of ois_en_spi2 in
+  *                                reg CTRL1_OIS
+  *
+  */
+int32_t lsm6dso_aux_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_ois_en_spi2_t *val)
+{
+  lsm6dso_ctrl1_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t*)&reg, 1);
+  switch ((reg.mode4_en << 1) | reg.ois_en_spi2) {
+    case LSM6DSO_AUX_DISABLE:
+      *val = LSM6DSO_AUX_DISABLE;
+      break;
+    case LSM6DSO_MODE_3_GY:
+      *val = LSM6DSO_MODE_3_GY;
+      break;
+    case LSM6DSO_MODE_4_GY_XL:
+      *val = LSM6DSO_MODE_4_GY_XL;
+      break;
+    default:
+      *val = LSM6DSO_AUX_DISABLE;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects gyroscope OIS chain full-scale.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of fs_g_ois in reg CTRL1_OIS
+  *
+  */
+int32_t lsm6dso_aux_gy_full_scale_set(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_fs_g_ois_t val)
+{
+  lsm6dso_ctrl1_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.fs_g_ois = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects gyroscope OIS chain full-scale.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of fs_g_ois in reg CTRL1_OIS
+  *
+  */
+int32_t lsm6dso_aux_gy_full_scale_get(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_fs_g_ois_t *val)
+{
+  lsm6dso_ctrl1_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t*)&reg, 1);
+  switch (reg.fs_g_ois) {
+    case LSM6DSO_250dps_AUX:
+      *val = LSM6DSO_250dps_AUX;
+      break;
+    case LSM6DSO_125dps_AUX:
+      *val = LSM6DSO_125dps_AUX;
+      break;
+    case LSM6DSO_500dps_AUX:
+      *val = LSM6DSO_500dps_AUX;
+      break;
+    case LSM6DSO_1000dps_AUX:
+      *val = LSM6DSO_1000dps_AUX;
+      break;
+    case LSM6DSO_2000dps_AUX:
+      *val = LSM6DSO_2000dps_AUX;
+      break;
+    default:
+      *val = LSM6DSO_250dps_AUX;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  SPI2 3- or 4-wire interface.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of sim_ois in reg CTRL1_OIS
+  *
+  */
+int32_t lsm6dso_aux_spi_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_sim_ois_t val)
+{
+  lsm6dso_ctrl1_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.sim_ois = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  SPI2 3- or 4-wire interface.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of sim_ois in reg CTRL1_OIS
+  *
+  */
+int32_t lsm6dso_aux_spi_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_sim_ois_t *val)
+{
+  lsm6dso_ctrl1_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t*)&reg, 1);
+  switch (reg.sim_ois) {
+    case LSM6DSO_AUX_SPI_4_WIRE:
+      *val = LSM6DSO_AUX_SPI_4_WIRE;
+      break;
+    case LSM6DSO_AUX_SPI_3_WIRE:
+      *val = LSM6DSO_AUX_SPI_3_WIRE;
+      break;
+    default:
+      *val = LSM6DSO_AUX_SPI_4_WIRE;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects gyroscope digital LPF1 filter bandwidth.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of ftype_ois in
+  *                              reg CTRL2_OIS
+  *
+  */
+int32_t lsm6dso_aux_gy_lp1_bandwidth_set(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_ftype_ois_t val)
+{
+  lsm6dso_ctrl2_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_OIS, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.ftype_ois = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL2_OIS, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects gyroscope digital LPF1 filter bandwidth.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of ftype_ois in reg CTRL2_OIS
+  *
+  */
+int32_t lsm6dso_aux_gy_lp1_bandwidth_get(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_ftype_ois_t *val)
+{
+  lsm6dso_ctrl2_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_OIS, (uint8_t*)&reg, 1);
+  switch (reg.ftype_ois) {
+    case LSM6DSO_351Hz39:
+      *val = LSM6DSO_351Hz39;
+      break;
+    case LSM6DSO_236Hz63:
+      *val = LSM6DSO_236Hz63;
+      break;
+    case LSM6DSO_172Hz70:
+      *val = LSM6DSO_172Hz70;
+      break;
+    case LSM6DSO_937Hz91:
+      *val = LSM6DSO_937Hz91;
+      break;
+    default:
+      *val = LSM6DSO_351Hz39;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects gyroscope OIS chain digital high-pass filter cutoff.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of hpm_ois in reg CTRL2_OIS
+  *
+  */
+int32_t lsm6dso_aux_gy_hp_bandwidth_set(lsm6dso_ctx_t *ctx,
+                                        lsm6dso_hpm_ois_t val)
+{
+  lsm6dso_ctrl2_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_OIS, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.hpm_ois = (uint8_t)val & 0x03U;
+    reg.hp_en_ois = ((uint8_t)val & 0x10U) >> 4;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL2_OIS, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects gyroscope OIS chain digital high-pass filter cutoff.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of hpm_ois in reg CTRL2_OIS
+  *
+  */
+int32_t lsm6dso_aux_gy_hp_bandwidth_get(lsm6dso_ctx_t *ctx,
+                                        lsm6dso_hpm_ois_t *val)
+{
+  lsm6dso_ctrl2_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_OIS, (uint8_t*)&reg, 1);
+  switch ((reg.hp_en_ois << 4) | reg.hpm_ois) {
+    case LSM6DSO_AUX_HP_DISABLE:
+      *val = LSM6DSO_AUX_HP_DISABLE;
+      break;
+    case LSM6DSO_AUX_HP_Hz016:
+      *val = LSM6DSO_AUX_HP_Hz016;
+      break;
+    case LSM6DSO_AUX_HP_Hz065:
+      *val = LSM6DSO_AUX_HP_Hz065;
+      break;
+    case LSM6DSO_AUX_HP_Hz260:
+      *val = LSM6DSO_AUX_HP_Hz260;
+      break;
+    case LSM6DSO_AUX_HP_1Hz040:
+      *val = LSM6DSO_AUX_HP_1Hz040;
+      break;
+    default:
+      *val = LSM6DSO_AUX_HP_DISABLE;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable / Disables OIS chain clamp.
+  *         Enable: All OIS chain outputs = 8000h
+  *         during self-test; Disable: OIS chain self-test
+  *         outputs dependent from the aux gyro full
+  *         scale selected.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of st_ois_clampdis in
+  *                                    reg CTRL3_OIS
+  *
+  */
+int32_t lsm6dso_aux_gy_clamp_set(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_st_ois_clampdis_t val)
+{
+  lsm6dso_ctrl3_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.st_ois_clampdis = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable / Disables OIS chain clamp.
+  *         Enable: All OIS chain outputs = 8000h
+  *         during self-test; Disable: OIS chain self-test
+  *         outputs dependent from the aux gyro full
+  *         scale selected.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of st_ois_clampdis in
+  *                                    reg CTRL3_OIS
+  *
+  */
+int32_t lsm6dso_aux_gy_clamp_get(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_st_ois_clampdis_t *val)
+{
+  lsm6dso_ctrl3_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t*)&reg, 1);
+  switch (reg.st_ois_clampdis) {
+    case LSM6DSO_ENABLE_CLAMP:
+      *val = LSM6DSO_ENABLE_CLAMP;
+      break;
+    case LSM6DSO_DISABLE_CLAMP:
+      *val = LSM6DSO_DISABLE_CLAMP;
+      break;
+    default:
+      *val = LSM6DSO_ENABLE_CLAMP;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects gyroscope OIS chain self-test.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of st_ois in reg CTRL3_OIS
+  *
+  */
+int32_t lsm6dso_aux_gy_self_test_set(lsm6dso_ctx_t *ctx, lsm6dso_st_ois_t val)
+{
+  lsm6dso_ctrl3_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.st_ois = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects gyroscope OIS chain self-test.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of st_ois in reg CTRL3_OIS
+  *
+  */
+int32_t lsm6dso_aux_gy_self_test_get(lsm6dso_ctx_t *ctx, lsm6dso_st_ois_t *val)
+{
+  lsm6dso_ctrl3_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t*)&reg, 1);
+  switch (reg.st_ois) {
+    case LSM6DSO_AUX_GY_DISABLE:
+      *val = LSM6DSO_AUX_GY_DISABLE;
+      break;
+    case LSM6DSO_AUX_GY_POS:
+      *val = LSM6DSO_AUX_GY_POS;
+      break;
+    case LSM6DSO_AUX_GY_NEG:
+      *val = LSM6DSO_AUX_GY_NEG;
+      break;
+    default:
+      *val = LSM6DSO_AUX_GY_DISABLE;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects accelerometer OIS channel bandwidth.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of
+  *                                       filter_xl_conf_ois in reg CTRL3_OIS
+  *
+  */
+int32_t lsm6dso_aux_xl_bandwidth_set(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_filter_xl_conf_ois_t val)
+{
+  lsm6dso_ctrl3_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.filter_xl_conf_ois = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects accelerometer OIS channel bandwidth.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of
+  *                                       filter_xl_conf_ois in reg CTRL3_OIS
+  *
+  */
+int32_t lsm6dso_aux_xl_bandwidth_get(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_filter_xl_conf_ois_t *val)
+{
+  lsm6dso_ctrl3_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t*)&reg, 1);
+
+  switch (reg.filter_xl_conf_ois) {
+    case LSM6DSO_289Hz:
+      *val = LSM6DSO_289Hz;
+      break;
+    case LSM6DSO_258Hz:
+      *val = LSM6DSO_258Hz;
+      break;
+    case LSM6DSO_120Hz:
+      *val = LSM6DSO_120Hz;
+      break;
+    case LSM6DSO_65Hz2:
+      *val = LSM6DSO_65Hz2;
+      break;
+    case LSM6DSO_33Hz2:
+      *val = LSM6DSO_33Hz2;
+      break;
+    case LSM6DSO_16Hz6:
+      *val = LSM6DSO_16Hz6;
+      break;
+    case LSM6DSO_8Hz30:
+      *val = LSM6DSO_8Hz30;
+      break;
+    case LSM6DSO_4Hz15:
+      *val = LSM6DSO_4Hz15;
+      break;
+    default:
+      *val = LSM6DSO_289Hz;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects accelerometer OIS channel full-scale.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of fs_xl_ois in
+  *                              reg CTRL3_OIS
+  *
+  */
+int32_t lsm6dso_aux_xl_full_scale_set(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_fs_xl_ois_t val)
+{
+  lsm6dso_ctrl3_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.fs_xl_ois = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects accelerometer OIS channel full-scale.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of fs_xl_ois in reg CTRL3_OIS
+  *
+  */
+int32_t lsm6dso_aux_xl_full_scale_get(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_fs_xl_ois_t *val)
+{
+  lsm6dso_ctrl3_ois_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t*)&reg, 1);
+  switch (reg.fs_xl_ois) {
+    case LSM6DSO_AUX_2g:
+      *val = LSM6DSO_AUX_2g;
+      break;
+    case LSM6DSO_AUX_16g:
+      *val = LSM6DSO_AUX_16g;
+      break;
+    case LSM6DSO_AUX_4g:
+      *val = LSM6DSO_AUX_4g;
+      break;
+    case LSM6DSO_AUX_8g:
+      *val = LSM6DSO_AUX_8g;
+      break;
+    default:
+      *val = LSM6DSO_AUX_2g;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_ main_serial_interface
+  * @brief     This section groups all the functions concerning main
+  *            serial interface management (not auxiliary)
+  * @{
+  *
+*/
+
+/**
+  * @brief  Connect/Disconnect SDO/SA0 internal pull-up.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of sdo_pu_en in
+  *                              reg PIN_CTRL
+  *
+  */
+int32_t lsm6dso_sdo_sa0_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_sdo_pu_en_t val)
+{
+  lsm6dso_pin_ctrl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_PIN_CTRL, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.sdo_pu_en = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PIN_CTRL, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Connect/Disconnect SDO/SA0 internal pull-up.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of sdo_pu_en in reg PIN_CTRL
+  *
+  */
+int32_t lsm6dso_sdo_sa0_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_sdo_pu_en_t *val)
+{
+  lsm6dso_pin_ctrl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_PIN_CTRL, (uint8_t*)&reg, 1);
+  switch (reg.sdo_pu_en) {
+    case LSM6DSO_PULL_UP_DISC:
+      *val = LSM6DSO_PULL_UP_DISC;
+      break;
+    case LSM6DSO_PULL_UP_CONNECT:
+      *val = LSM6DSO_PULL_UP_CONNECT;
+      break;
+    default:
+      *val = LSM6DSO_PULL_UP_DISC;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  SPI Serial Interface Mode selection.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of sim in reg CTRL3_C
+  *
+  */
+int32_t lsm6dso_spi_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_sim_t val)
+{
+  lsm6dso_ctrl3_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.sim = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  SPI Serial Interface Mode selection.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of sim in reg CTRL3_C
+  *
+  */
+int32_t lsm6dso_spi_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_sim_t *val)
+{
+  lsm6dso_ctrl3_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  switch (reg.sim) {
+    case LSM6DSO_SPI_4_WIRE:
+      *val = LSM6DSO_SPI_4_WIRE;
+      break;
+    case LSM6DSO_SPI_3_WIRE:
+      *val = LSM6DSO_SPI_3_WIRE;
+      break;
+    default:
+      *val = LSM6DSO_SPI_4_WIRE;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Disable / Enable I2C interface.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of i2c_disable in
+  *                                reg CTRL4_C
+  *
+  */
+int32_t lsm6dso_i2c_interface_set(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_i2c_disable_t val)
+{
+  lsm6dso_ctrl4_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.i2c_disable = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Disable / Enable I2C interface.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of i2c_disable in
+  *                                reg CTRL4_C
+  *
+  */
+int32_t lsm6dso_i2c_interface_get(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_i2c_disable_t *val)
+{
+  lsm6dso_ctrl4_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t*)&reg, 1);
+  switch (reg.i2c_disable) {
+    case LSM6DSO_I2C_ENABLE:
+      *val = LSM6DSO_I2C_ENABLE;
+      break;
+    case LSM6DSO_I2C_DISABLE:
+      *val = LSM6DSO_I2C_DISABLE;
+      break;
+    default:
+      *val = LSM6DSO_I2C_ENABLE;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  I3C Enable/Disable communication protocol[.set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of i3c_disable
+  *                                    in reg CTRL9_XL
+  *
+  */
+int32_t lsm6dso_i3c_disable_set(lsm6dso_ctx_t *ctx, lsm6dso_i3c_disable_t val)
+{
+  lsm6dso_i3c_bus_avb_t i3c_bus_avb;
+  lsm6dso_ctrl9_xl_t ctrl9_xl;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1);
+  if (ret == 0) {
+    ctrl9_xl.i3c_disable = ((uint8_t)val & 0x80U) >> 7;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1);
+  }
+  if (ret == 0) {
+
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_I3C_BUS_AVB,
+                           (uint8_t*)&i3c_bus_avb, 1);
+  }
+  if (ret == 0) {
+    i3c_bus_avb.i3c_bus_avb_sel = (uint8_t)val & 0x03U;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_I3C_BUS_AVB,
+                            (uint8_t*)&i3c_bus_avb, 1);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  I3C Enable/Disable communication protocol.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of i3c_disable in
+  *                                reg CTRL9_XL
+  *
+  */
+int32_t lsm6dso_i3c_disable_get(lsm6dso_ctx_t *ctx, lsm6dso_i3c_disable_t *val)
+{
+  lsm6dso_ctrl9_xl_t ctrl9_xl;
+  lsm6dso_i3c_bus_avb_t i3c_bus_avb;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_I3C_BUS_AVB,
+                           (uint8_t*)&i3c_bus_avb, 1);
+
+    switch ((ctrl9_xl.i3c_disable << 7) | i3c_bus_avb.i3c_bus_avb_sel) {
+      case LSM6DSO_I3C_DISABLE:
+        *val = LSM6DSO_I3C_DISABLE;
+        break;
+      case LSM6DSO_I3C_ENABLE_T_50us:
+        *val = LSM6DSO_I3C_ENABLE_T_50us;
+        break;
+      case LSM6DSO_I3C_ENABLE_T_2us:
+        *val = LSM6DSO_I3C_ENABLE_T_2us;
+        break;
+      case LSM6DSO_I3C_ENABLE_T_1ms:
+        *val = LSM6DSO_I3C_ENABLE_T_1ms;
+        break;
+      case LSM6DSO_I3C_ENABLE_T_25ms:
+        *val = LSM6DSO_I3C_ENABLE_T_25ms;
+        break;
+      default:
+        *val = LSM6DSO_I3C_DISABLE;
+        break;
+    }
+  }
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_interrupt_pins
+  * @brief     This section groups all the functions that manage interrup pins
+  * @{
+  *
+  */
+
+/**
+  * @brief  Connect/Disconnect INT1 internal pull-down.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of pd_dis_int1 in reg I3C_BUS_AVB
+  *
+  */
+int32_t lsm6dso_int1_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_int1_pd_en_t val)
+{
+  lsm6dso_i3c_bus_avb_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_I3C_BUS_AVB, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.pd_dis_int1 = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_I3C_BUS_AVB, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Connect/Disconnect INT1 internal pull-down.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of pd_dis_int1 in reg I3C_BUS_AVB
+  *
+  */
+int32_t lsm6dso_int1_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_int1_pd_en_t *val)
+{
+  lsm6dso_i3c_bus_avb_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_I3C_BUS_AVB, (uint8_t*)&reg, 1);
+  switch (reg.pd_dis_int1) {
+    case LSM6DSO_PULL_DOWN_DISC:
+      *val = LSM6DSO_PULL_DOWN_DISC;
+      break;
+    case LSM6DSO_PULL_DOWN_CONNECT:
+      *val = LSM6DSO_PULL_DOWN_CONNECT;
+      break;
+    default:
+      *val = LSM6DSO_PULL_DOWN_DISC;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Select the signal that need to route on int1 pad.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      struct of registers: INT1_CTRL,
+  *                  MD1_CFG, EMB_FUNC_INT1, FSM_INT1_A,
+  *                  FSM_INT1_B
+  *
+  */
+int32_t lsm6dso_pin_int1_route_set(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_pin_int1_route_t *val)
+{
+  lsm6dso_tap_cfg2_t tap_cfg2;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_INT1,
+                            (uint8_t*)&val->emb_func_int1, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FSM_INT1_A,
+                            (uint8_t*)&val->fsm_int1_a, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FSM_INT1_B,
+                            (uint8_t*)&val->fsm_int1_b, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  if (ret == 0) {
+    if ( (val->emb_func_int1.int1_fsm_lc |
+          val->emb_func_int1.int1_sig_mot |
+          val->emb_func_int1.int1_step_detector |
+          val->emb_func_int1.int1_tilt |
+          val->fsm_int1_a.int1_fsm1 |
+          val->fsm_int1_a.int1_fsm2 |
+          val->fsm_int1_a.int1_fsm3 |
+          val->fsm_int1_a.int1_fsm4 |
+          val->fsm_int1_a.int1_fsm5 |
+          val->fsm_int1_a.int1_fsm6 |
+          val->fsm_int1_a.int1_fsm7 |
+          val->fsm_int1_a.int1_fsm8 |
+          val->fsm_int1_b.int1_fsm9 |
+          val->fsm_int1_b.int1_fsm10 |
+          val->fsm_int1_b.int1_fsm11 |
+          val->fsm_int1_b.int1_fsm12 |
+          val->fsm_int1_b.int1_fsm13 |
+          val->fsm_int1_b.int1_fsm14 |
+          val->fsm_int1_b.int1_fsm15 |
+          val->fsm_int1_b.int1_fsm16) != PROPERTY_DISABLE  ){
+      val->md1_cfg.int1_emb_func = PROPERTY_ENABLE;
+    }
+    else{
+      val->md1_cfg.int1_emb_func = PROPERTY_DISABLE;
+    }
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_INT1_CTRL,
+                            (uint8_t*)&val->int1_ctrl, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_MD1_CFG, (uint8_t*)&val->md1_cfg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t*) &tap_cfg2, 1);
+  }
+  if (ret == 0) {
+
+    if ( (val->int1_ctrl.den_drdy_flag |
+        val->int1_ctrl.int1_boot |
+        val->int1_ctrl.int1_cnt_bdr |
+        val->int1_ctrl.int1_drdy_g |
+        val->int1_ctrl.int1_drdy_xl |
+        val->int1_ctrl.int1_fifo_full |
+        val->int1_ctrl.int1_fifo_ovr |
+        val->int1_ctrl.int1_fifo_th |
+        val->md1_cfg.int1_6d |
+        val->md1_cfg.int1_double_tap|
+        val->md1_cfg.int1_ff |
+        val->md1_cfg.int1_wu |
+        val->md1_cfg.int1_single_tap |
+        val->md1_cfg.int1_sleep_change) != PROPERTY_DISABLE)
+    {
+      tap_cfg2.interrupts_enable = PROPERTY_ENABLE;
+    }
+    else{
+      tap_cfg2.interrupts_enable = PROPERTY_DISABLE;
+    }
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t*) &tap_cfg2, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Select the signal that need to route on int1 pad.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      struct of registers: INT1_CTRL, MD1_CFG,
+  *                  EMB_FUNC_INT1, FSM_INT1_A, FSM_INT1_B
+  *
+  */
+int32_t lsm6dso_pin_int1_route_get(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_pin_int1_route_t *val)
+{
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_INT1,
+                           (uint8_t*)&val->emb_func_int1, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_INT1_A,
+                           (uint8_t*)&val->fsm_int1_a, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_INT1_B,
+                           (uint8_t*)&val->fsm_int1_b, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  if (ret == 0) {
+
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_INT1_CTRL,
+                           (uint8_t*)&val->int1_ctrl, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_MD1_CFG, (uint8_t*)&val->md1_cfg, 1);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Select the signal that need to route on int2 pad.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      union of registers INT2_CTRL,  MD2_CFG,
+  *                  EMB_FUNC_INT2, FSM_INT2_A, FSM_INT2_B
+  *
+  */
+int32_t lsm6dso_pin_int2_route_set(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_pin_int2_route_t *val)
+{
+  lsm6dso_tap_cfg2_t tap_cfg2;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_INT2,
+                            (uint8_t*)&val->emb_func_int2, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FSM_INT2_A,
+                            (uint8_t*)&val->fsm_int2_a, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FSM_INT2_B,
+                            (uint8_t*)&val->fsm_int2_b, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  if (ret == 0) {
+    if (( val->emb_func_int2.int2_fsm_lc
+         | val->emb_func_int2.int2_sig_mot
+         | val->emb_func_int2.int2_step_detector
+         | val->emb_func_int2.int2_tilt
+         | val->fsm_int2_a.int2_fsm1
+         | val->fsm_int2_a.int2_fsm2
+         | val->fsm_int2_a.int2_fsm3
+         | val->fsm_int2_a.int2_fsm4
+         | val->fsm_int2_a.int2_fsm5
+         | val->fsm_int2_a.int2_fsm6
+         | val->fsm_int2_a.int2_fsm7
+         | val->fsm_int2_a.int2_fsm8
+         | val->fsm_int2_b.int2_fsm9
+         | val->fsm_int2_b.int2_fsm10
+         | val->fsm_int2_b.int2_fsm11
+         | val->fsm_int2_b.int2_fsm12
+         | val->fsm_int2_b.int2_fsm13
+         | val->fsm_int2_b.int2_fsm14
+         | val->fsm_int2_b.int2_fsm15
+         | val->fsm_int2_b.int2_fsm16 )!= PROPERTY_DISABLE)
+    {
+      val->md2_cfg.int2_emb_func = PROPERTY_ENABLE;
+    }
+    else{
+      val->md2_cfg.int2_emb_func = PROPERTY_DISABLE;
+    }
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_INT2_CTRL,
+                            (uint8_t*)&val->int2_ctrl, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_MD2_CFG, (uint8_t*)&val->md2_cfg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t*) &tap_cfg2, 1);
+  }
+  if (ret == 0) {
+    if ( ( val->int2_ctrl.int2_cnt_bdr
+         | val->int2_ctrl.int2_drdy_g
+         | val->int2_ctrl.int2_drdy_temp
+         | val->int2_ctrl.int2_drdy_xl
+         | val->int2_ctrl.int2_fifo_full
+         | val->int2_ctrl.int2_fifo_ovr
+         | val->int2_ctrl.int2_fifo_th
+         | val->md2_cfg.int2_6d
+         | val->md2_cfg.int2_double_tap
+         | val->md2_cfg.int2_ff | val->md2_cfg.int2_wu
+         | val->md2_cfg.int2_single_tap
+         | val->md2_cfg.int2_sleep_change) != PROPERTY_DISABLE ){
+      tap_cfg2.interrupts_enable = PROPERTY_ENABLE;
+    }
+    else{
+      tap_cfg2.interrupts_enable = PROPERTY_DISABLE;
+    }
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t*) &tap_cfg2, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Select the signal that need to route on int2 pad.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      union of registers INT2_CTRL,  MD2_CFG,
+  *                  EMB_FUNC_INT2, FSM_INT2_A, FSM_INT2_B
+  *
+  */
+int32_t lsm6dso_pin_int2_route_get(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_pin_int2_route_t *val)
+{
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_INT2,
+                           (uint8_t*)&val->emb_func_int2, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_INT2_A,
+                           (uint8_t*)&val->fsm_int2_a, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_INT2_B,
+                           (uint8_t*)&val->fsm_int2_b, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  if (ret == 0) {
+
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_INT2_CTRL,
+                           (uint8_t*)&val->int2_ctrl, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_MD2_CFG, (uint8_t*)&val->md2_cfg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Push-pull/open drain selection on interrupt pads.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of pp_od in reg CTRL3_C
+  *
+  */
+int32_t lsm6dso_pin_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_pp_od_t val)
+{
+  lsm6dso_ctrl3_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.pp_od = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Push-pull/open drain selection on interrupt pads.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of pp_od in reg CTRL3_C
+  *
+  */
+int32_t lsm6dso_pin_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_pp_od_t *val)
+{
+  lsm6dso_ctrl3_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+
+  switch (reg.pp_od) {
+    case LSM6DSO_PUSH_PULL:
+      *val = LSM6DSO_PUSH_PULL;
+      break;
+    case LSM6DSO_OPEN_DRAIN:
+      *val = LSM6DSO_OPEN_DRAIN;
+      break;
+    default:
+      *val = LSM6DSO_PUSH_PULL;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Interrupt active-high/low.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of h_lactive in reg CTRL3_C
+  *
+  */
+int32_t lsm6dso_pin_polarity_set(lsm6dso_ctx_t *ctx, lsm6dso_h_lactive_t val)
+{
+  lsm6dso_ctrl3_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.h_lactive = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Interrupt active-high/low.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of h_lactive in reg CTRL3_C
+  *
+  */
+int32_t lsm6dso_pin_polarity_get(lsm6dso_ctx_t *ctx, lsm6dso_h_lactive_t *val)
+{
+  lsm6dso_ctrl3_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t*)&reg, 1);
+
+  switch (reg.h_lactive) {
+    case LSM6DSO_ACTIVE_HIGH:
+      *val = LSM6DSO_ACTIVE_HIGH;
+      break;
+    case LSM6DSO_ACTIVE_LOW:
+      *val = LSM6DSO_ACTIVE_LOW;
+      break;
+    default:
+      *val = LSM6DSO_ACTIVE_HIGH;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  All interrupt signals become available on INT1 pin.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of int2_on_int1 in reg CTRL4_C
+  *
+  */
+int32_t lsm6dso_all_on_int1_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_ctrl4_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.int2_on_int1 = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t*)&reg, 1);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  All interrupt signals become available on INT1 pin.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of int2_on_int1 in reg CTRL4_C
+  *
+  */
+int32_t lsm6dso_all_on_int1_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_ctrl4_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t*)&reg, 1);
+  *val = reg.int2_on_int1;
+
+  return ret;
+}
+
+/**
+  * @brief  Interrupt notification mode.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of lir in reg TAP_CFG0
+  *
+  */
+int32_t lsm6dso_int_notification_set(lsm6dso_ctx_t *ctx, lsm6dso_lir_t val)
+{
+  lsm6dso_tap_cfg0_t tap_cfg0;
+  lsm6dso_page_rw_t page_rw;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*) &tap_cfg0, 1);
+  if (ret == 0) {
+    tap_cfg0.lir = (uint8_t)val & 0x01U;
+    tap_cfg0.int_clr_on_read = (uint8_t)val & 0x01U;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*) &tap_cfg0, 1);
+  }
+  if (ret == 0) {
+
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t*) &page_rw, 1);
+  }
+  if (ret == 0) {
+    page_rw.emb_func_lir = ((uint8_t)val & 0x02U) >> 1;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t*) &page_rw, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Interrupt notification mode.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of lir in reg TAP_CFG0
+  *
+  */
+int32_t lsm6dso_int_notification_get(lsm6dso_ctx_t *ctx, lsm6dso_lir_t *val)
+{
+  lsm6dso_tap_cfg0_t tap_cfg0;
+  lsm6dso_page_rw_t page_rw;
+  int32_t ret;
+
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*) &tap_cfg0, 1);
+  if (ret == 0) {
+
+      ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t*) &page_rw, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  if (ret == 0) {
+    switch ((page_rw.emb_func_lir << 1) | tap_cfg0.lir) {
+      case LSM6DSO_ALL_INT_PULSED:
+        *val = LSM6DSO_ALL_INT_PULSED;
+        break;
+      case LSM6DSO_BASE_LATCHED_EMB_PULSED:
+        *val = LSM6DSO_BASE_LATCHED_EMB_PULSED;
+        break;
+      case LSM6DSO_BASE_PULSED_EMB_LATCHED:
+        *val = LSM6DSO_BASE_PULSED_EMB_LATCHED;
+        break;
+      case LSM6DSO_ALL_INT_LATCHED:
+        *val = LSM6DSO_ALL_INT_LATCHED;
+        break;
+      default:
+        *val = LSM6DSO_ALL_INT_PULSED;
+        break;
+    }
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t*) &page_rw, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_Wake_Up_event
+  * @brief     This section groups all the functions that manage the Wake Up
+  *            event generation.
+  * @{
+  *
+*/
+
+/**
+  * @brief  Weight of 1 LSB of wakeup threshold.[set]
+  *         0: 1 LSB =FS_XL  /  64
+  *         1: 1 LSB = FS_XL / 256
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of wake_ths_w in
+  *                                 reg WAKE_UP_DUR
+  *
+  */
+int32_t lsm6dso_wkup_ths_weight_set(lsm6dso_ctx_t *ctx,
+                                    lsm6dso_wake_ths_w_t val)
+{
+  lsm6dso_wake_up_dur_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.wake_ths_w = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Weight of 1 LSB of wakeup threshold.[get]
+  *         0: 1 LSB =FS_XL  /  64
+  *         1: 1 LSB = FS_XL / 256
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of wake_ths_w in
+  *                                 reg WAKE_UP_DUR
+  *
+  */
+int32_t lsm6dso_wkup_ths_weight_get(lsm6dso_ctx_t *ctx,
+                                    lsm6dso_wake_ths_w_t *val)
+{
+  lsm6dso_wake_up_dur_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t*)&reg, 1);
+
+  switch (reg.wake_ths_w) {
+    case LSM6DSO_LSb_FS_DIV_64:
+      *val = LSM6DSO_LSb_FS_DIV_64;
+      break;
+    case LSM6DSO_LSb_FS_DIV_256:
+      *val = LSM6DSO_LSb_FS_DIV_256;
+      break;
+    default:
+      *val = LSM6DSO_LSb_FS_DIV_64;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Threshold for wakeup: 1 LSB weight depends on WAKE_THS_W in
+  *         WAKE_UP_DUR.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of wk_ths in reg WAKE_UP_THS
+  *
+  */
+int32_t lsm6dso_wkup_threshold_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_wake_up_ths_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.wk_ths = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Threshold for wakeup: 1 LSB weight depends on WAKE_THS_W in
+  *         WAKE_UP_DUR.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of wk_ths in reg WAKE_UP_THS
+  *
+  */
+int32_t lsm6dso_wkup_threshold_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_wake_up_ths_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t*)&reg, 1);
+  *val = reg.wk_ths;
+
+  return ret;
+}
+
+/**
+  * @brief  Wake up duration event.[set]
+  *         1LSb = 1 / ODR
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of usr_off_on_wu in reg WAKE_UP_THS
+  *
+  */
+int32_t lsm6dso_xl_usr_offset_on_wkup_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_wake_up_ths_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.usr_off_on_wu = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Wake up duration event.[get]
+  *         1LSb = 1 / ODR
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of usr_off_on_wu in reg WAKE_UP_THS
+  *
+  */
+int32_t lsm6dso_xl_usr_offset_on_wkup_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_wake_up_ths_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t*)&reg, 1);
+  *val = reg.usr_off_on_wu;
+
+  return ret;
+}
+
+/**
+  * @brief  Wake up duration event.[set]
+  *         1LSb = 1 / ODR
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of wake_dur in reg WAKE_UP_DUR
+  *
+  */
+int32_t lsm6dso_wkup_dur_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_wake_up_dur_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.wake_dur = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Wake up duration event.[get]
+  *         1LSb = 1 / ODR
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of wake_dur in reg WAKE_UP_DUR
+  *
+  */
+int32_t lsm6dso_wkup_dur_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_wake_up_dur_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t*)&reg, 1);
+  *val = reg.wake_dur;
+
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_ Activity/Inactivity_detection
+  * @brief     This section groups all the functions concerning
+  *            activity/inactivity detection.
+  * @{
+  *
+*/
+
+/**
+  * @brief  Enables gyroscope Sleep mode.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of sleep_g in reg CTRL4_C
+  *
+  */
+int32_t lsm6dso_gy_sleep_mode_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_ctrl4_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.sleep_g = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enables gyroscope Sleep mode.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of sleep_g in reg CTRL4_C
+  *
+  */
+int32_t lsm6dso_gy_sleep_mode_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_ctrl4_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t*)&reg, 1);
+  *val = reg.sleep_g;
+
+  return ret;
+}
+
+/**
+  * @brief  Drives the sleep status instead of
+  *         sleep change on INT pins
+  *         (only if INT1_SLEEP_CHANGE or
+  *         INT2_SLEEP_CHANGE bits are enabled).[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of sleep_status_on_int in reg TAP_CFG0
+  *
+  */
+int32_t lsm6dso_act_pin_notification_set(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_sleep_status_on_int_t val)
+{
+  lsm6dso_tap_cfg0_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.sleep_status_on_int = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Drives the sleep status instead of
+  *         sleep change on INT pins (only if
+  *         INT1_SLEEP_CHANGE or
+  *         INT2_SLEEP_CHANGE bits are enabled).[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of sleep_status_on_int in reg TAP_CFG0
+  *
+  */
+int32_t lsm6dso_act_pin_notification_get(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_sleep_status_on_int_t *val)
+{
+  lsm6dso_tap_cfg0_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*)&reg, 1);
+  switch (reg.sleep_status_on_int) {
+    case LSM6DSO_DRIVE_SLEEP_CHG_EVENT:
+      *val = LSM6DSO_DRIVE_SLEEP_CHG_EVENT;
+      break;
+    case LSM6DSO_DRIVE_SLEEP_STATUS:
+      *val = LSM6DSO_DRIVE_SLEEP_STATUS;
+      break;
+    default:
+      *val = LSM6DSO_DRIVE_SLEEP_CHG_EVENT;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable inactivity function.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of inact_en in reg TAP_CFG2
+  *
+  */
+int32_t lsm6dso_act_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_inact_en_t val)
+{
+  lsm6dso_tap_cfg2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.inact_en = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable inactivity function.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of inact_en in reg TAP_CFG2
+  *
+  */
+int32_t lsm6dso_act_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_inact_en_t *val)
+{
+  lsm6dso_tap_cfg2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t*)&reg, 1);
+  switch (reg.inact_en) {
+    case LSM6DSO_XL_AND_GY_NOT_AFFECTED:
+      *val = LSM6DSO_XL_AND_GY_NOT_AFFECTED;
+      break;
+    case LSM6DSO_XL_12Hz5_GY_NOT_AFFECTED:
+      *val = LSM6DSO_XL_12Hz5_GY_NOT_AFFECTED;
+      break;
+    case LSM6DSO_XL_12Hz5_GY_SLEEP:
+      *val = LSM6DSO_XL_12Hz5_GY_SLEEP;
+      break;
+    case LSM6DSO_XL_12Hz5_GY_PD:
+      *val = LSM6DSO_XL_12Hz5_GY_PD;
+      break;
+    default:
+      *val = LSM6DSO_XL_AND_GY_NOT_AFFECTED;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Duration to go in sleep mode.[set]
+  *         1 LSb = 512 / ODR
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of sleep_dur in reg WAKE_UP_DUR
+  *
+  */
+int32_t lsm6dso_act_sleep_dur_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_wake_up_dur_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.sleep_dur = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Duration to go in sleep mode.[get]
+  *         1 LSb = 512 / ODR
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of sleep_dur in reg WAKE_UP_DUR
+  *
+  */
+int32_t lsm6dso_act_sleep_dur_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_wake_up_dur_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t*)&reg, 1);
+  *val = reg.sleep_dur;
+
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_tap_generator
+  * @brief     This section groups all the functions that manage the
+  *            tap and double tap event generation.
+  * @{
+  *
+*/
+
+/**
+  * @brief  Enable Z direction in tap recognition.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tap_z_en in reg TAP_CFG0
+  *
+  */
+int32_t lsm6dso_tap_detection_on_z_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_tap_cfg0_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.tap_z_en = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable Z direction in tap recognition.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tap_z_en in reg TAP_CFG0
+  *
+  */
+int32_t lsm6dso_tap_detection_on_z_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_tap_cfg0_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*)&reg, 1);
+  *val = reg.tap_z_en;
+
+  return ret;
+}
+
+/**
+  * @brief  Enable Y direction in tap recognition.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tap_y_en in reg TAP_CFG0
+  *
+  */
+int32_t lsm6dso_tap_detection_on_y_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_tap_cfg0_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.tap_y_en = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable Y direction in tap recognition.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tap_y_en in reg TAP_CFG0
+  *
+  */
+int32_t lsm6dso_tap_detection_on_y_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_tap_cfg0_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*)&reg, 1);
+  *val = reg.tap_y_en;
+
+  return ret;
+}
+
+/**
+  * @brief  Enable X direction in tap recognition.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tap_x_en in reg TAP_CFG0
+  *
+  */
+int32_t lsm6dso_tap_detection_on_x_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_tap_cfg0_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.tap_x_en = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable X direction in tap recognition.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tap_x_en in reg TAP_CFG0
+  *
+  */
+int32_t lsm6dso_tap_detection_on_x_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_tap_cfg0_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t*)&reg, 1);
+  *val = reg.tap_x_en;
+
+  return ret;
+}
+
+/**
+  * @brief  X-axis tap recognition threshold.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tap_ths_x in reg TAP_CFG1
+  *
+  */
+int32_t lsm6dso_tap_threshold_x_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_tap_cfg1_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG1, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.tap_ths_x = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG1, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  X-axis tap recognition threshold.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tap_ths_x in reg TAP_CFG1
+  *
+  */
+int32_t lsm6dso_tap_threshold_x_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_tap_cfg1_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG1, (uint8_t*)&reg, 1);
+  *val = reg.tap_ths_x;
+
+  return ret;
+}
+
+/**
+  * @brief  Selection of axis priority for TAP detection.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tap_priority in
+  *                                 reg TAP_CFG1
+  *
+  */
+int32_t lsm6dso_tap_axis_priority_set(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_tap_priority_t val)
+{
+  lsm6dso_tap_cfg1_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG1, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.tap_priority = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG1, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selection of axis priority for TAP detection.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of tap_priority in
+  *                                 reg TAP_CFG1
+  *
+  */
+int32_t lsm6dso_tap_axis_priority_get(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_tap_priority_t *val)
+{
+  lsm6dso_tap_cfg1_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG1, (uint8_t*)&reg, 1);
+  switch (reg.tap_priority) {
+    case LSM6DSO_XYZ:
+      *val = LSM6DSO_XYZ;
+      break;
+    case LSM6DSO_YXZ:
+      *val = LSM6DSO_YXZ;
+      break;
+    case LSM6DSO_XZY:
+      *val = LSM6DSO_XZY;
+      break;
+    case LSM6DSO_ZYX:
+      *val = LSM6DSO_ZYX;
+      break;
+    case LSM6DSO_YZX:
+      *val = LSM6DSO_YZX;
+      break;
+    case LSM6DSO_ZXY:
+      *val = LSM6DSO_ZXY;
+      break;
+    default:
+      *val = LSM6DSO_XYZ;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Y-axis tap recognition threshold.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tap_ths_y in reg TAP_CFG2
+  *
+  */
+int32_t lsm6dso_tap_threshold_y_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_tap_cfg2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.tap_ths_y = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Y-axis tap recognition threshold.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tap_ths_y in reg TAP_CFG2
+  *
+  */
+int32_t lsm6dso_tap_threshold_y_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_tap_cfg2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t*)&reg, 1);
+  *val = reg.tap_ths_y;
+
+  return ret;
+}
+
+/**
+  * @brief  Z-axis recognition threshold.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tap_ths_z in reg TAP_THS_6D
+  *
+  */
+int32_t lsm6dso_tap_threshold_z_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_tap_ths_6d_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.tap_ths_z = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Z-axis recognition threshold.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tap_ths_z in reg TAP_THS_6D
+  *
+  */
+int32_t lsm6dso_tap_threshold_z_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_tap_ths_6d_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t*)&reg, 1);
+  *val = reg.tap_ths_z;
+
+  return ret;
+}
+
+/**
+  * @brief  Maximum duration is the maximum time of an
+  *         over threshold signal detection to be recognized
+  *         as a tap event. The default value of these bits
+  *         is 00b which corresponds to 4*ODR_XL time.
+  *         If the SHOCK[1:0] bits are set to a different
+  *         value, 1LSB corresponds to 8*ODR_XL time.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of shock in reg INT_DUR2
+  *
+  */
+int32_t lsm6dso_tap_shock_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_int_dur2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.shock = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Maximum duration is the maximum time of an
+  *         over threshold signal detection to be recognized
+  *         as a tap event. The default value of these bits
+  *         is 00b which corresponds to 4*ODR_XL time.
+  *         If the SHOCK[1:0] bits are set to a different
+  *         value, 1LSB corresponds to 8*ODR_XL time.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of shock in reg INT_DUR2
+  *
+  */
+int32_t lsm6dso_tap_shock_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_int_dur2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t*)&reg, 1);
+  *val = reg.shock;
+
+  return ret;
+}
+
+/**
+  * @brief   Quiet time is the time after the first detected
+  *          tap in which there must not be any over threshold
+  *          event.
+  *          The default value of these bits is 00b which
+  *          corresponds to 2*ODR_XL time. If the QUIET[1:0]
+  *          bits are set to a different value,
+  *          1LSB corresponds to 4*ODR_XL time.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of quiet in reg INT_DUR2
+  *
+  */
+int32_t lsm6dso_tap_quiet_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_int_dur2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.quiet = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Quiet time is the time after the first detected
+  *         tap in which there must not be any over threshold
+  *         event.
+  *         The default value of these bits is 00b which
+  *         corresponds to 2*ODR_XL time.
+  *         If the QUIET[1:0] bits are set to a different
+  *         value, 1LSB corresponds to 4*ODR_XL time.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of quiet in reg INT_DUR2
+  *
+  */
+int32_t lsm6dso_tap_quiet_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_int_dur2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t*)&reg, 1);
+  *val = reg.quiet;
+
+  return ret;
+}
+
+/**
+  * @brief  When double tap recognition is enabled,
+  *         this register expresses the maximum time
+  *         between two consecutive detected taps to
+  *         determine a double tap event.
+  *         The default value of these bits is 0000b which
+  *         corresponds to 16*ODR_XL time.
+  *         If the DUR[3:0] bits are set to a different value,
+  *         1LSB corresponds to 32*ODR_XL time.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of dur in reg INT_DUR2
+  *
+  */
+int32_t lsm6dso_tap_dur_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_int_dur2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.dur = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  When double tap recognition is enabled,
+  *         this register expresses the maximum time
+  *         between two consecutive detected taps to
+  *         determine a double tap event.
+  *         The default value of these bits is 0000b which
+  *         corresponds to 16*ODR_XL time. If the DUR[3:0]
+  *         bits are set to a different value,
+  *         1LSB corresponds to 32*ODR_XL time.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of dur in reg INT_DUR2
+  *
+  */
+int32_t lsm6dso_tap_dur_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_int_dur2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t*)&reg, 1);
+  *val = reg.dur;
+
+  return ret;
+}
+
+/**
+  * @brief  Single/double-tap event enable.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of single_double_tap in reg WAKE_UP_THS
+  *
+  */
+int32_t lsm6dso_tap_mode_set(lsm6dso_ctx_t *ctx,
+                             lsm6dso_single_double_tap_t val)
+{
+  lsm6dso_wake_up_ths_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.single_double_tap = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Single/double-tap event enable.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of single_double_tap in reg WAKE_UP_THS
+  *
+  */
+int32_t lsm6dso_tap_mode_get(lsm6dso_ctx_t *ctx,
+                             lsm6dso_single_double_tap_t *val)
+{
+  lsm6dso_wake_up_ths_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t*)&reg, 1);
+
+  switch (reg.single_double_tap) {
+    case LSM6DSO_ONLY_SINGLE:
+      *val = LSM6DSO_ONLY_SINGLE;
+      break;
+    case LSM6DSO_BOTH_SINGLE_DOUBLE:
+      *val = LSM6DSO_BOTH_SINGLE_DOUBLE;
+      break;
+    default:
+      *val = LSM6DSO_ONLY_SINGLE;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_ Six_position_detection(6D/4D)
+  * @brief   This section groups all the functions concerning six position
+  *          detection (6D).
+  * @{
+  *
+*/
+
+/**
+  * @brief  Threshold for 4D/6D function.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of sixd_ths in reg TAP_THS_6D
+  *
+  */
+int32_t lsm6dso_6d_threshold_set(lsm6dso_ctx_t *ctx, lsm6dso_sixd_ths_t val)
+{
+  lsm6dso_tap_ths_6d_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.sixd_ths = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Threshold for 4D/6D function.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of sixd_ths in reg TAP_THS_6D
+  *
+  */
+int32_t lsm6dso_6d_threshold_get(lsm6dso_ctx_t *ctx, lsm6dso_sixd_ths_t *val)
+{
+  lsm6dso_tap_ths_6d_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t*)&reg, 1);
+  switch (reg.sixd_ths) {
+    case LSM6DSO_DEG_80:
+      *val = LSM6DSO_DEG_80;
+      break;
+    case LSM6DSO_DEG_70:
+      *val = LSM6DSO_DEG_70;
+      break;
+    case LSM6DSO_DEG_60:
+      *val = LSM6DSO_DEG_60;
+      break;
+    case LSM6DSO_DEG_50:
+      *val = LSM6DSO_DEG_50;
+      break;
+    default:
+      *val = LSM6DSO_DEG_80;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  4D orientation detection enable.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of d4d_en in reg TAP_THS_6D
+  *
+  */
+int32_t lsm6dso_4d_mode_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_tap_ths_6d_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.d4d_en = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  4D orientation detection enable.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of d4d_en in reg TAP_THS_6D
+  *
+  */
+int32_t lsm6dso_4d_mode_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_tap_ths_6d_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t*)&reg, 1);
+  *val = reg.d4d_en;
+
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_free_fall
+  * @brief   This section group all the functions concerning the free
+  *          fall detection.
+  * @{
+  *
+*/
+/**
+  * @brief  Free fall threshold setting.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of ff_ths in reg FREE_FALL
+  *
+  */
+int32_t lsm6dso_ff_threshold_set(lsm6dso_ctx_t *ctx, lsm6dso_ff_ths_t val)
+{
+  lsm6dso_free_fall_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FREE_FALL, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.ff_ths = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FREE_FALL, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Free fall threshold setting.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of ff_ths in reg FREE_FALL
+  *
+  */
+int32_t lsm6dso_ff_threshold_get(lsm6dso_ctx_t *ctx, lsm6dso_ff_ths_t *val)
+{
+  lsm6dso_free_fall_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FREE_FALL, (uint8_t*)&reg, 1);
+  switch (reg.ff_ths) {
+    case LSM6DSO_FF_TSH_156mg:
+      *val = LSM6DSO_FF_TSH_156mg;
+      break;
+    case LSM6DSO_FF_TSH_219mg:
+      *val = LSM6DSO_FF_TSH_219mg;
+      break;
+    case LSM6DSO_FF_TSH_250mg:
+      *val = LSM6DSO_FF_TSH_250mg;
+      break;
+    case LSM6DSO_FF_TSH_312mg:
+      *val = LSM6DSO_FF_TSH_312mg;
+      break;
+    case LSM6DSO_FF_TSH_344mg:
+      *val = LSM6DSO_FF_TSH_344mg;
+      break;
+    case LSM6DSO_FF_TSH_406mg:
+      *val = LSM6DSO_FF_TSH_406mg;
+      break;
+    case LSM6DSO_FF_TSH_469mg:
+      *val = LSM6DSO_FF_TSH_469mg;
+      break;
+    case LSM6DSO_FF_TSH_500mg:
+      *val = LSM6DSO_FF_TSH_500mg;
+      break;
+    default:
+      *val = LSM6DSO_FF_TSH_156mg;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Free-fall duration event.[set]
+  *         1LSb = 1 / ODR
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of ff_dur in reg FREE_FALL
+  *
+  */
+int32_t lsm6dso_ff_dur_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_wake_up_dur_t wake_up_dur;
+  lsm6dso_free_fall_t free_fall;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_FREE_FALL, (uint8_t*)&free_fall, 1);
+  }
+  if (ret == 0) {
+    wake_up_dur.ff_dur = ((uint8_t)val & 0x20U) >> 5;
+    free_fall.ff_dur = (uint8_t)val & 0x1FU;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_WAKE_UP_DUR,
+                            (uint8_t*)&wake_up_dur, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FREE_FALL, (uint8_t*)&free_fall, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Free-fall duration event.[get]
+  *         1LSb = 1 / ODR
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of ff_dur in reg FREE_FALL
+  *
+  */
+int32_t lsm6dso_ff_dur_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_wake_up_dur_t wake_up_dur;
+  lsm6dso_free_fall_t free_fall;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_FREE_FALL, (uint8_t*)&free_fall, 1);
+    *val = (wake_up_dur.ff_dur << 5) + free_fall.ff_dur;
+  }
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_fifo
+  * @brief   This section group all the functions concerning the fifo usage
+  * @{
+  *
+*/
+
+/**
+  * @brief  FIFO watermark level selection.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of wtm in reg FIFO_CTRL1
+  *
+  */
+int32_t lsm6dso_fifo_watermark_set(lsm6dso_ctx_t *ctx, uint16_t val)
+{
+  lsm6dso_fifo_ctrl1_t fifo_ctrl1;
+  lsm6dso_fifo_ctrl2_t fifo_ctrl2;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1);
+  if (ret == 0) {
+    fifo_ctrl1.wtm = 0x00FFU & (uint8_t)val;
+    fifo_ctrl2.wtm = (uint8_t)(( 0x0100U & val ) >> 8);
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL1, (uint8_t*)&fifo_ctrl1, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  FIFO watermark level selection.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of wtm in reg FIFO_CTRL1
+  *
+  */
+int32_t lsm6dso_fifo_watermark_get(lsm6dso_ctx_t *ctx, uint16_t *val)
+{
+  lsm6dso_fifo_ctrl1_t fifo_ctrl1;
+  lsm6dso_fifo_ctrl2_t fifo_ctrl2;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL1, (uint8_t*)&fifo_ctrl1, 1);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1);
+    *val = ((uint16_t)fifo_ctrl2.wtm << 8) + (uint16_t)fifo_ctrl1.wtm;
+  }
+  return ret;
+}
+
+/**
+  * @brief  FIFO compression feature initialization request [set].
+  *
+  * @param  ctx       read / write interface definitions
+  * @param  val       change the values of FIFO_COMPR_INIT in
+  *                   reg EMB_FUNC_INIT_B
+  *
+  */
+int32_t lsm6dso_compression_algo_init_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_emb_func_init_b_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_INIT_B, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.fifo_compr_init = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_INIT_B, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  FIFO compression feature initialization request [get].
+  *
+  * @param  ctx    read / write interface definitions
+  * @param  val    change the values of FIFO_COMPR_INIT in
+  *                reg EMB_FUNC_INIT_B
+  *
+  */
+int32_t lsm6dso_compression_algo_init_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_emb_func_init_b_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_INIT_B, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    *val = reg.fifo_compr_init;
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Enable and configure compression algo.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of uncoptr_rate in
+  *                  reg FIFO_CTRL2
+  *
+  */
+int32_t lsm6dso_compression_algo_set(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_uncoptr_rate_t val)
+{
+  lsm6dso_emb_func_en_b_t emb_func_en_b;
+  lsm6dso_fifo_ctrl2_t fifo_ctrl2;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_B,
+                           (uint8_t*)&emb_func_en_b, 1);
+  }
+  if (ret == 0) {
+    emb_func_en_b.fifo_compr_en = ((uint8_t)val & 0x04U) >> 2;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_EN_B,
+                            (uint8_t*)&emb_func_en_b, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  if (ret == 0) {
+
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2,
+                           (uint8_t*)&fifo_ctrl2, 1);
+  }
+  if (ret == 0) {
+    fifo_ctrl2.fifo_compr_rt_en = ((uint8_t)val & 0x04U) >> 2;
+    fifo_ctrl2.uncoptr_rate = (uint8_t)val & 0x03U;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL2,
+                            (uint8_t*)&fifo_ctrl2, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable and configure compression algo.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of uncoptr_rate in
+  *                  reg FIFO_CTRL2
+  *
+  */
+int32_t lsm6dso_compression_algo_get(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_uncoptr_rate_t *val)
+{
+  lsm6dso_fifo_ctrl2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t*)&reg, 1);
+
+  switch ((reg.fifo_compr_rt_en<<2) | reg.uncoptr_rate) {
+    case LSM6DSO_CMP_DISABLE:
+      *val = LSM6DSO_CMP_DISABLE;
+      break;
+    case LSM6DSO_CMP_ALWAYS:
+      *val = LSM6DSO_CMP_ALWAYS;
+      break;
+    case LSM6DSO_CMP_8_TO_1:
+      *val = LSM6DSO_CMP_8_TO_1;
+      break;
+    case LSM6DSO_CMP_16_TO_1:
+      *val = LSM6DSO_CMP_16_TO_1;
+      break;
+    case LSM6DSO_CMP_32_TO_1:
+      *val = LSM6DSO_CMP_32_TO_1;
+      break;
+    default:
+      *val = LSM6DSO_CMP_DISABLE;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enables ODR CHANGE virtual sensor to be batched in FIFO.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of odrchg_en in reg FIFO_CTRL2
+  *
+  */
+int32_t lsm6dso_fifo_virtual_sens_odr_chg_set(lsm6dso_ctx_t *ctx,
+                                              uint8_t val)
+{
+  lsm6dso_fifo_ctrl2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.odrchg_en = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enables ODR CHANGE virtual sensor to be batched in FIFO.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of odrchg_en in reg FIFO_CTRL2
+  *
+  */
+int32_t lsm6dso_fifo_virtual_sens_odr_chg_get(lsm6dso_ctx_t *ctx,
+                                              uint8_t *val)
+{
+  lsm6dso_fifo_ctrl2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t*)&reg, 1);
+  *val = reg.odrchg_en;
+
+  return ret;
+}
+
+/**
+  * @brief  Enables/Disables compression algorithm runtime.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of fifo_compr_rt_en in
+  *                  reg FIFO_CTRL2
+  *
+  */
+int32_t lsm6dso_compression_algo_real_time_set(lsm6dso_ctx_t *ctx,
+                                               uint8_t val)
+{
+  lsm6dso_fifo_ctrl2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.fifo_compr_rt_en = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief   Enables/Disables compression algorithm runtime. [get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of fifo_compr_rt_en in reg FIFO_CTRL2
+  *
+  */
+int32_t lsm6dso_compression_algo_real_time_get(lsm6dso_ctx_t *ctx,
+                                               uint8_t *val)
+{
+  lsm6dso_fifo_ctrl2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t*)&reg, 1);
+  *val = reg.fifo_compr_rt_en;
+
+  return ret;
+}
+
+/**
+  * @brief  Sensing chain FIFO stop values memorization at
+  *         threshold level.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of stop_on_wtm in reg FIFO_CTRL2
+  *
+  */
+int32_t lsm6dso_fifo_stop_on_wtm_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_fifo_ctrl2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.stop_on_wtm = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Sensing chain FIFO stop values memorization at
+  *         threshold level.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of stop_on_wtm in reg FIFO_CTRL2
+  *
+  */
+int32_t lsm6dso_fifo_stop_on_wtm_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_fifo_ctrl2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t*)&reg, 1);
+  *val = reg.stop_on_wtm;
+
+  return ret;
+}
+
+/**
+  * @brief  Selects Batching Data Rate (writing frequency in FIFO)
+  *         for accelerometer data.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of bdr_xl in reg FIFO_CTRL3
+  *
+  */
+int32_t lsm6dso_fifo_xl_batch_set(lsm6dso_ctx_t *ctx, lsm6dso_bdr_xl_t val)
+{
+  lsm6dso_fifo_ctrl3_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL3, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.bdr_xl = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL3, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects Batching Data Rate (writing frequency in FIFO)
+  *         for accelerometer data.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of bdr_xl in reg FIFO_CTRL3
+  *
+  */
+int32_t lsm6dso_fifo_xl_batch_get(lsm6dso_ctx_t *ctx, lsm6dso_bdr_xl_t *val)
+{
+  lsm6dso_fifo_ctrl3_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL3, (uint8_t*)&reg, 1);
+  switch (reg.bdr_xl) {
+    case LSM6DSO_XL_NOT_BATCHED:
+      *val = LSM6DSO_XL_NOT_BATCHED;
+      break;
+    case LSM6DSO_XL_BATCHED_AT_12Hz5:
+      *val = LSM6DSO_XL_BATCHED_AT_12Hz5;
+      break;
+    case LSM6DSO_XL_BATCHED_AT_26Hz:
+      *val = LSM6DSO_XL_BATCHED_AT_26Hz;
+      break;
+    case LSM6DSO_XL_BATCHED_AT_52Hz:
+      *val = LSM6DSO_XL_BATCHED_AT_52Hz;
+      break;
+    case LSM6DSO_XL_BATCHED_AT_104Hz:
+      *val = LSM6DSO_XL_BATCHED_AT_104Hz;
+      break;
+    case LSM6DSO_XL_BATCHED_AT_208Hz:
+      *val = LSM6DSO_XL_BATCHED_AT_208Hz;
+      break;
+    case LSM6DSO_XL_BATCHED_AT_417Hz:
+      *val = LSM6DSO_XL_BATCHED_AT_417Hz;
+      break;
+    case LSM6DSO_XL_BATCHED_AT_833Hz:
+      *val = LSM6DSO_XL_BATCHED_AT_833Hz;
+      break;
+    case LSM6DSO_XL_BATCHED_AT_1667Hz:
+      *val = LSM6DSO_XL_BATCHED_AT_1667Hz;
+      break;
+    case LSM6DSO_XL_BATCHED_AT_3333Hz:
+      *val = LSM6DSO_XL_BATCHED_AT_3333Hz;
+      break;
+    case LSM6DSO_XL_BATCHED_AT_6667Hz:
+      *val = LSM6DSO_XL_BATCHED_AT_6667Hz;
+      break;
+    case LSM6DSO_XL_BATCHED_AT_6Hz5:
+      *val = LSM6DSO_XL_BATCHED_AT_6Hz5;
+      break;
+    default:
+      *val = LSM6DSO_XL_NOT_BATCHED;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Selects Batching Data Rate (writing frequency in FIFO)
+  *         for gyroscope data.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of bdr_gy in reg FIFO_CTRL3
+  *
+  */
+int32_t lsm6dso_fifo_gy_batch_set(lsm6dso_ctx_t *ctx, lsm6dso_bdr_gy_t val)
+{
+  lsm6dso_fifo_ctrl3_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL3, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.bdr_gy = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL3, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects Batching Data Rate (writing frequency in FIFO)
+  *         for gyroscope data.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of bdr_gy in reg FIFO_CTRL3
+  *
+  */
+int32_t lsm6dso_fifo_gy_batch_get(lsm6dso_ctx_t *ctx, lsm6dso_bdr_gy_t *val)
+{
+  lsm6dso_fifo_ctrl3_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL3, (uint8_t*)&reg, 1);
+  switch (reg.bdr_gy) {
+    case LSM6DSO_GY_NOT_BATCHED:
+      *val = LSM6DSO_GY_NOT_BATCHED;
+      break;
+    case LSM6DSO_GY_BATCHED_AT_12Hz5:
+      *val = LSM6DSO_GY_BATCHED_AT_12Hz5;
+      break;
+    case LSM6DSO_GY_BATCHED_AT_26Hz:
+      *val = LSM6DSO_GY_BATCHED_AT_26Hz;
+      break;
+    case LSM6DSO_GY_BATCHED_AT_52Hz:
+      *val = LSM6DSO_GY_BATCHED_AT_52Hz;
+      break;
+    case LSM6DSO_GY_BATCHED_AT_104Hz:
+      *val = LSM6DSO_GY_BATCHED_AT_104Hz;
+      break;
+    case LSM6DSO_GY_BATCHED_AT_208Hz:
+      *val = LSM6DSO_GY_BATCHED_AT_208Hz;
+      break;
+    case LSM6DSO_GY_BATCHED_AT_417Hz:
+      *val = LSM6DSO_GY_BATCHED_AT_417Hz;
+      break;
+    case LSM6DSO_GY_BATCHED_AT_833Hz:
+      *val = LSM6DSO_GY_BATCHED_AT_833Hz;
+      break;
+    case LSM6DSO_GY_BATCHED_AT_1667Hz:
+      *val = LSM6DSO_GY_BATCHED_AT_1667Hz;
+      break;
+    case LSM6DSO_GY_BATCHED_AT_3333Hz:
+      *val = LSM6DSO_GY_BATCHED_AT_3333Hz;
+      break;
+    case LSM6DSO_GY_BATCHED_AT_6667Hz:
+      *val = LSM6DSO_GY_BATCHED_AT_6667Hz;
+      break;
+    case LSM6DSO_GY_BATCHED_AT_6Hz5:
+      *val = LSM6DSO_GY_BATCHED_AT_6Hz5;
+      break;
+    default:
+      *val = LSM6DSO_GY_NOT_BATCHED;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  FIFO mode selection.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of fifo_mode in reg FIFO_CTRL4
+  *
+  */
+int32_t lsm6dso_fifo_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_fifo_mode_t val)
+{
+  lsm6dso_fifo_ctrl4_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.fifo_mode = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  FIFO mode selection.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of fifo_mode in reg FIFO_CTRL4
+  *
+  */
+int32_t lsm6dso_fifo_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_fifo_mode_t *val)
+{
+  lsm6dso_fifo_ctrl4_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t*)&reg, 1);
+
+  switch (reg.fifo_mode) {
+    case LSM6DSO_BYPASS_MODE:
+      *val = LSM6DSO_BYPASS_MODE;
+      break;
+    case LSM6DSO_FIFO_MODE:
+      *val = LSM6DSO_FIFO_MODE;
+      break;
+    case LSM6DSO_STREAM_TO_FIFO_MODE:
+      *val = LSM6DSO_STREAM_TO_FIFO_MODE;
+      break;
+    case LSM6DSO_BYPASS_TO_STREAM_MODE:
+      *val = LSM6DSO_BYPASS_TO_STREAM_MODE;
+      break;
+    case LSM6DSO_STREAM_MODE:
+      *val = LSM6DSO_STREAM_MODE;
+      break;
+    case LSM6DSO_BYPASS_TO_FIFO_MODE:
+      *val = LSM6DSO_BYPASS_TO_FIFO_MODE;
+      break;
+    default:
+      *val = LSM6DSO_BYPASS_MODE;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects Batching Data Rate (writing frequency in FIFO)
+  *         for temperature data.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of odr_t_batch in reg FIFO_CTRL4
+  *
+  */
+int32_t lsm6dso_fifo_temp_batch_set(lsm6dso_ctx_t *ctx,
+                                    lsm6dso_odr_t_batch_t val)
+{
+  lsm6dso_fifo_ctrl4_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.odr_t_batch = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects Batching Data Rate (writing frequency in FIFO)
+  *         for temperature data.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of odr_t_batch in reg FIFO_CTRL4
+  *
+  */
+int32_t lsm6dso_fifo_temp_batch_get(lsm6dso_ctx_t *ctx,
+                                    lsm6dso_odr_t_batch_t *val)
+{
+  lsm6dso_fifo_ctrl4_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t*)&reg, 1);
+
+  switch (reg.odr_t_batch) {
+    case LSM6DSO_TEMP_NOT_BATCHED:
+      *val = LSM6DSO_TEMP_NOT_BATCHED;
+      break;
+    case LSM6DSO_TEMP_BATCHED_AT_1Hz6:
+      *val = LSM6DSO_TEMP_BATCHED_AT_1Hz6;
+      break;
+    case LSM6DSO_TEMP_BATCHED_AT_12Hz5:
+      *val = LSM6DSO_TEMP_BATCHED_AT_12Hz5;
+      break;
+    case LSM6DSO_TEMP_BATCHED_AT_52Hz:
+      *val = LSM6DSO_TEMP_BATCHED_AT_52Hz;
+      break;
+    default:
+      *val = LSM6DSO_TEMP_NOT_BATCHED;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects decimation for timestamp batching in FIFO.
+  *         Writing rate will be the maximum rate between XL and
+  *         GYRO BDR divided by decimation decoder.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of odr_ts_batch in reg FIFO_CTRL4
+  *
+  */
+int32_t lsm6dso_fifo_timestamp_decimation_set(lsm6dso_ctx_t *ctx,
+                                              lsm6dso_odr_ts_batch_t val)
+{
+  lsm6dso_fifo_ctrl4_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.odr_ts_batch = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief   Selects decimation for timestamp batching in FIFO.
+  *          Writing rate will be the maximum rate between XL and
+  *          GYRO BDR divided by decimation decoder.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of odr_ts_batch in reg FIFO_CTRL4
+  *
+  */
+int32_t lsm6dso_fifo_timestamp_decimation_get(lsm6dso_ctx_t *ctx,
+                                              lsm6dso_odr_ts_batch_t *val)
+{
+  lsm6dso_fifo_ctrl4_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t*)&reg, 1);
+  switch (reg.odr_ts_batch) {
+    case LSM6DSO_NO_DECIMATION:
+      *val = LSM6DSO_NO_DECIMATION;
+      break;
+    case LSM6DSO_DEC_1:
+      *val = LSM6DSO_DEC_1;
+      break;
+    case LSM6DSO_DEC_8:
+      *val = LSM6DSO_DEC_8;
+      break;
+    case LSM6DSO_DEC_32:
+      *val = LSM6DSO_DEC_32;
+      break;
+    default:
+      *val = LSM6DSO_NO_DECIMATION;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects the trigger for the internal counter of batching events
+  *         between XL and gyro.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of trig_counter_bdr
+  *                  in reg COUNTER_BDR_REG1
+  *
+  */
+int32_t lsm6dso_fifo_cnt_event_batch_set(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_trig_counter_bdr_t val)
+{
+  lsm6dso_counter_bdr_reg1_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.trig_counter_bdr = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Selects the trigger for the internal counter of batching events
+  *         between XL and gyro.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of trig_counter_bdr
+  *                                     in reg COUNTER_BDR_REG1
+  *
+  */
+int32_t lsm6dso_fifo_cnt_event_batch_get(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_trig_counter_bdr_t *val)
+{
+  lsm6dso_counter_bdr_reg1_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, (uint8_t*)&reg, 1);
+  switch (reg.trig_counter_bdr) {
+    case LSM6DSO_XL_BATCH_EVENT:
+      *val = LSM6DSO_XL_BATCH_EVENT;
+      break;
+    case LSM6DSO_GYRO_BATCH_EVENT:
+      *val = LSM6DSO_GYRO_BATCH_EVENT;
+      break;
+    default:
+      *val = LSM6DSO_XL_BATCH_EVENT;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Resets the internal counter of batching vents for a single sensor.
+  *         This bit is automatically reset to zero if it was set to ‘1’.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of rst_counter_bdr in
+  *                      reg COUNTER_BDR_REG1
+  *
+  */
+int32_t lsm6dso_rst_batch_counter_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_counter_bdr_reg1_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.rst_counter_bdr = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, (uint8_t*)&reg, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Resets the internal counter of batching events for a single sensor.
+  *         This bit is automatically reset to zero if it was set to ‘1’.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of rst_counter_bdr in
+  *                  reg COUNTER_BDR_REG1
+  *
+  */
+int32_t lsm6dso_rst_batch_counter_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_counter_bdr_reg1_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, (uint8_t*)&reg, 1);
+  *val = reg.rst_counter_bdr;
+
+  return ret;
+}
+
+/**
+  * @brief  Batch data rate counter.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of cnt_bdr_th in
+  *                  reg COUNTER_BDR_REG2 and COUNTER_BDR_REG1.
+  *
+  */
+int32_t lsm6dso_batch_counter_threshold_set(lsm6dso_ctx_t *ctx, uint16_t val)
+{
+  lsm6dso_counter_bdr_reg1_t counter_bdr_reg1;
+  lsm6dso_counter_bdr_reg2_t counter_bdr_reg2;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG1,
+                         (uint8_t*)&counter_bdr_reg1, 1);
+  if (ret == 0) {
+    counter_bdr_reg2.cnt_bdr_th =  0x00FFU & (uint8_t)val;
+    counter_bdr_reg1.cnt_bdr_th = (uint8_t)(0x0700U & val) >> 8;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_COUNTER_BDR_REG1,
+                            (uint8_t*)&counter_bdr_reg1, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_COUNTER_BDR_REG2,
+                            (uint8_t*)&counter_bdr_reg2, 1);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Batch data rate counter.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of cnt_bdr_th in
+  *                  reg COUNTER_BDR_REG2 and COUNTER_BDR_REG1.
+  *
+  */
+int32_t lsm6dso_batch_counter_threshold_get(lsm6dso_ctx_t *ctx, uint16_t *val)
+{
+  lsm6dso_counter_bdr_reg1_t counter_bdr_reg1;
+  lsm6dso_counter_bdr_reg2_t counter_bdr_reg2;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG1,
+                         (uint8_t*)&counter_bdr_reg1, 1);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG2,
+                           (uint8_t*)&counter_bdr_reg2, 1);
+
+    *val = ((uint16_t)counter_bdr_reg1.cnt_bdr_th << 8)
+    + (uint16_t)counter_bdr_reg2.cnt_bdr_th;
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Number of unread sensor data(TAG + 6 bytes) stored in FIFO.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of diff_fifo in reg FIFO_STATUS1
+  *
+  */
+int32_t lsm6dso_fifo_data_level_get(lsm6dso_ctx_t *ctx, uint16_t *val)
+{
+  lsm6dso_fifo_status1_t fifo_status1;
+  lsm6dso_fifo_status2_t fifo_status2;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_STATUS1,
+                         (uint8_t*)&fifo_status1, 1);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_STATUS2,
+                           (uint8_t*)&fifo_status2, 1);
+    *val = ((uint16_t)fifo_status2.diff_fifo << 8) +
+            (uint16_t)fifo_status1.diff_fifo;
+  }
+  return ret;
+}
+
+/**
+  * @brief  FIFO status.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      registers FIFO_STATUS2
+  *
+  */
+int32_t lsm6dso_fifo_status_get(lsm6dso_ctx_t *ctx,
+                                lsm6dso_fifo_status2_t *val)
+{
+  int32_t ret;
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_STATUS2, (uint8_t*) val, 1);
+  return ret;
+}
+
+/**
+  * @brief  Smart FIFO full status.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of fifo_full_ia in reg FIFO_STATUS2
+  *
+  */
+int32_t lsm6dso_fifo_full_flag_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_fifo_status2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_STATUS2, (uint8_t*)&reg, 1);
+  *val = reg.fifo_full_ia;
+
+  return ret;
+}
+
+/**
+  * @brief  FIFO overrun status.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of  fifo_over_run_latched in
+  *                  reg FIFO_STATUS2
+  *
+  */
+int32_t lsm6dso_fifo_ovr_flag_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_fifo_status2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_STATUS2, (uint8_t*)&reg, 1);
+  *val = reg.fifo_ovr_ia;
+
+  return ret;
+}
+
+/**
+  * @brief  FIFO watermark status.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of fifo_wtm_ia in reg FIFO_STATUS2
+  *
+  */
+int32_t lsm6dso_fifo_wtm_flag_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_fifo_status2_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_STATUS2, (uint8_t*)&reg, 1);
+  *val = reg.fifo_wtm_ia;
+
+  return ret;
+}
+
+/**
+  * @brief  Identifies the sensor in FIFO_DATA_OUT.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tag_sensor in reg FIFO_DATA_OUT_TAG
+  *
+  */
+int32_t lsm6dso_fifo_sensor_tag_get(lsm6dso_ctx_t *ctx,
+                                    lsm6dso_fifo_tag_t *val)
+{
+  lsm6dso_fifo_data_out_tag_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_DATA_OUT_TAG, (uint8_t*)&reg, 1);
+  switch (reg.tag_sensor) {
+    case LSM6DSO_GYRO_NC_TAG:
+      *val = LSM6DSO_GYRO_NC_TAG;
+      break;
+    case LSM6DSO_XL_NC_TAG:
+      *val = LSM6DSO_XL_NC_TAG;
+      break;
+    case LSM6DSO_TEMPERATURE_TAG:
+      *val = LSM6DSO_TEMPERATURE_TAG;
+      break;
+    case LSM6DSO_CFG_CHANGE_TAG:
+      *val = LSM6DSO_CFG_CHANGE_TAG;
+      break;
+    case LSM6DSO_XL_NC_T_2_TAG:
+      *val = LSM6DSO_XL_NC_T_2_TAG;
+      break;
+    case LSM6DSO_XL_NC_T_1_TAG:
+      *val = LSM6DSO_XL_NC_T_1_TAG;
+      break;
+    case LSM6DSO_XL_2XC_TAG:
+      *val = LSM6DSO_XL_2XC_TAG;
+      break;
+    case LSM6DSO_XL_3XC_TAG:
+      *val = LSM6DSO_XL_3XC_TAG;
+      break;
+    case LSM6DSO_GYRO_NC_T_2_TAG:
+      *val = LSM6DSO_GYRO_NC_T_2_TAG;
+      break;
+    case LSM6DSO_GYRO_NC_T_1_TAG:
+      *val = LSM6DSO_GYRO_NC_T_1_TAG;
+      break;
+    case LSM6DSO_GYRO_2XC_TAG:
+      *val = LSM6DSO_GYRO_2XC_TAG;
+      break;
+    case LSM6DSO_GYRO_3XC_TAG:
+      *val = LSM6DSO_GYRO_3XC_TAG;
+      break;
+    case LSM6DSO_SENSORHUB_SLAVE0_TAG:
+      *val = LSM6DSO_SENSORHUB_SLAVE0_TAG;
+      break;
+    case LSM6DSO_SENSORHUB_SLAVE1_TAG:
+      *val = LSM6DSO_SENSORHUB_SLAVE1_TAG;
+      break;
+    case LSM6DSO_SENSORHUB_SLAVE2_TAG:
+      *val = LSM6DSO_SENSORHUB_SLAVE2_TAG;
+      break;
+    case LSM6DSO_SENSORHUB_SLAVE3_TAG:
+      *val = LSM6DSO_SENSORHUB_SLAVE3_TAG;
+      break;
+    case LSM6DSO_STEP_CPUNTER_TAG:
+      *val = LSM6DSO_STEP_CPUNTER_TAG;
+      break;
+    case LSM6DSO_GAME_ROTATION_TAG:
+      *val = LSM6DSO_GAME_ROTATION_TAG;
+      break;
+    case LSM6DSO_GEOMAG_ROTATION_TAG:
+      *val = LSM6DSO_GEOMAG_ROTATION_TAG;
+      break;
+    case LSM6DSO_ROTATION_TAG:
+      *val = LSM6DSO_ROTATION_TAG;
+      break;
+    case LSM6DSO_SENSORHUB_NACK_TAG:
+      *val = LSM6DSO_SENSORHUB_NACK_TAG;
+      break;
+    default:
+      *val = LSM6DSO_GYRO_NC_TAG;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  :  Enable FIFO batching of pedometer embedded
+  *            function values.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of gbias_fifo_en in
+  *                  reg LSM6DSO_EMB_FUNC_FIFO_CFG
+  *
+  */
+int32_t lsm6dso_fifo_pedo_batch_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_emb_func_fifo_cfg_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_FIFO_CFG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.pedo_fifo_en = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_FIFO_CFG,
+                            (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable FIFO batching of pedometer embedded function values.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of pedo_fifo_en in
+  *                  reg LSM6DSO_EMB_FUNC_FIFO_CFG
+  *
+  */
+int32_t lsm6dso_fifo_pedo_batch_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_emb_func_fifo_cfg_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_FIFO_CFG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    *val = reg.pedo_fifo_en;
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief   Enable FIFO batching data of first slave.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of  batch_ext_sens_0_en in
+  *                  reg SLV0_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_batch_slave_0_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_slv0_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV0_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.batch_ext_sens_0_en = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV0_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable FIFO batching data of first slave.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of  batch_ext_sens_0_en in
+  *                  reg SLV0_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_batch_slave_0_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_slv0_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV0_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    *val = reg.batch_ext_sens_0_en;
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable FIFO batching data of second slave.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of  batch_ext_sens_1_en in
+  *                  reg SLV1_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_batch_slave_1_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_slv1_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV1_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.batch_ext_sens_1_en = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV1_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief   Enable FIFO batching data of second slave.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of  batch_ext_sens_1_en in
+  *                  reg SLV1_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_batch_slave_1_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_slv1_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV1_CONFIG, (uint8_t*)&reg, 1);
+    *val = reg.batch_ext_sens_1_en;
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable FIFO batching data of third slave.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of  batch_ext_sens_2_en in
+  *                  reg SLV2_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_batch_slave_2_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_slv2_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV2_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.batch_ext_sens_2_en = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV2_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable FIFO batching data of third slave.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of  batch_ext_sens_2_en in
+  *                  reg SLV2_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_batch_slave_2_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_slv2_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV2_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    *val = reg.batch_ext_sens_2_en;
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief   Enable FIFO batching data of fourth slave.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of  batch_ext_sens_3_en
+  *                  in reg SLV3_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_batch_slave_3_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_slv3_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV3_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.batch_ext_sens_3_en = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV3_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Enable FIFO batching data of fourth slave.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of  batch_ext_sens_3_en in
+  *                  reg SLV3_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_batch_slave_3_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_slv3_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV3_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    *val = reg.batch_ext_sens_3_en;
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_DEN_functionality
+  * @brief     This section groups all the functions concerning
+  *            DEN functionality.
+  * @{
+  *
+*/
+
+/**
+  * @brief  DEN functionality marking mode.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of den_mode in reg CTRL6_C
+  *
+  */
+int32_t lsm6dso_den_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_den_mode_t val)
+{
+  lsm6dso_ctrl6_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.den_mode = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t*)&reg, 1);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  DEN functionality marking mode.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of den_mode in reg CTRL6_C
+  *
+  */
+int32_t lsm6dso_den_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_den_mode_t *val)
+{
+  lsm6dso_ctrl6_c_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t*)&reg, 1);
+
+  switch (reg.den_mode) {
+    case LSM6DSO_DEN_DISABLE:
+      *val = LSM6DSO_DEN_DISABLE;
+      break;
+    case LSM6DSO_LEVEL_FIFO:
+      *val = LSM6DSO_LEVEL_FIFO;
+      break;
+    case LSM6DSO_LEVEL_LETCHED:
+      *val = LSM6DSO_LEVEL_LETCHED;
+      break;
+    case LSM6DSO_LEVEL_TRIGGER:
+      *val = LSM6DSO_LEVEL_TRIGGER;
+      break;
+    case LSM6DSO_EDGE_TRIGGER:
+      *val = LSM6DSO_EDGE_TRIGGER;
+      break;
+    default:
+      *val = LSM6DSO_DEN_DISABLE;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  DEN active level configuration.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of den_lh in reg CTRL9_XL
+  *
+  */
+int32_t lsm6dso_den_polarity_set(lsm6dso_ctx_t *ctx, lsm6dso_den_lh_t val)
+{
+  lsm6dso_ctrl9_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.den_lh = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&reg, 1);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  DEN active level configuration.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of den_lh in reg CTRL9_XL
+  *
+  */
+int32_t lsm6dso_den_polarity_get(lsm6dso_ctx_t *ctx, lsm6dso_den_lh_t *val)
+{
+  lsm6dso_ctrl9_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&reg, 1);
+
+  switch (reg.den_lh) {
+    case LSM6DSO_DEN_ACT_LOW:
+      *val = LSM6DSO_DEN_ACT_LOW;
+      break;
+    case LSM6DSO_DEN_ACT_HIGH:
+      *val = LSM6DSO_DEN_ACT_HIGH;
+      break;
+    default:
+      *val = LSM6DSO_DEN_ACT_LOW;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  DEN enable.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of den_xl_g in reg CTRL9_XL
+  *
+  */
+int32_t lsm6dso_den_enable_set(lsm6dso_ctx_t *ctx, lsm6dso_den_xl_g_t val)
+{
+  lsm6dso_ctrl9_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.den_xl_g = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&reg, 1);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  DEN enable.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of den_xl_g in reg CTRL9_XL
+  *
+  */
+int32_t lsm6dso_den_enable_get(lsm6dso_ctx_t *ctx, lsm6dso_den_xl_g_t *val)
+{
+  lsm6dso_ctrl9_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&reg, 1);
+
+  switch (reg.den_xl_g) {
+    case LSM6DSO_STAMP_IN_GY_DATA:
+      *val = LSM6DSO_STAMP_IN_GY_DATA;
+      break;
+    case LSM6DSO_STAMP_IN_XL_DATA:
+      *val = LSM6DSO_STAMP_IN_XL_DATA;
+      break;
+    case LSM6DSO_STAMP_IN_GY_XL_DATA:
+      *val = LSM6DSO_STAMP_IN_GY_XL_DATA;
+      break;
+    default:
+      *val = LSM6DSO_STAMP_IN_GY_DATA;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  DEN value stored in LSB of X-axis.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of den_z in reg CTRL9_XL
+  *
+  */
+int32_t lsm6dso_den_mark_axis_x_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_ctrl9_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.den_z = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&reg, 1);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  DEN value stored in LSB of X-axis.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of den_z in reg CTRL9_XL
+  *
+  */
+int32_t lsm6dso_den_mark_axis_x_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_ctrl9_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&reg, 1);
+  *val = reg.den_z;
+
+  return ret;
+}
+
+/**
+  * @brief  DEN value stored in LSB of Y-axis.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of den_y in reg CTRL9_XL
+  *
+  */
+int32_t lsm6dso_den_mark_axis_y_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_ctrl9_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.den_y = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&reg, 1);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  DEN value stored in LSB of Y-axis.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of den_y in reg CTRL9_XL
+  *
+  */
+int32_t lsm6dso_den_mark_axis_y_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_ctrl9_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&reg, 1);
+  *val = reg.den_y;
+
+  return ret;
+}
+
+/**
+  * @brief  DEN value stored in LSB of Z-axis.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of den_x in reg CTRL9_XL
+  *
+  */
+int32_t lsm6dso_den_mark_axis_z_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_ctrl9_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&reg, 1);
+  if (ret == 0) {
+    reg.den_x = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&reg, 1);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  DEN value stored in LSB of Z-axis.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of den_x in reg CTRL9_XL
+  *
+  */
+int32_t lsm6dso_den_mark_axis_z_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_ctrl9_xl_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t*)&reg, 1);
+  *val = reg.den_x;
+
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_Pedometer
+  * @brief     This section groups all the functions that manage pedometer.
+  * @{
+  *
+*/
+
+/**
+  * @brief  Enable pedometer algorithm.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      turn on and configure pedometer
+  *
+  */
+int32_t lsm6dso_pedo_sens_set(lsm6dso_ctx_t *ctx, lsm6dso_pedo_md_t val)
+{
+  lsm6dso_emb_func_en_a_t emb_func_en_a;
+  lsm6dso_emb_func_en_b_t emb_func_en_b;
+  lsm6dso_pedo_cmd_reg_t pedo_cmd_reg;
+  int32_t ret;
+
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_PEDO_CMD_REG,
+                                (uint8_t*)&pedo_cmd_reg);
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_A,
+                           (uint8_t*)&emb_func_en_a, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_B,
+                           (uint8_t*)&emb_func_en_b, 1);
+
+    emb_func_en_a.pedo_en = (uint8_t)val & 0x01U;
+    emb_func_en_b.pedo_adv_en = ((uint8_t)val & 0x02U)>>1;
+    pedo_cmd_reg.fp_rejection_en = ((uint8_t)val & 0x10U)>>4;
+    pedo_cmd_reg.ad_det_en = ((uint8_t)val & 0x20U)>>5;
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_EN_A,
+                            (uint8_t*)&emb_func_en_a, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_EN_B,
+                            (uint8_t*)&emb_func_en_b, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_PEDO_CMD_REG,
+                                   (uint8_t*)&pedo_cmd_reg);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable pedometer algorithm.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      turn on and configure pedometer
+  *
+  */
+int32_t lsm6dso_pedo_sens_get(lsm6dso_ctx_t *ctx, lsm6dso_pedo_md_t *val)
+{
+  lsm6dso_emb_func_en_a_t emb_func_en_a;
+  lsm6dso_emb_func_en_b_t emb_func_en_b;
+  lsm6dso_pedo_cmd_reg_t pedo_cmd_reg;
+  int32_t ret;
+
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_PEDO_CMD_REG,
+                                (uint8_t*)&pedo_cmd_reg);
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_A,
+                           (uint8_t*)&emb_func_en_a, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_B,
+                           (uint8_t*)&emb_func_en_b, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  switch ( (pedo_cmd_reg.ad_det_en <<5) | (pedo_cmd_reg.fp_rejection_en << 4) |
+           (emb_func_en_b.pedo_adv_en << 1) | emb_func_en_a.pedo_en) {
+    case LSM6DSO_PEDO_DISABLE:
+      *val = LSM6DSO_PEDO_DISABLE;
+      break;
+    case LSM6DSO_PEDO_BASE_MODE:
+      *val = LSM6DSO_PEDO_BASE_MODE;
+      break;
+    case LSM6DSO_PEDO_ADV_MODE:
+      *val = LSM6DSO_PEDO_ADV_MODE;
+      break;
+    case LSM6DSO_FALSE_STEP_REJ:
+      *val = LSM6DSO_FALSE_STEP_REJ;
+      break;
+    case LSM6DSO_FALSE_STEP_REJ_ADV_MODE:
+      *val = LSM6DSO_FALSE_STEP_REJ_ADV_MODE;
+      break;
+    default:
+      *val = LSM6DSO_PEDO_DISABLE;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Interrupt status bit for step detection.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of is_step_det in reg EMB_FUNC_STATUS
+  *
+  */
+int32_t lsm6dso_pedo_step_detect_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_emb_func_status_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_STATUS, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    *val = reg.is_step_det;
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Pedometer debounce configuration register (r/w).[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that contains data to write
+  *
+  */
+int32_t lsm6dso_pedo_debounce_steps_set(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_PEDO_DEB_STEPS_CONF, buff);
+  return ret;
+}
+
+/**
+  * @brief  Pedometer debounce configuration register (r/w).[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_pedo_debounce_steps_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_PEDO_DEB_STEPS_CONF, buff);
+  return ret;
+}
+
+/**
+  * @brief  Time period register for step detection on delta time (r/w).[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that contains data to write
+  *
+  */
+int32_t lsm6dso_pedo_steps_period_set(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  uint8_t index;
+
+  index = 0x00U;
+  ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_PEDO_SC_DELTAT_L, &buff[index]);
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_PEDO_SC_DELTAT_H,
+                                   &buff[index]);
+  }
+  return ret;
+}
+
+/**
+  * @brief   Time period register for step detection on delta time (r/w).[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_pedo_steps_period_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  uint8_t index;
+
+  index = 0x00U;
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_PEDO_SC_DELTAT_L, &buff[index]);
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_PEDO_SC_DELTAT_H,
+                                  &buff[index]);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Set when user wants to generate interrupt on count overflow
+  *         event/every step.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of carry_count_en in reg PEDO_CMD_REG
+  *
+  */
+int32_t lsm6dso_pedo_int_mode_set(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_carry_count_en_t val)
+{
+  lsm6dso_pedo_cmd_reg_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_PEDO_CMD_REG, (uint8_t*)&reg);
+  if (ret == 0) {
+    reg.carry_count_en = (uint8_t)val;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_PEDO_CMD_REG,
+                                   (uint8_t*)&reg);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Set when user wants to generate interrupt on count overflow
+  *         event/every step.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of carry_count_en in reg PEDO_CMD_REG
+  *
+  */
+int32_t lsm6dso_pedo_int_mode_get(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_carry_count_en_t *val)
+{
+  lsm6dso_pedo_cmd_reg_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_PEDO_CMD_REG, (uint8_t*)&reg);
+  switch (reg.carry_count_en) {
+    case LSM6DSO_EVERY_STEP:
+      *val = LSM6DSO_EVERY_STEP;
+      break;
+    case LSM6DSO_COUNT_OVERFLOW:
+      *val = LSM6DSO_COUNT_OVERFLOW;
+      break;
+    default:
+      *val = LSM6DSO_EVERY_STEP;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_significant_motion
+  * @brief   This section groups all the functions that manage the
+  *          significant motion detection.
+  * @{
+  *
+*/
+
+/**
+  * @brief  Enable significant motion detection function.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of sign_motion_en in reg EMB_FUNC_EN_A
+  *
+  */
+int32_t lsm6dso_motion_sens_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_emb_func_en_a_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_A, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.sign_motion_en = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_EN_A, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable significant motion detection function.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of sign_motion_en in reg EMB_FUNC_EN_A
+  *
+  */
+int32_t lsm6dso_motion_sens_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_emb_func_en_a_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_A, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    *val = reg.sign_motion_en;
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief   Interrupt status bit for significant motion detection.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of is_sigmot in reg EMB_FUNC_STATUS
+  *
+  */
+int32_t lsm6dso_motion_flag_data_ready_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_emb_func_status_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_STATUS, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    *val = reg.is_sigmot;
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_tilt_detection
+  * @brief     This section groups all the functions that manage the tilt
+  *            event detection.
+  * @{
+  *
+*/
+
+/**
+  * @brief  Enable tilt calculation.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tilt_en in reg EMB_FUNC_EN_A
+  *
+  */
+int32_t lsm6dso_tilt_sens_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_emb_func_en_a_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_A, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.tilt_en = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_EN_A, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Enable tilt calculation.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of tilt_en in reg EMB_FUNC_EN_A
+  *
+  */
+int32_t lsm6dso_tilt_sens_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_emb_func_en_a_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_A, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    *val = reg.tilt_en;
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Interrupt status bit for tilt detection.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of is_tilt in reg EMB_FUNC_STATUS
+  *
+  */
+int32_t lsm6dso_tilt_flag_data_ready_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_emb_func_status_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_STATUS, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    *val = reg.is_tilt;
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_ magnetometer_sensor
+  * @brief     This section groups all the functions that manage additional
+  *            magnetometer sensor.
+  * @{
+  *
+*/
+
+/**
+  * @brief  External magnetometer sensitivity value register.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that contains data to write
+  *
+  */
+int32_t lsm6dso_mag_sensitivity_set(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  uint8_t index;
+
+  index = 0x00U;
+  ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SENSITIVITY_L,
+                                 &buff[index]);
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SENSITIVITY_H,
+                                   &buff[index]);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  External magnetometer sensitivity value register.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_mag_sensitivity_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  uint8_t index;
+
+  index = 0x00U;
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SENSITIVITY_L,
+                                &buff[index]);
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SENSITIVITY_H,
+                                  &buff[index]);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Offset for hard-iron compensation register (r/w).[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that contains data to write
+  *
+  */
+int32_t lsm6dso_mag_offset_set(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  uint8_t index;
+
+  index = 0x00U;
+  ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_OFFX_L, &buff[index]);
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_OFFX_H, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_OFFY_L, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_OFFY_H, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_OFFZ_L, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_OFFZ_H, &buff[index]);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Offset for hard-iron compensation register (r/w).[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_mag_offset_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  uint8_t index;
+
+  index = 0x00U;
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_OFFX_L, &buff[index]);
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_OFFX_H, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_OFFY_L, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_OFFY_H, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_OFFZ_L, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_OFFZ_H, &buff[index]);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Soft-iron (3x3 symmetric) matrix correction
+  *         register (r/w). The value is expressed as
+  *         half-precision floating-point format:
+  *         SEEEEEFFFFFFFFFF
+  *         S: 1 sign bit;
+  *         E: 5 exponent bits;
+  *         F: 10 fraction bits).[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that contains data to write
+  *
+  */
+int32_t lsm6dso_mag_soft_iron_set(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  uint8_t index;
+
+  index = 0x00U;
+  ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_XX_L, &buff[index]);
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_XX_H, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_XY_L, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_XY_H, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_XZ_L, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_XZ_H, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_YY_L, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_YY_H, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_YZ_L, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_YZ_H, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_ZZ_L, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_ZZ_H, &buff[index]);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Soft-iron (3x3 symmetric) matrix
+  *         correction register (r/w).
+  *         The value is expressed as half-precision
+  *         floating-point format:
+  *         SEEEEEFFFFFFFFFF
+  *         S: 1 sign bit;
+  *         E: 5 exponent bits;
+  *         F: 10 fraction bits.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_mag_soft_iron_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  uint8_t index;
+
+  index = 0x00U;
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_XX_L, &buff[index]);
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_XX_H, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_XY_L, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_XY_H, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_XZ_L, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_XZ_H, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_YY_L, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_YY_H, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_YZ_L, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_YZ_H, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_ZZ_L, &buff[index]);
+  }
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_ZZ_H, &buff[index]);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Magnetometer Z-axis coordinates
+  *         rotation (to be aligned to
+  *         accelerometer/gyroscope axes
+  *         orientation).[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of mag_z_axis in reg MAG_CFG_A
+  *
+  */
+int32_t lsm6dso_mag_z_orient_set(lsm6dso_ctx_t *ctx, lsm6dso_mag_z_axis_t val)
+{
+  lsm6dso_mag_cfg_a_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_CFG_A, (uint8_t*)&reg);
+  if (ret == 0) {
+    reg.mag_z_axis = (uint8_t) val;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_CFG_A, (uint8_t*)&reg);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Magnetometer Z-axis coordinates
+  *         rotation (to be aligned to
+  *         accelerometer/gyroscope axes
+  *         orientation).[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of mag_z_axis in reg MAG_CFG_A
+  *
+  */
+int32_t lsm6dso_mag_z_orient_get(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_mag_z_axis_t *val)
+{
+  lsm6dso_mag_cfg_a_t reg;
+  int32_t ret;
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_CFG_A, (uint8_t*)&reg);
+  switch (reg.mag_z_axis) {
+    case LSM6DSO_Z_EQ_Y:
+      *val = LSM6DSO_Z_EQ_Y;
+      break;
+    case LSM6DSO_Z_EQ_MIN_Y:
+      *val = LSM6DSO_Z_EQ_MIN_Y;
+      break;
+    case LSM6DSO_Z_EQ_X:
+      *val = LSM6DSO_Z_EQ_X;
+      break;
+    case LSM6DSO_Z_EQ_MIN_X:
+      *val = LSM6DSO_Z_EQ_MIN_X;
+      break;
+    case LSM6DSO_Z_EQ_MIN_Z:
+      *val = LSM6DSO_Z_EQ_MIN_Z;
+      break;
+    case LSM6DSO_Z_EQ_Z:
+      *val = LSM6DSO_Z_EQ_Z;
+      break;
+    default:
+      *val = LSM6DSO_Z_EQ_Y;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief   Magnetometer Y-axis coordinates
+  *          rotation (to be aligned to
+  *          accelerometer/gyroscope axes
+  *          orientation).[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of mag_y_axis in reg MAG_CFG_A
+  *
+  */
+int32_t lsm6dso_mag_y_orient_set(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_mag_y_axis_t val)
+{
+  lsm6dso_mag_cfg_a_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_CFG_A, (uint8_t*)&reg);
+  if (ret == 0) {
+    reg.mag_y_axis = (uint8_t)val;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_CFG_A,(uint8_t*) &reg);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Magnetometer Y-axis coordinates
+  *         rotation (to be aligned to
+  *         accelerometer/gyroscope axes
+  *         orientation).[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of mag_y_axis in reg MAG_CFG_A
+  *
+  */
+int32_t lsm6dso_mag_y_orient_get(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_mag_y_axis_t *val)
+{
+  lsm6dso_mag_cfg_a_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_CFG_A, (uint8_t*)&reg);
+  switch (reg.mag_y_axis) {
+    case LSM6DSO_Y_EQ_Y:
+      *val = LSM6DSO_Y_EQ_Y;
+      break;
+    case LSM6DSO_Y_EQ_MIN_Y:
+      *val = LSM6DSO_Y_EQ_MIN_Y;
+      break;
+    case LSM6DSO_Y_EQ_X:
+      *val = LSM6DSO_Y_EQ_X;
+      break;
+    case LSM6DSO_Y_EQ_MIN_X:
+      *val = LSM6DSO_Y_EQ_MIN_X;
+      break;
+    case LSM6DSO_Y_EQ_MIN_Z:
+      *val = LSM6DSO_Y_EQ_MIN_Z;
+      break;
+    case LSM6DSO_Y_EQ_Z:
+      *val = LSM6DSO_Y_EQ_Z;
+      break;
+    default:
+      *val = LSM6DSO_Y_EQ_Y;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @brief  Magnetometer X-axis coordinates
+  *         rotation (to be aligned to
+  *         accelerometer/gyroscope axes
+  *         orientation).[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of mag_x_axis in reg MAG_CFG_B
+  *
+  */
+int32_t lsm6dso_mag_x_orient_set(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_mag_x_axis_t val)
+{
+  lsm6dso_mag_cfg_b_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_CFG_B, (uint8_t*)&reg);
+  if (ret == 0) {
+    reg.mag_x_axis = (uint8_t)val;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_CFG_B, (uint8_t*)&reg);
+  }
+  return ret;
+}
+
+/**
+  * @brief   Magnetometer X-axis coordinates
+  *          rotation (to be aligned to
+  *          accelerometer/gyroscope axes
+  *          orientation).[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of mag_x_axis in reg MAG_CFG_B
+  *
+  */
+int32_t lsm6dso_mag_x_orient_get(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_mag_x_axis_t *val)
+{
+  lsm6dso_mag_cfg_b_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_CFG_B, (uint8_t*)&reg);
+  switch (reg.mag_x_axis) {
+    case LSM6DSO_X_EQ_Y:
+      *val = LSM6DSO_X_EQ_Y;
+      break;
+    case LSM6DSO_X_EQ_MIN_Y:
+      *val = LSM6DSO_X_EQ_MIN_Y;
+      break;
+    case LSM6DSO_X_EQ_X:
+      *val = LSM6DSO_X_EQ_X;
+      break;
+    case LSM6DSO_X_EQ_MIN_X:
+      *val = LSM6DSO_X_EQ_MIN_X;
+      break;
+    case LSM6DSO_X_EQ_MIN_Z:
+      *val = LSM6DSO_X_EQ_MIN_Z;
+      break;
+    case LSM6DSO_X_EQ_Z:
+      *val = LSM6DSO_X_EQ_Z;
+      break;
+    default:
+      *val = LSM6DSO_X_EQ_Y;
+      break;
+  }
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_significant_motion
+  * @brief     This section groups all the functions that manage the
+  *            state_machine.
+  * @{
+  *
+*/
+
+/**
+  * @brief   Interrupt status bit for FSM long counter
+  *          timeout interrupt event.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of is_fsm_lc in reg EMB_FUNC_STATUS
+  *
+  */
+int32_t lsm6dso_long_cnt_flag_data_ready_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_emb_func_status_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_STATUS, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    *val = reg.is_fsm_lc;
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Final State Machine global enable.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of fsm_en in reg EMB_FUNC_EN_B
+  *
+  */
+int32_t lsm6dso_emb_fsm_en_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  int32_t ret;
+  lsm6dso_emb_func_en_b_t reg;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_B, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.fsm_en = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_EN_B, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Final State Machine global enable.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  uint8_t *: return the values of fsm_en in reg EMB_FUNC_EN_B
+  *
+  */
+int32_t lsm6dso_emb_fsm_en_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  int32_t ret;
+  lsm6dso_emb_func_en_b_t reg;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_B, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    *val = reg.fsm_en;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_EN_B, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Final State Machine enable.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      union of registers from FSM_ENABLE_A to FSM_ENABLE_B
+  *
+  */
+int32_t lsm6dso_fsm_enable_set(lsm6dso_ctx_t *ctx,
+                               lsm6dso_emb_fsm_enable_t *val)
+{
+  int32_t ret;
+  lsm6dso_emb_func_en_b_t reg;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FSM_ENABLE_A,
+                            (uint8_t*)&val->fsm_enable_a, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FSM_ENABLE_B,
+                            (uint8_t*)&val->fsm_enable_b, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_B, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    if ( (val->fsm_enable_a.fsm1_en   |
+         val->fsm_enable_a.fsm2_en  |
+         val->fsm_enable_a.fsm3_en  |
+         val->fsm_enable_a.fsm4_en  |
+         val->fsm_enable_a.fsm5_en  |
+         val->fsm_enable_a.fsm6_en  |
+         val->fsm_enable_a.fsm7_en  |
+         val->fsm_enable_a.fsm8_en  |
+         val->fsm_enable_b.fsm9_en  |
+         val->fsm_enable_b.fsm10_en  |
+         val->fsm_enable_b.fsm11_en  |
+         val->fsm_enable_b.fsm12_en  |
+         val->fsm_enable_b.fsm13_en  |
+         val->fsm_enable_b.fsm14_en  |
+         val->fsm_enable_b.fsm15_en  |
+         val->fsm_enable_b.fsm16_en  )
+        != PROPERTY_DISABLE)
+    {
+      reg.fsm_en = PROPERTY_ENABLE;
+    }
+    else
+    {
+      reg.fsm_en = PROPERTY_DISABLE;
+    }
+
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_EN_B, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Final State Machine enable.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      union of registers from FSM_ENABLE_A to FSM_ENABLE_B
+  *
+  */
+int32_t lsm6dso_fsm_enable_get(lsm6dso_ctx_t *ctx,
+                               lsm6dso_emb_fsm_enable_t *val)
+{
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_ENABLE_A, (uint8_t*) val, 2);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  FSM long counter status register. Long counter value is an
+  *         unsigned integer value (16-bit format).[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that contains data to write
+  *
+  */
+int32_t lsm6dso_long_cnt_set(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FSM_LONG_COUNTER_L, buff, 2);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  FSM long counter status register. Long counter value is an
+  *         unsigned integer value (16-bit format).[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_long_cnt_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_LONG_COUNTER_L, buff, 2);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Clear FSM long counter value.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of fsm_lc_clr in
+  *                  reg FSM_LONG_COUNTER_CLEAR
+  *
+  */
+int32_t lsm6dso_long_clr_set(lsm6dso_ctx_t *ctx, lsm6dso_fsm_lc_clr_t val)
+{
+  lsm6dso_fsm_long_counter_clear_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_LONG_COUNTER_CLEAR,
+    (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg. fsm_lc_clr = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_FSM_LONG_COUNTER_CLEAR,
+    (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Clear FSM long counter value.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of fsm_lc_clr in
+  *                  reg FSM_LONG_COUNTER_CLEAR
+  *
+  */
+int32_t lsm6dso_long_clr_get(lsm6dso_ctx_t *ctx, lsm6dso_fsm_lc_clr_t *val)
+{
+  lsm6dso_fsm_long_counter_clear_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_LONG_COUNTER_CLEAR,
+    (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    switch (reg.fsm_lc_clr) {
+      case LSM6DSO_LC_NORMAL:
+        *val = LSM6DSO_LC_NORMAL;
+        break;
+      case LSM6DSO_LC_CLEAR:
+        *val = LSM6DSO_LC_CLEAR;
+        break;
+      case LSM6DSO_LC_CLEAR_DONE:
+        *val = LSM6DSO_LC_CLEAR_DONE;
+        break;
+      default:
+        *val = LSM6DSO_LC_NORMAL;
+        break;
+    }
+  }
+
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  FSM output registers[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      struct of registers from FSM_OUTS1 to FSM_OUTS16
+  *
+  */
+int32_t lsm6dso_fsm_out_get(lsm6dso_ctx_t *ctx, lsm6dso_fsm_out_t *val)
+{
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_OUTS1, (uint8_t*) &val, 16);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Finite State Machine ODR configuration.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of fsm_odr in reg EMB_FUNC_ODR_CFG_B
+  *
+  */
+int32_t lsm6dso_fsm_data_rate_set(lsm6dso_ctx_t *ctx, lsm6dso_fsm_odr_t val)
+{
+  lsm6dso_emb_func_odr_cfg_b_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_ODR_CFG_B,
+                           (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.not_used_01 = 3; /* set default values */
+    reg.not_used_02 = 1; /* set default values */
+    reg.fsm_odr = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_ODR_CFG_B,
+                            (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Finite State Machine ODR configuration.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of fsm_odr in reg EMB_FUNC_ODR_CFG_B
+  *
+  */
+int32_t lsm6dso_fsm_data_rate_get(lsm6dso_ctx_t *ctx, lsm6dso_fsm_odr_t *val)
+{
+  lsm6dso_emb_func_odr_cfg_b_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_ODR_CFG_B,
+                           (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    switch (reg.fsm_odr) {
+      case LSM6DSO_ODR_FSM_12Hz5:
+        *val = LSM6DSO_ODR_FSM_12Hz5;
+        break;
+      case LSM6DSO_ODR_FSM_26Hz:
+        *val = LSM6DSO_ODR_FSM_26Hz;
+        break;
+      case LSM6DSO_ODR_FSM_52Hz:
+        *val = LSM6DSO_ODR_FSM_52Hz;
+        break;
+      case LSM6DSO_ODR_FSM_104Hz:
+        *val = LSM6DSO_ODR_FSM_104Hz;
+        break;
+      case LSM6DSO_ODR_FSM_208Hz:
+        *val = LSM6DSO_ODR_FSM_208Hz;
+        break;
+      case LSM6DSO_ODR_FSM_416Hz:
+        *val = LSM6DSO_ODR_FSM_416Hz;
+        break;
+      default:
+        *val = LSM6DSO_ODR_FSM_12Hz5;
+        break;
+    }
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  FSM initialization request.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of fsm_init in reg FSM_INIT
+  *
+  */
+int32_t lsm6dso_fsm_init_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_emb_func_init_b_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_INIT_B, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.fsm_init = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_INIT_B, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  FSM initialization request.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of fsm_init in reg FSM_INIT
+  *
+  */
+int32_t lsm6dso_fsm_init_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_emb_func_init_b_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_INIT_B, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    *val = reg.fsm_init;
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  FSM long counter timeout register (r/w). The long counter
+  *         timeout value is an unsigned integer value (16-bit format).
+  *         When the long counter value reached this value,
+  *         the FSM generates an interrupt.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that contains data to write
+  *
+  */
+int32_t lsm6dso_long_cnt_int_value_set(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  uint8_t index;
+
+  index = 0x00U;
+  ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_FSM_LC_TIMEOUT_L, &buff[index]);
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_FSM_LC_TIMEOUT_H,
+                                   &buff[index]);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  FSM long counter timeout register (r/w). The long counter
+  *         timeout value is an unsigned integer value (16-bit format).
+  *         When the long counter value reached this value,
+  *         the FSM generates an interrupt.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_long_cnt_int_value_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  uint8_t index;
+
+  index = 0x00U;
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_FSM_LC_TIMEOUT_L, &buff[index]);
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_FSM_LC_TIMEOUT_H,
+                                  &buff[index]);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  FSM number of programs register.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that contains data to write
+  *
+  */
+int32_t lsm6dso_fsm_number_of_programs_set(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+
+  ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_FSM_PROGRAMS, buff);
+
+  return ret;
+}
+
+/**
+  * @brief  FSM number of programs register.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_fsm_number_of_programs_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_FSM_PROGRAMS, buff);
+
+  return ret;
+}
+
+/**
+  * @brief  FSM start address register (r/w).
+  *         First available address is 0x033C.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that contains data to write
+  *
+  */
+int32_t lsm6dso_fsm_start_address_set(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  uint8_t index;
+
+  index = 0x00U;
+  ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_FSM_START_ADD_L, &buff[index]);
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_FSM_START_ADD_H,
+                                   &buff[index]);
+  }
+  return ret;
+}
+
+/**
+  * @brief  FSM start address register (r/w).
+  *         First available address is 0x033C.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  buff     buffer that stores data read
+  *
+  */
+int32_t lsm6dso_fsm_start_address_get(lsm6dso_ctx_t *ctx, uint8_t *buff)
+{
+  int32_t ret;
+  uint8_t index;
+
+  index = 0x00U;
+  ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_FSM_START_ADD_L, buff);
+  if (ret == 0) {
+    index++;
+    ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_FSM_START_ADD_H, buff);
+  }
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @defgroup  LSM6DSO_Sensor_hub
+  * @brief     This section groups all the functions that manage the
+  *            sensor hub.
+  * @{
+  *
+*/
+
+/**
+* @brief  Sensor hub output registers.[get]
+*
+* @param  ctx      read / write interface definitions
+* @param  val      union of registers from SENSOR_HUB_1 to SENSOR_HUB_18
+*
+  */
+int32_t lsm6dso_sh_read_data_raw_get(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_emb_sh_read_t *val)
+{
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_SENSOR_HUB_1, (uint8_t*) val, 18U);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Number of external sensors to be read by the sensor hub.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of aux_sens_on in reg MASTER_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_slave_connected_set(lsm6dso_ctx_t *ctx,
+                                       lsm6dso_aux_sens_on_t val)
+{
+  lsm6dso_master_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.aux_sens_on = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Number of external sensors to be read by the sensor hub.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of aux_sens_on in reg MASTER_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_slave_connected_get(lsm6dso_ctx_t *ctx,
+                                       lsm6dso_aux_sens_on_t *val)
+{
+  lsm6dso_master_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    switch (reg.aux_sens_on) {
+      case LSM6DSO_SLV_0:
+        *val = LSM6DSO_SLV_0;
+        break;
+      case LSM6DSO_SLV_0_1:
+        *val = LSM6DSO_SLV_0_1;
+        break;
+      case LSM6DSO_SLV_0_1_2:
+        *val = LSM6DSO_SLV_0_1_2;
+        break;
+      case LSM6DSO_SLV_0_1_2_3:
+        *val = LSM6DSO_SLV_0_1_2_3;
+        break;
+      default:
+        *val = LSM6DSO_SLV_0;
+        break;
+    }
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Sensor hub I2C master enable.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of master_on in reg MASTER_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_master_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_master_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.master_on = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Sensor hub I2C master enable.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of master_on in reg MASTER_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_master_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_master_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    *val = reg.master_on;
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Master I2C pull-up enable.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of shub_pu_en in reg MASTER_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_pin_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_shub_pu_en_t val)
+{
+  lsm6dso_master_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.shub_pu_en = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Master I2C pull-up enable.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of shub_pu_en in reg MASTER_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_pin_mode_get(lsm6dso_ctx_t *ctx,
+                                lsm6dso_shub_pu_en_t *val)
+{
+  lsm6dso_master_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    switch (reg.shub_pu_en) {
+      case LSM6DSO_EXT_PULL_UP:
+        *val = LSM6DSO_EXT_PULL_UP;
+        break;
+      case LSM6DSO_INTERNAL_PULL_UP:
+        *val = LSM6DSO_INTERNAL_PULL_UP;
+        break;
+      default:
+        *val = LSM6DSO_EXT_PULL_UP;
+        break;
+    }
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  I2C interface pass-through.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of pass_through_mode in
+  *                  reg MASTER_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_pass_through_set(lsm6dso_ctx_t *ctx, uint8_t val)
+{
+  lsm6dso_master_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.pass_through_mode = val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  I2C interface pass-through.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of pass_through_mode in
+  *                  reg MASTER_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_pass_through_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_master_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    *val = reg.pass_through_mode;
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Sensor hub trigger signal selection.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of start_config in reg MASTER_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_syncro_mode_set(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_start_config_t val)
+{
+  lsm6dso_master_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.start_config = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Sensor hub trigger signal selection.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of start_config in reg MASTER_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_syncro_mode_get(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_start_config_t *val)
+{
+  lsm6dso_master_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    switch (reg.start_config) {
+      case LSM6DSO_EXT_ON_INT2_PIN:
+        *val = LSM6DSO_EXT_ON_INT2_PIN;
+        break;
+      case LSM6DSO_XL_GY_DRDY:
+        *val = LSM6DSO_XL_GY_DRDY;
+        break;
+      default:
+        *val = LSM6DSO_EXT_ON_INT2_PIN;
+        break;
+    }
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Slave 0 write operation is performed only at the first
+  *         sensor hub cycle.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of write_once in reg MASTER_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_write_mode_set(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_write_once_t val)
+{
+  lsm6dso_master_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.write_once = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Slave 0 write operation is performed only at the first sensor
+  *         hub cycle.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of write_once in reg MASTER_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_write_mode_get(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_write_once_t *val)
+{
+  lsm6dso_master_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    switch (reg.write_once) {
+      case LSM6DSO_EACH_SH_CYCLE:
+        *val = LSM6DSO_EACH_SH_CYCLE;
+        break;
+      case LSM6DSO_ONLY_FIRST_CYCLE:
+        *val = LSM6DSO_ONLY_FIRST_CYCLE;
+        break;
+      default:
+        *val = LSM6DSO_EACH_SH_CYCLE;
+        break;
+    }
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Reset Master logic and output registers.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  *
+  */
+int32_t lsm6dso_sh_reset_set(lsm6dso_ctx_t *ctx)
+{
+  lsm6dso_master_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.rst_master_regs = PROPERTY_ENABLE;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.rst_master_regs = PROPERTY_DISABLE;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Reset Master logic and output registers.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of rst_master_regs in reg MASTER_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_reset_get(lsm6dso_ctx_t *ctx, uint8_t *val)
+{
+  lsm6dso_master_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    *val = reg.rst_master_regs;
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Rate at which the master communicates.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      change the values of shub_odr in reg slv1_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_data_rate_set(lsm6dso_ctx_t *ctx, lsm6dso_shub_odr_t val)
+{
+  lsm6dso_slv0_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV1_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    reg.shub_odr = (uint8_t)val;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV1_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Rate at which the master communicates.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Get the values of shub_odr in reg slv1_CONFIG
+  *
+  */
+int32_t lsm6dso_sh_data_rate_get(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_shub_odr_t *val)
+{
+  lsm6dso_slv0_config_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV1_CONFIG, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    switch (reg.shub_odr) {
+      case LSM6DSO_SH_ODR_104Hz:
+        *val = LSM6DSO_SH_ODR_104Hz;
+        break;
+      case LSM6DSO_SH_ODR_52Hz:
+        *val = LSM6DSO_SH_ODR_52Hz;
+        break;
+      case LSM6DSO_SH_ODR_26Hz:
+        *val = LSM6DSO_SH_ODR_26Hz;
+        break;
+      case LSM6DSO_SH_ODR_13Hz:
+        *val = LSM6DSO_SH_ODR_13Hz;
+        break;
+      default:
+        *val = LSM6DSO_SH_ODR_104Hz;
+        break;
+    }
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Configure slave 0 for perform a write.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      a structure that contain
+  *                      - uint8_t slv1_add;    8 bit i2c device address
+  *                      - uint8_t slv1_subadd; 8 bit register device address
+  *                      - uint8_t slv1_data;   8 bit data to write
+  *
+  */
+int32_t lsm6dso_sh_cfg_write(lsm6dso_ctx_t *ctx, lsm6dso_sh_cfg_write_t *val)
+{
+  lsm6dso_slv0_add_t reg;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    reg.slave0 = val->slv0_add;
+    reg.rw_0 = 0;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV0_ADD, (uint8_t*)&reg, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV0_SUBADD,
+    &(val->slv0_subadd), 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_DATAWRITE_SLV0,
+    &(val->slv0_data), 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Configure slave 0 for perform a read.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Structure that contain
+  *                      - uint8_t slv1_add;    8 bit i2c device address
+  *                      - uint8_t slv1_subadd; 8 bit register device address
+  *                      - uint8_t slv1_len;    num of bit to read
+  *
+  */
+int32_t lsm6dso_sh_slv0_cfg_read(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_sh_cfg_read_t *val)
+{
+  lsm6dso_slv0_add_t slv0_add;
+  lsm6dso_slv0_config_t slv0_config;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    slv0_add.slave0 = val->slv_add;
+    slv0_add.rw_0 = 1;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV0_ADD, (uint8_t*)&slv0_add, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV0_SUBADD,
+    &(val->slv_subadd), 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV0_CONFIG,
+                           (uint8_t*)&slv0_config, 1);
+  }
+  if (ret == 0) {
+    slv0_config.slave0_numop = val->slv_len;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV0_CONFIG,
+                            (uint8_t*)&slv0_config, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Configure slave 0 for perform a write/read.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Structure that contain
+  *                      - uint8_t slv1_add;    8 bit i2c device address
+  *                      - uint8_t slv1_subadd; 8 bit register device address
+  *                      - uint8_t slv1_len;    num of bit to read
+  *
+  */
+int32_t lsm6dso_sh_slv1_cfg_read(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_sh_cfg_read_t *val)
+{
+  lsm6dso_slv1_add_t slv1_add;
+  lsm6dso_slv1_config_t slv1_config;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    slv1_add.slave1_add = val->slv_add;
+    slv1_add.r_1 = 1;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV1_ADD, (uint8_t*)&slv1_add, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV1_SUBADD,
+    &(val->slv_subadd), 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV1_CONFIG,
+                           (uint8_t*)&slv1_config, 1);
+  }
+  if (ret == 0) {
+    slv1_config.slave1_numop = val->slv_len;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV1_CONFIG,
+                            (uint8_t*)&slv1_config, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Configure slave 0 for perform a write/read.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Structure that contain
+  *                      - uint8_t slv2_add;    8 bit i2c device address
+  *                      - uint8_t slv2_subadd; 8 bit register device address
+  *                      - uint8_t slv2_len;    num of bit to read
+  *
+  */
+int32_t lsm6dso_sh_slv2_cfg_read(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_sh_cfg_read_t *val)
+{
+  lsm6dso_slv2_add_t slv2_add;
+  lsm6dso_slv2_config_t slv2_config;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    slv2_add.slave2_add = val->slv_add;
+    slv2_add.r_2 = 1;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV2_ADD, (uint8_t*)&slv2_add, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV2_SUBADD,
+    &(val->slv_subadd), 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV2_CONFIG,
+                           (uint8_t*)&slv2_config, 1);
+  }
+  if (ret == 0) {
+    slv2_config.slave2_numop = val->slv_len;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV2_CONFIG,
+                            (uint8_t*)&slv2_config, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief Configure slave 0 for perform a write/read.[set]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      Structure that contain
+  *                      - uint8_t slv3_add;    8 bit i2c device address
+  *                      - uint8_t slv3_subadd; 8 bit register device address
+  *                      - uint8_t slv3_len;    num of bit to read
+  *
+  */
+int32_t lsm6dso_sh_slv3_cfg_read(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_sh_cfg_read_t *val)
+{
+  lsm6dso_slv3_add_t slv3_add;
+  lsm6dso_slv3_config_t slv3_config;
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    slv3_add.slave3_add = val->slv_add;
+    slv3_add.r_3 = 1;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV3_ADD, (uint8_t*)&slv3_add, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV3_SUBADD,
+    &(val->slv_subadd), 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV3_CONFIG,
+                           (uint8_t*)&slv3_config, 1);
+  }
+  if (ret == 0) {
+    slv3_config.slave3_numop = val->slv_len;
+    ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV3_CONFIG,
+                            (uint8_t*)&slv3_config, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+  return ret;
+}
+
+/**
+  * @brief  Sensor hub source register.[get]
+  *
+  * @param  ctx      read / write interface definitions
+  * @param  val      union of registers from STATUS_MASTER to
+  *
+  */
+int32_t lsm6dso_sh_status_get(lsm6dso_ctx_t *ctx,
+                              lsm6dso_status_master_t *val)
+{
+  int32_t ret;
+
+  ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK);
+  if (ret == 0) {
+    ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_MASTER, (uint8_t*) val, 1);
+  }
+  if (ret == 0) {
+    ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK);
+  }
+
+  return ret;
+}
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @}
+  *
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lsm6dso_reg.h	Tue Mar 05 16:26:47 2019 +0000
@@ -0,0 +1,2744 @@
+/*
+ ******************************************************************************
+ * @file    lsm6dso_reg.h
+ * @author  Sensor Solutions Software Team
+ * @brief   This file contains all the functions prototypes for the
+ *          lsm6dso_reg.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2018 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 LSM6DSO_DRIVER_H
+#define LSM6DSO_DRIVER_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+#include <math.h>
+
+/** @addtogroup LSM6DSO
+  * @{
+  *
+  */
+
+/** @defgroup LSM6DSO_sensors_common_types
+  * @{
+  *
+  */
+
+#ifndef MEMS_SHARED_TYPES
+#define MEMS_SHARED_TYPES
+
+/**
+  * @defgroup axisXbitXX_t
+  * @brief    These unions are useful to represent different sensors data type.
+  *           These unions are not need by the driver.
+  *
+  *           REMOVING the unions you are compliant with:
+  *           MISRA-C 2012 [Rule 19.2] -> " Union are not allowed "
+  *
+  * @{
+  *
+  */
+
+typedef union{
+  int16_t i16bit[3];
+  uint8_t u8bit[6];
+} axis3bit16_t;
+
+typedef union{
+  int16_t i16bit;
+  uint8_t u8bit[2];
+} axis1bit16_t;
+
+typedef union{
+  int32_t i32bit[3];
+  uint8_t u8bit[12];
+} axis3bit32_t;
+
+typedef union{
+  int32_t i32bit;
+  uint8_t u8bit[4];
+} axis1bit32_t;
+
+/**
+  * @}
+  *
+  */
+
+typedef struct{
+  uint8_t bit0       : 1;
+  uint8_t bit1       : 1;
+  uint8_t bit2       : 1;
+  uint8_t bit3       : 1;
+  uint8_t bit4       : 1;
+  uint8_t bit5       : 1;
+  uint8_t bit6       : 1;
+  uint8_t bit7       : 1;
+} bitwise_t;
+
+#define PROPERTY_DISABLE                (0U)
+#define PROPERTY_ENABLE                 (1U)
+
+#endif /* MEMS_SHARED_TYPES */
+
+/**
+  * @}
+  *
+  */
+
+/** @addtogroup  LSM6DSO_Interfaces_Functions
+  * @brief       This section provide a set of functions used to read and
+  *              write a generic register of the device.
+  *              MANDATORY: return 0 -> no Error.
+  * @{
+  *
+  */
+
+typedef int32_t (*lsm6dso_write_ptr)(void *, uint8_t, uint8_t*, uint16_t);
+typedef int32_t (*lsm6dso_read_ptr) (void *, uint8_t, uint8_t*, uint16_t);
+
+typedef struct {
+  /** Component mandatory fields **/
+  lsm6dso_write_ptr  write_reg;
+  lsm6dso_read_ptr   read_reg;
+  /** Customizable optional pointer **/
+  void *handle;
+} lsm6dso_ctx_t;
+
+/**
+  * @}
+  *
+  */
+
+/** @defgroup LSM6DSO_Infos
+  * @{
+  *
+  */
+
+/** I2C Device Address 8 bit format  if SA0=0 -> D5 if SA0=1 -> D7 **/
+#define LSM6DSO_I2C_ADD_L                    0xD5
+#define LSM6DSO_I2C_ADD_H                    0xD7
+
+/** Device Identification (Who am I) **/
+#define LSM6DSO_ID                           0x6C
+
+/**
+  * @}
+  *
+  */
+
+/**
+  * @addtogroup  LSM6DSO_Sensitivity
+  * @brief       These macro are maintained for back compatibility.
+  *              in order to convert data into engineering units please
+  *              use functions:
+  *                -> _from_fs2_to_mg(int16_t lsb);
+  *                -> _from_fs4_to_mg(int16_t lsb);
+  *                -> _from_fs8_to_mg(int16_t lsb);
+  *                -> _from_fs16_to_mg(int16_t lsb);
+  *                -> _from_fs125_to_mdps(int16_t lsb);
+  *                -> _from_fs500_to_mdps(int16_t lsb);
+  *                -> _from_fs250_to_mdps(int16_t lsb);
+  *                -> _from_fs1000_to_mdps(int16_t lsb);
+  *                -> _from_fs2000_to_mdps(int16_t lsb);
+  *                -> _from_lsb_to_celsius(int16_t lsb);
+  *                -> _from_lsb_to_nsec(int16_t lsb);
+  *
+  *              REMOVING the MACRO you are compliant with:
+  *              MISRA-C 2012 [Dir 4.9] -> " avoid function-like macros "
+  * @{
+  *
+  */
+
+#define LSM6DSO_FROM_FS_2g_TO_mg(lsb)    (float)(lsb *  61.0f) / 1000.0f
+#define LSM6DSO_FROM_FS_4g_TO_mg(lsb)    (float)(lsb * 122.0f) / 1000.0f
+#define LSM6DSO_FROM_FS_8g_TO_mg(lsb)    (float)(lsb * 244.0f) / 1000.0f
+#define LSM6DSO_FROM_FS_16g_TO_mg(lsb)   (float)(lsb * 488.0f) / 1000.0f
+
+#define LSM6DSO_FROM_FS_125dps_TO_mdps(lsb)    (float)(lsb *  4375.0f) / 1000.0f
+#define LSM6DSO_FROM_FS_250dps_TO_mdps(lsb)    (float)(lsb *  8750.0f) / 1000.0f
+#define LSM6DSO_FROM_FS_500dps_TO_mdps(lsb)    (float)(lsb * 17500.0f) / 1000.0f
+#define LSM6DSO_FROM_FS_1000dps_TO_mdps(lsb)   (float)(lsb * 35000.0f) / 1000.0f
+#define LSM6DSO_FROM_FS_2000dps_TO_mdps(lsb)   (float)(lsb * 70000.0f) / 1000.0f
+
+#define LSM6DSO_FROM_LSB_TO_degC(lsb)    ((float)((int16_t)lsb>>8)*1.0f + 25.0f)
+
+#define LSM6DSO_TIMESTAMP_LSB_TO_NSEC        25000ULL
+
+/**
+  * @}
+  *
+  */
+
+#define LSM6DSO_FUNC_CFG_ACCESS              0x01U
+typedef struct {
+  uint8_t not_used_01              : 6;
+  uint8_t reg_access               : 2; /* shub_reg_access + func_cfg_access */
+} lsm6dso_func_cfg_access_t;
+
+#define LSM6DSO_PIN_CTRL                     0x02U
+typedef struct {
+  uint8_t not_used_01              : 6;
+  uint8_t sdo_pu_en                : 1;
+  uint8_t ois_pu_dis               : 1;
+} lsm6dso_pin_ctrl_t;
+
+#define LSM6DSO_FIFO_CTRL1                   0x07U
+typedef struct {
+  uint8_t wtm                      : 8;
+} lsm6dso_fifo_ctrl1_t;
+
+#define LSM6DSO_FIFO_CTRL2                   0x08U
+typedef struct {
+  uint8_t wtm                      : 1;
+  uint8_t uncoptr_rate             : 2;
+  uint8_t not_used_01              : 1;
+  uint8_t odrchg_en                : 1;
+  uint8_t not_used_02              : 1;
+  uint8_t fifo_compr_rt_en         : 1;
+  uint8_t stop_on_wtm              : 1;
+} lsm6dso_fifo_ctrl2_t;
+
+#define LSM6DSO_FIFO_CTRL3                   0x09U
+typedef struct {
+  uint8_t bdr_xl                   : 4;
+  uint8_t bdr_gy                   : 4;
+} lsm6dso_fifo_ctrl3_t;
+
+#define LSM6DSO_FIFO_CTRL4                   0x0AU
+typedef struct {
+  uint8_t fifo_mode                : 3;
+  uint8_t not_used_01              : 1;
+  uint8_t odr_t_batch              : 2;
+  uint8_t odr_ts_batch             : 2;
+} lsm6dso_fifo_ctrl4_t;
+
+#define LSM6DSO_COUNTER_BDR_REG1             0x0BU
+typedef struct {
+  uint8_t cnt_bdr_th               : 3;
+  uint8_t not_used_01              : 2;
+  uint8_t trig_counter_bdr         : 1;
+  uint8_t rst_counter_bdr          : 1;
+  uint8_t dataready_pulsed         : 1;
+} lsm6dso_counter_bdr_reg1_t;
+
+#define LSM6DSO_COUNTER_BDR_REG2             0x0CU
+typedef struct {
+  uint8_t cnt_bdr_th               : 8;
+} lsm6dso_counter_bdr_reg2_t;
+
+#define LSM6DSO_INT1_CTRL  0x0D
+typedef struct {
+  uint8_t int1_drdy_xl             : 1;
+  uint8_t int1_drdy_g              : 1;
+  uint8_t int1_boot                : 1;
+  uint8_t int1_fifo_th             : 1;
+  uint8_t int1_fifo_ovr            : 1;
+  uint8_t int1_fifo_full           : 1;
+  uint8_t int1_cnt_bdr             : 1;
+  uint8_t den_drdy_flag            : 1;
+} lsm6dso_int1_ctrl_t;
+
+#define LSM6DSO_INT2_CTRL                    0x0EU
+typedef struct {
+  uint8_t int2_drdy_xl             : 1;
+  uint8_t int2_drdy_g              : 1;
+  uint8_t int2_drdy_temp           : 1;
+  uint8_t int2_fifo_th             : 1;
+  uint8_t int2_fifo_ovr            : 1;
+  uint8_t int2_fifo_full           : 1;
+  uint8_t int2_cnt_bdr             : 1;
+  uint8_t not_used_01              : 1;
+} lsm6dso_int2_ctrl_t;
+
+#define LSM6DSO_WHO_AM_I                     0x0FU
+#define LSM6DSO_CTRL1_XL                     0x10U
+typedef struct {
+  uint8_t not_used_01              : 1;
+  uint8_t lpf2_xl_en               : 1;
+  uint8_t fs_xl                    : 2;
+  uint8_t odr_xl                   : 4;
+} lsm6dso_ctrl1_xl_t;
+
+#define LSM6DSO_CTRL2_G                      0x11U
+typedef struct {
+  uint8_t not_used_01              : 1;
+  uint8_t fs_g                     : 3; /* fs_125 + fs_g */
+  uint8_t odr_g                    : 4;
+} lsm6dso_ctrl2_g_t;
+
+#define LSM6DSO_CTRL3_C                      0x12U
+typedef struct {
+  uint8_t sw_reset                 : 1;
+  uint8_t not_used_01              : 1;
+  uint8_t if_inc                   : 1;
+  uint8_t sim                      : 1;
+  uint8_t pp_od                    : 1;
+  uint8_t h_lactive                : 1;
+  uint8_t bdu                      : 1;
+  uint8_t boot                     : 1;
+} lsm6dso_ctrl3_c_t;
+
+#define LSM6DSO_CTRL4_C                      0x13U
+typedef struct {
+  uint8_t not_used_01              : 1;
+  uint8_t lpf1_sel_g               : 1;
+  uint8_t i2c_disable              : 1;
+  uint8_t drdy_mask                : 1;
+  uint8_t not_used_02              : 1;
+  uint8_t int2_on_int1             : 1;
+  uint8_t sleep_g                  : 1;
+  uint8_t not_used_03              : 1;
+} lsm6dso_ctrl4_c_t;
+
+#define LSM6DSO_CTRL5_C                      0x14U
+typedef struct {
+  uint8_t st_xl                    : 2;
+  uint8_t st_g                     : 2;
+  uint8_t not_used_01              : 1;
+  uint8_t rounding                 : 2;
+  uint8_t xl_ulp_en                : 1;
+} lsm6dso_ctrl5_c_t;
+
+#define LSM6DSO_CTRL6_C                      0x15U
+typedef struct {
+  uint8_t ftype                    : 3;
+  uint8_t usr_off_w                : 1;
+  uint8_t xl_hm_mode               : 1;
+  uint8_t den_mode                 : 3;   /* trig_en + lvl1_en + lvl2_en */
+} lsm6dso_ctrl6_c_t;
+
+#define LSM6DSO_CTRL7_G                      0x16U
+typedef struct {
+  uint8_t ois_on                   : 1;
+  uint8_t usr_off_on_out           : 1;
+  uint8_t ois_on_en                : 1;
+  uint8_t not_used_01              : 1;
+  uint8_t hpm_g                    : 2;
+  uint8_t hp_en_g                  : 1;
+  uint8_t g_hm_mode                : 1;
+} lsm6dso_ctrl7_g_t;
+
+#define LSM6DSO_CTRL8_XL                     0x17U
+typedef struct {
+  uint8_t low_pass_on_6d           : 1;
+  uint8_t xl_fs_mode               : 1;
+  uint8_t hp_slope_xl_en           : 1;
+  uint8_t fastsettl_mode_xl        : 1;
+  uint8_t hp_ref_mode_xl           : 1;
+  uint8_t hpcf_xl                  : 3;
+} lsm6dso_ctrl8_xl_t;
+
+#define LSM6DSO_CTRL9_XL                     0x18U
+typedef struct {
+  uint8_t not_used_01              : 1;
+  uint8_t i3c_disable              : 1;
+  uint8_t den_lh                   : 1;
+  uint8_t den_xl_g                 : 2;   /* den_xl_en + den_xl_g */
+  uint8_t den_z                    : 1;
+  uint8_t den_y                    : 1;
+  uint8_t den_x                    : 1;
+} lsm6dso_ctrl9_xl_t;
+
+#define LSM6DSO_CTRL10_C                     0x19U
+typedef struct {
+  uint8_t not_used_01              : 5;
+  uint8_t timestamp_en             : 1;
+  uint8_t not_used_02              : 2;
+} lsm6dso_ctrl10_c_t;
+
+#define LSM6DSO_ALL_INT_SRC                  0x1AU
+typedef struct {
+  uint8_t ff_ia                    : 1;
+  uint8_t wu_ia                    : 1;
+  uint8_t single_tap               : 1;
+  uint8_t double_tap               : 1;
+  uint8_t d6d_ia                   : 1;
+  uint8_t sleep_change_ia          : 1;
+  uint8_t not_used_01              : 1;
+  uint8_t timestamp_endcount       : 1;
+} lsm6dso_all_int_src_t;
+
+#define LSM6DSO_WAKE_UP_SRC                  0x1BU
+typedef struct {
+  uint8_t z_wu                     : 1;
+  uint8_t y_wu                     : 1;
+  uint8_t x_wu                     : 1;
+  uint8_t wu_ia                    : 1;
+  uint8_t sleep_state              : 1;
+  uint8_t ff_ia                    : 1;
+  uint8_t sleep_change_ia          : 1;
+  uint8_t not_used_01              : 1;
+} lsm6dso_wake_up_src_t;
+
+#define LSM6DSO_TAP_SRC                      0x1CU
+typedef struct {
+  uint8_t z_tap                    : 1;
+  uint8_t y_tap                    : 1;
+  uint8_t x_tap                    : 1;
+  uint8_t tap_sign                 : 1;
+  uint8_t double_tap               : 1;
+  uint8_t single_tap               : 1;
+  uint8_t tap_ia                   : 1;
+  uint8_t not_used_02              : 1;
+} lsm6dso_tap_src_t;
+
+#define LSM6DSO_D6D_SRC                      0x1DU
+typedef struct {
+  uint8_t xl                       : 1;
+  uint8_t xh                       : 1;
+  uint8_t yl                       : 1;
+  uint8_t yh                       : 1;
+  uint8_t zl                       : 1;
+  uint8_t zh                       : 1;
+  uint8_t d6d_ia                   : 1;
+  uint8_t den_drdy                 : 1;
+} lsm6dso_d6d_src_t;
+
+#define LSM6DSO_STATUS_REG                   0x1EU
+typedef struct {
+  uint8_t xlda                     : 1;
+  uint8_t gda                      : 1;
+  uint8_t tda                      : 1;
+  uint8_t not_used_01              : 5;
+} lsm6dso_status_reg_t;
+
+#define LSM6DSO_STATUS_SPIAUX                0x1EU
+typedef struct {
+  uint8_t xlda                     : 1;
+  uint8_t gda                      : 1;
+  uint8_t gyro_settling            : 1;
+  uint8_t not_used_01              : 5;
+} lsm6dso_status_spiaux_t;
+
+#define LSM6DSO_OUT_TEMP_L                   0x20U
+#define LSM6DSO_OUT_TEMP_H                   0x21U
+#define LSM6DSO_OUTX_L_G                     0x22U
+#define LSM6DSO_OUTX_H_G                     0x23U
+#define LSM6DSO_OUTY_L_G                     0x24U
+#define LSM6DSO_OUTY_H_G                     0x25U
+#define LSM6DSO_OUTZ_L_G                     0x26U
+#define LSM6DSO_OUTZ_H_G                     0x27U
+#define LSM6DSO_OUTX_L_A                     0x28U
+#define LSM6DSO_OUTX_H_A                     0x29U
+#define LSM6DSO_OUTY_L_A                     0x2AU
+#define LSM6DSO_OUTY_H_A                     0x2BU
+#define LSM6DSO_OUTZ_L_A                     0x2CU
+#define LSM6DSO_OUTZ_H_A                     0x2DU
+#define LSM6DSO_EMB_FUNC_STATUS_MAINPAGE     0x35U
+typedef struct {
+  uint8_t not_used_01             : 3;
+  uint8_t is_step_det             : 1;
+  uint8_t is_tilt                 : 1;
+  uint8_t is_sigmot               : 1;
+  uint8_t not_used_02             : 1;
+  uint8_t is_fsm_lc               : 1;
+} lsm6dso_emb_func_status_mainpage_t;
+
+#define LSM6DSO_FSM_STATUS_A_MAINPAGE        0x36U
+typedef struct {
+  uint8_t is_fsm1                 : 1;
+  uint8_t is_fsm2                 : 1;
+  uint8_t is_fsm3                 : 1;
+  uint8_t is_fsm4                 : 1;
+  uint8_t is_fsm5                 : 1;
+  uint8_t is_fsm6                 : 1;
+  uint8_t is_fsm7                 : 1;
+  uint8_t is_fsm8                 : 1;
+  } lsm6dso_fsm_status_a_mainpage_t;
+
+#define LSM6DSO_FSM_STATUS_B_MAINPAGE        0x37U
+typedef struct {
+  uint8_t IS_FSM9                 : 1;
+  uint8_t IS_FSM10                : 1;
+  uint8_t IS_FSM11                : 1;
+  uint8_t IS_FSM12                : 1;
+  uint8_t IS_FSM13                : 1;
+  uint8_t IS_FSM14                : 1;
+  uint8_t IS_FSM15                : 1;
+  uint8_t IS_FSM16                : 1;
+} lsm6dso_fsm_status_b_mainpage_t;
+
+#define LSM6DSO_STATUS_MASTER_MAINPAGE       0x39U
+typedef struct {
+  uint8_t sens_hub_endop          : 1;
+  uint8_t not_used_01             : 2;
+  uint8_t slave0_nack             : 1;
+  uint8_t slave1_nack             : 1;
+  uint8_t slave2_nack             : 1;
+  uint8_t slave3_nack             : 1;
+  uint8_t wr_once_done            : 1;
+} lsm6dso_status_master_mainpage_t;
+
+#define LSM6DSO_FIFO_STATUS1                 0x3AU
+typedef struct {
+  uint8_t diff_fifo                : 8;
+} lsm6dso_fifo_status1_t;
+
+#define LSM6DSO_FIFO_STATUS2                 0x3B
+typedef struct {
+  uint8_t diff_fifo                : 2;
+  uint8_t not_used_01              : 1;
+  uint8_t over_run_latched         : 1;
+  uint8_t counter_bdr_ia           : 1;
+  uint8_t fifo_full_ia             : 1;
+  uint8_t fifo_ovr_ia              : 1;
+  uint8_t fifo_wtm_ia              : 1;
+} lsm6dso_fifo_status2_t;
+
+#define LSM6DSO_TIMESTAMP0                   0x40U
+#define LSM6DSO_TIMESTAMP1                   0x41U
+#define LSM6DSO_TIMESTAMP2                   0x42U
+#define LSM6DSO_TIMESTAMP3                   0x43U
+#define LSM6DSO_TAP_CFG0                     0x56U
+typedef struct {
+  uint8_t lir                      : 1;
+  uint8_t tap_z_en                 : 1;
+  uint8_t tap_y_en                 : 1;
+  uint8_t tap_x_en                 : 1;
+  uint8_t slope_fds                : 1;
+  uint8_t sleep_status_on_int      : 1;
+  uint8_t int_clr_on_read          : 1;
+  uint8_t not_used_01              : 1;
+} lsm6dso_tap_cfg0_t;
+
+#define LSM6DSO_TAP_CFG1                     0x57U
+typedef struct {
+  uint8_t tap_ths_x                : 5;
+  uint8_t tap_priority             : 3;
+} lsm6dso_tap_cfg1_t;
+
+#define LSM6DSO_TAP_CFG2                     0x58U
+typedef struct {
+  uint8_t tap_ths_y                : 5;
+  uint8_t inact_en                 : 2;
+  uint8_t interrupts_enable        : 1;
+} lsm6dso_tap_cfg2_t;
+
+#define LSM6DSO_TAP_THS_6D                   0x59U
+typedef struct {
+  uint8_t tap_ths_z                : 5;
+  uint8_t sixd_ths                 : 2;
+  uint8_t d4d_en                   : 1;
+} lsm6dso_tap_ths_6d_t;
+
+#define LSM6DSO_INT_DUR2                     0x5AU
+typedef struct {
+  uint8_t shock                    : 2;
+  uint8_t quiet                    : 2;
+  uint8_t dur                      : 4;
+} lsm6dso_int_dur2_t;
+
+#define LSM6DSO_WAKE_UP_THS                  0x5BU
+typedef struct {
+  uint8_t wk_ths                   : 6;
+  uint8_t usr_off_on_wu            : 1;
+  uint8_t single_double_tap        : 1;
+} lsm6dso_wake_up_ths_t;
+
+#define LSM6DSO_WAKE_UP_DUR                  0x5CU
+typedef struct {
+  uint8_t sleep_dur                : 4;
+  uint8_t wake_ths_w               : 1;
+  uint8_t wake_dur                 : 2;
+  uint8_t ff_dur                   : 1;
+} lsm6dso_wake_up_dur_t;
+
+#define LSM6DSO_FREE_FALL                    0x5DU
+typedef struct {
+  uint8_t ff_ths                   : 3;
+  uint8_t ff_dur                   : 5;
+} lsm6dso_free_fall_t;
+
+#define LSM6DSO_MD1_CFG                      0x5EU
+typedef struct {
+  uint8_t int1_shub                : 1;
+  uint8_t int1_emb_func            : 1;
+  uint8_t int1_6d                  : 1;
+  uint8_t int1_double_tap          : 1;
+  uint8_t int1_ff                  : 1;
+  uint8_t int1_wu                  : 1;
+  uint8_t int1_single_tap          : 1;
+  uint8_t int1_sleep_change        : 1;
+} lsm6dso_md1_cfg_t;
+
+#define LSM6DSO_MD2_CFG                      0x5FU
+typedef struct {
+  uint8_t int2_timestamp           : 1;
+  uint8_t int2_emb_func            : 1;
+  uint8_t int2_6d                  : 1;
+  uint8_t int2_double_tap          : 1;
+  uint8_t int2_ff                  : 1;
+  uint8_t int2_wu                  : 1;
+  uint8_t int2_single_tap          : 1;
+  uint8_t int2_sleep_change        : 1;
+} lsm6dso_md2_cfg_t;
+
+#define LSM6DSO_I3C_BUS_AVB                  0x62U
+typedef struct {
+  uint8_t pd_dis_int1              : 1;
+  uint8_t not_used_01              : 2;
+  uint8_t i3c_bus_avb_sel          : 2;
+  uint8_t not_used_02              : 3;
+} lsm6dso_i3c_bus_avb_t;
+
+#define LSM6DSO_INTERNAL_FREQ_FINE           0x63U
+typedef struct {
+  uint8_t freq_fine                : 8;
+} lsm6dso_internal_freq_fine_t;
+
+#define LSM6DSO_INT_OIS                      0x6FU
+typedef struct {
+  uint8_t st_xl_ois                : 2;
+  uint8_t not_used_01              : 3;
+  uint8_t den_lh_ois               : 1;
+  uint8_t lvl2_ois                 : 1;
+  uint8_t int2_drdy_ois            : 1;
+} lsm6dso_int_ois_t;
+
+#define LSM6DSO_CTRL1_OIS                    0x70U
+typedef struct {
+  uint8_t ois_en_spi2              : 1;
+  uint8_t fs_g_ois                 : 3; /* fs_125_ois + fs[1:0]_g_ois */
+  uint8_t mode4_en                 : 1;
+  uint8_t sim_ois                  : 1;
+  uint8_t lvl1_ois                  : 1;
+  uint8_t not_used_01              : 1;
+} lsm6dso_ctrl1_ois_t;
+
+#define LSM6DSO_CTRL2_OIS                    0x71U
+typedef struct {
+  uint8_t hp_en_ois                : 1;
+  uint8_t ftype_ois                : 2;
+  uint8_t not_used_01              : 1;
+  uint8_t hpm_ois                  : 2;
+  uint8_t not_used_02              : 2;
+} lsm6dso_ctrl2_ois_t;
+
+#define LSM6DSO_CTRL3_OIS                    0x72U
+typedef struct {
+  uint8_t st_ois_clampdis          : 1;
+  uint8_t st_ois                   : 2;
+  uint8_t filter_xl_conf_ois       : 3;
+  uint8_t fs_xl_ois                : 2;
+} lsm6dso_ctrl3_ois_t;
+
+#define LSM6DSO_X_OFS_USR                    0x73U
+#define LSM6DSO_Y_OFS_USR                    0x74U
+#define LSM6DSO_Z_OFS_USR                    0x75U
+#define LSM6DSO_FIFO_DATA_OUT_TAG            0x78U
+typedef struct {
+  uint8_t tag_parity               : 1;
+  uint8_t tag_cnt                  : 2;
+  uint8_t tag_sensor               : 5;
+} lsm6dso_fifo_data_out_tag_t;
+
+#define LSM6DSO_FIFO_DATA_OUT_X_L            0x79U
+#define LSM6DSO_FIFO_DATA_OUT_X_H            0x7AU
+#define LSM6DSO_FIFO_DATA_OUT_Y_L            0x7BU
+#define LSM6DSO_FIFO_DATA_OUT_Y_H            0x7CU
+#define LSM6DSO_FIFO_DATA_OUT_Z_L            0x7DU
+#define LSM6DSO_FIFO_DATA_OUT_Z_H            0x7EU
+#define LSM6DSO_PAGE_SEL                     0x02U
+typedef struct {
+  uint8_t not_used_01              : 4;
+  uint8_t page_sel                 : 4;
+} lsm6dso_page_sel_t;
+
+#define LSM6DSO_EMB_FUNC_EN_A                0x04U
+typedef struct {
+  uint8_t not_used_01              : 3;
+  uint8_t pedo_en                  : 1;
+  uint8_t tilt_en                  : 1;
+  uint8_t sign_motion_en           : 1;
+  uint8_t not_used_02              : 2;
+} lsm6dso_emb_func_en_a_t;
+
+#define LSM6DSO_EMB_FUNC_EN_B                0x05U
+typedef struct {
+  uint8_t fsm_en                   : 1;
+  uint8_t not_used_01              : 2;
+  uint8_t fifo_compr_en            : 1;
+  uint8_t pedo_adv_en              : 1;
+  uint8_t not_used_02              : 3;
+} lsm6dso_emb_func_en_b_t;
+
+#define LSM6DSO_PAGE_ADDRESS                 0x08U
+typedef struct {
+  uint8_t page_addr                : 8;
+} lsm6dso_page_address_t;
+
+#define LSM6DSO_PAGE_VALUE                   0x09U
+typedef struct {
+  uint8_t page_value               : 8;
+} lsm6dso_page_value_t;
+
+#define LSM6DSO_EMB_FUNC_INT1                0x0AU
+typedef struct {
+  uint8_t not_used_01              : 3;
+  uint8_t int1_step_detector       : 1;
+  uint8_t int1_tilt                : 1;
+  uint8_t int1_sig_mot             : 1;
+  uint8_t not_used_02              : 1;
+  uint8_t int1_fsm_lc              : 1;
+} lsm6dso_emb_func_int1_t;
+
+#define LSM6DSO_FSM_INT1_A                   0x0BU
+typedef struct {
+  uint8_t int1_fsm1                : 1;
+  uint8_t int1_fsm2                : 1;
+  uint8_t int1_fsm3                : 1;
+  uint8_t int1_fsm4                : 1;
+  uint8_t int1_fsm5                : 1;
+  uint8_t int1_fsm6                : 1;
+  uint8_t int1_fsm7                : 1;
+  uint8_t int1_fsm8                : 1;
+} lsm6dso_fsm_int1_a_t;
+
+#define LSM6DSO_FSM_INT1_B                   0x0CU
+typedef struct {
+  uint8_t int1_fsm9                : 1;
+  uint8_t int1_fsm10               : 1;
+  uint8_t int1_fsm11               : 1;
+  uint8_t int1_fsm12               : 1;
+  uint8_t int1_fsm13               : 1;
+  uint8_t int1_fsm14               : 1;
+  uint8_t int1_fsm15               : 1;
+  uint8_t int1_fsm16               : 1;
+} lsm6dso_fsm_int1_b_t;
+
+#define LSM6DSO_EMB_FUNC_INT2                0x0EU
+typedef struct {
+  uint8_t not_used_01              : 3;
+  uint8_t int2_step_detector       : 1;
+  uint8_t int2_tilt                : 1;
+  uint8_t int2_sig_mot             : 1;
+  uint8_t not_used_02              : 1;
+  uint8_t int2_fsm_lc              : 1;
+} lsm6dso_emb_func_int2_t;
+
+#define LSM6DSO_FSM_INT2_A                   0x0FU
+typedef struct {
+  uint8_t int2_fsm1                : 1;
+  uint8_t int2_fsm2                : 1;
+  uint8_t int2_fsm3                : 1;
+  uint8_t int2_fsm4                : 1;
+  uint8_t int2_fsm5                : 1;
+  uint8_t int2_fsm6                : 1;
+  uint8_t int2_fsm7                : 1;
+  uint8_t int2_fsm8                : 1;
+} lsm6dso_fsm_int2_a_t;
+
+#define LSM6DSO_FSM_INT2_B                   0x10U
+typedef struct {
+  uint8_t int2_fsm9                : 1;
+  uint8_t int2_fsm10               : 1;
+  uint8_t int2_fsm11               : 1;
+  uint8_t int2_fsm12               : 1;
+  uint8_t int2_fsm13               : 1;
+  uint8_t int2_fsm14               : 1;
+  uint8_t int2_fsm15               : 1;
+  uint8_t int2_fsm16               : 1;
+} lsm6dso_fsm_int2_b_t;
+
+#define LSM6DSO_EMB_FUNC_STATUS              0x12U
+typedef struct {
+  uint8_t not_used_01              : 3;
+  uint8_t is_step_det              : 1;
+  uint8_t is_tilt                  : 1;
+  uint8_t is_sigmot                : 1;
+  uint8_t not_used_02              : 1;
+  uint8_t is_fsm_lc                : 1;
+} lsm6dso_emb_func_status_t;
+
+#define LSM6DSO_FSM_STATUS_A                 0x13U
+typedef struct {
+  uint8_t is_fsm1                  : 1;
+  uint8_t is_fsm2                  : 1;
+  uint8_t is_fsm3                  : 1;
+  uint8_t is_fsm4                  : 1;
+  uint8_t is_fsm5                  : 1;
+  uint8_t is_fsm6                  : 1;
+  uint8_t is_fsm7                  : 1;
+  uint8_t is_fsm8                  : 1;
+} lsm6dso_fsm_status_a_t;
+
+#define LSM6DSO_FSM_STATUS_B                 0x14U
+typedef struct {
+  uint8_t is_fsm9                  : 1;
+  uint8_t is_fsm10                 : 1;
+  uint8_t is_fsm11                 : 1;
+  uint8_t is_fsm12                 : 1;
+  uint8_t is_fsm13                 : 1;
+  uint8_t is_fsm14                 : 1;
+  uint8_t is_fsm15                 : 1;
+  uint8_t is_fsm16                 : 1;
+} lsm6dso_fsm_status_b_t;
+
+#define LSM6DSO_PAGE_RW                      0x17U
+typedef struct {
+  uint8_t not_used_01              : 5;
+  uint8_t page_rw                  : 2;  /* page_write + page_read */
+  uint8_t emb_func_lir             : 1;
+} lsm6dso_page_rw_t;
+
+#define LSM6DSO_EMB_FUNC_FIFO_CFG                  0x44U
+typedef struct {
+  uint8_t not_used_00              : 6;
+  uint8_t pedo_fifo_en             : 1;
+  uint8_t not_used_01              : 1;
+} lsm6dso_emb_func_fifo_cfg_t;
+
+#define LSM6DSO_FSM_ENABLE_A                 0x46U
+typedef struct {
+  uint8_t fsm1_en                  : 1;
+  uint8_t fsm2_en                  : 1;
+  uint8_t fsm3_en                  : 1;
+  uint8_t fsm4_en                  : 1;
+  uint8_t fsm5_en                  : 1;
+  uint8_t fsm6_en                  : 1;
+  uint8_t fsm7_en                  : 1;
+  uint8_t fsm8_en                  : 1;
+} lsm6dso_fsm_enable_a_t;
+
+#define LSM6DSO_FSM_ENABLE_B                 0x47U
+typedef struct {
+  uint8_t fsm9_en                  : 1;
+  uint8_t fsm10_en                 : 1;
+  uint8_t fsm11_en                 : 1;
+  uint8_t fsm12_en                 : 1;
+  uint8_t fsm13_en                 : 1;
+  uint8_t fsm14_en                 : 1;
+  uint8_t fsm15_en                 : 1;
+  uint8_t fsm16_en                 : 1;
+} lsm6dso_fsm_enable_b_t;
+
+#define LSM6DSO_FSM_LONG_COUNTER_L           0x48U
+#define LSM6DSO_FSM_LONG_COUNTER_H           0x49U
+#define LSM6DSO_FSM_LONG_COUNTER_CLEAR       0x4AU
+typedef struct {
+  uint8_t fsm_lc_clr               : 2;  /* fsm_lc_cleared + fsm_lc_clear */
+  uint8_t not_used_01              : 6;
+} lsm6dso_fsm_long_counter_clear_t;
+
+#define LSM6DSO_FSM_OUTS1                    0x4CU
+typedef struct {
+  uint8_t n_v                      : 1;
+  uint8_t p_v                      : 1;
+  uint8_t n_z                      : 1;
+  uint8_t p_z                      : 1;
+  uint8_t n_y                      : 1;
+  uint8_t p_y                      : 1;
+  uint8_t n_x                      : 1;
+  uint8_t p_x                      : 1;
+} lsm6dso_fsm_outs1_t;
+
+#define LSM6DSO_FSM_OUTS2                    0x4DU
+typedef struct {
+  uint8_t n_v                      : 1;
+  uint8_t p_v                      : 1;
+  uint8_t n_z                      : 1;
+  uint8_t p_z                      : 1;
+  uint8_t n_y                      : 1;
+  uint8_t p_y                      : 1;
+  uint8_t n_x                      : 1;
+  uint8_t p_x                      : 1;
+} lsm6dso_fsm_outs2_t;
+
+#define LSM6DSO_FSM_OUTS3                    0x4EU
+typedef struct {
+  uint8_t n_v                      : 1;
+  uint8_t p_v                      : 1;
+  uint8_t n_z                      : 1;
+  uint8_t p_z                      : 1;
+  uint8_t n_y                      : 1;
+  uint8_t p_y                      : 1;
+  uint8_t n_x                      : 1;
+  uint8_t p_x                      : 1;
+} lsm6dso_fsm_outs3_t;
+
+#define LSM6DSO_FSM_OUTS4                    0x4FU
+typedef struct {
+  uint8_t n_v                      : 1;
+  uint8_t p_v                      : 1;
+  uint8_t n_z                      : 1;
+  uint8_t p_z                      : 1;
+  uint8_t n_y                      : 1;
+  uint8_t p_y                      : 1;
+  uint8_t n_x                      : 1;
+  uint8_t p_x                      : 1;
+} lsm6dso_fsm_outs4_t;
+
+#define LSM6DSO_FSM_OUTS5                    0x50U
+typedef struct {
+  uint8_t n_v                      : 1;
+  uint8_t p_v                      : 1;
+  uint8_t n_z                      : 1;
+  uint8_t p_z                      : 1;
+  uint8_t n_y                      : 1;
+  uint8_t p_y                      : 1;
+  uint8_t n_x                      : 1;
+  uint8_t p_x                      : 1;
+} lsm6dso_fsm_outs5_t;
+
+#define LSM6DSO_FSM_OUTS6                    0x51U
+typedef struct {
+  uint8_t n_v                      : 1;
+  uint8_t p_v                      : 1;
+  uint8_t n_z                      : 1;
+  uint8_t p_z                      : 1;
+  uint8_t n_y                      : 1;
+  uint8_t p_y                      : 1;
+  uint8_t n_x                      : 1;
+  uint8_t p_x                      : 1;
+} lsm6dso_fsm_outs6_t;
+
+#define LSM6DSO_FSM_OUTS7                    0x52U
+typedef struct {
+  uint8_t n_v                      : 1;
+  uint8_t p_v                      : 1;
+  uint8_t n_z                      : 1;
+  uint8_t p_z                      : 1;
+  uint8_t n_y                      : 1;
+  uint8_t p_y                      : 1;
+  uint8_t n_x                      : 1;
+  uint8_t p_x                      : 1;
+} lsm6dso_fsm_outs7_t;
+
+#define LSM6DSO_FSM_OUTS8                    0x53U
+typedef struct {
+  uint8_t n_v                      : 1;
+  uint8_t p_v                      : 1;
+  uint8_t n_z                      : 1;
+  uint8_t p_z                      : 1;
+  uint8_t n_y                      : 1;
+  uint8_t p_y                      : 1;
+  uint8_t n_x                      : 1;
+  uint8_t p_x                      : 1;
+} lsm6dso_fsm_outs8_t;
+
+#define LSM6DSO_FSM_OUTS9                    0x54U
+typedef struct {
+  uint8_t n_v                      : 1;
+  uint8_t p_v                      : 1;
+  uint8_t n_z                      : 1;
+  uint8_t p_z                      : 1;
+  uint8_t n_y                      : 1;
+  uint8_t p_y                      : 1;
+  uint8_t n_x                      : 1;
+  uint8_t p_x                      : 1;
+} lsm6dso_fsm_outs9_t;
+
+#define LSM6DSO_FSM_OUTS10                   0x55U
+typedef struct {
+  uint8_t n_v                      : 1;
+  uint8_t p_v                      : 1;
+  uint8_t n_z                      : 1;
+  uint8_t p_z                      : 1;
+  uint8_t n_y                      : 1;
+  uint8_t p_y                      : 1;
+  uint8_t n_x                      : 1;
+  uint8_t p_x                      : 1;
+} lsm6dso_fsm_outs10_t;
+
+#define LSM6DSO_FSM_OUTS11                   0x56U
+typedef struct {
+  uint8_t n_v                      : 1;
+  uint8_t p_v                      : 1;
+  uint8_t n_z                      : 1;
+  uint8_t p_z                      : 1;
+  uint8_t n_y                      : 1;
+  uint8_t p_y                      : 1;
+  uint8_t n_x                      : 1;
+  uint8_t p_x                      : 1;
+} lsm6dso_fsm_outs11_t;
+
+#define LSM6DSO_FSM_OUTS12                   0x57U
+typedef struct {
+  uint8_t n_v                      : 1;
+  uint8_t p_v                      : 1;
+  uint8_t n_z                      : 1;
+  uint8_t p_z                      : 1;
+  uint8_t n_y                      : 1;
+  uint8_t p_y                      : 1;
+  uint8_t n_x                      : 1;
+  uint8_t p_x                      : 1;
+} lsm6dso_fsm_outs12_t;
+
+#define LSM6DSO_FSM_OUTS13                   0x58U
+typedef struct {
+  uint8_t n_v                      : 1;
+  uint8_t p_v                      : 1;
+  uint8_t n_z                      : 1;
+  uint8_t p_z                      : 1;
+  uint8_t n_y                      : 1;
+  uint8_t p_y                      : 1;
+  uint8_t n_x                      : 1;
+  uint8_t p_x                      : 1;
+} lsm6dso_fsm_outs13_t;
+
+#define LSM6DSO_FSM_OUTS14                   0x59U
+typedef struct {
+  uint8_t n_v                      : 1;
+  uint8_t p_v                      : 1;
+  uint8_t n_z                      : 1;
+  uint8_t p_z                      : 1;
+  uint8_t n_y                      : 1;
+  uint8_t p_y                      : 1;
+  uint8_t n_x                      : 1;
+  uint8_t p_x                      : 1;
+} lsm6dso_fsm_outs14_t;
+
+#define LSM6DSO_FSM_OUTS15                   0x5AU
+typedef struct {
+  uint8_t n_v                      : 1;
+  uint8_t p_v                      : 1;
+  uint8_t n_z                      : 1;
+  uint8_t p_z                      : 1;
+  uint8_t n_y                      : 1;
+  uint8_t p_y                      : 1;
+  uint8_t n_x                      : 1;
+  uint8_t p_x                      : 1;
+} lsm6dso_fsm_outs15_t;
+
+#define LSM6DSO_FSM_OUTS16                   0x5BU
+typedef struct {
+  uint8_t n_v                      : 1;
+  uint8_t p_v                      : 1;
+  uint8_t n_z                      : 1;
+  uint8_t p_z                      : 1;
+  uint8_t n_y                      : 1;
+  uint8_t p_y                      : 1;
+  uint8_t n_x                      : 1;
+  uint8_t p_x                      : 1;
+} lsm6dso_fsm_outs16_t;
+
+#define LSM6DSO_EMB_FUNC_ODR_CFG_B           0x5FU
+typedef struct {
+  uint8_t not_used_01              : 3;
+  uint8_t fsm_odr                  : 3;
+  uint8_t not_used_02              : 2;
+} lsm6dso_emb_func_odr_cfg_b_t;
+
+#define LSM6DSO_STEP_COUNTER_L               0x62U
+#define LSM6DSO_STEP_COUNTER_H               0x63U
+#define LSM6DSO_EMB_FUNC_SRC                 0x64U
+typedef struct {
+  uint8_t not_used_01              : 2;
+  uint8_t stepcounter_bit_set      : 1;
+  uint8_t step_overflow            : 1;
+  uint8_t step_count_delta_ia      : 1;
+  uint8_t step_detected            : 1;
+  uint8_t not_used_02              : 1;
+  uint8_t pedo_rst_step            : 1;
+} lsm6dso_emb_func_src_t;
+
+#define LSM6DSO_EMB_FUNC_INIT_A              0x66U
+typedef struct {
+  uint8_t not_used_01               : 3;
+  uint8_t step_det_init             : 1;
+  uint8_t tilt_init                 : 1;
+  uint8_t sig_mot_init              : 1;
+  uint8_t not_used_02               : 2;
+} lsm6dso_emb_func_init_a_t;
+
+#define LSM6DSO_EMB_FUNC_INIT_B              0x67U
+typedef struct {
+  uint8_t fsm_init                 : 1;
+  uint8_t not_used_01              : 2;
+  uint8_t fifo_compr_init          : 1;
+  uint8_t not_used_02              : 4;
+} lsm6dso_emb_func_init_b_t;
+
+#define LSM6DSO_MAG_SENSITIVITY_L            0xBAU
+#define LSM6DSO_MAG_SENSITIVITY_H            0xBBU
+#define LSM6DSO_MAG_OFFX_L                   0xC0U
+#define LSM6DSO_MAG_OFFX_H                   0xC1U
+#define LSM6DSO_MAG_OFFY_L                   0xC2U
+#define LSM6DSO_MAG_OFFY_H                   0xC3U
+#define LSM6DSO_MAG_OFFZ_L                   0xC4U
+#define LSM6DSO_MAG_OFFZ_H                   0xC5U
+#define LSM6DSO_MAG_SI_XX_L                  0xC6U
+#define LSM6DSO_MAG_SI_XX_H                  0xC7U
+#define LSM6DSO_MAG_SI_XY_L                  0xC8U
+#define LSM6DSO_MAG_SI_XY_H                  0xC9U
+#define LSM6DSO_MAG_SI_XZ_L                  0xCAU
+#define LSM6DSO_MAG_SI_XZ_H                  0xCBU
+#define LSM6DSO_MAG_SI_YY_L                  0xCCU
+#define LSM6DSO_MAG_SI_YY_H                  0xCDU
+#define LSM6DSO_MAG_SI_YZ_L                  0xCEU
+#define LSM6DSO_MAG_SI_YZ_H                  0xCFU
+#define LSM6DSO_MAG_SI_ZZ_L                  0xD0U
+#define LSM6DSO_MAG_SI_ZZ_H                  0xD1U
+#define LSM6DSO_MAG_CFG_A                    0xD4U
+typedef struct {
+  uint8_t mag_z_axis               : 3;
+  uint8_t not_used_01              : 1;
+  uint8_t mag_y_axis               : 3;
+  uint8_t not_used_02              : 1;
+} lsm6dso_mag_cfg_a_t;
+
+#define LSM6DSO_MAG_CFG_B                    0xD5U
+typedef struct {
+  uint8_t mag_x_axis               : 3;
+  uint8_t not_used_01              : 5;
+} lsm6dso_mag_cfg_b_t;
+
+#define LSM6DSO_FSM_LC_TIMEOUT_L             0x17AU
+#define LSM6DSO_FSM_LC_TIMEOUT_H             0x17BU
+#define LSM6DSO_FSM_PROGRAMS                 0x17CU
+#define LSM6DSO_FSM_START_ADD_L              0x17EU
+#define LSM6DSO_FSM_START_ADD_H              0x17FU
+#define LSM6DSO_PEDO_CMD_REG                 0x183U
+typedef struct {
+  uint8_t ad_det_en                : 1;
+  uint8_t not_used_01              : 1;
+  uint8_t fp_rejection_en          : 1;
+  uint8_t carry_count_en           : 1;
+  uint8_t not_used_02              : 4;
+} lsm6dso_pedo_cmd_reg_t;
+
+#define LSM6DSO_PEDO_DEB_STEPS_CONF          0x184U
+#define LSM6DSO_PEDO_SC_DELTAT_L             0x1D0U
+#define LSM6DSO_PEDO_SC_DELTAT_H             0x1D1U
+#define LSM6DSO_SENSOR_HUB_1                 0x02U
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_1_t;
+
+#define LSM6DSO_SENSOR_HUB_2                 0x03U
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_2_t;
+
+#define LSM6DSO_SENSOR_HUB_3                 0x04U
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_3_t;
+
+#define LSM6DSO_SENSOR_HUB_4                 0x05U
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_4_t;
+
+#define LSM6DSO_SENSOR_HUB_5                 0x06U
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_5_t;
+
+#define LSM6DSO_SENSOR_HUB_6                 0x07U
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_6_t;
+
+#define LSM6DSO_SENSOR_HUB_7                 0x08U
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_7_t;
+
+#define LSM6DSO_SENSOR_HUB_8                 0x09U
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_8_t;
+
+#define LSM6DSO_SENSOR_HUB_9                 0x0AU
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_9_t;
+
+#define LSM6DSO_SENSOR_HUB_10                0x0BU
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_10_t;
+
+#define LSM6DSO_SENSOR_HUB_11                0x0CU
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_11_t;
+
+#define LSM6DSO_SENSOR_HUB_12                0x0DU
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_12_t;
+
+#define LSM6DSO_SENSOR_HUB_13                0x0EU
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_13_t;
+
+#define LSM6DSO_SENSOR_HUB_14                0x0FU
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_14_t;
+
+#define LSM6DSO_SENSOR_HUB_15                0x10U
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_15_t;
+
+#define LSM6DSO_SENSOR_HUB_16                0x11U
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_16_t;
+
+#define LSM6DSO_SENSOR_HUB_17                0x12U
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_17_t;
+
+#define LSM6DSO_SENSOR_HUB_18                0x13U
+typedef struct {
+   uint8_t bit0                    : 1;
+   uint8_t bit1                    : 1;
+   uint8_t bit2                    : 1;
+   uint8_t bit3                    : 1;
+   uint8_t bit4                    : 1;
+   uint8_t bit5                    : 1;
+   uint8_t bit6                    : 1;
+   uint8_t bit7                    : 1;
+} lsm6dso_sensor_hub_18_t;
+
+#define LSM6DSO_MASTER_CONFIG                0x14U
+typedef struct {
+  uint8_t aux_sens_on              : 2;
+  uint8_t master_on                : 1;
+  uint8_t shub_pu_en               : 1;
+  uint8_t pass_through_mode        : 1;
+  uint8_t start_config             : 1;
+  uint8_t write_once               : 1;
+  uint8_t rst_master_regs          : 1;
+} lsm6dso_master_config_t;
+
+#define LSM6DSO_SLV0_ADD                     0x15U
+typedef struct {
+  uint8_t rw_0                     : 1;
+  uint8_t slave0                   : 7;
+} lsm6dso_slv0_add_t;
+
+#define LSM6DSO_SLV0_SUBADD                  0x16U
+typedef struct {
+  uint8_t slave0_reg               : 8;
+} lsm6dso_slv0_subadd_t;
+
+#define LSM6DSO_SLV0_CONFIG                  0x17U
+typedef struct {
+  uint8_t slave0_numop             : 3;
+  uint8_t batch_ext_sens_0_en      : 1;
+  uint8_t not_used_01              : 2;
+  uint8_t shub_odr                 : 2;
+} lsm6dso_slv0_config_t;
+
+#define LSM6DSO_SLV1_ADD                     0x18U
+typedef struct {
+  uint8_t r_1                      : 1;
+  uint8_t slave1_add               : 7;
+} lsm6dso_slv1_add_t;
+
+#define LSM6DSO_SLV1_SUBADD                  0x19U
+typedef struct {
+  uint8_t slave1_reg               : 8;
+} lsm6dso_slv1_subadd_t;
+
+#define LSM6DSO_SLV1_CONFIG                  0x1AU
+typedef struct {
+  uint8_t slave1_numop             : 3;
+  uint8_t batch_ext_sens_1_en      : 1;
+  uint8_t not_used_01              : 4;
+} lsm6dso_slv1_config_t;
+
+#define LSM6DSO_SLV2_ADD                     0x1BU
+typedef struct {
+  uint8_t r_2                      : 1;
+  uint8_t slave2_add               : 7;
+} lsm6dso_slv2_add_t;
+
+#define LSM6DSO_SLV2_SUBADD                  0x1CU
+typedef struct {
+  uint8_t slave2_reg               : 8;
+} lsm6dso_slv2_subadd_t;
+
+#define LSM6DSO_SLV2_CONFIG                  0x1DU
+typedef struct {
+  uint8_t slave2_numop             : 3;
+  uint8_t batch_ext_sens_2_en      : 1;
+  uint8_t not_used_01              : 4;
+} lsm6dso_slv2_config_t;
+
+#define LSM6DSO_SLV3_ADD                     0x1EU
+typedef struct {
+  uint8_t r_3                      : 1;
+  uint8_t slave3_add               : 7;
+} lsm6dso_slv3_add_t;
+
+#define LSM6DSO_SLV3_SUBADD                  0x1FU
+typedef struct {
+  uint8_t slave3_reg               : 8;
+} lsm6dso_slv3_subadd_t;
+
+#define LSM6DSO_SLV3_CONFIG                  0x20U
+typedef struct {
+  uint8_t slave3_numop             : 3;
+  uint8_t  batch_ext_sens_3_en     : 1;
+  uint8_t not_used_01              : 4;
+} lsm6dso_slv3_config_t;
+
+#define LSM6DSO_DATAWRITE_SLV0               0x21U
+typedef struct {
+  uint8_t slave0_dataw             : 8;
+} lsm6dso_datawrite_src_mode_sub_slv0_t;
+
+#define LSM6DSO_STATUS_MASTER                0x22U
+typedef struct {
+  uint8_t sens_hub_endop           : 1;
+  uint8_t not_used_01              : 2;
+  uint8_t slave0_nack              : 1;
+  uint8_t slave1_nack              : 1;
+  uint8_t slave2_nack              : 1;
+  uint8_t slave3_nack              : 1;
+  uint8_t wr_once_done             : 1;
+} lsm6dso_status_master_t;
+
+/**
+  * @defgroup LSM6DSO_Register_Union
+  * @brief    This union group all the registers that has a bitfield
+  *           description.
+  *           This union is useful but not need by the driver.
+  *
+  *           REMOVING this union you are compliant with:
+  *           MISRA-C 2012 [Rule 19.2] -> " Union are not allowed "
+  *
+  * @{
+  *
+  */
+typedef union{
+  lsm6dso_func_cfg_access_t               func_cfg_access;
+  lsm6dso_pin_ctrl_t                      pin_ctrl;
+  lsm6dso_fifo_ctrl1_t                    fifo_ctrl1;
+  lsm6dso_fifo_ctrl2_t                    fifo_ctrl2;
+  lsm6dso_fifo_ctrl3_t                    fifo_ctrl3;
+  lsm6dso_fifo_ctrl4_t                    fifo_ctrl4;
+  lsm6dso_counter_bdr_reg1_t              counter_bdr_reg1;
+  lsm6dso_counter_bdr_reg2_t              counter_bdr_reg2;
+  lsm6dso_int1_ctrl_t                     int1_ctrl;
+  lsm6dso_int2_ctrl_t                     int2_ctrl;
+  lsm6dso_ctrl1_xl_t                      ctrl1_xl;
+  lsm6dso_ctrl2_g_t                       ctrl2_g;
+  lsm6dso_ctrl3_c_t                       ctrl3_c;
+  lsm6dso_ctrl4_c_t                       ctrl4_c;
+  lsm6dso_ctrl5_c_t                       ctrl5_c;
+  lsm6dso_ctrl6_c_t                       ctrl6_c;
+  lsm6dso_ctrl7_g_t                       ctrl7_g;
+  lsm6dso_ctrl8_xl_t                      ctrl8_xl;
+  lsm6dso_ctrl9_xl_t                      ctrl9_xl;
+  lsm6dso_ctrl10_c_t                      ctrl10_c;
+  lsm6dso_all_int_src_t                   all_int_src;
+  lsm6dso_wake_up_src_t                   wake_up_src;
+  lsm6dso_tap_src_t                       tap_src;
+  lsm6dso_d6d_src_t                       d6d_src;
+  lsm6dso_status_reg_t                    status_reg;
+  lsm6dso_status_spiaux_t                 status_spiaux;
+  lsm6dso_fifo_status1_t                  fifo_status1;
+  lsm6dso_fifo_status2_t                  fifo_status2;
+  lsm6dso_tap_cfg0_t                      tap_cfg0;
+  lsm6dso_tap_cfg1_t                      tap_cfg1;
+  lsm6dso_tap_cfg2_t                      tap_cfg2;
+  lsm6dso_tap_ths_6d_t                    tap_ths_6d;
+  lsm6dso_int_dur2_t                      int_dur2;
+  lsm6dso_wake_up_ths_t                   wake_up_ths;
+  lsm6dso_wake_up_dur_t                   wake_up_dur;
+  lsm6dso_free_fall_t                     free_fall;
+  lsm6dso_md1_cfg_t                       md1_cfg;
+  lsm6dso_md2_cfg_t                       md2_cfg;
+  lsm6dso_i3c_bus_avb_t                   i3c_bus_avb;
+  lsm6dso_internal_freq_fine_t            internal_freq_fine;
+  lsm6dso_int_ois_t                       int_ois;
+  lsm6dso_ctrl1_ois_t                     ctrl1_ois;
+  lsm6dso_ctrl2_ois_t                     ctrl2_ois;
+  lsm6dso_ctrl3_ois_t                     ctrl3_ois;
+  lsm6dso_fifo_data_out_tag_t             fifo_data_out_tag;
+  lsm6dso_page_sel_t                      page_sel;
+  lsm6dso_emb_func_en_a_t                 emb_func_en_a;
+  lsm6dso_emb_func_en_b_t                 emb_func_en_b;
+  lsm6dso_page_address_t                  page_address;
+  lsm6dso_page_value_t                    page_value;
+  lsm6dso_emb_func_int1_t                 emb_func_int1;
+  lsm6dso_fsm_int1_a_t                    fsm_int1_a;
+  lsm6dso_fsm_int1_b_t                    fsm_int1_b;
+  lsm6dso_emb_func_int2_t                 emb_func_int2;
+  lsm6dso_fsm_int2_a_t                    fsm_int2_a;
+  lsm6dso_fsm_int2_b_t                    fsm_int2_b;
+  lsm6dso_emb_func_status_t               emb_func_status;
+  lsm6dso_fsm_status_a_t                  fsm_status_a;
+  lsm6dso_fsm_status_b_t                  fsm_status_b;
+  lsm6dso_page_rw_t                       page_rw;
+  lsm6dso_emb_func_fifo_cfg_t               emb_func_fifo_cfg;
+  lsm6dso_fsm_enable_a_t                  fsm_enable_a;
+  lsm6dso_fsm_enable_b_t                  fsm_enable_b;
+  lsm6dso_fsm_long_counter_clear_t        fsm_long_counter_clear;
+  lsm6dso_fsm_outs1_t                     fsm_outs1;
+  lsm6dso_fsm_outs2_t                     fsm_outs2;
+  lsm6dso_fsm_outs3_t                     fsm_outs3;
+  lsm6dso_fsm_outs4_t                     fsm_outs4;
+  lsm6dso_fsm_outs5_t                     fsm_outs5;
+  lsm6dso_fsm_outs6_t                     fsm_outs6;
+  lsm6dso_fsm_outs7_t                     fsm_outs7;
+  lsm6dso_fsm_outs8_t                     fsm_outs8;
+  lsm6dso_fsm_outs9_t                     fsm_outs9;
+  lsm6dso_fsm_outs10_t                    fsm_outs10;
+  lsm6dso_fsm_outs11_t                    fsm_outs11;
+  lsm6dso_fsm_outs12_t                    fsm_outs12;
+  lsm6dso_fsm_outs13_t                    fsm_outs13;
+  lsm6dso_fsm_outs14_t                    fsm_outs14;
+  lsm6dso_fsm_outs15_t                    fsm_outs15;
+  lsm6dso_fsm_outs16_t                    fsm_outs16;
+  lsm6dso_emb_func_odr_cfg_b_t            emb_func_odr_cfg_b;
+  lsm6dso_emb_func_src_t                  emb_func_src;
+  lsm6dso_emb_func_init_a_t               emb_func_init_a;
+  lsm6dso_emb_func_init_b_t               emb_func_init_b;
+  lsm6dso_mag_cfg_a_t                     mag_cfg_a;
+  lsm6dso_mag_cfg_b_t                     mag_cfg_b;
+  lsm6dso_pedo_cmd_reg_t                  pedo_cmd_reg;
+  lsm6dso_sensor_hub_1_t                  sensor_hub_1;
+  lsm6dso_sensor_hub_2_t                  sensor_hub_2;
+  lsm6dso_sensor_hub_3_t                  sensor_hub_3;
+  lsm6dso_sensor_hub_4_t                  sensor_hub_4;
+  lsm6dso_sensor_hub_5_t                  sensor_hub_5;
+  lsm6dso_sensor_hub_6_t                  sensor_hub_6;
+  lsm6dso_sensor_hub_7_t                  sensor_hub_7;
+  lsm6dso_sensor_hub_8_t                  sensor_hub_8;
+  lsm6dso_sensor_hub_9_t                  sensor_hub_9;
+  lsm6dso_sensor_hub_10_t                 sensor_hub_10;
+  lsm6dso_sensor_hub_11_t                 sensor_hub_11;
+  lsm6dso_sensor_hub_12_t                 sensor_hub_12;
+  lsm6dso_sensor_hub_13_t                 sensor_hub_13;
+  lsm6dso_sensor_hub_14_t                 sensor_hub_14;
+  lsm6dso_sensor_hub_15_t                 sensor_hub_15;
+  lsm6dso_sensor_hub_16_t                 sensor_hub_16;
+  lsm6dso_sensor_hub_17_t                 sensor_hub_17;
+  lsm6dso_sensor_hub_18_t                 sensor_hub_18;
+  lsm6dso_master_config_t                 master_config;
+  lsm6dso_slv0_add_t                      slv0_add;
+  lsm6dso_slv0_subadd_t                   slv0_subadd;
+  lsm6dso_slv0_config_t                   slv0_config;
+  lsm6dso_slv1_add_t                      slv1_add;
+  lsm6dso_slv1_subadd_t                   slv1_subadd;
+  lsm6dso_slv1_config_t                   slv1_config;
+  lsm6dso_slv2_add_t                      slv2_add;
+  lsm6dso_slv2_subadd_t                   slv2_subadd;
+  lsm6dso_slv2_config_t                   slv2_config;
+  lsm6dso_slv3_add_t                      slv3_add;
+  lsm6dso_slv3_subadd_t                   slv3_subadd;
+  lsm6dso_slv3_config_t                   slv3_config;
+  lsm6dso_datawrite_src_mode_sub_slv0_t   datawrite_src_mode_sub_slv0;
+  lsm6dso_status_master_t                 status_master;
+  bitwise_t                               bitwise;
+  uint8_t                                 byte;
+} lsm6dso_reg_t;
+
+/**
+  * @}
+  *
+  */
+
+int32_t lsm6dso_read_reg(lsm6dso_ctx_t *ctx, uint8_t reg, uint8_t* data,
+                         uint16_t len);
+int32_t lsm6dso_write_reg(lsm6dso_ctx_t *ctx, uint8_t reg, uint8_t* data,
+                          uint16_t len);
+
+extern float lsm6dso_from_fs2_to_mg(int16_t lsb);
+extern float lsm6dso_from_fs4_to_mg(int16_t lsb);
+extern float lsm6dso_from_fs8_to_mg(int16_t lsb);
+extern float lsm6dso_from_fs16_to_mg(int16_t lsb);
+extern float lsm6dso_from_fs125_to_mdps(int16_t lsb);
+extern float lsm6dso_from_fs500_to_mdps(int16_t lsb);
+extern float lsm6dso_from_fs250_to_mdps(int16_t lsb);
+extern float lsm6dso_from_fs1000_to_mdps(int16_t lsb);
+extern float lsm6dso_from_fs2000_to_mdps(int16_t lsb);
+extern float lsm6dso_from_lsb_to_celsius(int16_t lsb);
+extern float lsm6dso_from_lsb_to_nsec(int16_t lsb);
+
+typedef enum {
+  LSM6DSO_2g   = 0,
+  LSM6DSO_16g  = 1, /* if XL_FS_MODE = ‘1’ -> LSM6DSO_2g */
+  LSM6DSO_4g   = 2,
+  LSM6DSO_8g   = 3,
+} lsm6dso_fs_xl_t;
+int32_t lsm6dso_xl_full_scale_set(lsm6dso_ctx_t *ctx, lsm6dso_fs_xl_t val);
+int32_t lsm6dso_xl_full_scale_get(lsm6dso_ctx_t *ctx, lsm6dso_fs_xl_t *val);
+
+typedef enum {
+  LSM6DSO_XL_ODR_OFF    = 0,
+  LSM6DSO_XL_ODR_12Hz5  = 1,
+  LSM6DSO_XL_ODR_26Hz   = 2,
+  LSM6DSO_XL_ODR_52Hz   = 3,
+  LSM6DSO_XL_ODR_104Hz  = 4,
+  LSM6DSO_XL_ODR_208Hz  = 5,
+  LSM6DSO_XL_ODR_417Hz  = 6,
+  LSM6DSO_XL_ODR_833Hz  = 7,
+  LSM6DSO_XL_ODR_1667Hz = 8,
+  LSM6DSO_XL_ODR_3333Hz = 9,
+  LSM6DSO_XL_ODR_6667Hz = 10,
+  LSM6DSO_XL_ODR_6Hz5   = 11, /* (low power only) */
+} lsm6dso_odr_xl_t;
+int32_t lsm6dso_xl_data_rate_set(lsm6dso_ctx_t *ctx, lsm6dso_odr_xl_t val);
+int32_t lsm6dso_xl_data_rate_get(lsm6dso_ctx_t *ctx, lsm6dso_odr_xl_t *val);
+
+typedef enum {
+  LSM6DSO_250dps   = 0,
+  LSM6DSO_125dps   = 1,
+  LSM6DSO_500dps   = 2,
+  LSM6DSO_1000dps  = 4,
+  LSM6DSO_2000dps  = 6,
+} lsm6dso_fs_g_t;
+int32_t lsm6dso_gy_full_scale_set(lsm6dso_ctx_t *ctx, lsm6dso_fs_g_t val);
+int32_t lsm6dso_gy_full_scale_get(lsm6dso_ctx_t *ctx, lsm6dso_fs_g_t *val);
+
+typedef enum {
+  LSM6DSO_GY_ODR_OFF    = 0,
+  LSM6DSO_GY_ODR_12Hz5  = 1,
+  LSM6DSO_GY_ODR_26Hz   = 2,
+  LSM6DSO_GY_ODR_52Hz   = 3,
+  LSM6DSO_GY_ODR_104Hz  = 4,
+  LSM6DSO_GY_ODR_208Hz  = 5,
+  LSM6DSO_GY_ODR_417Hz  = 6,
+  LSM6DSO_GY_ODR_833Hz  = 7,
+  LSM6DSO_GY_ODR_1667Hz = 8,
+  LSM6DSO_GY_ODR_3333Hz = 9,
+  LSM6DSO_GY_ODR_6667Hz = 10,
+} lsm6dso_odr_g_t;
+int32_t lsm6dso_gy_data_rate_set(lsm6dso_ctx_t *ctx, lsm6dso_odr_g_t val);
+int32_t lsm6dso_gy_data_rate_get(lsm6dso_ctx_t *ctx, lsm6dso_odr_g_t *val);
+
+int32_t lsm6dso_block_data_update_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_block_data_update_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_LSb_1mg  = 0,
+  LSM6DSO_LSb_16mg = 1,
+} lsm6dso_usr_off_w_t;
+int32_t lsm6dso_xl_offset_weight_set(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_usr_off_w_t val);
+int32_t lsm6dso_xl_offset_weight_get(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_usr_off_w_t *val);
+
+typedef enum {
+  LSM6DSO_HIGH_PERFORMANCE_MD  = 0,
+  LSM6DSO_LOW_NORMAL_POWER_MD  = 1,
+  LSM6DSO_ULTRA_LOW_POWER_MD   = 2,
+} lsm6dso_xl_hm_mode_t;
+int32_t lsm6dso_xl_power_mode_set(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_xl_hm_mode_t val);
+int32_t lsm6dso_xl_power_mode_get(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_xl_hm_mode_t *val);
+
+typedef enum {
+  LSM6DSO_GY_HIGH_PERFORMANCE  = 0,
+  LSM6DSO_GY_NORMAL            = 1,
+} lsm6dso_g_hm_mode_t;
+int32_t lsm6dso_gy_power_mode_set(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_g_hm_mode_t val);
+int32_t lsm6dso_gy_power_mode_get(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_g_hm_mode_t *val);
+
+typedef struct {
+  lsm6dso_all_int_src_t       all_int_src;
+  lsm6dso_wake_up_src_t       wake_up_src;
+  lsm6dso_tap_src_t           tap_src;
+  lsm6dso_d6d_src_t           d6d_src;
+  lsm6dso_status_reg_t        status_reg;
+  lsm6dso_emb_func_status_t   emb_func_status;
+  lsm6dso_fsm_status_a_t      fsm_status_a;
+  lsm6dso_fsm_status_b_t      fsm_status_b;
+} lsm6dso_all_sources_t;
+int32_t lsm6dso_all_sources_get(lsm6dso_ctx_t *ctx,
+                                lsm6dso_all_sources_t *val);
+
+int32_t lsm6dso_status_reg_get(lsm6dso_ctx_t *ctx,
+                               lsm6dso_status_reg_t *val);
+
+int32_t lsm6dso_xl_flag_data_ready_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_gy_flag_data_ready_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_temp_flag_data_ready_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_xl_usr_offset_x_set(lsm6dso_ctx_t *ctx, uint8_t *buff);
+int32_t lsm6dso_xl_usr_offset_x_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+int32_t lsm6dso_xl_usr_offset_y_set(lsm6dso_ctx_t *ctx, uint8_t *buff);
+int32_t lsm6dso_xl_usr_offset_y_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+int32_t lsm6dso_xl_usr_offset_z_set(lsm6dso_ctx_t *ctx, uint8_t *buff);
+int32_t lsm6dso_xl_usr_offset_z_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+int32_t lsm6dso_xl_usr_offset_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_xl_usr_offset_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_timestamp_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_timestamp_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_timestamp_raw_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+typedef enum {
+  LSM6DSO_NO_ROUND      = 0,
+  LSM6DSO_ROUND_XL      = 1,
+  LSM6DSO_ROUND_GY      = 2,
+  LSM6DSO_ROUND_GY_XL   = 3,
+} lsm6dso_rounding_t;
+int32_t lsm6dso_rounding_mode_set(lsm6dso_ctx_t *ctx,
+                                    lsm6dso_rounding_t val);
+int32_t lsm6dso_rounding_mode_get(lsm6dso_ctx_t *ctx,
+                                    lsm6dso_rounding_t *val);
+
+int32_t lsm6dso_temperature_raw_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+int32_t lsm6dso_angular_rate_raw_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+int32_t lsm6dso_acceleration_raw_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+int32_t lsm6dso_fifo_out_raw_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+int32_t lsm6dso_number_of_steps_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+int32_t lsm6dso_steps_reset(lsm6dso_ctx_t *ctx);
+
+int32_t lsm6dso_odr_cal_reg_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_odr_cal_reg_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_USER_BANK           = 0,
+  LSM6DSO_SENSOR_HUB_BANK     = 1,
+  LSM6DSO_EMBEDDED_FUNC_BANK  = 2,
+} lsm6dso_reg_access_t;
+int32_t lsm6dso_mem_bank_set(lsm6dso_ctx_t *ctx, lsm6dso_reg_access_t val);
+int32_t lsm6dso_mem_bank_get(lsm6dso_ctx_t *ctx, lsm6dso_reg_access_t *val);
+
+int32_t lsm6dso_ln_pg_write_byte(lsm6dso_ctx_t *ctx, uint16_t address,
+                                 uint8_t *val);
+int32_t lsm6dso_ln_pg_read_byte(lsm6dso_ctx_t *ctx, uint16_t address,
+                                uint8_t *val);
+int32_t lsm6dso_ln_pg_write(lsm6dso_ctx_t *ctx, uint16_t address,
+                            uint8_t *buf, uint8_t len);
+int32_t lsm6dso_ln_pg_read(lsm6dso_ctx_t *ctx, uint16_t address,
+                           uint8_t *val);
+
+typedef enum {
+  LSM6DSO_DRDY_LATCHED = 0,
+  LSM6DSO_DRDY_PULSED  = 1,
+} lsm6dso_dataready_pulsed_t;
+int32_t lsm6dso_data_ready_mode_set(lsm6dso_ctx_t *ctx,
+                                    lsm6dso_dataready_pulsed_t val);
+int32_t lsm6dso_data_ready_mode_get(lsm6dso_ctx_t *ctx,
+                                    lsm6dso_dataready_pulsed_t *val);
+
+int32_t lsm6dso_device_id_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+int32_t lsm6dso_reset_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_reset_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_auto_increment_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_auto_increment_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_boot_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_boot_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_XL_ST_DISABLE  = 0,
+  LSM6DSO_XL_ST_POSITIVE = 1,
+  LSM6DSO_XL_ST_NEGATIVE = 2,
+} lsm6dso_st_xl_t;
+int32_t lsm6dso_xl_self_test_set(lsm6dso_ctx_t *ctx, lsm6dso_st_xl_t val);
+int32_t lsm6dso_xl_self_test_get(lsm6dso_ctx_t *ctx, lsm6dso_st_xl_t *val);
+
+typedef enum {
+  LSM6DSO_GY_ST_DISABLE  = 0,
+  LSM6DSO_GY_ST_POSITIVE = 1,
+  LSM6DSO_GY_ST_NEGATIVE = 3,
+} lsm6dso_st_g_t;
+int32_t lsm6dso_gy_self_test_set(lsm6dso_ctx_t *ctx, lsm6dso_st_g_t val);
+int32_t lsm6dso_gy_self_test_get(lsm6dso_ctx_t *ctx, lsm6dso_st_g_t *val);
+
+int32_t lsm6dso_xl_filter_lp2_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_xl_filter_lp2_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_gy_filter_lp1_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_gy_filter_lp1_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_filter_settling_mask_set(lsm6dso_ctx_t *ctx,
+                                         uint8_t val);
+int32_t lsm6dso_filter_settling_mask_get(lsm6dso_ctx_t *ctx,
+                                         uint8_t *val);
+
+typedef enum {
+  LSM6DSO_ULTRA_LIGHT  = 0,
+  LSM6DSO_VERY_LIGHT   = 1,
+  LSM6DSO_LIGHT        = 2,
+  LSM6DSO_MEDIUM       = 3,
+  LSM6DSO_STRONG       = 4,
+  LSM6DSO_VERY_STRONG  = 5,
+  LSM6DSO_AGGRESSIVE   = 6,
+  LSM6DSO_XTREME       = 7,
+} lsm6dso_ftype_t;
+int32_t lsm6dso_gy_lp1_bandwidth_set(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_ftype_t val);
+int32_t lsm6dso_gy_lp1_bandwidth_get(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_ftype_t *val);
+
+int32_t lsm6dso_xl_lp2_on_6d_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_xl_lp2_on_6d_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_HP_PATH_DISABLE_ON_OUT    = 0x00,
+  LSM6DSO_SLOPE_ODR_DIV_4           = 0x10,
+  LSM6DSO_HP_ODR_DIV_10             = 0x11,
+  LSM6DSO_HP_ODR_DIV_20             = 0x12,
+  LSM6DSO_HP_ODR_DIV_45             = 0x13,
+  LSM6DSO_HP_ODR_DIV_100            = 0x14,
+  LSM6DSO_HP_ODR_DIV_200            = 0x15,
+  LSM6DSO_HP_ODR_DIV_400            = 0x16,
+  LSM6DSO_HP_ODR_DIV_800            = 0x17,
+  LSM6DSO_HP_REF_MD_ODR_DIV_10      = 0x31,
+  LSM6DSO_HP_REF_MD_ODR_DIV_20      = 0x32,
+  LSM6DSO_HP_REF_MD_ODR_DIV_45      = 0x33,
+  LSM6DSO_HP_REF_MD_ODR_DIV_100     = 0x34,
+  LSM6DSO_HP_REF_MD_ODR_DIV_200     = 0x35,
+  LSM6DSO_HP_REF_MD_ODR_DIV_400     = 0x36,
+  LSM6DSO_HP_REF_MD_ODR_DIV_800     = 0x37,
+  LSM6DSO_LP_ODR_DIV_10             = 0x01,
+  LSM6DSO_LP_ODR_DIV_20             = 0x02,
+  LSM6DSO_LP_ODR_DIV_45             = 0x03,
+  LSM6DSO_LP_ODR_DIV_100            = 0x04,
+  LSM6DSO_LP_ODR_DIV_200            = 0x05,
+  LSM6DSO_LP_ODR_DIV_400            = 0x06,
+  LSM6DSO_LP_ODR_DIV_800            = 0x07,
+} lsm6dso_hp_slope_xl_en_t;
+int32_t lsm6dso_xl_hp_path_on_out_set(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_hp_slope_xl_en_t val);
+int32_t lsm6dso_xl_hp_path_on_out_get(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_hp_slope_xl_en_t *val);
+
+int32_t lsm6dso_xl_fast_settling_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_xl_fast_settling_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_USE_SLOPE = 0,
+  LSM6DSO_USE_HPF   = 1,
+} lsm6dso_slope_fds_t;
+int32_t lsm6dso_xl_hp_path_internal_set(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_slope_fds_t val);
+int32_t lsm6dso_xl_hp_path_internal_get(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_slope_fds_t *val);
+
+typedef enum {
+  LSM6DSO_HP_FILTER_NONE     = 0x00,
+  LSM6DSO_HP_FILTER_16mHz    = 0x80,
+  LSM6DSO_HP_FILTER_65mHz    = 0x81,
+  LSM6DSO_HP_FILTER_260mHz   = 0x82,
+  LSM6DSO_HP_FILTER_1Hz04    = 0x83,
+} lsm6dso_hpm_g_t;
+int32_t lsm6dso_gy_hp_path_internal_set(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_hpm_g_t val);
+int32_t lsm6dso_gy_hp_path_internal_get(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_hpm_g_t *val);
+
+typedef enum {
+  LSM6DSO_AUX_PULL_UP_DISC       = 0,
+  LSM6DSO_AUX_PULL_UP_CONNECT    = 1,
+} lsm6dso_ois_pu_dis_t;
+int32_t lsm6dso_aux_sdo_ocs_mode_set(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_ois_pu_dis_t val);
+int32_t lsm6dso_aux_sdo_ocs_mode_get(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_ois_pu_dis_t *val);
+
+typedef enum {
+  LSM6DSO_AUX_ON                    = 1,
+  LSM6DSO_AUX_ON_BY_AUX_INTERFACE   = 0,
+} lsm6dso_ois_on_t;
+int32_t lsm6dso_aux_pw_on_ctrl_set(lsm6dso_ctx_t *ctx, lsm6dso_ois_on_t val);
+int32_t lsm6dso_aux_pw_on_ctrl_get(lsm6dso_ctx_t *ctx, lsm6dso_ois_on_t *val);
+
+typedef enum {
+  LSM6DSO_USE_SAME_XL_FS        = 0,
+  LSM6DSO_USE_DIFFERENT_XL_FS   = 1,
+} lsm6dso_xl_fs_mode_t;
+int32_t lsm6dso_aux_xl_fs_mode_set(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_xl_fs_mode_t val);
+int32_t lsm6dso_aux_xl_fs_mode_get(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_xl_fs_mode_t *val);
+
+int32_t lsm6dso_aux_status_reg_get(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_status_spiaux_t *val);
+
+int32_t lsm6dso_aux_xl_flag_data_ready_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_aux_gy_flag_data_ready_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_aux_gy_flag_settling_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_AUX_XL_DISABLE = 0,
+  LSM6DSO_AUX_XL_POS     = 1,
+  LSM6DSO_AUX_XL_NEG     = 2,
+} lsm6dso_st_xl_ois_t;
+int32_t lsm6dso_aux_xl_self_test_set(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_st_xl_ois_t val);
+int32_t lsm6dso_aux_xl_self_test_get(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_st_xl_ois_t *val);
+
+typedef enum {
+  LSM6DSO_AUX_DEN_ACTIVE_LOW     = 0,
+  LSM6DSO_AUX_DEN_ACTIVE_HIGH    = 1,
+} lsm6dso_den_lh_ois_t;
+int32_t lsm6dso_aux_den_polarity_set(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_den_lh_ois_t val);
+int32_t lsm6dso_aux_den_polarity_get(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_den_lh_ois_t *val);
+
+typedef enum {
+  LSM6DSO_AUX_DEN_DISABLE         = 0,
+  LSM6DSO_AUX_DEN_LEVEL_LATCH     = 3,
+  LSM6DSO_AUX_DEN_LEVEL_TRIG      = 2,
+} lsm6dso_lvl2_ois_t;
+int32_t lsm6dso_aux_den_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_lvl2_ois_t val);
+int32_t lsm6dso_aux_den_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_lvl2_ois_t *val);
+
+int32_t lsm6dso_aux_drdy_on_int2_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_aux_drdy_on_int2_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_AUX_DISABLE  = 0,
+  LSM6DSO_MODE_3_GY    = 1,
+  LSM6DSO_MODE_4_GY_XL = 3,
+} lsm6dso_ois_en_spi2_t;
+int32_t lsm6dso_aux_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_ois_en_spi2_t val);
+int32_t lsm6dso_aux_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_ois_en_spi2_t *val);
+
+typedef enum {
+  LSM6DSO_250dps_AUX  = 0,
+  LSM6DSO_125dps_AUX  = 1,
+  LSM6DSO_500dps_AUX  = 2,
+  LSM6DSO_1000dps_AUX = 4,
+  LSM6DSO_2000dps_AUX = 6,
+} lsm6dso_fs_g_ois_t;
+int32_t lsm6dso_aux_gy_full_scale_set(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_fs_g_ois_t val);
+int32_t lsm6dso_aux_gy_full_scale_get(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_fs_g_ois_t *val);
+
+typedef enum {
+  LSM6DSO_AUX_SPI_4_WIRE = 0,
+  LSM6DSO_AUX_SPI_3_WIRE = 1,
+} lsm6dso_sim_ois_t;
+int32_t lsm6dso_aux_spi_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_sim_ois_t val);
+int32_t lsm6dso_aux_spi_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_sim_ois_t *val);
+
+typedef enum {
+  LSM6DSO_351Hz39 = 0,
+  LSM6DSO_236Hz63 = 1,
+  LSM6DSO_172Hz70 = 2,
+  LSM6DSO_937Hz91 = 3,
+} lsm6dso_ftype_ois_t;
+int32_t lsm6dso_aux_gy_lp1_bandwidth_set(lsm6dso_ctx_t *ctx,
+                                          lsm6dso_ftype_ois_t val);
+int32_t lsm6dso_aux_gy_lp1_bandwidth_get(lsm6dso_ctx_t *ctx,
+                                          lsm6dso_ftype_ois_t *val);
+
+typedef enum {
+  LSM6DSO_AUX_HP_DISABLE = 0x00,
+  LSM6DSO_AUX_HP_Hz016   = 0x10,
+  LSM6DSO_AUX_HP_Hz065   = 0x11,
+  LSM6DSO_AUX_HP_Hz260   = 0x12,
+  LSM6DSO_AUX_HP_1Hz040  = 0x13,
+} lsm6dso_hpm_ois_t;
+int32_t lsm6dso_aux_gy_hp_bandwidth_set(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_hpm_ois_t val);
+int32_t lsm6dso_aux_gy_hp_bandwidth_get(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_hpm_ois_t *val);
+
+typedef enum {
+  LSM6DSO_ENABLE_CLAMP  = 0,
+  LSM6DSO_DISABLE_CLAMP = 1,
+} lsm6dso_st_ois_clampdis_t;
+int32_t lsm6dso_aux_gy_clamp_set(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_st_ois_clampdis_t val);
+int32_t lsm6dso_aux_gy_clamp_get(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_st_ois_clampdis_t *val);
+
+typedef enum {
+  LSM6DSO_AUX_GY_DISABLE = 0,
+  LSM6DSO_AUX_GY_POS     = 1,
+  LSM6DSO_AUX_GY_NEG     = 3,
+} lsm6dso_st_ois_t;
+int32_t lsm6dso_aux_gy_self_test_set(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_st_ois_t val);
+int32_t lsm6dso_aux_gy_self_test_get(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_st_ois_t *val);
+
+typedef enum {
+  LSM6DSO_289Hz = 0,
+  LSM6DSO_258Hz = 1,
+  LSM6DSO_120Hz = 2,
+  LSM6DSO_65Hz2 = 3,
+  LSM6DSO_33Hz2 = 4,
+  LSM6DSO_16Hz6 = 5,
+  LSM6DSO_8Hz30 = 6,
+  LSM6DSO_4Hz15 = 7,
+} lsm6dso_filter_xl_conf_ois_t;
+int32_t lsm6dso_aux_xl_bandwidth_set(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_filter_xl_conf_ois_t val);
+int32_t lsm6dso_aux_xl_bandwidth_get(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_filter_xl_conf_ois_t *val);
+
+typedef enum {
+  LSM6DSO_AUX_2g  = 0,
+  LSM6DSO_AUX_16g = 1,
+  LSM6DSO_AUX_4g  = 2,
+  LSM6DSO_AUX_8g  = 3,
+} lsm6dso_fs_xl_ois_t;
+int32_t lsm6dso_aux_xl_full_scale_set(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_fs_xl_ois_t val);
+int32_t lsm6dso_aux_xl_full_scale_get(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_fs_xl_ois_t *val);
+
+typedef enum {
+  LSM6DSO_PULL_UP_DISC       = 0,
+  LSM6DSO_PULL_UP_CONNECT    = 1,
+} lsm6dso_sdo_pu_en_t;
+int32_t lsm6dso_sdo_sa0_mode_set(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_sdo_pu_en_t val);
+int32_t lsm6dso_sdo_sa0_mode_get(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_sdo_pu_en_t *val);
+
+typedef enum {
+  LSM6DSO_SPI_4_WIRE = 0,
+  LSM6DSO_SPI_3_WIRE = 1,
+} lsm6dso_sim_t;
+int32_t lsm6dso_spi_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_sim_t val);
+int32_t lsm6dso_spi_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_sim_t *val);
+
+typedef enum {
+  LSM6DSO_I2C_ENABLE  = 0,
+  LSM6DSO_I2C_DISABLE = 1,
+} lsm6dso_i2c_disable_t;
+int32_t lsm6dso_i2c_interface_set(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_i2c_disable_t val);
+int32_t lsm6dso_i2c_interface_get(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_i2c_disable_t *val);
+
+typedef enum {
+  LSM6DSO_I3C_DISABLE         = 0x00,
+  LSM6DSO_I3C_ENABLE_T_50us   = 0x80,
+  LSM6DSO_I3C_ENABLE_T_2us    = 0x81,
+  LSM6DSO_I3C_ENABLE_T_1ms    = 0x82,
+  LSM6DSO_I3C_ENABLE_T_25ms   = 0x83,
+} lsm6dso_i3c_disable_t;
+int32_t lsm6dso_i3c_disable_set(lsm6dso_ctx_t *ctx,
+                                lsm6dso_i3c_disable_t val);
+int32_t lsm6dso_i3c_disable_get(lsm6dso_ctx_t *ctx,
+                                lsm6dso_i3c_disable_t *val);
+
+typedef enum {
+  LSM6DSO_PULL_DOWN_DISC       = 0,
+  LSM6DSO_PULL_DOWN_CONNECT    = 1,
+} lsm6dso_int1_pd_en_t;
+int32_t lsm6dso_int1_mode_set(lsm6dso_ctx_t *ctx,
+                              lsm6dso_int1_pd_en_t val);
+int32_t lsm6dso_int1_mode_get(lsm6dso_ctx_t *ctx,
+                              lsm6dso_int1_pd_en_t *val);
+
+typedef struct {
+    lsm6dso_int1_ctrl_t          int1_ctrl;
+    lsm6dso_md1_cfg_t            md1_cfg;
+    lsm6dso_emb_func_int1_t      emb_func_int1;
+    lsm6dso_fsm_int1_a_t         fsm_int1_a;
+    lsm6dso_fsm_int1_b_t         fsm_int1_b;
+} lsm6dso_pin_int1_route_t;
+int32_t lsm6dso_pin_int1_route_set(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_pin_int1_route_t *val);
+int32_t lsm6dso_pin_int1_route_get(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_pin_int1_route_t *val);
+
+typedef struct {
+  lsm6dso_int2_ctrl_t          int2_ctrl;
+  lsm6dso_md2_cfg_t            md2_cfg;
+  lsm6dso_emb_func_int2_t      emb_func_int2;
+  lsm6dso_fsm_int2_a_t         fsm_int2_a;
+  lsm6dso_fsm_int2_b_t         fsm_int2_b;
+} lsm6dso_pin_int2_route_t;
+int32_t lsm6dso_pin_int2_route_set(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_pin_int2_route_t *val);
+int32_t lsm6dso_pin_int2_route_get(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_pin_int2_route_t *val);
+
+typedef enum {
+  LSM6DSO_PUSH_PULL   = 0,
+  LSM6DSO_OPEN_DRAIN  = 1,
+} lsm6dso_pp_od_t;
+int32_t lsm6dso_pin_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_pp_od_t val);
+int32_t lsm6dso_pin_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_pp_od_t *val);
+
+typedef enum {
+  LSM6DSO_ACTIVE_HIGH = 0,
+  LSM6DSO_ACTIVE_LOW  = 1,
+} lsm6dso_h_lactive_t;
+int32_t lsm6dso_pin_polarity_set(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_h_lactive_t val);
+int32_t lsm6dso_pin_polarity_get(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_h_lactive_t *val);
+
+int32_t lsm6dso_all_on_int1_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_all_on_int1_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_ALL_INT_PULSED            = 0,
+  LSM6DSO_BASE_LATCHED_EMB_PULSED   = 1,
+  LSM6DSO_BASE_PULSED_EMB_LATCHED   = 2,
+  LSM6DSO_ALL_INT_LATCHED           = 3,
+} lsm6dso_lir_t;
+int32_t lsm6dso_int_notification_set(lsm6dso_ctx_t *ctx, lsm6dso_lir_t val);
+int32_t lsm6dso_int_notification_get(lsm6dso_ctx_t *ctx, lsm6dso_lir_t *val);
+
+typedef enum {
+  LSM6DSO_LSb_FS_DIV_64       = 0,
+  LSM6DSO_LSb_FS_DIV_256      = 1,
+} lsm6dso_wake_ths_w_t;
+int32_t lsm6dso_wkup_ths_weight_set(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_wake_ths_w_t val);
+int32_t lsm6dso_wkup_ths_weight_get(lsm6dso_ctx_t *ctx,
+                                       lsm6dso_wake_ths_w_t *val);
+
+int32_t lsm6dso_wkup_threshold_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_wkup_threshold_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_xl_usr_offset_on_wkup_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_xl_usr_offset_on_wkup_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_wkup_dur_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_wkup_dur_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_gy_sleep_mode_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_gy_sleep_mode_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_DRIVE_SLEEP_CHG_EVENT = 0,
+  LSM6DSO_DRIVE_SLEEP_STATUS    = 1,
+} lsm6dso_sleep_status_on_int_t;
+int32_t lsm6dso_act_pin_notification_set(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_sleep_status_on_int_t val);
+int32_t lsm6dso_act_pin_notification_get(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_sleep_status_on_int_t *val);
+
+typedef enum {
+  LSM6DSO_XL_AND_GY_NOT_AFFECTED      = 0,
+  LSM6DSO_XL_12Hz5_GY_NOT_AFFECTED    = 1,
+  LSM6DSO_XL_12Hz5_GY_SLEEP           = 2,
+  LSM6DSO_XL_12Hz5_GY_PD              = 3,
+} lsm6dso_inact_en_t;
+int32_t lsm6dso_act_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_inact_en_t val);
+int32_t lsm6dso_act_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_inact_en_t *val);
+
+int32_t lsm6dso_act_sleep_dur_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_act_sleep_dur_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_tap_detection_on_z_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_tap_detection_on_z_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_tap_detection_on_y_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_tap_detection_on_y_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_tap_detection_on_x_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_tap_detection_on_x_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_tap_threshold_x_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_tap_threshold_x_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_XYZ = 0,
+  LSM6DSO_YXZ = 1,
+  LSM6DSO_XZY = 2,
+  LSM6DSO_ZYX = 3,
+  LSM6DSO_YZX = 5,
+  LSM6DSO_ZXY = 6,
+} lsm6dso_tap_priority_t;
+int32_t lsm6dso_tap_axis_priority_set(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_tap_priority_t val);
+int32_t lsm6dso_tap_axis_priority_get(lsm6dso_ctx_t *ctx,
+                                      lsm6dso_tap_priority_t *val);
+
+int32_t lsm6dso_tap_threshold_y_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_tap_threshold_y_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_tap_threshold_z_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_tap_threshold_z_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_tap_shock_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_tap_shock_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_tap_quiet_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_tap_quiet_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_tap_dur_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_tap_dur_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_ONLY_SINGLE = 0,
+  LSM6DSO_BOTH_SINGLE_DOUBLE = 1,
+} lsm6dso_single_double_tap_t;
+int32_t lsm6dso_tap_mode_set(lsm6dso_ctx_t *ctx,
+                             lsm6dso_single_double_tap_t val);
+int32_t lsm6dso_tap_mode_get(lsm6dso_ctx_t *ctx,
+                             lsm6dso_single_double_tap_t *val);
+
+typedef enum {
+  LSM6DSO_DEG_80  = 0,
+  LSM6DSO_DEG_70  = 1,
+  LSM6DSO_DEG_60  = 2,
+  LSM6DSO_DEG_50  = 3,
+} lsm6dso_sixd_ths_t;
+int32_t lsm6dso_6d_threshold_set(lsm6dso_ctx_t *ctx, lsm6dso_sixd_ths_t val);
+int32_t lsm6dso_6d_threshold_get(lsm6dso_ctx_t *ctx, lsm6dso_sixd_ths_t *val);
+
+int32_t lsm6dso_4d_mode_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_4d_mode_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_FF_TSH_156mg = 0,
+  LSM6DSO_FF_TSH_219mg = 1,
+  LSM6DSO_FF_TSH_250mg = 2,
+  LSM6DSO_FF_TSH_312mg = 3,
+  LSM6DSO_FF_TSH_344mg = 4,
+  LSM6DSO_FF_TSH_406mg = 5,
+  LSM6DSO_FF_TSH_469mg = 6,
+  LSM6DSO_FF_TSH_500mg = 7,
+} lsm6dso_ff_ths_t;
+int32_t lsm6dso_ff_threshold_set(lsm6dso_ctx_t *ctx, lsm6dso_ff_ths_t val);
+int32_t lsm6dso_ff_threshold_get(lsm6dso_ctx_t *ctx, lsm6dso_ff_ths_t *val);
+
+int32_t lsm6dso_ff_dur_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_ff_dur_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_fifo_watermark_set(lsm6dso_ctx_t *ctx, uint16_t val);
+int32_t lsm6dso_fifo_watermark_get(lsm6dso_ctx_t *ctx, uint16_t *val);
+
+int32_t lsm6dso_compression_algo_init_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_compression_algo_init_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_CMP_DISABLE  = 0x00,
+  LSM6DSO_CMP_ALWAYS   = 0x04,
+  LSM6DSO_CMP_8_TO_1   = 0x05,
+  LSM6DSO_CMP_16_TO_1  = 0x06,
+  LSM6DSO_CMP_32_TO_1  = 0x07,
+} lsm6dso_uncoptr_rate_t;
+int32_t lsm6dso_compression_algo_set(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_uncoptr_rate_t val);
+int32_t lsm6dso_compression_algo_get(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_uncoptr_rate_t *val);
+
+int32_t lsm6dso_fifo_virtual_sens_odr_chg_set(lsm6dso_ctx_t *ctx,
+                                              uint8_t val);
+int32_t lsm6dso_fifo_virtual_sens_odr_chg_get(lsm6dso_ctx_t *ctx,
+                                              uint8_t *val);
+
+int32_t lsm6dso_compression_algo_real_time_set(lsm6dso_ctx_t *ctx,
+                                               uint8_t val);
+int32_t lsm6dso_compression_algo_real_time_get(lsm6dso_ctx_t *ctx,
+                                               uint8_t *val);
+
+int32_t lsm6dso_fifo_stop_on_wtm_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_fifo_stop_on_wtm_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_XL_NOT_BATCHED        =  0,
+  LSM6DSO_XL_BATCHED_AT_12Hz5   =  1,
+  LSM6DSO_XL_BATCHED_AT_26Hz    =  2,
+  LSM6DSO_XL_BATCHED_AT_52Hz    =  3,
+  LSM6DSO_XL_BATCHED_AT_104Hz   =  4,
+  LSM6DSO_XL_BATCHED_AT_208Hz   =  5,
+  LSM6DSO_XL_BATCHED_AT_417Hz   =  6,
+  LSM6DSO_XL_BATCHED_AT_833Hz   =  7,
+  LSM6DSO_XL_BATCHED_AT_1667Hz  =  8,
+  LSM6DSO_XL_BATCHED_AT_3333Hz  =  9,
+  LSM6DSO_XL_BATCHED_AT_6667Hz  = 10,
+  LSM6DSO_XL_BATCHED_AT_6Hz5    = 11,
+} lsm6dso_bdr_xl_t;
+int32_t lsm6dso_fifo_xl_batch_set(lsm6dso_ctx_t *ctx, lsm6dso_bdr_xl_t val);
+int32_t lsm6dso_fifo_xl_batch_get(lsm6dso_ctx_t *ctx, lsm6dso_bdr_xl_t *val);
+
+typedef enum {
+  LSM6DSO_GY_NOT_BATCHED         = 0,
+  LSM6DSO_GY_BATCHED_AT_12Hz5    = 1,
+  LSM6DSO_GY_BATCHED_AT_26Hz     = 2,
+  LSM6DSO_GY_BATCHED_AT_52Hz     = 3,
+  LSM6DSO_GY_BATCHED_AT_104Hz    = 4,
+  LSM6DSO_GY_BATCHED_AT_208Hz    = 5,
+  LSM6DSO_GY_BATCHED_AT_417Hz    = 6,
+  LSM6DSO_GY_BATCHED_AT_833Hz    = 7,
+  LSM6DSO_GY_BATCHED_AT_1667Hz   = 8,
+  LSM6DSO_GY_BATCHED_AT_3333Hz   = 9,
+  LSM6DSO_GY_BATCHED_AT_6667Hz   = 10,
+  LSM6DSO_GY_BATCHED_AT_6Hz5     = 11,
+} lsm6dso_bdr_gy_t;
+int32_t lsm6dso_fifo_gy_batch_set(lsm6dso_ctx_t *ctx, lsm6dso_bdr_gy_t val);
+int32_t lsm6dso_fifo_gy_batch_get(lsm6dso_ctx_t *ctx, lsm6dso_bdr_gy_t *val);
+
+typedef enum {
+  LSM6DSO_BYPASS_MODE             = 0,
+  LSM6DSO_FIFO_MODE               = 1,
+  LSM6DSO_STREAM_TO_FIFO_MODE     = 3,
+  LSM6DSO_BYPASS_TO_STREAM_MODE   = 4,
+  LSM6DSO_STREAM_MODE             = 6,
+  LSM6DSO_BYPASS_TO_FIFO_MODE     = 7,
+} lsm6dso_fifo_mode_t;
+int32_t lsm6dso_fifo_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_fifo_mode_t val);
+int32_t lsm6dso_fifo_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_fifo_mode_t *val);
+
+typedef enum {
+  LSM6DSO_TEMP_NOT_BATCHED        = 0,
+  LSM6DSO_TEMP_BATCHED_AT_1Hz6    = 1,
+  LSM6DSO_TEMP_BATCHED_AT_12Hz5   = 2,
+  LSM6DSO_TEMP_BATCHED_AT_52Hz    = 3,
+} lsm6dso_odr_t_batch_t;
+int32_t lsm6dso_fifo_temp_batch_set(lsm6dso_ctx_t *ctx,
+                                    lsm6dso_odr_t_batch_t val);
+int32_t lsm6dso_fifo_temp_batch_get(lsm6dso_ctx_t *ctx,
+                                    lsm6dso_odr_t_batch_t *val);
+
+typedef enum {
+  LSM6DSO_NO_DECIMATION = 0,
+  LSM6DSO_DEC_1         = 1,
+  LSM6DSO_DEC_8         = 2,
+  LSM6DSO_DEC_32        = 3,
+} lsm6dso_odr_ts_batch_t;
+int32_t lsm6dso_fifo_timestamp_decimation_set(lsm6dso_ctx_t *ctx,
+                                              lsm6dso_odr_ts_batch_t val);
+int32_t lsm6dso_fifo_timestamp_decimation_get(lsm6dso_ctx_t *ctx,
+                                              lsm6dso_odr_ts_batch_t *val);
+
+typedef enum {
+  LSM6DSO_XL_BATCH_EVENT   = 0,
+  LSM6DSO_GYRO_BATCH_EVENT = 1,
+} lsm6dso_trig_counter_bdr_t;
+
+typedef enum {
+  LSM6DSO_GYRO_NC_TAG       = 1,
+  LSM6DSO_XL_NC_TAG,
+  LSM6DSO_TEMPERATURE_TAG,
+  LSM6DSO_TIMESTAMP_TAG,
+  LSM6DSO_CFG_CHANGE_TAG,
+  LSM6DSO_XL_NC_T_2_TAG,
+  LSM6DSO_XL_NC_T_1_TAG,
+  LSM6DSO_XL_2XC_TAG,
+  LSM6DSO_XL_3XC_TAG,
+  LSM6DSO_GYRO_NC_T_2_TAG,
+  LSM6DSO_GYRO_NC_T_1_TAG,
+  LSM6DSO_GYRO_2XC_TAG,
+  LSM6DSO_GYRO_3XC_TAG,
+  LSM6DSO_SENSORHUB_SLAVE0_TAG,
+  LSM6DSO_SENSORHUB_SLAVE1_TAG,
+  LSM6DSO_SENSORHUB_SLAVE2_TAG,
+  LSM6DSO_SENSORHUB_SLAVE3_TAG,
+  LSM6DSO_STEP_CPUNTER_TAG,
+  LSM6DSO_GAME_ROTATION_TAG,
+  LSM6DSO_GEOMAG_ROTATION_TAG,
+  LSM6DSO_ROTATION_TAG,
+  LSM6DSO_SENSORHUB_NACK_TAG    = 0x19,
+} lsm6dso_fifo_tag_t;
+int32_t lsm6dso_fifo_cnt_event_batch_set(lsm6dso_ctx_t *ctx,
+                                          lsm6dso_trig_counter_bdr_t val);
+int32_t lsm6dso_fifo_cnt_event_batch_get(lsm6dso_ctx_t *ctx,
+                                          lsm6dso_trig_counter_bdr_t *val);
+
+int32_t lsm6dso_rst_batch_counter_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_rst_batch_counter_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_batch_counter_threshold_set(lsm6dso_ctx_t *ctx,
+                                            uint16_t val);
+int32_t lsm6dso_batch_counter_threshold_get(lsm6dso_ctx_t *ctx,
+                                            uint16_t *val);
+
+int32_t lsm6dso_fifo_data_level_get(lsm6dso_ctx_t *ctx, uint16_t *val);
+
+int32_t lsm6dso_fifo_status_get(lsm6dso_ctx_t *ctx,
+                                lsm6dso_fifo_status2_t *val);
+
+int32_t lsm6dso_fifo_full_flag_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_fifo_ovr_flag_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_fifo_wtm_flag_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_fifo_sensor_tag_get(lsm6dso_ctx_t *ctx,
+                    lsm6dso_fifo_tag_t *val);
+
+int32_t lsm6dso_fifo_pedo_batch_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_fifo_pedo_batch_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_sh_batch_slave_0_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_sh_batch_slave_0_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_sh_batch_slave_1_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_sh_batch_slave_1_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_sh_batch_slave_2_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_sh_batch_slave_2_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_sh_batch_slave_3_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_sh_batch_slave_3_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_DEN_DISABLE    = 0,
+  LSM6DSO_LEVEL_FIFO     = 6,
+  LSM6DSO_LEVEL_LETCHED  = 3,
+  LSM6DSO_LEVEL_TRIGGER  = 2,
+  LSM6DSO_EDGE_TRIGGER   = 4,
+} lsm6dso_den_mode_t;
+int32_t lsm6dso_den_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_den_mode_t val);
+int32_t lsm6dso_den_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_den_mode_t *val);
+
+typedef enum {
+  LSM6DSO_DEN_ACT_LOW  = 0,
+  LSM6DSO_DEN_ACT_HIGH = 1,
+} lsm6dso_den_lh_t;
+int32_t lsm6dso_den_polarity_set(lsm6dso_ctx_t *ctx, lsm6dso_den_lh_t val);
+int32_t lsm6dso_den_polarity_get(lsm6dso_ctx_t *ctx, lsm6dso_den_lh_t *val);
+
+typedef enum {
+  LSM6DSO_STAMP_IN_GY_DATA     = 0,
+  LSM6DSO_STAMP_IN_XL_DATA     = 1,
+  LSM6DSO_STAMP_IN_GY_XL_DATA  = 2,
+} lsm6dso_den_xl_g_t;
+int32_t lsm6dso_den_enable_set(lsm6dso_ctx_t *ctx, lsm6dso_den_xl_g_t val);
+int32_t lsm6dso_den_enable_get(lsm6dso_ctx_t *ctx, lsm6dso_den_xl_g_t *val);
+
+int32_t lsm6dso_den_mark_axis_x_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_den_mark_axis_x_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_den_mark_axis_y_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_den_mark_axis_y_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_den_mark_axis_z_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_den_mark_axis_z_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_PEDO_DISABLE              = 0x00,
+  LSM6DSO_PEDO_BASE_MODE            = 0x01,
+  LSM6DSO_PEDO_ADV_MODE             = 0x03,
+  LSM6DSO_FALSE_STEP_REJ            = 0x13,
+  LSM6DSO_FALSE_STEP_REJ_ADV_MODE   = 0x33,
+} lsm6dso_pedo_md_t;
+int32_t lsm6dso_pedo_sens_set(lsm6dso_ctx_t *ctx, lsm6dso_pedo_md_t val);
+int32_t lsm6dso_pedo_sens_get(lsm6dso_ctx_t *ctx, lsm6dso_pedo_md_t *val);
+
+int32_t lsm6dso_pedo_step_detect_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_pedo_debounce_steps_set(lsm6dso_ctx_t *ctx,
+                                             uint8_t *buff);
+int32_t lsm6dso_pedo_debounce_steps_get(lsm6dso_ctx_t *ctx,
+                                             uint8_t *buff);
+
+int32_t lsm6dso_pedo_steps_period_set(lsm6dso_ctx_t *ctx, uint8_t *buff);
+int32_t lsm6dso_pedo_steps_period_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+typedef enum {
+  LSM6DSO_EVERY_STEP     = 0,
+  LSM6DSO_COUNT_OVERFLOW = 1,
+} lsm6dso_carry_count_en_t;
+int32_t lsm6dso_pedo_int_mode_set(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_carry_count_en_t val);
+int32_t lsm6dso_pedo_int_mode_get(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_carry_count_en_t *val);
+
+int32_t lsm6dso_motion_sens_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_motion_sens_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_motion_flag_data_ready_get(lsm6dso_ctx_t *ctx,
+                                                uint8_t *val);
+
+int32_t lsm6dso_tilt_sens_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_tilt_sens_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_tilt_flag_data_ready_get(lsm6dso_ctx_t *ctx,
+                                              uint8_t *val);
+
+int32_t lsm6dso_mag_sensitivity_set(lsm6dso_ctx_t *ctx, uint8_t *buff);
+int32_t lsm6dso_mag_sensitivity_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+int32_t lsm6dso_mag_offset_set(lsm6dso_ctx_t *ctx, uint8_t *buff);
+int32_t lsm6dso_mag_offset_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+int32_t lsm6dso_mag_soft_iron_set(lsm6dso_ctx_t *ctx, uint8_t *buff);
+int32_t lsm6dso_mag_soft_iron_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+typedef enum {
+  LSM6DSO_Z_EQ_Y     = 0,
+  LSM6DSO_Z_EQ_MIN_Y = 1,
+  LSM6DSO_Z_EQ_X     = 2,
+  LSM6DSO_Z_EQ_MIN_X = 3,
+  LSM6DSO_Z_EQ_MIN_Z = 4,
+  LSM6DSO_Z_EQ_Z     = 5,
+} lsm6dso_mag_z_axis_t;
+int32_t lsm6dso_mag_z_orient_set(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_mag_z_axis_t val);
+int32_t lsm6dso_mag_z_orient_get(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_mag_z_axis_t *val);
+
+typedef enum {
+  LSM6DSO_Y_EQ_Y     = 0,
+  LSM6DSO_Y_EQ_MIN_Y = 1,
+  LSM6DSO_Y_EQ_X     = 2,
+  LSM6DSO_Y_EQ_MIN_X = 3,
+  LSM6DSO_Y_EQ_MIN_Z = 4,
+  LSM6DSO_Y_EQ_Z     = 5,
+} lsm6dso_mag_y_axis_t;
+int32_t lsm6dso_mag_y_orient_set(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_mag_y_axis_t val);
+int32_t lsm6dso_mag_y_orient_get(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_mag_y_axis_t *val);
+
+typedef enum {
+  LSM6DSO_X_EQ_Y     = 0,
+  LSM6DSO_X_EQ_MIN_Y = 1,
+  LSM6DSO_X_EQ_X     = 2,
+  LSM6DSO_X_EQ_MIN_X = 3,
+  LSM6DSO_X_EQ_MIN_Z = 4,
+  LSM6DSO_X_EQ_Z     = 5,
+} lsm6dso_mag_x_axis_t;
+int32_t lsm6dso_mag_x_orient_set(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_mag_x_axis_t val);
+int32_t lsm6dso_mag_x_orient_get(lsm6dso_ctx_t *ctx,
+                                         lsm6dso_mag_x_axis_t *val);
+
+int32_t lsm6dso_long_cnt_flag_data_ready_get(lsm6dso_ctx_t *ctx,
+                                             uint8_t *val);
+
+int32_t lsm6dso_emb_fsm_en_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_emb_fsm_en_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef struct {
+    lsm6dso_fsm_enable_a_t          fsm_enable_a;
+    lsm6dso_fsm_enable_b_t          fsm_enable_b;
+} lsm6dso_emb_fsm_enable_t;
+int32_t lsm6dso_fsm_enable_set(lsm6dso_ctx_t *ctx,
+                               lsm6dso_emb_fsm_enable_t *val);
+int32_t lsm6dso_fsm_enable_get(lsm6dso_ctx_t *ctx,
+                               lsm6dso_emb_fsm_enable_t *val);
+
+int32_t lsm6dso_long_cnt_set(lsm6dso_ctx_t *ctx, uint8_t *buff);
+int32_t lsm6dso_long_cnt_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+typedef enum {
+  LSM6DSO_LC_NORMAL     = 0,
+  LSM6DSO_LC_CLEAR      = 1,
+  LSM6DSO_LC_CLEAR_DONE = 2,
+} lsm6dso_fsm_lc_clr_t;
+int32_t lsm6dso_long_clr_set(lsm6dso_ctx_t *ctx, lsm6dso_fsm_lc_clr_t val);
+int32_t lsm6dso_long_clr_get(lsm6dso_ctx_t *ctx, lsm6dso_fsm_lc_clr_t *val);
+
+typedef struct {
+    lsm6dso_fsm_outs1_t    fsm_outs1;
+    lsm6dso_fsm_outs2_t    fsm_outs2;
+    lsm6dso_fsm_outs3_t    fsm_outs3;
+    lsm6dso_fsm_outs4_t    fsm_outs4;
+    lsm6dso_fsm_outs5_t    fsm_outs5;
+    lsm6dso_fsm_outs6_t    fsm_outs6;
+    lsm6dso_fsm_outs7_t    fsm_outs7;
+    lsm6dso_fsm_outs8_t    fsm_outs8;
+    lsm6dso_fsm_outs1_t    fsm_outs9;
+    lsm6dso_fsm_outs2_t    fsm_outs10;
+    lsm6dso_fsm_outs3_t    fsm_outs11;
+    lsm6dso_fsm_outs4_t    fsm_outs12;
+    lsm6dso_fsm_outs5_t    fsm_outs13;
+    lsm6dso_fsm_outs6_t    fsm_outs14;
+    lsm6dso_fsm_outs7_t    fsm_outs15;
+    lsm6dso_fsm_outs8_t    fsm_outs16;
+} lsm6dso_fsm_out_t;
+int32_t lsm6dso_fsm_out_get(lsm6dso_ctx_t *ctx, lsm6dso_fsm_out_t *val);
+
+typedef enum {
+  LSM6DSO_ODR_FSM_12Hz5 = 0,
+  LSM6DSO_ODR_FSM_26Hz  = 1,
+  LSM6DSO_ODR_FSM_52Hz  = 2,
+  LSM6DSO_ODR_FSM_104Hz = 3,
+  LSM6DSO_ODR_FSM_208Hz = 4,
+  LSM6DSO_ODR_FSM_416Hz = 5,
+} lsm6dso_fsm_odr_t;
+int32_t lsm6dso_fsm_data_rate_set(lsm6dso_ctx_t *ctx, lsm6dso_fsm_odr_t val);
+int32_t lsm6dso_fsm_data_rate_get(lsm6dso_ctx_t *ctx, lsm6dso_fsm_odr_t *val);
+
+int32_t lsm6dso_fsm_init_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_fsm_init_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+int32_t lsm6dso_long_cnt_int_value_set(lsm6dso_ctx_t *ctx, uint8_t *buff);
+int32_t lsm6dso_long_cnt_int_value_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+int32_t lsm6dso_fsm_number_of_programs_set(lsm6dso_ctx_t *ctx, uint8_t *buff);
+int32_t lsm6dso_fsm_number_of_programs_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+int32_t lsm6dso_fsm_start_address_set(lsm6dso_ctx_t *ctx, uint8_t *buff);
+int32_t lsm6dso_fsm_start_address_get(lsm6dso_ctx_t *ctx, uint8_t *buff);
+
+typedef struct {
+    lsm6dso_sensor_hub_1_t   sh_byte_1;
+    lsm6dso_sensor_hub_2_t   sh_byte_2;
+    lsm6dso_sensor_hub_3_t   sh_byte_3;
+    lsm6dso_sensor_hub_4_t   sh_byte_4;
+    lsm6dso_sensor_hub_5_t   sh_byte_5;
+    lsm6dso_sensor_hub_6_t   sh_byte_6;
+    lsm6dso_sensor_hub_7_t   sh_byte_7;
+    lsm6dso_sensor_hub_8_t   sh_byte_8;
+    lsm6dso_sensor_hub_9_t   sh_byte_9;
+    lsm6dso_sensor_hub_10_t  sh_byte_10;
+    lsm6dso_sensor_hub_11_t  sh_byte_11;
+    lsm6dso_sensor_hub_12_t  sh_byte_12;
+    lsm6dso_sensor_hub_13_t  sh_byte_13;
+    lsm6dso_sensor_hub_14_t  sh_byte_14;
+    lsm6dso_sensor_hub_15_t  sh_byte_15;
+    lsm6dso_sensor_hub_16_t  sh_byte_16;
+    lsm6dso_sensor_hub_17_t  sh_byte_17;
+    lsm6dso_sensor_hub_18_t  sh_byte_18;
+} lsm6dso_emb_sh_read_t;
+int32_t lsm6dso_sh_read_data_raw_get(lsm6dso_ctx_t *ctx,
+                                     lsm6dso_emb_sh_read_t *val);
+
+typedef enum {
+  LSM6DSO_SLV_0       = 0,
+  LSM6DSO_SLV_0_1     = 1,
+  LSM6DSO_SLV_0_1_2   = 2,
+  LSM6DSO_SLV_0_1_2_3 = 3,
+} lsm6dso_aux_sens_on_t;
+int32_t lsm6dso_sh_slave_connected_set(lsm6dso_ctx_t *ctx,
+                                       lsm6dso_aux_sens_on_t val);
+int32_t lsm6dso_sh_slave_connected_get(lsm6dso_ctx_t *ctx,
+                                       lsm6dso_aux_sens_on_t *val);
+
+int32_t lsm6dso_sh_master_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_sh_master_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_EXT_PULL_UP      = 0,
+  LSM6DSO_INTERNAL_PULL_UP = 1,
+} lsm6dso_shub_pu_en_t;
+int32_t lsm6dso_sh_pin_mode_set(lsm6dso_ctx_t *ctx, lsm6dso_shub_pu_en_t val);
+int32_t lsm6dso_sh_pin_mode_get(lsm6dso_ctx_t *ctx, lsm6dso_shub_pu_en_t *val);
+
+int32_t lsm6dso_sh_pass_through_set(lsm6dso_ctx_t *ctx, uint8_t val);
+int32_t lsm6dso_sh_pass_through_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_EXT_ON_INT2_PIN = 0,
+  LSM6DSO_XL_GY_DRDY      = 1,
+} lsm6dso_start_config_t;
+int32_t lsm6dso_sh_syncro_mode_set(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_start_config_t val);
+int32_t lsm6dso_sh_syncro_mode_get(lsm6dso_ctx_t *ctx,
+                                   lsm6dso_start_config_t *val);
+
+typedef enum {
+  LSM6DSO_EACH_SH_CYCLE    = 0,
+  LSM6DSO_ONLY_FIRST_CYCLE = 1,
+} lsm6dso_write_once_t;
+int32_t lsm6dso_sh_write_mode_set(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_write_once_t val);
+int32_t lsm6dso_sh_write_mode_get(lsm6dso_ctx_t *ctx,
+                                  lsm6dso_write_once_t *val);
+
+int32_t lsm6dso_sh_reset_set(lsm6dso_ctx_t *ctx);
+int32_t lsm6dso_sh_reset_get(lsm6dso_ctx_t *ctx, uint8_t *val);
+
+typedef enum {
+  LSM6DSO_SH_ODR_104Hz = 0,
+  LSM6DSO_SH_ODR_52Hz  = 1,
+  LSM6DSO_SH_ODR_26Hz  = 2,
+  LSM6DSO_SH_ODR_13Hz  = 3,
+} lsm6dso_shub_odr_t;
+int32_t lsm6dso_sh_data_rate_set(lsm6dso_ctx_t *ctx, lsm6dso_shub_odr_t val);
+int32_t lsm6dso_sh_data_rate_get(lsm6dso_ctx_t *ctx, lsm6dso_shub_odr_t *val);
+
+typedef struct{
+  uint8_t   slv0_add;
+  uint8_t   slv0_subadd;
+  uint8_t   slv0_data;
+} lsm6dso_sh_cfg_write_t;
+int32_t lsm6dso_sh_cfg_write(lsm6dso_ctx_t *ctx, lsm6dso_sh_cfg_write_t *val);
+
+typedef struct{
+  uint8_t   slv_add;
+  uint8_t   slv_subadd;
+  uint8_t   slv_len;
+} lsm6dso_sh_cfg_read_t;
+int32_t lsm6dso_sh_slv0_cfg_read(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_sh_cfg_read_t *val);
+int32_t lsm6dso_sh_slv1_cfg_read(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_sh_cfg_read_t *val);
+int32_t lsm6dso_sh_slv2_cfg_read(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_sh_cfg_read_t *val);
+int32_t lsm6dso_sh_slv3_cfg_read(lsm6dso_ctx_t *ctx,
+                                 lsm6dso_sh_cfg_read_t *val);
+
+int32_t lsm6dso_sh_status_get(lsm6dso_ctx_t *ctx,
+                              lsm6dso_status_master_t *val);
+
+/**
+  * @}
+  *
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*LSM6DSO_DRIVER_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/