LELEC2811 - I&S / LIS2DW12

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Dependents:   X_NUCLEO_IKS01A3

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LIS2DW12Sensor.cpp Source File

LIS2DW12Sensor.cpp

Go to the documentation of this file.
00001 /**
00002  ******************************************************************************
00003  * @file    LIS2DW12Sensor.cpp
00004  * @author  CLab
00005  * @version V1.0.0
00006  * @date    15 November 2018
00007  * @brief   Implementation of an LIS2DW12 Inertial Measurement Unit (IMU) 3 axes
00008  *          sensor.
00009  ******************************************************************************
00010  * @attention
00011  *
00012  * <h2><center>&copy; COPYRIGHT(c) 2018 STMicroelectronics</center></h2>
00013  *
00014  * Redistribution and use in source and binary forms, with or without modification,
00015  * are permitted provided that the following conditions are met:
00016  *   1. Redistributions of source code must retain the above copyright notice,
00017  *      this list of conditions and the following disclaimer.
00018  *   2. Redistributions in binary form must reproduce the above copyright notice,
00019  *      this list of conditions and the following disclaimer in the documentation
00020  *      and/or other materials provided with the distribution.
00021  *   3. Neither the name of STMicroelectronics nor the names of its contributors
00022  *      may be used to endorse or promote products derived from this software
00023  *      without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00028  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00031  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00033  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  ******************************************************************************
00037  */
00038 
00039 
00040 /* Includes ------------------------------------------------------------------*/
00041 
00042 #include "LIS2DW12Sensor.h"
00043 
00044 
00045 /* Class Implementation ------------------------------------------------------*/
00046 
00047 /** Constructor
00048  * @param i2c object of an helper class which handles the I2C peripheral
00049  * @param address the address of the component's instance
00050  * @param int1_pin the interrupt 1 pin
00051  * @param int2_pin the interrupt 2 pin
00052  */
00053 LIS2DW12Sensor::LIS2DW12Sensor(DevI2C *i2c, uint8_t address, PinName int1_pin, PinName int2_pin) :
00054     _dev_i2c(i2c), _address(address), _cs_pin(NC), _int1_irq(int1_pin), _int2_irq(int2_pin)
00055 {
00056     assert(i2c);
00057     _dev_spi = NULL;
00058     _reg_ctx.write_reg = LIS2DW12_io_write;
00059     _reg_ctx.read_reg = LIS2DW12_io_read;
00060     _reg_ctx.handle = (void *)this;
00061 }
00062 
00063 /** Constructor
00064  * @param spi object of an helper class which handles the SPI peripheral
00065  * @param cs_pin the chip select pin
00066  * @param int1_pin the interrupt 1 pin
00067  * @param int2_pin the interrupt 2 pin
00068  * @param spi_type the SPI type (4-Wires or 3-Wires)
00069  */
00070 LIS2DW12Sensor::LIS2DW12Sensor(SPI *spi, PinName cs_pin, PinName int1_pin, PinName int2_pin, SPI_type_t spi_type) :
00071     _dev_spi(spi), _cs_pin(cs_pin), _int1_irq(int1_pin), _int2_irq(int2_pin), _spi_type(spi_type)
00072 {
00073     assert(spi);
00074     if (cs_pin == NC) {
00075         printf("ERROR LPS22HBSensor CS MUST NOT BE NC\n\r");
00076         _dev_spi = NULL;
00077         _dev_i2c = NULL;
00078         return;
00079     }
00080     _reg_ctx.write_reg = LIS2DW12_io_write;
00081     _reg_ctx.read_reg = LIS2DW12_io_read;
00082     _reg_ctx.handle = (void *)this;
00083     _cs_pin = 1;
00084     _dev_i2c = NULL;
00085     _address = 0;
00086 
00087     if (_spi_type == SPI3W) {
00088         /* Enable SPI 3-Wires on the component */
00089         uint8_t data = 0x05;
00090         lis2dw12_write_reg(&_reg_ctx, LIS2DW12_CTRL2, &data, 1);
00091     }
00092 
00093     /* Disable I2C on the component */
00094     lis2dw12_i2c_interface_set(&_reg_ctx, LIS2DW12_I2C_DISABLE);
00095 }
00096 
00097 /**
00098  * @brief     Initializing the component.
00099  * @param[in] init pointer to device specific initalization structure.
00100  * @retval    "0" in case of success, an error code otherwise.
00101  */
00102 int LIS2DW12Sensor::init(void *init)
00103 {
00104     /* Enable register address automatically incremented during a multiple byte
00105     access with a serial interface. */
00106     if (lis2dw12_auto_increment_set(&_reg_ctx, PROPERTY_ENABLE) != 0) {
00107         return 1;
00108     }
00109 
00110     /* Enable BDU */
00111     if (lis2dw12_block_data_update_set(&_reg_ctx, PROPERTY_ENABLE) != 0) {
00112         return 1;
00113     }
00114 
00115     /* FIFO mode selection */
00116     if (lis2dw12_fifo_mode_set(&_reg_ctx, LIS2DW12_BYPASS_MODE) != 0) {
00117         return 1;
00118     }
00119 
00120     /* Power mode selection */
00121     if (lis2dw12_power_mode_set(&_reg_ctx, LIS2DW12_HIGH_PERFORMANCE) != 0) {
00122         return 1;
00123     }
00124 
00125     /* Output data rate selection - power down. */
00126     if (lis2dw12_data_rate_set(&_reg_ctx, LIS2DW12_XL_ODR_OFF) != 0) {
00127         return 1;
00128     }
00129 
00130     /* Full scale selection. */
00131     if (lis2dw12_full_scale_set(&_reg_ctx, LIS2DW12_2g) != 0) {
00132         return 1;
00133     }
00134 
00135     /* Select default output data rate. */
00136     _x_last_odr = 100.0f;
00137 
00138     _x_last_operating_mode = LIS2DW12_HIGH_PERFORMANCE_MODE;
00139 
00140     _x_last_noise = LIS2DW12_LOW_NOISE_DISABLE;
00141 
00142     _x_is_enabled = 0;
00143 
00144     return 0;
00145 }
00146 
00147 /**
00148  * @brief  Enable LIS2DW12 Accelerator
00149  * @retval 0 in case of success, an error code otherwise
00150  */
00151 int LIS2DW12Sensor::enable_x(void)
00152 {
00153     /* Check if the component is already enabled */
00154     if (_x_is_enabled == 1) {
00155         return 0;
00156     }
00157 
00158     /* Output data rate selection. */
00159     if (set_x_odr_when_enabled(_x_last_odr, _x_last_operating_mode, _x_last_noise) == 1) {
00160         return 1;
00161     }
00162 
00163     _x_is_enabled = 1;
00164 
00165     return 0;
00166 }
00167 
00168 /**
00169  * @brief  Disable LIS2DW12 Accelerator
00170  * @retval 0 in case of success, an error code otherwise
00171  */
00172 int LIS2DW12Sensor::disable_x(void)
00173 {
00174     /* Check if the component is already disabled */
00175     if (_x_is_enabled == 0) {
00176         return 0;
00177     }
00178 
00179     /* Output data rate selection - power down. */
00180     if (lis2dw12_data_rate_set(&_reg_ctx, LIS2DW12_XL_ODR_OFF) != 0) {
00181         return 1;
00182     }
00183 
00184     _x_is_enabled = 0;
00185 
00186     return 0;
00187 }
00188 
00189 /**
00190  * @brief  Read ID of LIS2DW12 Accelerometer and Gyroscope
00191  * @param  p_id the pointer where the ID of the device is stored
00192  * @retval 0 in case of success, an error code otherwise
00193  */
00194 int LIS2DW12Sensor::read_id(uint8_t *id)
00195 {
00196     if (!id) {
00197         return 1;
00198     }
00199 
00200     /* Read WHO AM I register */
00201     if (lis2dw12_device_id_get(&_reg_ctx, id) != 0) {
00202         return 1;
00203     }
00204 
00205     return 0;
00206 }
00207 
00208 /**
00209  * @brief  Read data from LIS2DW12 Accelerometer
00210  * @param  acceleration the pointer where the accelerometer data are stored
00211  * @retval 0 in case of success, an error code otherwise
00212  */
00213 int LIS2DW12Sensor::get_x_axes(int32_t *acceleration)
00214 {
00215     int16_t data_raw[3];
00216     float sensitivity = 0;
00217 
00218     /* Read raw data from LIS2DW12 output register. */
00219     if (get_x_axes_raw(data_raw) == 1) {
00220         return 1;
00221     }
00222 
00223     /* Get LIS2DW12 actual sensitivity. */
00224     if (get_x_sensitivity(&sensitivity) == 1) {
00225         return 1;
00226     }
00227 
00228     /* Calculate the data. */
00229     acceleration[0] = (int32_t)(data_raw[0] * sensitivity);
00230     acceleration[1] = (int32_t)(data_raw[1] * sensitivity);
00231     acceleration[2] = (int32_t)(data_raw[2] * sensitivity);
00232 
00233     return 0;
00234 }
00235 
00236 /**
00237  * @brief  Read Accelerometer Sensitivity
00238  * @param  sensitivity the pointer where the accelerometer sensitivity is stored
00239  * @retval 0 in case of success, an error code otherwise
00240  */
00241 int LIS2DW12Sensor::get_x_sensitivity(float *sensitivity)
00242 {
00243     int32_t ret = 0;
00244     lis2dw12_fs_t full_scale;
00245     lis2dw12_mode_t mode;
00246 
00247     /* Read actual full scale selection from sensor. */
00248     if (lis2dw12_full_scale_get(&_reg_ctx, &full_scale) != 0) {
00249         return 1;
00250     }
00251 
00252     /* Read actual power mode selection from sensor. */
00253     if (lis2dw12_power_mode_get(&_reg_ctx, &mode) != 0) {
00254         return 1;
00255     }
00256 
00257     switch (mode) {
00258         case LIS2DW12_CONT_LOW_PWR_12bit:
00259         case LIS2DW12_SINGLE_LOW_PWR_12bit:
00260         case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit:
00261         case LIS2DW12_SINGLE_LOW_LOW_NOISE_PWR_12bit:
00262             switch (full_scale) {
00263                 case LIS2DW12_2g:
00264                     *sensitivity = LIS2DW12_ACC_SENSITIVITY_FOR_FS_2G_LOPOW1_MODE;
00265                     break;
00266 
00267                 case LIS2DW12_4g:
00268                     *sensitivity = LIS2DW12_ACC_SENSITIVITY_FOR_FS_4G_LOPOW1_MODE;
00269                     break;
00270 
00271                 case LIS2DW12_8g:
00272                     *sensitivity = LIS2DW12_ACC_SENSITIVITY_FOR_FS_8G_LOPOW1_MODE;
00273                     break;
00274 
00275                 case LIS2DW12_16g:
00276                     *sensitivity = LIS2DW12_ACC_SENSITIVITY_FOR_FS_16G_LOPOW1_MODE;
00277                     break;
00278 
00279                 default:
00280                     *sensitivity = -1.0f;
00281                     ret = 1;
00282                     break;
00283             }
00284             break;
00285 
00286         case LIS2DW12_HIGH_PERFORMANCE:
00287         case LIS2DW12_CONT_LOW_PWR_4:
00288         case LIS2DW12_CONT_LOW_PWR_3:
00289         case LIS2DW12_CONT_LOW_PWR_2:
00290         case LIS2DW12_SINGLE_LOW_PWR_4:
00291         case LIS2DW12_SINGLE_LOW_PWR_3:
00292         case LIS2DW12_SINGLE_LOW_PWR_2:
00293         case LIS2DW12_HIGH_PERFORMANCE_LOW_NOISE:
00294         case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_4:
00295         case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_3:
00296         case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_2:
00297         case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_4:
00298         case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_3:
00299         case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_2:
00300             switch (full_scale) {
00301                 case LIS2DW12_2g:
00302                     *sensitivity = LIS2DW12_ACC_SENSITIVITY_FOR_FS_2G_OTHER_MODES;
00303                     break;
00304 
00305                 case LIS2DW12_4g:
00306                     *sensitivity = LIS2DW12_ACC_SENSITIVITY_FOR_FS_4G_OTHER_MODES;
00307                     break;
00308 
00309                 case LIS2DW12_8g:
00310                     *sensitivity = LIS2DW12_ACC_SENSITIVITY_FOR_FS_8G_OTHER_MODES;
00311                     break;
00312 
00313                 case LIS2DW12_16g:
00314                     *sensitivity = LIS2DW12_ACC_SENSITIVITY_FOR_FS_16G_OTHER_MODES;
00315                     break;
00316 
00317                 default:
00318                     *sensitivity = -1.0f;
00319                     ret = 1;
00320                     break;
00321             }
00322             break;
00323 
00324         default:
00325             *sensitivity = -1.0f;
00326             ret = 1;
00327             break;
00328     }
00329 
00330     return ret;
00331 }
00332 
00333 /**
00334  * @brief  Read raw data from LIS2DW12 Accelerometer
00335  * @param  value the pointer where the accelerometer raw data are stored
00336  * @retval 0 in case of success, an error code otherwise
00337  */
00338 int LIS2DW12Sensor::get_x_axes_raw(int16_t *value)
00339 {
00340     axis3bit16_t data_raw;
00341     lis2dw12_mode_t mode;
00342     int32_t ret = 0;
00343 
00344     /* Read actual power mode selection from sensor. */
00345     if (lis2dw12_power_mode_get(&_reg_ctx, &mode) != 0) {
00346         return 1;
00347     }
00348 
00349     /* Read raw data values. */
00350     if (lis2dw12_acceleration_raw_get(&_reg_ctx, data_raw.u8bit) != 0) {
00351         return 1;
00352     }
00353 
00354     switch (mode) {
00355         case LIS2DW12_CONT_LOW_PWR_12bit:
00356         case LIS2DW12_SINGLE_LOW_PWR_12bit:
00357         case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit:
00358         case LIS2DW12_SINGLE_LOW_LOW_NOISE_PWR_12bit:
00359             /* Data format 12 bits. */
00360             value[0] = (data_raw.i16bit[0] / 16);
00361             value[1] = (data_raw.i16bit[1] / 16);
00362             value[2] = (data_raw.i16bit[2] / 16);
00363             break;
00364 
00365         case LIS2DW12_HIGH_PERFORMANCE:
00366         case LIS2DW12_CONT_LOW_PWR_4:
00367         case LIS2DW12_CONT_LOW_PWR_3:
00368         case LIS2DW12_CONT_LOW_PWR_2:
00369         case LIS2DW12_SINGLE_LOW_PWR_4:
00370         case LIS2DW12_SINGLE_LOW_PWR_3:
00371         case LIS2DW12_SINGLE_LOW_PWR_2:
00372         case LIS2DW12_HIGH_PERFORMANCE_LOW_NOISE:
00373         case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_4:
00374         case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_3:
00375         case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_2:
00376         case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_4:
00377         case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_3:
00378         case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_2:
00379             /* Data format 14 bits. */
00380             value[0] = (data_raw.i16bit[0] / 4);
00381             value[1] = (data_raw.i16bit[1] / 4);
00382             value[2] = (data_raw.i16bit[2] / 4);
00383             break;
00384 
00385         default:
00386             ret = 1;
00387             break;
00388     }
00389 
00390     return ret;
00391 }
00392 
00393 /**
00394  * @brief  Read LIS2DW12 Accelerometer output data rate
00395  * @param  odr the pointer to the output data rate
00396  * @retval 0 in case of success, an error code otherwise
00397  */
00398 int LIS2DW12Sensor::get_x_odr(float *odr)
00399 {
00400     int32_t ret = 0;
00401     lis2dw12_odr_t odr_low_level;
00402     lis2dw12_mode_t mode;
00403 
00404     /* Get current output data rate. */
00405     if (lis2dw12_data_rate_get(&_reg_ctx, &odr_low_level) != 0) {
00406         return 1;
00407     }
00408 
00409     /* Read actual power mode selection from sensor. */
00410     if (lis2dw12_power_mode_get(&_reg_ctx, &mode) != 0) {
00411         return 1;
00412     }
00413 
00414     switch (odr_low_level) {
00415         case LIS2DW12_XL_ODR_OFF:
00416         case LIS2DW12_XL_SET_SW_TRIG:
00417         case LIS2DW12_XL_SET_PIN_TRIG:
00418             *odr = 0.0f;
00419             break;
00420 
00421         case LIS2DW12_XL_ODR_1Hz6_LP_ONLY:
00422             switch (mode) {
00423                 case LIS2DW12_HIGH_PERFORMANCE:
00424                 case LIS2DW12_HIGH_PERFORMANCE_LOW_NOISE:
00425                     *odr = 12.5f;
00426                     break;
00427 
00428                 case LIS2DW12_CONT_LOW_PWR_4:
00429                 case LIS2DW12_CONT_LOW_PWR_3:
00430                 case LIS2DW12_CONT_LOW_PWR_2:
00431                 case LIS2DW12_CONT_LOW_PWR_12bit:
00432                 case LIS2DW12_SINGLE_LOW_PWR_4:
00433                 case LIS2DW12_SINGLE_LOW_PWR_3:
00434                 case LIS2DW12_SINGLE_LOW_PWR_2:
00435                 case LIS2DW12_SINGLE_LOW_PWR_12bit:
00436                 case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_4:
00437                 case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_3:
00438                 case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_2:
00439                 case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit:
00440                 case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_4:
00441                 case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_3:
00442                 case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_2:
00443                 case LIS2DW12_SINGLE_LOW_LOW_NOISE_PWR_12bit:
00444                     *odr = 1.6f;
00445                     break;
00446 
00447                 default:
00448                     *odr = -1.0f;
00449                     ret = 1;
00450                     break;
00451             }
00452             break;
00453 
00454         case LIS2DW12_XL_ODR_12Hz5:
00455             *odr = 12.5f;
00456             break;
00457 
00458         case LIS2DW12_XL_ODR_25Hz:
00459             *odr = 25.0f;
00460             break;
00461 
00462         case LIS2DW12_XL_ODR_50Hz:
00463             *odr = 50.0f;
00464             break;
00465 
00466         case LIS2DW12_XL_ODR_100Hz:
00467             *odr = 100.0f;
00468             break;
00469 
00470         case LIS2DW12_XL_ODR_200Hz:
00471             *odr = 200.0f;
00472             break;
00473 
00474         case LIS2DW12_XL_ODR_400Hz:
00475             switch (mode) {
00476                 case LIS2DW12_HIGH_PERFORMANCE:
00477                 case LIS2DW12_HIGH_PERFORMANCE_LOW_NOISE:
00478                     *odr = 400.0f;
00479                     break;
00480 
00481                 case LIS2DW12_CONT_LOW_PWR_4:
00482                 case LIS2DW12_CONT_LOW_PWR_3:
00483                 case LIS2DW12_CONT_LOW_PWR_2:
00484                 case LIS2DW12_CONT_LOW_PWR_12bit:
00485                 case LIS2DW12_SINGLE_LOW_PWR_4:
00486                 case LIS2DW12_SINGLE_LOW_PWR_3:
00487                 case LIS2DW12_SINGLE_LOW_PWR_2:
00488                 case LIS2DW12_SINGLE_LOW_PWR_12bit:
00489                 case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_4:
00490                 case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_3:
00491                 case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_2:
00492                 case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit:
00493                 case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_4:
00494                 case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_3:
00495                 case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_2:
00496                 case LIS2DW12_SINGLE_LOW_LOW_NOISE_PWR_12bit:
00497                     *odr = 200.0f;
00498                     break;
00499 
00500                 default:
00501                     *odr = -1.0f;
00502                     ret = 1;
00503                     break;
00504             }
00505             break;
00506 
00507         case LIS2DW12_XL_ODR_800Hz:
00508             switch (mode) {
00509                 case LIS2DW12_HIGH_PERFORMANCE:
00510                 case LIS2DW12_HIGH_PERFORMANCE_LOW_NOISE:
00511                     *odr = 800.0f;
00512                     break;
00513 
00514                 case LIS2DW12_CONT_LOW_PWR_4:
00515                 case LIS2DW12_CONT_LOW_PWR_3:
00516                 case LIS2DW12_CONT_LOW_PWR_2:
00517                 case LIS2DW12_CONT_LOW_PWR_12bit:
00518                 case LIS2DW12_SINGLE_LOW_PWR_4:
00519                 case LIS2DW12_SINGLE_LOW_PWR_3:
00520                 case LIS2DW12_SINGLE_LOW_PWR_2:
00521                 case LIS2DW12_SINGLE_LOW_PWR_12bit:
00522                 case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_4:
00523                 case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_3:
00524                 case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_2:
00525                 case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit:
00526                 case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_4:
00527                 case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_3:
00528                 case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_2:
00529                 case LIS2DW12_SINGLE_LOW_LOW_NOISE_PWR_12bit:
00530                     *odr = 200.0f;
00531                     break;
00532 
00533                 default:
00534                     *odr = -1.0f;
00535                     ret = 1;
00536                     break;
00537             }
00538             break;
00539 
00540         case LIS2DW12_XL_ODR_1k6Hz:
00541             switch (mode) {
00542                 case LIS2DW12_HIGH_PERFORMANCE:
00543                 case LIS2DW12_HIGH_PERFORMANCE_LOW_NOISE:
00544                     *odr = 1600.0f;
00545                     break;
00546 
00547                 case LIS2DW12_CONT_LOW_PWR_4:
00548                 case LIS2DW12_CONT_LOW_PWR_3:
00549                 case LIS2DW12_CONT_LOW_PWR_2:
00550                 case LIS2DW12_CONT_LOW_PWR_12bit:
00551                 case LIS2DW12_SINGLE_LOW_PWR_4:
00552                 case LIS2DW12_SINGLE_LOW_PWR_3:
00553                 case LIS2DW12_SINGLE_LOW_PWR_2:
00554                 case LIS2DW12_SINGLE_LOW_PWR_12bit:
00555                 case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_4:
00556                 case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_3:
00557                 case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_2:
00558                 case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit:
00559                 case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_4:
00560                 case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_3:
00561                 case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_2:
00562                 case LIS2DW12_SINGLE_LOW_LOW_NOISE_PWR_12bit:
00563                     *odr = 200.0f;
00564                     break;
00565 
00566                 default:
00567                     *odr = -1.0f;
00568                     ret = 1;
00569                     break;
00570             }
00571             break;
00572 
00573         default:
00574             *odr = -1.0f;
00575             ret = 1;
00576             break;
00577     }
00578 
00579     return ret;
00580 }
00581 
00582 /**
00583  * @brief  Set LIS2DW12 Accelerometer output data rate
00584  * @param  odr the output data rate to be set
00585  * @retval 0 in case of success, an error code otherwise
00586  */
00587 int LIS2DW12Sensor::set_x_odr(float odr)
00588 {
00589     return set_x_odr_with_mode(odr, LIS2DW12_HIGH_PERFORMANCE_MODE, LIS2DW12_LOW_NOISE_DISABLE);
00590 }
00591 
00592 /**
00593  * @brief  Set LIS2DW12 Accelerometer output data rate
00594  * @param  odr the output data rate to be set
00595  * @param  mode the operating mode to be used
00596  * @param  noise the low noise option
00597  * @retval 0 in case of success, an error code otherwise
00598  */
00599 int LIS2DW12Sensor::set_x_odr_with_mode(float odr, LIS2DW12_Operating_Mode_t mode, LIS2DW12_Low_Noise_t noise)
00600 {
00601     if (_x_is_enabled == 1) {
00602         if (set_x_odr_when_enabled(odr, mode, noise) != 0) {
00603             return 1;
00604         }
00605     } else {
00606         if (set_x_odr_when_disabled(odr, mode, noise) != 0) {
00607             return 1;
00608         }
00609     }
00610 
00611     return 0;
00612 }
00613 
00614 /**
00615  * @brief  Set LIS2DW12 Accelerometer output data rate when enabled
00616  * @param  odr the output data rate to be set
00617  * @param  mode the operating mode to be used
00618  * @param  noise the low noise option
00619  * @retval 0 in case of success, an error code otherwise
00620  */
00621 int LIS2DW12Sensor::set_x_odr_when_enabled(float odr, LIS2DW12_Operating_Mode_t mode, LIS2DW12_Low_Noise_t noise)
00622 {
00623     lis2dw12_odr_t new_odr;
00624     lis2dw12_mode_t new_power_mode;
00625 
00626     switch (mode) {
00627         case LIS2DW12_HIGH_PERFORMANCE_MODE:
00628         default:
00629             switch (noise) {
00630                 case LIS2DW12_LOW_NOISE_DISABLE:
00631                 default:
00632                     new_power_mode = LIS2DW12_HIGH_PERFORMANCE;
00633                     break;
00634                 case LIS2DW12_LOW_NOISE_ENABLE:
00635                     new_power_mode = LIS2DW12_HIGH_PERFORMANCE_LOW_NOISE;
00636                     break;
00637             }
00638 
00639             /* If High Performance mode minimum ODR is 12.5Hz */
00640             if (odr < 12.5f) {
00641                 odr = 12.5f;
00642             }
00643             break;
00644         case LIS2DW12_LOW_POWER_MODE4:
00645             switch (noise) {
00646                 case LIS2DW12_LOW_NOISE_DISABLE:
00647                 default:
00648                     new_power_mode = LIS2DW12_CONT_LOW_PWR_4;
00649                     break;
00650                 case LIS2DW12_LOW_NOISE_ENABLE:
00651                     new_power_mode = LIS2DW12_CONT_LOW_PWR_LOW_NOISE_4;
00652                     break;
00653             }
00654 
00655             /* If Low Power mode maximum ODR is 200Hz */
00656             if (odr > 200.0f) {
00657                 odr = 200.0f;
00658             }
00659             break;
00660         case LIS2DW12_LOW_POWER_MODE3:
00661             switch (noise) {
00662                 case LIS2DW12_LOW_NOISE_DISABLE:
00663                 default:
00664                     new_power_mode = LIS2DW12_CONT_LOW_PWR_3;
00665                     break;
00666                 case LIS2DW12_LOW_NOISE_ENABLE:
00667                     new_power_mode = LIS2DW12_CONT_LOW_PWR_LOW_NOISE_3;
00668                     break;
00669             }
00670 
00671             /* If Low Power mode maximum ODR is 200Hz */
00672             if (odr > 200.0f) {
00673                 odr = 200.0f;
00674             }
00675             break;
00676         case LIS2DW12_LOW_POWER_MODE2:
00677             switch (noise) {
00678                 case LIS2DW12_LOW_NOISE_DISABLE:
00679                 default:
00680                     new_power_mode = LIS2DW12_CONT_LOW_PWR_2;
00681                     break;
00682                 case LIS2DW12_LOW_NOISE_ENABLE:
00683                     new_power_mode = LIS2DW12_CONT_LOW_PWR_LOW_NOISE_2;
00684                     break;
00685             }
00686 
00687             /* If Low Power mode maximum ODR is 200Hz */
00688             if (odr > 200.0f) {
00689                 odr = 200.0f;
00690             }
00691             break;
00692         case LIS2DW12_LOW_POWER_MODE1:
00693             switch (noise) {
00694                 case LIS2DW12_LOW_NOISE_DISABLE:
00695                 default:
00696                     new_power_mode = LIS2DW12_CONT_LOW_PWR_12bit;
00697                     break;
00698                 case LIS2DW12_LOW_NOISE_ENABLE:
00699                     new_power_mode = LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit;
00700                     break;
00701             }
00702 
00703             /* If Low Power mode maximum ODR is 200Hz */
00704             if (odr > 200.0f) {
00705                 odr = 200.0f;
00706             }
00707             break;
00708     }
00709 
00710 
00711     new_odr = (odr <=    1.6f) ? LIS2DW12_XL_ODR_1Hz6_LP_ONLY
00712               : (odr <=   12.5f) ? LIS2DW12_XL_ODR_12Hz5
00713               : (odr <=   25.0f) ? LIS2DW12_XL_ODR_25Hz
00714               : (odr <=   50.0f) ? LIS2DW12_XL_ODR_50Hz
00715               : (odr <=  100.0f) ? LIS2DW12_XL_ODR_100Hz
00716               : (odr <=  200.0f) ? LIS2DW12_XL_ODR_200Hz
00717               : (odr <=  400.0f) ? LIS2DW12_XL_ODR_400Hz
00718               : (odr <=  800.0f) ? LIS2DW12_XL_ODR_800Hz
00719               :                    LIS2DW12_XL_ODR_1k6Hz;
00720 
00721     /* Output data rate selection. */
00722     if (lis2dw12_data_rate_set(&_reg_ctx, new_odr) != 0) {
00723         return 1;
00724     }
00725 
00726     /* Power mode selection. */
00727     if (lis2dw12_power_mode_set(&_reg_ctx, new_power_mode) != 0) {
00728         return 1;
00729     }
00730 
00731     /* Store actual output data rate, operating mode and low noise. */
00732     _x_last_odr = odr;
00733     _x_last_operating_mode = mode;
00734     _x_last_noise = noise;
00735 
00736     return 0;
00737 }
00738 
00739 /**
00740  * @brief  Set LIS2DW12 Accelerometer output data rate when disabled
00741  * @param  odr the output data rate to be set
00742  * @param  mode the operating mode to be used
00743  * @param  noise the low noise option
00744  * @retval 0 in case of success, an error code otherwise
00745  */
00746 int LIS2DW12Sensor::set_x_odr_when_disabled(float odr, LIS2DW12_Operating_Mode_t mode, LIS2DW12_Low_Noise_t noise)
00747 {
00748     _x_last_operating_mode = mode;
00749     _x_last_noise = noise;
00750 
00751     _x_last_odr = (odr <=    1.6f) ?    1.6f
00752                   : (odr <=   12.5f) ?   12.5f
00753                   : (odr <=   25.0f) ?   25.0f
00754                   : (odr <=   50.0f) ?   50.0f
00755                   : (odr <=  100.0f) ?  100.0f
00756                   : (odr <=  200.0f) ?  200.0f
00757                   : (odr <=  400.0f) ?  400.0f
00758                   : (odr <=  800.0f) ?  800.0f
00759                   :                    1600.0f;
00760 
00761     return 0;
00762 }
00763 
00764 /**
00765  * @brief  Read LIS2DW12 Accelerometer full scale
00766  * @param  full_scale the pointer to the full scale
00767  * @retval 0 in case of success, an error code otherwise
00768  */
00769 int LIS2DW12Sensor::get_x_fs(float *full_scale)
00770 {
00771     int32_t ret = 0;
00772     lis2dw12_fs_t fs_low_level;
00773 
00774     /* Read actual full scale selection from sensor. */
00775     if (lis2dw12_full_scale_get(&_reg_ctx, &fs_low_level) != 0) {
00776         return 1;
00777     }
00778 
00779     switch (fs_low_level) {
00780         case LIS2DW12_2g:
00781             *full_scale =  2;
00782             break;
00783 
00784         case LIS2DW12_4g:
00785             *full_scale =  4;
00786             break;
00787 
00788         case LIS2DW12_8g:
00789             *full_scale =  8;
00790             break;
00791 
00792         case LIS2DW12_16g:
00793             *full_scale = 16;
00794             break;
00795 
00796         default:
00797             *full_scale = -1;
00798             ret = 1;
00799             break;
00800     }
00801 
00802     return ret;
00803 }
00804 
00805 /**
00806  * @brief  Set LIS2DW12 Accelerometer full scale
00807  * @param  full_scale the full scale to be set
00808  * @retval 0 in case of success, an error code otherwise
00809  */
00810 int LIS2DW12Sensor::set_x_fs(float full_scale)
00811 {
00812     lis2dw12_fs_t new_fs;
00813 
00814     /* Seems like MISRA C-2012 rule 14.3a violation but only from single file statical analysis point of view because
00815        the parameter passed to the function is not known at the moment of analysis */
00816     new_fs = (full_scale <= 2) ? LIS2DW12_2g
00817              : (full_scale <= 4) ? LIS2DW12_4g
00818              : (full_scale <= 8) ? LIS2DW12_8g
00819              :                    LIS2DW12_16g;
00820 
00821     if (lis2dw12_full_scale_set(&_reg_ctx, new_fs) != 0) {
00822         return 1;
00823     }
00824 
00825     return 0;
00826 }
00827 
00828 /**
00829  * @brief  Read LIS2DW12 Accelerometer filter bandwidth
00830  * @param  bw_filt the pointer to the filter bandwidth
00831  * @retval 0 in case of success, an error code otherwise
00832  */
00833 int LIS2DW12Sensor::get_x_bw_filt(uint8_t *bw_filt)
00834 {
00835     int ret = 0;
00836     lis2dw12_bw_filt_t bw_filt_low_level;
00837 
00838     /* Get current filter bandwidth. */
00839     if (lis2dw12_filter_bandwidth_get(&_reg_ctx, &bw_filt_low_level) != 0) {
00840         return 1;
00841     }
00842 
00843     switch (bw_filt_low_level) {
00844         case LIS2DW12_ODR_DIV_2:
00845             *bw_filt = 0;
00846             break;
00847 
00848         case LIS2DW12_ODR_DIV_4:
00849             *bw_filt = 1;
00850             break;
00851 
00852         case LIS2DW12_ODR_DIV_10:
00853             *bw_filt = 2;
00854             break;
00855 
00856         case LIS2DW12_ODR_DIV_20:
00857             *bw_filt = 3;
00858             break;
00859 
00860         default:
00861             ret = 1;
00862             break;
00863     }
00864 
00865     return ret;
00866 }
00867 
00868 /**
00869  * @brief  Set LIS2DW12 Accelerometer filter bandwidth
00870  * @param  bw_filt the filter bandwidth to be set
00871  * @retval 0 in case of success, an error code otherwise
00872  */
00873 int LIS2DW12Sensor::set_x_bw_filt(uint8_t bw_filt)
00874 {
00875     lis2dw12_bw_filt_t new_bw_filt;
00876 
00877     new_bw_filt = (bw_filt == 0)    ? LIS2DW12_ODR_DIV_2
00878               : (bw_filt == 1)      ? LIS2DW12_ODR_DIV_4
00879               : (bw_filt == 2)      ? LIS2DW12_ODR_DIV_10
00880               :                     LIS2DW12_ODR_DIV_20;
00881 
00882     if (lis2dw12_filter_bandwidth_set(&_reg_ctx, new_bw_filt) != 0) {
00883         return 1;
00884     }
00885 
00886     return 0;
00887 }
00888 
00889 /**
00890  * @brief  Read LIS2DW12 Accelerometer power mode
00891  * @param  lp_mode the pointer to the low-power mode, mode the pointer to the mode, low_noise the pointer to the low-noise configuration
00892  * @retval 0 in case of success, an error code otherwise
00893  */
00894 int LIS2DW12Sensor::get_x_power_mode(uint8_t *lp_mode, uint8_t *mode, uint8_t *low_noise)
00895 {
00896     int ret = 0;
00897     lis2dw12_mode_t mode_low_level;
00898 
00899     /* Get current filter bandwidth. */
00900     if (lis2dw12_power_mode_get(&_reg_ctx, &mode_low_level) != 0) {
00901         return 1;
00902     }
00903 
00904     switch (mode_low_level) {
00905         case LIS2DW12_HIGH_PERFORMANCE:
00906             *lp_mode = 0;
00907             *mode = 1;
00908             *low_noise = 0;
00909             break;
00910         
00911         case LIS2DW12_CONT_LOW_PWR_4:
00912             *lp_mode = 3;
00913             *mode = 0;
00914             *low_noise = 0;
00915             break;
00916         
00917         case LIS2DW12_CONT_LOW_PWR_3:
00918             *lp_mode = 2;
00919             *mode = 0;
00920             *low_noise = 0;
00921             break;
00922         
00923         case LIS2DW12_CONT_LOW_PWR_2:
00924             *lp_mode = 1;
00925             *mode = 0;
00926             *low_noise = 0;
00927             break;
00928         
00929         case LIS2DW12_CONT_LOW_PWR_12bit:
00930             *lp_mode = 0;
00931             *mode = 0;
00932             *low_noise = 0;
00933             break;
00934         
00935         case LIS2DW12_SINGLE_LOW_PWR_4:
00936             *lp_mode = 3;
00937             *mode = 2;
00938             *low_noise = 0;
00939             break;
00940         
00941         case LIS2DW12_SINGLE_LOW_PWR_3:
00942             *lp_mode = 2;
00943             *mode = 2;
00944             *low_noise = 0;
00945             break;
00946         
00947         case LIS2DW12_SINGLE_LOW_PWR_2:
00948             *lp_mode = 1;
00949             *mode = 2;
00950             *low_noise = 0;
00951             break;
00952         
00953         case LIS2DW12_SINGLE_LOW_PWR_12bit:
00954             *lp_mode = 0;
00955             *mode = 2;
00956             *low_noise = 0;
00957             break;
00958         
00959         case LIS2DW12_HIGH_PERFORMANCE_LOW_NOISE:
00960             *lp_mode = 0;
00961             *mode = 1;
00962             *low_noise = 1;
00963             break;
00964         
00965         case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_4:
00966             *lp_mode = 3;
00967             *mode = 0;
00968             *low_noise = 1;
00969             break;
00970         
00971         case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_3:
00972             *lp_mode = 2;
00973             *mode = 0;
00974             *low_noise = 1;
00975             break;
00976         
00977         case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_2:
00978             *lp_mode = 1;
00979             *mode = 0;
00980             *low_noise = 1;
00981             break;
00982         
00983         case LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit:
00984             *lp_mode = 0;
00985             *mode = 0;
00986             *low_noise = 1;
00987             break;
00988         
00989         case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_4:
00990             *lp_mode = 3;
00991             *mode = 2;
00992             *low_noise = 1;
00993             break;
00994         
00995         case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_3:
00996             *lp_mode = 2;
00997             *mode = 2;
00998             *low_noise = 1;
00999             break;
01000         
01001         case LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_2:
01002             *lp_mode = 1;
01003             *mode = 2;
01004             *low_noise = 1;
01005             break;
01006         
01007         case LIS2DW12_SINGLE_LOW_LOW_NOISE_PWR_12bit:
01008             *lp_mode = 0;
01009             *mode = 2;
01010             *low_noise = 1;
01011             break;
01012 
01013         default:
01014             ret = 1;
01015             break;
01016     }
01017 
01018     return ret;
01019 }
01020 
01021 /**
01022  * @brief  Set LIS2DW12 Accelerometer power mode
01023  * @param  power_mode the power mode to be set
01024  * @retval 0 in case of success, an error code otherwise
01025  */
01026 int LIS2DW12Sensor::set_x_power_mode(uint8_t power_mode)
01027 {
01028     lis2dw12_mode_t new_mode;
01029 
01030     new_mode = (power_mode == 0x04)     ? LIS2DW12_HIGH_PERFORMANCE
01031               : (power_mode == 0x03)    ? LIS2DW12_CONT_LOW_PWR_4
01032               : (power_mode == 0x02)    ? LIS2DW12_CONT_LOW_PWR_3
01033               : (power_mode == 0x01)    ? LIS2DW12_CONT_LOW_PWR_2
01034               : (power_mode == 0x00)    ? LIS2DW12_CONT_LOW_PWR_12bit
01035               : (power_mode == 0x0B)    ? LIS2DW12_SINGLE_LOW_PWR_4
01036               : (power_mode == 0x0A)    ? LIS2DW12_SINGLE_LOW_PWR_3
01037               : (power_mode == 0x09)    ? LIS2DW12_SINGLE_LOW_PWR_2
01038               : (power_mode == 0x08)    ? LIS2DW12_SINGLE_LOW_PWR_12bit
01039               : (power_mode == 0x14)    ? LIS2DW12_HIGH_PERFORMANCE_LOW_NOISE
01040               : (power_mode == 0x13)    ? LIS2DW12_CONT_LOW_PWR_LOW_NOISE_4
01041               : (power_mode == 0x12)    ? LIS2DW12_CONT_LOW_PWR_LOW_NOISE_3
01042               : (power_mode == 0x11)    ? LIS2DW12_CONT_LOW_PWR_LOW_NOISE_2
01043               : (power_mode == 0x10)    ? LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit
01044               : (power_mode == 0x1B)    ? LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_4
01045               : (power_mode == 0x1A)    ? LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_3
01046               : (power_mode == 0x19)    ? LIS2DW12_SINGLE_LOW_PWR_LOW_NOISE_2
01047               : (power_mode == 0x18)    ? LIS2DW12_SINGLE_LOW_LOW_NOISE_PWR_12bit
01048               :                         LIS2DW12_HIGH_PERFORMANCE;
01049 
01050     if (lis2dw12_power_mode_set(&_reg_ctx, new_mode) != 0) {
01051         return 1;
01052     }
01053 
01054     return 0;
01055 }
01056 
01057 /**
01058  * @brief Enable the wake up detection for LIS2DW12 accelerometer sensor
01059  * @note  This function sets the LIS2DW12 accelerometer ODR to 200Hz and the LIS2DW12 accelerometer full scale to 2g
01060  * @retval 0 in case of success, an error code otherwise
01061  */
01062 int LIS2DW12Sensor::enable_wake_up_detection(void)
01063 {
01064     int32_t ret = 0;
01065     lis2dw12_ctrl4_int1_pad_ctrl_t val;
01066 
01067     /* Output Data Rate selection */
01068     if (set_x_odr(200.0f) != 0) {
01069         return 1;
01070     }
01071 
01072     /* Full scale selection */
01073     if (set_x_fs(2) != 0) {
01074         return 1;
01075     }
01076 
01077     /* WAKE_DUR setting */
01078     if (lis2dw12_wkup_dur_set(&_reg_ctx, 0x00) != 0) {
01079         return 1;
01080     }
01081 
01082     /* Set wake up threshold. */
01083     if (lis2dw12_wkup_threshold_set(&_reg_ctx, 0x02) != 0) {
01084         return 1;
01085     }
01086 
01087     if (lis2dw12_pin_int1_route_get(&_reg_ctx, &val) != 0) {
01088         return 1;
01089     }
01090 
01091     val.int1_wu = PROPERTY_ENABLE;
01092 
01093     if (lis2dw12_pin_int1_route_set(&_reg_ctx, &val) != 0) {
01094         return 1;
01095     }
01096 
01097     return ret;
01098 }
01099 
01100 /**
01101  * @brief Disable the wake up detection for LIS2DW12 accelerometer sensor
01102  * @retval 0 in case of success, an error code otherwise
01103  */
01104 int LIS2DW12Sensor::disable_wake_up_detection(void)
01105 {
01106     lis2dw12_ctrl4_int1_pad_ctrl_t ctrl4_int1_reg;
01107     lis2dw12_ctrl5_int2_pad_ctrl_t ctrl5_int2_reg;
01108     lis2dw12_ctrl_reg7_t ctrl_reg7;
01109 
01110     /* Disable wake up event on INT1 pin. */
01111     if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_CTRL4_INT1_PAD_CTRL, (uint8_t *)&ctrl4_int1_reg, 1) != 0) {
01112         return 1;
01113     }
01114 
01115     ctrl4_int1_reg.int1_wu = PROPERTY_DISABLE;
01116 
01117     if (lis2dw12_write_reg(&_reg_ctx, LIS2DW12_CTRL4_INT1_PAD_CTRL, (uint8_t *)&ctrl4_int1_reg, 1) != 0) {
01118         return 1;
01119     }
01120 
01121     /* Read INT2 Sleep Change */
01122     if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_CTRL5_INT2_PAD_CTRL, (uint8_t *)&ctrl5_int2_reg, 1) != 0) {
01123         return 1;
01124     }
01125 
01126     /*Disable Interrupts bit if none event is still enabled */
01127     if (ctrl5_int2_reg.int2_sleep_chg == 0 && ctrl4_int1_reg.int1_wu == 0 && ctrl4_int1_reg.int1_6d == 0) {
01128         if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_CTRL_REG7, (uint8_t *)&ctrl_reg7, 1) != 0) {
01129             return 1;
01130         }
01131 
01132         ctrl_reg7.interrupts_enable = PROPERTY_DISABLE;
01133 
01134         if (lis2dw12_write_reg(&_reg_ctx, LIS2DW12_CTRL_REG7, (uint8_t *)&ctrl_reg7, 1) != 0) {
01135             return 1;
01136         }
01137     }
01138 
01139     /* Reset wake up threshold. */
01140     if (lis2dw12_wkup_threshold_set(&_reg_ctx, 0x00) != 0) {
01141         return 1;
01142     }
01143 
01144     /* WAKE_DUR setting */
01145     if (lis2dw12_wkup_dur_set(&_reg_ctx, 0x00) != 0) {
01146         return 1;
01147     }
01148 
01149     return 0;
01150 }
01151 
01152 /**
01153  * @brief Set the wake up threshold for LIS2DW12 accelerometer sensor
01154  * @param thr the threshold to be set
01155  * @retval 0 in case of success, an error code otherwise
01156  */
01157 int LIS2DW12Sensor::set_wake_up_threshold(uint8_t thr)
01158 {
01159     /* Set wake up threshold. */
01160     if (lis2dw12_wkup_threshold_set(&_reg_ctx, thr) != 0) {
01161         return 1;
01162     }
01163 
01164     return 0;
01165 }
01166 
01167 /**
01168  * @brief Set the wake up duration for LIS2DW12 accelerometer sensor
01169  * @param dur the duration to be set
01170  * @retval 0 in case of success, an error code otherwise
01171  */
01172 int LIS2DW12Sensor::set_wake_up_duration(uint8_t dur)
01173 {
01174     /* Set wake up duration. */
01175     if (lis2dw12_wkup_dur_set(&_reg_ctx, dur) != 0) {
01176         return 1;
01177     }
01178 
01179     return 0;
01180 }
01181 
01182 /**
01183  * @brief Enable the inactivity detection for LIS2DW12 accelerometer sensor
01184  * @retval 0 in case of success, an error code otherwise
01185  */
01186 int LIS2DW12Sensor::enable_inactivity_detection(void)
01187 {
01188     int32_t ret = 0;
01189     lis2dw12_ctrl5_int2_pad_ctrl_t val;
01190 
01191     /* Output Data Rate and Full scale must be selected externally */
01192 
01193     /* SLEEP_DUR setting */
01194     if (lis2dw12_act_sleep_dur_set(&_reg_ctx, 0x01) != 0) {
01195         return 1;
01196     }
01197 
01198     /* Set wake up threshold. */
01199     if (lis2dw12_wkup_threshold_set(&_reg_ctx, 0x02) != 0) {
01200         return 1;
01201     }
01202 
01203     /* Enable inactivity detection. */
01204     if (lis2dw12_act_mode_set(&_reg_ctx, LIS2DW12_DETECT_ACT_INACT) != 0) {
01205         return 1;
01206     }
01207 
01208     if (lis2dw12_pin_int2_route_get(&_reg_ctx, &val) != 0) {
01209         return 1;
01210     }
01211 
01212     val.int2_sleep_chg = PROPERTY_ENABLE;
01213 
01214     if (lis2dw12_pin_int2_route_set(&_reg_ctx, &val) != 0) {
01215         return 1;
01216     }
01217 
01218     return ret;
01219 }
01220 
01221 /**
01222  * @brief Disable the inactivity detection for LIS2DW12 accelerometer sensor
01223  * @retval 0 in case of success, an error code otherwise
01224  */
01225 int LIS2DW12Sensor::disable_inactivity_detection(void)
01226 {
01227     lis2dw12_ctrl4_int1_pad_ctrl_t ctrl4_int1_reg;
01228     lis2dw12_ctrl5_int2_pad_ctrl_t ctrl5_int2_reg;
01229     lis2dw12_ctrl_reg7_t ctrl_reg7;
01230 
01231     /* Disable inactivity event on INT2 pin */
01232     if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_CTRL5_INT2_PAD_CTRL, (uint8_t *)&ctrl5_int2_reg, 1) != 0) {
01233         return 1;
01234     }
01235 
01236     ctrl5_int2_reg.int2_sleep_chg = PROPERTY_DISABLE;
01237 
01238     if (lis2dw12_write_reg(&_reg_ctx, LIS2DW12_CTRL5_INT2_PAD_CTRL, (uint8_t *)&ctrl5_int2_reg, 1) != 0) {
01239         return 1;
01240     }
01241 
01242     /* Read INT1 Wake Up event and INT1 6D Orientation event */
01243     if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_CTRL4_INT1_PAD_CTRL, (uint8_t *)&ctrl4_int1_reg, 1) != 0) {
01244         return 1;
01245     }
01246 
01247     /*Disable Interrupts bit if none event is still enabled */
01248     if (ctrl5_int2_reg.int2_sleep_chg == 0 && ctrl4_int1_reg.int1_wu == 0 && ctrl4_int1_reg.int1_6d == 0) {
01249         if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_CTRL_REG7, (uint8_t *)&ctrl_reg7, 1) != 0) {
01250             return 1;
01251         }
01252 
01253         ctrl_reg7.interrupts_enable = PROPERTY_DISABLE;
01254 
01255         if (lis2dw12_write_reg(&_reg_ctx, LIS2DW12_CTRL_REG7, (uint8_t *)&ctrl_reg7, 1) != 0) {
01256             return 1;
01257         }
01258     }
01259 
01260     /* Disable inactivity detection. */
01261     if (lis2dw12_act_mode_set(&_reg_ctx, LIS2DW12_NO_DETECTION) != 0) {
01262         return 1;
01263     }
01264 
01265     /* Reset wake up threshold. */
01266     if (lis2dw12_wkup_threshold_set(&_reg_ctx, 0x00) != 0) {
01267         return 1;
01268     }
01269 
01270     /* SLEEP_DUR setting */
01271     if (lis2dw12_act_sleep_dur_set(&_reg_ctx, 0x00) != 0) {
01272         return 1;
01273     }
01274 
01275     return 0;
01276 }
01277 
01278 /**
01279  * @brief Set the sleep duration for LIS2DW12 accelerometer sensor
01280  * @param dur the duration to be set
01281  * @retval 0 in case of success, an error code otherwise
01282  */
01283 int LIS2DW12Sensor::set_sleep_duration(uint8_t dur)
01284 {
01285     /* Set sleep duration. */
01286     if (lis2dw12_act_sleep_dur_set(&_reg_ctx, dur) != 0) {
01287         return 1;
01288     }
01289 
01290     return 0;
01291 }
01292 
01293 /**
01294  * @brief Enable the 6D orientation detection for LIS2DW12 accelerometer sensor
01295  * @note  This function sets the LIS2DW12 accelerometer ODR to 200Hz and the LIS2DW12 accelerometer full scale to 2g
01296  * @retval 0 in case of success, an error code otherwise
01297  */
01298 int LIS2DW12Sensor::enable_6d_orientation(void)
01299 {
01300     int32_t ret = 0;
01301     lis2dw12_ctrl4_int1_pad_ctrl_t val;
01302 
01303     /* Output Data Rate selection */
01304     if (set_x_odr(200.0f) == 1) {
01305         return 1;
01306     }
01307 
01308     /* Full scale selection. */
01309     if (set_x_fs(2.0f) == 1) {
01310         return 1;
01311     }
01312 
01313     /* 6D orientation threshold. */
01314     if (lis2dw12_6d_threshold_set(&_reg_ctx, 2) != 0) { /* 60 degrees */
01315         return 1;
01316     }
01317 
01318     /* Enable 6D orientation event on INT1 pin */
01319     if (lis2dw12_pin_int1_route_get(&_reg_ctx, &val) != 0) {
01320         return 1;
01321     }
01322 
01323     val.int1_6d = PROPERTY_ENABLE;
01324 
01325     if (lis2dw12_pin_int1_route_set(&_reg_ctx, &val) != 0) {
01326         return 1;
01327     }
01328 
01329     return ret;
01330 }
01331 
01332 /**
01333  * @brief Disable the 6D orientation detection for LIS2DW12 accelerometer sensor
01334  * @retval 0 in case of success, an error code otherwise
01335  */
01336 int LIS2DW12Sensor::disable_6d_orientation(void)
01337 {
01338     lis2dw12_ctrl4_int1_pad_ctrl_t ctrl4_int1_reg;
01339     lis2dw12_ctrl5_int2_pad_ctrl_t ctrl5_int2_reg;
01340     lis2dw12_ctrl_reg7_t ctrl_reg7;
01341 
01342     /* Disable 6D orientation event on INT1 pin */
01343     if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_CTRL4_INT1_PAD_CTRL, (uint8_t *)&ctrl4_int1_reg, 1) != 0) {
01344         return 1;
01345     }
01346 
01347     ctrl4_int1_reg.int1_6d = PROPERTY_DISABLE;
01348 
01349     if (lis2dw12_write_reg(&_reg_ctx, LIS2DW12_CTRL4_INT1_PAD_CTRL, (uint8_t *)&ctrl4_int1_reg, 1) != 0) {
01350         return 1;
01351     }
01352 
01353     /* Read INT2 Sleep Change */
01354     if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_CTRL5_INT2_PAD_CTRL, (uint8_t *)&ctrl5_int2_reg, 1) != 0) {
01355         return 1;
01356     }
01357 
01358     /*Disable Interrupts bit if none event is still enabled */
01359     if (ctrl5_int2_reg.int2_sleep_chg == 0 && ctrl4_int1_reg.int1_wu == 0 && ctrl4_int1_reg.int1_6d == 0) {
01360         if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_CTRL_REG7, (uint8_t *)&ctrl_reg7, 1) != 0) {
01361             return 1;
01362         }
01363 
01364         ctrl_reg7.interrupts_enable = PROPERTY_DISABLE;
01365 
01366         if (lis2dw12_write_reg(&_reg_ctx, LIS2DW12_CTRL_REG7, (uint8_t *)&ctrl_reg7, 1) != 0) {
01367             return 1;
01368         }
01369     }
01370 
01371     /* Reset 6D orientation threshold. */
01372     if (lis2dw12_6d_threshold_set(&_reg_ctx, 0) != 0) {
01373         return 1;
01374     }
01375 
01376     return 0;
01377 }
01378 
01379 /**
01380  * @brief Set the 6D orientation threshold for LIS2DW12 accelerometer sensor
01381  * @param thr the threshold to be set
01382  * @retval 0 in case of success, an error code otherwise
01383  */
01384 int LIS2DW12Sensor::set_6d_orientation_threshold(uint8_t thr)
01385 {
01386     if (thr > 3) {
01387         return 1;
01388     }
01389 
01390     if (lis2dw12_6d_threshold_set(&_reg_ctx, thr) != 0) {
01391         return 1;
01392     }
01393 
01394     return 0;
01395 }
01396 
01397 /**
01398  * @brief Get the 6D orientation XL axis for LIS2DW12 accelerometer sensor
01399  * @param xl the pointer to the 6D orientation XL axis
01400  * @retval 0 in case of success, an error code otherwise
01401  */
01402 int LIS2DW12Sensor::get_6d_orientation_xl(uint8_t *xl)
01403 {
01404     lis2dw12_sixd_src_t data;
01405 
01406     if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_SIXD_SRC, (uint8_t *)&data, 1) != 0) {
01407         return 1;
01408     }
01409 
01410     *xl = data.xl;
01411 
01412     return 0;
01413 }
01414 
01415 /**
01416  * @brief Get the 6D orientation XH axis for LIS2DW12 accelerometer sensor
01417  * @param xh the pointer to the 6D orientation XH axis
01418  * @retval 0 in case of success, an error code otherwise
01419  */
01420 int LIS2DW12Sensor::get_6d_orientation_xh(uint8_t *xh)
01421 {
01422     lis2dw12_sixd_src_t data;
01423 
01424     if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_SIXD_SRC, (uint8_t *)&data, 1) != 0) {
01425         return 1;
01426     }
01427 
01428     *xh = data.xh;
01429 
01430     return 0;
01431 }
01432 
01433 /**
01434  * @brief Get the 6D orientation YL axis for LIS2DW12 accelerometer sensor
01435  * @param yl the pointer to the 6D orientation YL axis
01436  * @retval 0 in case of success, an error code otherwise
01437  */
01438 int LIS2DW12Sensor::get_6d_orientation_yl(uint8_t *yl)
01439 {
01440     lis2dw12_sixd_src_t data;
01441 
01442     if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_SIXD_SRC, (uint8_t *)&data, 1) != 0) {
01443         return 1;
01444     }
01445 
01446     *yl = data.yl;
01447 
01448     return 0;
01449 }
01450 
01451 /**
01452  * @brief Get the 6D orientation YH axis for LIS2DW12 accelerometer sensor
01453  * @param yh the pointer to the 6D orientation YH axis
01454  * @retval 0 in case of success, an error code otherwise
01455  */
01456 int LIS2DW12Sensor::get_6d_orientation_yh(uint8_t *yh)
01457 {
01458     lis2dw12_sixd_src_t data;
01459 
01460     if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_SIXD_SRC, (uint8_t *)&data, 1) != 0) {
01461         return 1;
01462     }
01463 
01464     *yh = data.yh;
01465 
01466     return 0;
01467 }
01468 
01469 /**
01470  * @brief Get the 6D orientation ZL axis for LIS2DW12 accelerometer sensor
01471  * @param zl the pointer to the 6D orientation ZL axis
01472  * @retval 0 in case of success, an error code otherwise
01473  */
01474 int LIS2DW12Sensor::get_6d_orientation_zl(uint8_t *zl)
01475 {
01476     lis2dw12_sixd_src_t data;
01477 
01478     if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_SIXD_SRC, (uint8_t *)&data, 1) != 0) {
01479         return 1;
01480     }
01481 
01482     *zl = data.zl;
01483 
01484     return 0;
01485 }
01486 
01487 /**
01488  * @brief Get the 6D orientation ZH axis for LIS2DW12 accelerometer sensor
01489  * @param zh the pointer to the 6D orientation ZH axis
01490  * @retval 0 in case of success, an error code otherwise
01491  */
01492 int LIS2DW12Sensor::get_6d_orientation_zh(uint8_t *zh)
01493 {
01494     lis2dw12_sixd_src_t data;
01495 
01496     if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_SIXD_SRC, (uint8_t *)&data, 1) != 0) {
01497         return 1;
01498     }
01499 
01500     *zh = data.zh;
01501 
01502     return 0;
01503 }
01504 
01505 /**
01506  * @brief Get the status of all hardware events for LIS2DW12 accelerometer sensor
01507  * @param status the pointer to the status of all hardware events
01508  * @retval 0 in case of success, an error code otherwise
01509  */
01510 int LIS2DW12Sensor::get_event_status(LIS2DW12_Event_Status_t *status)
01511 {
01512     lis2dw12_status_t status_reg;
01513     lis2dw12_ctrl4_int1_pad_ctrl_t ctrl4_int1_reg;
01514     lis2dw12_ctrl5_int2_pad_ctrl_t ctrl5_int2_reg;
01515 
01516     (void)memset((void *)status, 0x0, sizeof(LIS2DW12_Event_Status_t));
01517 
01518     if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_STATUS, (uint8_t *)&status_reg, 1) != 0) {
01519         return 1;
01520     }
01521 
01522     if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_CTRL4_INT1_PAD_CTRL, (uint8_t *)&ctrl4_int1_reg, 1) != 0) {
01523         return 1;
01524     }
01525 
01526     if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_CTRL5_INT2_PAD_CTRL, (uint8_t *)&ctrl5_int2_reg, 1) != 0) {
01527         return 1;
01528     }
01529 
01530     if (ctrl4_int1_reg.int1_wu == 1U) {
01531         if (status_reg.wu_ia == 1U) {
01532             status->WakeUpStatus = 1;
01533         }
01534     }
01535 
01536     if (ctrl4_int1_reg.int1_6d == 1U) {
01537         if (status_reg._6d_ia == 1U) {
01538             status->D6DOrientationStatus = 1;
01539         }
01540     }
01541 
01542     if (ctrl5_int2_reg.int2_sleep_chg == 1U) {
01543         if (status_reg.sleep_state == 1U) {
01544             status->SleepStatus = 1;
01545         }
01546     }
01547 
01548     return 0;
01549 }
01550 
01551 /**
01552  * @brief  Get the number of samples contained into the FIFO
01553  * @param  num_samples the number of samples contained into the FIFO
01554  * @retval 0 in case of success, an error code otherwise
01555  */
01556 int LIS2DW12Sensor::get_fifo_num_samples(uint16_t *num_samples)
01557 {
01558     lis2dw12_fifo_samples_t fifo_samples;
01559 
01560     if (lis2dw12_read_reg(&_reg_ctx, LIS2DW12_FIFO_SAMPLES, (uint8_t *)&fifo_samples, 1) != 0) {
01561         return 1;
01562     }
01563 
01564     if (fifo_samples.diff == 0x20) {
01565         *num_samples = 32;
01566     } else {
01567         *num_samples = fifo_samples.diff;
01568     }
01569 
01570     return 0;
01571 }
01572 
01573 /**
01574  * @brief  Set the FIFO mode
01575  * @param  mode FIFO mode
01576  * @retval 0 in case of success, an error code otherwise
01577  */
01578 int LIS2DW12Sensor::set_fifo_mode(uint8_t mode)
01579 {
01580     int32_t ret = 0;
01581 
01582     /* Verify that the passed parameter contains one of the valid values. */
01583     switch ((lis2dw12_fmode_t)mode) {
01584         case LIS2DW12_BYPASS_MODE:
01585         case LIS2DW12_FIFO_MODE:
01586         case LIS2DW12_STREAM_TO_FIFO_MODE:
01587         case LIS2DW12_BYPASS_TO_STREAM_MODE:
01588         case LIS2DW12_STREAM_MODE:
01589             break;
01590 
01591         default:
01592             ret = 1;
01593             break;
01594     }
01595 
01596     if (ret == 1) {
01597         return ret;
01598     }
01599 
01600     if (lis2dw12_fifo_mode_set(&_reg_ctx, (lis2dw12_fmode_t)mode) != 0) {
01601         return 1;
01602     }
01603 
01604     return ret;
01605 }
01606 
01607 /**
01608  * @brief Read the data from register
01609  * @param reg register address
01610  * @param data register data
01611  * @retval 0 in case of success, an error code otherwise
01612  */
01613 int LIS2DW12Sensor::read_reg(uint8_t reg, uint8_t *data)
01614 {
01615 
01616     if (lis2dw12_read_reg(&_reg_ctx, reg, data, 1) != 0) {
01617         return 1;
01618     }
01619 
01620     return 0;
01621 }
01622 
01623 /**
01624  * @brief Write the data to register
01625  * @param reg register address
01626  * @param data register data
01627  * @retval 0 in case of success, an error code otherwise
01628  */
01629 int LIS2DW12Sensor::write_reg(uint8_t reg, uint8_t data)
01630 {
01631 
01632     if (lis2dw12_write_reg(&_reg_ctx, reg, &data, 1) != 0) {
01633         return 1;
01634     }
01635 
01636     return 0;
01637 }
01638 
01639 
01640 int32_t LIS2DW12_io_write(void *handle, uint8_t WriteAddr, uint8_t *pBuffer, uint16_t nBytesToWrite)
01641 {
01642     return ((LIS2DW12Sensor *)handle)->io_write(pBuffer, WriteAddr, nBytesToWrite);
01643 }
01644 
01645 int32_t LIS2DW12_io_read(void *handle, uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead)
01646 {
01647     return ((LIS2DW12Sensor *)handle)->io_read(pBuffer, ReadAddr, nBytesToRead);
01648 }