Manuel Caballero / MC3635
Revision:
2:292a5265228e
Parent:
0:fb11c9db05cc
--- a/MC3635.cpp	Wed May 30 11:50:20 2018 +0000
+++ b/MC3635.cpp	Wed May 30 13:00:29 2018 +0000
@@ -0,0 +1,1931 @@
+/**
+ * @brief       MC3635.h
+ * @details     3-Axis Accelerometer.
+ *              Function file.
+ *
+ *
+ * @return      N/A
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018    The ORIGIN
+ * @pre         N/A.
+ * @warning     N/A
+ * @pre         This code belongs to Nimbus Centre ( http://www.nimbus.cit.ie ).
+ */
+
+#include "MC3635.h"
+
+
+MC3635::MC3635 ( PinName sda, PinName scl, uint32_t addr, uint32_t freq )
+    : _i2c          ( sda, scl )
+    , _MC3635_Addr  ( addr )
+{
+    _i2c.frequency( freq );
+}
+
+
+MC3635::~MC3635()
+{
+}
+
+
+
+/**
+ * @brief       MC3635_SetStandbyMode  ( void )
+ *
+ * @details     It puts the device into the STANDBY mode.
+ *
+ * @param[in]    N/A.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_SetStandbyMode.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     N/A.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_SetStandbyMode ( void )
+{
+    char        cmd[] =   { MODE_C, 0 };
+    uint32_t    aux   =   0;
+
+
+    /* Get the register data */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+
+    /* Update the register data */
+    cmd[1] &=  ~MODE_C_MCTRL_MASK;
+    cmd[1] |=   MODE_C_MCTRL_STANDBY;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_SetSleepMode  ( void )
+ *
+ * @details     It puts the device into the SLEEP mode.
+ *
+ * @param[in]    N/A.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_SetSleepMode.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     N/A.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_SetSleepMode ( void )
+{
+    char        cmd[] =   { MODE_C, 0 };
+    uint32_t    aux   =   0;
+
+
+    /* Get the register data */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+
+    /* Update the register data */
+    cmd[1] &=  ~MODE_C_MCTRL_MASK;
+    cmd[1] |=   MODE_C_MCTRL_SLEEP;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+/**
+ * @brief       MC3635_InitializationSequence  ( void )
+ *
+ * @details     It starts an initialization sequence ( recommended sequence ).
+ *
+ * @param[in]    N/A.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_InitializationSequence.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         Data sheet APS-048-0044v1.5 p.22
+ * @warning     The device MUST be in STANDBY mode, the user has to call this function
+ *              first: MC3635_SetStandbyMode.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_InitializationSequence ( void )
+{
+    char        cmd[]    =   { 0, 0 };
+    uint32_t    aux      =   0;
+
+
+    /* Feature 1: Specify Interface */
+    cmd[0]   =   FREG_1;
+    cmd[1]   =   FREG_1_I2C_EN_ENABLED;
+    aux      =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
+
+    /* Initialization Register 1 */
+    cmd[0]   =   INIT_1;
+    cmd[1]   =   INIT_1_INIT_1_FIXED_VALUE;
+    aux      =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
+
+    /* Drive Motion X */
+    cmd[0]   =   DMX;
+    cmd[1]   =   0x01;
+    aux      =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
+
+    /* Drive Motion Y */
+    cmd[0]   =   DMY;
+    cmd[1]   =   0x80;
+    aux      =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
+
+    /* Initialization Register 2 */
+    cmd[0]   =   INIT_2;
+    cmd[1]   =   INIT_2_INT_2_FIXED_VALUE;
+    aux      =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
+
+    /* Initialization Register 3 */
+    cmd[0]   =   INIT_3;
+    cmd[1]   =   INIT_3_INT_3_FIXED_VALUE;
+    aux      =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+/**
+ * @brief       MC3635_WriteScratchpadRegister  ( MC3635_data_t )
+ *
+ * @details     This register can store any 8-bit value and has no effect on hardware.
+ *
+ * @param[in]    myScratchpadRegister:  Data to be written.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_WriteScratchpadRegister.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A
+ * @warning     The device MUST be in STANDBY mode, the user has to call this function
+ *              first: MC3635_SetStandbyMode.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_WriteScratchpadRegister ( MC3635_data_t myScratchpadRegister )
+{
+    char        cmd[]    =   { 0, 0 };
+    uint32_t    aux      =   0;
+
+
+    /* Write the data */
+    cmd[0]   =   SCRATCH;
+    cmd[1]   =   myScratchpadRegister.scratch;
+    aux      =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
+
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_ReadScratchpadRegister  ( MC3635_data_t* )
+ *
+ * @details     It reads the scratch pad register.
+ *
+ * @param[in]    N/A
+ *
+ * @param[out]   myScratchpadRegister:  Data into SCRATCH register.
+ *
+ *
+ * @return       Status of MC3635_ReadScratchpadRegister.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A
+ * @warning     N/A.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_ReadScratchpadRegister ( MC3635_data_t* myScratchpadRegister )
+{
+    char        cmd     =   SCRATCH;
+    uint32_t    aux     =   0;
+
+    /* Get the data */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd, 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd, 1 );
+    
+    /* Update the value */
+    myScratchpadRegister->scratch    =   cmd;
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_SetSoftwareReset  ( void )
+ *
+ * @details     It performs a software reset.
+ *
+ * @param[in]    N/A.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_SetSoftwareReset.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A
+ * @warning     Immediately after a RESET or power-up event, several registers must be written with initialization values,
+ *              MC3635_InitializationSequence MUST be called.
+ * @warning     It takes reset to be completed at least 1ms, the user MUST take care of this delay.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_SetSoftwareReset ( void )
+{
+    char        cmd[]   =   { RESET , 0 };
+    uint32_t    aux     =   0;
+
+
+    /* Get the register data */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+    cmd[1] |=   RESET_RESET_FORCE_POWER_ON_RESET;
+
+    /* Write into the register */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_SetReload  ( void )
+ *
+ * @details     It performs a reload.
+ *
+ * @param[in]    N/A.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_SetReload.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         This bit must be cleared by software.
+ * @warning     It takes reset to be completed at least 1ms, the user MUST take care of this delay.
+ * @warning     The device MUST be in STANDBY mode, the user has to call this function
+ *              first: MC3635_SetStandbyMode.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_SetReload ( void )
+{
+    char        cmd[]        =   { RESET , 0 };
+    uint32_t    myTimeOut    =   23232323;
+    uint32_t    aux          =   0;
+
+
+    /* Get the register data */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+    cmd[1] |=   RESET_RELOAD_RELOAD_REGISTER_FROM_OTP;
+
+
+    /* Write into the register */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+    /* Wait until the action was DONE */
+    cmd[0]   =   EXT_STAT_2;
+    do {
+        aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+        aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+        myTimeOut--;
+    } while ( ( ( cmd[1] & EXT_STAT_2_OTP_BUSY_MASK ) == EXT_STAT_2_OTP_BUSY_OTP_POWERED ) && ( myTimeOut > 0 ) );
+
+
+    /* Clear the flag   */
+    cmd[0]  =   RESET;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+    cmd[1] &=  ~RESET_RELOAD_MASK;
+    cmd[1] |=   RESET_RELOAD_NORMAL_OPERATION;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+
+    if ( ( aux == I2C_SUCCESS ) && ( myTimeOut > 0 ) )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_ReadExtendedStatusRegister2  ( MC3635_data_t* )
+ *
+ * @details     It reads the Extended Status Register 2.
+ *
+ * @param[in]    N/A.
+ *
+ * @param[out]   myExt_stat_2:          The data of the register.
+ *
+ *
+ * @return       Status of MC3635_ReadExtendedStatusRegister2.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A
+ * @warning     N/A.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_ReadExtendedStatusRegister2 ( MC3635_data_t* myExt_stat_2 )
+{
+    char        cmd   =   EXT_STAT_2;
+    uint32_t    aux   =   0;
+
+
+    /* Get the register data */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd, 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd, 1 );
+    
+    /* Update the value */
+    myExt_stat_2->ext_stat_2     =   cmd;
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_ReadRawData  ( MC3635_data_t* )
+ *
+ * @details     It reads X, Y and Z raw data output.
+ *
+ * @param[in]    N/A.
+ *
+ * @param[out]   myRawData:             Raw data for X, Y and Z axis.
+ *
+ *
+ * @return       Status of MC3635_ReadRawData.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A
+ * @warning     N/A.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_ReadRawData ( MC3635_data_t* myRawData )
+{
+    char        cmd[] =   { XOUT_LSB, 0, 0, 0, 0, 0 };
+    uint32_t    aux   =   0;
+
+
+    /* Get the register data */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ) );
+
+    /* Parse the data */
+    myRawData->XAxis_mg    =  cmd[1];
+    myRawData->XAxis_mg  <<=  8;
+    myRawData->XAxis_mg   |=  cmd[0];
+
+    myRawData->YAxis_mg    =  cmd[3];
+    myRawData->YAxis_mg  <<=  8;
+    myRawData->YAxis_mg   |=  cmd[2];
+
+    myRawData->ZAxis_mg    =  cmd[5];
+    myRawData->ZAxis_mg  <<=  8;
+    myRawData->ZAxis_mg   |=  cmd[4];
+
+    /* Get the range.
+       NOTE: 2G and 12-bit are the reference, other values have to be
+             adapted to the configuration.
+             This information is NOT in the datasheet, it was calculated
+             experimentally.
+    */
+    MC3635_GetRange ( myRawData );
+
+    switch ( myRawData->range ) {
+        default:
+        case RANGE_C_RANGE_2G:
+            // The reference
+            break;
+
+        case RANGE_C_RANGE_4G:
+            // RANGE_C_RANGE_2G * 2
+            myRawData->XAxis_mg  <<=   1;
+            myRawData->YAxis_mg  <<=   1;
+            myRawData->ZAxis_mg  <<=   1;
+            break;
+
+        case RANGE_C_RANGE_8G:
+            // RANGE_C_RANGE_2G * 4
+            myRawData->XAxis_mg  <<=   2;
+            myRawData->YAxis_mg  <<=   2;
+            myRawData->ZAxis_mg  <<=   2;
+            break;
+
+        case RANGE_C_RANGE_16G:
+            // RANGE_C_RANGE_2G * 8
+            myRawData->XAxis_mg  <<=   3;
+            myRawData->YAxis_mg  <<=   3;
+            myRawData->ZAxis_mg  <<=   3;
+            break;
+
+        case RANGE_C_RANGE_12G:
+            // RANGE_C_RANGE_2G * 6
+            myRawData->XAxis_mg  *=   6.0;
+            myRawData->YAxis_mg  *=   6.0;
+            myRawData->ZAxis_mg  *=   6.0;
+            break;
+    }
+
+
+    /* Get the resolution.
+       NOTE: 2G and 12-bit are the reference, other values have to be
+             adapted to the configuration.
+             This information is NOT in the datasheet, it was calculated
+             experimentally.
+    */
+    MC3635_GetResolution ( myRawData );
+
+    switch ( myRawData->resolution ) {
+        default:
+        case RANGE_C_RES_6_BITS:
+            // RANGE_C_RES_12_BITS * 64
+            myRawData->XAxis_mg  <<=   6;
+            myRawData->YAxis_mg  <<=   6;
+            myRawData->ZAxis_mg  <<=   6;
+            break;
+
+        case RANGE_C_RES_7_BITS:
+            // RANGE_C_RES_12_BITS * 32
+            myRawData->XAxis_mg  <<=   5;
+            myRawData->YAxis_mg  <<=   5;
+            myRawData->ZAxis_mg  <<=   5;
+            break;
+
+        case RANGE_C_RES_8_BITS:
+            // RANGE_C_RES_12_BITS * 16
+            myRawData->XAxis_mg  <<=   4;
+            myRawData->YAxis_mg  <<=   4;
+            myRawData->ZAxis_mg  <<=   4;
+            break;
+
+        case RANGE_C_RES_10_BITS:
+            // RANGE_C_RES_12_BITS * 4
+            myRawData->XAxis_mg  <<=   2;
+            myRawData->YAxis_mg  <<=   2;
+            myRawData->ZAxis_mg  <<=   2;
+            break;
+
+        case RANGE_C_RES_12_BITS:
+            // The reference
+            break;
+
+        case RANGE_C_RES_14_BITS:
+            // RANGE_C_RES_12_BITS / 4
+            myRawData->XAxis_mg  >>=   2;
+            myRawData->YAxis_mg  >>=   2;
+            myRawData->ZAxis_mg  >>=   2;
+            break;
+    }
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_ReadStatusRegister1  ( MC3635_data_t* )
+ *
+ * @details     It reads the Status Register 1.
+ *
+ * @param[in]    N/A.
+ *
+ * @param[out]   myStatus_1:            The data of the register.
+ *
+ *
+ * @return       Status of MC3635_ReadStatusRegister1.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A
+ * @warning     N/A.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_ReadStatusRegister1 ( MC3635_data_t* myStatus_1 )
+{
+    char        cmd   =   STATUS_1;
+    uint32_t    aux   =   0;
+
+
+    /* Get the register data */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd, 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd, 1 );
+
+    /* Update the value */
+    myStatus_1->status_1     =   cmd;
+    
+    
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_ReadStatusRegister2  ( MC3635_data_t* )
+ *
+ * @details     It reads the Status Register 2.
+ *
+ * @param[in]    N/A.
+ *
+ * @param[out]   myStatus_2:            The data of the register.
+ *
+ *
+ * @return       Status of MC3635_ReadStatusRegister2.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A
+ * @warning     N/A.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_ReadStatusRegister2 ( MC3635_data_t* myStatus_2 )
+{
+    char        cmd   =   STATUS_2;
+    uint32_t    aux   =   0;
+
+
+    /* Get the register data */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd, 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd, 1 );
+    
+    /* Update the value */
+    myStatus_2->status_2     =   cmd;
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_ReadFeatureRegister1  ( MC3635_data_t* )
+ *
+ * @details     It reads the Feature Register 1.
+ *
+ * @param[in]    N/A.
+ *
+ * @param[out]   myFeatureRegister1:    The data of the register.
+ *
+ *
+ * @return       Status of MC3635_ReadFeatureRegister1.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A
+ * @warning     N/A.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_ReadFeatureRegister1 ( MC3635_data_t* myFeatureRegister1 )
+{
+    char        cmd   =   FREG_1;
+    uint32_t    aux   =   0;
+
+
+    /* Get the register data */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd, 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd, 1 );
+    
+    /* Update the value */
+    myFeatureRegister1->FeatureRegister1     =   cmd;
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_ReadFeatureRegister2  ( MC3635_data_t* )
+ *
+ * @details     It reads the Feature Register 2.
+ *
+ * @param[in]    N/A.
+ *
+ * @param[out]   myFeatureRegister2:    The data of the register.
+ *
+ *
+ * @return       Status of MC3635_ReadFeatureRegister2.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A
+ * @warning     N/A.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_ReadFeatureRegister2 ( MC3635_data_t* myFeatureRegister2 )
+{
+    char        cmd   =   FREG_2;
+    uint32_t    aux   =   0;
+
+
+    /* Get the register data */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd, 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd, 1 );
+
+    /* Update the value */
+    myFeatureRegister2->FeatureRegister2     =   cmd;
+    
+    
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_EnableAxis  ( MC3635_mode_c_mctrl_t , MC3635_mode_c_x_axis_pd_t , MC3635_mode_c_y_axis_pd_t , MC3635_mode_c_z_axis_pd_t )
+ *
+ * @details     It enables/disables X/Y/Z Axis.
+ *
+ * @param[in]    myXAxis:           Enabled/Disabled.
+ * @param[in]    myYAxis:           Enabled/Disabled.
+ * @param[in]    myZAxis:           Enabled/Disabled.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_EnableAxis.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     The device MUST be in STANDBY mode, the user has to call this function
+ *              first: MC3635_SetStandbyMode.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_EnableAxis ( MC3635_mode_c_x_axis_pd_t myXAxis, MC3635_mode_c_y_axis_pd_t myYAxis, MC3635_mode_c_z_axis_pd_t myZAxis )
+{
+    char        cmd[] =   { MODE_C, 0 };
+    uint32_t    aux   =   0;
+
+
+    /* Update the register data */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+    cmd[1] &=  ~( MODE_C_X_AXIS_PD_MASK | MODE_C_Y_AXIS_PD_MASK | MODE_C_Z_AXIS_PD_MASK );
+    cmd[1] |=   ( myXAxis | myYAxis | myZAxis );
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_SetStandbyClockRate  ( MC3635_sniff_c_stb_rate_t )
+ *
+ * @details     It sets the clock rate for STANDBY mode.
+ *
+ * @param[in]    mySTANDBY_ClockRate:   Wake Power Mode.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_SetStandbyClockRate.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     The device MUST be in STANDBY mode, the user has to call this function
+ *              first: MC3635_SetStandbyMode.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_SetStandbyClockRate ( MC3635_sniff_c_stb_rate_t mySTANDBY_ClockRate )
+{
+    char        cmd[] =   { SNIFF_C, 0 };
+    uint32_t    aux   =   0;
+
+
+    /* Get the register data */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+
+    /* Update the register data */
+    cmd[1] &=  ~SNIFF_C_STB_RATE_MASK;
+    cmd[1] |=   mySTANDBY_ClockRate;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_SetMode  ( MC3635_mode_c_mctrl_t , MC3635_power_mode_t , MC3635_sample_rate_t )
+ *
+ * @details     It sets the device mode, power mode and the ODR.
+ *
+ * @param[in]    myMode:            Device mode: SNIFF, CWAKE or SWAKE.
+ * @param[in]    myPowerMode:       Device power mode.
+ * @param[in]    myODR:             Sample Rate.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_SetMode.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         If you want to put the device into either STANDBY, SLEEP or TRIG mode, DO NOT use this function,
+ *              just use the its own functions.
+ * @warning     The device MUST be in STANDBY mode, the user has to call this function
+ *              first: MC3635_SetStandbyMode.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_SetMode ( MC3635_mode_c_mctrl_t myMode, MC3635_power_mode_t myPowerMode, MC3635_sample_rate_t myODR )
+{
+    char        cmd[] =   { 0, 0 };
+    uint32_t    aux   =   0;
+
+
+    /* CHECK INVALID MODES  */
+    // TRIG, STANDBY and SLEEP mode have their own function, do NOT use this one!
+    if ( ( myMode == MODE_C_MCTRL_STANDBY ) || ( myMode == MODE_C_MCTRL_SLEEP ) || ( myMode == MODE_C_MCTRL_TRIG ) ) {
+        return MC3635_FAILURE;
+    }
+
+    /* POWER MODE   */
+    // Get the register data
+    cmd[0]  =   PMCR;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+    if ( myMode == MODE_C_MCTRL_SNIFF ) {
+        cmd[1] &=  ~PMCR_SPM_MASK;
+        cmd[1] |=   ( myPowerMode << 4U );
+    } else {
+        cmd[1] &=  ~PMCR_CSPM_MASK;
+        cmd[1] |=   ( myPowerMode << 0U );
+    }
+
+    // Update the register
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+    /*  SAMPLE RATE FOR THE GIVEN MODE */
+    // SNIFF mode
+    if ( myMode == MODE_C_MCTRL_SNIFF ) {
+        cmd[0]  =   SNIFF_C;
+
+        switch ( myPowerMode ) {
+            case ULTRA_LOW_POWER_MODE:
+                if ( ( myODR == ODR_13 ) || ( myODR == ODR_14 ) ) {
+                    return MC3635_FAILURE;
+                }
+                break;
+
+            default:
+            case LOW_POWER_MODE:
+                if ( ( myODR == ODR_12 ) || ( myODR == ODR_13 ) || ( myODR == ODR_14 ) ) {
+                    return MC3635_FAILURE;
+                }
+                break;
+
+            case PRECISION:
+                if ( ( myODR == ODR_9 ) || ( myODR == ODR_10 ) || ( myODR == ODR_11 ) || ( myODR == ODR_12 ) || ( myODR == ODR_13 ) || ( myODR == ODR_14 ) ) {
+                    return MC3635_FAILURE;
+                }
+                break;
+        }
+    }
+    // CWAKE and SWAKE mode
+    else {
+        cmd[0]  =   RATE_1;
+
+        if ( ( myODR == ODR_0 ) || ( myODR == ODR_1 ) || ( myODR == ODR_2 ) || ( myODR == ODR_3 ) || ( myODR == ODR_4 ) || ( myODR == ODR_13 ) || ( myODR == ODR_14 ) ) {
+            return MC3635_FAILURE;
+        } else {
+            switch ( myPowerMode ) {
+                case ULTRA_LOW_POWER_MODE:
+                    if ( myODR == ODR_5 ) {
+                        return MC3635_FAILURE;
+                    }
+                    break;
+
+                default:
+                case LOW_POWER_MODE:
+                    if ( myODR == ODR_12 ) {
+                        return MC3635_FAILURE;
+                    }
+                    break;
+
+                case PRECISION:
+                    if ( ( myODR == ODR_9 ) || ( myODR == ODR_10 ) || ( myODR == ODR_11 ) || ( myODR == ODR_12 ) ) {
+                        return MC3635_FAILURE;
+                    }
+                    break;
+            }
+        }
+    }
+
+
+    // Check if Specific setup steps are required
+    if ( myODR == ODR_15 ) {
+        // Previous steps ( Step 1, Step 2 and Step 3 ) have to be implemented by the user before calling this function
+        // Step 4 is implemented at the begging of this function.
+
+        // Step 5: Point to set wake/sniff settings
+        cmd[0]  =   RATE_1;
+        cmd[1]  =   0x10;
+        aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+        if ( cmd[0] == SNIFF_C ) {
+            // Step 6: Rate 15 setup 1 for sniff
+            cmd[0]  =   TRIGC;
+            cmd[1]  =   0x30;
+            aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+            // Step 7: Rate 15 setup 2 for sniff
+            cmd[0]  =   RATE_1;
+            cmd[1]  =   0x30;
+            aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+            // Step 8: Rate 15 setup 3 for sniff
+            cmd[0]  =   TRIGC;
+            cmd[1]  =   0x01;
+            aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+            // Step 9: Point to value 1
+            cmd[0]  =   RATE_1;
+            cmd[1]  =   0x60;
+            aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+            // Step 10: Write value 1
+            cmd[0]  =   TRIGC;
+            switch ( myPowerMode ) {
+                case ULTRA_LOW_POWER_MODE:
+                    cmd[1]  =   0x52;
+                    break;
+
+                default:
+                case LOW_POWER_MODE:
+                    cmd[1]  =   0x72;
+                    break;
+
+                case PRECISION:
+                    cmd[1]  =   0x32;
+                    break;
+            }
+
+            aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+            // Step 11: Point to value 2
+            cmd[0]  =   RATE_1;
+            cmd[1]  =   0x70;
+            aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+        } else {
+            // Step 6: Rate 15 setup 1 for the given device mode
+            cmd[0]  =   TRIGC;
+            cmd[1]  =   0x03;
+            aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+            // Step 7: Rate 15 setup 2 for the given device mode
+            cmd[0]  =   RATE_1;
+            cmd[1]  =   0x20;
+            aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+            // Step 8: Rate 15 setup 3 for the given device mode
+            cmd[0]  =   TRIGC;
+            cmd[1]  =   0x01;
+            aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+            // Step 9: Point to value 1
+            cmd[0]  =   RATE_1;
+            cmd[1]  =   0x40;
+            aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+            // Step 10: Write value 1
+            cmd[0]  =   TRIGC;
+            switch ( myPowerMode ) {
+                case ULTRA_LOW_POWER_MODE:
+                    cmd[1]  =   0x52;
+                    break;
+
+                default:
+                case LOW_POWER_MODE:
+                    cmd[1]  =   0x72;
+                    break;
+
+                case PRECISION:
+                    cmd[1]  =   0x32;
+                    break;
+            }
+
+            aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+            // Step 11: Point to value 2
+            cmd[0]  =   RATE_1;
+            cmd[1]  =   0x50;
+            aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+        }
+
+        // Step 12: Write value 2
+        cmd[0]  =   TRIGC;
+        switch ( myPowerMode ) {
+            case ULTRA_LOW_POWER_MODE:
+                cmd[1]  =   0x01;
+                break;
+
+            default:
+            case LOW_POWER_MODE:
+                cmd[1]  =   0x02;
+                break;
+
+            case PRECISION:
+                cmd[1]  =   0x12;
+                break;
+        }
+        aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+        // Step 13: Apply the values
+        cmd[0]  =   RATE_1;
+        cmd[1]  =   0x0F;
+        aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+    } else {
+        // Get the register data
+        aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+        aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+
+        // Update the register data for the specific mode
+        if ( cmd[0] == SNIFF_C ) {
+            cmd[1] &=  ~SNIFF_C_SNIFF_SR_MASK;
+            cmd[1] |=   myODR;
+        } else {
+            cmd[1] &=  ~RATE_1_RR_MASK;
+            cmd[1] |=   myODR;
+        }
+
+        aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+    }
+
+
+    /* DEVICE MODE */
+    // Step 14: Go to the given device mode
+    cmd[0]  =   MODE_C;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+    cmd[1] &=  ~MODE_C_MCTRL_MASK;
+    cmd[1] |=   myMode;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_SetTriggerMode  ( MC3635_mode_c_trig_cmd_t , uint8_t , MC3635_sniff_c_stb_rate_t )
+ *
+ * @details     It sets the TRIGGER mode.
+ *
+ * @param[in]    myTriggerEnable:       Enable/Disable Trigger mode.
+ * @param[in]    myTriggerSamples:      Number of samples for the trigger mode.
+ * @param[in]    mySTANDBY_ClockRate:   ODR for the trigger mode.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_SetTriggerMode.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     The device MUST be in STANDBY mode, the user has to call this function
+ *              first: MC3635_SetStandbyMode.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_SetTriggerMode ( MC3635_mode_c_trig_cmd_t myTriggerEnable, uint8_t myTriggerSamples,
+                                                         MC3635_sniff_c_stb_rate_t mySTANDBY_ClockRate )
+{
+    char        cmd[] =   { 0, 0 };
+    uint32_t    aux   =   0;
+    
+
+    if ( myTriggerSamples == 0 ) {
+        return MC3635_FAILURE;
+    } else {
+        /* ODR */
+        MC3635_SetStandbyClockRate ( mySTANDBY_ClockRate );
+
+
+        /* NUMBER OF SAMPLES    */
+        cmd[0]  =   TRIGC;
+        cmd[1]  =   myTriggerSamples;
+        aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+        /* TRIGGER MODE AND ENABLE/DISABLE TRIGGER  */
+        // Get the register data
+        cmd[0]  =   MODE_C;
+        aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+        aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+        // Update the register data
+        cmd[1] &=  ~( MODE_C_MCTRL_MASK | MODE_C_TRIG_CMD_MASK );
+        cmd[1] |=   ( MODE_C_MCTRL_TRIG | myTriggerEnable );
+        aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+    }
+
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_ManualSniffReset  ( MC3635_sniffcf_c_sniff_reset_t )
+ *
+ * @details     It is a manual reset for the Sniff block.
+ *
+ * @param[in]    mySniffResetBit:   Sniff block reset.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_ManualSniffReset.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     The device MUST be in STANDBY mode, the user has to call this function
+ *              first: MC3635_SetStandbyMode.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_ManualSniffReset ( MC3635_sniffcf_c_sniff_reset_t mySniffResetBit )
+{
+    char        cmd[] =   { SNIFFCF_C, 0 };
+    uint32_t    aux   =   0;
+
+
+    // Get the register data
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+    // Update the register data
+    cmd[1] &=  ~SNIFFCF_C_SNIFF_RESET_MASK;
+    cmd[1] |=   mySniffResetBit;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_ConfSniffMode  ( MC3635_sniffcf_c_sniff_thadr_t , uint8_t , MC3635_sniffth_c_sniff_and_or_t , MC3635_sniffth_c_sniff_mode_t , MC3635_sniffcf_c_sniff_cnten_t ,
+ *                                      MC3635_sniffcf_c_sniff_mux_t )
+ *
+ * @details     It configures the parameters for the SNIFF mode.
+ *
+ * @param[in]    mySniffADR:   Sniff block reset.
+ * @param[in]    mySniffThreshold:   Sniff block reset.
+ * @param[in]    mySniffLogicalMode:   Sniff block reset.
+ * @param[in]    mySniffDeltaCount:   Sniff block reset.
+ * @param[in]    mySniffEnableDetectionCount:   Sniff block reset.
+ * @param[in]    mySniffMux:   Sniff block reset.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_ConfSniffMode.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     The device MUST be in STANDBY mode, the user has to call this function
+ *              first: MC3635_SetStandbyMode.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_ConfSniffMode ( MC3635_sniffcf_c_sniff_thadr_t mySniffADR, uint8_t mySniffThreshold, MC3635_sniffth_c_sniff_and_or_t mySniffLogicalMode,
+                                                        MC3635_sniffth_c_sniff_mode_t mySniffDeltaCount, MC3635_sniffcf_c_sniff_cnten_t mySniffEnableDetectionCount, MC3635_sniffcf_c_sniff_mux_t mySniffMux )
+{
+    char        cmd[] =   { 0, 0 };
+    uint32_t    aux   =   0;
+
+
+    /* SNIFF THRESHOLD, LOGICAL MODE and DELTA COUNT */
+    // If threshold is selected:        0 <= mySniffThreshold <= 63
+    // If detection count is selected:  0 < mySniffThreshold <= 62
+    if ( ( ( ( mySniffADR == SNIFFCF_C_SNIFF_THADR_SNIFF_THRESHOLD_X_AXIS ) || ( mySniffADR == SNIFFCF_C_SNIFF_THADR_SNIFF_THRESHOLD_Y_AXIS ) || ( mySniffADR == SNIFFCF_C_SNIFF_THADR_SNIFF_THRESHOLD_Z_AXIS ) )  && ( mySniffThreshold > 63 ) ) ||
+            ( ( ( mySniffADR == SNIFFCF_C_SNIFF_THADR_SNIFF_DETECTION_X_AXIS ) || ( mySniffADR == SNIFFCF_C_SNIFF_THADR_SNIFF_DETECTION_Y_AXIS ) || ( mySniffADR == SNIFFCF_C_SNIFF_THADR_SNIFF_DETECTION_Z_AXIS ) )  && ( ( mySniffThreshold == 0 ) || ( mySniffThreshold > 62 ) ) ) ) {
+        return   MC3635_FAILURE;
+    } else {
+        // Update the register data
+        cmd[0]  =   SNIFFTH_C;
+        cmd[1]  =   ( mySniffADR | mySniffLogicalMode | mySniffDeltaCount );
+        aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+    }
+
+    /* SNIFF THRESHOLD ADDRESS, DETECTION COUNT and MUX */
+    // Get the register data
+    cmd[0]  =   SNIFFCF_C;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+    // Update the register data
+    cmd[1] &=  ~( SNIFFCF_C_SNIFF_THADR_MASK | SNIFFCF_C_SNIFF_CNTEN_MASK | SNIFFCF_C_SNIFF_MUX_MASK );
+    cmd[1] |=   ( mySniffADR | mySniffEnableDetectionCount | mySniffMux );
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_SetResolution  ( MC3635_range_c_res_t )
+ *
+ * @details     It sets the accelerometer resolution.
+ *
+ * @param[in]    myResolution:      Resolution.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_SetResolution.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     The device MUST be in STANDBY mode, the user has to call this function
+ *              first: MC3635_SetStandbyMode.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_SetResolution ( MC3635_range_c_res_t myResolution )
+{
+    char        cmd[] =   { RANGE_C, 0 };
+    uint32_t    aux   =   0;
+
+
+    // Get the register data
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+    // Update the register data
+    cmd[1] &=  ~RANGE_C_RES_MASK;
+    cmd[1] |=   myResolution;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_GetResolution  ( MC3635_data_t* )
+ *
+ * @details     It gets the accelerometer resolution.
+ *
+ * @param[in]    myResolution:      Accelerometer Resolution.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_GetResolution.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     N/A.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_GetResolution ( MC3635_data_t* myResolution )
+{
+    char        cmd[] =   { RANGE_C, 0 };
+    uint32_t    aux   =   0;
+
+
+    // Get the register data
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+    // Parse the data
+    myResolution->resolution     =   ( MC3635_range_c_res_t )( cmd[1] & RANGE_C_RES_MASK );
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_SetRange  ( MC3635_range_c_range_t )
+ *
+ * @details     It sets the accelerometer range.
+ *
+ * @param[in]    myRange:           Range.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_SetRange.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     The device MUST be in STANDBY mode, the user has to call this function
+ *              first: MC3635_SetStandbyMode.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_SetRange ( MC3635_range_c_range_t myRange )
+{
+    char        cmd[] =   { RANGE_C, 0 };
+    uint32_t    aux   =   0;
+
+
+    // Get the register data
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+    // Update the register data
+    cmd[1] &=  ~RANGE_C_RANGE_MASK;
+    cmd[1] |=   myRange;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_GetRange  ( MC3635_data_t* )
+ *
+ * @details     It gets the accelerometer range.
+ *
+ * @param[in]    myResolution:      Accelerometer Range.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_GetRange.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     N/A.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_GetRange ( MC3635_data_t* myRange )
+{
+    char        cmd[] =   { RANGE_C, 0 };
+    uint32_t    aux   =   0;
+
+
+    // Get the register data
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+    // Parse the data
+    myRange->range     =   ( MC3635_range_c_range_t )( cmd[1] & RANGE_C_RANGE_MASK );
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_SetFIFO  ( uint8_t , MC3635_fifo_c_fifo_mode_t )
+ *
+ * @details     It sets the FIFO behavior.
+ *
+ * @param[in]    myNumberOfSamples:  Number of samples in the FIFO.
+ * @param[in]    myFIFO_Mode:        FIFO mode: Normal operation/Watermark.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_SetFIFO.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     The device MUST be in STANDBY mode, the user has to call this function
+ *              first: MC3635_SetStandbyMode.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_SetFIFO ( uint8_t myNumberOfSamples, MC3635_fifo_c_fifo_mode_t myFIFO_Mode )
+{
+    char        cmd[] =   { FIFO_C, 0 };
+    uint32_t    aux   =   0;
+
+
+    // Check FIFO number of samples
+    if ( ( myNumberOfSamples < 1 ) || ( myNumberOfSamples > 31 ) ) {
+        return   MC3635_FAILURE;
+    }
+
+    // Get the register data
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+    // Update the register data
+    cmd[1] &=  ~( FIFO_C_FIFO_TH_MASK | FIFO_C_FIFO_MODE_MASK );
+    cmd[1] |=   ( myNumberOfSamples | myFIFO_Mode );
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_EnableFIFO  ( MC3635_fifo_c_fifo_en_t )
+ *
+ * @details     It enables/disables the FIFO.
+ *
+ * @param[in]    myFIFO_Enable:      Enable/Disable FIFO.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_EnableFIFO.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     The device MUST be in STANDBY mode, the user has to call this function
+ *              first: MC3635_SetStandbyMode.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_EnableFIFO ( MC3635_fifo_c_fifo_en_t myFIFO_Enable )
+{
+    char        cmd[] =   { FIFO_C, 0 };
+    uint32_t    aux   =   0;
+
+
+    // Get the register data
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+    // Update the register data
+    cmd[1] &=  ~FIFO_C_FIFO_EN_MASK;
+    cmd[1] |=   myFIFO_Enable;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_ResetFIFO  ( void )
+ *
+ * @details     It resets the FIFO pointers.
+ *
+ * @param[in]    N/A.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_ResetFIFO.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     The device MUST be in STANDBY mode, the user has to call this function
+ *              first: MC3635_SetStandbyMode.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_ResetFIFO ( void )
+{
+    char        cmd[] =   { FIFO_C, 0 };
+    uint32_t    aux   =   0;
+
+
+    // Get the register data
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+    // Update the register data
+    cmd[1] &=  ~FIFO_C_FIFO_RESET_MASK;
+    cmd[1] |=   FIFO_C_FIFO_RESET_ENABLED;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_GetGain  ( MC3635_axis_t , MC3635_data_t* )
+ *
+ * @details     It gets the gain for a certain axis.
+ *
+ * @param[in]    myChosenAxis:       Axis gain.
+ *
+ * @param[out]   myGain:             Gain itself.
+ *
+ *
+ * @return       Status of MC3635_GetGain.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     N/A.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_GetGain ( MC3635_axis_t myChosenAxis, MC3635_data_t* myGain )
+{
+    char        cmd[]        =   { 0, 0 };
+    uint8_t     myAuxReg1, myAuxReg2;
+    uint16_t    myAuxGain    =   0;
+    uint32_t    aux          =   0;
+
+
+    /* Select the right axis  */
+    switch ( myChosenAxis ) {
+        case X_AXIS:
+            myAuxReg1        =   XOFFH;
+            myAuxReg2        =   XGAIN;
+            break;
+
+        case Y_AXIS:
+            myAuxReg1        =   YOFFH;
+            myAuxReg2        =   YGAIN;
+            break;
+
+        case Z_AXIS:
+            myAuxReg1        =   ZOFFH;
+            myAuxReg2        =   ZGAIN;
+            break;
+
+        default:
+            return   MC3635_FAILURE;
+            //break;
+    }
+
+
+    /* MSB GAIN: Get the register data */
+    cmd[0]  =   myAuxReg1;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+
+    myAuxGain   =   ( cmd[1] & XGAINH_GAIN_MASK );
+    myAuxGain <<=   1;
+
+    /* LSB GAIN: Get the register data */
+    cmd[0]  =   myAuxReg2;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+
+    myAuxGain |=   cmd[1];
+
+
+    /* Parse the data into the chosen axis  */
+    switch ( myChosenAxis ) {
+        case X_AXIS:
+            myGain->XGAIN    =   myAuxGain;
+            break;
+
+        case Y_AXIS:
+            myGain->YGAIN    =   myAuxGain;
+            break;
+
+        case Z_AXIS:
+            myGain->ZGAIN    =   myAuxGain;
+            break;
+
+        default:
+            return   MC3635_FAILURE;
+            //break;
+    }
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_GetOffset  ( MC3635_axis_t , MC3635_data_t* )
+ *
+ * @details     It gets the offset for a certain axis.
+ *
+ * @param[in]    myChosenAxis:       Axis gain.
+ *
+ * @param[out]   myOffset:           Offset itself.
+ *
+ *
+ * @return       Status of MC3635_GetOffset.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     N/A.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_GetOffset ( MC3635_axis_t myChosenAxis, MC3635_data_t* myOffset )
+{
+    char        cmd[]        =   { 0, 0 };
+    uint8_t     myAuxReg1, myAuxReg2;
+    int16_t     myAuxOffset  =   0;
+    uint32_t    aux          =   0;
+
+
+    /* Select the right axis  */
+    switch ( myChosenAxis ) {
+        case X_AXIS:
+            myAuxReg1    =   XOFFH;
+            myAuxReg2    =   XOFFL;
+            break;
+
+        case Y_AXIS:
+            myAuxReg1    =   YOFFH;
+            myAuxReg2    =   YOFFL;
+            break;
+
+        case Z_AXIS:
+            myAuxReg1    =   ZOFFH;
+            myAuxReg2    =   ZOFFL;
+            break;
+
+        default:
+            return   MC3635_FAILURE;
+            //break;
+    }
+
+
+    /* MSB OFFSET: Get the register data */
+    cmd[0]  =   myAuxReg1;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+
+    myAuxOffset   =   ( cmd[1] & XOFFH_MASK );
+    myAuxOffset <<=   8;
+
+
+    /* LSB OFFSET: Get the register data */
+    cmd[0]  =   myAuxReg2;
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+
+    myAuxOffset |=   cmd[1];
+
+
+    /* Parse the data into the chosen axis  */
+    switch ( myChosenAxis ) {
+        case X_AXIS:
+            myOffset->XOffset    =   myAuxOffset;
+            break;
+
+        case Y_AXIS:
+            myOffset->YOffset    =   myAuxOffset;
+            break;
+
+        case Z_AXIS:
+            myOffset->ZOffset    =   myAuxOffset;
+            break;
+
+        default:
+            return   MC3635_FAILURE;
+            //break;
+    }
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_Conf_INTN  ( MC3635_intr_c_ipp_t , MC3635_intr_c_iah_t )
+ *
+ * @details     It configures the interrupt pin mode and level control.
+ *
+ * @param[in]    myINTN_ModeControl:    INTN pin interrupt pin mode control.
+ * @param[in]    myINTN_LevelControl:   The active drive level of the INTN pin.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_Conf_INTN.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     The device MUST be in STANDBY mode, the user has to call this function
+ *              first: MC3635_SetStandbyMode.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_Conf_INTN ( MC3635_intr_c_ipp_t myINTN_ModeControl, MC3635_intr_c_iah_t myINTN_LevelControl )
+{
+    char        cmd[]        =   { INTR_C, 0 };
+    uint32_t    aux          =   0;
+
+
+    /* Get the register data */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+
+    /* Update the register data */
+    cmd[1] &=  ~( INTR_C_IPP_MASK | INTR_C_IAH_MASK );
+    cmd[1] |=   ( myINTN_ModeControl | myINTN_LevelControl );
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}
+
+
+
+/**
+ * @brief       MC3635_Set_INTN  ( MC3635_intr_c_int_wake_t , MC3635_intr_c_int_acq_t , MC3635_intr_c_int_fifo_empty_t , MC3635_intr_c_int_fifo_full_t ,
+ *                                 MC3635_intr_c_int_fifo_thresh_t , MC3635_intr_c_int_fifo_swake_t )
+ *
+ * @details     It activates the interrupts on INTN pin.
+ *
+ * @param[in]    myINT_WakeMode:        WAKE interrupt (SNIFF to WAKE) enable.
+ * @param[in]    myINT_ACQMode:         Interrupt on sample or acquisition enable.
+ * @param[in]    myINT_FIFO_EmptyMode:  FIFO empty interrupt enable.
+ * @param[in]    myINT_FIFO_FullMode:   FIFO full interrupt enable.
+ * @param[in]    myINT_FIFO_ThreshMode: FIFO threshold interrupt enable.
+ * @param[in]    myINT_SwakeMode:       This interrupt is valid only in SWAKE mode.
+ *
+ * @param[out]   N/A.
+ *
+ *
+ * @return       Status of MC3635_Set_INTN.
+ *
+ *
+ *
+ * @author      Manuel Caballero
+ * @date        30/May/2018
+ * @version     30/May/2018     The ORIGIN
+ * @pre         N/A.
+ * @warning     The device MUST be in STANDBY mode, the user has to call this function
+ *              first: MC3635_SetStandbyMode.
+ */
+MC3635::MC3635_status_t  MC3635::MC3635_Set_INTN ( MC3635_intr_c_int_wake_t myINT_WakeMode, MC3635_intr_c_int_acq_t myINT_ACQMode,
+                                                   MC3635_intr_c_int_fifo_empty_t myINT_FIFO_EmptyMode, MC3635_intr_c_int_fifo_full_t myINT_FIFO_FullMode,
+                                                   MC3635_intr_c_int_fifo_thresh_t myINT_FIFO_ThreshMode, MC3635_intr_c_int_fifo_swake_t myINT_SwakeMode                )
+{
+    char        cmd[]        =   { INTR_C, 0 };
+    uint32_t    aux          =   0;
+
+
+    /* Get the register data */
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], 1, true  );
+    aux     =   _i2c.read  ( _MC3635_Addr, &cmd[1], 1 );
+
+
+    /* Update the register data */
+    cmd[1] &=  ~( INTR_C_INT_WAKE_MASK | INTR_C_INT_ACQ_MASK | INTR_C_INT_FIFO_EMPTY_MASK | INTR_C_INT_FIFO_FULL_MASK | INTR_C_INT_FIFO_THRESH_MASK | INTR_C_INT_SWAKE_MASK );
+    cmd[1] |=   ( myINT_WakeMode | myINT_ACQMode | myINT_FIFO_EmptyMode | myINT_FIFO_FullMode | myINT_FIFO_ThreshMode | myINT_SwakeMode );
+    aux     =   _i2c.write ( _MC3635_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false  );
+
+
+
+    if ( aux == I2C_SUCCESS )
+        return   MC3635_SUCCESS;
+    else
+        return   MC3635_FAILURE;
+}