/**************************************************************************//**
 *  @file si117xhrm.h
 *  @brief Main header file for si117xhrm library.
 *  @version 1.0.4
 *******************************************************************************
 * @section License
 * <b>(C) Copyright 2017 Silicon Labs, http://www.silabs.com</b>
 *******************************************************************************
 *
 * This software is confidential and proprietary information owned by Silicon
 * Labs which is subject to worldwide copyright protection.  No use or other
 * rights associated with this software may exist other than as expressly
 * stated by written agreement with Silicon Labs.  No licenses to the
 * intellectual property rights included in the software, including patent and
 * trade secret rights, are otherwise given by implication, estoppel or
 * otherwise. This contains the prototypes and datatypes needed
 * to use the si117hrm library.
 *
 ******************************************************************************/

#ifndef SI117xHRM_STATIC_H__

#define	SI117xHRM_STATIC_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include "si117xdrv.h"


/**************************************************************************//**
 * HRM/SpO2 Algorithm Defines
 *****************************************************************************/
#define	SI117xHRM_SUCCESS							    0
#define	SI117xHRM_ERROR_RESERVED    				    -1
#define	SI117xHRM_ERROR_INVALID_MEASUREMENT_RATE        -2
#define	SI117xHRM_ERROR_SAMPLE_QUEUE_EMPTY			    -3
#define	SI117xHRM_ERROR_INVALID_PART_ID				    -4
#define	SI117xHRM_ERROR_FUNCTION_NOT_SUPPORTED          -5
#define SI117xHRM_ERROR_BAD_POINTER                     -6
#define SI117xHRM_ERROR_DEBUG_DISABLED                  -7
#define SI117xHRM_ERROR_NON_SUPPORTED_PART_ID           -8    //The feature is not support by the part
#define SI117xHRM_ERROR_INVALID_SAMPLE_DATA             -9
#define SI117xHRM_ERROR_PARAM1_OUT_OF_RANGE			    -10
#define SI117xHRM_ERROR_PARAM2_OUT_OF_RANGE			    (SI117xHRM_ERROR_PARAM0_OUT_OF_RANGE - 1)
#define SI117xHRM_ERROR_PARAM3_OUT_OF_RANGE			    (SI117xHRM_ERROR_PARAM0_OUT_OF_RANGE - 2)
#define SI117xHRM_ERROR_PARAM4_OUT_OF_RANGE			    (SI117xHRM_ERROR_PARAM0_OUT_OF_RANGE - 3)
#define SI117xHRM_ERROR_PARAM5_OUT_OF_RANGE			    (SI117xHRM_ERROR_PARAM0_OUT_OF_RANGE - 4)
#define SI117xHRM_ERROR_PARAM6_OUT_OF_RANGE			    (SI117xHRM_ERROR_PARAM0_OUT_OF_RANGE - 5)
#define SI117xHRM_ERROR_PARAM7_OUT_OF_RANGE			    (SI117xHRM_ERROR_PARAM0_OUT_OF_RANGE - 6)
#define SI117xHRM_ERROR_PARAM8_OUT_OF_RANGE			    (SI117xHRM_ERROR_PARAM0_OUT_OF_RANGE - 7)
#define SI117xHRM_ERROR_PARAM9_OUT_OF_RANGE			    (SI117xHRM_ERROR_PARAM0_OUT_OF_RANGE - 8)
#define SI117xHRM_ERROR_PARAM10_OUT_OF_RANGE		    (SI117xHRM_ERROR_PARAM0_OUT_OF_RANGE - 9)
                                                    
// The HRM status values are a bit field. More than one status can be 'on' at any given time.
#define SI117xHRM_STATUS_SUCCESS					0
#define SI117xHRM_STATUS_FINGER_OFF					(1<<0)
#define SI117xHRM_STATUS_FINGER_ON					(1<<1)
#define SI117xHRM_STATUS_ZERO_CROSSING_INVALID		(1<<2)
#define SI117xHRM_STATUS_BPF_PS_VPP_OFF_RANGE		(1<<3)
#define SI117xHRM_STATUS_AUTO_CORR_TOO_LOW			(1<<4)
#define SI117xHRM_STATUS_CREST_FACTOR_TOO_HIGH		(1<<5)
#define SI117xHRM_STATUS_FRAME_PROCESSED			(1<<6)
#define SI117xHRM_STATUS_AUTO_CORR_MAX_INVALID		(1<<7)
#define SI117xHRM_STATUS_HRM_MASK					0x00ff	// Include all HRM bits
#define SPO2_STATUS_PROCESS_SPO2_FRAME				1		// Used to inform to process the SpO2 frame.
#define SI117xHRM_STATUS_SPO2_FINGER_OFF			(1<<8)
#define SI117xHRM_STATUS_SPO2_FINGER_ON			    (1<<9)
#define SI117xHRM_STATUS_SPO2_CREST_FACTOR_OFF		(1<<10)
#define SI117xHRM_STATUS_SPO2_TOO_LOW_AC			(1<<11)
#define SI117xHRM_STATUS_SPO2_TOO_HIGH_AC			(1<<12)
#define SI117xHRM_STATUS_SPO2_EXCEPTION			    (1<<13)
#define SI117xHRM_STATUS_SPO2_MASK					0xff00	// Include all HRM bits

#define	SIHRM_USE_DYNAMIC_DATA_STRUCTURE	0

#define SIHRM_ALGORITHM_STATUS_CONTROL_FLAG_VALID_PART      0x1
#define SIHRM_ALGORITHM_STATUS_CONTROL_FLAG_DEBUG_ENABLED   0x2
#define SIHRM_ALGORITHM_STATUS_CONTROL_FLAG_FIFO_TEST_MODE  0x4

#define SI117xHRM_VERSION "1.0.4"   //this should never be more than 32 characters per the API reference guide

#define DC_SENSING_DECISION_CNT 63
#define DC_SENSING_AGC_START_CNT DC_SENSING_DECISION_CNT+10

#define SI117xHRM_TRUE     1
#define SI117xHRM_FALSE    0

#define QF_SCALER				            8		// Q-format for Normalization_Scaler
#define FS_ESTIMATE_DURATION	            60		// (sample)
#define FS_UPDATE_RATE			            30		// (%)

//#define ZR_BIAS_SCALE	                    (+1/4)  // %butter BPF, BPF(PS) biases to positive side
#define ZR_BIAS_SCALE	                    (-1/4)  // %cheby2 BPF, BPF(PS) biases to negative side
#define ZC_HR_TOLERANCE                     25

#define HRM_PS_DC_REFERENCE	                15000	// Used for the auto HRM PS AC scaler based on the 1s-averaged PS DC.
#define HRM_PS_VPP_MAX_GREEN_FINGERTIP		HRM_PS_DC_REFERENCE*30/300  // PI=20.0% if positive and negative AC amplitudes are same.

#define HRM_CREST_FACTOR_THRESH_FINGERTIP	15

/* if PS raw value is greater than this threshold the algorithm believes that
 * skin contact is detected */
#define	HRM_PS_RAW_SKIN_CONTACT_THRESHOLD	1500
#define HRM_DC_SENSING_SKIN_CONTACT_THRESH	HRM_PS_RAW_SKIN_CONTACT_THRESHOLD*10/10
#define HRM_DC_SENSING_WORK_LEVEL	        25000
#define HRM_PI_MIN_THRESHOLD				20	    // 20 means PI=0.2%. If PI is below the threshold, the HRM AGC increases the LED current by 1 notch, up to 0x0f.

#define HRM_AMBIENT_BLOCKED_THRESHOLD		500

#define HRM_DC_SENSING_START				0x00	// DC sensing scheme is looking for the next DC sensing.
#define HRM_DC_SENSING_RESTART				0x01	// Restart DC sensing.
#define HRM_DC_SENSING_CHANGE_PARAMETERS	0x02	// Stop the PPG measurement and change the configuration. Restart the PPG measurement.
#define HRM_DC_SENSING_SENSE_FINISH			0x04	// Finish the DC measurement and select the proper current for the HRM operation.
#define HRM_DC_SENSING_SEEK_NO_CONTACT		0x10	// Monitor to see if PS is below the finger-off threshold. Restore Si117x current and set HRM_DC_Sensing_Flag=HRM_DC_SENSING_START for the next DC sensing.

#define INTERPOLATOR_L                      4

#define HRM_BPF_ACTIVE			            0x01	//BPF_Active_Flag bit
#define SpO2_RED_BPF_ACTIVE		            0x02	//BPF_Active_Flag bit
#define SpO2_IR_BPF_ACTIVE		            0x04	//BPF_Active_Flag bit

#define HRM_PS_AGC_DELAY_WINDOW			    50      //(samples)

#define SOS_SCALE_SHIFT	                    16
#define SCALE_I_SHIFT	                    5
#define SCALE_F_SHIFT	                    8

#define SQRT_SHIFT	                        16
#define R_SCALER	                        128

#define SPO2_REFLECTIVE_MODE	            1	// 1--REFLECTIVE MODE, 0--TRANSMISSIVE MODE

// Do not run PS AGC
#define HRM_PS_AGC				            1 	// 1--Increase LED current during valid HR if PS is below the work level or PI is below 0.2%(could occur on wrist).
#define HRM_DATA_LOG			            0	// Debugging: 1--Dump out test data, such as PS, the normalized PS1 and BPF(PS1).

#define HRM_PS_AGC_DISABLED			        0x00
#define HRM_PS_AGC_ENABLED			        0x01
#define HRM_PS_AGC_GAIN_CHANGED		        0x02
#define HRM_PS_AGC_NO_TOUCH			        0x04

#define HRM_DC_WORKING_LEVEL                25000
#define HRM_NUM_SAMPLES_IN_FRAME            256  //10 second frame - used by the AGC

// BPF parameters
#define	BPF_BIQUAD_STAGE_MAX	            3		// Coefficients of all BPFs below have 3 stages.

#define	MAX_FRAME_SAMPLES		                      7*95   // Max Fs=95Hz
#define SI117XHRM_ENABLE_MEASUREMENT_RATE_25Hz        0
#define	SI117XHRM_ENABLE_MEASUREMENT_RATE_60Hz	      0
#define SI117XHRM_ENABLE_MEASUREMENT_RATE_95Hz	      1
#define	SI117XHRM_ENABLE_MEASUREMENT_RATE_185Hz	      0
#define	SI117XHRM_ENABLE_MEASUREMENT_RATE_229Hz	      0
#define	SI117XHRM_ENABLE_MEASUREMENT_RATE_430Hz	      0
#define	SI117XHRM_USE_DYNAMIC_DATA_STRUCTURE	      0

#define	SI117xHRM_MAX_INTERPOLATION_FACTOR		    9

#define SI117XHRM_BUILD_GECKO_SPO2	                1


/**************************************************************************//**
 * HRM/SpO2 Algorithm Types
 *****************************************************************************/
typedef float sihrmFloat_t;

typedef void *HANDLE;

/**
 * Data structure for BPF
 */
typedef struct Si117xBPF
{
  int32_t x[BPF_BIQUAD_STAGE_MAX][3];	// BPF data buffer
  int32_t yi[BPF_BIQUAD_STAGE_MAX][3];	// BPF data buffer
  int32_t yf[BPF_BIQUAD_STAGE_MAX][3];	// BPF data buffer
} Si117xBPF_t;

/**
 * Data structure for Si117x HRM AGC scheme
 */
typedef struct Si117xhrmAGC
{
  uint32_t raw_ppg_sum;
  uint32_t raw_ppg_count;
  uint16_t led_current_value;
  uint16_t agc_flag;
  uint16_t saved_ppg;
} Si117xhrmAGC_t;

/**
 * Data structure for Si117x SpO2 algorithm handler
 */
typedef struct Si117xSpO2Handle
{
  Si117xBPF_t SpO2_Red_BPF, SpO2_IR_BPF;  // BPF struct for SpO2_Red and SpO2_IR

  int16_t SpO2_RED_AC_sample_buffer[MAX_FRAME_SAMPLES];  // Data buffer for the framed samples that can be processed in a background job.
  int16_t SpO2_IR_AC_sample_buffer[MAX_FRAME_SAMPLES];   // Data buffer for the framed samples that can be processed in a background job.
  uint16_t SpO2_RED_DC_sample_buffer[MAX_FRAME_SAMPLES]; // Data buffer for the framed samples that can be processed in a background job.
  uint16_t SpO2_IR_DC_sample_buffer[MAX_FRAME_SAMPLES];	 // Data buffer for the framed samples that can be processed in a background job.

  /* Use each of 4 SpO2 frame sample buffers as a circular buffer,
   * so that SpO2 sample process adds samples to it and SpO2 frame
   * process outputs samples from it. */
  int16_t SpO2_Buffer_In_index;		// Input pointer to the frame sample circular buffer.
  int16_t SpO2_Percent;				// SpO2(%) and the debug message
  int16_t SpO2_raw_level_count;		// Used for Finger On/Off validation
  uint16_t SpO2_Red_interpolator_buf[INTERPOLATOR_L*2], SpO2_IR_interpolator_buf[INTERPOLATOR_L*2];

  //These were local static vars in V0.6.2:
  uint16_t SpO2_Red_BPF_Ripple_Count;	// SpO2 BPF-ripple reduction variable
  uint16_t SpO2_Red_PS_Input_old;		// SpO2 BPF-ripple reduction variable
  uint16_t SpO2_IR_BPF_Ripple_Count;	// SpO2 BPF-ripple reduction variable
  uint16_t SpO2_IR_PS_Input_old;		// SpO2 BPF-ripple reduction variable
  uint16_t TimeSinceFingerOff;			// (sample)
} Si117xSpO2Handle_t;

/**
 * Data structure for Si117x PPG task configuration
 */
typedef struct Si117xhrmPpgConfiguration
{
  uint8_t ppg_led1_config;
  uint8_t ppg_led2_config;
  uint8_t ppg_led3_config;
  uint8_t ppg_led4_config;
  uint8_t ppg_mode;
  uint8_t ppg_measconfig;
  uint8_t ppg_adcconfig;
} Si117xhrmPpgConfiguration_t;

/**
 * Data structure for Si117x device configuration
 */
typedef struct Si117xhrmDeviceConfiguration
{
  uint8_t taskEnable;
  uint16_t measrate;
  uint8_t ppg_meascount;
  uint8_t bioz_meascount;
  uint8_t ecg_meascount;
  uint16_t fifo_int_level;
  uint8_t meas_cntl;
  uint8_t bioz_dc_value;
  uint8_t bioz_freq_sel;
  Si117xhrmPpgConfiguration_t ppgConfig[4];
  uint8_t ecg_measconfig;
  uint8_t ecg_adcconfig;
  uint8_t synch_config;
} Si117xhrmDeviceConfiguration_t;

/**
 * Data structure for user's configuration
 */
typedef struct Si117xhrmUserConfiguration
{
  uint8_t taskEnable;
  uint8_t powerMode;
  uint8_t debugEnable;
  uint8_t accelerometerSynchronizationMode;                 // Currently this should always be set to 1
  uint32_t timestampPeriod100ns;		                    // The timestamp period in units of 100 nanoseconds...
  uint32_t accelerometerNormalizationFactorx10;
  uint16_t numSamplesPerInterrupt;   
  void *debugData;
  Si117xhrmDeviceConfiguration_t *deviceConfiguration;      // The value should be set to NULL
}Si117xhrmUserConfiguration_t;

/**
 * Data structure for Si117x HRM algorithm handler
 */
typedef struct Si117xhrmHandle_t
{
  SI117XDRV_DeviceSelect_t deviceID;
  Si117xSpO2Handle_t *spo2;
  HANDLE si117x_handle;                         // si117x I2C handle

  uint8_t HRM_Interpolator_Factor;
  uint16_t HRM_interpolator_buf[INTERPOLATOR_L*2];
  int16_t *pHRM_Interpolator_Coefs;
  int32_t flag_samples;

  int16_t HRM_sample_buffer[MAX_FRAME_SAMPLES];	// Data buffer for the framed samples that can be processed in a background j
  int16_t HRM_Buffer_In_Index;					// Input index to the frame sample circular buffer.
  int16_t Fs;									// (Hz) Si117x PS sampling rate
  int16_t BPF_biquads, BPF_output_scaler;
  int32_t *pBPF_b_0;
  Si117xBPF_t HRM_BPF;							// BPF struct for HRM
  int16_t hrUpdateInterval;						// HRM_Inits set to 1(s)*Fs
  int16_t T_Low0,T_High0;						// (sample), times for min and max heart rates.
  int16_t hrIframe;								// (sample), Frame length.
  int16_t NumOfLowestHRCycles;					// # of lowest-HR cycle. The longer the frame scale is, more accurate the heart rate is.

  int16_t measurement_rate;
  uint16_t HRM_Normalization_Scaler;			// Normalization scaler for HRM PS based on ADC gain, LED current and etc.
  uint16_t RED_Normalization_Scaler;			// Normalization scaler for SpO2 Red PS based on ADC gain, LED current and etc.
  uint16_t IR_Normalization_Scaler;				// Normalization scaler for SpO2 IR PS based on ADC gain, LED current and etc.
  int16_t sample_count;							// Sample count
  int16_t HRM_PS_raw_level_count;
  uint16_t hrmRawPs;
  uint16_t Normalized_HRM_PS;
  uint8_t hrm_ps_select;						// 0=PPG1, 1=PPG2, 2=PPG3
  uint8_t spo2_ir_ps_select;					// 0=PPG1, 1=PPG2, 2=PPG3
  uint8_t spo2_red_ps_select;					// 0=PPG1, 1=PPG2, 2=PPG3
  int16_t HRM_PS_Vpp_max;
  int16_t HRM_PS_Vpp_min;
  int16_t HRM_PS_CrestFactor_Thresh;

  uint16_t HRM_DC_Sensing_Count;				// Used in HRM DC sensing
  uint16_t HRM_Raw_PS_old;
  uint16_t HRM_DC_Sensing_Flag;					// Used in HRM DC sensing
  uint8_t ppg_led_local;                        // Used in HRM DC sensing
  uint16_t DC_Sensing_Level[4][64/2];           // DC-sensing levels for PS(n) for n=1:2:63 LED currents with configured ADCgain(n), n=1,2,3,4.
  uint16_t DC_Sensing_LED[4];                   // Used in HRM DC sensing
  uint8_t CLK_DIV_value[4];                     // Used in HRM DC sensing
  uint8_t DC_sensing_changes_CLK_DIV;           // Used in HRM DC sensing
  uint16_t RANGE_value[4];                      // Used in HRM DC sensing
  Si117xhrmAGC_t HRM_AGC[4];                    // AGC struct for HRM
  uint8_t HRM_Interpolator_Factor_Saved;		// Used for Fs=10 & 25Hz HRM & SpO2
  uint8_t BPF_Active_Flag;						// BPF-ripple-reduction flags
  uint16_t HRM_BPF_Ripple_Count;				// HRM BPF-ripple reduction variable
  int16_t HeartRateInvalidation_Previous;
  uint32_t HRM_PS_DC;
  uint16_t hrmPerfusionIndex;					// 20 means PI=20/10000=0.2%
  uint16_t HRM_PS_Input_old;					// HRM BPF-ripple reduction variable
  uint16_t algorithmStatusControlFlags;         // bit 0: 1=valid part found; 0=valid part not found
  uint32_t timestampPeriod100ns;		        // The timestamp period in 100 nanoseconds units, TBD
  Si117xhrmUserConfiguration_t *configuration;  // Configuration
  uint8_t hrmActiveDC;
  uint16_t timestampClockFreq;					// Actual Fs. (10000 or 8192)
} Si117xhrmHandle_t;

/**
 * Data structure for HRM Data returned from the algorithm
 */
typedef struct Si117xhrmData		
{
  int16_t Fs;
  uint16_t hrmRawPpg;
  uint16_t hrmRawPpg2,hrmRawPpg3,hrmRawPpg4;
  int16_t hrUpdateInterval;
  uint16_t hrmHRQ;
  sihrmFloat_t hrmAuxData1;
  uint16_t hrmAuxData2;
  int16_t hrIframe;
  uint16_t hrmRawPs;
  uint16_t hrmPs;
  uint16_t hrmInterpolatedPs[SI117xHRM_MAX_INTERPOLATION_FACTOR];	 // This is useful for displaying the waveform
  int16_t hrmPsVppLow;
  int16_t hrmPsVppHigh;
  int16_t hrmCrestFactor;
  uint16_t hrmAdcgainCurrent;	  // HRM AGC: ADCgain<<12+current[2]<<8+current[1]<<4+current[0]
  uint8_t hrmNumSamples;		  // each Process() may result in more than one sample due to interpolation
  int16_t hrmSamples[SI117xHRM_MAX_INTERPOLATION_FACTOR];		// samples after interpolation, filtering and normalization.  These are the sample used for HRM calculation
  uint16_t hrmPerfusionIndex;
  uint16_t spo2RedDcSample;
  uint16_t spo2IrDcSample;
  uint16_t spo2DcToAcRatio;		// Peak To Peak Ratio
  int16_t spo2CrestFactor;
  uint16_t spo2IrPerfusionIndex;
  uint16_t DC_Sensing_LED[4];
} Si117xhrmData_t;

/**
 * Si117x interrupt sample structure
 */
typedef struct Si117xhrmIrqSample
{
  uint16_t sequence;         // sequence number
  uint16_t timestamp;        // 16-bit Timestamp to record
  uint16_t ppg[4];           // PPG Sample
  uint8_t syncMessage;       // if a synch message is found in the FIFO since the last sample it should be placed here
  int16_t accelerometer_x;   // Accelerometer X
  int16_t accelerometer_y;   // Accelerometer Y
  int16_t accelerometer_z;   // Accelerometer Z
} Si117xhrmIrqSample_t;

/**
 * Data structure for auxiliary debug data
 */
#define SI117xHRM_NUM_AUX_DEBUG_DATA_VALUES     4
#define SI117xHRM_DEBUG_CHANNEL_ENABLE          0x1
#define SI117xHRM_DEBUG_FIFO_TEST_MODE_ENABLE   0x2

typedef struct Si117xhrmSampleAuxDebug
{
  uint32_t data[SI117xHRM_NUM_AUX_DEBUG_DATA_VALUES];
} Si117xhrmSampleAuxDebug_t;

/** 
 * Number of bytes needed in RAM for HRM
 */
#define SI117xHRM_HRM_DATA_SIZE 4064

/** 
 * Struct for passing allocated RAM locations to HRM library
 */
typedef struct Si117xhrmDataStorage
{
  uint8_t hrm[SI117xHRM_HRM_DATA_SIZE];  /**< HRM_DATA_SIZE bytes allocated */

} Si117xhrmDataStorage_t;

/**
 * Bytes needed in RAM for SPO2
 */
#define SI117XHRM_SPO2_DATA_SIZE 5644

/**
 * Struct for SpO2 RAM storage
 */
typedef struct Si117xSpO2DataStorage
{
  uint8_t data[SI117XHRM_SPO2_DATA_SIZE]; /**< SPO2_DATA_SIZE bytes allocated */
} Si117xSpO2DataStorage_t;

/**
 * Struct for passing allocated RAM locations to HRM library
 */
typedef struct Si117xDataStorage
{
  Si117xSpO2DataStorage_t *spo2;  /**< Pointer to SpO2 RAM */
  Si117xhrmDataStorage_t *hrm;    /**< Pointer to HRM RAM */
} Si117xDataStorage_t;


/**************************************************************************//**
 * @brief
 *	Initialize the optical sensor device and the HRM algorithm
 *
 * @param[in] portName
 *	Platform specific data to specify the i2c port information.
 *
 * @param[in] options
 *	Initialization options flags.
 *
 * @param[in] data
 *  Pointer to data storage structure
 *
 * @param[in] handle
 *	Pointer to si117xhrm handle
 *
 * @return
 *	Returns error status.
 *****************************************************************************/
int32_t si117xhrm_Initialize(void *portName, int32_t options, Si117xDataStorage_t *data, Si117xhrmHandle_t **handle);

/**************************************************************************//**
 * @brief
 *	Close the optical sensor device and algorithm
 *
 * @param[in] handle
 *	Pointer to si117xhrm handle
 *
 * @return
 *	Returns error status
 *****************************************************************************/
int32_t si117xhrm_Close(Si117xhrmHandle_t *handle);

/**************************************************************************//**
 * @brief
 *	Configure si117xhrm debugging mode.
 *
 * @param[in] handle
 *	Pointer to si117xhrm handle
 *
 * @param[in] enable
 *	Enable or Disable debug
 *
 * @param[in] debug
 *	Pointer to debug status
 *
 * @return
 *	Returns error status.
 *****************************************************************************/
int32_t si117xhrm_SetupDebug(Si117xhrmHandle_t *handle, int32_t enable, void *debug);


/**************************************************************************//**
 * @brief
 *	Output debug message
 *
 * @param[in] handle
 *	Pointer to si117xhrm handle
 *
 * @param[in] message
 *	Message data
 *
 * @return
 *	Returns error status.
 *****************************************************************************/
int32_t si117xhrm_OutputDebugMessage(Si117xhrmHandle_t *handle, int8_t * message);

/**************************************************************************//**
 * @brief
 *	Configure device and algorithm
 *
 * @param[in] _handle
 *	si117xhrm handle
 *
 * @param[in] configuration
 *	Pointer to a configuration structure of type Si117xhrmConfiguration_t
 *
 * @return
 *	Returns error status.
 *****************************************************************************/
int32_t si117xhrm_Configure(Si117xhrmHandle_t *handle, Si117xhrmUserConfiguration_t *configuration);

/**************************************************************************//**
 * @brief
 *	Process Si117x samples and compute HRM/SpO2 results
 *
 * @param[in] _handle
 *	si117xhrm handle
 *
 * @param[out] heart_rate
 *  Pointer to a location where this function will return the heart rate result
 *
 * @param[out] SpO2
 *  Pointer to a location where this function will return the SpO2 result
 *
 * @param[out] hrm_status
 *  Pointer to a integer where this function will report status flags
 *
 * @param[out] hrm_data
 *  Optional pointer to a si117xhrmData_t structure where this function will return
 *  auxiliary data useful for the application.  If the application is not
 *  interested in this data it may pass NULL to this parameter.
 *
 * @param[in] samples
 *  Si117x samples
 *
 * @return
 *	Returns error status.
 *****************************************************************************/
int32_t si117xhrm_ProcessExternalSample(Si117xhrmHandle_t *handle, int16_t *heart_rate, int16_t *SpO2, int32_t *hrm_status, Si117xhrmData_t *hrm_data, Si117xhrmIrqSample_t *samples);

/**************************************************************************//**
 * @brief
 *	HRM process engine.  This function should be called at least once per sample
 *
 * @param[in] _handle
 *	si117xhrm handle
 *
 * @param[out] heartRate
 *	Pointer to a location where this function will return the heart rate result
 *
 * @param[out] SpO2
 *  Pointer to a location where this function will return the SpO2 result
 *
 * @param[in] numSamples
 *
 * @param[out] numSamplesProcessed
 *
 * @param[out] hrmStatus
 *	Pointer to a integer where this function will report status flags
 *
 * @param[out] hrmData
 *	Optional pointer to a si117xhrmData_t structure where this function will return 
 *  auxiliary data useful for the application.  If the application is not 
 *  interested in this data it may pass NULL to this parameter.
 *
 * @return
 *	Returns error status.
 *****************************************************************************/
int32_t si117xhrm_Process(Si117xhrmHandle_t *handle, int16_t *heartRate, int16_t *SpO2, int16_t numSamples, int16_t *numSamplesProcessed, int32_t *hrmStatus, Si117xhrmData_t *hrmData);

/**************************************************************************//*
 * @brief
 *	Start the device's autonomous measurement operation.
 *  The device must be configured before calling this function.
 *
 * @param[in] _handle
 *	si117xhrm handle
 *
 * @param[in] reset
 *	Reset the internal parameters of the HRM algorithm.  If set to false the
 *	HRM algorithm will begin running using parameter values from the last time
 *	it was run.  If the users heart rate has changed significantly since the
 *	last time the algorithm has run and reset is set to false, it could take
 *	longer to converge on the correct heart rate.  It is recommended to set
 *	reset to true if the HRM algorithm has been stopped for greater than 15s.
 *
 * @return
 *	Returns error status.
 *****************************************************************************/
int32_t si117xhrm_Run(Si117xhrmHandle_t *handle, int8_t reset);

/**************************************************************************//**
 * @brief
 *	Pause the device's autonomous measurement operation.
 *  HRM must be running before calling this function.
 *
 * @param[in] _handle
 *	si117xhrm handle
 *
 * @return
 *	Returns error status.
 *****************************************************************************/
int32_t si117xhrm_Pause(Si117xhrmHandle_t *handle);

/**************************************************************************//**
 * @brief
 *	Returns algorithm version
 *
 * @param[out] revision
 *	String representing the si117xhrm library version.  The version string has
 *  a maximum size of 32 bytes.
 *
 * @return
 *	Returns error status.
 *****************************************************************************/
int32_t si117xhrm_QuerySoftwareRevision(int8_t *revision);

/**************************************************************************//**
 * @brief
 *	Get low level i2c handle
 *
 * @param[in] _handle
 *	si117xhrm handle
 *
 * @param[out] deviceHandle
 *	Low level i2c handle
 *
 * @return
 *	Returns error status.
 *****************************************************************************/
int32_t si117xhrm_GetLowLevelHandle(Si117xhrmHandle_t *handle, HANDLE *deviceHandle);


#ifdef __cplusplus
}
#endif

#endif		//SI117xHRM_STATIC_H__
