Triet Pham
Created October 24, 2017 © GPL3+

SensorTile Voice/Sensor-Based Smart Home Access Platform

End-to-end integrated smart home access system made possible with low-cost ST BlueVoice/sensor and NFC tag.

AdvancedFull instructions provided20 hours716

Things used in this project

Hardware components

STEVAL-STLKT01V1
STMicroelectronics STEVAL-STLKT01V1
×1
NousLogic - Watchman Smart "Plug and Play" Door Lock
×1
iPad
Apple iPad
×1
iPhone
Apple iPhone
×1
IDENTIV - ST NFC tag
×1

Software apps and online services

STMicroelectronics ST FP-SNS-ALLMEMS1 MCUS EMBEDDED SOFTWARE
NousLogic ReachMe-QR (iOS)
NousLogic ReachMe-QR (Android)
ReachMe.Me
STMicroelectronics ST BlueMS App (iOS)
STMicroelectronics FP-AUD-BVLINK1 MCUS EMBEDDED SOFTWARE

Story

Read more

Schematics

Smart Door Lock System Block Diagram (with SensorTile BlueVoice/sensor and ST NFC tag)

Code

main.c

C/C++
This is one of the files most relevant to the features we used, for the full version, go to http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-ode-function-pack-sw/fp-sns-allmems1.html
/**
  ******************************************************************************
  * @file    main.c
  * @author  Central LAB
  * @version V3.1.0
  * @date    14-July-2017
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */

/**
 * @mainpage FP-SNS-ALLMEMS1 Bluetooth Low Energy and Sensors Software
 *
 * @image html st_logo.png
 *
 * <b>Introduction</b>
 *
 * This firmware package includes Components Device Drivers, Board Support Package
 * and example application for the following STMicroelectronics elements:
 * - X-NUCLEO-IDB04A1/X-NUCLEO-IDB05A1 Bluetooth Low energy expansion boards
 * - X-NUCLEO-IKS01A1 Expansion board for four MEMS sensor devices:
 *       HTS221, LPS25H, LSM6DS0, LSM6DS3, LIS3MDL
 * - X-NUCLEO-IKS01A2 Expansion board for four MEMS sensor devices:
 *       HTS221, LPS22HB, LSM6DSL, LSM303AGR
 * - X-NUCLEO-CCA02M1 Digital MEMS microphones expansion board
 * - NUCLEO-F446RE NUCLEO-F401RE NUCLEO-L476RG Nucleo boards
 * - STEVAL-STLKT01V1 (SensorTile) evaluation board that contains the following components:
 *     - MEMS sensor devices: HTS221, LPS22HB, LSM303, LSM6DSM
 *     - digital microphone: MP34DT04
 *     - Gas Gauge IC with alarm output: STC3115
 * - STEVAL-BCNKT01V1 (BlueCoin) evaluation board that contains the following components:
 *     - MEMS sensor devices: LPS22HB, LSM303AGR, LSM6DSM
 *     - digital microphone: 4 x MP34DT04-C1
 * - The MotionFX (iNEMOEngine PRO) suite uses advanced algorithms to integrate outputs
 *   from multiple MEMS sensors in a smartway, independent of environmental conditions,
 *   to reach optimal performance. Real-time motion-sensor data fusion is set to significantly
 *   improve the user experience, increasing accuracy, resolution, stability and response time.
 * - MotionAR (iNEMOEngine PRO) software provides real-time activity recognition data using MEMS accelerometer sensor
 * - MotionCP (iNEMOEngine PRO) software provides carry Position recognition data using MEMS accelerometer sensor
 *   (feature not available on NUCLEO-F446RE, NUCLEO-F401RE and STEVAL-BCNKT01V1)
 * - MotionGR (iNEMOEngine PRO) software provides carry Gesture recognition data using MEMS accelerometer sensor 
 *   (feature not available on NUCLEO-F446RE, NUCLEO-F401RE and STEVAL-BCNKT01V1)
 * - AcousticSL software provides real-time audio source localization using PCM signal audio
 *   (feature not available on the STEVAL-STLKT01V1)
 * - AcousticBF software provides real-time beam forming software, using the audio signals acquired from two digital 
 *   MEMS microphones, it creates a virtual directional microphone pointing to a fixed direction in space 
 *   (feature not available on STEVAL-STLKT01V1 and NUCLEO-L476RG).
 * - BlueVoiceADPCM software enables real-time half-duplex voice-over-Bluetooth low energy communication profile.
 *   It includes one characteristic for audio transmission and one for synchronization and it is responsible for audio encoding and periodical data
 *   transmission on Server side and for decoding of received voice data on Client side
 * - USB device library (for only STEVAL-STLCS01V1) provides support of multi packet transfer to allow
 *   sending big amount of data without split them into max packet size transfers.
 *
 * @attention
 * <b>Important Hardware Additional Information</b><br>
 * <br>\image html X-NUCLEO-IKS01A1_HW_Info.jpg "Figure 1: X-NUCLEO-IKS01A1 expansion board"
 * <br>Before to connect X-NUCLEO-IKS01A1 with X-NUCLEO-CCA02M1 expansion board through the Arduino UNO R3 extension connector,
 * remove the 0-ohm resistors SB25, SB26 and SB27 onto X-NUCLEO-IKS01A1 board, as the above figure 1 shows.<br>
 * <br>\image html X-NUCLEO-IKS01A2_HW_Info.jpg "Figure 2: X-NUCLEO-IKS01A2 expansion board"
 * <br>Before to connect X-NUCLEO-IKS01A2 with X-NUCLEO-CCA02M1 expansion board through the Arduino UNO R3 extension connector,
 * on to X-NUCLEO-IKS01A2 board remove these 0-ohm resistor:
 * - For F4xx STM32 Nucleo motherboard remove SB25, SB26 and SB27
 * - For L4 STM32 Nucleo motherboard remove SB25 if additional microphones are plugged on to X-NUCLEO-CCA02M1 board.<br>
 * .
 * <br>\image html X-NUCLEO-CCA02M1_HW_Info.jpg "Figure 3: X-NUCLEO-CCA02M1 expansion board"
 * <br>For only L4 STM32 Nucleo motherboard, before to connect the board X-NUCLEO-CCA02M1 with the STM32 L4 Nucleo motherboard through the Morpho connector layout,
 * on to X-NUCLEO-CCA02M1 board:
 * - close the solder bridges SB12, SB16 and open the solder bridges SB7, SB15 and SB17
 * - if additional microphones are plugged, close the solder bridge SB17.<br>
 *
 * <b>Example Application</b>
 *
 * The Example application initizializes all the Components and Library creating 3 Custom Bluetooth services:
 * - The first service exposes all the HW and SW characteristics:
 *  - HW characteristics:
 *      - related to MEMS sensor devices: Temperature, Humidity, Pressure, Magnetometer, Gyroscope and Accelleromenter 
 *        and Microphones Signal Noise dB level.
 *      - battery alarm output (for only SensorTile) 
 *  - SW characteristics: the quaternions generated by the MotionFX library in short precision, the activity
 *    recognized using the MotionAR algorithm, the carry position recognized using the MotionCP algorithm (excluding STM32 Nucleo F4xx),
 *    the Gesture recognized using the MotionGR algorithm(excluding STM32 Nucleo F4xx), the audio source localization using the AcousticSL software (excluding STEVAL-STLKT01V1)
 *    that provides real-time audio source localization, AcousticBF software (Excluding STEVAL-STLKT01V1 and STM32 Nucleo L476) provides real-time beam forming
 *    using the audio signals acquired from two digital MEMS microphones.
 *    It uses BlueVoiceADPCM software for real-time half-duplex voice-over-Bluetooth low energy communication profile.
 * - The second Service exposes the console services where we have stdin/stdout and stderr capabilities
 * - The last Service is used for configuration purpose
 *
 * For NUCLEO boards the example application allows the user to control the initialization phase via UART.
 * Launch a terminal application and set the UART port to 460800 bps, 8 bit, No Parity, 1 stop bit.
 * For having the same UART functionality on SensorTile board, is necessary to recompile the code uncomment the line 87
 *	//#define ALLMEMS1_ENABLE_PRINTF
 * on file:
 *	Projects\Multi\Applications\ALLMEMS1\Inc\ALLMEMS1_config.h file
 * This enables the UART that starts with a delay of 10 Seconds for allowing the time to open the UART for looking
 * the initialization phase.
 *
 * This example must be used with the related BlueMS Android/iOS application available on Play/itune store (Version 3.5.0 or higher),
 * in order to read the sent information by Bluetooth Low Energy protocol
 *
 *                              -----------------------
 *                              | VERY IMPORTANT (1): |
 *                              -----------------------
 * 1) This example support the Firmware-Over-The-Air (FOTA) update using the BlueMS Android/iOS application (Version 3.0.0 and above)
 * The FOTA does not work when using X-NUCLEO-IDB04A1
 *
 * 2) This example must run starting at address 0x08004000 in memory and works ONLY if the BootLoader 
 * is saved at the beginning of the FLASH (address 0x08000000)
 *
 * 3) If the user presses the blue user button on Nucleo board, 3 times on less that 2 seconds,
 * he forces a new Calibration for MotionFX Library
 * The calibration value could be stored on FLASH memory or in RAM for avoiding to do the calibration at each board reset
 *
 * 4) For each IDE (IAR/Vision/System Workbench), and for each platform (NUCLEO-F446RE/NUCLEO-F401RE/NUCLEO-L476RG/SensorTile),
 * there are some scripts *.bat and *.sh that makes the following operations:
 * - Full Flash Erase
 * - Load the BootLoader on the rigth flash region
 * - Load the Program (after the compilation) on the rigth flash region (This could be used for a FOTA)
 * - Dump back one single binary that contain BootLoader+Program that could be
 *   flashed at the flash beginning (address 0x08000000) (This COULD BE NOT used for FOTA)
 * - Reset the board
 * .
 *
 *                              -----------------------
 *                              | VERY IMPORTANT (2): |
 *                              -----------------------
 * It's necessary to choose the right Target configuration during the compilation.
 * If the code is compiled for IKS01A1 could not run if it's attached the X-NUCLEO-IKS01A2 and vice versa
 *
 *
 *                                   ----------
 *                                   | ISSUE: |
 *                                   ----------
 * FOTA is not available on NUCLEO-F401RE and NUCLEO-F446RE using binary generated by System Workbench for STM32
 * (due to flash size constraints).
 *
 *                               --------------------
 *                               | KNOWN LIMITATION |
 *                               --------------------
 * - Even if FP-SNS-ALLMEMS1 send 100quaternions/second with Bluetooth, the mobile devices could render only 60frames/second
 * - FOTA does not work when using X-NUCLEO-IDB04A1
 * - For NUCLEO-F446RE/NUCLEO-F401RE board, there is an hardware conflict between the boards X-NUCLEO-IKS01A2 and the X-NUCLEO-CCA02M1.
 *   The hardware features of the LSM6DSL are disabled.
 */

/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <math.h>

//#include "stm32F4xx_hal.h"

#include <limits.h>
#include "TargetFeatures.h"
#include "main.h"
#include "OTA.h"
#include "MetaDataManager.h"
#include "sensor_service.h"
#include "bluenrg_utils.h"
#include "HWAdvanceFeatures.h"

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

#define BLUEMSYS_N_BUTTON_PRESS 3
#define BLUEMSYS_CHECK_CALIBRATION ((uint32_t)0x12345678)

/* Imported Variables -------------------------------------------------------------*/
extern uint8_t set_connectable;
extern int connected;

/* Code for MotionAR integration - Start Section */
extern MAR_output_t ActivityCode;
/* Code for MotionAR integration - End Section */

#ifdef ALLMEMS1_MOTIONCP
extern MCP_output_t CarryPositionCode;
#endif /* ALLMEMS1_MOTIONCP */

#ifdef ALLMEMS1_MOTIONGR
extern MGR_output_t GestureRecognitionCode;
#endif /* ALLMEMS1_MOTIONGR */

#ifdef STM32_SENSORTILE
  #ifdef ALLMEMS1_ENABLE_PRINTF
    extern TIM_HandleTypeDef  TimHandle;
    extern void CDC_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
  #endif /* ALLMEMS1_ENABLE_PRINTF */
#endif /* STM32_SENSORTILE */

/* Exported Variables -------------------------------------------------------------*/

float sensitivity;
/* Acc sensitivity multiply by FROM_MG_TO_G constant */
float sensitivity_Mul;

MFX_MagCal_output_t magOffset;
SensorAxes_t MAG_Offset; 

uint32_t ConnectionBleStatus  =0;

uint32_t ForceReCalibration    =0;
uint32_t FirstConnectionConfig =0;

uint8_t BufferToWrite[256];
int32_t BytesToWrite;

TIM_HandleTypeDef    TimCCHandle;
TIM_HandleTypeDef    TimEnvHandle;
TIM_HandleTypeDef    TimAudioDataHandle;

uint8_t bdaddr[6];

uint32_t uhCCR4_Val = DEFAULT_uhCCR4_Val;

uint32_t CalibrationData[30];

/* Table with All the known Meta Data */
MDM_knownGMD_t known_MetaData[]={
  {GMD_CALIBRATION,(sizeof(CalibrationData))},
  {GMD_END    ,0}/* THIS MUST BE THE LAST ONE */
};

static CRC_HandleTypeDef hcrc;

extern volatile float RMS_Ch[];
extern float DBNOISE_Value_Old_Ch[];
extern uint16_t PCM_Buffer[];

#ifdef USE_STM32F4XX_NUCLEO
extern uint16_t PDM_Buffer[];
#endif /* USE_STM32F4XX_NUCLEO */
extern volatile float RMS_Ch[];
extern float DBNOISE_Value_Old_Ch[];
extern uint16_t PCM_Buffer[];

#ifdef USE_STM32F4XX_NUCLEO
extern uint16_t PDM_Buffer[];
#endif /* USE_STM32F4XX_NUCLEO */

/* Private variables ---------------------------------------------------------*/
static volatile int ButtonPressed        =0;
static volatile int MEMSInterrupt        =0;
static volatile uint32_t HCI_ProcessEvent=0;
static volatile uint32_t SendEnv         =0;
static volatile uint32_t SendAudioLevel  =0;
static volatile uint32_t SendAccGyroMag  =0;

#ifdef STM32_SENSORTILE
static volatile uint32_t SendBatteryInfo =0;
#endif /* STM32_SENSORTILE */

/* Code for MotionFX integration - Start Section */
static volatile uint32_t Quaternion      =0;
/* Code for MotionFX integration - End Section */

/* Code for MotionAR integration - Start Section */
static volatile uint32_t UpdateMotionAR  =0;
/* Code for MotionAR integration - End Section */

#ifdef ALLMEMS1_MOTIONCP
static volatile uint32_t UpdateMotionCP  =0;
#endif /* ALLMEMS1_MOTIONCP */

#ifdef ALLMEMS1_MOTIONGR
static volatile uint32_t UpdateMotionGR  =0;
#endif /* ALLMEMS1_MOTIONGR */

#ifdef ALLMEMS1_ACOUSTIC_SOURCE_LOCALIZATION
static volatile uint32_t SendAudioSourceLocalization=0;

extern volatile int32_t SourceLocationToSend;
#endif /* ALLMEMS1_ACOUSTIC_SOURCE_LOCALIZATION */

unsigned char isCal = 0;
static uint32_t mag_time_stamp = 0;

/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);

static void Init_BlueNRG_Custom_Services(void);
static void Init_BlueNRG_Stack(void);

static unsigned char ResetCalibrationInMemory(void);

static void MX_CRC_Init(void);

static void InitTimers(void);
static void SendEnvironmentalData(void);
static void MEMSCallback(void);
static void MagCalibTest(void);
static void ReCalibration(void);
static void ButtonCallback(void);
static void SendMotionData(void);
static void SendAudioLevelData(void);

//void SW_BV_send_Callback(void);

#ifdef ALLMEMS1_ACOUSTIC_BEAM_FORMING
extern volatile uint8_t BF_toggleFlag;
#endif /* ALLMEMS1_ACOUSTIC_BEAM_FORMING */

#ifdef STM32_SENSORTILE
static void SendBatteryInfoData(void);
#endif /* STM32_SENSORTILE */

void AudioProcess_DB_Noise(void);

/* Code for MotionFX integration - Start Section */
static void ComputeQuaternions(void);
/* Code for MotionFX integration - End Section */

/* Code for MotionAR integration - Start Section */
static void ComputeMotionAR(void);
/* Code for MotionAR integration - End Section */

#ifdef ALLMEMS1_MOTIONCP
static void ComputeMotionCP(void);
#endif /* ALLMEMS1_MOTIONCP */

#ifdef ALLMEMS1_MOTIONGR
static void ComputeMotionGR(void);
#endif /* ALLMEMS1_MOTIONGR */

#ifdef ALLMEMS1_ACOUSTIC_SOURCE_LOCALIZATION
static void SendAudioSourceLocalizationData(void);
#endif /* ALLMEMS1_ACOUSTIC_SOURCE_LOCALIZATION */

uint32_t t_coin=0;

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  HAL_Init();

  /* Configure the System clock */
  SystemClock_Config();
      
#ifdef STM32_NUCLEO
  InitTargetPlatform(TARGET_NUCLEO);
#elif STM32_SENSORTILE
  InitTargetPlatform(TARGET_SENSORTILE);
#elif STM32_BLUECOIN
  InitTargetPlatform(TARGET_BLUECOIN);
  t_coin=HAL_GetTick();
  BSP_LED_On(LED2);
  HAL_Delay(800);
  BSP_LED_Off(LED2);

  /* Check if the system has resumed from IWDG reset */
  if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET)
  {
    /* Clear reset flags */
    __HAL_RCC_CLEAR_RESET_FLAGS();
  }
#endif /* STM32_NUCLEO */
  
  /* For enabling CRC clock for using motion libraries (for checking if STM32 microprocessor is used)*/
  MX_CRC_Init();
  
  /* Check the MetaDataManager */
 InitMetaDataManager((void *)&known_MetaData,MDM_DATA_TYPE_GMD,NULL); 
  
  ALLMEMS1_PRINTF("\n\t(HAL %ld.%ld.%ld_%ld)\r\n"
        "\tCompiled %s %s"

#if defined (__IAR_SYSTEMS_ICC__)
        " (IAR)\r\n"
#elif defined (__CC_ARM)
        " (KEIL)\r\n"
#elif defined (__GNUC__)
        " (openstm32)\r\n"
#endif
         "\tSend Every %4dmS %d Short precision Quaternions\r\n"
         "\tSend Every %4dmS Temperature/Humidity/Pressure\r\n"
         "\tSend Every %4dmS Acc/Gyro/Magneto\r\n"
         "\tSend Every %4dmS dB noise\r\n\n",
           HAL_GetHalVersion() >>24,
          (HAL_GetHalVersion() >>16)&0xFF,
          (HAL_GetHalVersion() >> 8)&0xFF,
           HAL_GetHalVersion()      &0xFF,
         __DATE__,__TIME__,
         QUAT_UPDATE_MUL_10MS*10,SEND_N_QUATERNIONS,
         ENV_UPDATE_MUL_100MS * 100,
         DEFAULT_uhCCR4_Val/10,
         MICS_DB_UPDATE_MUL_10MS * 10);

#ifdef ALLMEMS1_DEBUG_CONNECTION
  ALLMEMS1_PRINTF("Debug Connection         Enabled\r\n");
#endif /* ALLMEMS1_DEBUG_CONNECTION */

#ifdef ALLMEMS1_DEBUG_NOTIFY_TRAMISSION
  ALLMEMS1_PRINTF("Debug Notify Trasmission Enabled\r\n\n");
#endif /* ALLMEMS1_DEBUG_NOTIFY_TRAMISSION */

  /* Initialize the BlueNRG */
  Init_BlueNRG_Stack();

  /* Initialize the BlueNRG Custom services */
  Init_BlueNRG_Custom_Services();  

  if(TargetBoardFeatures.HWAdvanceFeatures) {
    InitHWFeatures();
  }
  
  /* Check the BootLoader Compliance */
  ALLMEMS1_PRINTF("\r\n");
  if(CheckBootLoaderCompliance()) {
    ALLMEMS1_PRINTF("BootLoader Compliant with FOTA procedure\r\n\n");
  } else {
    ALLMEMS1_PRINTF("ERROR: BootLoader NOT Compliant with FOTA procedure\r\n\n");
  }

  /* Set Accelerometer Full Scale to 2G */
  Set2GAccelerometerFullScale();

  /* Read the Acc Sensitivity */
  BSP_ACCELERO_Get_Sensitivity(TargetBoardFeatures.HandleAccSensor,&sensitivity);
  sensitivity_Mul = sensitivity * ((float) FROM_MG_TO_G);

  /* initialize timers */
  InitTimers();

  /* Infinite loop */
  while (1){
    /* Led Blinking when there is not a client connected */
    if(!connected)
    {
      if(!TargetBoardFeatures.LedStatus) {
        if(!(HAL_GetTick()&0x3FF)) {
          LedOnTargetPlatform();
        }
      } else {
        if(!(HAL_GetTick()&0x3F)) {
          LedOffTargetPlatform();
        }
      }
    }

    if(set_connectable){     
      /* Code for MotionFX integration - Start Section */
      /* Initialize MotionFX library */ 
      if(TargetBoardFeatures.MotionFXIsInitalized==0)
      {
        MotionFX_manager_init();
        MotionFX_manager_start_9X();
        /* Enable magnetometer calibration */
        MagCalibTest();
      }
      /* Code for MotionFX integration - End Section */
      
      /* Code for MotionAR integration - Start Section */ 
      /* Initialize MotionAR Library */ 
      if(TargetBoardFeatures.MotionARIsInitalized==0)
        MotionAR_manager_init();
      /* Code for MotionAR integration - End Section */
      
      #ifdef ALLMEMS1_MOTIONCP
      /* Initialize MotionCP Library */ 
      if(TargetBoardFeatures.MotionCPIsInitalized==0)
        MotionCP_manager_init();
      #endif /* ALLMEMS1_MOTIONCP */

      #ifdef ALLMEMS1_MOTIONGR
      /* Initialize MotionGR Library */
      if(TargetBoardFeatures.MotionGRIsInitalized==0)
        MotionGR_manager_init();
      #endif /* ALLMEMS1_MOTIONGR */
      
#ifdef ALLMEMS1_ACOUSTIC_SOURCE_LOCALIZATION
      /* Initialize AcousticSL Library */
      if(TargetBoardFeatures.AcousticSLIsInitalized==0)
        AcousticSL_Manager_init();
#endif /* ALLMEMS1_ACOUSTIC_SOURCE_LOCALIZATION */
      
#ifdef ALLMEMS1_ACOUSTIC_BEAM_FORMING
      /* Initialize AcousticBF Library */
        if(TargetBoardFeatures.AcousticBFIsInitalized==0){
          AcousticBF_Manager_init();
        }
#endif /* ALLMEMS1_ACOUSTIC_BEAM_FORMING */
      
      /* Code for BlueVoice integration - Start Section */
      /* Initialize BlueVoice Library */
        if(TargetBoardFeatures.AudioBVIsInitalized==0)
          AudioBV_Manager_init();
      /* Code for BlueVoice integration - End Section */

      if(NecessityToSaveMetaDataManager) {
        uint32_t Success = EraseMetaDataManager();
        if(Success) {
          SaveMetaDataManager();
        }
      }

      /* Now update the BLE advertize data and make the Board connectable */
      setConnectable();
      set_connectable = FALSE;
      
#ifdef USE_STM32F4XX_NUCLEO
        //BSP_AUDIO_IN_Record(PDM_Buffer, 0);
#endif /* USE_STM32F4XX_NUCLEO */

    }
    
    /* Handle Interrupt from MEMS */
    if(MEMSInterrupt) {
      MEMSCallback();
      MEMSInterrupt=0;
    }

    /* Handle user button */
    if(ButtonPressed) {
      ButtonCallback();
      ButtonPressed=0;       
    }

    /* Handle Re-Calibration */
    if(ForceReCalibration) {
      ForceReCalibration=0;
      ReCalibration();
    }

    /* handle BLE event */
    if(HCI_ProcessEvent) {
      HCI_ProcessEvent=0;
      HCI_Process();
    }

    /* Environmental Data */
    if(SendEnv) {
      SendEnv=0;
      SendEnvironmentalData();
    }
    
    /* Mic Data */
    if (SendAudioLevel) {
      SendAudioLevel = 0;
      SendAudioLevelData();
    }

#ifdef STM32_SENSORTILE    
    /* Battery Info Data */
    if(SendBatteryInfo) {
      SendBatteryInfo=0;
      SendBatteryInfoData();
    }
#endif /* STM32_SENSORTILE */

    /* Motion Data */
    if(SendAccGyroMag) {
      SendAccGyroMag=0;
      SendMotionData();
    }

    /* Code for MotionFX integration - Start Section */
    if(Quaternion) {
      Quaternion=0;
      ComputeQuaternions();
    }
    /* Code for MotionFX integration - End Section */

    /* Code for MotionAR integration - Start Section */
    if(UpdateMotionAR) {
      UpdateMotionAR=0;
      ComputeMotionAR();
    }
    /* Code for MotionAR integration - End Section */
    
    #ifdef ALLMEMS1_MOTIONCP
    if(UpdateMotionCP) {
      UpdateMotionCP=0;
      ComputeMotionCP();
    }
    #endif /* ALLMEMS1_MOTIONCP */

    #ifdef ALLMEMS1_MOTIONGR
    if(UpdateMotionGR) {
      UpdateMotionGR=0;
      ComputeMotionGR();
    }
    #endif /* ALLMEMS1_MOTIONGR */
    
#ifdef ALLMEMS1_ACOUSTIC_SOURCE_LOCALIZATION
    /* Audio Source Localization Data */
    if (SendAudioSourceLocalization)
    {
      SendAudioSourceLocalization = 0;
      SendAudioSourceLocalizationData();
    }
#endif /* ALLMEMS1_ACOUSTIC_SOURCE_LOCALIZATION */ 

    /* Wait for Event */
    __WFI();
  }
}

/**
  * @brief  This function sets the ACC FS to 2g
  * @param  None
  * @retval None
  */
void Set2GAccelerometerFullScale(void)
{
  /* Set Full Scale to +/-2g */
  BSP_ACCELERO_Set_FS_Value(TargetBoardFeatures.HandleAccSensor,2.0f);
  
  /* Read the Acc Sensitivity */
  BSP_ACCELERO_Get_Sensitivity(TargetBoardFeatures.HandleAccSensor,&sensitivity);
  sensitivity_Mul = sensitivity* ((float) FROM_MG_TO_G);
}

/**
  * @brief  This function dsets the ACC FS to 4g
  * @param  None
  * @retval None
  */
void Set4GAccelerometerFullScale(void)
{
  
  /* Set Full Scale to +/-4g */
  BSP_ACCELERO_Set_FS_Value(TargetBoardFeatures.HandleAccSensor,4.0f);

  /* Read the Acc Sensitivity */
  BSP_ACCELERO_Get_Sensitivity(TargetBoardFeatures.HandleAccSensor,&sensitivity);
  sensitivity_Mul = sensitivity* ((float) FROM_MG_TO_G);
}

/**
  * @brief  Output Compare callback in non blocking mode 
  * @param  htim : TIM OC handle
  * @retval None
  */
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
  uint32_t uhCapture=0;
  
  /* Code for MotionFX and MotionGR integration - Start Section */
  /* TIM1_CH1 toggling with frequency = 100Hz */
  if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
  {
    uhCapture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
    /* Set the Capture Compare Register value */
    __HAL_TIM_SET_COMPARE(&TimCCHandle, TIM_CHANNEL_1, (uhCapture + DEFAULT_uhCCR1_Val));

    /* Code for MotionFX integration - Start Section */
    if ((W2ST_CHECK_CONNECTION(W2ST_CONNECT_QUAT)) | (W2ST_CHECK_CONNECTION(W2ST_CONNECT_EC))) {
      Quaternion=1;
    }
    /* Code for MotionFX integration - End Section */

    #ifdef ALLMEMS1_MOTIONGR
    if(W2ST_CHECK_CONNECTION(W2ST_CONNECT_GR)) {
      UpdateMotionGR=1;
    }
    #endif /* ALLMEMS1_MOTIONGR */
  }
  /* Code for MotionFX and MotionGR integration - End Section */

  #ifdef ALLMEMS1_MOTIONCP
  /* TIM1_CH2 toggling with frequency = 50Hz */
  if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
  {
    uhCapture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
    /* Set the Capture Compare Register value */
    __HAL_TIM_SET_COMPARE(&TimCCHandle, TIM_CHANNEL_2, (uhCapture + DEFAULT_uhCCR2_Val));

    if(W2ST_CHECK_CONNECTION(W2ST_CONNECT_CP)) {
      UpdateMotionCP=1;
    }
  }
  #endif /* ALLMEMS1_MOTIONCP */

  /* Code for MotionAR integration - Start Section */
  /* TIM1_CH3 toggling with frequency = 16Hz */
  if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
  {
    uhCapture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3);
    /* Set the Capture Compare Register value */
    __HAL_TIM_SET_COMPARE(&TimCCHandle, TIM_CHANNEL_3, (uhCapture + DEFAULT_uhCCR3_Val));
    
    if(W2ST_CHECK_CONNECTION(W2ST_CONNECT_AR)) {
      UpdateMotionAR=1;
    }
  }
  /* Code for MotionAR integration - End Section */

  /* TIM1_CH4 toggling with frequency = 20 Hz */
  if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)
  {
     uhCapture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_4);
    /* Set the Capture Compare Register value */
    __HAL_TIM_SET_COMPARE(&TimCCHandle, TIM_CHANNEL_4, (uhCapture + uhCCR4_Val));
    SendAccGyroMag=1;
  }
}


/**
  * @brief  Period elapsed callback in non blocking mode for Environmental timer
  * @param  htim : TIM handle
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if(htim == (&TimEnvHandle)) {
    /* Environmental */
    if(W2ST_CHECK_CONNECTION(W2ST_CONNECT_ENV))
      SendEnv=1;

#ifdef STM32_SENSORTILE    
    /* Battery Info */
    if(W2ST_CHECK_CONNECTION(W2ST_CONNECT_GG_EVENT))
      SendBatteryInfo= 1;
#endif /* STM32_SENSORTILE */
    
#ifdef STM32_SENSORTILE
#ifdef ALLMEMS1_ENABLE_PRINTF
    } else if(htim == (&TimHandle)) {
      CDC_TIM_PeriodElapsedCallback(htim);
#endif /* ALLMEMS1_ENABLE_PRINTF */
#endif /* STM32_SENSORTILE */
  } else if(htim == (&TimAudioDataHandle)) {
    /* Mic Data */
    if(W2ST_CHECK_CONNECTION(W2ST_CONNECT_AUDIO_LEVEL))
      SendAudioLevel=1;
    
#ifdef ALLMEMS1_ACOUSTIC_SOURCE_LOCALIZATION    
    /* Audio Source Localization Data */
    if(W2ST_CHECK_CONNECTION(W2ST_CONNECT_SL))
      SendAudioSourceLocalization= 1;
#endif /* ALLMEMS1_ACOUSTIC_SOURCE_LOCALIZATION */
  }
}

/**
  * @brief  Callback for user button
  * @param  None
  * @retval None
  */
static void ButtonCallback(void)
{
  /* Only if connected */
  if(connected) {
    static uint32_t HowManyButtonPress=0;
    static uint32_t tickstart=0;
    uint32_t tickstop;

    if(!tickstart)
      tickstart = HAL_GetTick();

    tickstop = HAL_GetTick();

    if((tickstop-tickstart)>2000) {
      HowManyButtonPress=0;
      tickstart=tickstop;
    }

    if(TargetBoardFeatures.MotionFXIsInitalized)
    {
      if((HowManyButtonPress+1)==BLUEMSYS_N_BUTTON_PRESS)
      {
        ForceReCalibration=1;
        HowManyButtonPress=0;
      }
      else
      {
        HowManyButtonPress++;
        if(W2ST_CHECK_CONNECTION(W2ST_CONNECT_STD_TERM))
        {
           BytesToWrite = sprintf((char *)BufferToWrite, "%ld in %ldmS Reset Calib\r\n",3-HowManyButtonPress,2000-(tickstop-tickstart));
           Term_Update(BufferToWrite,BytesToWrite);
        }
        else
        {
          ALLMEMS1_PRINTF("%ld in %ldmS Reset Calib\r\n",3-HowManyButtonPress,2000-(tickstop-tickstart));
        }
      }
    }
    else
    {
      ALLMEMS1_PRINTF("UserButton Pressed\r\n");
    }
  }
}

/**
  * @brief  Reset the magneto calibration 
  * @param  None
  * @retval None
  */
static void ReCalibration(void)
{
  /* Only if connected */
  if(connected) {
    /* Reset the Compass Calibration */
    isCal=0;
    MFX_MagCal_output_t mag_cal_test;

    /* Notifications of Compass Calibration */
    Config_Notify(FEATURE_MASK_SENSORFUSION_SHORT,W2ST_COMMAND_CAL_STATUS,isCal ? 100: 0);
    Config_Notify(FEATURE_MASK_ECOMPASS,W2ST_COMMAND_CAL_STATUS,isCal ? 100: 0);

    /* Reset the Calibration */
    if(W2ST_CHECK_CONNECTION(W2ST_CONNECT_STD_TERM)) {
       BytesToWrite = sprintf((char *)BufferToWrite, "\nForce ReCalibration\n\r");
       Term_Update(BufferToWrite,BytesToWrite);
    } else
      ALLMEMS1_PRINTF("\nForce ReCalibration\n\r");
    {
       ResetCalibrationInMemory();
    }

    /* Enable magnetometer calibration */
    MotionFX_manager_MagCal_start(SAMPLE_PERIOD);
    MotionFX_MagCal_getParams(&mag_cal_test);

    /* Switch off the LED */    
    LedOffTargetPlatform();
  }
}

/**
  * @brief  Send Notification where there is a interrupt from MEMS
  * @param  None
  * @retval None
  */
static void MEMSCallback(void)
{
  uint8_t stat = 0;

  if(W2ST_CHECK_HW_FEATURE(W2ST_HWF_FREE_FALL)) {
    /* Check if the interrupt is due to Free Fall */
    BSP_ACCELERO_Get_Free_Fall_Detection_Status_Ext(TargetBoardFeatures.HandleAccSensor,&stat);
    if(stat) {
      AccEvent_Notify(ACC_FREE_FALL);
    }
  }

  if(W2ST_CHECK_HW_FEATURE(W2ST_HWF_DOUBLE_TAP)) {
    /* Check if the interrupt is due to Double Tap */
    BSP_ACCELERO_Get_Double_Tap_Detection_Status_Ext(TargetBoardFeatures.HandleAccSensor,&stat);
    if(stat) {
      AccEvent_Notify(ACC_DOUBLE_TAP);
    }
  }

  if(W2ST_CHECK_HW_FEATURE(W2ST_HWF_SINGLE_TAP)) {
    /* Check if the interrupt is due to Single Tap */
    BSP_ACCELERO_Get_Single_Tap_Detection_Status_Ext(TargetBoardFeatures.HandleAccSensor,&stat);
    if(stat) {
      AccEvent_Notify(ACC_SINGLE_TAP);
    }
  }

  if(W2ST_CHECK_HW_FEATURE(W2ST_HWF_WAKE_UP)) {
    /* Check if the interrupt is due to Wake Up */
    BSP_ACCELERO_Get_Wake_Up_Detection_Status_Ext(TargetBoardFeatures.HandleAccSensor,&stat);
    if(stat) {
      AccEvent_Notify(ACC_WAKE_UP);
    }
  }

  if(W2ST_CHECK_HW_FEATURE(W2ST_HWF_TILT)) {
    /* Check if the interrupt is due to Tilt */
    BSP_ACCELERO_Get_Tilt_Detection_Status_Ext(TargetBoardFeatures.HandleAccSensor,&stat);
    if(stat) {
      AccEvent_Notify(ACC_TILT);
    }
  }

  if(W2ST_CHECK_HW_FEATURE(W2ST_HWF_6DORIENTATION)) {
    /* Check if the interrupt is due to 6D Orientation */
    BSP_ACCELERO_Get_6D_Orientation_Status_Ext(TargetBoardFeatures.HandleAccSensor,&stat);
    if(stat) {
      AccEventType Orientation = GetHWOrientation6D();
      AccEvent_Notify(Orientation);
    }
  }

  if(W2ST_CHECK_HW_FEATURE(W2ST_HWF_PEDOMETER)) {
    /* Check if the interrupt is due to Pedometer */
    BSP_ACCELERO_Get_Pedometer_Status_Ext(TargetBoardFeatures.HandleAccSensor,&stat);
    if(stat) {
      uint16_t StepCount = GetStepHWPedometer();
      AccEvent_Notify(StepCount);
    }
  }
}

/**
  * @brief  Send Motion Data Acc/Mag/Gyro to BLE
  * @param  None
  * @retval None
  */
static void SendMotionData(void)
{
  SensorAxes_t ACC_Value;
  SensorAxes_t GYR_Value;
  SensorAxes_t MAG_Value;

  /* Read the Acc values */
  BSP_ACCELERO_Get_Axes(TargetBoardFeatures.HandleAccSensor,&ACC_Value);

  /* Read the Magneto values */
  BSP_MAGNETO_Get_Axes(TargetBoardFeatures.HandleMagSensor,&MAG_Value);

  /* Read the Gyro values */
  BSP_GYRO_Get_Axes(TargetBoardFeatures.HandleGyroSensor,&GYR_Value);
  
  AccGyroMag_Update(&ACC_Value,&GYR_Value,&MAG_Value);
}

/* Code for MotionFX integration - Star Section */
/* @brief  MotionFX Working function
 * @param  None
 * @retval None
 */
static void ComputeQuaternions(void)
{
  static SensorAxes_t quat_axes[SEND_N_QUATERNIONS];
  
  static int32_t calibIndex =0;
  static int32_t CounterFX  =0;
  static int32_t CounterEC  =0;
  
  SensorAxesRaw_t ACC_Value_Raw;
  SensorAxes_t GYR_Value;
  SensorAxes_t MAG_Value;

  MFX_MagCal_input_t mag_data_in;

  /* Increment the Counter */
  if(W2ST_CHECK_CONNECTION(W2ST_CONNECT_EC)) {
    CounterEC++;
  } else {
    CounterFX++;
  }

  /* Read the Acc RAW values */
  BSP_ACCELERO_Get_AxesRaw(TargetBoardFeatures.HandleAccSensor,&ACC_Value_Raw);

  /* Read the Magneto values */
  BSP_MAGNETO_Get_Axes(TargetBoardFeatures.HandleMagSensor,&MAG_Value);

  /* Read the Gyro values */
  BSP_GYRO_Get_Axes(TargetBoardFeatures.HandleGyroSensor,&GYR_Value);
      
  /* Check if is calibrated */
  if(isCal!=0x01){
    /* Run Compass Calibration @ 25Hz */
    calibIndex++;
    if (calibIndex == 4){
      calibIndex = 0;

      mag_data_in.mag[0]= MAG_Value.AXIS_X * FROM_MGAUSS_TO_UT50;
      mag_data_in.mag[1]= MAG_Value.AXIS_Y * FROM_MGAUSS_TO_UT50;
      mag_data_in.mag[2]= MAG_Value.AXIS_Z * FROM_MGAUSS_TO_UT50;
      mag_data_in.time_stamp = mag_time_stamp;
      mag_time_stamp += SAMPLE_PERIOD;
      MotionFX_manager_MagCal_run(&mag_data_in, &magOffset);
      
      /* Control the calibration status */
      if( (magOffset.cal_quality == MFX_MAGCALOK) ||
          (magOffset.cal_quality == MFX_MAGCALGOOD) )
      {
        isCal= 1;
        
        MAG_Offset.AXIS_X= (int32_t)(magOffset.hi_bias[0] * FROM_UT50_TO_MGAUSS);
        MAG_Offset.AXIS_Y= (int32_t)(magOffset.hi_bias[1] * FROM_UT50_TO_MGAUSS);
...

This file has been truncated, please download it to see its full contents.

AudioBV_Manager.c

C/C++
This is one of the files most relevant to the features we used, for the full version, go to http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-ode-function-pack-sw/fp-sns-allmems1.html
/**
 ******************************************************************************
 * @file    AudioBV_Manager.c
 * @author  Central LAB
 * @version V3.1.0
 * @date    14-July-2017
 * @brief   This file includes BlueVoice interface functions
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *   1. Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright notice,
 *      this list of conditions and the following disclaimer in the documentation
 *      and/or other materials provided with the distribution.
 *   3. Neither the name of STMicroelectronics nor the names of its contributors
 *      may be used to endorse or promote products derived from this software
 *      without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "TargetFeatures.h"
//#include "stm32F4xx_hal.h"

/* Code for BlueVoice integration - Start Section */

/* Imported Variables -------------------------------------------------------------*/
extern uint16_t PCM_Buffer[];
extern BV_ADPCM_ProfileHandle_t BLUEVOICE_tx_handle;

#ifdef ALLMEMS1_ACOUSTIC_BEAM_FORMING
extern volatile uint8_t BF_toggleFlag;
#endif /* ALLMEMS1_ACOUSTIC_BEAM_FORMING */

/* Private Variables -------------------------------------------------------------*/
static uint32_t led_toggle_count = 0; /*!< Variable used to handle led toggling.*/
BV_ADPCM_Config_t BLUEVOICE_Config;
BV_ADPCM_Status bvStat;

extern volatile uint16_t BFOUT[];
volatile int32_t BF_dir;

/* Code for BlueVoice integration - Start Section */
static uint16_t num_byte_sent = 0;
/* Code for BlueVoice integration - End Section */

//#if defined(STM32F401xE) || defined(STM32_BLUECOIN)  
void SW_Task3_Start(void);
//#endif

/* Private Defines -------------------------------------------------------------*/
#define LED_TOGGLE_STREAMING  100


/**
* @brief  Initialises BlueVoice manager
* @param  None
* @retval None
*/
void AudioBV_Manager_init(void)
{
  BluevoiceADPCM_Initialize();
  
#ifdef STM32_NUCLEO
  BLUEVOICE_Config.sampling_frequency = FR_8000;
  BLUEVOICE_Config.channel_in = 1;
  BLUEVOICE_Config.channel_tot = 2;
  bvStat = BluevoiceADPCM_SetConfig(&BLUEVOICE_Config);
  if (bvStat != BV_ADPCM_SUCCESS) {
    goto fail;
  }
  HAL_NVIC_SetPriority((IRQn_Type)EXTI3_IRQn, 0x07, 0); 
  HAL_NVIC_EnableIRQ((IRQn_Type)EXTI3_IRQn); 
  
#endif /* STM32_NUCLEO */
  
#ifdef STM32_SENSORTILE
  BLUEVOICE_Config.sampling_frequency = FR_8000;
  BLUEVOICE_Config.channel_in = 1;
  BLUEVOICE_Config.channel_tot = 1;
  bvStat = BluevoiceADPCM_SetConfig(&BLUEVOICE_Config);
  if (bvStat != BV_ADPCM_SUCCESS) {
    goto fail;
  }
  HAL_NVIC_SetPriority((IRQn_Type)EXTI3_IRQn, 0x07, 0); 
  HAL_NVIC_EnableIRQ((IRQn_Type)EXTI3_IRQn); 
#endif /* STM32_SENSORTILE */

#ifdef STM32_BLUECOIN
  BLUEVOICE_Config.sampling_frequency = FR_8000;
  BLUEVOICE_Config.channel_in = 1;
  BLUEVOICE_Config.channel_tot = 4;
  bvStat = BluevoiceADPCM_SetConfig(&BLUEVOICE_Config);
  if (bvStat != BV_ADPCM_SUCCESS) {
    goto fail;
  }
  HAL_NVIC_SetPriority((IRQn_Type)EXTI3_IRQn, 0x07, 0); 
  HAL_NVIC_EnableIRQ((IRQn_Type)EXTI3_IRQn); 
#endif /* STM32_BLUECOIN */
  
  bvStat = BluevoiceADPCM_SetTxHandle(&BLUEVOICE_tx_handle);
  if (bvStat != BV_ADPCM_SUCCESS) {
    goto fail;
  }
  
  /* If everything is ok */
  TargetBoardFeatures.AudioBVIsInitalized=1;
  ALLMEMS1_PRINTF("Initialized ST BlueVoiceADPCM v2.0.0\r\n");

  return;
  
  fail:
    while(1){}
}

/**
* @brief  User function that is called when the PCM_Buffer is full and ready to send.
* @param  none
* @retval None
*/
void AudioProcess_BV(void)
{
  BV_ADPCM_Status status;
  
#ifdef ALLMEMS1_ACOUSTIC_BEAM_FORMING
  if(BF_toggleFlag==TRUE){
    AudioProcess_BF(BF_dir);
  }
#endif /* ALLMEMS1_ACOUSTIC_BEAM_FORMING */

 
  if (BluevoiceADPCM_IsProfileConfigured())
  {
#ifdef ALLMEMS1_ACOUSTIC_BEAM_FORMING
    if(BF_toggleFlag==TRUE)
    {
      status = BluevoiceADPCM_AudioIn( (uint16_t*)/*BF_Buffer*/BFOUT, BV_PCM_AUDIO_IN_SAMPLES);
    }
    else
#endif /* ALLMEMS1_ACOUSTIC_BEAM_FORMING */
    {
      status = BluevoiceADPCM_AudioIn( (uint16_t*)PCM_Buffer, BV_PCM_AUDIO_IN_SAMPLES); 
    }

#ifdef ALLMEMS1_ACOUSTIC_BEAM_FORMING    
    if(BF_toggleFlag==FALSE)
#endif /* ALLMEMS1_ACOUSTIC_BEAM_FORMING */
    {
      if (led_toggle_count++ >= LED_TOGGLE_STREAMING) 
      {
        led_toggle_count = 0;
        LedToggleTargetPlatform();
      }
    }
    
    if(status==BV_ADPCM_OUT_BUF_READY) {
      SW_Task3_Start();
    }
  }
  
}

#if (defined(STM32F401xE) || defined(STM32F446xx))
/**
* @brief 
* @param None
* @retval None
*/
void BV_SetInForBF(void)
{
  BLUEVOICE_Config.channel_tot = 4;

  while(BluevoiceADPCM_SetConfig(&BLUEVOICE_Config) != BV_ADPCM_SUCCESS);
}

/**
* @brief 
* @param None
* @retval None
*/
void BV_SetOutForBF(void)
{
  BLUEVOICE_Config.channel_tot = 2;
    
  while(BluevoiceADPCM_SetConfig(&BLUEVOICE_Config) != BV_ADPCM_SUCCESS);
}
#endif /* (defined(STM32F401xE) || defined(STM32F446xx)) */



/**
* @brief Throws Highest priority interrupt
* @param None
* @retval None
*/
void SW_Task3_Start(void)
{ 
  HAL_NVIC_SetPendingIRQ(EXTI3_IRQn); 
}

void SW_BV_send_Callback(void)
{
            
  BluevoiceADPCM_SendData(&num_byte_sent);
}

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

HWAdvanceFeatures.c

C/C++
This is one of the files most relevant to the features we used, for the full version, go to http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-ode-function-pack-sw/fp-sns-allmems1.html
/**
  ******************************************************************************
  * @file    HWAdvanceFeatures.c
  * @author  Central LAB
  * @version V3.1.0
  * @date    14-July-2017
  * @brief   DS3/DSM HW Advance Features API
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */

#include <stdio.h>
#include "HWAdvanceFeatures.h"
#include "TargetFeatures.h"

#ifdef STM32_SENSORTILE
  #define INT_PIN INT2_PIN
#else
  #define INT_PIN INT1_PIN
#endif

/* Exported variables ---------------------------------------------------------*/
uint32_t HWAdvanceFeaturesStatus=0;

/* Imported Variables -------------------------------------------------------------*/
static float DefaultAccODR;

/**
  * @brief  This function Reads the default Acceleration Output Data Rate
  * @param  None
  * @retval None
  */
void InitHWFeatures(void){
   /* Read the Default Output Data Rate for Accelerometer */
  BSP_ACCELERO_Get_ODR(TargetBoardFeatures.HandleAccSensor,&DefaultAccODR);
}

/**
  * @brief  This function disables all the HW's Features
  * @param  None
  * @retval None
  */
void DisableHWFeatures(void)
{
  if(W2ST_CHECK_HW_FEATURE(W2ST_HWF_PEDOMETER)) {
    DisableHWPedometer();
  }
  
  if(W2ST_CHECK_HW_FEATURE(W2ST_HWF_FREE_FALL)) {
    DisableHWFreeFall();
  }
  
  if(W2ST_CHECK_HW_FEATURE(W2ST_HWF_DOUBLE_TAP)) {
    DisableHWDoubleTap();
  }
  
  if(W2ST_CHECK_HW_FEATURE(W2ST_HWF_SINGLE_TAP)) {
    DisableHWSingleTap();
  }
  
  if(W2ST_CHECK_HW_FEATURE(W2ST_HWF_WAKE_UP)) {
    DisableHWWakeUp();
  }
  
  if(W2ST_CHECK_HW_FEATURE(W2ST_HWF_TILT)) {
    DisableHWTilt();
  }
  
  if(W2ST_CHECK_HW_FEATURE(W2ST_HWF_6DORIENTATION)) {
    DisableHWOrientation6D();
  }
}



/**
  * @brief  This function enables the HW's 6D Orientation
  * @param  None
  * @retval None
  */
void EnableHWOrientation6D(void)
{
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    /* Disable all the HW features before */
    DisableHWFeatures();

    /* Enable Free Fall detection */
    if(BSP_ACCELERO_Enable_6D_Orientation_Ext(TargetBoardFeatures.HandleAccSensor,INT_PIN)==COMPONENT_ERROR) {
      ALLMEMS1_PRINTF("Error Enabling 6D Orientation\r\n");
    } else {
      ALLMEMS1_PRINTF("Enabled 6D Orientation\r\n");
      W2ST_ON_HW_FEATURE(W2ST_HWF_6DORIENTATION);
    }
  }
}

/**
  * @brief  This function disables the HW's 6D Orientation
  * @param  None
  * @retval None
  */
void DisableHWOrientation6D(void)
{
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    /* Disable Free Fall detection */
    if(BSP_ACCELERO_Disable_6D_Orientation_Ext(TargetBoardFeatures.HandleAccSensor)==COMPONENT_ERROR) {
      ALLMEMS1_PRINTF("Error Disabling 6D Orientation\r\n");
    } else {
      ALLMEMS1_PRINTF("Disabled 6D Orientation\r\n");
      W2ST_OFF_HW_FEATURE(W2ST_HWF_6DORIENTATION);
    }

    /* Set the Output Data Rate to Default value */
    BSP_ACCELERO_Set_ODR_Value(TargetBoardFeatures.HandleAccSensor,DefaultAccODR);
  }
}

/**
  * @brief  This function eturns the HW's 6D Orientation result
  * @param  None
  * @retval AccEventType 6D Orientation Found
  */
AccEventType GetHWOrientation6D(void)
{  
  AccEventType OrientationResult = ACC_NOT_USED;
  
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    uint8_t xl = 0;
    uint8_t xh = 0;
    uint8_t yl = 0;
    uint8_t yh = 0;
    uint8_t zl = 0;
    uint8_t zh = 0;
    
    if ( BSP_ACCELERO_Get_6D_Orientation_XL_Ext( TargetBoardFeatures.HandleAccSensor, &xl ) == COMPONENT_ERROR ){
      ALLMEMS1_PRINTF("Error getting 6D orientation XL axis from LSM6DS3\r\n");
    }

    if ( BSP_ACCELERO_Get_6D_Orientation_XH_Ext( TargetBoardFeatures.HandleAccSensor, &xh ) == COMPONENT_ERROR ){
      ALLMEMS1_PRINTF("Error getting 6D orientation XH axis from LSM6DS3\r\n");
    }

    if ( BSP_ACCELERO_Get_6D_Orientation_YL_Ext( TargetBoardFeatures.HandleAccSensor, &yl ) == COMPONENT_ERROR ){
      ALLMEMS1_PRINTF("Error getting 6D orientation YL axis from LSM6DS3\r\n");
    }

    if ( BSP_ACCELERO_Get_6D_Orientation_YH_Ext( TargetBoardFeatures.HandleAccSensor, &yh ) == COMPONENT_ERROR ){
      ALLMEMS1_PRINTF("Error getting 6D orientation YH axis from LSM6DS3\r\n");
    }

    if ( BSP_ACCELERO_Get_6D_Orientation_ZL_Ext( TargetBoardFeatures.HandleAccSensor, &zl ) == COMPONENT_ERROR ){
      ALLMEMS1_PRINTF("Error getting 6D orientation ZL axis from LSM6DS3\r\n");
    }

    if ( BSP_ACCELERO_Get_6D_Orientation_ZH_Ext( TargetBoardFeatures.HandleAccSensor, &zh ) == COMPONENT_ERROR ){
      ALLMEMS1_PRINTF("Error getting 6D orientation ZH axis from LSM6DS3\r\n");
    }
    
    if ( xl == 0 && yl == 0 && zl == 0 && xh == 0 && yh == 1 && zh == 0 ) {
      OrientationResult = ACC_6D_OR_RIGTH;
    } else if ( xl == 1 && yl == 0 && zl == 0 && xh == 0 && yh == 0 && zh == 0 ) {
      OrientationResult = ACC_6D_OR_TOP;
    } else if ( xl == 0 && yl == 0 && zl == 0 && xh == 1 && yh == 0 && zh == 0 ) {
      OrientationResult = ACC_6D_OR_BOTTOM;
    } else if ( xl == 0 && yl == 1 && zl == 0 && xh == 0 && yh == 0 && zh == 0 ) {
      OrientationResult = ACC_6D_OR_LEFT;
    } else if ( xl == 0 && yl == 0 && zl == 0 && xh == 0 && yh == 0 && zh == 1 ) {
      OrientationResult = ACC_6D_OR_UP;
    } else if ( xl == 0 && yl == 0 && zl == 1 && xh == 0 && yh == 0 && zh == 0 ){
      OrientationResult = ACC_6D_OR_DOWN;
    } else {
      ALLMEMS1_PRINTF("None of the 6D orientation axes is set in LSM6DS3\r\n");
    }
  }
  return OrientationResult;
}
/**
  * @brief  This function enables the HW's Tilt Detection
  * @param  None
  * @retval None
  */
void EnableHWTilt(void)
{
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    /* Disable all the HW features before */
    DisableHWFeatures();

    /* Enable Tilt detection */
    if(BSP_ACCELERO_Enable_Tilt_Detection_Ext(TargetBoardFeatures.HandleAccSensor,INT_PIN)==COMPONENT_ERROR) {
      ALLMEMS1_PRINTF("Error Enabling Tilt Detection\r\n");
    } else {
      ALLMEMS1_PRINTF("Enabled Tilt\r\n");
      W2ST_ON_HW_FEATURE(W2ST_HWF_TILT);
    }
  }
}

/**
  * @brief  This function disables the HW's Tilt Detection
  * @param  None
  * @retval None
  */
void DisableHWTilt(void)
{
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    /* Disable Tilt detection */
    if(BSP_ACCELERO_Disable_Tilt_Detection_Ext(TargetBoardFeatures.HandleAccSensor)==COMPONENT_ERROR) {
      ALLMEMS1_PRINTF("Error Disabling Tilt Detection\r\n");
    } else {
      ALLMEMS1_PRINTF("Disabled Tilt\r\n");
      W2ST_OFF_HW_FEATURE(W2ST_HWF_TILT);
    }

    /* Set the Output Data Rate to Default value */
    BSP_ACCELERO_Set_ODR_Value(TargetBoardFeatures.HandleAccSensor,DefaultAccODR);
  }
}


/**
  * @brief  This function enables the HW's Wake Up Detection
  * @param  None
  * @retval None
  */
void EnableHWWakeUp(void)
{
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    /* Disable all the HW features before */
    DisableHWFeatures();

    /* Enable Wake up detection */
    if(BSP_ACCELERO_Enable_Wake_Up_Detection_Ext(TargetBoardFeatures.HandleAccSensor,INT_PIN)==COMPONENT_ERROR) {
      ALLMEMS1_PRINTF("Error Enabling Wake Up Detection\r\n");
    } else {
      ALLMEMS1_PRINTF("Enabled Wake Up\r\n");
      W2ST_ON_HW_FEATURE(W2ST_HWF_WAKE_UP);
    }
  }
}

/**
  * @brief  This function disables the HW's Wake Up Detection
  * @param  None
  * @retval None
  */
void DisableHWWakeUp(void)
{
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    /* Disable Wake up detection */
    if(BSP_ACCELERO_Disable_Wake_Up_Detection_Ext(TargetBoardFeatures.HandleAccSensor)==COMPONENT_ERROR) {
      ALLMEMS1_PRINTF("Error Disabling Wake Up Detection\r\n");
    } else {
      ALLMEMS1_PRINTF("Disabled Wake Up\r\n");
      W2ST_OFF_HW_FEATURE(W2ST_HWF_WAKE_UP);
    }

    /* Set the Output Data Rate to Default value */
    BSP_ACCELERO_Set_ODR_Value(TargetBoardFeatures.HandleAccSensor,DefaultAccODR);
  }
}

/**
  * @brief  This function enables the HW's Free Fall Detection
  * @param  None
  * @retval None
  */
void EnableHWFreeFall(void)
{
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    /* Disable all the HW features before */
    DisableHWFeatures();

    /* Enable Free Fall detection */
    if(BSP_ACCELERO_Enable_Free_Fall_Detection_Ext(TargetBoardFeatures.HandleAccSensor,INT_PIN)==COMPONENT_ERROR) {
      ALLMEMS1_PRINTF("Error Enabling Free Fall Detection\r\n");
    } else {
      ALLMEMS1_PRINTF("Enabled Free Fall\r\n");
      W2ST_ON_HW_FEATURE(W2ST_HWF_FREE_FALL);
    }
    
#ifdef STM32_NUCLEO
  #ifdef IKS01A1
    if(BSP_ACCELERO_Set_Free_Fall_Threshold_Ext(TargetBoardFeatures.HandleAccSensor,LSM6DS3_ACC_GYRO_FF_THS_10)==COMPONENT_ERROR) {
  #elif IKS01A2
    if(BSP_ACCELERO_Set_Free_Fall_Threshold_Ext(TargetBoardFeatures.HandleAccSensor,LSM6DSL_ACC_GYRO_FF_THS_250mg)==COMPONENT_ERROR) {
  #endif /* IKS01A1 */
#elif STM32_SENSORTILE
    if(BSP_ACCELERO_Set_Free_Fall_Threshold_Ext(TargetBoardFeatures.HandleAccSensor,LSM6DSM_ACC_GYRO_FF_THS_219mg)==COMPONENT_ERROR) {
#elif STM32_BLUECOIN
    if(BSP_ACCELERO_Set_Free_Fall_Threshold_Ext(TargetBoardFeatures.HandleAccSensor,LSM6DSM_ACC_GYRO_FF_THS_219mg)==COMPONENT_ERROR) {      
#endif /* STM32_NUCLEO */
      ALLMEMS1_PRINTF("Error setting Free Fall Treshold\r\n");
    }
  }
}

/**
  * @brief  This function disables the HW's Free Fall Detection
  * @param  None
  * @retval None
  */
void DisableHWFreeFall(void)
{
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    /* Disable Free Fall detection */
    if(BSP_ACCELERO_Disable_Free_Fall_Detection_Ext(TargetBoardFeatures.HandleAccSensor)==COMPONENT_ERROR) {
      ALLMEMS1_PRINTF("Error Disabling Free Fall Detection\r\n");
    } else {
      ALLMEMS1_PRINTF("Disabled Free Fall\r\n");
      W2ST_OFF_HW_FEATURE(W2ST_HWF_FREE_FALL);
    }

    /* Set the Output Data Rate to Default value */
    BSP_ACCELERO_Set_ODR_Value(TargetBoardFeatures.HandleAccSensor,DefaultAccODR);
  }
}

/**
  * @brief  This function enables the HW's Double Tap Detection
  * @param  None
  * @retval None
  */
void EnableHWDoubleTap(void)
{
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    /* Disable all the HW features before */
    DisableHWFeatures();

    /* Enable Double Tap detection */
    if(BSP_ACCELERO_Enable_Double_Tap_Detection_Ext(TargetBoardFeatures.HandleAccSensor,INT_PIN)==COMPONENT_ERROR) {
      ALLMEMS1_PRINTF("Error Enabling Double Tap Detection\r\n");
    } else {
      ALLMEMS1_PRINTF("Enabled Double Tap\r\n");
      W2ST_ON_HW_FEATURE(W2ST_HWF_DOUBLE_TAP);
    }
    
#ifdef STM32_NUCLEO
  #ifdef IKS01A1
    if(BSP_ACCELERO_Set_Tap_Threshold_Ext(TargetBoardFeatures.HandleAccSensor,LSM6DS3_TAP_THRESHOLD_MID)==COMPONENT_ERROR) {
  #elif IKS01A2
    if(BSP_ACCELERO_Set_Tap_Threshold_Ext(TargetBoardFeatures.HandleAccSensor,LSM6DSL_TAP_THRESHOLD_MID)==COMPONENT_ERROR) {
  #endif /* IKS01A1 */
#elif STM32_SENSORTILE
    if(BSP_ACCELERO_Set_Tap_Threshold_Ext(TargetBoardFeatures.HandleAccSensor,LSM6DSM_TAP_THRESHOLD_MID)==COMPONENT_ERROR) {
#elif STM32_BLUECOIN
    if(BSP_ACCELERO_Set_Tap_Threshold_Ext(TargetBoardFeatures.HandleAccSensor,LSM6DSM_TAP_THRESHOLD_MID)==COMPONENT_ERROR) {      
#endif /* STM32_NUCLEO */
      ALLMEMS1_PRINTF("Error setting Double Tap Treshold\r\n");
    }
  }
}

/**
  * @brief  This function disables the HW's Double Tap Detection
  * @param  None
  * @retval None
  */
void DisableHWDoubleTap(void)
{
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    /* Disable Double Tap detection */
    if(BSP_ACCELERO_Disable_Double_Tap_Detection_Ext(TargetBoardFeatures.HandleAccSensor)==COMPONENT_ERROR) {
      ALLMEMS1_PRINTF("Error Disabling Double Tap Detection\r\n");
    } else {
      ALLMEMS1_PRINTF("Disabled Double Tap\r\n");
      W2ST_OFF_HW_FEATURE(W2ST_HWF_DOUBLE_TAP);
    }

    /* Set the Output Data Rate to Default value */
    BSP_ACCELERO_Set_ODR_Value(TargetBoardFeatures.HandleAccSensor,DefaultAccODR);
  }
}

/**
  * @brief  This function enables the HW's Single Tap Detection
  * @param  None
  * @retval None
  */
void EnableHWSingleTap(void)
{
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    /* Disable all the HW features before */
    DisableHWFeatures();

    /* Enable Single Tap detection */
    if(BSP_ACCELERO_Enable_Single_Tap_Detection_Ext(TargetBoardFeatures.HandleAccSensor,INT_PIN)==COMPONENT_ERROR) {
      ALLMEMS1_PRINTF("Error Enabling Single Tap Detection\r\n");
    } else {
      ALLMEMS1_PRINTF("Enabled Sigle Tap\r\n");
      W2ST_ON_HW_FEATURE(W2ST_HWF_SINGLE_TAP);
    }
  }
}

/**
  * @brief  This function disables the HW's Single Tap Detection
  * @param  None
  * @retval None
  */
void DisableHWSingleTap(void)
{
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    /* Disable Single Tap detection */
    if(BSP_ACCELERO_Disable_Single_Tap_Detection_Ext(TargetBoardFeatures.HandleAccSensor)==COMPONENT_ERROR) {
      ALLMEMS1_PRINTF("Error Disabling Single Tap Detection\r\n");
    } else {
      ALLMEMS1_PRINTF("Disabled Sigle Tap\r\n");
      W2ST_OFF_HW_FEATURE(W2ST_HWF_SINGLE_TAP);
    }

    /* Set the Output Data Rate to Default value */
    BSP_ACCELERO_Set_ODR_Value(TargetBoardFeatures.HandleAccSensor,DefaultAccODR);
  }
}

/**
  * @brief  This function enables the HW's pedometer
  * @param  None
  * @retval None
  */
void EnableHWPedometer(void)
{
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    /* Disable all the HW features before */
    DisableHWFeatures();

    if(BSP_ACCELERO_Enable_Pedometer_Ext(TargetBoardFeatures.HandleAccSensor)==COMPONENT_ERROR) {
      ALLMEMS1_PRINTF("Error Enabling Pedometer\r\n");
    } else {
      ALLMEMS1_PRINTF("Enabled Pedometer\r\n");
      W2ST_ON_HW_FEATURE(W2ST_HWF_PEDOMETER);
    }
  }
}

/**
  * @brief  This function disables the HW's pedometer
  * @param  None
  * @retval None
  */
void DisableHWPedometer(void)
{
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    if(BSP_ACCELERO_Disable_Pedometer_Ext(TargetBoardFeatures.HandleAccSensor)==COMPONENT_ERROR) {
      ALLMEMS1_PRINTF("Error Disabling Pedometer\r\n");
    } else {
      ALLMEMS1_PRINTF("Disabled Pedometer\r\n");
      W2ST_OFF_HW_FEATURE(W2ST_HWF_PEDOMETER);
    }

    /* Set the Output Data Rate to Default value */
    BSP_ACCELERO_Set_ODR_Value(TargetBoardFeatures.HandleAccSensor,DefaultAccODR);
  }
}

/**
  * @brief  This function resets the HW's pedometer steps counter
  * @param  None
  * @retval None
  */
void ResetHWPedometer(void)
{
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    if ( BSP_ACCELERO_Reset_Step_Counter_Ext( TargetBoardFeatures.HandleAccSensor ) == COMPONENT_ERROR ){
      ALLMEMS1_PRINTF("Error Resetting Pedometer's Counter\r\n");
    } else {
      ALLMEMS1_PRINTF("Reset Pedometer's Counter\r\n");
    }
  }
}

/**
  * @brief  This function retunrs the HW's pedometer steps counter value
  * @param  None
  * @retval uint16_t Steps Counter
  */
uint16_t GetStepHWPedometer(void)
{
  uint16_t step_count=0;
  if(TargetBoardFeatures.HWAdvanceFeatures) {
    if(BSP_ACCELERO_Get_Step_Count_Ext( TargetBoardFeatures.HandleAccSensor, &step_count ) == COMPONENT_ERROR ){
      ALLMEMS1_PRINTF("Error Reading Pedometer's Counter\r\n");
    } else {
      ALLMEMS1_PRINTF("Pedometer's Counter=%u\r\n",step_count);
    }
  }
  return step_count;
}

/******************* (C) COPYRIGHT 2017 STMicroelectronics *****END OF FILE****/

ST BlueMS iOS App

ST BlueMS iOS App for reference.

ST BlueMS Android App

ST BlueMS Android App for reference

Credits

Triet Pham

Triet Pham

0 projects • 0 followers

Comments