Maxim Integrated / Mbed OS Host_Software_MAX32664GWEC_SpO2_HR-_EXTE

Dependencies:   BMI160 max32630hsp3 MemoryLCD USBDevice

Fork of Host_Software_MAX32664GWEC_SpO2_HR-_EXTE by Seyhmus Cacina

Files at this revision

API Documentation at this revision

Comitter:
seyhmus.cacina
Date:
Mon Mar 18 14:09:48 2019 +0300
Child:
1:cb15208e5c31
Commit message:
ME11C Sample Code First Commit

Changed in this revision

Drivers/USBDevice.lib Show annotated file Show diff for this revision Revisions of this file
SHComm/SHComm.cpp Show annotated file Show diff for this revision Revisions of this file
SHComm/SHComm.h Show annotated file Show diff for this revision Revisions of this file
SHMAX8614X/HostAccelHelper.cpp Show annotated file Show diff for this revision Revisions of this file
SHMAX8614X/HostAccelHelper.h Show annotated file Show diff for this revision Revisions of this file
SHMAX8614X/SH_Max8614x_BareMetal.cpp Show annotated file Show diff for this revision Revisions of this file
SHMAX8614X/SH_Max8614x_BareMetal.h Show annotated file Show diff for this revision Revisions of this file
accelerometer/bmi160.cpp Show annotated file Show diff for this revision Revisions of this file
accelerometer/bmi160.h Show annotated file Show diff for this revision Revisions of this file
accelerometer/bmi160_i2c.cpp Show annotated file Show diff for this revision Revisions of this file
accelerometer/bmi160_spi.cpp Show annotated file Show diff for this revision Revisions of this file
bootloader/bootldrAPI.cpp Show annotated file Show diff for this revision Revisions of this file
bootloader/bootldrAPI.h Show annotated file Show diff for this revision Revisions of this file
cmdUI/cmdInterface.cpp Show annotated file Show diff for this revision Revisions of this file
cmdUI/cmdInterface.h Show annotated file Show diff for this revision Revisions of this file
demoDefinitions.h Show annotated file Show diff for this revision Revisions of this file
demoUI/demoUI.cpp Show annotated file Show diff for this revision Revisions of this file
demoUI/demoUI.h Show annotated file Show diff for this revision Revisions of this file
demoUI/screen/BufferedDisplay.cpp Show annotated file Show diff for this revision Revisions of this file
demoUI/screen/BufferedDisplay.h Show annotated file Show diff for this revision Revisions of this file
demoUI/screen/GraphicsDisplay.cpp Show annotated file Show diff for this revision Revisions of this file
demoUI/screen/GraphicsDisplay.h Show annotated file Show diff for this revision Revisions of this file
demoUI/screen/LCDSettings.h Show annotated file Show diff for this revision Revisions of this file
demoUI/screen/LS013B7DH03.cpp Show annotated file Show diff for this revision Revisions of this file
demoUI/screen/LS013B7DH03.h Show annotated file Show diff for this revision Revisions of this file
demoUI/screen/TextDisplay.cpp Show annotated file Show diff for this revision Revisions of this file
demoUI/screen/TextDisplay.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
platform/MAX20303.cpp Show annotated file Show diff for this revision Revisions of this file
platform/MAX20303.h Show annotated file Show diff for this revision Revisions of this file
platform/max32630hsp.cpp Show annotated file Show diff for this revision Revisions of this file
platform/max32630hsp.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Drivers/USBDevice.lib	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/MaximIntegrated/code/USBDevice/#dad310740b28
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SHComm/SHComm.cpp	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,1374 @@
+/*
+ * SHcomm.cpp
+ *
+ *  Created on: Nov 16, 2018
+ *      Author: Yagmur.Gok
+ */
+
+/*
+#ifdef __cplusplus
+extern "C" {
+#endif
+*/
+
+#include <events/mbed_events.h>
+#include <mbed.h>
+#include "mbed.h"
+
+#include "SHComm.h"
+
+
+#define SS_I2C_8BIT_SLAVE_ADDR      0xAA
+#define SENSORHUB_I2C_ADRESS        SS_I2C_8BIT_SLAVE_ADDR
+
+#define ENABLED   ((int)(1))
+#define DISABLED  ((int)(0))
+
+#define SS_DUMP_REG_SLEEP_MS        (100)
+#define SS_ENABLE_SENSOR_SLEEP_MS   (20)
+#define SS_DEFAULT_CMD_SLEEP_MS     (2)
+#define SS_WAIT_BETWEEN_TRIES_MS    (2)
+#define SS_CMD_WAIT_PULLTRANS_MS    (5)
+#define SS_FEEDFIFO_CMD_SLEEP_MS	(30)
+
+
+#define SS_DEFAULT_RETRIES       ((int) (4))
+#define SS_ZERO_DELAY               0
+#define SS_ZERO_BYTES               0
+
+
+/*define sample size of algorithm and raw sensor data in bytes*/
+#define SH_ALGO_WHRM_SAMPLE_DATABYTES  4
+#define SH_ALGO_SP02_SAMPLE_DATABYTES  4
+
+
+/*define command sequences given in Maxim ME32664 user manual*/
+#define SH_GET_HUB_STATUS_CMDSEQ               {0x00,0x00}
+#define SH_SET_OPERATING_MODE_CMDSEQ(opMode)   {0x01,0x00,opMode}
+       #define SH_SET_OPERATING_MODE_BOOTLOADER_CMDSEQ      {0x02,0x00,0x08}
+       #define SH_SET_OPERATING_MODE_APPLICATION_CMDSEQ     {0x02,0x00,0x00}
+       #define SH_SET_OPERATING_MODE_RESET_CMDSEQ           {0x02,0x00,0x02}
+#define SH_GET_OPERATING_MODE_CMDSEQ           {0x02,0x00}
+
+#define SH_SET_OUTPUT_MODE_CMDSEQ( outMode)    {0x10,0x00, outMode}
+	   #define SH_SET_OUTMODE_NODATA_CMDSEQ                 {0x10,0x00,0x00}
+       #define SH_SET_OUTMODE_SENSORDATA_CMDSEQ             {0x10,0x00,0x01}
+       #define SH_SET_OUTMODE_ALGODATA_CMDSEQ               {0x10,0x00,0x02}
+       #define SH_SET_OUTMODE_PAUSE_CMDSEQ                  {0x10,0x00,0x04}
+       #define SH_SET_OUTMODE_SENSAMPLECNT_CMDSEQ           {0x10,0x00,0x05}
+	   #define SH_SET_OUTMODE_ALGOSAMPLECNT_CMDSEQ          {0x10,0x00,0x06}
+       #define SH_SET_OUTMODE_ALGOSENSAMPLECNT_CMDSEQ       {0x10,0x00,0x07}
+
+#define SH_GET_OUTPUT_MODE_CMDSEQ             {0x11,0x00}
+
+#define SH_DFIFO_SET_INT_THRESHOLD_CMDSEQ( ucThreshold )    {0x10,0x01,ucThreshold}
+#define SH_DFIFO_GET_INT_THRESHOLD_CMDSEQ                   {0x11,0x01}
+
+#define SH_DFIFO_GET_NSAMPLES_CMDSEQ          {0x12,0x00}
+#define SH_DFIFO_PULL_SAMPLE_CMDSEQ           {0x12,0x01}
+#define SH_GET_EXTINPUT_FIFOSZ_CMDSEQ         {0x13,0x01}
+#define SH_GET_SAMPLEBYTECNT_INPUTFIFO_CMDSEQ {0x13,0x04}
+#define SH_FEED_TO_INPUTFIFO_CMDSEQ           {0x14,0x00}
+
+#define SH_WRITE_SENSORREG_CMDSEQ( sensorIdx , regAddr )    { 0x40, sensorIdx , regAddr}
+#define SH_READ_SENSORREG_CMDSEQ( sensorIdx , regAddr )     { 0x41, sensorIdx , regAddr}
+#define SH_READ_AFE_ATTRIBUTES_CMDSEQ(sensorIdx)            { 0x42, sensorIdx}
+#define SH_READ_ALLREGISTERS_CMDSEQ(sensorIdx)              { 0x43, sensorIdx}
+
+#define SH_ENABLE_SENSOR_CMDSEQ(sensorIdx , extMode)    {0x44, sensorIdx, 0x01 , extMode }
+#define SH_DISABLE_SENSOR_CMDSEQ(sensorIdx)   {0x44, sensorIdx, 0x00}
+
+
+#define SH_AGC_SET_ADCRANGE_CMDSEQ( uiPercentage)           {0x50, 0x00, 0x00 , uiPercentage}
+#define SH_AGC_SET_STEPSZ_CMDSEQ( uiPercentage)             {0x50, 0x00, 0x01 , uiPercentage}
+#define SH_AGC_SET_SENSITIVITY_CMDSEQ( uiPercentage)        {0x50, 0x00, 0x02 , uiPercentage}
+#define SH_AGC_SET_NSAMPLESAVRAGING_CMDSEQ( ucNsamples)     {0x50, 0x00, 0x03 , uiNsamples}
+#define SH_WHRM_SET_SAMPRATE_CMDSEQ( ucNsamples)            {0x50, 0x02, 0x03 , uiNsamples}
+
+
+#define SH_ENABLE_ALGO_CMDSEQ( algoIdx)      { 0x52, algoIdx , 0x01}
+#define SH_DISABLE_ALGO_CMDSEQ( algoIdx)     { 0x52, algoIdx , 0x00}
+
+#define SH_SET_ALGO_CONFIGURATION_CMDSEQ( algoIdx, cgfIdx)  { 0x50 , algoIdx, cgfIdx }
+#define SH_GET_ALGO_CONFIGURATION_CMDSEQ( algoIdx, cgfIdx)  { 0x51 , algoIdx, cgfIdx }
+
+#define SH_COMM_CHECK_CMDSEQ                 {0xFF, 0x00}
+
+
+
+//phase2 additions
+#define SH_CHECKIF_BOOTLDRMODE_CMDSEQ   { 0x02, 0x00 }
+#define SH_SELFTEST_CMDSEQ(idx)         { 0x70, (uint8_t)idx }
+#define SH_EXIT_BOOTLDRMODE_CMDSEQ      { 0x01, 0x00 }
+#define SH_GETLOGSIZE_CMDSEQ            { 0x90, 0x01 }
+#define SH_READHUBLOGS_CMDSEQ           { 0x90, 0x00 }
+
+#define SH_GET_BOOTLDRPAGESIZE_CMDSEQ   { 0x81, 0x01 }
+#define SH_SET_BOOTLDRPAGECOUNT_CMDSEQ  { 0x80, 0x02 }
+
+#define BOOTLOADER_MAX_PAGE_SIZE 8192
+
+/* BOOTLOADER HOST */
+#define EBL_CMD_TRIGGER_MODE	0
+#define EBL_GPIO_TRIGGER_MODE	1
+
+
+
+/*
+ *   define the "platform specific" hardware interface which SSinterface requires:
+ *   1. master i2c port
+ *   2. interrupt attachable I/O pin (mfio)
+ *   3. I/O pin for reset
+ *   Note: Definitions below are for MAX32630FTR Pagasus board . Modify for your platform.
+ **/
+
+I2C *m_i2cBus;                /*i2c  bus sensor hub is connected to*/
+
+PinName ss_mfio(P5_4);             /* platform specific mfio event pin */
+PinName ss_reset(P5_6);            /* platform specific sensor hub reset pin */
+DigitalInOut mfio_pin(ss_mfio);    /* mfio pin mode be I/O */
+DigitalInOut reset_pin(ss_reset);  /* reset pin mode be I/O */
+InterruptIn irq_pin(ss_mfio);      /* define mfio pin interrupt attachable*/
+
+
+/*
+ * SSI API funcions
+ * NOTE: Generic functions for any platform.
+ *       exceptions: below needs needs modification according to platform and HAL drivers
+ *       1. Hard reset function
+ *       2. Enable/disable mfio event interrput
+ *       3. mfio pin interrupt routine
+ *
+ * **/
+
+/*global buffer for sensor i2c commands+data*/
+uint8_t sh_write_buf[512];
+static volatile bool m_irq_received_ = false;
+static volatile bool mfio_int_happened = false;
+
+/* sensor hub states */
+static bool sc_en     = false;
+static int data_type  = 0;
+static int is_sensor_enabled[SS_MAX_SUPPORTED_SENSOR_NUM] = {0};
+static int is_algo_enabled[SS_MAX_SUPPORTED_ALGO_NUM]     = {0};
+static int enabled_algo_mode[SS_MAX_SUPPORTED_ALGO_NUM]   = {0};
+static int sensor_sample_sz[SS_MAX_SUPPORTED_SENSOR_NUM]  = {0};
+static int algo_sample_sz[SS_MAX_SUPPORTED_ALGO_NUM]      = {0};
+
+/* Mode to control sesnor hub resets. ie via GPIO based hard reset or Command based soft reset*/
+static uint8_t ebl_mode = EBL_GPIO_TRIGGER_MODE;
+
+/* desc  :
+ *         Func to init master i2c hardware comm interface with sennor hub
+ *                 init mfio interrupt pin and attach irq to pin
+ *                 init reset pin
+ * params:
+ *         N/A
+ */
+
+
+void sh_irq_handler();
+void sh_init_hwcomm_interface(){
+	static I2C ssI2C(P3_4, P3_5);     /*set up sensor hub i2c communication at 400 kHz*/
+	ssI2C.frequency(400000);
+	m_i2cBus = &ssI2C;
+
+	reset_pin.input();
+	reset_pin.mode(PullUp);
+	mfio_pin.input();                /*set mfio as input for getting mfio event reporting when sesnor hub is on  application mode */
+	mfio_pin.mode(PullUp);
+
+	irq_pin.fall(sh_irq_handler);    /*attach falling edge interrupt to mfio pin for mfio event reporting */
+
+    return;
+}
+
+/* mfio pin event reporting related interrupt functions*/
+/*
+ * data ready event reporting isr from sensor hub
+ *
+ * params:
+ *         N/A
+ * */
+void sh_irq_handler()
+{
+	m_irq_received_ = true;
+}
+void sh_clear_mfio_event_flag(void){
+	m_irq_received_ = false;
+}
+
+bool sh_has_mfio_event(void){
+	return m_irq_received_;
+}
+
+/*  desc:
+ *       func to enable event reporting from sensor hub
+ *
+ *  params:
+ *       N/A
+ * */
+void sh_enable_irq_mfioevent(void)
+{
+	irq_pin.enable_irq();
+}
+
+/*  desc:
+ *       func to disable event reporting from sensor hub
+ *
+ *  params:
+ *       N/A
+ * */
+void sh_disable_irq_mfioevent(void)
+{
+	irq_pin.disable_irq();
+}
+
+/* desc:
+ *     reset event reporting process from sensor hub, on host side
+ *
+ *  params:
+ *       N/A
+ **/
+bool sh_reset_mfio_irq(){
+	bool ret = mfio_int_happened;
+	mfio_int_happened = false;
+	sh_disable_irq_mfioevent();
+	irq_pin.fall(sh_irq_handler);
+	sh_enable_irq_mfioevent();
+	return ret;
+}
+
+
+/*
+ * desc:
+ *    function to reset sensor hub and put to application mode after reset  interface and get data format.
+ *
+ * params:
+ *
+ *    __I wakeupMode : 0x00 : application mode
+ *                     0x08 : bootloader mode
+ * */
+int sh_hard_reset(int wakeupMode){
+
+   int status;
+   sh_disable_irq_mfioevent();
+   reset_pin.output();
+   mfio_pin.output();
+
+   reset_pin.write(0);
+   wait_ms(SS_RESET_TIME);
+
+   if( (wakeupMode & 0xFF) == 0 ) {
+
+	   mfio_pin.write(1);
+	   reset_pin.write(1);
+	   wait_ms(SS_STARTUP_TO_MAIN_APP_TIME);
+
+   }else {
+
+	    mfio_pin.write(0);
+		reset_pin.write(1);
+		wait_ms(SS_STARTUP_TO_BTLDR_TIME);
+   }
+	mfio_pin.input();
+	mfio_pin.mode(PullUp);
+	reset_pin.input();
+	sh_enable_irq_mfioevent();
+
+
+}
+
+
+int sh_set_ebl_mode(const uint8_t mode)
+{
+	int status;
+	if (mode == EBL_CMD_TRIGGER_MODE || mode == EBL_GPIO_TRIGGER_MODE) {
+		ebl_mode = mode;
+		status =  SS_SUCCESS;
+	} else
+		status = SS_ERR_INPUT_VALUE;
+
+	return status;
+}
+
+const int sh_get_ebl_mode(void)
+{
+   return ebl_mode;
+}
+
+int sh_reset_to_bootloader(void){
+
+	int status;
+	uint8_t hubMode;
+
+     if(ebl_mode == EBL_GPIO_TRIGGER_MODE)
+    	 sh_hard_reset(0x08);
+     if(ebl_mode == EBL_CMD_TRIGGER_MODE)
+    	 status = sh_set_sensorhub_operating_mode(0x08);
+
+     status = sh_get_sensorhub_operating_mode(&hubMode);
+     if( status != 0x00 /*SS_SUCCESS*/ || hubMode != 0x08 ){
+    	 status = -1;
+     }
+
+     return status;
+
+}
+
+static bool in_bootldr;
+
+
+int in_bootldr_mode()
+{
+	uint8_t cmd_bytes[] = { SS_FAM_R_MODE, SS_CMDIDX_MODE };
+	uint8_t rxbuf[2] = { 0 };
+
+	int status = sh_read_cmd(&cmd_bytes[0], sizeof(cmd_bytes),
+			0, 0,
+			&rxbuf[0], sizeof(rxbuf), SS_DEFAULT_CMD_SLEEP_MS);
+	if (status != SS_SUCCESS)
+		return -1;
+
+	return (rxbuf[1] & SS_MASK_MODE_BOOTLDR);
+}
+
+int exit_from_bootloader(void)
+{
+	uint8_t cmd_bytes[] = { SS_FAM_W_MODE, SS_CMDIDX_MODE };
+	uint8_t data[] = { 0x00 };
+
+	int status = sh_write_cmd_with_data( &cmd_bytes[0], sizeof(cmd_bytes),
+										 &data[0], 1 /*sizeof(data)*/,
+										 10*SS_DEFAULT_CMD_SLEEP_MS);
+
+	in_bootldr = (status == SS_SUCCESS) ? true : false;
+
+	return status;
+}
+
+int stay_in_bootloader()
+{
+	uint8_t cmd_bytes[] = { SS_FAM_W_MODE, SS_CMDIDX_MODE };
+	uint8_t data[] = { SS_MASK_MODE_BOOTLDR };
+
+	int status = sh_write_cmd_with_data(
+			&cmd_bytes[0], sizeof(cmd_bytes),
+			&data[0], sizeof(data), SS_DEFAULT_CMD_SLEEP_MS);
+
+	in_bootldr = (status == SS_SUCCESS) ? true : false;
+	return status;
+}
+
+
+static void cfg_mfio(PinDirection dir)
+{
+	if (dir == PIN_INPUT) {
+		mfio_pin.input();
+		mfio_pin.mode(PullUp);
+	} else {
+		sh_enable_irq_mfioevent();
+		mfio_pin.output();
+	}
+}
+
+int sh_debug_reset_to_bootloader(void)
+{
+
+	int status = -1;
+
+	sh_disable_irq_mfioevent();
+	if (ebl_mode == EBL_GPIO_TRIGGER_MODE) {
+
+		reset_pin.output();
+		cfg_mfio(PIN_OUTPUT);
+		reset_pin.write(0);
+		wait_ms(SS_RESET_TIME);
+		mfio_pin.write(0);
+		reset_pin.write(1);
+		wait_ms(SS_STARTUP_TO_BTLDR_TIME);
+		cfg_mfio(PIN_INPUT);
+		reset_pin.input();
+		sh_enable_irq_mfioevent();
+		stay_in_bootloader();
+		if (in_bootldr_mode() < 0)
+			status = SS_ERR_UNKNOWN;
+		else
+			status = SS_SUCCESS;
+
+	}else{
+		stay_in_bootloader();
+		sh_enable_irq_mfioevent();
+		status = SS_SUCCESS;
+
+	}
+
+    return status;
+}
+
+
+int sh_reset_to_main_app(void)
+{
+	int status = -1;
+	sh_disable_irq_mfioevent();
+	if (ebl_mode == EBL_GPIO_TRIGGER_MODE) {
+
+		reset_pin.output();
+		cfg_mfio(PIN_OUTPUT);
+		mfio_pin.write(0);
+		wait_ms(SS_RESET_TIME - 5);
+		reset_pin.write(0);
+		wait_ms(SS_RESET_TIME - 5);
+		mfio_pin.write(1);
+		wait_ms(SS_RESET_TIME - 5);
+		reset_pin.write(1);
+		//wait_ms(50);
+		//mfio_pin.write(0);
+		wait_ms(2*SS_STARTUP_TO_MAIN_APP_TIME);
+		cfg_mfio(PIN_INPUT);
+		reset_pin.input();
+
+    	sh_enable_irq_mfioevent();
+		// Verify we exited bootloader mode
+		if (in_bootldr_mode() == 0)
+			status = SS_SUCCESS;
+		else
+			status = SS_ERR_UNKNOWN;
+	}else{
+		status = exit_from_bootloader();
+		sh_enable_irq_mfioevent();
+	}
+
+	return status;
+
+}
+
+/*
+ * desc:
+ *    function to init sensor comm interface and get data format.
+ *
+ * */
+void sh_init_hubinterface(void){
+
+	sh_init_hwcomm_interface();
+	//sh_get_data_type(&data_type, &sc_en);
+    return;
+}
+
+
+/*
+ *
+ *   SENSOR HUB COMMUNICATION INTERFACE ( Defined in MAX32664 User Guide ) API FUNCTIONS
+ *
+ *
+ * */
+
+
+//PHASE2 ADDITIONS:
+
+int sh_self_test(int idx, uint8_t *result, int sleep_ms){
+
+	uint8_t cmd_bytes[] = { SS_FAM_R_SELFTEST, (uint8_t)idx }; // = SH_SELFTEST_CMDSEQ;
+    uint8_t rxbuf[2];
+    result[0] = 0xFF;
+
+    int status = sh_read_cmd(&cmd_bytes[0],sizeof(cmd_bytes) ,
+                             0, 0,
+						     &rxbuf[0], sizeof(rxbuf),
+						     sleep_ms  );
+
+	if (status != SS_SUCCESS)
+		return SS_ERR_TRY_AGAIN;
+
+    result[0] = rxbuf[1];
+	return status;
+}
+
+const char* sh_get_hub_fw_version(void)
+{
+    uint8_t cmd_bytes[2];
+    uint8_t rxbuf[4];
+
+    static char fw_version[32] = "SENSORHUB";
+
+	int bootldr = sh_checkif_bootldr_mode();
+
+	if (bootldr > 0) {
+		cmd_bytes[0] = SS_FAM_R_BOOTLOADER;
+		cmd_bytes[1] = SS_CMDIDX_BOOTFWVERSION;
+	} else if (bootldr == 0) {
+		cmd_bytes[0] = SS_FAM_R_IDENTITY;
+		cmd_bytes[1] = SS_CMDIDX_FWVERSION;
+	} else {
+
+		return &fw_version[0];
+	}
+
+    int status = sh_read_cmd( &cmd_bytes[0], sizeof(cmd_bytes),
+             	 	 	 	  0, 0,
+							  &rxbuf[0], sizeof(rxbuf),
+							  SS_DEFAULT_CMD_SLEEP_MS );
+
+    if (status == SS_SUCCESS) {
+        snprintf(fw_version, sizeof(fw_version),
+            "%d.%d.%d", rxbuf[1], rxbuf[2], rxbuf[3]);
+	}
+
+    return &fw_version[0];
+}
+
+
+const char* sh_get_hub_algo_version(void)
+{
+    uint8_t cmd_bytes[3];
+    uint8_t rxbuf[4];
+
+    static char algo_version[64] = "SENSORHUBALGORITHMS";
+
+	int bootldr = sh_checkif_bootldr_mode();
+
+	if (bootldr > 0) {
+		cmd_bytes[0] = SS_FAM_R_BOOTLOADER;
+		cmd_bytes[1] = SS_CMDIDX_BOOTFWVERSION;
+		cmd_bytes[2] = 0;
+	} else if (bootldr == 0) {
+		cmd_bytes[0] = SS_FAM_R_IDENTITY;
+		cmd_bytes[1] = SS_CMDIDX_ALGOVER;
+		cmd_bytes[2] = SS_CMDIDX_AVAILSENSORS;
+	} else {
+
+		return &algo_version[0];
+	}
+
+    int status = sh_read_cmd( &cmd_bytes[0], sizeof(cmd_bytes),
+                              0, 0,
+                              &rxbuf[0], sizeof(rxbuf),
+						      SS_DEFAULT_CMD_SLEEP_MS   );
+
+    if (status == SS_SUCCESS) {
+        snprintf(algo_version, sizeof(algo_version),
+            "%d.%d.%d", rxbuf[1], rxbuf[2], rxbuf[3]);
+
+    }
+
+    return &algo_version[0];
+}
+
+int sh_send_raw(uint8_t *rawdata, int rawdata_sz)
+{
+	return sh_write_cmd(&rawdata[0], rawdata_sz, 5 * SS_ENABLE_SENSOR_SLEEP_MS);
+}
+
+int sh_get_log_len(int *log_len)
+{
+	uint8_t cmd_bytes[] = { SS_FAM_R_LOG, SS_CMDIDX_R_LOG_LEN }; // = SH_GETLOGSIZE_CMDSEQ;
+	uint8_t rxbuf[2] = {0};
+    int logLen = 0;
+
+	int status = sh_read_cmd(&cmd_bytes[0], sizeof(cmd_bytes),
+								   0, 0,
+								   &rxbuf[0], sizeof(rxbuf),
+								   SS_DEFAULT_CMD_SLEEP_MS   );
+
+	if (status == SS_SUCCESS) {
+		logLen = (rxbuf[1] << 8) | rxbuf[0];
+	}
+	*log_len = logLen;
+
+	return status;
+}
+
+int sh_read_ss_log(int num_bytes, uint8_t *log_buf, int log_buf_sz)
+{
+	int bytes_to_read = num_bytes + 1; //+1 for status byte
+	//mxm_assert_msg((bytes_to_read <= log_buf_sz), "log_buf too small");
+
+	uint8_t cmd_bytes[] = { SS_FAM_R_LOG, SS_CMDIDX_R_LOG_DATA }; // = SH_READHUBLOGS_CMDSEQ;
+
+	int status = sh_read_cmd(&cmd_bytes[0], sizeof(cmd_bytes),
+						     0, 0,
+							 log_buf, bytes_to_read,
+							 SS_CMD_WAIT_PULLTRANS_MS  );
+
+	return status;
+}
+
+// END OF PHASE2 ADDITIONS
+
+
+
+
+int sh_write_cmd( uint8_t *tx_buf,
+		          int tx_len,
+				  int sleep_ms)
+{
+	int retries = SS_DEFAULT_RETRIES;
+	int ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)tx_buf, tx_len);
+	while (ret != 0 && retries-- > 0) {
+
+		wait_ms(1);
+    	ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)tx_buf, tx_len);
+	}
+    if (ret != 0)
+       return SS_ERR_UNAVAILABLE;
+
+
+    wait_ms(sleep_ms);
+
+    char status_byte;
+    ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, &status_byte, 1);
+	bool try_again = (status_byte == SS_ERR_TRY_AGAIN);
+	while ((ret != 0 || try_again)
+			&& retries-- > 0) {
+	 	wait_ms(sleep_ms);
+    	ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, &status_byte, 1);
+		try_again = (status_byte == SS_ERR_TRY_AGAIN);
+	}
+
+    if (ret != 0 || try_again)
+        return SS_ERR_UNAVAILABLE;
+
+	return (int) (SS_STATUS)status_byte;
+}
+
+
+int sh_write_cmd_with_data(uint8_t *cmd_bytes,
+		                   int cmd_bytes_len,
+                           uint8_t *data,
+						   int data_len,
+                           int cmd_delay_ms)
+{
+    memcpy(sh_write_buf, cmd_bytes, cmd_bytes_len);
+    memcpy(sh_write_buf + cmd_bytes_len, data, data_len);
+    int status = sh_write_cmd(sh_write_buf,cmd_bytes_len + data_len, cmd_delay_ms);
+    return status;
+}
+
+
+int sh_read_cmd( uint8_t *cmd_bytes,
+		         int cmd_bytes_len,
+	             uint8_t *data,
+				 int data_len,
+	             uint8_t *rxbuf,
+				 int rxbuf_sz,
+                 int sleep_ms )
+{
+
+	int retries = SS_DEFAULT_RETRIES;
+
+    int ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)cmd_bytes, cmd_bytes_len, (data_len != 0));
+    if (data_len != 0)
+        ret |= m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)data, data_len, false);
+
+
+	while (ret != 0 && retries-- > 0) {
+		wait_ms(1);
+    	ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)cmd_bytes, cmd_bytes_len, (data_len != 0));
+	    if (data_len != 0)
+	        ret |= m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)data, data_len, false);
+
+	}
+    if (ret != 0)
+    	return SS_ERR_UNAVAILABLE;
+
+
+    wait_ms(sleep_ms);
+
+    ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, (char*)rxbuf, rxbuf_sz);
+	bool try_again = (rxbuf[0] == SS_ERR_TRY_AGAIN);
+	while ((ret != 0 || try_again) && retries-- > 0) {
+		wait_ms(sleep_ms);
+    	ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, (char*)rxbuf, rxbuf_sz);
+		try_again = (rxbuf[0] == SS_ERR_TRY_AGAIN);
+	}
+    if (ret != 0 || try_again)
+        return SS_ERR_UNAVAILABLE;
+
+    return (int) ((SS_STATUS)rxbuf[0]);
+}
+
+
+
+int sh_get_sensorhub_status(uint8_t *hubStatus){
+
+	uint8_t ByteSeq[] = SH_GET_HUB_STATUS_CMDSEQ;
+	uint8_t rxbuf[2] = { 0 };
+
+	int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq),
+			                    0, 0,
+			                    &rxbuf[0], sizeof(rxbuf),
+								SS_DEFAULT_CMD_SLEEP_MS);
+
+	*hubStatus = rxbuf[1];
+	return status;
+}
+
+
+int sh_get_sensorhub_operating_mode(uint8_t *hubMode){
+
+	uint8_t ByteSeq[] = SH_GET_OPERATING_MODE_CMDSEQ;
+	uint8_t rxbuf[2] = { 0 };
+
+	int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq),
+			                    0, 0,
+			                    &rxbuf[0], sizeof(rxbuf),
+								SS_DEFAULT_CMD_SLEEP_MS);
+
+	*hubMode = rxbuf[1];
+	return status;
+}
+
+
+int sh_set_sensorhub_operating_mode(uint8_t hubMode){
+
+	uint8_t ByteSeq[] = SH_SET_OPERATING_MODE_CMDSEQ(hubMode);
+	int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), SS_DEFAULT_CMD_SLEEP_MS);
+    return status;
+
+}
+
+
+//int sh_set_data_type( uint8_t outMode)
+int sh_set_data_type(int data_type_, bool sc_en_)
+{
+
+#if 0
+	uint8_t dataTypeSc = (uint8_t)((sc_en ? SS_MASK_OUTPUTMODE_SC_EN : 0) | ((data_type << SS_SHIFT_OUTPUTMODE_DATATYPE) & SS_MASK_OUTPUTMODE_DATATYPE));
+	uint8_t ByteSeq[] = SH_SET_OUTPUT_MODE_CMDSEQ( dataTypeSc);
+	int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), SS_DEFAULT_CMD_SLEEP_MS);
+    if( status == 0x00){
+    	data_type = data_type_;
+        sc_en = sc_en_;
+    }
+#endif
+
+	uint8_t cmd_bytes[] = { SS_FAM_W_COMMCHAN, SS_CMDIDX_OUTPUTMODE };
+	uint8_t data_bytes[] = { (uint8_t)((sc_en_ ? SS_MASK_OUTPUTMODE_SC_EN : 0) |
+							((data_type_ << SS_SHIFT_OUTPUTMODE_DATATYPE) & SS_MASK_OUTPUTMODE_DATATYPE)) };
+
+	int status = sh_write_cmd_with_data(&cmd_bytes[0], sizeof(cmd_bytes),
+								&data_bytes[0], sizeof(data_bytes),
+								SS_DEFAULT_CMD_SLEEP_MS);
+	data_type = data_type_;
+	sc_en = sc_en_;
+
+	return status;
+}
+
+
+int sh_get_data_type(int *data_type_, bool *sc_en_){
+
+	uint8_t ByteSeq[] = SH_GET_OUTPUT_MODE_CMDSEQ;
+	uint8_t rxbuf[2] = {0};
+	int status = sh_read_cmd( &ByteSeq[0], sizeof(ByteSeq),
+							  0, 0,
+							  &rxbuf[0], sizeof(rxbuf),
+							  SS_DEFAULT_CMD_SLEEP_MS);
+	if (status == 0x00 /*SS_SUCCESS*/) {
+		*data_type_ =
+			(rxbuf[1] & SS_MASK_OUTPUTMODE_DATATYPE) >> SS_SHIFT_OUTPUTMODE_DATATYPE;
+		*sc_en_ =
+			(bool)((rxbuf[1] & SS_MASK_OUTPUTMODE_SC_EN) >> SS_SHIFT_OUTPUTMODE_SC_EN);
+
+	}
+
+	return status;
+
+}
+
+
+int sh_set_fifo_thresh( int threshold ){
+
+#if 0
+	uint8_t ucThresh = (uint8_t) (threshold & 0xFF);
+	uint8_t ByteSeq[] = SH_DFIFO_SET_INT_THRESHOLD_CMDSEQ(ucThresh );
+	int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), SS_DEFAULT_CMD_SLEEP_MS);
+	return status;
+#endif
+
+	uint8_t cmd_bytes[] = { SS_FAM_W_COMMCHAN, SS_CMDIDX_FIFOAFULL };
+	uint8_t data_bytes[] = { (uint8_t)threshold };
+
+	int status = sh_write_cmd_with_data(&cmd_bytes[0], sizeof(cmd_bytes),
+								&data_bytes[0], sizeof(data_bytes),
+								SS_DEFAULT_CMD_SLEEP_MS
+	                            );
+	return status;
+
+}
+
+
+int sh_get_fifo_thresh(int *thresh){
+
+	uint8_t ByteSeq[] = SH_DFIFO_GET_INT_THRESHOLD_CMDSEQ;
+	uint8_t rxbuf[2] = {0};
+	int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq),
+							 0, 0,
+							 &rxbuf[0], sizeof(rxbuf),
+							 SS_DEFAULT_CMD_SLEEP_MS);
+
+	*thresh = (int) rxbuf[1];
+
+	return status;
+
+}
+
+
+int sh_ss_comm_check(void){
+
+
+	uint8_t ByteSeq[] = SH_COMM_CHECK_CMDSEQ;
+	uint8_t rxbuf[2];
+
+	int status = sh_read_cmd( &ByteSeq[0], sizeof(ByteSeq),
+							  0, 0,
+							  &rxbuf[0], sizeof(rxbuf),
+							  SS_DEFAULT_CMD_SLEEP_MS );
+
+	int tries = 4;
+	while (status == SS_ERR_TRY_AGAIN && tries--) {
+		wait_ms(1000);
+		status = sh_read_cmd( &ByteSeq[0], sizeof(ByteSeq),
+									  0, 0,
+									  &rxbuf[0], sizeof(rxbuf),
+									  SS_DEFAULT_CMD_SLEEP_MS );
+
+	}
+
+	return status;
+}
+
+
+int sh_num_avail_samples(int *numSamples) {
+
+	 uint8_t ByteSeq[] = SH_DFIFO_GET_NSAMPLES_CMDSEQ;
+	 uint8_t rxbuf[2] = {0};
+
+	 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq),
+							  0, 0,
+							  &rxbuf[0], sizeof(rxbuf),
+							  1);
+
+	 *numSamples = (int) rxbuf[1];
+
+	 return status;
+}
+
+
+int sh_read_fifo_data( int numSamples,
+		               int sampleSize,
+		               uint8_t* databuf,
+					   int databufSz) {
+
+	int bytes_to_read = numSamples * sampleSize + 1; //+1 for status byte
+
+	uint8_t ByteSeq[] = SH_DFIFO_PULL_SAMPLE_CMDSEQ;
+	int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq),
+							 0, 0,
+							 databuf, bytes_to_read,
+							 10);
+
+	return status;
+}
+
+
+/*
+ * desc:
+ *        func to read sample size for SmartSensor input FIFO for extrenal accel data
+ *
+ * params:
+ *		  __O sampSize:  size of data sample struct in bytes
+ * returns:
+ *        1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ *
+ **/
+int sh_read_input_fifo_samplesz( int *sampSize){
+
+	/* NOT IMPLEMENTED IN SS INTERFACE */
+
+}
+
+/*
+ * desc:
+ *        func to write data  samples to  SmartSensor input FIFO for extrenal accel data
+ *
+ * params:
+          ...
+ * returns:
+ *        1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_write_input_fifo( void *arg){
+
+	/* NOT IMPLEMENTED IN SS INTERFACE */
+
+}
+
+
+int sh_set_reg(int idx, uint8_t addr, uint32_t val, int regSz){
+
+	uint8_t ByteSeq[] = SH_WRITE_SENSORREG_CMDSEQ( ((uint8_t)idx) , addr );
+	uint8_t data_bytes[4];
+	for (int i = 0; i < regSz; i++) {
+		data_bytes[i] = (val >> (8 * (regSz - 1)) & 0xFF);
+	}
+	int status = sh_write_cmd_with_data( &ByteSeq[0], sizeof(ByteSeq),
+							             &data_bytes[0], (uint8_t) regSz,
+										 SS_DEFAULT_CMD_SLEEP_MS);
+
+    return status;
+}
+
+
+int sh_get_reg(int idx, uint8_t addr, uint32_t *val){
+
+
+	uint32_t i32tmp;
+	uint8_t ByteSeq[] = SH_READ_AFE_ATTRIBUTES_CMDSEQ(((uint8_t) idx));
+	uint8_t rxbuf[3] = {0};
+
+	int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq),
+								0, 0,
+							 &rxbuf[0], sizeof(rxbuf),
+							 SS_DEFAULT_CMD_SLEEP_MS);
+
+
+    if(status == 0x00 /* SS_SUCCESS */) {
+
+    	int reg_width = rxbuf[1];
+    	uint8_t ByteSeq2[] = SH_READ_SENSORREG_CMDSEQ( ((uint8_t)idx) , addr );
+    	uint8_t rxbuf2[5] = {0};
+    	status = sh_read_cmd(&ByteSeq2[0], sizeof(ByteSeq2),
+    						0, 0,
+    						&rxbuf2[0], reg_width + 1,
+							SS_DEFAULT_CMD_SLEEP_MS);
+
+    	if (status == 0x00  /* SS_SUCCESS */) {
+    		i32tmp = 0;
+    		for (int i = 0; i < reg_width; i++) {
+    			i32tmp = (i32tmp << 8) | rxbuf2[i + 1];
+    		}
+            *val = i32tmp;
+    	}
+     }
+
+    return status;
+
+}
+
+
+int sh_sensor_enable( int idx , int sensorSampleSz , uint8_t ext_mode ){
+
+	uint8_t ByteSeq[] = SH_ENABLE_SENSOR_CMDSEQ( ((uint8_t) idx) ,  ((uint8_t) ext_mode));
+	int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), 5 * SS_ENABLE_SENSOR_SLEEP_MS);
+	if(status == 0x00){
+
+		is_sensor_enabled[idx] = ENABLED;
+		sensor_sample_sz[idx] = sensorSampleSz;
+	}
+    return status;
+
+}
+
+
+int sh_sensor_disable( int idx ){
+
+	uint8_t ByteSeq[] = SH_DISABLE_SENSOR_CMDSEQ( ((uint8_t) idx));
+	int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), SS_ENABLE_SENSOR_SLEEP_MS);
+	if(status == 0x00){
+
+		is_sensor_enabled[idx] = DISABLED;
+	}
+	return status;
+
+}
+
+
+int sh_get_input_fifo_size(int *fifo_size)
+{
+
+	uint8_t ByteSeq[] = SH_GET_EXTINPUT_FIFOSZ_CMDSEQ;
+	uint8_t rxbuf[3]; /* status + fifo size */
+
+
+	int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq),
+							  0, 0,
+							  rxbuf, sizeof(rxbuf), 2*SS_DEFAULT_CMD_SLEEP_MS);
+
+	*fifo_size = rxbuf[1] << 8 | rxbuf[2];
+	return status;
+}
+
+
+int sh_feed_to_input_fifo(uint8_t *tx_buf, int tx_buf_sz, int *nb_written)
+{
+	int status;
+
+	uint8_t ByteSeq[] = SH_FEED_TO_INPUTFIFO_CMDSEQ;
+	uint8_t rxbuf[3];
+
+	tx_buf[0] = 0x14;
+	tx_buf[1] = 0x00;
+
+	status= sh_read_cmd(tx_buf, tx_buf_sz,
+			          0, 0,
+			          rxbuf, sizeof(rxbuf), SS_FEEDFIFO_CMD_SLEEP_MS);
+
+	*nb_written = rxbuf[1] * 256 + rxbuf[2];
+	return status;
+}
+
+
+int sh_get_num_bytes_in_input_fifo(int *fifo_size)
+{
+
+    uint8_t ByteSeq[] = SH_GET_SAMPLEBYTECNT_INPUTFIFO_CMDSEQ;
+	uint8_t rxbuf[3]; /* status + fifo size */
+
+
+	int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq),
+							 0, 0,
+							 rxbuf, sizeof(rxbuf),
+							 2*SS_DEFAULT_CMD_SLEEP_MS);
+
+	*fifo_size = rxbuf[1] << 8 | rxbuf[2];
+	return status;
+}
+
+
+/*
+ * ALGARITIM RELATED FUNCTIONS :)
+ *
+ *
+ *
+ *
+ *
+ * */
+
+
+int sh_enable_algo(int idx , int algoSampleSz){
+
+	uint8_t ByteSeq[] = SH_ENABLE_ALGO_CMDSEQ( ((uint8_t) idx) );
+	int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), 25 * SS_ENABLE_SENSOR_SLEEP_MS);
+	if(status == 0x00){
+
+		is_algo_enabled[idx] = ENABLED;
+		algo_sample_sz[idx]  = algoSampleSz;
+	}
+    return status;
+
+}
+
+
+int sh_enable_algo_withmode(int idx, int mode, int algoSampleSz)
+{
+
+	uint8_t cmd_bytes[] = { SS_FAM_W_ALGOMODE, (uint8_t)idx, (uint8_t)mode };
+
+	int status = sh_write_cmd_with_data(&cmd_bytes[0], sizeof(cmd_bytes), 0, 0, 25 * SS_ENABLE_SENSOR_SLEEP_MS);
+
+	if (status == SS_SUCCESS) {
+		is_algo_enabled[idx]   = ENABLED;
+		algo_sample_sz[idx]    = algoSampleSz;
+		enabled_algo_mode[idx] = mode;
+	}
+
+	return status;
+}
+
+
+
+int sh_disable_algo(int idx){
+
+	uint8_t ByteSeq[] = SH_DISABLE_ALGO_CMDSEQ( ((uint8_t) idx) );
+	int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), SS_ENABLE_SENSOR_SLEEP_MS );
+	if(status == 0x00){
+
+		is_algo_enabled[idx] = DISABLED;
+	}
+    return status;
+
+}
+
+
+int sh_set_algo_cfg(int algo_idx, int cfg_idx, uint8_t *cfg, int cfg_sz){
+
+	uint8_t ByteSeq[] = SH_SET_ALGO_CONFIGURATION_CMDSEQ( ((uint8_t) algo_idx) ,  ((uint8_t) cfg_idx)  );
+	int status = sh_write_cmd_with_data( &ByteSeq[0], sizeof(ByteSeq),
+			                             cfg, cfg_sz,
+										 SS_DEFAULT_CMD_SLEEP_MS);
+
+	return status;
+
+}
+
+
+int sh_get_algo_cfg(int algo_idx, int cfg_idx, uint8_t *cfg, int cfg_sz){
+
+	uint8_t ByteSeq[] = SH_GET_ALGO_CONFIGURATION_CMDSEQ( ((uint8_t) algo_idx) ,  ((uint8_t) cfg_idx)  );
+	int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq),
+						     0, 0,
+							 cfg, cfg_sz,
+							 SS_DEFAULT_CMD_SLEEP_MS);
+	return status;
+
+}
+
+
+/*
+ * desc:
+ *      func to get active cumulative sample size of sensor hub in order to
+ *           calculate number of bytes to be read from sensor hub report data buffer
+ *
+ * params:
+ *      __I data_type : active data type of sensor hub -> no data              :0 (SS_DATATYPE_PAUSE)
+ *                                                        raw sensor data only :1 (SS_DATATYPE_RAW)
+ *                                                        algo data only       :2 (SS_DATATYPE_ALGO)
+ *                                                        algo+raw data        :3 (SS_DATATYPE_BOTH)
+ *      __O sample_size : calculated active cumulative sample size
+
+ * returns:
+ *        N/A
+ *
+ **/
+static void fifo_sample_size(int data_type_, int *sample_size)
+{
+
+    int tmpSz = 0;
+	//*sample_size = 0;
+
+	if (data_type_ == SS_DATATYPE_RAW || data_type_ == SS_DATATYPE_BOTH) {
+		for (int i = 0; i < SS_MAX_SUPPORTED_SENSOR_NUM; i++) {
+			if (is_sensor_enabled[i]) {
+				tmpSz += sensor_sample_sz[i];
+				//*sample_size += sensor_data_reqs[i]->data_size;
+			}
+		}
+	}
+
+	if (data_type_ == SS_DATATYPE_ALGO || data_type_ == SS_DATATYPE_BOTH) {
+		for (int i = 0; i < SS_MAX_SUPPORTED_ALGO_NUM; i++) {
+			if (is_algo_enabled[i]) {
+				tmpSz += algo_sample_sz[i];
+				//*sample_size += algo_data_reqs[i]->data_size;
+			}
+		}
+	}
+
+	*sample_size = tmpSz;
+}
+
+
+int sh_ss_execute_once( uint8_t *databuf , int databufLen , int *nSamplesRead){
+
+	if(m_irq_received_ == false) {
+		  *nSamplesRead = 0;
+		  return -1;
+	}
+
+	uint8_t sample_count;
+
+    sh_disable_irq_mfioevent();
+    sh_clear_mfio_event_flag();
+
+	uint8_t hubStatus = 0;
+	int status = sh_get_sensorhub_status(&hubStatus);
+	if(status != 0x00 /*SS_SUCCESS*/){
+    	*nSamplesRead = 0;
+    	sh_enable_irq_mfioevent();
+        return status;
+    }
+
+    if (hubStatus & SS_MASK_STATUS_DATA_RDY) {
+
+    	 int num_samples = 1;
+    	 status = sh_num_avail_samples(&num_samples);
+      	 if (status != 0x00 /*SS_SUCCESS*/){
+    		 *nSamplesRead = 0;
+    		 sh_enable_irq_mfioevent();
+    		 return status;
+         }
+
+
+    	 int sample_size;
+    	 fifo_sample_size(data_type, &sample_size);
+    	 /*DEBUG *///
+
+
+    	 int bytes_to_read = num_samples * sample_size + 1; //+1 for status byte
+         if ( bytes_to_read > databufLen) {
+ 			//Reduce number of samples to read to fit in buffer
+ 			num_samples = (databufLen - 1) / sample_size;
+ 		 }
+
+
+        wait_ms(5);
+        status = sh_read_fifo_data(num_samples, sample_size, &databuf[0], databufLen);
+        if(status != 0x00 /*SS_SUCCESS*/){
+        	*nSamplesRead = 0;
+        	sh_enable_irq_mfioevent();
+        	return status;
+        }
+        *nSamplesRead = num_samples;
+    }
+
+    sh_enable_irq_mfioevent();
+    return status;
+}
+
+
+
+/*
+ * BOOTLOADER RELATED FUNCTIONS
+ *
+ *
+ * */
+
+static const int aes_nonce_sz = 11;
+static const int aes_auth_sz  = 16;
+static int bl_comm_delay_factor = 1;
+
+
+
+int sh_set_bootloader_delayfactor(const int factor ) {
+
+	int status = -1;
+	if( factor >= 1  && factor < 51){
+	    bl_comm_delay_factor = factor;
+	    status = 0x00;
+	}
+
+	return status;
+
+}
+
+const int sh_get_bootloader_delayfactor(void){
+
+     return bl_comm_delay_factor;
+}
+
+int sh_exit_from_bootloader(void)
+{
+
+	return sh_reset_to_main_app(); //sh_set_sensorhub_operating_mode(0x00);
+}
+
+int sh_put_in_bootloader(void)
+{
+	return sh_set_sensorhub_operating_mode( 0x08);
+}
+
+int sh_checkif_bootldr_mode(void)
+{
+	uint8_t hubMode;
+	int status = sh_get_sensorhub_operating_mode(&hubMode);
+	return (status != SS_SUCCESS)? -1:(hubMode & SS_MASK_MODE_BOOTLDR);
+}
+
+int sh_get_bootloader_pagesz(int *pagesz){
+
+	//uint8_t ByteSeq[]= SH_GET_BOOTLDRPAGESIZE_CMDSEQ;
+	uint8_t ByteSeq[]= { SS_FAM_R_BOOTLOADER, SS_CMDIDX_PAGESIZE };
+    uint8_t rxbuf[3];
+    int sz = 0;
+
+    int status = sh_read_cmd( &ByteSeq[0], sizeof(ByteSeq),
+                          0, 0,
+                          &rxbuf[0], sizeof(rxbuf),
+						  SS_DEFAULT_CMD_SLEEP_MS);
+    if (status == 0x00) {
+           //rxbuf holds page size in big-endian format
+            sz = (256*(int)rxbuf[1]) + rxbuf[2];
+            if(sz > BOOTLOADER_MAX_PAGE_SIZE ) {
+                   sz = -2;
+            }
+    }
+
+    *pagesz = sz;
+
+    return status;
+
+}
+
+int sh_set_bootloader_numberofpages(const int pageCount){
+
+	//uint8_t ByteSeq[] = SH_SET_BOOTLDRPAGECOUNT_CMDSEQ;
+    uint8_t ByteSeq[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETNUMPAGES };
+    //num pages = 256*MSB + LSB
+    uint8_t data_bytes[] = { (uint8_t)((pageCount >> 8) & 0xFF), (uint8_t)(pageCount & 0xFF) };
+
+    int status = sh_write_cmd_with_data(&ByteSeq[0], sizeof(ByteSeq),
+								        &data_bytes[0], sizeof(data_bytes),
+										bl_comm_delay_factor * SS_DEFAULT_CMD_SLEEP_MS );
+
+    return status;
+
+}
+
+int sh_set_bootloader_iv(uint8_t iv_bytes[aes_nonce_sz]){
+
+	 uint8_t ByteSeq[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETIV };
+	 int status = sh_write_cmd_with_data( &ByteSeq[0], sizeof(ByteSeq),
+			                              &iv_bytes[0], aes_nonce_sz /*sizeof(iv_bytes)*/,
+										  bl_comm_delay_factor * SS_DEFAULT_CMD_SLEEP_MS
+										  );
+
+     return status;
+
+}
+
+
+int sh_set_bootloader_auth(uint8_t auth_bytes[aes_auth_sz]){
+
+	 uint8_t ByteSeq[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETAUTH };
+	 int status = sh_write_cmd_with_data( &ByteSeq[0], sizeof(ByteSeq),
+			                              &auth_bytes[0], aes_auth_sz /*sizeof(auth_bytes)*/,
+										  bl_comm_delay_factor * SS_DEFAULT_CMD_SLEEP_MS
+										  );
+
+     return status;
+
+}
+
+
+int sh_set_bootloader_erase(void){
+
+    uint8_t ByteSeq[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_ERASE };
+
+    int status = sh_write_cmd_with_data(&ByteSeq[0], sizeof(ByteSeq),
+                                        0, 0,
+										bl_comm_delay_factor * SS_BOOTLOADER_ERASE_DELAY);
+
+    return status;
+
+}
+
+
+int sh_bootloader_flashpage(uint8_t *flashDataPreceedByCmdBytes , const int page_size){
+
+	static const int flash_cmdbytes_len   = 2;
+	static const int check_bytes_len      = 16;
+	static const int page_write_time_ms   = 200;
+
+    //static const uint8_t ByteSeq[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SENDPAGE };
+    int status = -1;
+
+    if( (*flashDataPreceedByCmdBytes == SS_FAM_W_BOOTLOADER) &&  ( *(flashDataPreceedByCmdBytes+1) == SS_CMDIDX_SENDPAGE ) ) {
+
+		/* We do not use sh_write_cmd_with_data function because internal buffers of the function
+		   is limited to 512 bytes which does not support if flashing page size is bigger */
+		status = sh_write_cmd(flashDataPreceedByCmdBytes, page_size + check_bytes_len + flash_cmdbytes_len, bl_comm_delay_factor * page_write_time_ms);
+
+    }
+	return status;
+
+}
+
+
+
+/*
+#ifdef __cplusplus
+}
+#endif
+*/
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SHComm/SHComm.h	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,743 @@
+/*
+ * SHComm.h
+ *
+ *  Created on: Nov 16, 2018
+ *      Author: Yagmur.Gok
+ */
+
+#ifndef SOURCE_SHCOMM_H_
+#define SOURCE_SHCOMM_H_
+
+/*
+#ifdef __cplusplus
+extern "C" {
+#endif
+*/
+
+// Sensor/Algo indicies
+#define SH_SENSORIDX_MAX8614X	0x00
+#define SH_SENSORIDX_MAX30205	0x01
+#define SH_SENSORIDX_MAX30001	0x02
+#define SH_SENSORIDX_MAX30101	0x03
+#define SH_SENSORIDX_ACCEL	    0x04
+#define SH_NUM_CURRENT_SENSORS	5
+
+#define SH_ALGOIDX_AGC	        0x00
+#define SH_ALGOIDX_AEC			0x01
+#define SH_ALGOIDX_WHRM			0x02
+#define SH_ALGOIDX_ECG			0x03
+#define SH_ALGOIDX_BPT			0x04
+#define SH_ALGOIDX_WSPO2        0x05
+#define SH_NUM_CURRENT_ALGOS	6
+
+#define PADDING_BYTE            (0xEE)
+#define DATA_BYTE               (0xED)
+
+
+#define SS_I2C_8BIT_SLAVE_ADDR 0xAA
+#define SS_DEFAULT_CMD_SLEEP_MS 2
+#define SS_DUMP_REG_SLEEP_MS 100
+#define SS_ENABLE_SENSOR_SLEEP_MS 20
+#define SS_BOOTLOADER_ERASE_DELAY	1000
+
+#define SH_INPUT_DATA_DIRECT_SENSOR	0x00
+#define SH_INPUT_DATA_FROM_HOST		0x01
+
+#define SS_FAM_R_STATUS		0x00
+	#define SS_CMDIDX_STATUS	0x00
+		#define SS_SHIFT_STATUS_ERR				0
+		#define SS_MASK_STATUS_ERR				(0x07 << SS_SHIFT_STATUS_ERR)
+		#define SS_SHIFT_STATUS_DATA_RDY		3
+		#define SS_MASK_STATUS_DATA_RDY			(1 << SS_SHIFT_STATUS_DATA_RDY)
+		#define SS_SHIFT_STATUS_FIFO_OUT_OVR	4
+		#define SS_MASK_STATUS_FIFO_OUT_OVR		(1 << SS_SHIFT_STATUS_FIFO_OUT_OVR)
+		#define SS_SHIFT_STATUS_FIFO_IN_OVR		5
+		#define SS_MASK_STATUS_FIFO_IN_OVR		(1 << SS_SHIFT_STATUS_FIFO_IN_OVR)
+
+		#define SS_SHIFT_STATUS_LOG_OVR			6
+		#define SS_MASK_STATUS_LOG_OVR			(1 << SS_SHIFT_STATUS_LOG_OVR)
+
+		#define SS_SHIFT_STATUS_LOG_RDY			7
+		#define SS_MASK_STATUS_LOG_RDY			(1 << SS_SHIFT_STATUS_LOG_RDY)
+
+
+
+#define SS_FAM_W_MODE	0x01
+#define SS_FAM_R_MODE	0x02
+	#define SS_CMDIDX_MODE	0x00
+		#define SS_SHIFT_MODE_SHDN		0
+		#define SS_MASK_MODE_SHDN		(1 << SS_SHIFT_MODE_SHDN)
+		#define SS_SHIFT_MODE_RESET		1
+		#define SS_MASK_MODE_RESET		(1 << SS_SHIFT_MODE_RESET)
+		#define SS_SHIFT_MODE_FIFORESET	2
+		#define SS_MASK_MODE_FIFORESET	(1 << SS_SHIFT_MODE_FIFORESET)
+		#define SS_SHIFT_MODE_BOOTLDR	3
+		#define SS_MASK_MODE_BOOTLDR	(1 << SS_SHIFT_MODE_BOOTLDR)
+
+/*MYG*/
+#define SH_MODE_REQUEST_RET_BYTES        (2)
+#define SH_MODE_REQUEST_DELAY            (2)
+#define SH_STATUS_REQUEST_RET_BYTES      (2)
+#define SH_STATUS_REQUEST_DELAY          (2)
+
+
+
+#define SS_I2C_READ		0x03
+
+#define SS_FAM_W_COMMCHAN	0x10
+#define SS_FAM_R_COMMCHAN	0x11
+	#define SS_CMDIDX_OUTPUTMODE	0x00
+		#define SS_SHIFT_OUTPUTMODE_DATATYPE	0
+		#define SS_MASK_OUTPUTMODE_DATATYPE		(0x03 << SS_SHIFT_OUTPUTMODE_DATATYPE)
+			#define SS_DATATYPE_PAUSE				0
+			#define SS_DATATYPE_RAW					1
+			#define SS_DATATYPE_ALGO				2
+			#define SS_DATATYPE_BOTH				3
+		#define SS_SHIFT_OUTPUTMODE_SC_EN		2
+		#define SS_MASK_OUTPUTMODE_SC_EN		(1 << SS_SHIFT_OUTPUTMODE_SC_EN)
+	#define SS_CMDIDX_FIFOAFULL		0x01
+
+#define SS_FAM_R_OUTPUTFIFO	0x12
+	#define SS_CMDIDX_OUT_NUMSAMPLES	0x00
+	#define SS_CMDIDX_READFIFO		    0x01
+
+#define SS_FAM_R_INPUTFIFO						0x13
+	#define SS_CMDIDX_SAMPLE_SIZE				0x00
+	#define SS_CMDIDX_INPUT_FIFO_SIZE			0x01
+	#define SS_CMDIDX_SENSOR_FIFO_SIZE			0x02
+	#define SS_CMDIDX_NUM_SAMPLES_SENSOR_FIFO	0x03
+	#define SS_CMDIDX_NUM_SAMPLES_INPUT_FIFO	0x04
+
+#define SS_FAM_W_INPUTFIFO	0x14
+	#define SS_CMDIDN_WRITEFIFO		0x00
+	#define SS_CMDIDX_WRITE_FIFO    0x00
+
+#define SS_FAM_W_WRITEREG		0x40
+#define SS_FAM_R_READREG		0x41
+#define SS_FAM_R_REGATTRIBS		0x42
+#define SS_FAM_R_DUMPREG		0x43
+
+#define SS_FAM_W_SENSORMODE	0x44
+#define SS_FAM_R_SENSORMODE	0x45
+
+//TODO: Fill in known configuration parameters
+#define SS_FAM_W_ALGOCONFIG	0x50
+#define SS_FAM_R_ALGOCONFIG	0x51
+	#define SS_CFGIDX_AGC_TARGET		0x00
+	#define SS_CFGIDX_AGC_CORR_COEFF	0x01
+	#define SS_CFGIDX_AGC_SENSITIVITY	0x02
+	#define SS_CFGIDX_AGC_SMP_AVG		0x03
+
+	#define SS_CFGIDX_WHRM_SR			0x00
+	#define SS_CFGIDX_WHRM_MAX_HEIGHT	0x01
+	#define SS_CFGIDX_WHRM_MAX_WEIGHT	0x02
+	#define SS_CFGIDX_WHRM_MAX_AGE		0x03
+	#define SS_CFGIDX_WHRM_MIN_HEIGHT	0x04
+	#define SS_CFGIDX_WHRM_MIN_WEIGHT	0x05
+	#define SS_CFGIDX_WHRM_MIN_AGE		0x06
+	#define SS_CFGIDX_WHRM_DEF_HEIGHT	0x07
+	#define SS_CFGIDX_WHRM_DEF_WEIGHT	0x08
+	#define SS_CFGIDX_WHRM_DEF_AGE		0x09
+	#define SS_CFGIDX_WHRM_INIT_HR		0x0A
+	// additional for WHRM_AEC_SCD
+	#define SS_CFGIDX_WHRM_AEC_ENABLE						0x0B
+	#define SS_CFGIDX_WHRM_SCD_ENABLE						0x0C
+	#define SS_CFGIDX_WHRM_ADJ_TARGET_PD_CURRENT_PERIOD		0x0D
+	#define SS_CFGIDX_WHRM_SCD_DEBOUNCE_WINDOW				0x0E
+	#define SS_CFGIDX_WHRM_MOTION_MAG_THRESHOLD				0x0F
+	#define SS_CFGIDX_WHRM_MIN_PD_CURRENT			    	0x10
+	#define SS_CFGIDX_WHRM_PD_CONFIG				    	0x11
+
+    	// config for WSPO2
+	#define SS_CFGIDX_WSPO2_CAL								0x00
+	#define SS_CFGIDX_WSPO2_SR								0x01
+	#define SS_CFGIDX_WSPO2_ALGO_MODE						0x02
+	#define SS_CFGIDX_WSPO2_AGC_MODE						0x03
+	#define SS_CFGIDX_WSPO2_MOTION_DET						0x04
+	#define SS_CFGIDX_WSPO2_MOTION_PERIOD					0x05
+	#define SS_CFGIDX_WSPO2_MOTION_THRESHOLD 				0x06
+	#define SS_CFGIDX_WSPO2_AGC_TIMEOUT						0x07
+	#define SS_CFGIDX_WSPO2_TIMEOUT							0x08
+	#define SS_CFGIDX_WSPO2_PD_CONFIG						0x09
+
+	#define SS_CFGIDX_BP_USE_MED		0x00
+	#define SS_CFGIDX_BP_SYS_BP_CAL		0x01
+	#define SS_CFGIDX_BP_DIA_BP_CAL		0x02
+	#define SS_CFGIDX_BP_CAL_DATA		0x03
+	#define SS_CFGIDX_BP_EST_DATE		0x04
+	#define SS_CFGIDX_BP_EST_NONREST	0x05
+
+#define SS_FAM_W_ALGOMODE	0x52
+#define SS_FAM_R_ALGOMODE	0x53
+
+#define SS_FAM_W_EXTERNSENSORMODE	0x60
+#define SS_FAM_R_EXTERNSENSORMODE	0x61
+
+#define SS_FAM_R_SELFTEST    0x70
+
+#define SS_FAM_W_BOOTLOADER	0x80
+	#define SS_CMDIDX_SETIV			0x00
+	#define SS_CMDIDX_SETAUTH		0x01
+	#define SS_CMDIDX_SETNUMPAGES	0x02
+	#define SS_CMDIDX_ERASE			0x03
+	#define SS_CMDIDX_SENDPAGE		0x04
+	#define SS_CMDIDX_ERASE_PAGE	0x05
+#define SS_FAM_R_BOOTLOADER	0x81
+	#define SS_CMDIDX_BOOTFWVERSION	0x00
+	#define SS_CMDIDX_PAGESIZE		0x01
+
+#define SS_FAM_W_BOOTLOADER_CFG	0x82
+#define SS_FAM_R_BOOTLOADER_CFG	0x83
+	#define SS_CMDIDX_BL_SAVE		0x00
+	#define SS_CMDIDX_BL_ENTRY		0x01
+		#define SS_BL_CFG_ENTER_BL_MODE		0x00
+		#define SS_BL_CFG_EBL_PIN			0x01
+		#define SS_BL_CFG_EBL_POL			0x02
+	#define SS_CMDIDX_BL_EXIT		0x02
+		#define SS_BL_CFG_EXIT_BL_MODE		0x00
+		#define SS_BL_CFG_TIMEOUT			0x01
+
+/* Enable logging/debugging */
+#define SS_FAM_R_LOG				0x90
+	#define SS_CMDIDX_R_LOG_DATA	0x00
+	#define SS_CMDIDX_R_LOG_LEN		0x01
+
+	#define SS_CMDIDX_R_LOG_LEVEL	0x02
+		#define SS_LOG_DISABLE		0x00
+		#define SS_LOG_CRITICAL		0x01
+		#define SS_LOG_ERROR		0x02
+		#define SS_LOG_INFO			0x04
+		#define SS_LOG_DEBUG		0x08
+
+#define SS_FAM_W_LOG_CFG			0x91
+	#define SS_CMDIDX_LOG_GET_LEVEL	0x00
+	#define SS_CMDIDX_LOG_SET_LEVEL	0x01
+
+#define SS_FAM_R_IDENTITY			0xFF
+	#define SS_CMDIDX_PLATTYPE		0x00
+	#define SS_CMDIDX_PARTID		0x01
+	#define SS_CMDIDX_REVID			0x02
+	#define SS_CMDIDX_FWVERSION		0x03
+	#define SS_CMDIDX_AVAILSENSORS	0x04
+	#define SS_CMDIDX_DRIVERVER		0x05
+	#define SS_CMDIDX_AVAILALGOS	0x06
+	#define SS_CMDIDX_ALGOVER		0x07
+
+
+/* Newly added ones; checko for collosion or repeats with the ones above */
+#define SS_RESET_TIME	10
+#define SS_STARTUP_TO_BTLDR_TIME	20
+#define SS_STARTUP_TO_MAIN_APP_TIME	1000
+
+#define SS_MAX_SUPPORTED_SENSOR_NUM	0xFE
+#define SS_MAX_SUPPORTED_ALGO_NUM	0xFE
+
+#define SS_APPPLICATION_MODE   0x00
+#define SS_BOOTLOADER_MODE     0x08
+
+typedef enum {
+	SS_SUCCESS             =0x00,
+	SS_ERR_COMMAND         =0x01,
+	SS_ERR_UNAVAILABLE     =0x02,
+	SS_ERR_DATA_FORMAT     =0x03,
+	SS_ERR_INPUT_VALUE     =0x04,
+	SS_ERR_BTLDR_GENERAL   =0x80,
+	SS_ERR_BTLDR_CHECKSUM  =0x81,
+	SS_ERR_TRY_AGAIN       =0xFE,
+	SS_ERR_UNKNOWN         =0xFF,
+
+} SS_STATUS;
+
+
+
+/* ***************************************************************************************** *
+ *																							 *
+ *   SENSOR HUB COMMUNICATION INTERFACE ( Defined in MAX32664 User Guide ) API FUNCTIONS     *
+ *																							 *
+ *																							 *
+ * ***************************************************************************************** */
+
+
+/**
+* @brief	Func to write to sensor hub via sending generic command byte sequences
+*
+* @param[in]	tx_buf   - command byte sequence
+* @param[in]	tx_len   - command byte sequence length in bytes
+* @param[in]	sleep_ms - time to wait for sensor hub to report statuss
+*
+* @return 1 byte status: 0x00 (SS_SUCCESS) on success
+*/
+int sh_write_cmd( uint8_t *tx_buf,
+		          int tx_len,
+				  int sleep_ms );
+
+
+/**
+* @brief	Func to write to sensor hub via sending generic command byte sequences and data bytes
+*
+* @param[in]	cmd_bytes      - command byte sequence
+* @param[in]	cmd_bytes_len  - command byte sequence length in bytes
+* @param[in]    data           - data byte array to be sent following cmd bytes
+* @param[in]    data_len       - data array size in bytes
+* @param[in]    cmd_delay_ms   - time to wait for sensor hub to report status
+*
+* @return 1 byte status: 0x00 (SS_SUCCESS) on success
+*/
+int sh_write_cmd_with_data(uint8_t *cmd_bytes,
+		                   int cmd_bytes_len,
+                           uint8_t *data,
+						   int data_len,
+                           int cmd_delay_ms);
+
+
+/**
+* @brief	Func to read from sensor hub via sending generic command byte sequences
+*
+* @param[in]	cmd_bytes      - command byte sequence
+* @param[in]	cmd_bytes_len  - command byte sequence length in bytes
+* @param[in]    data           - data byte array to be sent following cmd bytes
+* @param[in]    data_len       - data array size in bytes
+* @param[out]   rxbuf          - byte buffer to store incoming data (including status byte)
+* @param[in]    rxbuf_sz       - incoming data buffer size in bytes ( to prevent overflow)
+* @param[in]    cmd_delay_ms   - time to wait for sensor hub to report status
+*
+* @return 1 byte status: 0x00 (SS_SUCCESS) on success
+*/
+int sh_read_cmd( uint8_t *cmd_bytes,
+		         int cmd_bytes_len,
+	             uint8_t *data,
+				 int data_len,
+	             uint8_t *rxbuf,
+				 int rxbuf_sz,
+                 int sleep_ms );
+
+
+/**
+* @brief	func to read sensor hub status
+* @param[out]	hubStatus   - pointer to output byte sesnor hub status will be written
+* @details	 ensor hub status byte:   [2:0] ->  0 : no Err ,              1: comm failure with sensor
+ *                                    [3]   ->  0 : FIFO below threshold; 1: FIFO filled to threshold or above.
+ *                                    [4]   ->  0 : No FIFO overflow;     1: Sensor Hub Output FIFO overflowed, data lost.
+ *                                    [5]   ->  0 : No FIFO overflow;     1: Sensor Hub Input FIFO overflowed, data lost.
+ *                                    [6]   ->  0 : Sensor Hub ready;     1: Sensor Hub is busy processing.
+ *                                    [6]   ->  reserved.
+*
+* @return 1 byte status: 0x00 (SS_SUCCESS) on success
+*/
+int sh_get_sensorhub_status(uint8_t *hubStatus);
+
+
+/**
+* @brief	func to read sensor operating mode
+*
+* @param[in]	hubMode   - pointer to output byte mode will be written
+* @details      0x00: application operating mode
+*               0x08: bootloader operating mode
+*
+* @return 1 byte status: 0x00 (SS_SUCCESS) on success
+*/
+int sh_get_sensorhub_operating_mode(uint8_t *hubMode);
+
+
+/**
+* @brief	func to set sensor hub operating mode
+*
+* @param[out]	hubMode   - pointer to output byte mode will be written
+* @details      0x00: application operating mode
+*               0x02: soft reset
+*               0x08: bootloader operating mode
+*
+* @return 1 byte status: 0x00 (SS_SUCCESS) on success
+*/
+int sh_set_sensorhub_operating_mode(uint8_t hubMode);
+
+
+/**
+* @brief	func to set sensorhub data output mode
+*
+* @param[in]	data_type : 1 byte output format
+* @details      outpur format 0x00 : no data
+ *                            0x01 : sensor data  SS_DATATYPE_RAW
+ *                            0x02 : algo data    SS_DATATYPE_ALGO
+ *                            0x03 : algo+sensor  SS_DATATYPE_BOTH
+*
+* @return 1 byte status: 0x00 (SS_SUCCESS) on success
+*/
+int sh_set_data_type(int data_type, bool sc_en);
+
+
+/**
+* @brief	func to get sensorhub data output mode
+*
+* @param[out]	data_type   - pointer to  byte, output format will be written to.
+*
+* @param[out]    sc_en     -  pointer to  boolean, sample count enable/disable status format will be written to.
+*                            If true, SmartSensor is prepending data with 1 byte sample count.
+*
+* @details      output format 0x00 : only algorithm data
+ *                            0x01 : only raw sensor data
+ *                            0x02 : algo + raw sensor data
+ *                            0x03 : no data
+*
+* @return 1 byte status: 0x00 (SS_SUCCESS) on success
+*/
+int sh_get_data_type(int *data_type, bool *sc_en);
+
+
+/**
+ * @brief	func to set the number of samples for the SmartSensor to collect
+ *			before issuing an mfio event reporting interrupt
+ *
+ * @param[in]	thresh - Number of samples (1-255) to collect before interrupt
+ *
+ * @return 1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_set_fifo_thresh( int threshold );
+
+
+/**
+ * @brief	func to get the number of samples the SmartSensor will collect
+ *			before issuing an mfio event reporting interrupt
+ *
+ * @param[out]	thresh - Number of samples (1-255) collected before interrupt
+ *
+ * @return 1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_get_fifo_thresh(int *thresh);
+
+
+/**
+ * @brief	func to check that the SmartSensor is connected
+ *
+ * @return 1 byte connection status 0x00: on connection
+ */
+int sh_ss_comm_check(void);
+
+
+/**
+* @brief	func to get the number of available samples in SmartSensor output FIFO
+*
+* @param[out]	numSamples -  number of data struct samples (1-255)
+*
+* @return 1 byte status: 0x00 (SS_SUCCESS) on success
+*/
+int sh_num_avail_samples(int *numSamples);
+
+
+/**
+* @brief	func to pull samples from SmartSensor output FIFO
+*
+* @param[in]	numSamples  - number of data struct samples to be pulled
+* @param[in]    sampleSize  - size of cumulative data sample struct (based on enabled sesnors+algorithms) in bytes
+* @param[out]   databuf     - buffer samples be written
+* @param[in]    databufSize - size of provided buffer size samples to be written
+*
+* @return 1 byte status: 0x00 (SS_SUCCESS) on success
+*/
+int sh_read_fifo_data( int numSamples, int sampleSize, uint8_t* databuf, int databufSz);
+
+
+/**
+ * @brief	func to set register of a device onboard SmartSensor
+ *
+ * @param[in] idx   - Index of device to read
+ * @param[in] addr  - Register address
+ * @param[in] val   - Register value
+ * @param[in] regSz - Size of sensor device register in bytes
+ *
+ * @return	1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_set_reg(int idx, uint8_t addr, uint32_t val, int regSz);
+
+
+/**
+ * @brief	func to read register from a device onboard SmartSensor
+ *
+ * @param[in]  idx - Index of device to read
+ * @param[in]  addr - Register address
+ * @param[out] val - Register value
+ *
+ * @return	1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_get_reg(int idx, uint8_t addr, uint32_t *val);
+
+
+// depricated: int sh_sensor_enable( int idx , int sensorSampleSz);
+/**
+ * @brief	func to enable a sensor device onboard SmartSensor
+ *
+ * @param[in] idx             - index of sensor device( i.e max8614x) to enable
+ * @param[in] sensorSampleSz  - sample size of sensor device( i.e max8614x) to enable
+ * @param[in] ext_mode        - enable extermal data input to Sensot Hub, ie accelerometer data for WHRM+WSPo2
+ *
+ * @return	1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_sensor_enable( int idx , int sensorSampleSz , uint8_t ext_mode );
+
+
+/**
+ * @brief	func to disable a device on the SmartSensor
+ *
+ * @param[in] idx - Index of device
+ *
+ * @return	1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_sensor_disable( int idx );
+
+
+/**
+ * @brief	func to get the total number of samples the input FIFO can hold
+ *
+ * @param[in] fifo_size - intger input FIFO capacity will be written to.
+ *
+ * @return	1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_get_input_fifo_size(int *fifo_size);
+
+
+/**
+ * @brief	func to send ass external sensor data (accelerometer) to sensor hub's input FIFO
+ *
+ * @param[in]  tx_buf     - host sample data to be send to sensor hub input FIFO
+ * @param[in]  tx_buf_sz  - number of bytes of tx_buf
+ * @param[out] nb_written - number of samples succesfully written to sensor hub's input FIFO
+ *
+ * @return	1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_feed_to_input_fifo(uint8_t *tx_buf, int tx_buf_sz, int *nb_written);
+
+
+/**
+ * @brief	func to get the total number of bytes in the sensor hub's input FIFO
+ *
+ * @param[in]  fifo_size - total number of sample bytes available in input FIFO
+ *
+ * @return	1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_get_num_bytes_in_input_fifo(int *fifo_size);
+
+
+/**
+ * @brief	func to enable an algorithm on  SmartSensor
+ *
+ * @param[in] idx            - index of algorithm to enable
+ * @param[in] sensorSampleSz - sample size of algorithm to enable
+ *
+ * @details   idx -    0x00 : AGC
+ *                     0x01 : AEC
+ *                     0x02 : WHRM/Maximfast
+ *                     0x03 : ECG
+ *                     0x04 : BPT
+ *                     0x05 : SPo2
+ *                     0x06 : HRM/Maximfast finger
+ *
+ * @return	1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_enable_algo(int idx , int algoSampleSz);
+
+/* @sh_enable_algo + mode of the algorithm:
+ *
+ *
+ *
+ * */
+int sh_enable_algo_withmode(int idx, int mode, int algoSampleSz);
+
+/**
+ * @brief	func to disable an algorithm on the SmartSensor
+ *
+ * @param[in] idx - index of algorithm to disable
+ *
+ * @return	1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_disable_algo(int idx);
+
+
+/**
+ * @brief	func to set the value of an algorithm configuration parameter
+ *
+ * @param[in] algo_idx   - index of algorithm
+ * @param[in] cfg_idx    - index of configuration parameter
+ * @param[in] cfg Array  - byte array of configuration
+ * @param[in] cfg_sz     - size of cfg array
+ *
+ * @return 1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_set_algo_cfg(int algo_idx, int cfg_idx, uint8_t *cfg, int cfg_sz);
+
+
+/**
+ * @brief	func to get the value of an algorithm configuration parameter
+ *
+ * @param[in] algo_idx  - index of algorithm
+ * @param[in] cfg_idx   - index of configuration parameter
+ * @param[out] cfg      - array of configuration bytes to be filled in
+ * @param[in] cfg_sz    - number of configuration parameter bytes to be read
+ *
+ * @return 1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_get_algo_cfg(int algo_idx, int cfg_idx, uint8_t *cfg, int cfg_sz);
+
+/**
+ * @brief   func to pull sensor, algo data sample bytes from sensor hub. outpur buffer, Content of the buffer depends on
+ *          enabled sensors, algorithms and their sample sizes.
+ *
+ * @param[out] databuf      - byte buffer to hold pulled samples
+ * @param[in]  databufLen   - size of provided databuf in bytes
+ * @param[out] nSamplesRea  - number of pulled samples in databuf
+ *
+ * @return N/A
+ */
+//void sh_ss_execute_once( uint8_t *databuf , int databufLen , int *nSamplesRead);
+int sh_ss_execute_once( uint8_t *databuf , int databufLen , int *nSamplesRead);
+
+
+
+
+
+
+/* ***************************************************************************************** *
+ *																							 *
+ *			PHASE2 ADDITIONS                     									         *
+ *                                                    										 *
+ * ***************************************************************************************** */
+
+
+/**
+ * @brief		run the self test commands
+ * param[in]	idx - the id of the sensor for the self test
+ * param[in]	result - self-test response
+ * param[in]	sleep_ms - duration of wait for read command
+ *
+ * @return		1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+SS_STATUS self_test(int idx, uint8_t *result, int sleep_ms = SS_DEFAULT_CMD_SLEEP_MS);
+int sh_self_test(int idx, uint8_t *result, int sleep_ms);
+
+
+/**
+ * @brief		transition from bootloder mode to application mode
+ *
+ * @return		1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_exit_from_bootloader(void);
+
+
+/**
+ * @brief		transition from application mode to bootloader mode
+ *
+ * @return		1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_put_in_bootloader(void);
+
+/**
+ * @brief	Check if SmartSensor is in bootloader mode
+ *
+ * @return	1 byte mode info : 1 if in bootloader mode, 0 if in main app, -1 if comm error
+ */
+int sh_checkif_bootldr_mode(void);
+
+/**
+* @brief	Get a string representing the SmartSensor firmware version
+* @details	If in bootloader mode, returns bootloader version
+*
+* @return   Pointer to firmware version string
+*/
+const char* sh_get_hub_fw_version(void);
+
+/**
+* @brief	Get a string representing the SmartSensor algo version
+* @details	If in bootloader mode, returns bootloader version
+*
+* @return   Pointer to algo version string
+*/
+const char* sh_get_hub_algo_version(void);
+
+
+/**
+ * @brief		send raw string to I2C
+ * @param[in]	rawdata - Raw data string, after slave address
+ * @param[out]	rawdata_sz - Raw data size
+ *
+ * @return      1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int  sh_send_raw(uint8_t *rawdata, int rawdata_sz);
+
+/**
+ * @brief		get length of hub debug log data available
+ * @param[out]	log_len - length of hub log data available
+ *
+ * @return      1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_get_log_len(int *log_len);
+
+
+/**
+ * @brief		read hub debug log data available
+ * @details	    first call sh_get_log_len() to get available log data in bytes then
+ *              call this function with parameter num_bytes with a value smaller then available log data in bytes
+ *
+ * @param[in]	num_bytes  - number of log data bytes to be read
+ * @param[in]	log_buf_sz - byte size of buffer log data will be dumped to
+ * @param[out]	log_buf    - byte buffer log data will be dumped to
+ *
+ * @return      1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success
+ */
+int sh_read_ss_log(int num_bytes, uint8_t *log_buf, int log_buf_sz);
+
+
+
+
+/* ***************************************************************************************** *
+ *																							 *
+ *			BOOTLOADER ADDITIONS                     									         *
+ *                                                    										 *
+ * ***************************************************************************************** */
+int sh_get_bootloader_pagesz(int *pagesz);
+int sh_set_bootloader_numberofpages(const int pageCount);
+int sh_set_bootloader_iv(const uint8_t *ivbytes);
+int sh_set_bootloader_iv(uint8_t iv_bytes[]);
+int sh_set_bootloader_auth(uint8_t auth_bytes[]);
+int sh_set_bootloader_erase(void);
+int sh_bootloader_flashpage(uint8_t *flashDataPreceedByCmdBytes , const int page_size);
+int sh_set_bootloader_delayfactor(const int factor );
+const int sh_get_bootloader_delayfactor(void);
+int sh_set_ebl_mode(const uint8_t mode);
+const int sh_get_ebl_mode(void);
+int sh_reset_to_bootloader(void);
+int sh_reset_to_main_app(void);
+
+int sh_debug_reset_to_bootloader(void);
+
+int exit_from_bootloader(void);
+
+
+/* *************************************************************************************** *
+ * DEMO SPECIFIC DECLERATIONS, NOT RELATED TO SENSOR HUB INTERFACE API.                    *
+ *                                                                                         *
+ *                                                                                         *                                                                                         *
+ * *****************************************************************************************/
+
+void sh_init_hwcomm_interface();
+bool sh_has_mfio_event(void);
+void sh_enable_irq_mfioevent(void);
+void sh_disable_irq_mfioevent(void);
+void sh_clear_mfio_event_flag(void);
+int sh_hard_reset(int wakeupMode);
+
+extern uint8_t sh_write_buf[];
+
+/*
+#ifdef __cplusplus
+}
+#endif
+*/
+
+
+
+#endif /* _SENSOR_HUB_H */
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SHMAX8614X/HostAccelHelper.cpp	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+ * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Maxim Integrated
+ * Products, Inc. shall not be used except as stated in the Maxim Integrated
+ * Products, Inc. Branding Policy.
+ *
+ * The mere transfer of this software does not imply any licenses
+ * of trade secrets, proprietary technology, copyrights, patents,
+ * trademarks, maskwork rights, or any other form of intellectual
+ * property whatsoever. Maxim Integrated Products, Inc. retains all
+ * ownership rights.
+ *******************************************************************************
+ */
+#include "HostAccelHelper.h"
+#include "mbed.h"
+#include "bmi160.h"
+#include "CircularBuffer.h"
+
+#define BUF_SIZE (32)
+
+I2C I2CM2(P5_7, P6_0); /* SDA, SCL */
+InterruptIn bmi160_int_pin(P3_6);
+BMI160_I2C bmi160_dev(&I2CM2, BMI160_I2C::I2C_ADRS_SDO_LO, &bmi160_int_pin);
+CircularBuffer<accel_data_t, BUF_SIZE> glbl_BMI160_QUEUE;
+
+
+static BMI160_I2C *pbmi160;
+
+
+
+
+void CSTMR_SH_HostAccelerometerInitialize() {
+	pbmi160 = &bmi160_dev;
+	pbmi160->reset();
+	glbl_BMI160_QUEUE.reset();
+	wait_ms(20);
+}
+
+
+void CSTMR_SH_HostAccelerometerSetDefaults() {
+	pbmi160->BMI160_DefaultInitalize();
+}
+
+int CSTMR_SH_HostAccelerometerSetSampleRate(int sampleRate) {
+	return pbmi160->setSampleRate(sampleRate);
+}
+
+int CSTMR_SH_HostAccelerometerEnableDataReadyInterrupt() {
+	return pbmi160->enable_data_ready_interrupt();
+}
+
+int CSTMR_SH_HostAccelerometerGet_sensor_xyz(accel_data_t *accel_data) {
+	int ret = 0;
+	BMI160::SensorData stacc_data = {0};
+
+	if(pbmi160 == NULL)
+		return -1;
+
+	if (pbmi160) {
+		ret = pbmi160->getSensorXYZ(stacc_data, BMI160::SENS_2G);
+		if (ret < 0)
+			return ret;
+	}
+
+	accel_data->x = stacc_data.xAxis.scaled;
+	accel_data->y = stacc_data.yAxis.scaled;
+	accel_data->z = stacc_data.zAxis.scaled;
+	accel_data->x_raw = stacc_data.xAxis.raw;
+	accel_data->y_raw = stacc_data.yAxis.raw;
+	accel_data->z_raw = stacc_data.zAxis.raw;
+
+	return ret;
+}
+
+
+int CSTMR_SH_HostAccelerometerEnqueueData(accel_data_t *accel_data) {
+	int ret = 0;
+	if(glbl_BMI160_QUEUE.full())
+		ret = -1;
+	else {
+		glbl_BMI160_QUEUE.push(*accel_data);
+	}
+	return ret;
+}
+
+int CSTMR_SH_HostAccelerometerGetDataCount() {
+	return glbl_BMI160_QUEUE.size();
+}
+
+int CSTMR_SH_HostAccelerometerDequeuData(accel_data_t *accel_data) {
+	int ret = 0;
+
+	if(glbl_BMI160_QUEUE.empty()) {
+		ret = -1;
+	} else {
+		glbl_BMI160_QUEUE.pop(*accel_data);
+	}
+	return ret;
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SHMAX8614X/HostAccelHelper.h	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+ * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Maxim Integrated
+ * Products, Inc. shall not be used except as stated in the Maxim Integrated
+ * Products, Inc. Branding Policy.
+ *
+ * The mere transfer of this software does not imply any licenses
+ * of trade secrets, proprietary technology, copyrights, patents,
+ * trademarks, maskwork rights, or any other form of intellectual
+ * property whatsoever. Maxim Integrated Products, Inc. retains all
+ * ownership rights.
+ *******************************************************************************
+ */
+
+#ifndef _HOST_ACCEL_HELPER_H_
+#define _HOST_ACCEL_HELPER_H_
+
+#include <stdint.h>
+
+/* Struct defining the sample of accelerometer
+ * Note: as alogorithms expect data as mg or g ; calculations needs to be done over raws accel sensordata and convert to mg or g
+ *       acceld data is feed to sensor hub in mg or g format for all 3 axis,s data. Float definitions below are for mg and g
+ *       calculations and can be modified to work with fixed point data type.
+ *
+ * */
+typedef struct _accel_data_t {
+	float x;
+	float y;
+	float z;
+	int16_t x_raw;
+	int16_t y_raw;
+	int16_t z_raw;
+} accel_data_t;
+
+/**
+ * @brief	Initialize the accelerometer on the host device
+ */
+void CSTMR_SH_HostAccelerometerInitialize();
+
+/**
+ * @brief	Set default parameters for the accelerometer
+ */
+void CSTMR_SH_HostAccelerometerSetDefaults();
+
+/**
+ * @brief	Set the sampling rate of the accelerometer
+ *
+ *
+ * @return	0 on SUCCESS
+ */
+int CSTMR_SH_HostAccelerometerSetSampleRate(int sampleRate);
+
+/**
+ * @brief	Enable data ready interrupt of the accelerometer
+ *
+ *
+ * @return	0 on SUCCESS
+ */
+int CSTMR_SH_HostAccelerometerEnableDataReadyInterrupt();
+
+/**
+ * @brief	Gets a sample from the accelerometer if the sample is ready
+ *
+ *
+ * @return	0 on SUCCESS
+ */
+int CSTMR_SH_HostAccelerometerGet_sensor_xyz(accel_data_t *accel_data);
+
+/**
+ * @brief	Add the given sample to the accelerometer queue
+ *
+ *
+ * @return	0 on SUCCESS
+ */
+int CSTMR_SH_HostAccelerometerEnqueueData(accel_data_t *accel_data);
+
+/**
+ * @brief	Get the sample count in the accelerometer queue
+ *
+ *
+ * @return	0 on SUCCESS
+ */
+int CSTMR_SH_HostAccelerometerGetDataCount();
+
+/**
+ * @brief	Get a sample from the accelerometer queue
+ *
+ *
+ * @return	0 on SUCCESS
+ */
+int CSTMR_SH_HostAccelerometerDequeuData(accel_data_t *accel_data);
+
+
+
+
+
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SHMAX8614X/SH_Max8614x_BareMetal.cpp	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,1262 @@
+/*******************************************************************************
+ * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+ * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Maxim Integrated
+ * Products, Inc. shall not be used except as stated in the Maxim Integrated
+ * Products, Inc. Branding Policy.
+ *
+ * The mere transfer of this software does not imply any licenses
+ * of trade secrets, proprietary technology, copyrights, patents,
+ * trademarks, maskwork rights, or any other form of intellectual
+ * property whatsoever. Maxim Integrated Products, Inc. retains all
+ * ownership rights.
+ *******************************************************************************
+ */
+#include "SH_Max8614x_BareMetal.h"
+#include "SHComm.h"
+#include "HostAccelHelper.h"
+#include <string.h> //for memset
+#include <stdint.h>
+
+#include "demoDefinitions.h"
+
+uint16_t HrmResult       = 0;
+uint16_t SPO2Result      = 0;
+uint8_t  HrmConfidence   = 0;
+uint8_t  SPo2Confidence  = 0;
+
+
+//#define SERIALOUT printf
+
+#if defined(DEBUG_INFO)
+	#define __DBGMESSAGE( str , val ) {printf(str, val);}
+#else
+	#define __DBGMESSAGE( str , val )
+#endif
+
+
+// Defines
+#define SSMAX8614X_REG_SIZE  		1
+#define SSMAX8614X_MODE1_DATASIZE  18				//Taken from API doc
+#define SSWHRM_MODE1_DATASIZE 		6				//Taken from API doc
+#define SSWSPO2_MODE1_DATASIZE  	9				// added for wspo2
+#define SSACCEL_MODE1_DATASIZE  	6				//Taken from API doc
+#define SSAGC_MODE1_DATASIZE  		0				//Taken from API doc
+#define SSBPT_MODE1_2_DATASIZE  	4				//Taken from API doc /* TODO */
+
+#define MIN_MACRO(a,b) ((a)<(b)?(a):(b))
+
+// sensor configuration
+//#define ENABLE_SENSOR_HUB_ACCEL
+#define USE_HOST_ACCEL
+// algorithm configuration
+#define ENABLE_WHRM_AND_SP02
+#define ENABLE_WSP02
+// end of senor and algorithm configuration
+#define MAX_NUM_WR_ACC_SAMPLES			 5
+#define BMI160_SAMPLE_RATE				25
+// end of defines
+
+//function pointer use to perform arithmetic operation
+typedef void (*rx_data_callback)(uint8_t *);
+typedef struct {
+	int data_size;
+	rx_data_callback rx_data_parser;
+} ss_data_req;
+
+typedef struct {
+	int16_t x;
+	int16_t y;
+	int16_t z;
+} accel_mode1_data;
+
+typedef struct {
+	uint32_t led1;
+	uint32_t led2;
+	uint32_t led3;
+	uint32_t led4;
+	uint32_t led5;
+	uint32_t led6;
+} max8614x_mode1_data;
+
+typedef struct {
+	uint16_t hr;
+	uint8_t hr_conf;
+	uint16_t spo2;
+	uint8_t status;
+} whrm_mode1_data;
+
+
+typedef struct {  /// added for WSPO2
+	uint16_t r;
+	uint8_t spo2_conf;
+	uint16_t spo2;
+	uint8_t percentComplete;
+	uint8_t lowSignalQualityFlag;
+	uint8_t motionFlag;
+	uint8_t status;   //isSpo2Calculated;
+} wspo2_mode1_data;
+
+typedef struct Max86140_SH_Status_Tracker {
+	uint8_t sensor_data_from_host;
+	uint8_t data_type_enabled;					// what type of data is enabled
+	uint8_t sample_count_enabled;				// does me11 provide sample count
+	uint32_t sample_count;
+	uint8_t data_buf_storage[512];				// store data read from SH
+	ss_data_req algo_callbacks[SH_NUM_CURRENT_ALGOS];
+	ss_data_req sensor_callbacks[SH_NUM_CURRENT_SENSORS];
+	uint8_t sensor_enabled_mode[SH_NUM_CURRENT_SENSORS];
+	uint8_t algo_enabled_mode[SH_NUM_CURRENT_ALGOS];
+	int input_fifo_size;
+} Max86140_SH_Status_Tracker_t;
+
+// Max8614x Default Callbacks
+void max8614x_data_rx(uint8_t* data_ptr)
+{
+	max8614x_mode1_data sample;
+	sample.led1 = (data_ptr[0] << 16) | (data_ptr[1] << 8) | data_ptr[2];
+	sample.led2 = (data_ptr[3] << 16) | (data_ptr[4] << 8) | data_ptr[5];
+	sample.led3 = (data_ptr[6] << 16) | (data_ptr[7] << 8) | data_ptr[8];
+	sample.led4 = (data_ptr[9] << 16) | (data_ptr[10] << 8) | data_ptr[11];
+	sample.led5 = (data_ptr[12] << 16) | (data_ptr[13] << 8) | data_ptr[14];
+	sample.led6 = (data_ptr[15] << 16) | (data_ptr[16] << 8) | data_ptr[17];
+
+	//SERIALOUT("led1=%.6X led2=%.6X led3=%.6X led4=%.6X led5=%.6X led6=%.6X\r\n",
+	//		sample.led1, sample.led2, sample.led3, sample.led4, sample.led5, sample.led6);
+
+	//enqueue(&max8614x_queue, &sample);
+}
+void whrm_data_rx(uint8_t* data_ptr) {
+	//See API doc for data format
+	whrm_mode1_data sample;
+	sample.hr = (data_ptr[0] << 8) | data_ptr[1];
+	sample.hr_conf = data_ptr[2];
+	sample.spo2 = (data_ptr[3] << 8) | data_ptr[4];
+	sample.status = data_ptr[5];
+	HrmResult  = sample.hr / 10;
+	HrmConfidence = sample.hr_conf;
+	SERIALOUT("hr_c=%d\r\n", HrmResult);
+#if defined(DEBUG_INFO)
+	SERIALOUT("hr=%.1f conf=%d spo2=%d status=%d\r\n", (float)sample.hr / 10.0, sample.hr_conf, sample.spo2, sample.status);
+#endif
+	//enqueue(&whrm_queue, &sample);
+}
+
+void wspo2_data_rx(uint8_t* data_ptr)
+{
+	//See API doc for data format
+	wspo2_mode1_data sample;
+	sample.r = (data_ptr[0] << 8) | data_ptr[1];  // already x10
+	sample.spo2_conf = data_ptr[2];
+	sample.spo2 = (data_ptr[3] << 8) | data_ptr[4]; // already x10
+	sample.percentComplete = data_ptr[5];
+	sample.lowSignalQualityFlag = data_ptr[6];
+	sample.motionFlag = data_ptr[7];
+	sample.status = data_ptr[8];
+	SPO2Result = sample.spo2 / 10;
+	SPo2Confidence = sample.spo2_conf;
+#if defined(DEBUG_INFO)
+	SERIALOUT("r=%.1f SpO2Conf=%d SpO2=%.1f prcntComp=%d lowSig=%d motion=%d isCalc=%d\r\n", (float)sample.r / 10.0, sample.spo2_conf, (float)sample.spo2/10.0, sample.percentComplete, sample.lowSignalQualityFlag , sample.motionFlag, sample.status);
+#endif
+	//enqueue(&wspo2_queue, &sample);
+}
+
+void accel_data_rx(uint8_t* data_ptr) {
+	//See API doc for data format
+	accel_mode1_data sample;
+	sample.x = (data_ptr[0] << 8) | data_ptr[1];
+	sample.y = (data_ptr[2] << 8) | data_ptr[3];
+	sample.z = (data_ptr[4] << 8) | data_ptr[5];
+#if defined(DEBUG_INFO)
+	//SERIALOUT("x:%d, y:%d, z:%d\r\n", sample.x, sample.y, sample.z);
+#endif
+}
+
+void agc_data_rx(uint8_t* data_ptr) {
+	//NOP: AGC does not collect data
+}
+// end of Max8614x Default Callbacks
+
+
+static Max86140_SH_Status_Tracker * get_config_struct() {
+
+    /* assigns a static adress to configuration struct*/
+	static Max86140_SH_Status_Tracker glbl_max8614x_status_track;
+	return &glbl_max8614x_status_track;
+}
+
+void initialize_config_struct() {
+	Max86140_SH_Status_Tracker *p_glbl_max8614x_status_track = get_config_struct();
+	/*
+	 * Desc: Configuration init flow, Perform this action at init stage of data acquisition. Raw sesnsor data buffer pointer is input to each
+	 *       enabled sensor/algorithm,s funtion that is responsible to extract numeric data from data byte stream from sensor hub.
+	 *
+	 *       - Append Sensor Raw Data structure with raw sensor data sample size and pointer to function of sensor that is reposible to parse
+	 *         data byte stream from sesnor hub and extract sensor numeric data.
+	 *       - Append accompanying sensors to main state of sensor. ie Accelerometer from Host with sensor data sample size and pointer to function of
+	 *         sensor that is reposible to parse data byte stream from sesnor hub and extract sensor numeric data.
+	 *       - Append algorithms to be enabled  with algorithm data sample size and pointer to function of
+	 *         algorithm that is reposible to parse data byte stream from sensor hub and extract sensor numeric data.
+	 *
+	 * */
+
+	//set all the values to 0
+	memset(p_glbl_max8614x_status_track, 0, sizeof(*p_glbl_max8614x_status_track));
+	// max8614x
+	p_glbl_max8614x_status_track->sensor_callbacks[SH_SENSORIDX_MAX8614X].data_size = SSMAX8614X_MODE1_DATASIZE;
+	p_glbl_max8614x_status_track->sensor_callbacks[SH_SENSORIDX_MAX8614X].rx_data_parser = &max8614x_data_rx;
+	// accelerometer
+	p_glbl_max8614x_status_track->sensor_callbacks[SH_SENSORIDX_ACCEL].data_size = SSACCEL_MODE1_DATASIZE;
+	p_glbl_max8614x_status_track->sensor_callbacks[SH_SENSORIDX_ACCEL].rx_data_parser = &accel_data_rx;
+	// agc
+	p_glbl_max8614x_status_track->algo_callbacks[SH_ALGOIDX_AGC].data_size = SSAGC_MODE1_DATASIZE;
+	p_glbl_max8614x_status_track->algo_callbacks[SH_ALGOIDX_AGC].rx_data_parser = &agc_data_rx;
+	// whrm
+	p_glbl_max8614x_status_track->algo_callbacks[SH_ALGOIDX_WHRM].data_size = SSWHRM_MODE1_DATASIZE;
+	p_glbl_max8614x_status_track->algo_callbacks[SH_ALGOIDX_WHRM].rx_data_parser = &whrm_data_rx;
+	// spo2
+	p_glbl_max8614x_status_track->algo_callbacks[SH_ALGOIDX_WSPO2].data_size = SSWSPO2_MODE1_DATASIZE;
+	p_glbl_max8614x_status_track->algo_callbacks[SH_ALGOIDX_WSPO2].rx_data_parser = &wspo2_data_rx;
+}
+
+
+void SH_Max8614x_get_reg(uint8_t addr, uint32_t *val) {
+	int status = sh_get_reg(SH_SENSORIDX_MAX8614X, addr, val);
+
+	if (status == 0) {
+		__DBGMESSAGE("\r\n reg_val=%02X err=0 \r\n", ((uint8_t)*val))
+	} else {
+		__DBGMESSAGE("\r\n err=%d\r\n", -1)
+	}
+
+	return;
+}
+
+int CSTMR_SH_FeedAccDataIntoSH(Max86140_SH_Status_Tracker_t *p_max8614x_status_track) {
+	static accel_data_t peek_buf[MAX_NUM_WR_ACC_SAMPLES];
+	static uint8_t tx_buf[MAX_NUM_WR_ACC_SAMPLES * sizeof(accel_mode1_data) + 2]; // 2 bytes for the command
+	if(!p_max8614x_status_track->sensor_data_from_host) {
+		return -1;
+	} else {
+		accel_data_t accel_data = {0};
+		accel_mode1_data acc_sample;
+		int num_tx, num_samples, num_bytes = 0, num_wr_bytes = 0;
+		int num_written_samples, nb_expected;
+		int ret = 0;
+
+		// get accelerometer data
+		ret = CSTMR_SH_HostAccelerometerGet_sensor_xyz(&accel_data);
+		if (ret < 0)
+			return ret;
+
+		if(CSTMR_SH_HostAccelerometerEnqueueData(&accel_data) != 0) {
+			__DBGMESSAGE("Thrown an accel sample\n", NULL)
+		}
+
+		if(CSTMR_SH_HostAccelerometerGetDataCount() < MAX_NUM_WR_ACC_SAMPLES) {
+			return -1;
+		}
+
+		ret = sh_get_num_bytes_in_input_fifo(&num_bytes);
+		if (ret != 0) {
+			__DBGMESSAGE("Unable to read num bytes in input fifo\r\n", NULL)
+			return -1;
+		}
+		num_tx = p_max8614x_status_track->input_fifo_size - num_bytes;
+		if (num_tx <= 0) {
+			__DBGMESSAGE("num_tx can't be negative\r\n",NULL)
+			return -1;
+		}
+		num_samples = num_tx / sizeof(accel_mode1_data);
+		num_samples = MIN_MACRO(num_samples, MAX_NUM_WR_ACC_SAMPLES);
+		num_tx = num_samples * sizeof(accel_mode1_data);
+		if (num_samples == 0) {
+			__DBGMESSAGE("Input FIFO is Full\r\n",NULL)
+			return -1;
+		}
+
+		for(int i = 0; i < num_samples; ++i) {
+			ret |= CSTMR_SH_HostAccelerometerDequeuData(&peek_buf[i]);
+		}
+		if (ret != 0) {
+			__DBGMESSAGE("CSTMR_SH_HostAccelerometerDequeuData failed\r\n",NULL)
+			return -1;
+		}
+
+
+		for (int i = 2, j = 0; j < num_samples; i+= sizeof(accel_mode1_data), j++) {
+			accel_data = peek_buf[j];
+			acc_sample.x = (int16_t)(accel_data.x*1000);
+			acc_sample.y = (int16_t)(accel_data.y*1000);
+			acc_sample.z = (int16_t)(accel_data.z*1000);
+			tx_buf[i] = acc_sample.x;
+			tx_buf[i + 1] = acc_sample.x >> 8;
+			tx_buf[i + 2] = acc_sample.y;
+			tx_buf[i + 3] = acc_sample.y >> 8;
+			tx_buf[i + 4] = acc_sample.z;
+			tx_buf[i + 5] = acc_sample.z >> 8;
+
+		}
+
+		ret = sh_feed_to_input_fifo(tx_buf, num_tx + 2, &num_wr_bytes);
+		if(ret != 0) {
+			__DBGMESSAGE("sh_feed_to_input_fifo\r\n",NULL)
+			return -1;
+		}
+		num_written_samples = num_wr_bytes / sizeof(accel_mode1_data);
+		if(num_written_samples != num_samples) {
+			__DBGMESSAGE("num_written_samples failed\r\n",NULL)
+			return -1;
+		}
+	}
+	return 0;
+}
+
+
+void SH_Max8614x_set_reg(uint8_t addr, uint32_t val) {
+	int status;
+	status = sh_set_reg(SH_SENSORIDX_MAX8614X, addr, val, SSMAX8614X_REG_SIZE);
+	__DBGMESSAGE("\r\n err=%d\r\n", status);
+}
+
+
+
+int SH_Max8614x_data_report_execute(void) {
+
+	int num_samples, databufLen;
+	uint8_t *databuf;
+
+
+	Max86140_SH_Status_Tracker_t *p_glbl_max8614x_status_track = get_config_struct();
+
+	// prepare the buffer to store the results
+	databuf = p_glbl_max8614x_status_track->data_buf_storage;
+	databufLen = sizeof(p_glbl_max8614x_status_track->data_buf_storage);
+
+	// poll SH
+	sh_ss_execute_once(databuf, databufLen, &num_samples);
+	//__DBGMESSAGE( "nsamplesFIFO: %d \r\n" , num_samples)
+
+	if(num_samples > 0 && num_samples <255) {
+		//Skip status byte
+		uint8_t *data_ptr = &databuf[1];
+
+		int i = 0;
+		for (i = 0; i < num_samples; i++) {
+			int sh_data_type = p_glbl_max8614x_status_track->data_type_enabled;
+			if (p_glbl_max8614x_status_track->sample_count_enabled) {
+				p_glbl_max8614x_status_track->sample_count = *data_ptr++;
+			}
+			//Chop up data and send to modules with enabled sensors
+			if (sh_data_type == SS_DATATYPE_RAW || sh_data_type == SS_DATATYPE_BOTH) {
+				for (int i = 0; i < SH_NUM_CURRENT_SENSORS; i++) {
+					if (p_glbl_max8614x_status_track->sensor_enabled_mode[i]) {
+						p_glbl_max8614x_status_track->sensor_callbacks[i].rx_data_parser(data_ptr);
+						data_ptr += p_glbl_max8614x_status_track->sensor_callbacks[i].data_size;
+					}
+				}
+			}
+			if (sh_data_type == SS_DATATYPE_ALGO || sh_data_type == SS_DATATYPE_BOTH) {
+				for (int i = 0; i < SH_NUM_CURRENT_ALGOS; i++) {
+					if (p_glbl_max8614x_status_track->algo_enabled_mode[i]) {
+						p_glbl_max8614x_status_track->algo_callbacks[i].rx_data_parser(data_ptr);
+						data_ptr += p_glbl_max8614x_status_track->algo_callbacks[i].data_size;
+					}
+				}
+			}
+		}
+        /* JUST*/
+		CSTMR_SH_FeedAccDataIntoSH(p_glbl_max8614x_status_track);
+	}
+	// feed accelerometer into me11
+	//////////////////CSTMR_SH_FeedAccDataIntoSH(p_glbl_max8614x_status_track);
+
+
+	return num_samples;
+}
+
+/*MYG: added for Vimo Duan on 26.12.2018 */
+static int SH_Max8614x_set_default_spo2cfg(void){
+
+	//const uint32_t val[3] = {0x00000000 , 0xfff33dc3, 0x009e943f};
+	/*static uint8_t CalCoef[12] = { 0x00, 0x00, 0x00, 0x00,
+	                                 0xff, 0xf3, 0x3d, 0xc3,
+								     0x00, 0x9e, 0x94, 0x3f };*/
+
+	static uint8_t CalCoef[12] = { 0xff, 0xe6, 0x91, 0x96,
+								   0x00, 0x0c, 0xb7, 0x35,
+								   0x00, 0x98, 0x96, 0x80 };
+
+	 int status = sh_set_algo_cfg(SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_CAL, &CalCoef[0], 12);
+
+}
+
+int SH_Max8614x_algo_init(enum enAlgoMode paramAlgoMode) {
+
+	/*
+	 *
+	 * */
+	int status;
+	Max86140_SH_Status_Tracker_t *p_glbl_max8614x_status_track = get_config_struct();
+	if(p_glbl_max8614x_status_track->algo_enabled_mode[SH_ALGOIDX_WHRM] ||
+			p_glbl_max8614x_status_track->algo_enabled_mode[SH_ALGOIDX_WSPO2]) {
+		    __DBGMESSAGE("\r\n Algo already enabled\r\n",NULL)
+		return -1;
+	}
+
+	if(paramAlgoMode == kAlgoModeHeartRate) {
+		status = sh_enable_algo(SH_ALGOIDX_WHRM, SSWHRM_MODE1_DATASIZE);
+		if (status != SS_SUCCESS) {
+			__DBGMESSAGE("\r\n err=%d\r\n", COMM_GENERAL_ERROR)
+			__DBGMESSAGE("FAILED at line %d, enable whrm\n", __LINE__)
+			return status;
+		}
+		p_glbl_max8614x_status_track->algo_enabled_mode[SH_ALGOIDX_WHRM] = 0x01;
+	} else {
+		status = SH_Max8614x_set_default_spo2cfg();
+		status = sh_enable_algo(SH_ALGOIDX_WSPO2, SSWSPO2_MODE1_DATASIZE);
+		if (status != SS_SUCCESS) {
+			__DBGMESSAGE("\r\n err=%d\r\n", COMM_GENERAL_ERROR)
+			__DBGMESSAGE("FAILED at line %d, enable whrm\n", __LINE__)
+			return status;
+		}
+		p_glbl_max8614x_status_track->algo_enabled_mode[SH_ALGOIDX_WSPO2] = 0x01;
+	}
+}
+
+
+
+int SH_Max8614x_default_init(enum enAlgoMode paramAlgoMode) {
+	/*
+	 *  Desc: Initialization flow to get algorithm estimation results:
+	 *        1. initialize algorithm config struct
+	 *        2. enable data type to both raw sensor and algorithm data
+	 *        3. get input fifo size to learn fifo capacity
+	 *        4. set fifo threshold for mfio event frequency
+	 *        5. enable sensor to acquire ppg data
+	 *        6. enable accompanying accel sensor
+	 *        7. enable algorithm
+	 *        8. Sensor Hub now starts to write raw sensor/algorithm data to its data report FIFO which
+	 *           reports mfio event when data size determined by fifo threshold is written to report fifo
+	 *           data can be read by SH_Max8614x_data_report_execute function.
+	 *
+	 * */
+
+	int status;
+
+	// first initialize the global config struct
+	initialize_config_struct();
+	Max86140_SH_Status_Tracker_t *p_glbl_max8614x_status_track = get_config_struct();
+
+	// get input fifo size
+	status = sh_get_input_fifo_size(&p_glbl_max8614x_status_track->input_fifo_size);
+	if (status != SS_SUCCESS) {
+		__DBGMESSAGE("\r\n err=%d\r\n", COMM_GENERAL_ERROR)
+		__DBGMESSAGE("FAILED at line %d\n", __LINE__)
+		return COMM_GENERAL_ERROR;;
+	}
+
+	// enable both data stype
+	p_glbl_max8614x_status_track->data_type_enabled = SS_DATATYPE_BOTH;
+	p_glbl_max8614x_status_track->sample_count_enabled = false;
+	status = sh_set_data_type(p_glbl_max8614x_status_track->data_type_enabled,
+							  p_glbl_max8614x_status_track->sample_count_enabled);
+	if (status != 0) {
+		__DBGMESSAGE("\r\n err=%d\r\n", COMM_GENERAL_ERROR)
+		__DBGMESSAGE("FAILED at line %d\n", __LINE__)
+		return COMM_GENERAL_ERROR;
+	}
+
+	status = sh_set_fifo_thresh(5);
+	if (status != 0) {
+		__DBGMESSAGE("\r\n err=%d\r\n", COMM_GENERAL_ERROR)
+		__DBGMESSAGE("FAILED at line %d\n", __LINE__)
+		return COMM_GENERAL_ERROR;
+	}
+
+	status = sh_sensor_enable(SH_SENSORIDX_MAX8614X, SSMAX8614X_MODE1_DATASIZE, SH_INPUT_DATA_DIRECT_SENSOR);
+	if (status != 0) {
+		__DBGMESSAGE("\r\n err=%d\r\n",  COMM_GENERAL_ERROR)
+		__DBGMESSAGE("FAILED at line %d\n", __LINE__)
+		return COMM_GENERAL_ERROR;
+	}
+	p_glbl_max8614x_status_track->sensor_enabled_mode[SH_SENSORIDX_MAX8614X] = 0x01;
+
+#ifdef ENABLE_SENSOR_HUB_ACCEL
+	status = sh_sensor_enable(SH_SENSORIDX_ACCEL, SSACCEL_MODE1_DATASIZE, SH_INPUT_DATA_DIRECT_SENSOR);
+	if (status != SS_SUCCESS) {
+		__DBGMESSAGE("\r\n err=%d\r\n", COMM_GENERAL_ERROR)
+		__DBGMESSAGE("FAILED at line %d\n", __LINE__)
+	}
+	p_glbl_max8614x_status_track->sensor_data_from_host = false;
+	p_glbl_max8614x_status_track->sensor_enabled_mode[SH_SENSORIDX_ACCEL] = 0x01;
+#elif defined(USE_HOST_ACCEL)
+	CSTMR_SH_HostAccelerometerInitialize();
+	CSTMR_SH_HostAccelerometerSetDefaults();
+	status = CSTMR_SH_HostAccelerometerSetSampleRate(BMI160_SAMPLE_RATE);
+	if (status != 0) {
+		__DBGMESSAGE("Unable to set BMI160's sample rate\n",NULL)
+		__DBGMESSAGE("\r\n err=%d\r\n", COMM_GENERAL_ERROR)
+		__DBGMESSAGE("FAILED at line %d\n", __LINE__)
+		return status;
+	}
+
+	status = CSTMR_SH_HostAccelerometerEnableDataReadyInterrupt();
+	if(status != 0){
+		__DBGMESSAGE("Unable to enable BMI160 Interrupt, ret: %d\n", status)
+		return status;
+	}
+
+	status = sh_sensor_enable(SH_SENSORIDX_ACCEL, SSACCEL_MODE1_DATASIZE, SH_INPUT_DATA_FROM_HOST);
+	if (status != 0) {
+		__DBGMESSAGE("\r\n err=%d\r\n", COMM_GENERAL_ERROR)
+		__DBGMESSAGE("FAILED at line %d\n", __LINE__)
+		return status;
+	}
+	p_glbl_max8614x_status_track->sensor_data_from_host = true;
+	p_glbl_max8614x_status_track->sensor_enabled_mode[SH_SENSORIDX_ACCEL] = 0x01;
+#endif
+	status = SH_Max8614x_algo_init(paramAlgoMode);
+	if(status != 0) {
+		__DBGMESSAGE("AlgoInitFailed\r\n",NULL)
+	}
+
+	    __DBGMESSAGE("\r\n err=%d\r\n",  status)
+	return status;
+}
+
+void SH_Max8614x_stop() {
+	sh_disable_irq_mfioevent();
+	Max86140_SH_Status_Tracker_t *p_glbl_max8614x_status_track = get_config_struct();
+
+	for(int i = 0; i < SH_NUM_CURRENT_SENSORS; ++i) {
+		if(p_glbl_max8614x_status_track->sensor_enabled_mode[i]) {
+			p_glbl_max8614x_status_track->sensor_enabled_mode[i] = 0;
+			sh_sensor_disable(i);
+		}
+
+	}
+
+	for(int i = 0; i < SH_NUM_CURRENT_ALGOS; ++i) {
+		if(p_glbl_max8614x_status_track->algo_enabled_mode[i]) {
+			p_glbl_max8614x_status_track->algo_enabled_mode[i] = 0;
+			sh_disable_algo(i);
+		}
+	}
+
+	if(p_glbl_max8614x_status_track->sensor_data_from_host) {
+		CSTMR_SH_HostAccelerometerInitialize();
+		p_glbl_max8614x_status_track->sensor_data_from_host = 0;
+	}
+
+	sh_clear_mfio_event_flag();
+	sh_enable_irq_mfioevent();
+}
+
+
+
+
+
+
+/* **********************************************************************************************
+ * 																							   	*
+ *   					   COMMAND INTERFACE RELATED METHODS								 	*
+ *																								*
+ * **********************************************************************************************/
+
+
+
+//MYG: CHECK FOR STDIN WITH SSCANF < WHY THEY NEEDED PARSE_CMD?????   PAY ATTENTION: HEX AND/OR DECIMAL PARAMETER ENRTY!!!
+
+static int SH_Max8614x_set_singleparamcfg(const char *cfg , int algo_idx, int cfg_idx ){
+	int status = -1;
+	uint32_t val;
+	if( sscanf(cfg, "%*s %*s %*s %10x", &val) == 1 ){
+		uint8_t Temp[1] = { (uint8_t)(val) };
+		status = sh_set_algo_cfg(algo_idx, cfg_idx , &Temp[0], 1);
+	}
+    return status;  // if command error return -1 if operational error return >0 error
+}
+
+static int SH_Max8614x_get_singleparamcfg( int algo_idx, int cfg_idx , int *val){
+	// CMD: get_cfg spo2 samplerate
+
+	int status = -1;
+	uint8_t rxBuff[1+1]; // first byte is status
+
+	status = sh_get_algo_cfg(algo_idx, cfg_idx, &rxBuff[0], 2);
+    if( status == 0){
+	    *val = rxBuff[1];
+     }else
+    	*val = -1;
+
+    return status;
+}
+
+static int SH_Max8614x_set_singleparamcfg_(const char *cfg , const int algo_idx, const int cfg_idx , const int paramsz){
+	int status = -1;
+	uint32_t val;
+	if(paramsz == 1 || paramsz == 2) {
+    	if( sscanf(cfg, "%*s %*s %*s %10x", &val) == 1 ){
+    		uint8_t Temp[2] = { (uint8_t)((val >> 8) & 0xFF),  (uint8_t) (val & 0xFF) };
+    		status = sh_set_algo_cfg(algo_idx, cfg_idx , &Temp[2-paramsz], paramsz);
+    	}
+	}
+    return status;  // if command error return -1 if operational error return >0 error
+}
+
+
+static int SH_Max8614x_get_singleparamcfg_( const int algo_idx, const int cfg_idx ,const int paramsz, int *val){
+	// CMD: get_cfg spo2 samplerate
+
+	int tmp;
+	int status = -1;
+	uint8_t rxBuff[3]; // first byte is status 1/2 bytes cfgparam asked for.
+	if(paramsz == 1 || paramsz == 2) {
+	    status = sh_get_algo_cfg(algo_idx, cfg_idx, &rxBuff[0], paramsz+1);
+		if( status == 0){
+			tmp = (int)((rxBuff[1]<<(8*(paramsz-1))) + rxBuff[2]*(paramsz-1));  // MYG: CHECK IF TRUE!
+		}else
+			tmp = -1;
+	}else
+		tmp = -1;
+
+	*val = tmp;
+	return status;
+}
+
+
+
+/************************************WSPO2 METHODS**********************************************/
+
+int SH_Max8614x_get_wspo2_dataformat(const char *null_arg){
+
+	 SERIALOUT("\r\n format={smpleCnt,8},"
+			"{irCnt,20},{redCnt,20},{accelX,14,3},{accelY,14,3},"
+			"{accelZ,14,3},{r,12},{wspo2conf,8},{spo2,11,1},{wspo2percentcomplete,8},{wspo2lowSNR,1},{wspo2motion,1},{status,8} err=0\r\n");
+     return 0;
+}
+
+int SH_Max8614x_measure_wspo2(const char *null_arg){
+
+	 int status;
+	 SH_Max8614x_stop();
+	 status = SH_Max8614x_default_init(kAlgoModeSPO2);
+	 if(status == 0)
+		 SERIALOUT("whrm started \r\n");
+	 else
+		 SERIALOUT("ERR");
+
+    return status;
+
+}
+
+int SH_Max8614x_set_ppgreg(const char *addr_value_args){
+
+	//CMD: set_reg ppgsensor 0xAA 0xAA
+	int addr,val,status;
+	if( sscanf(addr_value_args,"%*s %*s %4x %10x", &addr , &addr ) == 2 ){
+        status = sh_set_reg(SH_SENSORIDX_MAX8614X, (uint8_t) addr, (uint32_t) val, SSMAX8614X_REG_SIZE);
+        if(status == 0)
+        	SERIALOUT("OK \r\n");
+	}else
+		    SERIALOUT("ERR \r\n");
+
+    return status;
+}
+
+int SH_Max8614x_get_ppgreg(const char *addr_arg){
+
+	//CMD: get_reg ppgsensor 0xAA
+	int addr;
+	int status = -1;
+	uint32_t val;
+
+	if( sscanf(addr_arg,"%*s %*s %4x", &addr) == 1 ){
+		int status = sh_get_reg(SH_SENSORIDX_MAX8614X, (uint8_t) addr, &val);
+        if(status == 0)
+        	SERIALOUT("reg_val=%02X \r\n",val);
+	}else
+		    SERIALOUT("ERR \r\n");
+
+    return status;
+}
+
+int SH_Max8614x_self_test_ppg(const char *null_arg){
+
+	// MYG: mfio interaction needed!
+    return -1;
+}
+
+int SH_Max8614x_self_test_acc(const char *null_arg){
+	// MYG: mfio interaction needed!
+	return -1;
+}
+
+int SH_Max8614x_set_spo2_calibration(const char *calib_args){
+
+    //CMD: set_cfg spo2 cal 0xAAAAAAAA 0xBBBBBBBB 0xCCCCCCCC
+	int status = -1;
+	uint32_t val[3];
+
+	if( sscanf(calib_args,"%*s %*s %*s %10x %10x %10x", &val[0], &val[1], &val[2] ) == 3 ){
+
+		uint8_t CalCoef[12] = { (uint8_t)((val[0] >> (3*8)) & 0xFF),  (uint8_t)((val[0] >> (2*8)) & 0xFF), (uint8_t)((val[0] >> (1*8)) & 0xFF), (uint8_t)((val[0] >> (0*8)) & 0xFF), // A
+								(uint8_t)((val[1] >> (3*8)) & 0xFF),  (uint8_t)((val[1] >> (2*8)) & 0xFF), (uint8_t)((val[1] >> (1*8)) & 0xFF), (uint8_t)((val[1] >> (0*8)) & 0xFF), // B
+								(uint8_t)((val[2] >> (3*8)) & 0xFF),  (uint8_t)((val[2] >> (2*8)) & 0xFF), (uint8_t)((val[2] >> (1*8)) & 0xFF), (uint8_t)((val[2] >> (0*8)) & 0xFF)  // C
+							   };
+
+		status = sh_set_algo_cfg(SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_CAL, &CalCoef[0], 12);
+		if( status == 0)
+			SERIALOUT("OK \r\n");
+		else
+			SERIALOUT("ERR \r\n");
+	}else
+		    SERIALOUT("CMDERR \r\n");
+
+    return status;
+}
+
+
+int SH_Max8614x_get_spo2_calibration(const char *null_arg){
+
+	uint8_t rxBuff[12+1];  // first byte is status
+	uint32_t val[3];
+    int status = sh_get_algo_cfg(SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_CAL, &rxBuff[0], sizeof(rxBuff));
+    val[0] =  (rxBuff[1]<< 24) +  (rxBuff[2]<< 16) + (rxBuff[3]<< 8) + (rxBuff[4]<< 0);
+    val[1] =  (rxBuff[5]<< 24) +  (rxBuff[6]<< 16) + (rxBuff[7]<< 8) + (rxBuff[8]<< 0);
+    val[2] =  (rxBuff[9]<< 24) +  (rxBuff[10]<< 16) + (rxBuff[11]<< 8) + (rxBuff[12]<< 0);
+
+    SERIALOUT("spo2_calib: A=0x%x B=0x%x C=0x%x" , val[0], val[1], val[2] );
+    return 0;
+}
+
+
+int SH_Max8614x_set_spo2_algomode(const char *mode_arg){
+
+	int status = SH_Max8614x_set_singleparamcfg( mode_arg , SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_ALGO_MODE );
+    if( status == 0)
+    	SERIALOUT("OK \r\n");
+    else {
+    	if( status == -1)
+    		SERIALOUT("CMDERR \r\n");
+    	else
+    		SERIALOUT("ERR \r\n");
+    }
+    return status;
+}
+
+int SH_Max8614x_get_spo2_algomode(const char *null_arg){
+
+
+	int val;
+	int status =  SH_Max8614x_get_singleparamcfg( SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_ALGO_MODE , &val);
+    if(val != -1)
+    	SERIALOUT("spo2_algo_mode= %d \r\n", val);
+    else
+    	SERIALOUT("ERR \r\n");
+
+    return status;
+
+}
+
+int SH_Max8614x_set_spo2_samplerate(const char *srate_arg){
+    //CMD: set_cfg spo2 samplerate sampleRate
+	int status = -1;
+	uint32_t val;
+	if( sscanf(srate_arg,"%*s %*s %*s %3u", &val) == 1 ){
+		uint8_t Temp[1] = { (uint8_t)(val) };
+		status = sh_set_algo_cfg(SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_SR, &Temp[0], 1);
+        if(status == 0)
+        	SERIALOUT("OK \r\n");
+        else
+        	SERIALOUT("ERR \r\n");
+	}else
+		SERIALOUT("CMDERR \r\n");
+
+     return status;
+}
+
+int SH_Max8614x_get_spo2_samplerate(const char *null_arg){
+	// CMD: get_cfg spo2 samplerate
+	uint32_t val;
+	int status = -1;
+	uint8_t rxBuff[1+1]; // first byte is status
+	status = sh_get_algo_cfg(SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_SR, &rxBuff[0], sizeof(rxBuff));
+    if( status == 0){
+	    val = rxBuff[1];
+        SERIALOUT("spo2_samprate= %d \r\n", val);
+    }else
+    	SERIALOUT("ERR \r\n");
+
+    return status;
+}
+
+int SH_Max8614x_set_spo2_agcusage(const char *onoff_arg){
+
+	int status = SH_Max8614x_set_singleparamcfg( onoff_arg , SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_AGC_MODE );
+    if( status == 0)
+    	SERIALOUT("OK \r\n");
+    else {
+    	if( status == -1)
+    		SERIALOUT("CMDERR \r\n");
+    	else
+    		SERIALOUT("ERR \r\n");
+    }
+    return status;
+}
+
+int SH_Max8614x_get_spo2_agcusage(const char *null_arg){
+
+	int val;
+	int status =  SH_Max8614x_get_singleparamcfg( SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_AGC_MODE , &val);
+    if(val != -1)
+    	SERIALOUT("spo2_agc_usage= %d", val);
+    else
+    	SERIALOUT("ERR \r\n");
+
+    return status;
+}
+
+int SH_Max8614x_set_spo2_agctimeout(const char *timeout_arg){
+
+	int status = SH_Max8614x_set_singleparamcfg( timeout_arg , SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_AGC_TIMEOUT );
+    if( status == 0)
+    	SERIALOUT("OK \r\n");
+    else {
+    	if( status == -1)
+    		SERIALOUT("CMDERR \r\n");
+    	else
+    		SERIALOUT("ERR \r\n");
+    }
+    return status;
+}
+
+
+int SH_Max8614x_get_spo2_agctimeout(const char *null_arg){
+
+	int val;
+	int status =  SH_Max8614x_get_singleparamcfg( SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_AGC_TIMEOUT , &val);
+    if(val != -1)
+    	SERIALOUT("spo2_agctimeout= %d", val);
+    else
+    	SERIALOUT("ERR \r\n");
+
+    return status;
+
+}
+
+int SH_Max8614x_set_spo2_algotimeout(const char *timeout_arg){
+
+	int status = SH_Max8614x_set_singleparamcfg( timeout_arg , SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_TIMEOUT );
+    if( status == 0)
+    	SERIALOUT("OK \r\n");
+    else {
+    	if( status == -1)
+    		SERIALOUT("CMDERR \r\n");
+    	else
+    		SERIALOUT("ERR \r\n");
+    }
+    return status;
+}
+
+int SH_Max8614x_get_spo2_algotimeout(const char *null_arg){
+
+	int val;
+	int status =  SH_Max8614x_get_singleparamcfg( SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_TIMEOUT , &val);
+    if(val != -1)
+    	SERIALOUT("spo2_algotimeout= %d", val);
+    else
+    	SERIALOUT("ERR \r\n");
+
+    return status;
+
+}
+
+int SH_Max8614x_set_spo2_motionusage(const char *onoff_arg){
+
+	int status = SH_Max8614x_set_singleparamcfg( onoff_arg, SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_MOTION_DET );
+    if( status == 0)
+    	SERIALOUT("OK \r\n");
+    else {
+    	if( status == -1)
+    		SERIALOUT("CMDERR \r\n");
+    	else
+    		SERIALOUT("ERR \r\n");
+    }
+    return status;
+}
+
+int SH_Max8614x_get_spo2_motionusage(const char *null_arg){
+
+	int val;
+	int status =  SH_Max8614x_get_singleparamcfg( SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_MOTION_DET , &val);
+    if(val != -1)
+    	SERIALOUT("spo2_motion_detection= %d", val);
+    else
+    	SERIALOUT("ERR \r\n");
+
+    return status;
+
+}
+
+int SH_Max8614x_set_spo2_motionperiod(const char *period_arg){
+
+	int status = SH_Max8614x_set_singleparamcfg_(period_arg , SH_ALGOIDX_WSPO2 , SS_CFGIDX_WSPO2_MOTION_PERIOD , 2);
+    if( status == 0)
+    	SERIALOUT("OK \r\n");
+    else {
+    	if( status == -1)
+    		SERIALOUT("CMDERR \r\n");
+    	else
+    		SERIALOUT("ERR \r\n");
+    }
+    return status;
+
+}
+
+int SH_Max8614x_get_spo2_motionperiod(const char *null_arg){
+
+	int val;
+	int status =  SH_Max8614x_get_singleparamcfg_( SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_MOTION_PERIOD, 2, &val);
+    if(val != -1)
+    	SERIALOUT("spo2_motionperiod= %d", val);
+    else
+    	SERIALOUT("ERR \r\n");
+
+    return status;
+
+}
+
+int SH_Max8614x_set_spo2_motionthresh(const char *thresh_arg){
+
+    uint32_t val;
+	int status;
+    if( sscanf(thresh_arg, "%*s %*s %*s %x", &val) == 1 ){
+
+    	    uint8_t CalCoef[4] = { (uint8_t)((val >> 24) & 0xFF),(uint8_t)((val >> 16) & 0xFF),(uint8_t)((val >> 8) & 0xFF),  (uint8_t) (val & 0xFF) };
+    	    status = sh_set_algo_cfg(SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_MOTION_THRESHOLD , &CalCoef[0], 4);
+            if(status == 0)
+            	SERIALOUT("OK \r\n");
+            else
+            	SERIALOUT("ERR \r\n");
+    }else
+    		SERIALOUT("CMDERR \r\n");
+
+    return status;
+
+}
+
+int SH_Max8614x_get_spo2_motionthresh(const char *null_arg){
+
+	int status;
+	uint32_t val;
+	uint8_t rxBuff[4+1];  // first byte is status
+
+	status = sh_get_algo_cfg(SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_MOTION_THRESHOLD, &rxBuff[0], sizeof(rxBuff));
+    if( status == 0){
+	    val = ((rxBuff[1] & 0xFF)<<24) + ((rxBuff[2] & 0xFF)<<16) + ((rxBuff[3] & 0xFF)<<8) + ((rxBuff[4] & 0xFF)<<0);
+
+        SERIALOUT("spo2_motion_thresh in hex= %x \r\n", val);
+    }else
+    	SERIALOUT("ERR \r\n");
+
+    return status;
+
+}
+
+int SH_Max8614x_set_spo2_pdiodeconfig(const char *pdcfg_arg){
+
+	int status = SH_Max8614x_set_singleparamcfg( pdcfg_arg, SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_PD_CONFIG );
+    if( status == 0)
+    	SERIALOUT("OK \r\n");
+    else {
+    	if( status == -1)
+    		SERIALOUT("CMDERR \r\n");
+    	else
+    		SERIALOUT("ERR \r\n");
+    }
+    return status;
+
+}
+
+int SH_Max8614x_get_spo2_pdiodeconfig(const char *null_arg){
+
+	int val;
+	int status =  SH_Max8614x_get_singleparamcfg( SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_PD_CONFIG , &val);
+    if(val != -1)
+    	SERIALOUT("spo2_pdiode_config= %d", val);
+    else
+    	SERIALOUT("ERR \r\n");
+
+    return status;
+}
+
+
+
+//************************************WHRM METHODS***********************************************/
+
+int SH_Max8614x_get_whrm_dataformat(const char *null_arg){
+
+	 SERIALOUT("\r\n  format={smpleCnt,16},"
+		"{grnCnt,20},{grn2Cnt,20},{accelX,14,3},{accelY,14,3},"
+		"{accelZ,14,3},{hr,12},{hrconf,8},{spo2,11,1},{activity,8} err=0\r\n" );
+      return 0;
+}
+
+int SH_Max8614x_measure_whrm(const char *null_arg){
+
+	 int status;
+	 SH_Max8614x_stop();
+	 status = SH_Max8614x_default_init(kAlgoModeHeartRate);
+	 if(status == 0)
+		 SERIALOUT("whrm started \r\n");
+	 else
+		 SERIALOUT("ERR");
+
+     return status;
+}
+
+int SH_Max8614x_set_whrm_aecusage(const char *onoff_arg){
+
+	int status = SH_Max8614x_set_singleparamcfg( onoff_arg , SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_AEC_ENABLE);
+    if( status == 0)
+    	SERIALOUT("OK \r\n");
+    else {
+    	if( status == -1)
+    		SERIALOUT("CMDERR \r\n");
+    	else
+    		SERIALOUT("ERR \r\n");
+    }
+    return status;
+
+}
+
+int SH_Max8614x_get_whrm_aecusage(const char *null_arg){
+
+	int val;
+	int status =  SH_Max8614x_get_singleparamcfg( SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_AEC_ENABLE , &val);
+    if(val != -1)
+    	SERIALOUT("whrm_aec_usage= %d", val);
+    else
+    	SERIALOUT("ERR \r\n");
+
+    return status;
+
+}
+
+int SH_Max8614x_set_whrm_scdusage(const char *onoff_arg){
+
+	int status = SH_Max8614x_set_singleparamcfg( onoff_arg , SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_SCD_ENABLE);
+    if( status == 0)
+    	SERIALOUT("OK \r\n");
+    else {
+    	if( status == -1)
+    		SERIALOUT("CMDERR \r\n");
+    	else
+    		SERIALOUT("ERR \r\n");
+    }
+    return status;
+
+}
+
+
+int SH_Max8614x_get_whrm_scdusage(const char *null_arg){
+
+	int val;
+	int status =  SH_Max8614x_get_singleparamcfg( SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_SCD_ENABLE , &val);
+    if(val != -1)
+    	SERIALOUT("whrm_scd_usage= %d", val);
+    else
+    	SERIALOUT("ERR \r\n");
+
+    return status;
+
+}
+
+int SH_Max8614x_set_whrm_scdadjperiod(const char *period_arg){
+
+	int status = SH_Max8614x_set_singleparamcfg_(period_arg , SH_ALGOIDX_WHRM , SS_CFGIDX_WHRM_ADJ_TARGET_PD_CURRENT_PERIOD , 2);
+    if( status == 0)
+    	SERIALOUT("OK \r\n");
+    else {
+    	if( status == -1)
+    		SERIALOUT("CMDERR \r\n");
+    	else
+    		SERIALOUT("ERR \r\n");
+    }
+    return status;
+}
+
+int SH_Max8614x_get_whrm_scdadjperiod(const char *null_arg){
+
+	int val;
+	int status =  SH_Max8614x_get_singleparamcfg_( SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_ADJ_TARGET_PD_CURRENT_PERIOD, 2, &val);
+    if(val != -1)
+    	SERIALOUT("whrm_scd_adjperiod= %d", val);
+    else
+    	SERIALOUT("ERR \r\n");
+
+    return status;
+
+}
+
+int SH_Max8614x_set_whrm_scddebouncewin(const char *dwindow_arg){
+
+	int status = SH_Max8614x_set_singleparamcfg_(dwindow_arg , SH_ALGOIDX_WHRM , SS_CFGIDX_WHRM_SCD_DEBOUNCE_WINDOW , 2);
+    if( status == 0)
+    	SERIALOUT("OK \r\n");
+    else {
+    	if( status == -1)
+    		SERIALOUT("CMDERR \r\n");
+    	else
+    		SERIALOUT("ERR \r\n");
+    }
+    return status;
+
+}
+int SH_Max8614x_get_whrm_scddebouncewin(const char *null_arg){
+
+	int val;
+	int status =  SH_Max8614x_get_singleparamcfg_( SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_SCD_DEBOUNCE_WINDOW , 2, &val);
+    if(val != -1)
+    	SERIALOUT("whrm_scd_debouncewin= %d", val);
+    else
+    	SERIALOUT("ERR \r\n");
+
+    return status;
+
+}
+
+int SH_Max8614x_set_whrm_motionthresh(const char *motion_arg){
+
+	int status = SH_Max8614x_set_singleparamcfg_(motion_arg , SH_ALGOIDX_WHRM , SS_CFGIDX_WHRM_MOTION_MAG_THRESHOLD , 2);
+    if( status == 0)
+    	SERIALOUT("OK \r\n");
+    else {
+    	if( status == -1)
+    		SERIALOUT("CMDERR \r\n");
+    	else
+    		SERIALOUT("ERR \r\n");
+    }
+    return status;
+
+}
+
+int SH_Max8614x_get_whrm_motionthresh(const char *null_arg){
+
+	int val;
+	int status =  SH_Max8614x_get_singleparamcfg_( SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_MOTION_MAG_THRESHOLD , 2, &val);
+    if(val != -1)
+    	SERIALOUT("whrm_motion_threshold= %d", val);
+    else
+    	SERIALOUT("ERR \r\n");
+
+    return status;
+
+}
+
+int SH_Max8614x_set_whrm_minpdiodecurr(const char *curr_arg){
+
+	int status = SH_Max8614x_set_singleparamcfg_(curr_arg, SH_ALGOIDX_WHRM , SS_CFGIDX_WHRM_MIN_PD_CURRENT , 2);
+    if( status == 0)
+    	SERIALOUT("OK \r\n");
+    else {
+    	if( status == -1)
+    		SERIALOUT("CMDERR \r\n");
+    	else
+    		SERIALOUT("ERR \r\n");
+    }
+    return status;
+
+}
+
+int SH_Max8614x_get_whrm_minpdiodecurr(const char *null_arg){
+
+	int val;
+	int status =  SH_Max8614x_get_singleparamcfg_( SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_MIN_PD_CURRENT , 2, &val);
+    if(val != -1)
+    	SERIALOUT("whrm_currentrange= %d", val);  // MYG: CHECKIF EXPRESSION IS TRUE!
+    else
+    	SERIALOUT("ERR \r\n");
+
+    return status;
+
+}
+
+int SH_Max8614x_set_whrm_pdiodeconfig(const char *cfg_arg){
+
+	int status = SH_Max8614x_set_singleparamcfg( cfg_arg , SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_PD_CONFIG);
+    if( status == 0)
+    	SERIALOUT("OK \r\n");
+    else {
+    	if( status == -1)
+    		SERIALOUT("CMDERR \r\n");
+    	else
+    		SERIALOUT("ERR \r\n");
+    }
+    return status;
+
+}
+
+int SH_Max8614x_get_whrm_pdiodeconfig(const char *null_arg){
+
+	int val;
+	int status =  SH_Max8614x_get_singleparamcfg( SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_PD_CONFIG, &val);
+    if(val != -1)
+    	SERIALOUT("whrm_pdiode_config= %d", val);
+    else
+    	SERIALOUT("ERR \r\n");
+
+    return status;
+
+}
+
+int SH_Max8614x_stop_acquisition(const char *null_arg){
+	      SH_Max8614x_stop();
+}
+
+
+
+/*FOR THIS DEMO PURPOSE*/
+int Max8614x_Set_WSPO2Mode(int mode){
+
+	uint8_t Temp[1] = { (uint8_t)(mode) };
+	int status = sh_set_algo_cfg(SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_ALGO_MODE , &Temp[0], 1);
+    return status;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SHMAX8614X/SH_Max8614x_BareMetal.h	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,236 @@
+/*******************************************************************************
+ * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+ * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Maxim Integrated
+ * Products, Inc. shall not be used except as stated in the Maxim Integrated
+ * Products, Inc. Branding Policy.
+ *
+ * The mere transfer of this software does not imply any licenses
+ * of trade secrets, proprietary technology, copyrights, patents,
+ * trademarks, maskwork rights, or any other form of intellectual
+ * property whatsoever. Maxim Integrated Products, Inc. retains all
+ * ownership rights.
+ *******************************************************************************
+ */
+#ifndef SH_Max8614x_BareMetal_H_
+#define SH_Max8614x_BareMetal_H_
+
+#include <stdint.h>
+#include <stdio.h>
+#include "demoDefinitions.h"
+
+
+#define COMM_SUCCESS        0
+#define COMM_GENERAL_ERROR  -1
+#define COMM_INVALID_PARAM  -254
+#define COMM_NOT_RECOGNIZED -255
+
+enum enAlgoMode{
+	kAlgoModeHeartRate = 0,
+	kAlgoModeSPO2      = 1,
+	kAlgoModeContSPO2  = 2,
+};
+
+/**
+ * @brief	Get the value of register at addr
+ *
+ * @param[in]	addr - adress of the register
+ * @param[out]	val - value at the register
+
+ */
+void SH_Max8614x_get_reg(uint8_t addr, uint32_t *val);
+
+/**
+* @brief	Write a value to the register at address addr
+*
+* @param[in]	addr - adress of the register to write
+* @param[in]	val - value of the register to write
+*/
+void SH_Max8614x_set_reg(uint8_t addr, uint32_t val);
+
+/**
+* @brief	Initialize Max86140 with default configuration
+*
+* @param[in] paramAlgoMode - the mode of the algorithm to initialize
+*
+* @return 0 on SUCCESS
+*/
+int SH_Max8614x_default_init(enum enAlgoMode paramAlgoMode);
+
+/**
+* @brief	Check the data stored in the Sensor Hub. Reads and prints
+* 			the data if available
+*
+*/
+int SH_Max8614x_data_report_execute(void);
+
+/**
+* @brief	Stops the active sensors and algorithms
+*
+*/
+void SH_Max8614x_stop(void);
+
+
+
+
+/*FOR THIS EXAMPLE DEMO PURPOSES*/
+int Max8614x_Set_WSPO2Mode(int mode);
+
+extern uint16_t HrmResult;
+extern uint16_t SPO2Result;
+extern uint8_t  HrmConfidence;
+extern uint8_t  SPo2Confidence;
+
+/* define to see debug messages*/
+#define DEBUG_INFO
+
+
+int SH_Max8614x_get_whrm_dataformat(const char *null_arg);
+int SH_Max8614x_get_wspo2_dataformat(const char *null_arg);
+int SH_Max8614x_set_ppgreg(const char *addr_value_args);
+int SH_Max8614x_get_ppgreg(const char *addr_arg);
+int SH_Max8614x_measure_whrm(const char *null_arg);
+int SH_Max8614x_measure_wspo2(const char *null_arg);
+int SH_Max8614x_self_test_ppg(const char *null_arg);
+int SH_Max8614x_self_test_acc(const char *null_arg);
+
+
+int SH_Max8614x_set_spo2_calibration(const char *calib_args);
+int SH_Max8614x_get_spo2_calibration(const char *null_arg);
+int SH_Max8614x_set_spo2_algomode(const char *mode_arg);
+int SH_Max8614x_get_spo2_algomode(const char *null_arg);
+int SH_Max8614x_set_spo2_samplerate(const char *srate_arg);
+int SH_Max8614x_get_spo2_samplerate(const char *null_arg);
+int SH_Max8614x_set_spo2_agcusage(const char *onoff_arg);
+int SH_Max8614x_get_spo2_agcusage(const char *null_arg);
+int SH_Max8614x_set_spo2_agctimeout(const char *timeout_arg);
+int SH_Max8614x_get_spo2_agctimeout(const char *null_arg);
+int SH_Max8614x_set_spo2_algotimeout(const char *timeout_arg);
+int SH_Max8614x_get_spo2_algotimeout(const char *null_arg);
+int SH_Max8614x_set_spo2_motionusage(const char *onoff_arg);
+int SH_Max8614x_get_spo2_motionusage(const char *null_arg);
+int SH_Max8614x_set_spo2_motionperiod(const char *period_arg);
+int SH_Max8614x_get_spo2_motionperiod(const char *null_arg);
+int SH_Max8614x_set_spo2_motionthresh(const char *thresh_arg);
+int SH_Max8614x_get_spo2_motionthresh(const char *null_arg);
+int SH_Max8614x_set_spo2_pdiodeconfig(const char *pdcfg_arg);
+int SH_Max8614x_get_spo2_pdiodeconfig(const char *null_arg);
+
+int SH_Max8614x_set_whrm_aecusage(const char *onoff_arg);
+int SH_Max8614x_get_whrm_aecusage(const char *null_arg);
+int SH_Max8614x_set_whrm_scdusage(const char *onoff_arg);
+int SH_Max8614x_get_whrm_scdusage(const char *null_arg);
+int SH_Max8614x_set_whrm_scdadjperiod(const char *period_arg);
+int SH_Max8614x_get_whrm_scdadjperiod(const char *null_arg);
+int SH_Max8614x_set_whrm_scddebouncewin(const char *dwindow_arg);
+int SH_Max8614x_get_whrm_scddebouncewin(const char *null_arg);
+int SH_Max8614x_set_whrm_motionthresh(const char *motion_arg);
+int SH_Max8614x_get_whrm_motionthresh(const char *null_arg);
+int SH_Max8614x_set_whrm_minpdiodecurr(const char *curr_arg);
+int SH_Max8614x_get_whrm_minpdiodecurr(const char *null_arg);
+int SH_Max8614x_set_whrm_pdiodeconfig(const char *cfg_arg);
+int SH_Max8614x_get_whrm_pdiodeconfig(const char *null_arg);
+int SH_Max8614x_send_raw(const char *raw_data);
+int SH_Max8614x_stop_acquisition(const char *null_arg);
+
+
+#define NUMCMDS8614X (43)
+#define CONSOLE_STR_BUF_SZ  ((int)1024);
+
+
+typedef int (*cmdExecFunc)( const char*); // typedef void (*cmdExecFunc)( const void*);
+
+typedef struct {
+	char const* cmdStr;
+	cmdExecFunc execute;
+	char const *help;
+}cmd_interface_t;
+
+
+static int command_help(const char *str);
+
+
+const cmd_interface_t CMDTABLE8614x[] = {
+
+		{  "get_format whrmdata"     		, SH_Max8614x_get_whrm_dataformat		,  "returns whrm algo sample format in terms of bit fileds"												},
+		{  "get_format wspo2data"    		, SH_Max8614x_get_wspo2_dataformat 		,  "returns wspo2 algo sample format in terms of bit fileds"											},
+		{  "enable_measurement whrm" 		, SH_Max8614x_measure_whrm 				,  "start whrm measurement with default settings"  														},
+		{  "enable_measurement wspo2"		, SH_Max8614x_measure_wspo2 			,  "start wspo2 measurement with default settings" 														},
+		{  "get_reg ppgsensor"       		, SH_Max8614x_get_ppgreg 				,  "get register value of 8614x sensor, usage:  get_reg ppgsensor rAddr(1byte)" 						},
+		{  "set_reg ppgsensor"       		, SH_Max8614x_set_ppgreg 				,  "set register value of 8614x sensor, usage :  set_reg ppgsensor rAddr(1byte) rval(1byte)" 			},
+		{  "self_test ppgsensor"     		, SH_Max8614x_self_test_ppg 			,  "starts self test of onboard ppg sensor" 															},
+		{  "self_test accel"         		, SH_Max8614x_self_test_acc 			,  "starts self test of onboard accel sensor" 															},
+		{  "set_cfg spo2 cal"        		, SH_Max8614x_set_spo2_calibration 		,  "sets spo2 calibration, usage: set_cfg spo2 cal 0xAAAAAAAA 0xBBBBBBBB 0xCCCCCCCC" 			        },
+		{  "get_cfg spo2 cal"        		, SH_Max8614x_get_spo2_calibration 		,  "gets spo2 calibration" 																				},
+		{  "set_cfg spo2 algomode"   		, SH_Max8614x_set_spo2_algomode 		,  "sets the spo2 algo mode to oneshot(0) or continious(1), usage: set_cfg spo2 algomode mode(1byte)" 	},
+		{  "get_cfg spo2 algomode"			, SH_Max8614x_get_spo2_algomode 		,  "check if spo2 is oneshot/continious" 																},
+	    {  "set_cfg spo2 samplerate" 		, SH_Max8614x_set_spo2_samplerate		,  "sets spo2 sample rate, uasge: set_cfg spo2 samplerate sampleRate(numeric value)" 					},
+		{  "get_cfg spo2 samplerate" 		, SH_Max8614x_get_spo2_samplerate 		,  "gets spo2 sample rate" 																				},
+		{  "set_cfg sop2 agc"		 		, SH_Max8614x_set_spo2_agcusage 		,  "on/off  automatic gain control in wspo, usage: set_cfg wsop2 agc X(1byte)  X: 0 off 1 on" 			},
+		{  "get_cfg sop2 agc" 				, SH_Max8614x_get_spo2_agcusage 		,  "check if agc is on/off" 																			},
+		{  "set_cfg spo2 agctimeout"  	    , SH_Max8614x_set_spo2_agctimeout 		,  "sets agc timeout for spo2, usage:  set_cfg spo2 agctimeout timeout(numeric)" 						},
+		{  "get_cfg spo2 agctimeout"        , SH_Max8614x_get_spo2_agctimeout 		,  "gets agctimeout for spo2" 																			},
+		{  "set_cfg spo2 timeout"  	        , SH_Max8614x_set_spo2_algotimeout 		,  "sets timeout for spo2 incase of no valid result, usage:  set_cfg spo2 timeout timeout(numeric)" 	},
+		{  "get_cfg spo2 timeout"           , SH_Max8614x_get_spo2_algotimeout 		,  "gets valid result timeout for spo2" 																},
+		{  "set_cfg spo2 motion"  	        , SH_Max8614x_set_spo2_motionusage 		,  "on/off motion data usage for spo2, usage: set_cfg spo2 motionenable X(1byte)  X: 0 off 1 on " 		},
+		{  "get_cfg spo2 motion"  	        , SH_Max8614x_get_spo2_motionusage		,  "checks if spo2 uses motion data" 																	},
+		{  "set_cfg spo2 motionperiod"  	, SH_Max8614x_set_spo2_motionperiod 	,  "sets motion period for spo2, usage:  set_cfg spo2 motionperiod period(numeric)" 					},
+		{  "get_cfg spo2 motionperiod"      , SH_Max8614x_get_spo2_motionperiod		,  "gets motion period for spo2" 																		},
+		{  "set_cfg spo2 motionthreshold"   , SH_Max8614x_set_spo2_motionthresh		,  "sets motion threshold for spo2, usage:  set_cfg spo2 motionthreshold thres(numeric)" 				},
+		{  "get_cfg spo2 motionthreshold"  	, SH_Max8614x_get_spo2_motionthresh 	,  "gets motion threshold for spo2" 																	},
+		{  "set_cfg spo2 pdconfig"          , SH_Max8614x_set_spo2_pdiodeconfig     ,  "sets spo2 photodiode config, usage set_cfg spo2 pdconfig X , X: 1-pd1, 2-pd2, 3-both, 4-avaraged" 	},
+		{  "get_cfg spo2 pdconfig"          , SH_Max8614x_get_spo2_pdiodeconfig     ,  "gets spo2 photodiode config" },
+		{  "set_cfg whrm aecenable"         , SH_Max8614x_set_whrm_aecusage       	,  "on/off whrm aec algo,  usage: set_cfg whrm aec X , X: 0 off 1 on" 									},
+		{  "get_cfg whrm aecenable"         , SH_Max8614x_get_whrm_aecusage       	,  "check if aec algo for whrm is on/off" 																},
+        {  "set_cfg whrm scdenable"         , SH_Max8614x_set_whrm_scdusage      	,  "on/off whrm skin contact detection,  usage: set_cfg whrm scd X , X: 0 off 1 on" 					},
+		{  "get_cfg whrm scdenable"         , SH_Max8614x_get_whrm_scdusage       	,  "check if whrm skin contact detection is on/off" 													},
+        {  "set_cfg whrm scdadjperiod"      , SH_Max8614x_set_whrm_scdadjperiod     ,  "sets photo diode adj peroiod for whrm scd algo, usage:  set_cfg whrm scdadjperiod period(numeric)" 	},
+		{  "get_cfg whrm scdadjperiod"      , SH_Max8614x_get_whrm_scdadjperiod     ,  "gets photo diode adj peroiod for whrm scd algo" 													},
+		{  "set_cfg whrm scddebouncewin"    , SH_Max8614x_set_whrm_scddebouncewin   ,  "sets debounce window for whrm scd algo, usage:  set_cfg whrm scddebouncewin window(numeric)" 		},
+		{  "get_cfg whrm scddebouncewin"    , SH_Max8614x_get_whrm_scddebouncewin   ,  "gets debounce window for whrm scd algo" 															},
+		{  "set_cfg whrm motionthreshold"   , SH_Max8614x_set_whrm_motionthresh 	,  "sets motion threshold for whrm, usage:  set_cfg whrm motionthreshold threshold(numeric)" 			},
+		{  "get_cfg whrm motionthreshold"  	, SH_Max8614x_get_whrm_motionthresh 	,  "gets motion threshold for whrm" 																	},
+		{  "set_cfg whrm minpdcurrent"      , SH_Max8614x_set_whrm_minpdiodecurr 	,  "sets photodiode current range for whrm, usage:  set_cfg whrm minpdcurrent current(numeric)" 		},
+		{  "get_cfg whrm minpdcurrent"  	, SH_Max8614x_get_whrm_minpdiodecurr 	,  "gets photodiode current rangefor whrm" 																},
+        {  "set_cfg whrm pdconfig"          , SH_Max8614x_set_whrm_pdiodeconfig 	,  "sets photdiode config for whrm, usage:  set_cfg whrmaecscd pdconfig configstring" 					},
+		{  "get_cfg whrm pdconfig"          , SH_Max8614x_get_whrm_pdiodeconfig 	,  "gets photdiode config for whrm" 																	},
+		{  "stop"                           , SH_Max8614x_stop_acquisition          ,  "stops raw&algorithm data acquisition within 8614x instance of hub"                            },
+		{  "help"                           , command_help          		        ,  "commnand info" 	}
+		//		{  "send_raw"                       , SH_Max8614x_send_raw 					,  "sends raw data to sensor hub, usage: send_raw datastring" 											},
+};
+
+
+static int command_help(const char *str){
+	int cmdIdx = 0;
+
+	SERIALOUT("AVAILABLE COMMANDS: \r\n\r\n");
+	while( cmdIdx != NUMCMDS8614X){
+		SERIALOUT(" %s : \r\n  %s \r\n\r\n", CMDTABLE8614x[cmdIdx].cmdStr , CMDTABLE8614x[cmdIdx].help );
+        cmdIdx++;
+	};
+
+}
+
+
+#endif
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/accelerometer/bmi160.cpp	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,724 @@
+/**********************************************************************
+* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+**********************************************************************/
+
+
+#include "bmi160.h"
+
+
+const struct BMI160::AccConfig BMI160::DEFAULT_ACC_CONFIG = {SENS_2G,
+                                                             ACC_US_OFF,
+                                                             ACC_BWP_2,
+                                                             ACC_ODR_8};
+
+const struct BMI160::GyroConfig BMI160::DEFAULT_GYRO_CONFIG = {DPS_2000,
+                                                               GYRO_BWP_2,
+                                                               GYRO_ODR_8};
+
+
+//*****************************************************************************
+int32_t BMI160::setSensorPowerMode(Sensors sensor, PowerModes pwrMode)
+{
+    int32_t rtnVal = -1;
+
+    switch(sensor)
+    {
+        case MAG:
+            rtnVal = writeRegister(CMD, (MAG_SET_PMU_MODE | pwrMode));
+        break;
+
+        case GYRO:
+            rtnVal = writeRegister(CMD, (GYR_SET_PMU_MODE | pwrMode));
+        break;
+
+        case ACC:
+            rtnVal = writeRegister(CMD, (ACC_SET_PMU_MODE | pwrMode));
+        break;
+
+        default:
+            rtnVal = -1;
+        break;
+    }
+
+    return rtnVal;
+}
+
+
+//*****************************************************************************
+int32_t BMI160::setSensorConfig(const AccConfig &config)
+{
+    uint8_t data[2];
+
+    data[0] = ((config.us << ACC_US_POS) | (config.bwp << ACC_BWP_POS) |
+               (config.odr << ACC_ODR_POS));
+    data[1] = config.range;
+
+    return writeBlock(ACC_CONF, ACC_RANGE, data);
+}
+
+
+//*****************************************************************************
+int32_t BMI160::setSensorConfig(const GyroConfig &config)
+{
+    uint8_t data[2];
+
+    data[0] = ((config.bwp << GYRO_BWP_POS) | (config.odr << GYRO_ODR_POS));
+    data[1] = config.range;
+
+    return writeBlock(GYR_CONF, GYR_RANGE, data);
+}
+
+
+//*****************************************************************************
+int32_t BMI160::getSensorConfig(AccConfig &config)
+{
+    uint8_t data[2];
+    int32_t rtnVal = readBlock(ACC_CONF, ACC_RANGE, data);
+
+    if(rtnVal == RTN_NO_ERROR)
+    {
+        config.range = static_cast<BMI160::AccRange>(
+        (data[1] & ACC_RANGE_MASK));
+        config.us = static_cast<BMI160::AccUnderSampling>(
+        ((data[0] & ACC_US_MASK) >> ACC_US_POS));
+        config.bwp = static_cast<BMI160::AccBandWidthParam>(
+        ((data[0] & ACC_BWP_MASK) >> ACC_BWP_POS));
+        config.odr = static_cast<BMI160::AccOutputDataRate>(
+        ((data[0] & ACC_ODR_MASK) >> ACC_ODR_POS));
+    }
+
+    return rtnVal;
+}
+
+
+//*****************************************************************************
+int32_t BMI160::getSensorConfig(GyroConfig &config)
+{
+    uint8_t data[2];
+    int32_t rtnVal = readBlock(GYR_CONF, GYR_RANGE, data);
+
+    if(rtnVal == RTN_NO_ERROR)
+    {
+        config.range = static_cast<BMI160::GyroRange>(
+        (data[1] & GYRO_RANGE_MASK));
+        config.bwp = static_cast<BMI160::GyroBandWidthParam>(
+        ((data[0] & GYRO_BWP_MASK) >> GYRO_BWP_POS));
+        config.odr = static_cast<BMI160::GyroOutputDataRate>(
+        ((data[0] & GYRO_ODR_MASK) >> GYRO_ODR_POS));
+    }
+
+    return rtnVal;
+}
+
+
+//*****************************************************************************
+int32_t BMI160::getSensorAxis(SensorAxis axis, AxisData &data, AccRange range)
+{
+    uint8_t localData[2];
+    int32_t rtnVal;
+
+    switch(axis)
+    {
+        case X_AXIS:
+            rtnVal = readBlock(DATA_14, DATA_15, localData);
+        break;
+
+        case Y_AXIS:
+            rtnVal = readBlock(DATA_16, DATA_17, localData);
+        break;
+
+        case Z_AXIS:
+            rtnVal = readBlock(DATA_18, DATA_19, localData);
+        break;
+
+        default:
+            rtnVal = -1;
+        break;
+    }
+
+    if(rtnVal == RTN_NO_ERROR)
+    {
+        data.raw = ((localData[1] << 8) | localData[0]);
+        switch(range)
+        {
+            case SENS_2G:
+                data.scaled = (data.raw/SENS_2G_LSB_PER_G);
+            break;
+
+            case SENS_4G:
+                data.scaled = (data.raw/SENS_4G_LSB_PER_G);
+            break;
+
+            case SENS_8G:
+                data.scaled = (data.raw/SENS_8G_LSB_PER_G);
+            break;
+
+            case SENS_16G:
+                data.scaled = (data.raw/SENS_16G_LSB_PER_G);
+            break;
+        }
+    }
+
+    return rtnVal;
+}
+
+
+//*****************************************************************************
+int32_t BMI160::getSensorAxis(SensorAxis axis, AxisData &data, GyroRange range)
+{
+    uint8_t localData[2];
+    int32_t rtnVal;
+
+    switch(axis)
+    {
+        case X_AXIS:
+            rtnVal = readBlock(DATA_8, DATA_9, localData);
+        break;
+
+        case Y_AXIS:
+            rtnVal = readBlock(DATA_10, DATA_11, localData);
+        break;
+
+        case Z_AXIS:
+            rtnVal = readBlock(DATA_12, DATA_13, localData);
+        break;
+
+        default:
+            rtnVal = -1;
+        break;
+    }
+
+    if(rtnVal == RTN_NO_ERROR)
+    {
+        data.raw = ((localData[1] << 8) | localData[0]);
+        switch(range)
+        {
+            case DPS_2000:
+                data.scaled = (data.raw/SENS_2000_DPS_LSB_PER_DPS);
+            break;
+
+            case DPS_1000:
+                data.scaled = (data.raw/SENS_1000_DPS_LSB_PER_DPS);
+            break;
+
+            case DPS_500:
+                data.scaled = (data.raw/SENS_500_DPS_LSB_PER_DPS);
+            break;
+
+            case DPS_250:
+                data.scaled = (data.raw/SENS_250_DPS_LSB_PER_DPS);
+            break;
+
+            case DPS_125:
+                data.scaled = (data.raw/SENS_125_DPS_LSB_PER_DPS);
+            break;
+        }
+    }
+
+    return rtnVal;
+}
+
+
+//*****************************************************************************
+int32_t BMI160::getSensorXYZ(SensorData &data, AccRange range)
+{
+    uint8_t localData[6];
+    int32_t rtnVal = readBlock(DATA_14, DATA_19, localData);
+
+	if (m_use_irq == true && bmi160_irq_asserted == false)
+		return -1;
+
+	bmi160_irq_asserted = false;
+    if(rtnVal == RTN_NO_ERROR)
+    {
+        data.xAxis.raw = ((localData[1] << 8) | localData[0]);
+        data.yAxis.raw = ((localData[3] << 8) | localData[2]);
+        data.zAxis.raw = ((localData[5] << 8) | localData[4]);
+
+        switch(range)
+        {
+            case SENS_2G:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_2G_LSB_PER_G);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_2G_LSB_PER_G);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_2G_LSB_PER_G);
+            break;
+
+            case SENS_4G:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_4G_LSB_PER_G);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_4G_LSB_PER_G);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_4G_LSB_PER_G);
+            break;
+
+            case SENS_8G:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_8G_LSB_PER_G);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_8G_LSB_PER_G);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_8G_LSB_PER_G);
+            break;
+
+            case SENS_16G:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_16G_LSB_PER_G);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_16G_LSB_PER_G);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_16G_LSB_PER_G);
+            break;
+        }
+    }
+
+    return rtnVal;
+}
+
+
+//*****************************************************************************
+int32_t BMI160::getSensorXYZ(SensorData &data, GyroRange range)
+{
+    uint8_t localData[6];
+    int32_t rtnVal = readBlock(DATA_8, DATA_13, localData);
+
+    if(rtnVal == RTN_NO_ERROR)
+    {
+        data.xAxis.raw = ((localData[1] << 8) | localData[0]);
+        data.yAxis.raw = ((localData[3] << 8) | localData[2]);
+        data.zAxis.raw = ((localData[5] << 8) | localData[4]);
+
+        switch(range)
+        {
+            case DPS_2000:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
+            break;
+
+            case DPS_1000:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
+            break;
+
+            case DPS_500:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_500_DPS_LSB_PER_DPS);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_500_DPS_LSB_PER_DPS);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_500_DPS_LSB_PER_DPS);
+            break;
+
+            case DPS_250:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_250_DPS_LSB_PER_DPS);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_250_DPS_LSB_PER_DPS);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_250_DPS_LSB_PER_DPS);
+            break;
+
+            case DPS_125:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_125_DPS_LSB_PER_DPS);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_125_DPS_LSB_PER_DPS);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_125_DPS_LSB_PER_DPS);
+            break;
+        }
+    }
+
+    return rtnVal;
+}
+
+
+//*****************************************************************************
+int32_t BMI160::getSensorXYZandSensorTime(SensorData &data,
+                                          SensorTime &sensorTime,
+                                          AccRange range)
+{
+    uint8_t localData[9];
+    int32_t rtnVal = readBlock(DATA_14, SENSORTIME_2, localData);
+    if(rtnVal == RTN_NO_ERROR)
+    {
+        data.xAxis.raw = ((localData[1] << 8) | localData[0]);
+        data.yAxis.raw = ((localData[3] << 8) | localData[2]);
+        data.zAxis.raw = ((localData[5] << 8) | localData[4]);
+
+        switch(range)
+        {
+            case SENS_2G:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_2G_LSB_PER_G);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_2G_LSB_PER_G);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_2G_LSB_PER_G);
+            break;
+
+            case SENS_4G:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_4G_LSB_PER_G);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_4G_LSB_PER_G);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_4G_LSB_PER_G);
+            break;
+
+            case SENS_8G:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_8G_LSB_PER_G);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_8G_LSB_PER_G);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_8G_LSB_PER_G);
+            break;
+
+            case SENS_16G:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_16G_LSB_PER_G);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_16G_LSB_PER_G);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_16G_LSB_PER_G);
+            break;
+        }
+
+        sensorTime.raw = ((localData[8] << 16) | (localData[7] << 8) |
+                           localData[6]);
+        sensorTime.seconds = (sensorTime.raw * SENSOR_TIME_LSB);
+    }
+
+    return rtnVal;
+}
+
+
+//*****************************************************************************
+int32_t BMI160::getSensorXYZandSensorTime(SensorData &data,
+                                          SensorTime &sensorTime,
+                                          GyroRange range)
+{
+    uint8_t localData[16];
+    int32_t rtnVal = readBlock(DATA_8, SENSORTIME_2, localData);
+    if(rtnVal == RTN_NO_ERROR)
+    {
+        data.xAxis.raw = ((localData[1] << 8) | localData[0]);
+        data.yAxis.raw = ((localData[3] << 8) | localData[2]);
+        data.zAxis.raw = ((localData[5] << 8) | localData[4]);
+
+        switch(range)
+        {
+            case DPS_2000:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
+            break;
+
+            case DPS_1000:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
+            break;
+
+            case DPS_500:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_500_DPS_LSB_PER_DPS);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_500_DPS_LSB_PER_DPS);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_500_DPS_LSB_PER_DPS);
+            break;
+
+            case DPS_250:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_250_DPS_LSB_PER_DPS);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_250_DPS_LSB_PER_DPS);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_250_DPS_LSB_PER_DPS);
+            break;
+
+            case DPS_125:
+                data.xAxis.scaled = (data.xAxis.raw/SENS_125_DPS_LSB_PER_DPS);
+                data.yAxis.scaled = (data.yAxis.raw/SENS_125_DPS_LSB_PER_DPS);
+                data.zAxis.scaled = (data.zAxis.raw/SENS_125_DPS_LSB_PER_DPS);
+            break;
+        }
+
+        sensorTime.raw = ((localData[14] << 16) | (localData[13] << 8) |
+                           localData[12]);
+        sensorTime.seconds = (sensorTime.raw * SENSOR_TIME_LSB);
+    }
+
+    return rtnVal;
+}
+
+
+//*****************************************************************************
+int32_t BMI160::getGyroAccXYZandSensorTime(SensorData &accData,
+                                           SensorData &gyroData,
+                                           SensorTime &sensorTime,
+                                           AccRange accRange,
+                                           GyroRange gyroRange)
+{
+    uint8_t localData[16];
+    int32_t rtnVal = readBlock(DATA_8, SENSORTIME_2, localData);
+    if(rtnVal == RTN_NO_ERROR)
+    {
+        gyroData.xAxis.raw = ((localData[1] << 8) | localData[0]);
+        gyroData.yAxis.raw = ((localData[3] << 8) | localData[2]);
+        gyroData.zAxis.raw = ((localData[5] << 8) | localData[4]);
+
+        accData.xAxis.raw = ((localData[7] << 8) | localData[6]);
+        accData.yAxis.raw = ((localData[9] << 8) | localData[8]);
+        accData.zAxis.raw = ((localData[11] << 8) | localData[10]);
+
+        switch(gyroRange)
+        {
+            case DPS_2000:
+                gyroData.xAxis.scaled = (gyroData.xAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
+                gyroData.yAxis.scaled = (gyroData.yAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
+                gyroData.zAxis.scaled = (gyroData.zAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
+            break;
+
+            case DPS_1000:
+                gyroData.xAxis.scaled = (gyroData.xAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
+                gyroData.yAxis.scaled = (gyroData.yAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
+                gyroData.zAxis.scaled = (gyroData.zAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
+            break;
+
+            case DPS_500:
+                gyroData.xAxis.scaled = (gyroData.xAxis.raw/SENS_500_DPS_LSB_PER_DPS);
+                gyroData.yAxis.scaled = (gyroData.yAxis.raw/SENS_500_DPS_LSB_PER_DPS);
+                gyroData.zAxis.scaled = (gyroData.zAxis.raw/SENS_500_DPS_LSB_PER_DPS);
+            break;
+
+            case DPS_250:
+                gyroData.xAxis.scaled = (gyroData.xAxis.raw/SENS_250_DPS_LSB_PER_DPS);
+                gyroData.yAxis.scaled = (gyroData.yAxis.raw/SENS_250_DPS_LSB_PER_DPS);
+                gyroData.zAxis.scaled = (gyroData.zAxis.raw/SENS_250_DPS_LSB_PER_DPS);
+            break;
+
+            case DPS_125:
+                gyroData.xAxis.scaled = (gyroData.xAxis.raw/SENS_125_DPS_LSB_PER_DPS);
+                gyroData.yAxis.scaled = (gyroData.yAxis.raw/SENS_125_DPS_LSB_PER_DPS);
+                gyroData.zAxis.scaled = (gyroData.zAxis.raw/SENS_125_DPS_LSB_PER_DPS);
+            break;
+        }
+
+        switch(accRange)
+        {
+            case SENS_2G:
+                accData.xAxis.scaled = (accData.xAxis.raw/SENS_2G_LSB_PER_G);
+                accData.yAxis.scaled = (accData.yAxis.raw/SENS_2G_LSB_PER_G);
+                accData.zAxis.scaled = (accData.zAxis.raw/SENS_2G_LSB_PER_G);
+            break;
+
+            case SENS_4G:
+                accData.xAxis.scaled = (accData.xAxis.raw/SENS_4G_LSB_PER_G);
+                accData.yAxis.scaled = (accData.yAxis.raw/SENS_4G_LSB_PER_G);
+                accData.zAxis.scaled = (accData.zAxis.raw/SENS_4G_LSB_PER_G);
+            break;
+
+            case SENS_8G:
+                accData.xAxis.scaled = (accData.xAxis.raw/SENS_8G_LSB_PER_G);
+                accData.yAxis.scaled = (accData.yAxis.raw/SENS_8G_LSB_PER_G);
+                accData.zAxis.scaled = (accData.zAxis.raw/SENS_8G_LSB_PER_G);
+            break;
+
+            case SENS_16G:
+                accData.xAxis.scaled = (accData.xAxis.raw/SENS_16G_LSB_PER_G);
+                accData.yAxis.scaled = (accData.yAxis.raw/SENS_16G_LSB_PER_G);
+                accData.zAxis.scaled = (accData.zAxis.raw/SENS_16G_LSB_PER_G);
+            break;
+        }
+
+        sensorTime.raw = ((localData[14] << 16) | (localData[13] << 8) |
+                           localData[12]);
+        sensorTime.seconds = (sensorTime.raw * SENSOR_TIME_LSB);
+    }
+
+    return rtnVal;
+}
+
+int32_t BMI160::setSampleRate(int sample_rate)
+{
+	int sr_reg_val = -1;
+	int i;
+	const uint16_t odr_table[][2] = {
+	    {25, GYRO_ODR_6}, ///<25Hz
+        {50, GYRO_ODR_7}, ///<50Hz
+        {100, GYRO_ODR_8}, ///<100Hz
+        {200, GYRO_ODR_9}, ///<200Hz
+        {400, GYRO_ODR_10}, ///<400Hz
+        {800, GYRO_ODR_11}, ///<800Hz
+        {1600, GYRO_ODR_12}, ///<1600Hz
+        {3200, GYRO_ODR_13}, ///<3200Hz
+	};
+
+	int num_sr = sizeof(odr_table)/sizeof(odr_table[0]);
+	for (i = 0; i < num_sr; i++) {
+		if (sample_rate == odr_table[i][0]) {
+			sr_reg_val = odr_table[i][1];
+			break;
+		}
+	}
+
+	if (sr_reg_val == -1)
+		return -2;
+
+	AccConfig accConfigRead;
+	if (getSensorConfig(accConfigRead) == BMI160::RTN_NO_ERROR) {
+	accConfigRead.odr = (AccOutputDataRate)sr_reg_val;
+		return setSensorConfig(accConfigRead) == BMI160::RTN_NO_ERROR ? 0 : -1;
+	} else
+		return -1;
+}
+
+
+//*****************************************************************************
+int32_t BMI160::getSensorTime(SensorTime &sensorTime)
+{
+    uint8_t localData[3];
+    int32_t rtnVal = readBlock(SENSORTIME_0, SENSORTIME_2, localData);
+
+    if(rtnVal == RTN_NO_ERROR)
+    {
+        sensorTime.raw = ((localData[2] << 16) | (localData[1] << 8) |
+                           localData[0]);
+        sensorTime.seconds = (sensorTime.raw * SENSOR_TIME_LSB);
+    }
+
+    return rtnVal;
+}
+
+
+//*****************************************************************************
+int32_t BMI160::getTemperature(float *temp)
+{
+    uint8_t data[2];
+    uint16_t rawTemp;
+
+    int32_t rtnVal = readBlock(TEMPERATURE_0, TEMPERATURE_1, data);
+    if(rtnVal == RTN_NO_ERROR)
+    {
+        rawTemp = ((data[1] << 8) | data[0]);
+        if(rawTemp & 0x8000)
+        {
+            *temp = (23.0F - ((0x10000 - rawTemp)/512.0F));
+        }
+        else
+        {
+            *temp = ((rawTemp/512.0F) + 23.0F);
+        }
+    }
+
+    return rtnVal;
+}
+
+//***********************************************************************************
+int32_t BMI160::BMI160_DefaultInitalize(){
+
+		//soft reset the accelerometer
+		writeRegister(CMD ,SOFT_RESET);
+		wait(0.1);
+
+	    //Power up sensors in normal mode
+	    if(setSensorPowerMode(BMI160::GYRO, BMI160::SUSPEND) != BMI160::RTN_NO_ERROR){
+	        //printf("Failed to set gyroscope power mode\n");
+	    }
+
+	    wait(0.1);
+
+	    if(setSensorPowerMode(BMI160::ACC, BMI160::NORMAL) != BMI160::RTN_NO_ERROR){
+	        //printf("Failed to set accelerometer power mode\n");
+	    }
+	    wait(0.1);
+
+	    BMI160::AccConfig accConfig;
+	    BMI160::AccConfig accConfigRead;
+	    accConfig.range = BMI160::SENS_2G;
+	    accConfig.us = BMI160::ACC_US_OFF;
+	    accConfig.bwp = BMI160::ACC_BWP_2;
+	    accConfig.odr = BMI160::ACC_ODR_6;
+	    if(setSensorConfig(accConfig) == BMI160::RTN_NO_ERROR)
+	    {
+	        if(getSensorConfig(accConfigRead) == BMI160::RTN_NO_ERROR)
+	        {
+	            if((accConfig.range != accConfigRead.range) ||
+	                    (accConfig.us != accConfigRead.us) ||
+	                    (accConfig.bwp != accConfigRead.bwp) ||
+	                    (accConfig.odr != accConfigRead.odr))
+	            {
+	               /* printf("ACC read data desn't equal set data\n\n");
+	                printf("ACC Set Range = %d\n", accConfig.range);
+	                printf("ACC Set UnderSampling = %d\n", accConfig.us);
+	                printf("ACC Set BandWidthParam = %d\n", accConfig.bwp);
+	                printf("ACC Set OutputDataRate = %d\n\n", accConfig.odr);
+	                printf("ACC Read Range = %d\n", accConfigRead.range);
+	                printf("ACC Read UnderSampling = %d\n", accConfigRead.us);
+	                printf("ACC Read BandWidthParam = %d\n", accConfigRead.bwp);
+	                printf("ACC Read OutputDataRate = %d\n\n", accConfigRead.odr);*/
+	            }
+
+	        }
+	        else
+	        {
+	             //printf("Failed to read back accelerometer configuration\n");
+	        }
+	    }
+	    else
+	    {
+	        //printf("Failed to set accelerometer configuration\n");
+	    }
+	    return 0;
+}
+
+//***********************************************************************************
+int32_t BMI160::enable_data_ready_interrupt() {
+	uint8_t data = 0;
+	uint8_t temp = 0;
+	int32_t result;
+
+	result = readRegister(INT_EN_1, &data);
+	temp = data & ~0x10;
+	data = temp | ((1 << 4) & 0x10);
+	/* Writing data to INT ENABLE 1 Address */
+	result |= writeRegister(INT_EN_1, data);
+
+	// configure in_out ctrl
+	//bmi160_get_regs(BMI160_INT_OUT_CTRL_ADDR, &data, 1, dev);
+	result |= readRegister(INT_OUT_CTRL, &data);
+	data = 0x09;
+	result |= writeRegister(INT_OUT_CTRL,data);
+
+	//config int latch
+	//bmi160_get_regs(BMI160_INT_LATCH_ADDR, &data, 1, dev);
+	result |= readRegister(INT_LATCH, &data);
+	data = 0x0F;
+	result |= writeRegister(INT_LATCH, data);
+
+	//bmi160_get_regs(BMI160_INT_MAP_1_ADDR, &data, 1, dev);
+	result |= readRegister(INT_MAP_1, &data);
+	data = 0x80;
+	result |= writeRegister(INT_MAP_1, data);
+
+	if(result != 0){
+		//printf("BMI160::%s failed.\r\n", __func__);
+		return -1;
+	}
+
+	m_bmi160_irq->disable_irq();
+	m_bmi160_irq->mode(PullUp);
+	m_bmi160_irq->fall(this, &BMI160::irq_handler);
+	m_bmi160_irq->enable_irq();
+	return 0;
+}
+
+void BMI160::irq_handler() {
+	bmi160_irq_asserted = true;
+}
+
+int32_t BMI160::reset() {
+	if (m_use_irq)
+		m_bmi160_irq->disable_irq();
+	bmi160_irq_asserted = false;
+	writeRegister(CMD, SOFT_RESET);
+	return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/accelerometer/bmi160.h	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,846 @@
+/**********************************************************************
+* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+**********************************************************************/
+
+
+#ifndef BMI160_H
+#define BMI160_H
+
+#include "mbed.h"
+
+/**
+@brief The BMI160 is a small, low power, low noise 16-bit inertial measurement
+unit designed for use in mobile applications like augmented reality or indoor
+navigation which require highly accurate, real-time sensor data.
+
+In full operation mode, with both the accelerometer and gyroscope enabled, the
+current consumption is typically 950 μA, enabling always-on applications in
+battery driven devices. It is available in a compact 14-pin 2.5 x 3.0 x 0.8 mm³
+LGA package."
+
+This class is an abstract base class and can not be instaniated, use BMI160_I2C
+or BMI160_SPI.
+*/
+class BMI160
+{
+public:
+
+    ///Return value on success.
+    static const uint8_t RTN_NO_ERROR = 0;
+
+    ///Sensor types
+    enum Sensors
+    {
+        MAG = 0, ///<Optional external sensor
+        GYRO,    ///<Angular rate sensor
+        ACC      ///<g sensor
+    };
+
+    ///Sensor Axis
+    enum SensorAxis
+    {
+        X_AXIS = 0,
+        Y_AXIS,
+        Z_AXIS
+    };
+
+    ///Structure for axis data
+    struct AxisData
+    {
+        int16_t raw;  ///<Axis raw data
+        float scaled; ///<Axis scaled data
+    };
+
+    ///Structure for sensor time data
+    struct SensorTime
+    {
+        uint32_t raw;  ///<raw SensorTime
+        float seconds; ///<SensorTime as seconds
+    };
+
+    ///Period of internal counter
+    static const float SENSOR_TIME_LSB = 39e-6;
+
+    ///Structure for holding sensor data
+    struct SensorData
+    {
+        AxisData xAxis; ///<Sensor X axis data
+        AxisData yAxis; ///<Sensor Y axis data
+        AxisData zAxis; ///<Sensor Z axis data
+    };
+
+
+    ///BMI160 registers
+    enum Registers
+    {
+        CHIP_ID = 0x00,  ///<Chip Identification.
+        ERR_REG = 0x02,  ///<Reports sensor error flags.  Flags reset when read.
+        PMU_STATUS,      ///<Reports current power mode for sensors.
+        DATA_0,          ///<MAG_X axis bits7:0
+        DATA_1,          ///<MAG_X axis bits15:8
+        DATA_2,          ///<MAG_Y axis bits7:0
+        DATA_3,          ///<MAG_Y axis bits15:8
+        DATA_4,          ///<MAG_Z axis bits7:0
+        DATA_5,          ///<MAG_Z axis bits15:8
+        DATA_6,          ///<RHALL bits7:0
+        DATA_7,          ///<RHALL bits15:8
+        DATA_8,          ///<GYR_X axis bits7:0
+        DATA_9,          ///<GYR_X axis bits15:8
+        DATA_10,         ///<GYR_Y axis bits7:0
+        DATA_11,         ///<GYR_Y axis bits15:8
+        DATA_12,         ///<GYR_Z axis bits7:0
+        DATA_13,         ///<GYR_Z axis bits15:8
+        DATA_14,         ///<ACC_X axis bits7:0
+        DATA_15,         ///<ACC_X axis bits15:8
+        DATA_16,         ///<ACC_Y axis bits7:0
+        DATA_17,         ///<ACC_Y axis bits15:8
+        DATA_18,         ///<ACC_Z axis bits7:0
+        DATA_19,         ///<ACC_Z axis bits15:8
+        SENSORTIME_0,    ///<24bit counter synchronized with data, bits7:0
+        SENSORTIME_1,    ///<24bit counter synchronized with data, bits15:8
+        SENSORTIME_2,    ///<24bit counter synchronized with data, bits23:16
+        STATUS,          ///<Reports sensors status flags
+        INT_STATUS_0,    ///<Contains interrupt status flags
+        INT_STATUS_1,    ///<Contains interrupt status flags
+        INT_STATUS_2,    ///<Contains interrupt status flags
+        INT_STATUS_3,    ///<Contains interrupt status flags
+        TEMPERATURE_0,   ///<Contains temperature of sensor, bits7:0
+        TEMPERATURE_1,   ///<Contains temperature of sensor, bits15:8
+        FIFO_LENGTH_0,   ///<Current fill level of FIFO, bits7:0
+        FIFO_LENGTH_1,   ///<Current fill level of FIFO, bits10:8
+        FIFO_DATA,       ///<FIFO data read out register, burst read
+        ACC_CONF = 0x40, ///<Set ODR, bandwidth, and read mode of accelerometer
+        ACC_RANGE,       ///<Sets accelerometer g-range
+        GYR_CONF,        ///<Set ODR, bandwidth, and read mode of gyroscope
+        GYR_RANGE,       ///<Sets gyroscope angular rate measurement range
+        MAG_CONF,        ///<Sets ODR of magnetometer interface
+        FIFO_DOWNS,      ///<Sets down sampling ratios of accel and gyro data
+                         ///<for FIFO
+        FIFO_CONFIG_0,   ///<Sets FIFO Watermark
+        FIFO_CONFIG_1,   ///<Sets which sensor data is available in FIFO,
+                         ///<Header/Headerless mode, Ext Int tagging, Sensortime
+        MAG_IF_0 = 0x4B, ///<Magnetometer 7-bit I2C address, bits7:1
+        MAG_IF_1,        ///<Magnetometer interface configuration
+        MAG_IF_2,        ///<Magnetometer address to read
+        MAG_IF_3,        ///<Magnetometer address to write
+        MAG_IF_4,        ///<Magnetometer data to write
+        INT_EN_0,        ///<Interrupt enable bits
+        INT_EN_1,        ///<Interrupt enable bits
+        INT_EN_2,        ///<Interrupt enable bits
+        INT_OUT_CTRL,    ///<Contains the behavioral configuration of INT pins
+        INT_LATCH,       ///<Contains the interrupt rest bit and the interrupt
+                         ///<mode selection
+        INT_MAP_0,       ///<Controls which interrupt signals are mapped to the
+                         ///<INT1 and INT2 pins
+        INT_MAP_1,       ///<Controls which interrupt signals are mapped to the
+                         ///<INT1 and INT2 pins
+        INT_MAP_2,       ///<Controls which interrupt signals are mapped to the
+                         ///<INT1 and INT2 pins
+        INT_DATA_0,      ///<Contains the data source definition for the two
+                         ///<interrupt groups
+        INT_DATA_1,      ///<Contains the data source definition for the two
+                         ///<interrupt groups
+        INT_LOWHIGH_0,   ///<Contains the configuration for the low g interrupt
+        INT_LOWHIGH_1,   ///<Contains the configuration for the low g interrupt
+        INT_LOWHIGH_2,   ///<Contains the configuration for the low g interrupt
+        INT_LOWHIGH_3,   ///<Contains the configuration for the low g interrupt
+        INT_LOWHIGH_4,   ///<Contains the configuration for the low g interrupt
+        INT_MOTION_0,    ///<Contains the configuration for the any motion and
+                         ///<no motion interrupts
+        INT_MOTION_1,    ///<Contains the configuration for the any motion and
+                         ///<no motion interrupts
+        INT_MOTION_2,    ///<Contains the configuration for the any motion and
+                         ///<no motion interrupts
+        INT_MOTION_3,    ///<Contains the configuration for the any motion and
+                         ///<no motion interrupts
+        INT_TAP_0,       ///<Contains the configuration for the tap interrupts
+        INT_TAP_1,       ///<Contains the configuration for the tap interrupts
+        INT_ORIENT_0,    ///<Contains the configuration for the oeientation
+                         ///<interrupt
+        INT_ORIENT_1,    ///<Contains the configuration for the oeientation
+                         ///<interrupt
+        INT_FLAT_0,      ///<Contains the configuration for the flat interrupt
+        INT_FLAT_1,      ///<Contains the configuration for the flat interrupt
+        FOC_CONF,        ///<Contains configuration for the fast offset
+                         ///<compensation for the accelerometer and gyroscope
+        CONF,            ///<Configuration of sensor, nvm_prog_en bit
+        IF_CONF,         ///<Contains settings for the digital interface
+        PMU_TRIGGER,     ///<Sets trigger conditions to change gyro power modes
+        SELF_TEST,       ///<Self test configuration
+        NV_CONF = 0x70,  ///<Contains settings for the digital interface
+        OFFSET_0,        ///<Contains offset comp values for acc_off_x7:0
+        OFFSET_1,        ///<Contains offset comp values for acc_off_y7:0
+        OFFSET_2,        ///<Contains offset comp values for acc_off_z7:0
+        OFFSET_3,        ///<Contains offset comp values for gyr_off_x7:0
+        OFFSET_4,        ///<Contains offset comp values for gyr_off_y7:0
+        OFFSET_5,        ///<Contains offset comp values for gyr_off_z7:0
+        OFFSET_6,        ///<gyr/acc offset enable bit and gyr_off_(zyx) bits9:8
+        STEP_CNT_0,      ///<Step counter bits 15:8
+        STEP_CNT_1,      ///<Step counter bits 7:0
+        STEP_CONF_0,     ///<Contains configuration of the step detector
+        STEP_CONF_1,     ///<Contains configuration of the step detector
+        CMD = 0x7E       ///<Command register triggers operations like
+                         ///<softreset, NVM programming, etc.
+    };
+
+
+    ///@name ERR_REG(0x02)
+    ///Error register data
+    ///@{
+
+    static const uint8_t FATAL_ERR_MASK = 0x01;
+    static const uint8_t FATAL_ERR_POS = 0x00;
+    static const uint8_t ERR_CODE_MASK = 0x1E;
+    static const uint8_t ERR_CODE_POS = 0x01;
+    static const uint8_t I2C_FAIL_ERR_MASK = 0x20;
+    static const uint8_t I2C_FAIL_ERR_POS = 0x05;
+    static const uint8_t DROP_CMD_ERR_MASK = 0x40;
+    static const uint8_t DROP_CMD_ERR_POS = 0x06;
+    static const uint8_t MAG_DRDY_ERR_MASK = 0x80;
+    static const uint8_t MAG_DRDY_ERR_POS = 0x08;
+
+    ///Enumerated error codes
+    enum ErrorCodes
+    {
+        NO_ERROR = 0,        ///<No Error
+        ERROR_1,             ///<Listed as error
+        ERROR_2,             ///<Listed as error
+        LPM_INT_PFD,         ///<Low-power mode and interrupt uses pre-filtered
+                             ///<data
+        ODR_MISMATCH = 0x06, ///<ODRs of enabled sensors in headerless mode do
+                             ///<not match
+        PFD_USED_LPM         ///<Pre-filtered data are used in low power mode
+    };
+    ///@}
+
+
+    ///@name ACC_CONF(0x40) and ACC_RANGE(0x41)
+    ///Data for configuring accelerometer
+    ///@{
+
+    static const uint8_t ACC_ODR_MASK = 0x0F;
+    static const uint8_t ACC_ODR_POS = 0x00;
+    static const uint8_t ACC_BWP_MASK = 0x70;
+    static const uint8_t ACC_BWP_POS = 0x04;
+    static const uint8_t ACC_US_MASK = 0x80;
+    static const uint8_t ACC_US_POS = 0x07;
+    static const uint8_t ACC_RANGE_MASK = 0x0F;
+    static const uint8_t ACC_RANGE_POS = 0x00;
+
+    ///Accelerometer output data rates
+    enum AccOutputDataRate
+    {
+        ACC_ODR_1 = 1,  ///< 25/32Hz
+        ACC_ODR_2,      ///< 25/16Hz
+        ACC_ODR_3,      ///< 25/8Hz
+        ACC_ODR_4,      ///< 25/4Hz
+        ACC_ODR_5,      ///< 25/2Hz
+        ACC_ODR_6,      ///< 25Hz
+        ACC_ODR_7,      ///< 50Hz
+        ACC_ODR_8,      ///< 100Hz
+        ACC_ODR_9,      ///< 200Hz
+        ACC_ODR_10,     ///< 400Hz
+        ACC_ODR_11,     ///< 800Hz
+        ACC_ODR_12      ///< 1600Hz
+    };
+
+    ///Accelerometer bandwidth parameters
+    enum AccBandWidthParam
+    {
+        ACC_BWP_0 = 0, ///< Average 1 cycle;  when acc_us = 0 OSR4
+        ACC_BWP_1,     ///< Average 2 cycles; when acc_us = 0 OSR2
+        ACC_BWP_2,     ///< Average 4 cycles; when acc_us = 0 normal mode
+        ACC_BWP_3,     ///< Average 8 cycles
+        ACC_BWP_4,     ///< Average 16 cycles
+        ACC_BWP_5,     ///< Average 32 cycles
+        ACC_BWP_6,     ///< Average 64 cycles
+        ACC_BWP_7      ///< Average 128 cycles
+    };
+
+    ///Accelerometer undersampling
+    enum AccUnderSampling
+    {
+        ACC_US_OFF = 0,
+        ACC_US_ON
+    };
+
+    ///Accelerometer ranges
+    enum AccRange
+    {
+        SENS_2G = 0x03,  ///<Accelerometer range +-2G
+        SENS_4G = 0x05,  ///<Accelerometer range +-4G
+        SENS_8G = 0x08,  ///<Accelerometer range +-8G
+        SENS_16G = 0x0C ///<Accelerometer range +-16G
+    };
+
+    static const float SENS_2G_LSB_PER_G = 16384.0F;
+    static const float SENS_4G_LSB_PER_G = 8192.0F;
+    static const float SENS_8G_LSB_PER_G = 4096.0F;
+    static const float SENS_16G_LSB_PER_G = 2048.0F;
+
+    ///Accelerometer configuration data structure
+    struct AccConfig
+    {
+        AccRange range;        ///<Accelerometer range
+        AccUnderSampling us;   ///<Accelerometr undersampling mode
+        AccBandWidthParam bwp; ///<Accelerometer bandwidth param
+        AccOutputDataRate odr; ///<Accelerometr output data rate
+    };
+
+    ///Accelerometer default configuration
+    static const AccConfig DEFAULT_ACC_CONFIG;
+    ///@}
+
+
+    ///@name GYR_CONF(0x42) and GYR_RANGE(0x43)
+    ///Data for configuring gyroscope
+    ///@{
+
+    static const uint8_t GYRO_ODR_MASK = 0x0F;
+    static const uint8_t GYRO_ODR_POS = 0x00;
+    static const uint8_t GYRO_BWP_MASK = 0x30;
+    static const uint8_t GYRO_BWP_POS = 0x04;
+    static const uint8_t GYRO_RANGE_MASK = 0x07;
+    static const uint8_t GYRO_RANGE_POS = 0x00;
+
+    ///Gyroscope output data rates
+    enum GyroOutputDataRate
+    {
+        GYRO_ODR_6 = 0x06,  ///<25Hz
+        GYRO_ODR_7 = 0x07,  ///<50Hz
+        GYRO_ODR_8 = 0x08,  ///<100Hz
+        GYRO_ODR_9 = 0x09,  ///<200Hz
+        GYRO_ODR_10 = 0x0A, ///<400Hz
+        GYRO_ODR_11 = 0x0B, ///<800Hz
+        GYRO_ODR_12 = 0x0C, ///<1600Hz
+        GYRO_ODR_13 = 0x0D  ///<3200Hz
+    };
+
+    ///Gyroscope bandwidth paramaters
+    enum GyroBandWidthParam
+    {
+        GYRO_BWP_0 = 0, ///<OSR4 Over Sampling Rate of 4
+        GYRO_BWP_1,     ///<OSR2 Over Sampling Rate of 2
+        GYRO_BWP_2      ///<Normal Mode, Equidistant Sampling
+    };
+
+    ///Gyroscope ranges
+    enum GyroRange
+    {
+        DPS_2000 = 0, ///<+-2000dps, 16.4LSB/dps
+        DPS_1000,     ///<+-1000dps, 32.8LSB/dps
+        DPS_500,      ///<+-500dps, 65.6LSB/dps
+        DPS_250,      ///<+-250dps, 131.2LSB/dps
+        DPS_125       ///<+-125dps, 262.4LSB/dps,
+    };
+
+    static const float SENS_2000_DPS_LSB_PER_DPS = 16.4F;
+    static const float SENS_1000_DPS_LSB_PER_DPS = 32.8F;
+    static const float SENS_500_DPS_LSB_PER_DPS = 65.6F;
+    static const float SENS_250_DPS_LSB_PER_DPS = 131.2F;
+    static const float SENS_125_DPS_LSB_PER_DPS = 262.4F;
+
+    ///Gyroscope configuration data structure
+    struct GyroConfig
+    {
+        GyroRange range;        ///<Gyroscope range
+        GyroBandWidthParam bwp; ///<Gyroscope bandwidth param
+        GyroOutputDataRate odr; ///<Gyroscope output data rate
+    };
+
+    ///Gyroscope default configuration
+    static const GyroConfig DEFAULT_GYRO_CONFIG;
+    ///@}
+
+
+    ///Enumerated power modes
+    enum PowerModes
+    {
+        SUSPEND = 0,  ///<Acc and Gyro, No sampling, No FIFO data readout
+        NORMAL,       ///<Acc and Gyro, Full chip operation
+        LOW_POWER,    ///<Acc duty-cycling between suspend and normal
+        FAST_START_UP ///<Gyro start up delay time to normal mode <= 10 ms
+    };
+
+
+    ///Enumerated commands used with CMD register
+    enum Commands
+    {
+        START_FOC = 0x03,        ///<Starts Fast Offset Calibrartion
+        ACC_SET_PMU_MODE = 0x10, ///<Sets acc power mode
+        GYR_SET_PMU_MODE = 0x14, ///<Sets gyro power mode
+        MAG_SET_PMU_MODE = 0x18, ///<Sets mag power mode
+        PROG_NVM = 0xA0,         ///<Writes NVM backed registers into NVM
+        FIFO_FLUSH = 0xB0,       ///<Clears FIFO
+        INT_RESET,               ///<Clears interrupt engine, INT_STATUS, and
+                                 ///<the interrupt pin
+        STEP_CNT_CLR,            ///<Triggers reset of the step counter
+        SOFT_RESET = 0xB6        ///<Triggers a reset including a reboot.
+    };
+
+
+    ///@brief BMI160 Destructor.\n
+    ///
+    ///On Entry:
+    ///@param[in] none
+    ///
+    ///On Exit:
+    ///@param[out] none
+    ///
+    ///@returns none
+    virtual ~BMI160(){ }
+
+
+    ///@brief Reads a single register.\n
+    ///
+    ///On Entry:
+    ///@param[in] data - pointer to memory for storing read data
+    ///
+    ///On Exit:
+    ///@param[out] data - holds contents of read register on success
+    ///
+    ///@returns 0 on success, non 0 on failure
+    virtual int32_t readRegister(Registers reg, uint8_t *data) = 0;
+
+
+    ///@brief Writes a single register.\n
+    ///
+    ///On Entry:
+    ///@param[in] data - data to write to register
+    ///
+    ///On Exit:
+    ///@param[out] none
+    ///
+    ///@returns 0 on success, non 0 on failure
+    virtual int32_t writeRegister(Registers reg, const uint8_t data) = 0;
+
+
+    ///@brief Reads a block of registers.\n
+    ///@detail User must ensure that all registers between 'startReg' and
+    ///'stopReg' exist and are readable.  Function reads up to, including,
+    ///'stopReg'.\n
+    ///
+    ///On Entry:
+    ///@param[in] startReg - register to start reading from
+    ///@param[in] stopReg - register to stop reading from
+    ///@param[in] data - pointer to memory for storing read data
+    ///
+    ///On Exit:
+    ///@param[out] data - holds contents of read registers on success
+    ///
+    ///@returns 0 on success, non 0 on failure
+    virtual int32_t readBlock(Registers startReg, Registers stopReg,
+    uint8_t *data) = 0;
+
+
+    ///@brief Writes a block of registers.\n
+    ///@detail User must ensure that all registers between 'startReg' and
+    ///'stopReg' exist and are writeable.  Function writes up to, including,
+    ///'stopReg'.\n
+    ///
+    ///On Entry:
+    ///@param[in] startReg - register to start writing at
+    ///@param[in] stopReg - register to stop writing at
+    ///@param[in] data - pointer to data to write to registers
+    ///
+    ///On Exit:
+    ///@param[out] none
+    ///
+    ///@returns 0 on success, non 0 on failure
+    virtual int32_t writeBlock(Registers startReg, Registers stopReg,
+    const uint8_t *data) = 0;
+
+
+    ///@brief Sets sensors power mode through CMD register.\n
+    ///@details Observe command execution times given in datasheet.\n
+    ///
+    ///On Entry:
+    ///@param[in] sensor - Sensor which power mode we are setting
+    ///@param[in] pwrMode - Desired powermode of the sensor
+    ///
+    ///On Exit:
+    ///@param[out]
+    ///
+    ///@returns 0 on success, non 0 on failure
+    int32_t setSensorPowerMode(Sensors sensor, PowerModes pwrMode);
+
+
+    ///@brief Configure sensor.\n
+    ///
+    ///On Entry:
+    ///@param[in] config - sSensor configuration data structure
+    ///
+    ///On Exit:
+    ///@param[out] none
+    ///
+    ///@returns 0 on success, non 0 on failure
+    int32_t setSensorConfig(const AccConfig &config);
+    int32_t setSensorConfig(const GyroConfig &config);
+
+
+    ///@brief Get sensor configuration.\n
+    ///
+    ///On Entry:
+    ///@param[in] config - Sensor configuration data structure
+    ///
+    ///On Exit:
+    ///@param[out] config - on success, holds sensor's current
+    ///configuration
+    ///
+    ///@returns 0 on success, non 0 on failure
+    int32_t getSensorConfig(AccConfig &config);
+    int32_t getSensorConfig(GyroConfig &config);
+
+
+    ///@brief Get sensor axis.\n
+    ///
+    ///On Entry:
+    ///@param[in] axis - Sensor axis
+    ///@param[in] data - AxisData structure
+    ///@param[in] range - Sensor range
+    ///
+    ///On Exit:
+    ///@param[out] data - Structure holds raw and scaled axis data
+    ///
+    ///@returns 0 on success, non 0 on failure
+    int32_t getSensorAxis(SensorAxis axis, AxisData &data, AccRange range);
+    int32_t getSensorAxis(SensorAxis axis, AxisData &data, GyroRange range);
+
+
+    ///@brief Get sensor xyz axis.\n
+    ///
+    ///On Entry:
+    ///@param[in] data - SensorData structure
+    ///@param[in] range - Sensor range
+    ///
+    ///On Exit:
+    ///@param[out] data - Structure holds raw and scaled data for all three axis
+    ///
+    ///@returns 0 on success, non 0 on failure
+    int32_t getSensorXYZ(SensorData &data, AccRange range);
+    int32_t getSensorXYZ(SensorData &data, GyroRange range);
+
+
+    ///@brief Get sensor xyz axis and sensor time.\n
+    ///
+    ///On Entry:
+    ///@param[in] data - SensorData structure
+    ///@param[in] sensorTime - SensorTime structure for data
+    ///@param[in] range - Sensor range
+    ///
+    ///On Exit:
+    ///@param[out] data - Structure holds raw and scaled data for all three axis
+    ///@param[out] sensorTime - Holds sensor time on success
+    ///
+    ///@returns 0 on success, non 0 on failure
+    int32_t getSensorXYZandSensorTime(SensorData &data, SensorTime &sensorTime,
+                                      AccRange range);
+    int32_t getSensorXYZandSensorTime(SensorData &data, SensorTime &sensorTime,
+                                      GyroRange range);
+
+
+    ///@brief Get Gyroscope/Accelerometer data and sensor time.\n
+    ///
+    ///On Entry:
+    ///@param[in] accData -  Sensor data structure for accelerometer
+    ///@param[in] gyroData - Sensor data structure for gyroscope
+    ///@param[in] sensorTime - SensorTime data structure
+    ///@param[in] accRange - Accelerometer range
+    ///@param[in] gyroRange - Gyroscope range
+    ///
+    ///On Exit:
+    ///@param[out] accData -  Synchronized accelerometer data
+    ///@param[out] gyroData - Synchronized gyroscope data
+    ///@param[out] sensorTime - Synchronized sensor time
+    ///
+    ///@returns 0 on success, non 0 on failure
+    int32_t getGyroAccXYZandSensorTime(SensorData &accData,
+                                       SensorData &gyroData,
+                                       SensorTime &sensorTime,
+                                       AccRange accRange, GyroRange gyroRange);
+
+
+    ///@brief Get sensor time.\n
+    ///
+    ///On Entry:
+    ///@param[in] sensorTime - SensorTime structure for data
+    ///
+    ///On Exit:
+    ///@param[out] sensorTime - Holds sensor time on success
+    ///
+    ///@returns returns 0 on success, non 0 on failure
+    int32_t getSensorTime(SensorTime &sensorTime);
+
+
+    ///@brief Get die temperature.\n
+    ///
+    ///On Entry:
+    ///@param[in] temp - pointer to float for temperature
+    ///
+    ///On Exit:
+    ///@param[out] temp - on success, holds the die temperature
+    ///
+    ///@returns 0 on success, non 0 on failure
+    int32_t getTemperature(float *temp);
+
+    // Initialize BMI160 with default parameters:
+    // set GYRO: Suspended, Acc Normal Mode, ODR:25 Hz
+    int32_t BMI160_DefaultInitalize();
+
+    //
+    //
+    int32_t enable_data_ready_interrupt();
+
+	//
+	// Set sample rate
+	// This function can be alled after BMI160_DefaultInitalize
+	int32_t setSampleRate(int sample_rate);
+
+	/// @brief Soft reset
+	///
+	int32_t reset();
+
+private:
+	bool m_use_irq;
+	bool bmi160_irq_asserted;
+	InterruptIn *m_bmi160_irq;
+	void irq_handler();
+
+protected:
+	BMI160(InterruptIn *int_pin): m_bmi160_irq(int_pin), m_use_irq(true) {
+		bmi160_irq_asserted = false;
+	}
+
+	BMI160(): m_use_irq(false) { }
+};
+
+
+/**
+@brief BMI160_I2C - supports BMI160 object with I2C interface
+*/
+class BMI160_I2C: public BMI160
+{
+public:
+
+    ///BMI160 default I2C address.
+    static const uint8_t I2C_ADRS_SDO_LO = 0x68;
+    ///BMI160 optional I2C address.
+    static const uint8_t I2C_ADRS_SDO_HI = 0x69;
+
+
+    ///@brief BMI160_I2C Constructor.\n
+    ///
+    ///On Entry:
+    ///@param[in] i2cBus - reference to I2C bus for this device
+    ///@param[in] i2cAdrs - 7-bit I2C address
+    ///
+    ///On Exit:
+    ///@param[out] none
+    ///
+    ///@returns none
+    BMI160_I2C(I2C *i2cBus, uint8_t i2cAdrs);
+
+    ///@brief BMI160_I2C Constructor.\n
+    ///
+    ///On Entry:
+    ///@param[in] i2cBus - reference to I2C bus for this device
+    ///@param[in] i2cAdrs - 7-bit I2C address
+    ///@param[in] int_pin - Interrupt pin
+    ///
+    ///On Exit:
+    ///@param[out] none
+    ///
+    ///@returns none
+	BMI160_I2C(I2C *i2cBus, uint8_t i2cAdrs, InterruptIn *int_pin);
+
+    ///@brief Reads a single register.\n
+    ///
+    ///On Entry:
+    ///@param[in] data - pointer to memory for storing read data
+    ///
+    ///On Exit:
+    ///@param[out] data - holds contents of read register on success
+    ///
+    ///@returns 0 on success, non 0 on failure
+    virtual int32_t readRegister(Registers reg, uint8_t *data);
+
+
+    ///@brief Writes a single register.\n
+    ///
+    ///On Entry:
+    ///@param[in] data - data to write to register
+    ///
+    ///On Exit:
+    ///@param[out] none
+    ///
+    ///@returns 0 on success, non 0 on failure
+    virtual int32_t writeRegister(Registers reg, const uint8_t data);
+
+
+    ///@brief Reads a block of registers.\n
+    ///@detail User must ensure that all registers between 'startReg' and
+    ///'stopReg' exist and are readable.  Function reads up to, including,
+    ///'stopReg'.\n
+    ///
+    ///On Entry:
+    ///@param[in] startReg - register to start reading from
+    ///@param[in] stopReg - register to stop reading from
+    ///@param[in] data - pointer to memory for storing read data
+    ///
+    ///On Exit:
+    ///@param[out] data - holds contents of read registers on success
+    ///
+    ///@returns 0 on success, non 0 on failure
+    virtual int32_t readBlock(Registers startReg, Registers stopReg,
+    uint8_t *data);
+
+
+    ///@brief Writes a block of registers.\n
+    ///@detail User must ensure that all registers between 'startReg' and
+    ///'stopReg' exist and are writeable.  Function writes up to, including,
+    ///'stopReg'.\n
+    ///
+    ///On Entry:
+    ///@param[in] startReg - register to start writing at
+    ///@param[in] stopReg - register to stop writing at
+    ///@param[in] data - pointer to data to write to registers
+    ///
+    ///On Exit:
+    ///@param[out] none
+    ///
+    ///@returns 0 on success, non 0 on failure
+    virtual int32_t writeBlock(Registers startReg, Registers stopReg,
+    const uint8_t *data);
+
+private:
+    I2C *m_i2cBus;
+    uint8_t m_Wadrs, m_Radrs;
+};
+
+
+/**
+@brief BMI160_SPI - supports BMI160 object with SPI interface
+*/
+class BMI160_SPI: public BMI160
+{
+public:
+
+    ///@brief BMI160_SPI Constructor.\n
+    ///
+    ///On Entry:
+    ///@param[in] spiBus - reference to SPI bus for this device
+    ///@param[in] cs - reference to DigitalOut used for chip select
+    ///
+    ///On Exit:
+    ///@param[out] none
+    ///
+    ///@returns none
+    BMI160_SPI(SPI *spiBus, DigitalOut &cs);
+
+
+    ///@brief Reads a single register.\n
+    ///
+    ///On Entry:
+    ///@param[in] data - pointer to memory for storing read data
+    ///
+    ///On Exit:
+    ///@param[out] data - holds contents of read register on success
+    ///
+    ///@returns 0 on success, non 0 on failure
+    virtual int32_t readRegister(Registers reg, uint8_t *data);
+
+
+    ///@brief Writes a single register.\n
+    ///
+    ///On Entry:
+    ///@param[in] data - data to write to register
+    ///
+    ///On Exit:
+    ///@param[out] none
+    ///
+    ///@returns 0 on success, non 0 on failure
+    virtual int32_t writeRegister(Registers reg, const uint8_t data);
+
+
+    ///@brief Reads a block of registers.\n
+    ///@detail User must ensure that all registers between 'startReg' and
+    ///'stopReg' exist and are readable.  Function reads up to, including,
+    ///'stopReg'.\n
+    ///
+    ///On Entry:
+    ///@param[in] startReg - register to start reading from
+    ///@param[in] stopReg - register to stop reading from
+    ///@param[in] data - pointer to memory for storing read data
+    ///
+    ///On Exit:
+    ///@param[out] data - holds contents of read registers on success
+    ///
+    ///@returns 0 on success, non 0 on failure
+    virtual int32_t readBlock(Registers startReg, Registers stopReg,
+    uint8_t *data);
+
+
+    ///@brief Writes a block of registers.\n
+    ///@detail User must ensure that all registers between 'startReg' and
+    ///'stopReg' exist and are writeable.  Function writes up to, including,
+    ///'stopReg'.\n
+    ///
+    ///On Entry:
+    ///@param[in] startReg - register to start writing at
+    ///@param[in] stopReg - register to stop writing at
+    ///@param[in] data - pointer to data to write to registers
+    ///
+    ///On Exit:
+    ///@param[out] none
+    ///
+    ///@returns 0 on success, non 0 on failure
+    virtual int32_t writeBlock(Registers startReg, Registers stopReg,
+    const uint8_t *data);
+
+private:
+
+    SPI *m_spiBus;
+    DigitalOut m_cs;
+};
+
+#endif /* BMI160_H */
+
+
+///@brief fx documentation template.\n
+///
+///On Entry:
+///@param[in] none
+///
+///On Exit:
+///@param[out] none
+///
+///@returns none
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/accelerometer/bmi160_i2c.cpp	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,104 @@
+/**********************************************************************
+* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+**********************************************************************/
+
+
+#include "bmi160.h"
+
+
+//*****************************************************************************
+BMI160_I2C::BMI160_I2C(I2C *i2cBus, uint8_t i2cAdrs)
+:m_i2cBus(i2cBus), m_Wadrs(i2cAdrs << 1), m_Radrs((i2cAdrs << 1) | 1)
+{
+
+}
+
+BMI160_I2C::BMI160_I2C(I2C *i2cBus, uint8_t i2cAdrs, InterruptIn *int_pin)
+:m_i2cBus(i2cBus), m_Wadrs(i2cAdrs << 1), m_Radrs((i2cAdrs << 1) | 1), BMI160(int_pin)
+{
+
+}
+
+//*****************************************************************************
+int32_t BMI160_I2C::readRegister(Registers reg, uint8_t *data)
+{
+    int32_t rtnVal = -1;
+    char packet[] = {static_cast<char>(reg)};
+
+    if(m_i2cBus->write(m_Wadrs, packet, 1) == 0)
+    {
+        rtnVal = m_i2cBus->read(m_Radrs, reinterpret_cast<char *>(data), 1);
+    }
+
+    return rtnVal;
+}
+
+
+//*****************************************************************************
+int32_t BMI160_I2C::writeRegister(Registers reg, const uint8_t data)
+{
+    char packet[] = {static_cast<char>(reg), static_cast<char>(data)};
+
+    return m_i2cBus->write(m_Wadrs, packet, sizeof(packet));
+}
+
+
+//*****************************************************************************
+int32_t BMI160_I2C::readBlock(Registers startReg, Registers stopReg,
+uint8_t *data)
+{
+    int32_t rtnVal = -1;
+    int32_t numBytes = ((stopReg - startReg) + 1);
+    char packet[] = {static_cast<char>(startReg)};
+
+    if(m_i2cBus->write(m_Wadrs, packet, 1) == 0)
+    {
+        rtnVal = m_i2cBus->read(m_Radrs, reinterpret_cast<char *>(data), numBytes);
+    }
+
+    return rtnVal;
+}
+
+
+//*****************************************************************************
+int32_t BMI160_I2C::writeBlock(Registers startReg, Registers stopReg,
+const uint8_t *data)
+{
+    int32_t numBytes = ((stopReg - startReg) + 1);
+    char packet[numBytes + 1];
+
+    packet[0] = static_cast<char>(startReg);
+
+    memcpy(packet + 1, data, numBytes);
+
+    return m_i2cBus->write(m_Wadrs, packet, sizeof(packet));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/accelerometer/bmi160_spi.cpp	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,81 @@
+/**********************************************************************
+* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+**********************************************************************/
+
+
+#include "bmi160.h"
+
+
+//*****************************************************************************
+BMI160_SPI::BMI160_SPI(SPI *spiBus, DigitalOut &cs)
+:m_spiBus(spiBus), m_cs(cs)
+{
+
+}
+
+
+//*****************************************************************************
+int32_t BMI160_SPI::readRegister(Registers reg, uint8_t *data)
+{
+    int32_t rtnVal = -1;
+
+    return rtnVal;
+}
+
+
+//*****************************************************************************
+int32_t BMI160_SPI::writeRegister(Registers reg, const uint8_t data)
+{
+    int32_t rtnVal = -1;
+
+    return rtnVal;
+}
+
+
+//*****************************************************************************
+int32_t BMI160_SPI::readBlock(Registers startReg, Registers stopReg,
+uint8_t *data)
+{
+    int32_t rtnVal = -1;
+
+    return rtnVal;
+}
+
+
+//*****************************************************************************
+int32_t BMI160_SPI::writeBlock(Registers startReg, Registers stopReg,
+const uint8_t *data)
+{
+    int32_t rtnVal = -1;
+
+    return rtnVal;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bootloader/bootldrAPI.cpp	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,651 @@
+/*
+ * bootldrInterface.cpp
+ *
+ *  Created on: Feb 7, 2019
+ *      Author: Yagmur.Gok
+ */
+
+#include <mbed.h>  /*for type definitions*/
+#include "bootldrAPI.h"
+#include "SHComm.h"
+#include "demoDefinitions.h"
+
+//extern Serial daplink;
+
+//#define SERIALOUT printf
+//#define SERIALIN  printf
+
+#define COMM_SUCCESS        0
+#define COMM_GENERAL_ERROR  -1
+#define COMM_INVALID_PARAM  -254
+#define COMM_NOT_RECOGNIZED -255
+
+#define BL_FLASH_ERR_GENERAL  	-1
+#define BL_FLASH_ERR_CHECKSUM 	-2
+#define BL_FLASH_ERR_AUTH      	-3
+#define BL_SET_NUM_PAGES_FAIL	-4
+#define BL_FLASS_ERASE_FAIL		-5
+#define BL_SET_IV_FAIL			-6
+#define BL_FLASHING_FAIL		-7
+#define BL_RAM_ALLOC_FAIL		-8
+
+#define AES_NONCE_SIZE 11
+#define AES_AUTH_SIZE  16
+#define BOOTLOADER_MAX_PAGE_SIZE (8192)
+#define CHECKBYTES_SIZE (16)
+#define FLASHCMDBYTES (2)
+
+#define SS_BOOTLOADER_ERASE_DELAY	700
+#define AES_NONCE_SIZE				11
+#define AES_AUTH_SIZE				16
+#define MAX_PAGE_SIZE				8192
+#define CHECKBYTES_SIZE				16
+
+#define PAGE_WRITE_DELAY_MS			170
+#define MAX_PAGE_NUMBER				31
+#define PAGE_ERASE_CMD_SLEEP_MS		50
+#define BL_CFG_SAVE_CMD_SLEEP_MS	50
+
+static int parse_iv(const char* cmd, uint8_t* iv_bytes);
+static int parse_auth(const char* cmd, uint8_t *auth_bytes);
+static int is_hub_ready_for_flash(void);
+static void clear_state_info(void);
+
+
+typedef struct {
+	int num_allocated_pages; /* Allocated page size */
+	int num_pages;
+	int num_received_pages;
+	int page_size;
+	uint8_t auth[AES_AUTH_SIZE];
+	uint8_t nonce[AES_NONCE_SIZE];
+	uint8_t pages[MAX_PAGE_NUMBER * (MAX_PAGE_SIZE + CHECKBYTES_SIZE)]; //TODO: Use dynamic allocation
+} app_image_t;
+
+
+static app_image_t *app_image = NULL;
+
+static struct {
+
+	uint32_t num_pages;
+	uint32_t page_size;
+	uint32_t hub_mode_bootloader;
+	uint32_t is_iv_set;
+	uint32_t is_auth_done;
+	uint32_t is_flash_erased;
+	uint32_t flag_image_on_ram;
+	uint32_t bootcmds_delay_factor;
+	uint32_t ebl_mode;
+
+}bootldrState = { 0 , 0 , 0 ,0 , 0 , 0 , 0 , 1 ,1};
+
+
+
+int BOOTLDR_get_host_bootloader_state(const char *null_arg){
+
+	SERIALOUT(" \r\n BOOT STATE INFO: \r\n num_pages= %d \r\n page_size= %d \r\n is_iv_set= %d \r\n is_auth_done= %d \r\n is_flash_erased= %d \r\n flag_image_on_ram= %d \r\n bootcmds_delay_factor= %d \r\n ebl_mode= %d \r\n",
+			                             bootldrState.num_pages,
+										 bootldrState.page_size,
+										 bootldrState.is_iv_set,
+										 bootldrState.is_auth_done,
+										 bootldrState.is_flash_erased,
+										 bootldrState.flag_image_on_ram,
+										 bootldrState.bootcmds_delay_factor,
+										 bootldrState.ebl_mode );
+
+
+}
+
+int SH_BOOTLDR_enter_blmode(const char *null_arg){
+
+	int status = 0x00;
+
+	//status = sh_put_in_bootloader();
+	//status = sh_set_ebl_mode((uint8_t)1); /* 1: GPIO rest 0: CMD reset*/
+
+    if( status == 0x00) {
+
+	    //////////status = sh_reset_to_bootloader(); - CHECKIF PROBLEM STILL PRESENT!!
+    	status = sh_debug_reset_to_bootloader();
+	    //status = sh_set_sensorhub_operating_mode((uint8_t)0x08);
+		if (status == 0x00) {
+		   SERIALOUT("\r\n%s err=%d\r\n", "bootldr", COMM_SUCCESS);
+		   bootldrState.hub_mode_bootloader  = 1;
+		}
+		else
+		   SERIALOUT("\r\n%s err=%d\r\n", "bootldr", COMM_GENERAL_ERROR);
+    }
+
+	return status;
+
+}
+
+
+int SH_BOOTLDR_exit_blmode(const char *null_arg){
+
+	int status;
+	status = sh_reset_to_main_app() ; //sh_exit_from_bootloader();
+	if (status == 0x00)
+		printf("\r\n exited from bootloader mode \r\n");
+
+	if (status == 0x00) {
+	   SERIALOUT("\r\n%s err=%d\r\n", "exit", COMM_SUCCESS);
+       bootldrState.hub_mode_bootloader  = 0;
+	}
+    else
+       SERIALOUT("\r\n%s err=%d\r\n", "exit", COMM_GENERAL_ERROR);
+
+	return status;
+
+}
+
+int SH_BOOTLOADER_image_on_ram( const char *arg ){
+
+      int status = COMM_SUCCESS;
+	  int tmp;
+      sscanf(arg, "%*s %d", &tmp );
+      bootldrState.flag_image_on_ram = (tmp > 0)? 1:0 ;
+
+      if(tmp == 1){
+
+    	  app_image = (app_image_t*) malloc(sizeof(*app_image));
+    	  if(app_image != NULL){
+
+    		  app_image->num_allocated_pages = MAX_PAGE_NUMBER;
+    		  app_image->num_pages = 0;
+    		  app_image->num_received_pages = 0;
+    		  app_image->page_size = MAX_PAGE_SIZE;
+    		  //app_image->nonce = {0};
+    		  //app_image->auth  = {0};
+    		  //app_image->pages = {0};
+
+     	  }else {
+    		  SERIALOUT("Memory allocation fail for ram image \r\n");
+    		  status = BL_RAM_ALLOC_FAIL;
+    	  }
+
+      }
+
+      SERIALOUT("\r\n%s err=%d\r\n", "image_on_ram", COMM_SUCCESS);
+
+}
+
+int SH_BOOTLDR_get_pagesz(const char *null_arg){
+
+	int status;
+	int pageSize;
+
+	if (bootldrState.flag_image_on_ram) {
+		SERIALOUT("\r\n%s value=%d err=%d\r\n", "page_size", MAX_PAGE_SIZE, COMM_SUCCESS);
+		app_image->page_size   = MAX_PAGE_SIZE;
+		bootldrState.page_size = MAX_PAGE_SIZE;
+		SERIALOUT("\r\n%s err=%d\r\n", "image_on_ram", 1);
+
+	}else {
+
+		status = sh_get_bootloader_pagesz(&pageSize);
+		if (status == 0x00 ){
+			  if( pageSize == -2){
+				  SERIALOUT("\r\n Page size over maximum allowable \r\n");
+				  status = -1;
+			  }else {
+				  SERIALOUT("\r\n%s value=%d err=%d\r\n", "page_size", pageSize, status);
+				  bootldrState.page_size = pageSize;
+			  }
+		}else
+			SERIALOUT("\r\n%s err=%d\r\n", "page_size", status);
+
+	}
+    return status;
+
+}
+
+int SH_BOOTLDR_set_pagecount(const char *arg){
+
+	int status = -1;
+	int pageCount;
+
+    if(sscanf(arg, "%*s %d", &pageCount)){
+
+        if(bootldrState.flag_image_on_ram){
+        	app_image->num_pages =  (pageCount <= MAX_PAGE_NUMBER)?  pageCount:0;
+        	app_image->num_allocated_pages = MAX_PAGE_NUMBER;
+        	bootldrState.num_pages = app_image->num_pages;
+
+        }else {
+
+			status = sh_set_bootloader_numberofpages(pageCount);
+			if (status == 0x00){
+				bootldrState.num_pages = pageCount;
+			}else
+				bootldrState.num_pages = 0;
+        }
+    }
+    SERIALOUT("\r\n%s err=%d\r\n", "num_pages", status);
+	return status;
+
+}
+
+int SH_BOOTLDR_set_iv(const char *arg) {
+
+    uint8_t iv_bytes[AES_NONCE_SIZE];
+    int status =  parse_iv(arg, &iv_bytes[0]);
+    if( status == 0x00){
+
+     	if(bootldrState.flag_image_on_ram){
+    		int i=0;
+    		for(i = 0 ; i != AES_NONCE_SIZE ; i++)
+    			app_image->nonce[i] = iv_bytes[i];
+    		bootldrState.is_iv_set = 1;
+
+    	}else {
+
+			status = sh_set_bootloader_iv(iv_bytes);
+			if( status == 0x00 ) {
+				bootldrState.is_iv_set = 1;
+			}
+			else {
+				bootldrState.is_iv_set = 0;
+				status = COMM_GENERAL_ERROR;
+			}
+		}
+	}
+    SERIALOUT("\r\n%s err=%d\r\n", "set_iv", status);
+
+    return status;
+
+}
+
+
+int SH_BOOTLDR_set_authentication(const char *arg){
+
+	uint8_t auth_bytes[AES_AUTH_SIZE];
+	int status = parse_auth(arg, &auth_bytes[0]);
+    if( status == 0x00){
+
+    	if(bootldrState.flag_image_on_ram){
+    		int i=0;
+    		for(i = 0 ; i != AES_AUTH_SIZE ; i++)
+    			app_image->auth[i] = auth_bytes[i];
+    		bootldrState.is_auth_done = 1;
+
+    	}else {
+
+			status = sh_set_bootloader_auth(auth_bytes);
+			if( status == 0x00 ){
+				bootldrState.is_auth_done = 1;
+			}
+			else
+				status = COMM_GENERAL_ERROR;
+    	}
+
+    }
+    SERIALOUT("\r\n%s err=%d\r\n", "set_auth", status);
+
+    return status;
+
+}
+
+int SH_BOOTLDR_eraseflash(const char *null_arg){
+
+	int status;
+	if(bootldrState.flag_image_on_ram){
+		SERIALOUT("\r\n%s err=%d\r\n", "erase", COMM_SUCCESS);
+		status == 0x00 /*SS_SUCCESS*/;
+
+	}else {
+
+		status = sh_set_bootloader_erase();
+		if(status == 0x00 /*SS_SUCCESS*/) {
+			bootldrState.is_flash_erased = 1;
+		}else{
+			status = COMM_GENERAL_ERROR;
+		}
+		SERIALOUT("\r\n%s err=%d\r\n", "erase", status);
+
+	}
+    return status;
+
+}
+
+
+int SH_BOOTLDR_receive_image_to_ram(void){
+
+
+	int status;
+	int totalBytes = 0;
+	int currentPage = 1;
+
+	if( app_image != NULL && app_image->num_allocated_pages > 0) {
+
+		uint8_t *page = &app_image->pages[0];
+		uint32_t offset = 0;
+		while (currentPage <= app_image->num_pages) {
+
+			while (totalBytes < (MAX_PAGE_SIZE + CHECKBYTES_SIZE)) {
+				page[totalBytes++] = SERIALIN(); // daplink.getc();  ; /////////////////////////////////////////////////////m_USB->_getc();
+			}
+
+			currentPage++;
+			SERIALOUT("\r\npageFlashDone err=%d\r\n", COMM_SUCCESS);
+
+			offset += MAX_PAGE_SIZE + CHECKBYTES_SIZE;
+			page = &app_image->pages[offset];
+			totalBytes = 0;
+		}
+
+		app_image->num_received_pages = currentPage;
+
+		status =  COMM_SUCCESS;
+
+	}else
+	    status =  COMM_GENERAL_ERROR;
+
+	return status;
+
+}
+
+int SH_BOOTLDR_flash_pages(void){
+
+
+    int totalBytes = 0;
+    int currentPage = 1;
+	char charbuf_flash[256];
+	int data_len_flash = 0;
+	int status;
+
+    static uint8_t tx_buf[ BOOTLOADER_MAX_PAGE_SIZE + CHECKBYTES_SIZE + FLASHCMDBYTES] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SENDPAGE };
+    uint8_t *data_buffer = &tx_buf[2];
+
+    if(!is_hub_ready_for_flash()){
+    	printf("missing condition for flashing:  no page size , no page number, iv notset , no outhentication , flash noterased or mode is not bootloader!\r\n");
+    	clear_state_info();
+    	return -1;
+    }
+    printf(" \r\n NOW WE ARE FLASHING THE PAGES..........\r\n");
+    printf(" \r\n page_size:  %d \r\n", bootldrState.page_size);
+    printf(" \r\n num_pages:  %d \r\n", bootldrState.num_pages);
+
+    while (currentPage <= bootldrState.num_pages) {
+
+        while (totalBytes < (bootldrState.page_size + CHECKBYTES_SIZE)) {
+            data_buffer[totalBytes++] = SERIALIN(); //daplink.getc(); //m_USB->_getc();  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MYG
+            //Here we should be able to take the data over BLE
+        }
+        printf(" \r\n NOW WE GOT A  PAGE..........\r\n");
+        //status = sh_bootloader_flashpage(&tx_buf[0] , bootldrState.page_size);
+
+        status = sh_write_cmd(tx_buf, bootldrState.page_size + CHECKBYTES_SIZE + 2, 2000);
+
+        if (status == 0x00)
+        		printf(" \r\n NOW WE PUSHED A  PAGE..........\r\n");
+/*
+        if (status == 0x00){
+        	currentPage++;
+        	SERIALOUT("\r\npageFlashDone err=%d\r\n", COMM_SUCCESS);
+        }else{
+
+        	if (status == SS_ERR_BTLDR_CHECKSUM)
+        		SERIALOUT("\r\npageFlashDone err=%d\r\n", BL_FLASH_ERR_CHECKSUM);
+        	else
+        		SERIALOUT("\r\npageFlashDone err=%d\r\n", BL_FLASH_ERR_GENERAL);
+
+        }
+ */
+
+        if (status == SS_ERR_BTLDR_CHECKSUM) {
+
+            data_len_flash = snprintf(charbuf_flash, sizeof(charbuf_flash), "\r\npageFlashDone err=%d\r\n", FLASH_ERR_CHECKSUM);
+            SERIALOUT(charbuf_flash);
+        } else if (status != SS_SUCCESS) {
+
+            data_len_flash = snprintf(charbuf_flash, sizeof(charbuf_flash), "\r\npageFlashDone err=%d\r\n", FLASH_ERR_GENERAL);
+            SERIALOUT(charbuf_flash);
+        } else {
+            currentPage++;
+
+            data_len_flash = snprintf(charbuf_flash, sizeof(charbuf_flash), "\r\npageFlashDone err=%d\r\n", COMM_SUCCESS);
+            SERIALOUT(charbuf_flash);
+        }
+        totalBytes = 0;
+
+    }
+    //SERIALOUT(" all pages are flashed \r\n");
+    clear_state_info();
+
+    return status;
+
+}
+
+
+int SH_BOOTLDR_flash(const char *null_arg){
+
+	int status;
+	if(bootldrState.flag_image_on_ram)
+		status = SH_BOOTLDR_receive_image_to_ram();
+	else
+		status = SH_BOOTLDR_flash_pages();
+
+	SERIALOUT("\r\n%s err=%d\r\n", "flash", status);
+
+	return status;
+}
+
+
+int SH_BOOTLDR_flash_appimage_from_ram(const char *null_arg){
+
+
+	int currentPage = 1;
+	uint32_t offset = 0;
+	int ret;
+
+	if(app_image == NULL)
+	    return -1;
+
+	/* Put device to bootloader mode */
+	int status = SH_BOOTLDR_enter_blmode(NULL);
+	if( status != 0x00)
+         return -1;
+
+	wait_ms(10);
+
+	status = sh_set_bootloader_numberofpages(app_image->num_pages);
+	SERIALOUT("*** set_num_page... ret: %d\n", ret);
+	if (status != 0x00) {
+		return BL_SET_NUM_PAGES_FAIL;
+	}
+
+	status = sh_set_bootloader_iv(app_image->nonce);
+	SERIALOUT("*** set_iv... ret: %d\n", ret);
+	if (status != 0) {
+		return BL_SET_IV_FAIL;
+	}
+
+	status = sh_set_bootloader_auth(app_image->auth);
+	SERIALOUT("*** set_auth... ret: %d\n", ret);
+	if (status != 0) {
+		return BL_FLASH_ERR_AUTH;
+	}
+
+	status = sh_set_bootloader_erase() ;
+	SERIALOUT("*** erase app memory... ret: %d\n", ret);
+	if (status != 0) {
+		return BL_FLASS_ERASE_FAIL;
+	}
+
+	static uint8_t tx_buf[MAX_PAGE_SIZE + CHECKBYTES_SIZE + 2];
+
+	tx_buf[0] = SS_FAM_W_BOOTLOADER;
+	tx_buf[1] = SS_CMDIDX_SENDPAGE;
+
+	while (currentPage <= app_image->num_pages) {
+
+		memcpy(&tx_buf[2], &app_image->pages[offset], MAX_PAGE_SIZE + CHECKBYTES_SIZE);
+
+		status = sh_write_cmd(tx_buf, MAX_PAGE_SIZE + CHECKBYTES_SIZE + 2, bootldrState.bootcmds_delay_factor * PAGE_WRITE_DELAY_MS);
+
+		if (status == SS_ERR_BTLDR_CHECKSUM) {
+
+			SERIALOUT("\r\npageFlashDone err=%d\r\n", BL_FLASH_ERR_CHECKSUM);
+			break;
+		} else if (status != SS_SUCCESS) {
+
+			SERIALOUT("\r\npageFlashDone err=%d\r\n", BL_FLASH_ERR_GENERAL);
+			break;
+		} else {
+
+			SERIALOUT("\r\npageFlashDone err=%d\r\n", COMM_SUCCESS);
+		}
+
+		offset += MAX_PAGE_SIZE + CHECKBYTES_SIZE;
+		currentPage++;
+	}
+
+	return COMM_SUCCESS;
+
+}
+
+int SH_BOOTLDR_set_host_ebl_mode(const char *arg) {
+
+    int status;
+    int tmp;
+    sscanf(arg, "%*s %*s %*s %d", &tmp);
+    status = sh_set_ebl_mode(tmp);
+    if( status == 0x00) {
+    	bootldrState.ebl_mode = tmp;
+    }else
+    	status = COMM_INVALID_PARAM;
+
+    SERIALOUT("\r\n%s err=%d\r\n", "set_cfg host ebl",status);
+
+    return status;
+
+}
+
+int SH_BOOTLDR_get_host_ebl_mode(const char *null_arg){
+
+      int value;
+      value = sh_get_ebl_mode();
+      SERIALOUT("\r\n%s value=%s\r\n", "get_cfg host ebl", (value==1)? "GPIO_RST_MODE":"CMD_RST_MODE");
+      return 0x00;
+}
+
+int SH_BOOTLDR_set_host_bootcmds_delay_factor( const char *arg) {
+
+     int status;
+	 int tmp;
+     sscanf(arg, "%*s %*s %*s %d", &tmp);
+     status =  sh_set_bootloader_delayfactor( tmp);
+     if( status == 0x00) {
+    	 bootldrState.bootcmds_delay_factor = tmp;
+     }else
+    	 status = COMM_INVALID_PARAM;
+
+     SERIALOUT("\r\n%s err=%d\r\n", "set_cfg host cdf",status);
+
+     return status;
+
+}
+
+int SH_BOOTLDR_get_host_bootcmds_delay_factor( const char *null_arg){
+
+	int value;
+	value =  sh_get_bootloader_delayfactor();
+	SERIALOUT("\r\n%s value=%d \r\n", "get_cfg host cdf", value);
+	return 0x00;
+
+}
+
+static int is_hub_ready_for_flash(void){
+
+	int status = 0;
+	if( bootldrState.hub_mode_bootloader == 1 &&
+		 bootldrState.is_auth_done == 1	&&
+		  bootldrState.is_iv_set == 1 &&
+		   bootldrState.is_flash_erased == 1 &&
+		    bootldrState.num_pages > 0 &&
+			 bootldrState.page_size > 0 )
+		    	status =  1;
+
+    return status;
+}
+
+static void clear_state_info(void) {
+
+	bootldrState.is_auth_done    = 0;
+	bootldrState.is_iv_set       = 0;
+	bootldrState.is_flash_erased = 0;
+	bootldrState.num_pages       = 0;
+	bootldrState.page_size       = 0;
+	bootldrState.hub_mode_bootloader;
+
+	return;
+}
+
+static int parse_iv(const char* cmd, uint8_t* iv_bytes) {
+
+	int status = 0x00;
+	char cmdStr[] = "set_iv ";
+	int length = strlen(cmd);
+	int expected_length = strlen(cmdStr) + 2*AES_NONCE_SIZE;
+
+	if (length != expected_length) {
+		SERIALOUT("Couldn't parse IV, incorrect number of characters (len:%d, expected:%d)\n",
+               length, expected_length);
+		status = COMM_INVALID_PARAM;
+	}else{
+
+		const char* ivPtr = cmd + strlen(cmdStr);
+		int num_found;
+		int byteVal;
+		for (int ividx = 0; ividx < AES_NONCE_SIZE; ividx++) {
+			num_found = sscanf(ivPtr, "%2X", &byteVal);
+
+			if (num_found != 1 || byteVal > 0xFF) {
+				status = COMM_INVALID_PARAM;
+				//break; //
+				return status;
+			}
+			iv_bytes[ividx] = (uint8_t)byteVal;
+		   ivPtr += 2;
+		}
+	}
+    return status;
+
+}
+
+
+static int parse_auth(const char* cmd, uint8_t *auth_bytes){
+
+	int status = 0x00;
+	char cmdStr[] = "set_auth ";
+    int length = strlen(cmd);
+    int expected_length = strlen(cmdStr) + 2*AES_AUTH_SIZE;
+
+    if (length != expected_length) {
+    	status = -1;
+    }else{
+
+		const char* macPtr = cmd + strlen(cmdStr);
+
+		int num_found;
+		int byteVal;
+		for (int aidx = 0; aidx < AES_AUTH_SIZE; aidx++) {
+			num_found = sscanf(macPtr, "%2X", &byteVal);
+
+			if (num_found != 1 || byteVal > 0xFF) {
+				status = COMM_INVALID_PARAM;;
+				//break; //
+				return status;
+			}
+
+			auth_bytes[aidx] = (uint8_t)byteVal;
+			macPtr += 2;
+		}
+
+    }
+    return status;
+
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bootloader/bootldrAPI.h	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,200 @@
+/*
+ * bootldrInterface.h
+ *
+ *  Created on: Feb 7, 2019
+ *      Author: Yagmur.Gok
+ */
+
+#ifndef SOURCE_CMDUI_BOOTLDRINTERFACE_H_
+#define SOURCE_CMDUI_BOOTLDRINTERFACE_H_
+
+typedef int (*cmdExecFunc)( const char*); // typedef void (*cmdExecFunc)( const void*);
+
+typedef struct {
+	char const* cmdStr;
+	cmdExecFunc execute;
+	char const *help;
+}cmd_interface_tb;
+
+#define FLASH_ERR_GENERAL   -1
+#define FLASH_ERR_CHECKSUM  -2
+#define FLASH_ERR_AUTH      -3
+
+/**
+* @brief	  sets the SENSOR HUB to Bootloader Mode for Firmware update. Prints status info on command console
+*
+* @param[in]  null_arg : NULL string, just to match the form of command table function pointer type
+*
+* @return status info, 0x00 on success.
+**/
+int SH_BOOTLDR_enter_blmode(const char *null_arg);
+
+/**
+* @brief	  exits the SENSOR HUB from Bootloader Mode to Application Mode. Prints status info on command console
+*
+* @param[in]  null_arg : NULL string, just to match the form of command table function pointer type
+*
+* @return status info, 0x00 on success.
+**/
+int SH_BOOTLDR_exit_blmode(const char *null_arg);
+
+/**
+* @brief	  gets the page size of bootloader within SENSOR HUB. Prints status info and page size value on command console
+*
+* @param[in]  null_arg : NULL string, just to match the form of command table function pointer type
+*
+* @return status info, 0x00 on success.
+**/
+int SH_BOOTLDR_get_pagesz(const char *null_arg);
+
+/**
+* @brief	  sets the totatl page count for MSBL file to be uploaded to SENSOR HUB. Prints status info on command console
+*
+* @param[in]  arg : byte string including command followed by page size value extracted from header of MSBL file in DECIMAL format!
+*                   "num_pages 24"
+*
+* @return status info, 0x00 on success.
+**/
+int SH_BOOTLDR_set_pagecount(const char *arg);
+
+/**
+* @brief	  sets the IV vector of  MSBL file to be uploaded to SENSOR HUB. Prints status info on command console
+*             IV vector is 22 bytes of data extracted from header of MSBL file.
+*
+* @param[in]  arg : byte string including command followed by 22 byte IV value in HEXADECIMAL format! do no preceed IV bytes wirh 0x !!!!
+                    "set_iv 1234567891234567891234"
+*
+* @return status info, 0x00 on success.
+**/
+int SH_BOOTLDR_set_iv(const char *arg);
+
+/**
+* @brief	  sets the Authentication vector of  MSBL file to be uploaded to SENSOR HUB. Prints status info on command console
+*             Authentication vector is 36 bytes of data extracted from header of MSBL file.
+*
+* @param[in]  arg : byte string including command followed by 22 byte IV value in HEXADECIMAL format! do no preceed IV bytes wirh 0x !!!!
+                    "set_auth 12345678912345678912345678912345"
+*
+* @return status info, 0x00 on success.
+**/
+int SH_BOOTLDR_set_authentication(const char *arg);
+
+/**
+* @brief	  erases application code of SENSOR HUB. Prints status info on command console
+*
+* @param[in]  null_arg : NULL string, just to match the form of command table function pointer type
+*
+* @return status info, 0x00 on success.
+**/
+int SH_BOOTLDR_eraseflash(const char *null_arg);
+
+/**
+* @brief	  puts the SENSOR HUB to the state of waiting for MSBL application code pages from serial command interface.
+*             Prints status info on command console upon flashing of every page.
+*
+* @param[in]  null_arg : NULL string, just to match the form of command table function pointer type
+*
+* @return status info, 0x00 on success.
+**/
+int SH_BOOTLDR_flash(const char *null_arg);
+
+/**
+* @brief	  sets the SENSOR HUB to the bootloader state where application image pages are first stored into HOST ram and will be flashed
+*             at once. Prints status info on command console.
+*
+* @param[in]  arg : byte string including command followed by 1 byte omage on ram flag in DECIMAL format
+*                   "image_on_ram 0/1"  0: for classic mode where pages are downloaded form PC over serial command console and
+*                    flashed to SENSOR HUB 1 by 1. 1: for image on ram mode.
+*
+* @return status info, 0x00 on success.
+**/
+int SH_BOOTLOADER_image_on_ram( const char *arg );
+
+/**
+* @brief	  flashes pages in HOST Ram to Sensor Hub.
+*             USE ONLY IN IMAGE_ON_RAM MODE !!!!
+*
+* @param[in]  null_arg : NULL string, just to match the form of command table function pointer type
+*
+* @return status info, 0x00 on success.
+**/
+int SH_BOOTLDR_flash_appimage_from_ram(const char *null_arg);
+
+/**
+* @brief	  set the delay factor multipler for Bootloader wait durations in commands and between flashing of pages
+*
+* @param[in]  arg : byte string including command followed by delay factor in DECIMAL format
+*                   "set_cfg host cdf 1" to "set_cfg host cdf 4" practical range. 1 is default.
+*
+* @return status info, 0x00 on success.
+**/
+int SH_BOOTLDR_set_host_bootcmds_delay_factor( const char *arg);
+
+/**
+* @brief	  get the delay factor multipler for Bootloader wait durations in commands and between flashing of pages.
+*             Prints delay factor multipler value on command console.
+*
+* @param[in]  null_arg : NULL string, just to match the form of command table function pointer type
+*
+* @return status info, 0x00 on success.
+**/
+int SH_BOOTLDR_get_host_bootcmds_delay_factor( const char *null_arg);
+
+/**
+* @brief	  sets the resetting method of SENSOR HUB between command based and GPIO based resets. Default is GPIO based reset.ie 1.
+*
+* @param[in]  arg : byte string including command followed by ebl mode in DECIMAL format
+*                   "set_cfg host ebl 1/0" . 0 for command based reset; 1 for GPIO based reset which is default and preferred option.
+*
+* @return status info, 0x00 on success.
+**/
+int SH_BOOTLDR_set_host_ebl_mode(const char *arg);
+
+/**
+* @brief	  gets the resetting method of SENSOR HUB between command based and GPIO based resets.
+*             Prints delay factor multipler value on command console.
+*
+* @param[in]  null_arg : NULL string, just to match the form of command table function pointer type
+*
+* @return status info, 0x00 on success.
+**/
+int SH_BOOTLDR_get_host_ebl_mode(const char *null_arg);
+
+/**
+* @brief	  gets the struct keeping state information about bootloading steps required at HOST side.
+*             Prints struct data fields and state flags; ie. is_iv_set? page_size acquired from hub etc.
+*             If all steps are not done, flashing operation do not take place and informs user on command
+*             console
+*
+* @param[in]  null_arg : NULL string, just to match the form of command table function pointer type
+*
+* @return status info, 0x00 on success.
+**/
+int BOOTLDR_get_host_bootloader_state(const char *null_arg);
+
+
+#define NUMCMDSBOOTLDRAPI (15)
+
+const cmd_interface_tb CMDTABLEBOOTLDR[] = {
+
+		{  "bootldr"     	  , SH_BOOTLDR_enter_blmode	      			  , "resets and puts sensor hub to bootloader mode "	   			 												},
+		{  "exit"             , SH_BOOTLDR_exit_blmode        			  , "exits sensor hub from bootloader mode to app mode" 			  							  					},
+		{  "page_size"        , SH_BOOTLDR_get_pagesz         			  , "returns sensor hub bootloader page size for app data pages"   							      					},
+		{  "num_pages"        , SH_BOOTLDR_set_pagecount      			  , "sets sensor hub bootloader app image pages, uasge: num_pages PAGES" 				    						},
+		{  "set_iv"           , SH_BOOTLDR_set_iv             			  , "sets sensor hub bootloader initial vector bytes, usage: set_iv XXXXXXXXXXX (11 hex chrs)"      				},
+		{  "set_auth"         , SH_BOOTLDR_set_authentication 			  , "sets sensor hub bootloader authentication bytes, usage: set_iv XXXXXXXXXXXXXXXX (16 hex chrs)" 				},
+		{  "erase"            , SH_BOOTLDR_eraseflash         			  , "erases sesn hub application flash memory" 							        				  					},
+		{  "image_on_ram"     , SH_BOOTLOADER_image_on_ram    			  , "selects pagBypage download-flash / block download-flash options"           									},
+		{  "flash"            , SH_BOOTLDR_flash              	    	  ,  "flash image to hub/dowload pages from PC based on image_on_ram selection" 									},
+		{  "image_flash"      , SH_BOOTLDR_flash_appimage_from_ram        , "flashes app image in ram to sensor hub, call after flash cmd in image_on_ram mode"								},
+		{  "set_cfg host cdf" , SH_BOOTLDR_set_host_bootcmds_delay_factor , "sets delay factor for bootoader cmd waits default 1, usage: set_cfg host cdf FACTOR"       					},
+		{  "set_cfg host ebl" , SH_BOOTLDR_set_host_ebl_mode              , "sets GPIO/CMD reset for reset hub to bootoader mode. default GPIO, usage: set_cfg host ebl 1/0,  1 for GPIO"  	},
+		{  "get_cfg host cdf" , SH_BOOTLDR_get_host_bootcmds_delay_factor , "sets delay factor for bootoader cmd waits default 1, usage: set_cfg host cdf FACTOR"       					},
+		{  "get_cfg host ebl" , SH_BOOTLDR_get_host_ebl_mode              , "sets GPIO/CMD reset for reset hub to bootoader mode. default GPIO, usage: set_cfg host ebl 1/0,  1 for GPIO"  	},
+		{  "get_host_boot_state_info" , BOOTLDR_get_host_bootloader_state , "gets boot state keeping struct of host"  	                                                                    },
+
+
+};
+
+#endif /* SOURCE_CMDUI_BOOTLDRINTERFACE_H_ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmdUI/cmdInterface.cpp	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,175 @@
+/*
+ * cmdInterface.cpp
+ *
+ *  Created on: Jan 30, 2019
+ *      Author: Yagmur.Gok
+ */
+
+#include <mbed.h>
+#include "cmdInterface.h"
+#include "SH_Max8614x_BareMetal.h"
+#include "bootldrAPI.h"
+#include "SHComm.h"
+#include "demoDefinitions.h"
+
+static uint8_t hostOperatingMode = HOSTMODEAPPLICATION;
+
+
+static int get_host_operating_mode(const char* arg){
+
+	int status = 0x00;
+	SERIALOUT("\r\n%s host_operating_mode=%s\r\n", "get_host_mode", (hostOperatingMode ==HOSTMODEAPPLICATION)? "APPMODE":"BOOTLOADERMODE" );
+    return status;
+}
+
+static int set_host_operating_mode(const char* arg){
+
+    int status = -1;
+	uint32_t val;
+	if(  sscanf(arg, "%*s %x", &val) == 1 ){
+		hostOperatingMode = ( val > 0 )? HOSTMODEBOOTLOADER:HOSTMODEAPPLICATION;
+
+		status = 0x00;
+	}
+	SERIALOUT("\r\n%s err=%d\r\n", "set_host_opmode", status);
+    return status;
+
+}
+
+
+
+static int get_hub_operating_mode(const char* arg){
+
+	uint8_t hubMode;
+	int status = sh_get_sensorhub_operating_mode(&hubMode);
+	if( status == 0x00)
+		SERIALOUT("\r\n hub_operating_mode=%s\r\n", (hubMode == 0x00)? "APPMODE":"BOOTLOADERMODE" );
+	else
+		SERIALOUT("\r\n%s err=%d\r\n", "get_sensorhub_opmode", status);
+
+    return status;
+}
+
+uint8_t get_internal_operating_mode(void){
+
+	return hostOperatingMode;
+}
+
+
+cmd_interface_t setHostModeCMD = {"set_host_opmode"     , set_host_operating_mode , "sets mode of host to app or bootloader"};
+cmd_interface_t getHostModeCMD = {"get_host_opmode"     , get_host_operating_mode , "gets mode of host app or bootloader"};
+cmd_interface_t getHubModeCMD =  {"get_sensorhub_opmode", get_hub_operating_mode , "gets mode of host app or bootloader"};
+
+
+static bool starts_with(const char* str1, const char* str2)
+{
+	while (*str1 && *str2) {
+		if (*str1 != *str2)
+			return false;
+		str1++;
+		str2++;
+	}
+
+	if (*str2)
+		return false;
+
+	return true;
+}
+
+//MYG DEBUG:
+
+int parse_execute_command( const char *cmd_str)
+{
+
+	int found = 0;
+    int tableIdx;
+    if( starts_with(&cmd_str[0], setHostModeCMD.cmdStr)) {
+    	int status = setHostModeCMD.execute(cmd_str);
+        if( status != 0x00){
+        	SERIALOUT("\r\n%s err=%d\r\n", "set_host_mode", COMM_INVALID_PARAM);
+        	hostOperatingMode = 0;
+        }
+        found = 1;
+    }
+
+    if( starts_with(&cmd_str[0], getHostModeCMD.cmdStr)) {
+    	int  status = getHostModeCMD.execute(cmd_str);
+    	found = 1;
+    }
+
+    if( starts_with(&cmd_str[0], getHubModeCMD.cmdStr)) {
+    	int  status = getHubModeCMD.execute(cmd_str);
+    	found = 1;
+    }
+
+    if( hostOperatingMode == HOSTMODEAPPLICATION) {
+
+		tableIdx = NUMCMDS8614X;
+		do{
+			tableIdx -= 1;
+			if (starts_with(&cmd_str[0], CMDTABLE8614x[tableIdx].cmdStr)){
+
+				CMDTABLE8614x[tableIdx].execute(cmd_str);
+				/*MYG DEBUG8*/// SERIALPRINT("___SELECTED COMMAND IDX IS: %d \r\n", tableIdx);
+				SERIALOUT(" \r\n"); // Here is needed due to a bug on mbed serial!
+				found = 1;
+			}
+
+		}while(tableIdx && found == 0 );
+
+    }
+
+    if( hostOperatingMode == HOSTMODEBOOTLOADER) {
+
+
+    	tableIdx = NUMCMDSBOOTLDRAPI;
+		do{
+			tableIdx -= 1;
+			if (starts_with(&cmd_str[0], CMDTABLEBOOTLDR[tableIdx].cmdStr)){
+
+				CMDTABLEBOOTLDR[tableIdx].execute(cmd_str);
+				/*MYG DEBUG8*/// SERIALPRINT("___SELECTED COMMAND IDX IS: %d \r\n", tableIdx);
+				SERIALOUT(" \r\n"); // Here is needed due to a bug on mbed serial!
+				found = 1;
+			}
+
+		}while(tableIdx && found == 0 );
+    }
+
+    return found;
+}
+
+
+void cmdIntf_build_command(char ch)
+{
+	static char cmd_str[1024];
+    static int cmd_idx = 0;
+    int status;
+
+	if (ch == 0x00) {
+		return;
+	}
+
+	if ((ch == '\n') || (ch == '\r')) {
+		if (cmd_idx < 1024)
+		cmd_str[cmd_idx++] = '\0';
+		status = parse_execute_command(cmd_str);
+
+		//Clear cmd_str
+		while (cmd_idx > 0)
+			cmd_str[--cmd_idx] = '\0';
+
+	} else if ((ch == 0x08 || ch == 0x7F) && cmd_idx > 0) {
+		//Backspace character
+		if (cmd_idx > 0)
+			cmd_str[--cmd_idx] = '\0';
+	} else {
+
+		if (cmd_idx < 1024)
+			cmd_str[cmd_idx++] = ch;
+	}
+
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmdUI/cmdInterface.h	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,32 @@
+/*
+ * cmdInterface.h
+ *
+ *  Created on: Jan 30, 2019
+ *      Author: Yagmur.Gok
+ */
+
+#ifndef SOURCE_CMDUI_CMDINTERFACE_H_
+#define SOURCE_CMDUI_CMDINTERFACE_H_
+
+#define COMM_SUCCESS        0
+#define COMM_GENERAL_ERROR  -1
+#define COMM_INVALID_PARAM  -254
+#define COMM_NOT_RECOGNIZED -255
+
+#define FLASH_ERR_GENERAL   -1
+#define FLASH_ERR_CHECKSUM  -2
+#define FLASH_ERR_AUTH      -3
+
+void cmdIntf_build_command(char ch);
+
+
+enum{
+	HOSTMODEAPPLICATION = 0,
+	HOSTMODEBOOTLOADER  = 1
+};
+
+uint8_t get_internal_operating_mode(void);
+
+
+#endif /* SOURCE_CMDUI_CMDINTERFACE_H_ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demoDefinitions.h	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,22 @@
+/*
+ * demoDefinitions.h
+ *
+ *  Created on: Feb 13, 2019
+ *      Author: Yagmur.Gok
+ */
+
+#ifndef SOURCE_DEMODEFINITIONS_H_
+#define SOURCE_DEMODEFINITIONS_H_
+
+
+#include "USBSerial.h"
+
+extern Serial daplink;
+extern USBSerial microUSB;
+//#define SERIALOUT printf
+#define SERIALOUT microUSB.printf
+#define SERIALIN microUSB._getc
+#define SERIAL_AVAILABLE microUSB.readable
+
+#endif /* SOURCE_DEMODEFINITIONS_H_ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demoUI/demoUI.cpp	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,437 @@
+
+
+/*
+ * Note: This API i intended for demo purposes and specific to display screen LS013B7DH03. Being targeted for result display only
+ *       performance/memory measures are not taken into account! It is kept simple and some rules of embedded sw developmentare are
+ *       sacrified for being easily understandable.
+ *
+ * */
+
+#include "demoUI.h"
+/*demo specific display screen driver*/
+#include "screen/LS013B7DH03.h"
+
+const unsigned char UbuntuCondensed16x21[] = {
+		49, 16,21,3,
+        0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char
+        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xCF, 0x01, 0xFC, 0xCF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char !
+        0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char "
+        0x0B, 0x00, 0x00, 0x00, 0x40, 0x10, 0x00, 0x40, 0xFE, 0x01, 0xFC, 0x1F, 0x00, 0x7C, 0x10, 0x00, 0x40, 0x10, 0x00, 0x40, 0xF0, 0x01, 0xC0, 0xFF, 0x01, 0xFC, 0x1F, 0x00, 0x7C, 0x10, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char #
+        0x08, 0x00, 0x00, 0x00, 0xE0, 0x60, 0x00, 0xF0, 0xC1, 0x00, 0x18, 0xC3, 0x00, 0x1E, 0xC7, 0x07, 0x1E, 0xC6, 0x07, 0x18, 0xFE, 0x00, 0x18, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char $
+        0x0D, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x00, 0x04, 0x02, 0x01, 0xFC, 0xE3, 0x01, 0xF8, 0x79, 0x00, 0x00, 0x1E, 0x00, 0xC0, 0x03, 0x00, 0xF0, 0xFC, 0x00, 0x3C, 0xFE, 0x01, 0x04, 0x02, 0x01, 0x00, 0xFE, 0x01, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char %
+        0x0A, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x78, 0xFE, 0x00, 0xFC, 0xC7, 0x01, 0x8C, 0x83, 0x01, 0x8C, 0x8F, 0x01, 0xFC, 0x9C, 0x01, 0x78, 0xF0, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x8E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char &
+        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char '
+        0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7F, 0x00, 0xF0, 0xFF, 0x03, 0x3C, 0x00, 0x0F, 0x06, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char (
+        0x04, 0x06, 0x00, 0x18, 0x3C, 0x00, 0x0F, 0xF0, 0xFF, 0x03, 0x80, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char )
+        0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x58, 0x00, 0x00, 0xD4, 0x00, 0x00, 0x3C, 0x00, 0x00, 0xD4, 0x00, 0x00, 0x58, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char *
+        0x09, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x80, 0x7F, 0x00, 0x80, 0x7F, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char +
+        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x80, 0x0F, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char ,
+        0x05, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char -
+        0x03, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char .
+        0x06, 0x00, 0x80, 0x1F, 0x00, 0xF8, 0x07, 0x80, 0x7F, 0x00, 0xF8, 0x07, 0x00, 0x7E, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char /
+        0x08, 0x00, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0xF8, 0xFF, 0x00, 0x1C, 0xC0, 0x01, 0x0C, 0x80, 0x01, 0x1C, 0xC0, 0x01, 0xF8, 0xFF, 0x00, 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char 0
+        0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char 1
+        0x07, 0x00, 0x00, 0x00, 0x08, 0xC0, 0x01, 0x0C, 0xF8, 0x01, 0x0C, 0x9C, 0x01, 0x0C, 0x87, 0x01, 0xFC, 0x83, 0x01, 0xF8, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char 2
+        0x08, 0x00, 0x00, 0x00, 0x08, 0xC0, 0x00, 0x0C, 0x80, 0x01, 0x0C, 0x83, 0x01, 0x0C, 0x83, 0x01, 0x9C, 0xC7, 0x01, 0xF8, 0xFF, 0x00, 0xF0, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char 3
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x80, 0x1F, 0x00, 0xF0, 0x19, 0x00, 0x3C, 0x18, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char 4
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xFC, 0x83, 0x01, 0xFC, 0x83, 0x01, 0x0C, 0x83, 0x01, 0x0C, 0xC7, 0x01, 0x0C, 0xFE, 0x00, 0x0C, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char 5
+        0x08, 0x00, 0x00, 0x00, 0x80, 0x7F, 0x00, 0xF0, 0xFF, 0x00, 0x78, 0xC3, 0x01, 0x18, 0x83, 0x01, 0x0C, 0x83, 0x01, 0x0C, 0xFF, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char 6
+        0x08, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0xC0, 0x01, 0x0C, 0xFC, 0x01, 0x8C, 0x1F, 0x00, 0xEC, 0x01, 0x00, 0x7C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char 7
+        0x08, 0x00, 0x00, 0x00, 0xF0, 0x78, 0x00, 0xF8, 0xFD, 0x00, 0x0C, 0x87, 0x01, 0x0C, 0x82, 0x01, 0x0C, 0x87, 0x01, 0xF8, 0xFD, 0x00, 0x78, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char 8
+        0x08, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xF8, 0x83, 0x01, 0x0C, 0x87, 0x01, 0x0C, 0xC6, 0x00, 0x1C, 0xF6, 0x00, 0xF8, 0x7F, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char 9
+        0x03, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0x01, 0xE0, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char :
+        0x04, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x18, 0xE0, 0x80, 0x0F, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char ;
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x11, 0x00, 0x80, 0x31, 0x00, 0xC0, 0x60, 0x00, 0xC0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char <
+        0x08, 0x00, 0x00, 0x00, 0x80, 0x31, 0x00, 0x80, 0x31, 0x00, 0x80, 0x31, 0x00, 0x80, 0x31, 0x00, 0x80, 0x31, 0x00, 0x80, 0x31, 0x00, 0x80, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char =
+        0x08, 0x00, 0x00, 0x00, 0xC0, 0x60, 0x00, 0xC0, 0x60, 0x00, 0x80, 0x31, 0x00, 0x00, 0x11, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char >
+        0x07, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0xCE, 0x01, 0x0C, 0xCF, 0x01, 0x8C, 0x03, 0x00, 0xF8, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char ?
+        0x10, 0x00, 0x00, 0x00, 0x80, 0x7F, 0x00, 0xE0, 0xFF, 0x01, 0xF0, 0xC0, 0x03, 0x38, 0x00, 0x07, 0x18, 0x3E, 0x0E, 0x0C, 0x7F, 0x0C, 0x8C, 0x61, 0x0C, 0x8C, 0x61, 0x0C, 0x8C, 0x3F, 0x0C, 0x8C, 0x7F, 0x0C, 0x1C, 0x60, 0x00, 0x18, 0x60, 0x00, 0x70, 0x70, 0x00, 0xE0, 0x3F, 0x00, 0xC0, 0x1F, 0x00,  // Code for char @
+        0x0B, 0x00, 0x80, 0x01, 0x00, 0xF8, 0x01, 0x00, 0x7F, 0x00, 0xE0, 0x3F, 0x00, 0xFC, 0x30, 0x00, 0x0C, 0x30, 0x00, 0xFC, 0x30, 0x00, 0xE0, 0x37, 0x00, 0x00, 0x7F, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char A
+        0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x0C, 0x83, 0x01, 0x0C, 0x83, 0x01, 0x0C, 0x83, 0x01, 0x9C, 0xC7, 0x01, 0xF8, 0xFF, 0x00, 0xF0, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char B
+        0x09, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0xF0, 0x7F, 0x00, 0x38, 0xE0, 0x00, 0x0C, 0xC0, 0x01, 0x0C, 0x80, 0x01, 0x0C, 0x80, 0x01, 0x0C, 0x80, 0x01, 0x18, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char C
+        0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x0C, 0x80, 0x01, 0x0C, 0x80, 0x01, 0x0C, 0x80, 0x01, 0x1C, 0xC0, 0x01, 0x38, 0xE0, 0x00, 0xF0, 0x7F, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char D
+        0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x0C, 0x83, 0x01, 0x0C, 0x83, 0x01, 0x0C, 0x83, 0x01, 0x0C, 0x83, 0x01, 0x0C, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char E
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x0C, 0x03, 0x00, 0x0C, 0x03, 0x00, 0x0C, 0x03, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char F
+        0x0A, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0xF0, 0x7F, 0x00, 0x38, 0xE0, 0x00, 0x1C, 0xC0, 0x01, 0x0C, 0x80, 0x01, 0x0C, 0x80, 0x01, 0x0C, 0x80, 0x01, 0x0C, 0xFE, 0x01, 0x08, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char G
+        0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char H
+        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char I
+        0x06, 0x00, 0xC0, 0x00, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0xFC, 0xFF, 0x01, 0xFC, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char J
+        0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x80, 0x03, 0x00, 0xE0, 0x07, 0x00, 0x78, 0x1C, 0x00, 0x1C, 0xF8, 0x00, 0x04, 0xE0, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char K
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char L
+        0x0E, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x1C, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x70, 0x00, 0x00, 0x7E, 0x00, 0xE0, 0x0F, 0x00, 0xFC, 0x00, 0x00, 0x1C, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xE0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char M
+        0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x7C, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xF8, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char N
+        0x0C, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0xF0, 0x7F, 0x00, 0x38, 0xE0, 0x00, 0x1C, 0xC0, 0x01, 0x0C, 0x80, 0x01, 0x0C, 0x80, 0x01, 0x0C, 0x80, 0x01, 0x1C, 0xC0, 0x01, 0x38, 0xE0, 0x00, 0xF0, 0x7F, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char O
+        0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x0C, 0x0C, 0x00, 0x0C, 0x0C, 0x00, 0x1C, 0x0E, 0x00, 0xF8, 0x07, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char P
+        0x0C, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0xF0, 0x7F, 0x00, 0x38, 0xE0, 0x00, 0x1C, 0xC0, 0x01, 0x0C, 0x80, 0x01, 0x0C, 0x80, 0x07, 0x0C, 0x80, 0x0F, 0x1C, 0xC0, 0x0D, 0x38, 0xE0, 0x18, 0xF0, 0x7F, 0x18, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char Q
+        0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x0C, 0x0C, 0x00, 0x0C, 0x0C, 0x00, 0x1C, 0x3E, 0x00, 0xF8, 0xF7, 0x00, 0xF0, 0xC3, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char R
+        0x07, 0x00, 0x00, 0x00, 0xF0, 0xC0, 0x00, 0xF8, 0x83, 0x01, 0x8C, 0x83, 0x01, 0x0C, 0x87, 0x01, 0x0C, 0xFE, 0x00, 0x1C, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char S
+        0x09, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFC, 0xFF, 0x01, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char T
+        0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0xC0, 0x01, 0xFC, 0xFF, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char U
+        0x09, 0x1C, 0x00, 0x00, 0xFC, 0x03, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x80, 0x01, 0x00, 0xFC, 0x01, 0xE0, 0x7F, 0x00, 0xFC, 0x07, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char V
+        0x0F, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x80, 0xFF, 0x01, 0x00, 0x80, 0x01, 0x00, 0xF8, 0x01, 0x80, 0x7F, 0x00, 0xF0, 0x07, 0x00, 0x70, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0xFF, 0x01, 0x00, 0x80, 0x01, 0x80, 0xFF, 0x01, 0xFC, 0xFF, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char W
+        0x09, 0x04, 0x00, 0x01, 0x1C, 0xC0, 0x01, 0x78, 0xF0, 0x00, 0xE0, 0x1F, 0x00, 0x80, 0x07, 0x00, 0xE0, 0x1F, 0x00, 0x78, 0xF0, 0x00, 0x1C, 0xC0, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char X
+        0x0A, 0x04, 0x00, 0x00, 0x3C, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xFF, 0x01, 0x00, 0xFF, 0x01, 0xC0, 0x03, 0x00, 0xF8, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char Y
+        0x08, 0x00, 0x00, 0x00, 0x0C, 0xC0, 0x01, 0x0C, 0xF0, 0x01, 0x0C, 0xBE, 0x01, 0x8C, 0x8F, 0x01, 0xEC, 0x81, 0x01, 0x7C, 0x80, 0x01, 0x1C, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char Z
+        0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x1F, 0xFE, 0xFF, 0x1F, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char [
+        0x06, 0x7E, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x80, 0x7F, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char BackSlash
+        0x04, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0xFE, 0xFF, 0x1F, 0xFE, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char ]
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xE0, 0x03, 0x00, 0x7C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char ^
+        0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char _
+        0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char `
+        0x07, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0xC0, 0xFC, 0x01, 0xC0, 0x8C, 0x01, 0xC0, 0x8C, 0x01, 0xC0, 0xFF, 0x01, 0x80, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char a
+        0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x01, 0xFE, 0xFF, 0x01, 0xC0, 0x80, 0x01, 0xC0, 0x80, 0x01, 0xC0, 0xC1, 0x01, 0x80, 0xFF, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char b
+        0x07, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xFF, 0x00, 0xC0, 0xC1, 0x01, 0xC0, 0x80, 0x01, 0xC0, 0x80, 0x01, 0xC0, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char c
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xFF, 0x00, 0xC0, 0xC1, 0x01, 0xC0, 0x80, 0x01, 0xC0, 0x80, 0x01, 0xFE, 0xFF, 0x01, 0xFE, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char d
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xFF, 0x00, 0xC0, 0xCD, 0x01, 0xC0, 0x8C, 0x01, 0xC0, 0x8C, 0x01, 0x80, 0x8F, 0x01, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char e
+        0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x01, 0xFE, 0xFF, 0x01, 0xC6, 0x00, 0x00, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char f
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xFF, 0x18, 0xC0, 0xC1, 0x19, 0xC0, 0x80, 0x19, 0xC0, 0x80, 0x19, 0xC0, 0xFF, 0x0F, 0xC0, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char g
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x01, 0xFE, 0xFF, 0x01, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0x80, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char h
+        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xFF, 0x01, 0xCC, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char i
+        0x04, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0xCC, 0xFF, 0x1F, 0xCC, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char j
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x01, 0xFE, 0xFF, 0x01, 0x00, 0x1C, 0x00, 0x80, 0xFF, 0x00, 0xC0, 0xE3, 0x01, 0x40, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char k
+        0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char l
+        0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0xC0, 0xFF, 0x01, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x01, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0x80, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char m
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0xC0, 0xFF, 0x01, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char n
+        0x09, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xFF, 0x00, 0xC0, 0xC1, 0x01, 0xC0, 0x80, 0x01, 0xC0, 0x80, 0x01, 0xC0, 0xC1, 0x01, 0x80, 0xFF, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char o
+        0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x1F, 0xC0, 0xFF, 0x1F, 0xC0, 0x80, 0x01, 0xC0, 0x80, 0x01, 0xC0, 0xC1, 0x01, 0x80, 0xFF, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char p
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x80, 0xFF, 0x00, 0xC0, 0xC1, 0x01, 0xC0, 0x80, 0x01, 0xC0, 0x80, 0x01, 0xC0, 0xFF, 0x1F, 0xC0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char q
+        0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x01, 0xC0, 0xFF, 0x01, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char r
+        0x06, 0x00, 0x00, 0x00, 0x80, 0x87, 0x01, 0xC0, 0x8F, 0x01, 0xC0, 0x9C, 0x01, 0xC0, 0xF8, 0x01, 0xC0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char s
+        0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0xF8, 0xFF, 0x01, 0xC0, 0x80, 0x01, 0xC0, 0x80, 0x01, 0xC0, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char t
+        0x08, 0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0xC0, 0xFF, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0xC0, 0xFF, 0x01, 0xC0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char u
+        0x08, 0xC0, 0x01, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0xFE, 0x01, 0xC0, 0x7F, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char v
+        0x0B, 0xC0, 0x03, 0x00, 0xC0, 0xFF, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x80, 0x01, 0x00, 0xFE, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x80, 0x01, 0x00, 0xFE, 0x01, 0xC0, 0xFF, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char w
+        0x08, 0x40, 0x00, 0x01, 0xC0, 0xC1, 0x01, 0x80, 0xF7, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x3E, 0x00, 0x80, 0xF7, 0x00, 0xC0, 0xC1, 0x01, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char x
+        0x07, 0xC0, 0x01, 0x18, 0xC0, 0x3F, 0x18, 0x00, 0xFE, 0x1F, 0x00, 0xE0, 0x0F, 0x00, 0xFE, 0x03, 0xC0, 0x3F, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char y
+        0x06, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x01, 0xC0, 0xF8, 0x01, 0xC0, 0xBE, 0x01, 0xC0, 0x87, 0x01, 0xC0, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char z
+        0x06, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xFC, 0xFF, 0x0F, 0xFE, 0xF3, 0x1F, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char {
+        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x1F, 0xFE, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char |
+        0x05, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0xFE, 0xF3, 0x1F, 0xFC, 0xFF, 0x0F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char }
+        0x09, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char ~
+        0x06, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   // Code for char 
+        };
+
+
+
+static const unsigned char maxim128Bitmaps[] =
+{
+
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //              #########
+		0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //            ##############
+		0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, //          ##################                                               ##
+		0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, //        #####################                                              ##
+		0x00, 0x03, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //       ########################
+		0x00, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //      ##########################
+		0x00, 0x0F, 0xFF, 0xFF, 0xFE, 0x00, 0x2F, 0xB8, 0x7C, 0xE3, 0x32, 0x7B, 0xC0, 0x00, 0x00, 0x00, //     ###########################           # ##### ###    #####  ###   ##  ##  #  #### ####
+		0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x00, 0x3F, 0xFC, 0x7E, 0x77, 0x33, 0xFF, 0xE0, 0x00, 0x00, 0x00, //    #############################          ############   ######  ### ###  ##  #############
+		0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x80, 0x31, 0x8C, 0x02, 0x3E, 0x33, 0x1C, 0x60, 0x00, 0x00, 0x00, //    ##############################         ##   ##   ##        #   #####   ##  ##   ###   ##
+		0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x31, 0x8C, 0x1E, 0x1C, 0x33, 0x18, 0x60, 0x00, 0x00, 0x00, //   ###############################         ##   ##   ##     ####    ###    ##  ##   ##    ##
+		0x00, 0x3E, 0x01, 0xF8, 0x0F, 0xC0, 0x31, 0x8C, 0xFA, 0x1C, 0x33, 0x18, 0x60, 0x00, 0x00, 0x00, //   #####        ######       ######        ##   ##   ##  ##### #    ###    ##  ##   ##    ##
+		0x00, 0x7E, 0x00, 0xF0, 0x07, 0xE0, 0x31, 0x8C, 0xC2, 0x1E, 0x33, 0x18, 0x60, 0x00, 0x00, 0x00, //  ######         ####         ######       ##   ##   ##  ##    #    ####   ##  ##   ##    ##
+		0x00, 0x7E, 0x18, 0xE1, 0x87, 0xE0, 0x31, 0x8C, 0xC6, 0x37, 0x33, 0x18, 0x60, 0x00, 0x00, 0x00, //  ######    ##   ###    ##    ######       ##   ##   ##  ##   ##   ## ###  ##  ##   ##    ##
+		0x00, 0xFE, 0x18, 0xE3, 0x87, 0xE0, 0x31, 0x8C, 0xEE, 0x63, 0xB3, 0x18, 0x60, 0x00, 0x00, 0x00, // #######    ##   ###   ###    ######       ##   ##   ##  ### ###  ##   ### ##  ##   ##    ##
+		0x00, 0xFE, 0x1C, 0xC3, 0x87, 0xE0, 0x31, 0x8C, 0x7A, 0xE1, 0xB3, 0x18, 0x60, 0x00, 0x00, 0x00, // #######    ###  ##    ###    ######       ##   ##   ##   #### # ###    ## ##  ##   ##    ##
+		0x00, 0xFE, 0x1C, 0xC7, 0x87, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // #######    ###  ##   ####    ######
+		0x00, 0xFE, 0x1F, 0x87, 0x87, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // #######    ######    ####    ######
+		0x00, 0xFE, 0x1F, 0x8F, 0x87, 0xE0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, // #######    ######   #####    ######       ##                                                                      ##
+		0x00, 0xFE, 0x1F, 0x0F, 0x87, 0xE0, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x30, // #######    #####    #####    ######       ##            ##                                    ##                  ##
+		0x00, 0xFE, 0x1E, 0x0F, 0x87, 0xE0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x30, // #######    ####     #####    ######                     ##                                    ##                  ##
+		0x00, 0xFE, 0x1E, 0x07, 0x87, 0xE0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x30, // #######    ####      ####    ######                     ##                                    ##                  ##
+		0x00, 0xFE, 0x1E, 0x07, 0x87, 0xE0, 0x33, 0xF1, 0xF3, 0xF1, 0xFD, 0xBB, 0xE7, 0xE7, 0xC3, 0xF0, // #######    ####      ####    ######       ##  ######   #####  ######   ####### ## ### #####  ######  #####    ######
+		0x00, 0x7E, 0x1C, 0x43, 0x87, 0xE0, 0x33, 0x98, 0xC2, 0x31, 0x19, 0xE4, 0x33, 0x0C, 0x66, 0x30, //  ######    ###   #    ###    ######       ##  ###  ##   ##    #   ##   #   ##  ####  #    ##  ##    ##   ##  ##   ##
+		0x00, 0x7E, 0x18, 0x63, 0x87, 0xE0, 0x33, 0x18, 0xC6, 0x1B, 0x19, 0xC0, 0x33, 0x0C, 0x66, 0x30, //  ######    ##    ##   ###    ######       ##  ##   ##   ##   ##    ## ##   ##  ###        ##  ##    ##   ##  ##   ##
+		0x00, 0x7E, 0x18, 0xE1, 0x87, 0xC0, 0x33, 0x18, 0xC7, 0xFB, 0x19, 0x81, 0xF3, 0x1F, 0xEE, 0x30, //  ######    ##   ###    ##    #####        ##  ##   ##   ##   ######## ##   ##  ##      #####  ##   ######## ###   ##
+		0x00, 0x3E, 0x10, 0xF1, 0x87, 0xC0, 0x33, 0x18, 0xC7, 0xF1, 0xF1, 0x87, 0xB3, 0x1F, 0xCC, 0x30, //   #####    #    ####   ##    #####        ##  ##   ##   ##   #######   #####   ##    #### ##  ##   #######  ##    ##
+		0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x33, 0x18, 0xC6, 0x01, 0xE1, 0x86, 0x33, 0x0C, 0x0E, 0x30, //   ###############################         ##  ##   ##   ##   ##        ####    ##    ##   ##  ##    ##      ###   ##
+		0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x80, 0x33, 0x18, 0xC6, 0x09, 0x81, 0x84, 0x33, 0x8C, 0x26, 0x30, //    ##############################         ##  ##   ##   ##   ##     #  ##      ##    #    ##  ###   ##    #  ##   ##
+		0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x33, 0x18, 0xF3, 0xF1, 0xF9, 0x87, 0xF1, 0xEF, 0xE7, 0xF0, //     ############################          ##  ##   ##   ####  ######   ######  ##    #######   #### #######  #######
+		0x00, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0x33, 0x18, 0x71, 0xE3, 0x1D, 0x83, 0xD0, 0xE3, 0x83, 0x90, //      ##########################           ##  ##   ##    ###   ####   ##   ### ##     #### #    ###   ###     ###  #
+		0x00, 0x03, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, //       ########################                                       ##     ##
+		0x00, 0x01, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x03, 0xBC, 0x00, 0x00, 0x00, 0x00, 0x00, //        ######################                                         ### ####
+		0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, //         ####################                                           #####
+		0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //           ################
+		0x00, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //             ###########
+		0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //                 ####
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+// Bitmap sizes for maxim128
+const unsigned char maxim128WidthPages   = 16;
+const unsigned char maxim128HeightPixels = 36;
+
+#define	PIN_displayCS		P0_7
+#define	PIN_displayEXTCOM	P6_4
+#define	PIN_MODE_BUTTON		P6_5
+#define	PIN_MODE_BUTTON		P2_3
+
+//#define USE_BIGFONT
+
+
+typedef struct{
+	PwmOut *dispPWM;
+	SPI *dispPSI;
+	DigitalOut 	*dispCS;
+	silabs::LS013B7DH03 *display;
+	InterruptIn  *button;
+	uint8_t buttonMode;
+	volatile uint8_t algoMode;
+	volatile uint8_t prevAlgoMode;
+	char buffer[32];
+
+}demo_ui_t;
+
+static demo_ui_t demoUIDEV;
+
+/*need protection with mutex or update in critical section outside isr context*/
+static unsigned int dispCnt = 0;
+
+void button_isr(void){
+
+    int i;
+    volatile uint32_t isr_delay  = 0;
+    demoUIDEV.button->disable_irq();
+    //demoUIDEV.algoMode = 1- demoUIDEV.algoMode;
+    demoUIDEV.algoMode = demoUIDEV.algoMode+1;
+    if(demoUIDEV.algoMode == 3)
+    	demoUIDEV.algoMode = 0;
+
+    for(i = 10000000 ; i; i--){
+    	isr_delay++;
+    }
+    dispCnt = 0;
+    demoUIDEV.button->enable_irq();
+}
+
+
+void demoUI_init_(demo_ui_t *demoUIDEV )
+{
+
+	static PwmOut	           displayPWM(PIN_displayEXTCOM);
+	static SPI                 displaySPI(P0_5, P0_6, P0_4, NC);
+	static DigitalOut 	       displayCS(PIN_displayCS);
+	static silabs::LS013B7DH03 display(&displaySPI , &displayCS);
+    static InterruptIn         button(PIN_MODE_BUTTON);
+
+	demoUIDEV->dispCS  = &displayCS;
+	demoUIDEV->dispPWM = &displayPWM;
+	demoUIDEV->dispPSI = &displaySPI;
+	demoUIDEV->display = &display;
+
+	demoUIDEV->button = &button;
+	demoUIDEV->buttonMode = 0;
+	demoUIDEV->algoMode       = DISPLAY_WHRM;
+	demoUIDEV->prevAlgoMode   = DISPLAY_WHRM;
+
+	demoUIDEV->dispPSI->frequency(1000000);
+	demoUIDEV->dispPWM->period_ms(16);
+	demoUIDEV->dispPWM->pulsewidth_ms(8);
+	demoUIDEV->display->clearImmediate(NULL);
+#if defined(USE_BIGFONT)
+	display.set_font(UbuntuCondensed16x21);
+#endif
+	demoUIDEV->button->fall(button_isr);
+	demoUIDEV->button->disable_irq();
+	wait_ms(20);
+	demoUIDEV->button->enable_irq();
+}
+
+
+void demoUI_display_algo_estimations_(demo_ui_t *demoUIDEV , int integer , int confidence)
+{
+
+
+	//demoUIDEV->display->locate(3,10);
+	demoUIDEV->display->foreground(Black);
+	demoUIDEV->display->background(White);
+
+#if defined(USE_BIGFONT)
+	demoUIDEV->display->locate(2,6);
+
+#else
+	demoUIDEV->display->locate(2,4);
+#endif
+
+    switch( demoUIDEV->algoMode ){
+      case DISPLAY_WHRM:
+#if defined(USE_BIGFONT)
+    	    demoUIDEV->display->locate(2,22);
+			demoUIDEV->display->printf("HEART RATE");
+
+			if(integer > 10 && integer < 100)
+				 snprintf(demoUIDEV->buffer, 32, "BpS: %s%d ","  ", integer);
+			else if( integer > 100 &&  integer < 205)
+			   snprintf(demoUIDEV->buffer, 32, "BpS: %s%d "," ", integer);
+#else
+
+    	     demoUIDEV->display->printf("HEART RATE    ");
+    	     if(integer > 10 && integer < 100)
+                    snprintf(demoUIDEV->buffer, 32, "BpS: %s%d   ","  ", integer);
+      	     else if( integer > 100 &&  integer < 205)
+      	            snprintf(demoUIDEV->buffer, 32, "BpS: %s%d   "," ", integer);
+#endif
+    	     break;
+
+      case DISPLAY_WSPo2:
+#if defined(USE_BIGFONT)
+    	      demoUIDEV->display->locate(2,22);
+    	      demoUIDEV->display->printf("BLD OXYGEN");
+    	  	  if(integer >= 0 && integer < 100)
+      		         snprintf(demoUIDEV->buffer, 32, "SPo2: %s%d   ","%%", integer);
+#else
+    	     demoUIDEV->display->printf("BLOOD OXYGEN");
+    	      if( integer < 80 ){
+    	    	   dispCnt++;
+
+    	    	   unsigned int quanta =  (dispCnt >> 2) & 0x00000003;
+    	    	   if( quanta == 0)
+    	    		   snprintf(demoUIDEV->buffer, 32, "COMPUTING     ");
+                   else if( quanta == 1)
+    	    		   snprintf(demoUIDEV->buffer, 32, "COMPUTING.    ");
+    	    	   else if( quanta == 2)
+    	    		   snprintf(demoUIDEV->buffer, 32, "COMPUTING..   ");
+    	    	   else
+    	    		   snprintf(demoUIDEV->buffer, 32, "COMPUTING...  ");
+
+                   if( dispCnt > 100 &&  dispCnt < 120 )
+                	    snprintf(demoUIDEV->buffer, 32, "LOW SNR       ");
+                   else if( dispCnt > 120)
+                	    dispCnt = 0;
+     	      }
+    	      else{
+    	    	  snprintf(demoUIDEV->buffer, 32, "SPo2: %s%d    ","%%", integer);
+    	    	  dispCnt = 0;
+    	      }
+
+#endif
+              break;
+
+      case DISPLAY_ContiniousWSPo2:
+#if defined(USE_BIGFONT)
+    	      demoUIDEV->display->locate(2,22);
+    	      demoUIDEV->display->printf("BLD OXYGEN");
+    	  	  if(integer >= 0 && integer < 100)
+      		         snprintf(demoUIDEV->buffer, 32, "SPo2: %s%d   ","%%", integer);
+#else
+    	      demoUIDEV->display->printf("CONTMOD SPO2");
+    	      if( integer < -80 ){
+    	    	   dispCnt++;
+
+    	    	   unsigned int quanta =  (dispCnt >> 2) & 0x00000003;
+    	    	   if( quanta == 0)
+    	    		   snprintf(demoUIDEV->buffer, 32, "COMPUTING     ");
+                   else if( quanta == 1)
+    	    		   snprintf(demoUIDEV->buffer, 32, "COMPUTING.    ");
+    	    	   else if( quanta == 2)
+    	    		   snprintf(demoUIDEV->buffer, 32, "COMPUTING..   ");
+    	    	   else
+    	    		   snprintf(demoUIDEV->buffer, 32, "COMPUTING...  ");
+
+                   if( dispCnt > 100 &&  dispCnt < 120 )
+                	    snprintf(demoUIDEV->buffer, 32, "LOW SNR       ");
+                   else if( dispCnt > 120)
+                	    dispCnt = 0;
+     	      }
+    	      else{
+    	    	  snprintf(demoUIDEV->buffer, 32, "SPo2: %s%d    ","%%", integer);
+    	    	  dispCnt = 0;
+    	      }
+
+#endif
+
+     }
+
+#if defined(USE_BIGFONT)
+    demoUIDEV->display->locate(10,42);
+#else
+    demoUIDEV->display->locate(2,6);
+#endif
+    demoUIDEV->display->printf(demoUIDEV->buffer);
+
+    if(confidence >= 0){
+    	demoUIDEV->display->locate(2,8);
+    	snprintf(demoUIDEV->buffer, 32, "Conf: %s%d    ","%%", confidence);
+    	demoUIDEV->display->printf(demoUIDEV->buffer);
+   }else {
+	   demoUIDEV->display->locate(2,8);
+	   snprintf(demoUIDEV->buffer, 32, "              ");
+	   demoUIDEV->display->printf(demoUIDEV->buffer);
+   }
+    demoUIDEV->display->showBMP((uint8_t*)maxim128Bitmaps, 128, 40, 0, 86);
+    demoUIDEV->display->update();
+
+	/*DEBUG*///wait_ms(20);
+}
+
+void demoUI_display_set_algoMode_( demo_ui_t *demoUIDEV , int algo){
+
+	demoUIDEV->algoMode = (algo == 0)? DISPLAY_WHRM : DISPLAY_WSPo2;
+}
+int demoUI_display_get_algoMode_(demo_ui_t *demoUIDEV){
+   return (demoUIDEV->algoMode);
+}
+
+void demoUI_init(void ){
+	demoUI_init_(&demoUIDEV);
+	demoUI_display_set_algoMode_(&demoUIDEV ,DISPLAY_WHRM);
+	return;
+}
+
+void demoUI_display_algo_estimations(int integer , int confidence){
+	demoUI_display_algo_estimations_(&demoUIDEV,integer, confidence);
+	return;
+
+}
+
+
+void demoUI_display_bootldr_screen_(demo_ui_t *demoUIDEV){
+
+	demoUIDEV->display->foreground(Black);
+	demoUIDEV->display->background(White);
+	demoUIDEV->display->locate(2,4);
+	demoUIDEV->display->printf("HOST IN MODE");
+	snprintf(demoUIDEV->buffer, 32, " BOOTLOADER ");
+	demoUIDEV->display->locate(2,6);
+	demoUIDEV->display->printf(demoUIDEV->buffer);
+    demoUIDEV->display->showBMP((uint8_t*)maxim128Bitmaps, 128, 40, 0, 86);
+    demoUIDEV->display->update();
+    return;
+}
+
+
+void demoUI_display_bootldr_screen(void){
+
+	demoUI_display_bootldr_screen_(&demoUIDEV);
+	return;
+
+}
+
+void demoUI_display_set_algoMode(int algo){
+	demoUI_display_set_algoMode_(&demoUIDEV ,algo);
+	return;
+}
+
+int demoUI_display_get_mode(void){
+   return demoUI_display_get_algoMode_(&demoUIDEV);
+}
+
+void demoUI_display(int algoResult){
+     static bool is_initialized = false;
+     if( !is_initialized){
+    	 demoUI_init_(&demoUIDEV);
+    	 is_initialized = true;
+    	 return;
+     }
+     demoUI_display_algo_estimations_(&demoUIDEV,algoResult , 0);
+}
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demoUI/demoUI.h	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,45 @@
+/*
+ * demoUI.h
+ *
+ *  Created on: Nov 29, 2018
+ *      Author: Yagmur.Gok
+ */
+
+#ifndef SOURCE_DEMOUI_DEMOUI_H_
+#define SOURCE_DEMOUI_DEMOUI_H_
+
+#include <events/mbed_events.h>
+#include <mbed.h>
+
+#include "screen/LS013B7DH03.h"
+
+enum{
+	DISPLAY_WHRM            = 0,
+	DISPLAY_WSPo2           = 1,
+	DISPLAY_ContiniousWSPo2 = 2
+};
+
+#define USE_DEMO_DISPDEV
+#if defined(USE_DEMO_DISPDEV)
+
+
+	void demoUI_init();
+	void demoUI_display_algo_estimations(int integer , int confidence);
+	void demoUI_display_set_algoMode(int algo);
+	int demoUI_display_get_mode(void);
+	void demoUI_display(int algoResult);
+	void demoUI_display_bootldr_screen(void);
+
+
+#else
+	void start_demo_display(void);
+	void display_algo_estimations( uint8_t mode , int integer, int fraction);
+	void setup_mode_button(void);
+
+#endif
+
+
+extern volatile uint8_t algoMode;
+
+#endif /* SOURCE_DEMOUI_DEMOUI_H_ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demoUI/screen/BufferedDisplay.cpp	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,140 @@
+/***************************************************************************//**
+ * @file BufferedDisplay.cpp
+ * @brief Buffered version of GraphicsDisplay
+ *******************************************************************************
+ * @section License
+ * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
+ *******************************************************************************
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
+ * obligation to support this Software. Silicon Labs is providing the
+ * Software "AS IS", with no express or implied warranties of any kind,
+ * including, but not limited to, any implied warranties of merchantability
+ * or fitness for any particular purpose or warranties against infringement
+ * of any proprietary rights of a third party.
+ *
+ * Silicon Labs will not be liable for any consequential, incidental, or
+ * special damages, or any other relief, or for any claim by any third party,
+ * arising from your use of this Software.
+ *
+ ******************************************************************************/
+
+#include "../screen/BufferedDisplay.h"
+
+#define SWAP8(a) ((((a) & 0x80) >> 7) | (((a) & 0x40) >> 5) | (((a) & 0x20) >> 3) | (((a) & 0x10) >> 1) | (((a) & 0x08) << 1) | (((a) & 0x04) << 3) | (((a) & 0x02) << 5) | (((a) & 0x01) << 7))
+
+namespace silabs {
+
+	BufferedDisplay::BufferedDisplay(const char *name) : GraphicsDisplay(name) {
+		memset((uint8_t*)_pixelBuffer, White, sizeof(_pixelBuffer));	// init full frame buffer
+		memset((uint8_t*)_dirtyRows, 0xFF, sizeof(_dirtyRows)); 		// init dirty status
+	}
+
+	/**
+	 * Override of GraphicsDisplay's pixel()
+	 */
+
+	void BufferedDisplay::pixel(int x, int y, int colour) {
+	    /* Apply constraint to x and y */
+	    if(x < 0 || y < 0) return;
+	    if(x >= DISPLAY_WIDTH || y >= DISPLAY_HEIGHT) return;
+	    
+	    /***************************************************************************************************************** 
+	     * The display expects LSB input, while the SPI is configured for 8bit MSB transfers. Therefore, we should  
+	     * construct the framebuffer accordingly, so that an MSB transmission will put pixel 0 first on the wire.
+	     *
+	     * So the actual pixel layout in framebuffer (for 128x128) is as follows:
+	     * {                                                    //Framebuffer
+	     *	{                                                   //Line 0
+	     *	 {p0, p1, p2, p3, p4, p5, p6, p7},                  //Line 0 byte 0 (byte 0)
+	     *   {p8, p9,p10,p11,p12,p13,p14,p15},                  //Line 0 byte 1 (byte 1)
+	     *   ...
+	     *   {p120,p121,p122,p123,p124,p125,p126,p127}          //Line 0 byte 15 (byte 15)
+	     *  },        
+	     *  {													//Line 1
+	     *	 {p128,p129,p130,p131,p132,p133,p134,p135},         //Line 1 byte 0 (byte 16)
+	     *   ...
+	     *  },
+	     *  ...
+	     *  {													//Line 127
+	     *	 {...},              								//Line 127 byte 0 (byte 2032)
+	     *   ...
+	     *   {...}												//Line 127 byte 15 (byte 2047) = 128*128 bits
+	     *	}
+	     * }
+	     *
+	     * This means that to calculate the actual bit position in the framebuffer byte, we need to swap the bit 
+	     * order of the lower three bits. So pixel 7 becomes bit offset 0, 6 -> 1, 5 -> 2, 4->3, 3->4, 2->5, 1->6 and 0->7.
+	     *****************************************************************************************************************/
+	    uint8_t swapx = 7 - ((unsigned int)x & 0x07);
+	    x = ((unsigned int)x & 0xFFFFFFF8) | swapx;
+
+	    /* Since we are dealing with 1-bit pixels, we can avoid having to do bitshift and comparison operations twice.
+	     * Basically, do the comparison with the requested state and current state, and if it changed, do an XOR on the framebuffer pixel and set the line to dirty.
+	     */
+	    bool change = ((_pixelBuffer[((y * DISPLAY_WIDTH) + x) / DISPLAY_BUFFER_TYPE_SIZE] & (1 << (x & DISPLAY_BUFFER_TYPE_MASK))) != ((colour & 0x01) << (x & DISPLAY_BUFFER_TYPE_MASK)));
+		if(change) {
+			/* Pixel's value and requested value are different, so since it's binary, we can simply do an XOR */
+            _pixelBuffer[((y * DISPLAY_WIDTH) + x) / DISPLAY_BUFFER_TYPE_SIZE] ^= (1 << (x & DISPLAY_BUFFER_TYPE_MASK));
+
+            /* notify dirty status of this line */
+            _dirtyRows[y / DISPLAY_BUFFER_TYPE_SIZE] |= (1 << (y & DISPLAY_BUFFER_TYPE_MASK));
+		}
+	}
+
+	int BufferedDisplay::width() {
+		return DISPLAY_WIDTH;
+	}
+	int BufferedDisplay::height() {
+		return DISPLAY_HEIGHT;
+	}
+
+	/**
+	 * Function to move bitmap into frame buffer
+	 * arguments:
+	 * 	* bitmap: pointer to uint8 array containing horizontal pixel data
+	 * 	* bmpWidth: width of the bitmap in pixels (must be multiple of 8)
+	 * 	* bmpHeight: height of the bitmap in pixels
+	 * 	* startX: starting position to apply bitmap in horizontal direction (0 = leftmost) (must be multiple of 8)
+	 * 	* startY: starting position to apply bitmap in vertical direction (0 = topmost)
+	 */
+	void BufferedDisplay::showBMP(const uint8_t* bitmap, const uint32_t bmpWidth, const uint32_t bmpHeight, const uint32_t startX, const uint32_t startY) {
+		uint32_t bmpLine = 0, y = startY, bytesPerLine = ((bmpWidth >= (DISPLAY_WIDTH - startX)) ? (DISPLAY_WIDTH - startX) : bmpWidth) / 8;
+
+		/* Apply constraints */
+		if((bmpWidth & 0x07) != 0) return;
+		if((startX & 0x07) != 0) return;
+		if(startX >= DISPLAY_WIDTH) return;
+		
+		//Superflouous due to for-loop check
+		//if((startY >= DISPLAY_HEIGHT) return;
+
+		/* Copy over bytes to the framebuffer, do not write outside framebuffer boundary */
+		for(; y < DISPLAY_HEIGHT; y++) {
+			/* Check that we are not writing more than the BMP height */
+			if(bmpLine >= bmpHeight) break;
+			
+			/* Copy over one line (bmpLine) from the BMP file to the corresponding line (y) in the pixel buffer */
+			memcpy( (void*) &(((uint8_t*)_pixelBuffer)[((y * DISPLAY_WIDTH) + startX) / 8]),
+					(const void*) &(bitmap[bmpLine * (bmpWidth / 8)]),
+					bytesPerLine);
+
+			/* Set dirty status for the line we just overwrote */
+			_dirtyRows[y / DISPLAY_BUFFER_TYPE_SIZE] |= (1 << (y % DISPLAY_BUFFER_TYPE_SIZE));
+			bmpLine++;
+		}
+
+		return;
+	}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demoUI/screen/BufferedDisplay.h	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,82 @@
+/***************************************************************************//**
+ * @file BufferedDisplay.h
+ * @brief Framebuffered version of GraphicsDisplay
+ *******************************************************************************
+ * @section License
+ * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
+ *******************************************************************************
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
+ * obligation to support this Software. Silicon Labs is providing the
+ * Software "AS IS", with no express or implied warranties of any kind,
+ * including, but not limited to, any implied warranties of merchantability
+ * or fitness for any particular purpose or warranties against infringement
+ * of any proprietary rights of a third party.
+ *
+ * Silicon Labs will not be liable for any consequential, incidental, or
+ * special damages, or any other relief, or for any claim by any third party,
+ * arising from your use of this Software.
+ *
+ ******************************************************************************/
+
+#ifndef SILABS_BUFFEREDDISPLAY_H
+#define SILABS_BUFFEREDDISPLAY_H
+
+#include "../screen/GraphicsDisplay.h"
+#include "../screen/LCDSettings.h"
+
+namespace silabs {
+/** Framebuffered version of GraphicsDisplay
+ * 
+ * This has been implemented as part of the MemoryLCD library.
+ */
+class BufferedDisplay : public GraphicsDisplay {
+
+public:
+
+	BufferedDisplay(const char *name=NULL);
+
+	/**
+	 * Override of GraphicsDisplay pixel() function to set a pixel in the buffer
+     *
+     * @param x      Zero-based x-axis index of pixel to set. 0 = leftmost.
+     * @param y      Zero-based y-axis index of pixel to set. 0 = topmost.
+     * @param colour Colour value to set pixel to. In this implementation, only LSB is taken into account.
+	 */
+	virtual void pixel(int x, int y, int colour);
+	virtual int width();
+	virtual int height();
+
+	/**
+	 * Function to move bitmap into frame buffer
+	 * 
+	 * @param bitmap      pointer to uint8 array containing horizontal pixel data
+	 * @param bmpWidth    width of the bitmap in pixels (must be multiple of 8)
+	 * @param bmpHeight   height of the bitmap in pixels
+	 * @param startX      starting position to apply bitmap in horizontal direction (0 = leftmost) (must be multiple of 8)
+	 * @param startY      starting position to apply bitmap in vertical direction (0 = topmost)
+	 */
+	void showBMP(const uint8_t* bitmap, const uint32_t bmpWidth, const uint32_t bmpHeight, const uint32_t startX, const uint32_t startY);
+
+protected:
+	volatile DISPLAY_BUFFER_TYPE _pixelBuffer[DISPLAY_BUFFER_ELEMENTS]; // one full frame buffer
+	volatile DISPLAY_BUFFER_TYPE _dirtyRows[DISPLAY_HEIGHT/DISPLAY_BUFFER_TYPE_SIZE]; // 1 bit per row to indicate dirty status
+};
+
+} // namespace silabs
+
+
+
+
+#endif //SILABS_BUFFEREDDISPLAY_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demoUI/screen/GraphicsDisplay.cpp	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,457 @@
+/* mbed GraphicsDisplay Display Library Base Class
+ * Copyright (c) 2007-2009 sford
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+ 
+#include "../screen/GraphicsDisplay.h"
+
+#define incx() x++, dxt += d2xt, t += dxt
+#define incy() y--, dyt += d2yt, t += dyt
+
+const unsigned char FONT8x8[97][8] = {
+{0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, num_bytes_per_char
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space 0x20
+{0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00}, // !
+{0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, // "
+{0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00}, // #
+{0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00}, // $
+{0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00}, // %
+{0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00}, // &
+{0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00}, // '
+{0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00}, // (
+{0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00}, // )
+{0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00}, // *
+{0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00}, // +
+{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30}, // ,
+{0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00}, // -
+{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}, // .
+{0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00}, // / (forward slash)
+{0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00}, // 0 0x30
+{0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00}, // 1
+{0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00}, // 2
+{0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00}, // 3
+{0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00}, // 4
+{0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00}, // 5
+{0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00}, // 6
+{0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00}, // 7
+{0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00}, // 8
+{0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00}, // 9
+{0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00}, // :
+{0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30}, // ;
+{0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00}, // <
+{0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00}, // =
+{0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00}, // >
+{0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00}, // ?
+{0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00}, // @ 0x40
+{0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00}, // A
+{0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00}, // B
+{0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00}, // C
+{0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00}, // D
+{0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00}, // E
+{0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00}, // F
+{0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00}, // G
+{0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}, // H
+{0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // I
+{0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00}, // J
+{0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00}, // K
+{0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00}, // L
+{0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00}, // M
+{0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00}, // N
+{0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00}, // O
+{0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00}, // P 0x50
+{0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00}, // Q
+{0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00}, // R
+{0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00}, // S
+{0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00}, // T
+{0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00}, // U
+{0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00}, // V
+{0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00}, // W
+{0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00}, // X
+{0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00}, // Y
+{0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00}, // Z
+{0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00}, // [
+{0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00}, // \ (back slash)
+{0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00}, // ]
+{0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // ^
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF}, // _
+{0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00}, // ` 0x60
+{0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00}, // a
+{0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00}, // b
+{0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00}, // c
+{0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00}, // d
+{0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00}, // e
+{0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00}, // f
+{0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C}, // g
+{0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00}, // h
+{0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00}, // i
+{0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C}, // j
+{0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00}, // k
+{0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // l
+{0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00}, // m
+{0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00}, // n
+{0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00}, // o
+{0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78}, // p
+{0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F}, // q
+{0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00}, // r
+{0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00}, // s
+{0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00}, // t
+{0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00}, // u
+{0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00}, // v
+{0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00}, // w
+{0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00}, // x
+{0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C}, // y
+{0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00}, // z
+{0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00}, // {
+{0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00}, // |
+{0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00}, // }
+{0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00}, // ~
+{0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00}}; // DEL
+    
+GraphicsDisplay::GraphicsDisplay(const char *name):TextDisplay(name) {
+    foreground((uint16_t)Black);
+    background((uint16_t)White);
+    // current pixel location
+	_x = 0;
+	_y = 0;
+	// window settings
+	_x1 = 0;
+	_x2 = 0;
+	_y1 = 0;
+	_y2 = 0;
+}
+    
+void GraphicsDisplay::character(int column, int row, int value) { 
+    if(externalfont){ // send external font
+        unsigned int hor,vert,offset,bpl,j,i,b;
+        const unsigned char* sign;
+        unsigned char z,w;
+        if ((value < 31) || (value > 127)) return;   // test char range
+        // read font parameter from start of array
+        offset = font[0];                    // bytes / char
+        hor = font[1];                       // get hor size of font
+        vert = font[2];                      // get vert size of font
+        bpl = font[3];                       // bytes per line
+        if (char_x + hor > width()) {
+            char_x = 0;
+            char_y = char_y + vert;
+            if (char_y >= height() - font[2]) {
+                char_y = 0;
+            }
+        }     
+        window(char_x, char_y,hor,vert); // char box
+        sign = &font[((value -32) * offset) + 4]; // start of char bitmap
+        w = sign[0];                          // width of actual char
+        for (j=0; j<vert; j++) {  //  vert line
+            for (i=0; i<hor; i++) {   //  horz line
+                z =  sign[bpl * i + ((j & 0xF8) >> 3)+1];
+                b = 1 << (j & 0x07);
+                if (( z & b ) == 0x00) {               
+                    putp(_foreground);              
+                } 
+                else {                     
+                    putp(_background);                                
+                }
+            }
+        }
+        if ((w + 2) < hor) {                   // x offset to next char
+            char_x += w + 2;
+            }
+            else char_x += hor;
+    }   
+    // send default font            
+    else {
+        blitbit(column * 8, row * 8, 8, 8, (char*)&(FONT8x8[value - 0x1F][0]));
+    }
+}
+
+void GraphicsDisplay::window(int x, int y, int w, int h) {
+    // current pixel location
+    _x = x;
+    _y = y;
+    // window settings
+    _x1 = x;
+    _x2 = x + w - 1;
+    _y1 = y;
+    _y2 = y + h - 1;
+}
+    
+void GraphicsDisplay::putp(int colour) {
+    // put pixel at current pixel location
+    pixel(_x, _y, colour);
+    // update pixel location based on window settings
+    _x++;
+    if(_x > _x2) {
+        _x = _x1;
+        _y++;
+        if(_y > _y2) {
+            _y = _y1;
+        }
+    }
+}
+
+void GraphicsDisplay::rect(int x0, int y0, int x1, int y1, int color) {
+    if (x1 > x0) hline(x0,x1,y0,color);
+    else  hline(x1,x0,y0,color);
+    if (y1 > y0) vline(x0,y0,y1,color);
+    else vline(x0,y1,y0,color);
+    if (x1 > x0) hline(x0,x1,y1,color);
+    else  hline(x1,x0,y1,color);
+    if (y1 > y0) vline(x1,y0,y1,color);
+    else vline(x1,y1,y0,color);
+    return;
+}
+ 
+void GraphicsDisplay::fillrect(int x0, int y0, int w, int h, int colour) {
+    unsigned long int index=0;
+    if (w < 0) {
+        x0 = x0 + w;
+        w = -w;
+    }
+    if (h < 0) {
+        y0 = y0 + h;
+        h = -h;
+    }
+    window(x0,y0,w,h);
+    int num = h*w;
+    for( index = 0; index<num; index++ ) {
+       putp(colour); 
+    }
+    return;
+}
+
+void GraphicsDisplay::fill(int x, int y, int w, int h, int colour) { 
+    fillrect(x, y, w, h, colour);
+}
+
+void GraphicsDisplay::circle(int x, int y, int r,int colour){
+	int ce = -r;
+	int cx = r;
+	int cy = 0;
+	while(cx >= cy){
+		pixel(x+cx,y+cy,colour);
+		pixel(x-cx,y-cy,colour);
+		pixel(x-cx,y+cy,colour);
+		pixel(x+cx,y-cy,colour);
+		pixel(x+cy,y+cx,colour);
+		pixel(x-cy,y+cx,colour);
+		pixel(x-cy,y-cx,colour);
+		pixel(x+cy,y-cx,colour);
+		ce += 2*cy++ + 1;
+		if(ce >= 0){
+			ce -= 2*cx---1;	
+		}
+		
+	}
+
+}
+
+// To draw circle set a and b to the same values
+void GraphicsDisplay::ellipse(int xc, int yc, int a, int b, unsigned int colour)
+{
+    /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */
+    int x = 0, y = b;
+    long a2 = (long)a*a, b2 = (long)b*b;
+    long crit1 = -(a2/4 + a%2 + b2);
+    long crit2 = -(b2/4 + b%2 + a2);
+    long crit3 = -(b2/4 + b%2);
+    long t = -a2*y;                         // e(x+1/2,y-1/2) - (a^2+b^2)/4
+    long dxt = 2*b2*x, dyt = -2*a2*y;
+    long d2xt = 2*b2, d2yt = 2*a2;
+ 
+    while (y>=0 && x<=a) {
+        pixel(xc+x, yc+y, colour);
+        if (x!=0 || y!=0)
+            pixel(xc-x, yc-y, colour);
+        if (x!=0 && y!=0) {
+            pixel(xc+x, yc-y, colour);
+            pixel(xc-x, yc+y, colour);
+        }
+        if (t + b2*x <= crit1 ||            // e(x+1,y-1/2) <= 0
+                t + a2*y <= crit3)          // e(x+1/2,y) <= 0
+            incx();
+        else if (t - a2*y > crit2)          // e(x+1/2,y-1) > 0
+            incy();
+        else {
+            incx();
+            incy();
+        }
+    }
+}
+// To draw circle set a and b to the same values
+void GraphicsDisplay::fillellipse(int xc, int yc, int a, int b, unsigned int colour)
+{
+    /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */
+    int x = 0, y = b;
+    int rx = x, ry = y;
+    unsigned int width = 1;
+    unsigned int height = 1;
+    long a2 = (long)a*a, b2 = (long)b*b;
+    long crit1 = -(a2/4 + a%2 + b2);
+    long crit2 = -(b2/4 + b%2 + a2);
+    long crit3 = -(b2/4 + b%2);
+    long t = -a2*y;                         // e(x+1/2,y-1/2) - (a^2+b^2)/4
+    long dxt = 2*b2*x, dyt = -2*a2*y;
+    long d2xt = 2*b2, d2yt = 2*a2;
+    if (b == 0) {
+        fillrect(xc-a, yc, 2*a+1, 1, colour);
+        return;
+    }
+    while (y>=0 && x<=a) {
+        if (t + b2*x <= crit1 ||            // e(x+1,y-1/2) <= 0
+                t + a2*y <= crit3) {        // e(x+1/2,y) <= 0
+            if (height == 1)
+                ;                           // draw nothing
+            else if (ry*2+1 > (height-1)*2) {
+                fillrect(xc-rx, yc-ry, width, height-1, colour);
+                fillrect(xc-rx, yc+ry+1, width, 1-height, colour);
+                ry -= height-1;
+                height = 1;
+            } else {
+                fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
+                ry -= ry;
+                height = 1;
+            }
+            incx();
+            rx++;
+            width += 2;
+        } else if (t - a2*y > crit2) {      // e(x+1/2,y-1) > 0
+            incy();
+            height++;
+        } else {
+            if (ry*2+1 > height*2) {
+                fillrect(xc-rx, yc-ry, width, height, colour);
+                fillrect(xc-rx, yc+ry+1, width, -height, colour);
+            } else {
+                fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
+            }
+            incx();
+            incy();
+            rx++;
+            width += 2;
+            ry -= height;
+            height = 1;
+        }
+    }
+    if (ry > height) {
+        fillrect(xc-rx, yc-ry, width, height, colour);
+        fillrect(xc-rx, yc+ry+1, width, -height, colour);
+    } else {
+        fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
+    }
+}
+ 
+ 
+void GraphicsDisplay::line(int x0, int y0, int x1, int y1, int colour) {
+    //window(x0, y, w, h);
+    int   dx = 0, dy = 0;
+    int   dx_sym = 0, dy_sym = 0;
+    int   dx_x2 = 0, dy_x2 = 0;
+    int   di = 0;
+    dx = x1-x0;
+    dy = y1-y0;
+ 
+    if (dx == 0) {        /* vertical line */
+        if (y1 > y0) vline(x0,y0,y1,colour);
+        else vline(x0,y1,y0,colour);
+        return;
+    }
+    if (dx > 0) {
+        dx_sym = 1;
+    } else {
+        dx_sym = -1;
+    }
+    if (dy == 0) {        /* horizontal line */
+        if (x1 > x0) hline(x0,x1,y0,colour);
+        else  hline(x1,x0,y0,colour);
+        return;
+    }
+    if (dy > 0) {
+        dy_sym = 1;
+    } else {
+        dy_sym = -1;
+    }
+    dx = dx_sym*dx;
+    dy = dy_sym*dy;
+    dx_x2 = dx*2;
+    dy_x2 = dy*2;
+    if (dx >= dy) {
+        di = dy_x2 - dx;
+        while (x0 != x1) {
+ 
+            pixel(x0, y0, colour);
+            x0 += dx_sym;
+            if (di<0) {
+                di += dy_x2;
+            } else {
+                di += dy_x2 - dx_x2;
+                y0 += dy_sym;
+            }
+        }
+        pixel(x0, y0, colour);
+    } else {
+        di = dx_x2 - dy;
+        while (y0 != y1) {
+            pixel(x0, y0, colour);
+            y0 += dy_sym;
+            if (di < 0) {
+                di += dx_x2;
+            } else {
+                di += dx_x2 - dy_x2;
+                x0 += dx_sym;
+            }
+        }
+        pixel(x0, y0, colour);
+    }
+    return;
+}
+ 
+void GraphicsDisplay::hline(int x0, int x1, int y, int colour) {
+    int w;
+    w = x1 - x0 + 1;
+    window(x0,y,w,1);
+    for (int x=0; x<w; x++) {
+        putp(colour);
+    }
+    return;
+}
+ 
+void GraphicsDisplay::vline(int x, int y0, int y1, int colour) {
+    int h;
+    h = y1 - y0 + 1;
+    window(x,y0,1,h);
+    for (int y=0; y<h; y++) {
+        putp(colour);
+    }
+    return;
+}
+
+void GraphicsDisplay::cls() {
+    fill(0, 0, width(), height(), _background);
+}
+    
+void GraphicsDisplay::blit(int x, int y, int w, int h, const int *colour) { 
+    window(x, y, w, h);
+    for(int i=0; i<w*h; i++) {
+        putp(colour[i]);
+    }
+}
+    
+void GraphicsDisplay::blitbit(int x, int y, int w, int h, const char* colour) {
+    window(x, y, w, h);
+    for(int i = 0; i < w*h; i++) {
+        char byte = colour[i >> 3];
+        int offset = i & 0x7;
+        int c = ((byte << (offset)) & 0x80) ? _foreground : _background;
+        putp(c);
+    }
+}
+    
+int GraphicsDisplay::columns() { 
+    return width() / 8; 
+}
+
+int GraphicsDisplay::rows() { 
+    return height() / 8; 
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demoUI/screen/GraphicsDisplay.h	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,69 @@
+/* mbed GraphicsDisplay Display Library Base Class
+ * Copyright (c) 2007-2009 sford
+ * Released under the MIT License: http://mbed.org/license/mit
+ *
+ * A library for providing a common base class for Graphics displays
+ * To port a new display, derive from this class and implement
+ * the constructor (setup the display), pixel (put a pixel
+ * at a location), width and height functions. Everything else
+ * (locate, printf, putc, cls, window, putp, fill, blit, blitbit) 
+ * will come for free. You can also provide a specialised implementation
+ * of window and putp to speed up the results
+ */
+
+#ifndef MBED_GRAPHICSDISPLAY_H
+#define MBED_GRAPHICSDISPLAY_H
+
+#include "../screen/TextDisplay.h"
+
+class GraphicsDisplay : public TextDisplay {
+
+public:         
+          
+    GraphicsDisplay(const char* name);
+     
+    virtual void pixel(int x, int y, int colour) = 0;
+    virtual int width() = 0;
+    virtual int height() = 0;
+        
+    virtual void window(int x, int y, int w, int h);
+    virtual void putp(int colour);
+    
+    virtual void cls();
+    virtual void rect(int x0, int y0, int x1, int y1, int colour);
+    virtual void fillrect(int x0, int y0, int w, int h, int colour);
+    // fill equals fillrect, name has been kept to not break compatibility
+    virtual void fill(int x, int y, int w, int h, int colour);
+    
+    // To draw circle using ellipse, set a and b to the same values
+    virtual void ellipse(int xc, int yc, int a, int b, unsigned int colour);
+    virtual void fillellipse(int xc, int yc, int a, int b, unsigned int colour);
+    virtual void circle(int x, int y, int r, int colour);
+    
+    virtual void hline(int x0, int x1, int y, int colour);
+    virtual void vline(int x0, int y0, int y1, int colour);
+    virtual void line(int x0, int y0, int x1, int y1, int colour);
+    
+    virtual void blit(int x, int y, int w, int h, const int *colour);    
+    virtual void blitbit(int x, int y, int w, int h, const char* colour);
+    
+    virtual void character(int column, int row, int value);
+    virtual int columns();
+    virtual int rows();
+    
+protected:
+
+    // pixel location
+    short _x;
+    short _y;
+    
+    // window location
+    short _x1;
+    short _x2;
+    short _y1;
+    short _y2;
+
+};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demoUI/screen/LCDSettings.h	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,30 @@
+#ifndef LCDSETTINGS_H
+#define LCDSETTINGS_H
+
+/** MemoryLCD width in pixels */ 
+#define DISPLAY_WIDTH				(128)
+
+/** MemoryLCD height in pixels */
+#define DISPLAY_HEIGHT				(128)
+
+/** Data type for storing buffer the pixel buffer */
+#if	((DISPLAY_WIDTH % 32) == 0)
+#define	DISPLAY_BUFFER_TYPE			uint32_t
+#define DISPLAY_BUFFER_TYPE_MASK    (0x1F)
+#else
+#define DISPLAY_BUFFER_TYPE			uint8_t
+#define DISPLAY_BUFFER_TYPE_MASK    (0x07)
+#endif
+
+#define DISPLAY_BUFFER_TYPE_SIZE	(sizeof(DISPLAY_BUFFER_TYPE) * 8)
+#define DISPLAY_BUFFER_ELEMENTS 	((DISPLAY_WIDTH*DISPLAY_HEIGHT)/DISPLAY_BUFFER_TYPE_SIZE)
+
+/** Maximum length of a printf to the display */
+#define MAX_PRINTF_CHARS			40
+
+/** Color definitions */
+#define White						0xFFFFFFFF
+#define Black						0x00000000
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demoUI/screen/LS013B7DH03.cpp	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,246 @@
+/***************************************************************************//**
+ * @file LS013B7DH03.cpp
+ * @brief Driver class for the Sharp LS013B7DH03 memory LCD on some kits.
+ *******************************************************************************
+ * @section License
+ * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
+ *******************************************************************************
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
+ * obligation to support this Software. Silicon Labs is providing the
+ * Software "AS IS", with no express or implied warranties of any kind,
+ * including, but not limited to, any implied warranties of merchantability
+ * or fitness for any particular purpose or warranties against infringement
+ * of any proprietary rights of a third party.
+ *
+ * Silicon Labs will not be liable for any consequential, incidental, or
+ * special damages, or any other relief, or for any claim by any third party,
+ * arising from your use of this Software.
+ *
+ ******************************************************************************/
+
+#include "../screen/LS013B7DH03.h"
+
+#include <mbed.h>
+#include "SPI.h"
+//#include "Peripherals.h"
+
+/* LS013B7DH03 SPI commands */
+#define LS013B7DH03_CMD_UPDATE     (0x01)
+#define LS013B7DH03_CMD_ALL_CLEAR  (0x04)
+
+/* Macro to switch endianness on char value */
+#define SWAP8(a) ((((a) & 0x80) >> 7) | (((a) & 0x40) >> 5) | (((a) & 0x20) >> 3) | (((a) & 0x10) >> 1) | (((a) & 0x08) << 1) | (((a) & 0x04) << 3) | (((a) & 0x02) << 5) | (((a) & 0x01) << 7))
+
+namespace silabs {
+
+
+LS013B7DH03::LS013B7DH03(mbed::SPI * spi, DigitalOut * CS, const char *name) : BufferedDisplay( name )  {
+	//Save pointer to ChipSelect pin
+	_CS = CS;
+	_CS->write(0);
+	DigitalOut DISP(P6_6);
+
+//Save pointer to ExtCom pin
+///	_EXTCOM = ExtCom;
+///	_EXTCOM->write(0);
+
+	DISP  = 0;
+	wait_ms(1);
+	DISP = 1;
+
+	//Save pointer to spi peripheral
+	_spi = spi;
+	//_spi->frequency(600000);
+	_spi->format( 8, 0 );
+
+	_internalEventCallback.attach(this, &LS013B7DH03::_cbHandler);
+
+	//Initialize
+	//_spi->set_dma_usage((DMAUsage)DMA_USAGE_NEVER);
+	_refreshCount = 0;
+	_lcdPolarity = 0;
+	_state = IDLE;
+	_completionCallbackPtr = NULL;
+	_rowCount = 0;
+
+	//Start toggling the EXTCOM pin
+	//_displayToggler.attach(this, &LS013B7DH03::toggle, 0.008f);
+}
+
+/**
+ * Call this function at 55 ~ 65 Hz to keep the display up-to-date.
+ */
+void LS013B7DH03::toggle() {
+//	_EXTCOM->write(!_EXTCOM->read());
+//	_refreshCount++;
+}
+
+/**
+ * Function to get internal refresh counter
+ */
+uint32_t LS013B7DH03::getRefreshTicks() {
+	return _refreshCount;
+}
+
+/**
+ * Call this function to push all changes to the display
+ */
+int LS013B7DH03::update( cbptr_t callback ) {
+	uint32_t rowCount = 0;
+	bool update = false;
+
+	// Check if something actually changed in the pixelbuffer
+	for(rowCount = 0; rowCount < DISPLAY_HEIGHT/DISPLAY_BUFFER_TYPE_SIZE; rowCount++) {
+		if(_dirtyRows[rowCount] != 0) update = true;
+	}
+
+	if(update == false) return LS013B7DH03_NO_ACTION;
+
+	// Watch out to not mess up a transfer
+	if(_state != IDLE) return LS013B7DH03_ERROR_BUSY;
+
+	_completionCallbackPtr = callback;
+
+	// Take control
+	_state = WAIT_WRITE;
+	_rowCount = 0;
+
+	//Initialize the command vector
+	_cmd[0] = (uint8_t)SWAP8(LS013B7DH03_CMD_UPDATE);
+	_cmd[1] = SWAP8(1);
+
+	// Activate LCD
+	_CS->write(1);
+	_csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);
+
+	return LS013B7DH03_OK;
+}
+
+/**
+ * Function to test display buffer
+ */
+int LS013B7DH03::showDemo() {
+	for(uint32_t i = 0; i < DISPLAY_BUFFER_ELEMENTS; i+=2) {
+		_pixelBuffer[i] = 0x00555345;
+	}
+	memset((void*)_dirtyRows, 0x33, sizeof(_dirtyRows));
+
+	return LS013B7DH03_OK;
+}
+
+/**
+ * Call this function to immediately clear the display
+ */
+int LS013B7DH03::clearImmediate( cbptr_t callback ) {
+	// Watch out to not mess up a transfer
+	if(_state != IDLE) return LS013B7DH03_ERROR_BUSY;
+
+	_state = WAIT_CLEAR;
+	_completionCallbackPtr = callback;
+
+	// Clear out the pixel buffer
+	memset((void*)_pixelBuffer, White, sizeof(_pixelBuffer));
+	memset((void*)_dirtyRows, 0, sizeof(_dirtyRows));
+
+	_cmd[0] = (uint8_t)(SWAP8(LS013B7DH03_CMD_ALL_CLEAR | _lcdPolarity));
+	_cmd[1] = 0;
+
+	// Wait for the ChipSelect line
+	_CS->write(1);
+	_csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);
+
+	return LS013B7DH03_OK;
+}
+
+void LS013B7DH03::_cbHandlerTimeout( void ) {
+	this->_cbHandler(0);
+}
+
+void LS013B7DH03::_cbHandler( int event ) {
+	if((_state == WAIT_WRITE) || (_state == WRITING))
+	{
+		_state = WRITING;
+		while(_rowCount < DISPLAY_HEIGHT) {
+			// Determine the next line to send
+			if((_dirtyRows[_rowCount / DISPLAY_BUFFER_TYPE_SIZE] & (1 << (_rowCount % DISPLAY_BUFFER_TYPE_SIZE))) != 0) {
+
+				// Row is dirty, send an update to the display
+				_cmd[1] = (uint8_t)SWAP8(_rowCount + 1);
+				memcpy((void*)&(_cmd[2]), (const void*)&(_pixelBuffer[_rowCount*(DISPLAY_WIDTH/DISPLAY_BUFFER_TYPE_SIZE)]), DISPLAY_WIDTH / DISPLAY_BUFFER_TYPE_SIZE * sizeof(DISPLAY_BUFFER_TYPE));
+
+				if(_spi->write((const char*)_cmd, (2 + (DISPLAY_WIDTH / DISPLAY_BUFFER_TYPE_SIZE * sizeof(DISPLAY_BUFFER_TYPE))) , (char*)NULL, 0/*, _internalEventCallback, SPI_EVENT_COMPLETE*/) != (2 + (DISPLAY_WIDTH / DISPLAY_BUFFER_TYPE_SIZE * sizeof(DISPLAY_BUFFER_TYPE)))) {
+					// SPI is busy, with another transaction. This means the data to the LCD has been corrupted, so fail here.
+					_state = DONE;
+					//printf("Failed at _cbHandler\n");
+					// Make sure the handler is called again
+					_csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.1f);
+				}else{	//sc...
+					_csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.001f);
+				}
+
+				// Transaction is in progress, so update row state
+				_dirtyRows[_rowCount / DISPLAY_BUFFER_TYPE_SIZE] &= ~(1 << (_rowCount % DISPLAY_BUFFER_TYPE_SIZE));
+				_rowCount++;
+				return;
+			}
+
+			// Row wasn't touched, so check the next row
+			_rowCount++;
+		}
+
+		// Done sending!
+		_cmd[1] = 0xFF;
+		_state = TRANSFERS_DONE;
+		if(_spi->write((const char*)_cmd, 2, (char*)NULL, 0/*, _internalEventCallback, SPI_EVENT_COMPLETE*/) != 2) {
+			// SPI is busy, with another transaction. This means the data to the LCD has been corrupted, so fail here.
+			_state = DONE;
+
+			// Make sure the handler is called again
+			_csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.1f);
+		}else{	//sc...
+			_csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.001f);
+		}
+		return;
+	}
+	else if (_state == WAIT_CLEAR)
+	{
+		_state = TRANSFERS_DONE;
+		if(_spi->write((const char*)_cmd, 2, (char*)NULL, 0/*, _internalEventCallback, SPI_EVENT_COMPLETE*/) != 2) {
+			// SPI is busy, with another transaction. This means the data to the LCD has been corrupted, so fail here.
+			_state = DONE;
+
+			// Make sure the handler is called again
+			_csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.1f);
+		}else{	//sc...
+			_csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.001f);
+		}
+		return;
+	}
+	else if (_state == TRANSFERS_DONE)
+	{
+		_state = DONE;
+		_csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);
+		return;
+	}
+	else if (_state == DONE)
+	{
+		_CS->write(0);
+		_state = IDLE;
+		if(_completionCallbackPtr != 0) _completionCallbackPtr();
+		return;
+	}
+}
+
+} // namespace silabs
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demoUI/screen/LS013B7DH03.h	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,124 @@
+/***************************************************************************//**
+ * @file LS013B7DH03.h
+ * @brief Driver class for the Sharp LS013B7DH03 memory LCD on some kits.
+ *******************************************************************************
+ * @section License
+ * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
+ *******************************************************************************
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
+ * obligation to support this Software. Silicon Labs is providing the
+ * Software "AS IS", with no express or implied warranties of any kind,
+ * including, but not limited to, any implied warranties of merchantability
+ * or fitness for any particular purpose or warranties against infringement
+ * of any proprietary rights of a third party.
+ *
+ * Silicon Labs will not be liable for any consequential, incidental, or
+ * special damages, or any other relief, or for any claim by any third party,
+ * arising from your use of this Software.
+ *
+ ******************************************************************************/
+
+#ifndef SILABS_LS013B7DH03_H
+#define SILABS_LS013B7DH03_H
+
+#include "platform.h"
+#include <mbed.h>
+#include "../screen/BufferedDisplay.h"
+#include "../screen/LCDSettings.h"
+//#include "Peripherals.h"
+
+typedef void (*cbptr_t)(void);
+
+#define LS013B7DH03_ERROR_BUSY		-1
+#define LS013B7DH03_ERROR_SPI_BUSY	-2
+#define LS013B7DH03_NO_ACTION		-3
+#define LS013B7DH03_ERROR_ARGUMENT	-4
+#define	LS013B7DH03_OK				0
+
+typedef enum {
+	IDLE,			// No operation currently ongoing
+	CLEARING,		// In the process of clearing the display
+	WRITING,		// In the process of sending a display update
+	WAIT_CLEAR,		// Going to clear after CS pin timeout
+	WAIT_WRITE,		// Going to write after CS pin timeout
+	TRANSFERS_DONE, // Last transfer in progress
+	DONE			// Done with transmission, waiting for CS pin to become high
+} LS013B7DH03_state_t;
+
+namespace silabs {
+class LS013B7DH03 : public BufferedDisplay {
+
+public:
+
+	LS013B7DH03(SPI * spi, DigitalOut * CS,  const char *name=NULL);
+
+	/**
+	 * Call this function to push all changes to the display
+	 */
+	int update( cbptr_t callback = NULL );
+
+	/**
+	 * Immediately clear the display: set pixel buffer to zero and clear out the display.
+	 */
+	int clearImmediate( cbptr_t callback = NULL );
+
+	/**
+	 * Function to test display buffer
+	 */
+	int showDemo();
+
+
+
+	/**
+	 * Function to get internal refresh counter
+	 */
+	uint32_t getRefreshTicks();
+
+
+protected:
+	mbed::SPI *_spi;
+	//mbed::DigitalOut *_EXTCOM;
+	mbed::DigitalOut *_CS;
+
+	mbed::Ticker _displayToggler;
+	mbed::Timeout _csTimeout;
+
+	event_callback_t _internalEventCallback;
+	volatile uint32_t _refreshCount;
+	uint8_t _lcdPolarity;
+	LS013B7DH03_state_t _state;
+	cbptr_t _completionCallbackPtr;
+	volatile uint32_t _rowCount;
+	uint8_t _cmd[2 + (DISPLAY_WIDTH / DISPLAY_BUFFER_TYPE_SIZE * sizeof(DISPLAY_BUFFER_TYPE))];
+
+	/**
+	 * Callback handler for internal SPI transfers.
+	 */
+	void _cbHandler( int event );
+
+	/**
+	 * Callback handler for internal SPI transfers triggered by timeout.
+	 */
+	void _cbHandlerTimeout( void );
+
+	/**
+	 * Call this function at 55 ~ 65 Hz to keep the display from losing contrast.
+	 */
+	void toggle();
+};
+
+} // namespace silabs
+
+#endif //SILABS_LS013B7DH03_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demoUI/screen/TextDisplay.cpp	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,94 @@
+/* mbed TextDisplay Display Library Base Class
+ * Copyright (c) 2007-2009 sford
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+ 
+#include "../screen/TextDisplay.h"
+
+#include <cstdarg>
+
+TextDisplay::TextDisplay(const char *name){
+    _row = 0;
+    _column = 0;
+
+    if (name == NULL) {
+        _path = NULL;
+    } else {
+        _path = new char[strlen(name) + 2];
+        sprintf(_path, "/%s", name);
+    }
+}
+    
+int TextDisplay::_putc(int value) {
+    if(value == '\n') {
+        _column = 0;
+        _row++;
+        if(_row >= rows()) {
+            _row = 0;
+        }
+    } else {
+        character(_column, _row, value);
+        _column++;
+        if(_column >= columns()) {
+            _column = 0;
+            _row++;
+            if(_row >= rows()) {
+                _row = 0;
+            }
+        }
+    }
+    return value;
+}
+
+// crude cls implementation, should generally be overwritten in derived class
+void TextDisplay::cls() {
+    locate(0, 0);
+    for(int i=0; i<columns()*rows(); i++) {
+        _putc(' ');
+    }
+}
+
+void TextDisplay::set_font(const unsigned char * f) {
+    font = f;
+    if(font==NULL) {
+    	externalfont = 0;  // set display.font
+    	locate(0, 0);
+    }    
+    else{
+    	externalfont = 1;
+    	locate(0, 0);
+    }
+}
+
+void TextDisplay::locate(int column, int row) {
+    _column = column;
+    _row = row;
+    char_x = column;
+    char_y = row;
+}
+
+int TextDisplay::_getc() {
+    return -1;
+}
+        
+void TextDisplay::foreground(uint16_t colour) {
+    _foreground = colour;
+}
+
+void TextDisplay::background(uint16_t colour) {
+    _background = colour;
+}
+
+void TextDisplay::printf(const char* format, ...) {
+	char buffer[MAX_PRINTF_CHARS + 1] = { 0 };
+	uint32_t iterator = 0;
+	va_list args;
+	va_start(args, format);
+	vsprintf(buffer, format, args);
+	va_end(args);
+
+	while((buffer[iterator] != 0) && (iterator < MAX_PRINTF_CHARS)) {
+		_putc(buffer[iterator++]);
+	}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demoUI/screen/TextDisplay.h	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,93 @@
+/* mbed TextDisplay Library Base Class
+ * Copyright (c) 2007-2009 sford
+ * Released under the MIT License: http://mbed.org/license/mit
+ *
+ * A common base class for Text displays
+ * To port a new display, derive from this class and implement
+ * the constructor (setup the display), character (put a character
+ * at a location), rows and columns (number of rows/cols) functions.
+ * Everything else (locate, printf, putc, cls) will come for free
+ *
+ * The model is the display will wrap at the right and bottom, so you can
+ * keep writing and will always get valid characters. The location is 
+ * maintained internally to the class to make this easy
+ */
+
+#ifndef MBED_TEXTDISPLAY_H
+#define MBED_TEXTDISPLAY_H
+
+#include "../screen/LCDSettings.h"
+#include "mbed.h"
+
+class TextDisplay {
+public:
+
+  // functions needing implementation in derived implementation class
+  /** Create a TextDisplay interface
+     *
+     * @param name The name used in the path to access the strean through the filesystem
+     */
+    TextDisplay(const char *name = NULL);
+
+    /** output a character at the given position
+     *
+     * @param column column where charater must be written
+     * @param  row where character must be written
+     * @param c the character to be written to the TextDisplay
+     */
+    virtual void character(int column, int row, int c) = 0;
+
+    /** return number if rows on TextDisplay
+     * @result number of rows
+     */
+    virtual int rows() = 0;
+
+    /** return number if columns on TextDisplay
+    * @result number of rows
+    */
+    virtual int columns() = 0;
+    
+    // Sets external font usage, eg. dispaly.set_font(Arial12x12);
+    // This uses pixel positioning.
+    // display.set_font(NULL); returns to internal default font.
+    void set_font(const unsigned char * f);
+    
+    // set position of the next character or string print.
+    // External font, set pixel x(column),y(row) position.
+    // internal(default) font, set character column and row position 
+    virtual void locate(int column, int row);
+    
+    // functions that come for free, but can be overwritten
+
+    /** clear screen
+    */
+    virtual void cls();
+    virtual void foreground(uint16_t colour);
+    virtual void background(uint16_t colour);
+    // putc (from Stream)
+    // printf (from Stream)
+    virtual void printf(const char* format, ...);
+    
+protected:
+
+    virtual int _putc(int value);
+    virtual int _getc();
+    
+    // external font functions
+    const unsigned char* font;
+    int externalfont;
+ 
+    // character location
+    uint16_t _column;
+    uint16_t _row;
+    unsigned int char_x;
+    unsigned int char_y;
+
+    // colours
+    uint16_t _foreground;
+    uint16_t _background;
+    char *_path;
+};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+ * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Maxim Integrated
+ * Products, Inc. shall not be used except as stated in the Maxim Integrated
+ * Products, Inc. Branding Policy.
+ *
+ * The mere transfer of this software does not imply any licenses
+ * of trade secrets, proprietary technology, copyrights, patents,
+ * trademarks, maskwork rights, or any other form of intellectual
+ * property whatsoever. Maxim Integrated Products, Inc. retains all
+ * ownership rights.
+ *******************************************************************************
+ */
+
+
+/**********************************************************************************
+ *
+ *  Desc: Example Code to get algorithm estimation results of Heart rate( HRM) and Blood
+ *        Oxygen (SPo2) form sensor hub and display it on screen. Example starts by monitoring heart rate
+ *        ans switches to blood oxygen monitoring via a button press (switch button)
+ *
+ *        Example,
+ *
+ *        1. Initializes user interface
+ *                   initialize display screen and switch button for algo selection.
+ *
+ *        2. Initializes underlying hardware port for sensor hub communication:
+ *                   setup i2c comm. inits reset pin and mfio event pin and connects interrupt to mfio pin.
+ *
+ *        3. When switched to a minitoring mode
+ *                   disables previous algorithm, clears mfio event
+ *                   calls default init function for the sensor whose data is used by enabled algorithms. Algorithms are
+ *                   registered under sesnor instance for this example. Fcunction
+ *                   	        1. initialize algorithm config struct enabled
+ *                              2. enable data type to both raw sensor and algorithm data
+ *                              3. get input fifo size to learn fifo capacity
+ *                              4. set fifo threshold for mfio event frequency
+ *                              5. reaenable sensor to acquire ppg data
+ *                              6. enable accompanying accel sensor
+ *                              7. enable switched algorithm
+ *
+ *     4. Sensor Hub now starts to write raw sensor/algorithm data to its data report FIFO which
+ *        reports mfio event when data size determined by fifo threshold is written to report fifo.
+ *
+ *     5. Example calls SH_Max8614x_data_report_execute() which
+ *                 1. calls SH API's sh_ss_execute_once() function which:
+ *                            writes sensor hub's report fifo content (sensor/algorithm data samples) to a buffer(1).
+ *                 2. calls CSTMR_SH_FeedAccDataIntoSH() to send accelerometer data to sensor hub which os required for heart rate
+ *                    Note: SPo2 requires stablity so do not move/shake senor when taking SPo2 data.
+ *                 3. Parses buffer(1) data to extract numeric sensor and algorithm samples according to enabled algorithms.
+ *                    look: whrm_data_rx() , wspo2_data_rx() , max8614x_data_rx() and sample structs whrm_mode1_data, wspo2_mode1_data and max8614x_mode1_data
+ *
+ *     6. numeric values  are written to HrmResult, SPO2Result ... within MAX8614x  whrm_data_rx() ... and included as extern in main.cpp
+ *
+ *     7. Example calls demoUI_display_algo_estimations() to display result on watch screen
+ *
+ *
+ ***********************************************************************************/
+
+#include <events/mbed_events.h>
+#include <mbed.h>
+#include "max32630hsp.h"
+#include "SHComm.h"
+#include "SH_Max8614x_BareMetal.h"
+#include "bmi160.h"
+#include "cmdInterface.h"
+#include "demoUI.h"
+#include "demoDefinitions.h"
+
+extern uint16_t HrmResult;
+extern uint16_t SPO2Result;
+extern uint8_t  HrmConfidence;
+extern uint8_t  SPo2Confidence;
+
+DigitalOut debugled(LED1, 1);
+// Hardware serial port over DAPLink
+Serial daplink(USBTX, USBRX, 115200);
+
+#include "USBSerial.h"
+USBSerial microUSB(0x1f00, 0x2012, 0x0001, false);
+
+
+
+// ICARUS Board initialization
+InterruptIn interruptIn_PowerButton(P7_6);
+MAX32630HSP icarus(MAX32630HSP::VIO_1V8, &interruptIn_PowerButton);
+
+#define WAIT_SENSORHUB_STABLE_BOOTUP_MS  ((uint32_t)2000)
+
+
+static bool isWhrmInitialized     = false;
+static bool isSpo2Initialized     = false;
+static bool isContSpo2Initialized = false;
+
+static const int SPO2SINGLESHOTMODE = 1;
+static const int SPO2CONTINIOUSMODE = 0;
+
+int main() {
+
+	wait_ms(WAIT_SENSORHUB_STABLE_BOOTUP_MS);
+	//demoUI_display_set_algoMode(kAlgoModeHeartRate);
+	int hostMode = HOSTMODEAPPLICATION;
+
+	demoUI_init();
+
+	sh_init_hwcomm_interface();
+	sh_disable_irq_mfioevent();
+	sh_clear_mfio_event_flag();
+	sh_enable_irq_mfioevent();
+	int i = 0;
+
+	int displayMode;
+	uint16_t resultToDisplay;
+	uint8_t  confidenceToDisplay;
+
+	while(1) {
+
+
+		//USBSerial *serial = &microUSB;
+		char ch;
+		while ( SERIAL_AVAILABLE()/*daplink.readable()*/) {
+			//ch = daplink.getc();
+            //printf("%c  " , ch );
+			//ch = microUSB._getc();
+			ch = SERIALIN();
+			cmdIntf_build_command(ch);
+		}
+
+        hostMode  = get_internal_operating_mode();
+		if( hostMode  == HOSTMODEAPPLICATION) {
+
+				displayMode = demoUI_display_get_mode();
+
+				if( displayMode == kAlgoModeHeartRate ){
+					 if( !isWhrmInitialized){
+#if defined(DEBUG_INFO)
+						 SERIALOUT(" WHRM inititalized \r\n");
+#endif
+						 SH_Max8614x_stop();
+						 SH_Max8614x_default_init(kAlgoModeHeartRate);
+						 isWhrmInitialized = true;
+						 isSpo2Initialized = false;
+						 isContSpo2Initialized = false;
+						 wait_ms(1000); /* for display screen*/
+					 }
+					 resultToDisplay     = HrmResult;
+					 confidenceToDisplay = HrmConfidence;
+
+				}else if( displayMode == kAlgoModeSPO2 ){
+					if( !isSpo2Initialized){
+#if defined(DEBUG_INFO)
+						SERIALOUT(" WSPo2 inititalized \r\n");
+#endif
+						SH_Max8614x_stop();
+						Max8614x_Set_WSPO2Mode(SPO2SINGLESHOTMODE);
+						SH_Max8614x_default_init(kAlgoModeSPO2);
+						isWhrmInitialized = false;
+						isSpo2Initialized = true;
+						isContSpo2Initialized = false;
+						wait_ms(1000); /* for display screen*/
+					}
+					resultToDisplay = SPO2Result;
+					confidenceToDisplay = SPo2Confidence;
+
+				}else if( displayMode == kAlgoModeContSPO2 ){
+
+					if( !isContSpo2Initialized){
+#if defined(DEBUG_INFO)
+						SERIALOUT(" Continious WSPo2 inititalized \r\n");
+#endif
+						SH_Max8614x_stop();
+						Max8614x_Set_WSPO2Mode(SPO2CONTINIOUSMODE);
+						SH_Max8614x_default_init(kAlgoModeSPO2);
+						isWhrmInitialized = false;
+						isSpo2Initialized = false;
+						isContSpo2Initialized = true;
+						wait_ms(1000); /* for display screen*/
+					}
+					resultToDisplay = SPO2Result;
+					confidenceToDisplay = SPo2Confidence;
+
+			  }
+
+				int cumSampleCNt = SH_Max8614x_data_report_execute();
+
+				if(cumSampleCNt){ /* If data samples ara avaliable display on screen*/
+#if defined(DEBUG_INFO)
+					//SERIALOUT("estimate: =%d conf: %d dispMode: %d \r\n", resultToDisplay , confidenceToDisplay, displayMode);
+#endif
+					if( displayMode == kAlgoModeContSPO2 )
+						 demoUI_display_algo_estimations(resultToDisplay, SPo2Confidence ); /*In continious SPO2 mode display confidence on screen so user can validate result */
+					if( displayMode == kAlgoModeSPO2 )
+						demoUI_display_algo_estimations(resultToDisplay, -1);
+					if( displayMode == kAlgoModeHeartRate)
+						demoUI_display_algo_estimations(resultToDisplay, -1);
+					//printf(" Display Mode : %d \r\n", displayMode );
+				}
+
+
+		}else {
+
+				demoUI_display_bootldr_screen();
+               //wait_ms(10);
+		}
+
+	}
+
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-os.lib	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-os/#51d55508e8400b60af467005646c4e2164738d48
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/platform/MAX20303.cpp	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,367 @@
+/*******************************************************************************
+ * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+ * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Maxim Integrated
+ * Products, Inc. shall not be used except as stated in the Maxim Integrated
+ * Products, Inc. Branding Policy.
+ *
+ * The mere transfer of this software does not imply any licenses
+ * of trade secrets, proprietary technology, copyrights, patents,
+ * trademarks, maskwork rights, or any other form of intellectual
+ * property whatsoever. Maxim Integrated Products, Inc. retains all
+ * ownership rights.
+ *******************************************************************************
+ */
+
+
+#include "MAX20303.h"
+
+
+
+//******************************************************************************
+MAX20303::MAX20303(I2C *i2c):
+	m_i2c(i2c), m_writeAddress(MAX20303_SLAVE_WR_ADDR),
+	m_readAddress(MAX20303_SLAVE_RD_ADDR)
+{
+}
+
+
+//******************************************************************************
+MAX20303::~MAX20303(void)
+{
+  //empty block
+}
+
+
+//******************************************************************************
+int MAX20303::LDO1Config()
+{
+	int32_t ret = 0;
+	uint8_t val;
+//	ret |= writeReg(MAX20303::REG_AP_CMDOUT, 0x40);
+//	ret |= writeReg(MAX20303::REG_AP_DATOUT0, 0x05);
+//	ret |= writeReg(MAX20303::REG_AP_DATOUT1, 0x34);
+//
+//	readReg(MAX20303::REG_AP_CMDOUT, val);
+//	readReg(MAX20303::REG_AP_DATOUT0, val);
+//	readReg(MAX20303::REG_AP_DATOUT1, val);
+	appcmdoutvalue_ = 0x40;
+	appdatainoutbuffer_[0] = 0x05;
+	appdatainoutbuffer_[1] = 0x34;
+	AppWrite(2);
+
+	return ret;
+}
+
+//******************************************************************************
+int MAX20303::LDO2Config()
+{
+	int32_t ret = 0;
+	uint8_t val;
+	appcmdoutvalue_ = 0x42;
+	appdatainoutbuffer_[0] = 0x01;
+	appdatainoutbuffer_[1] = 0x15;     // 0.9V + (0.1V * number)   =  3V
+	AppWrite(2);
+
+	return ret;
+}
+
+
+//******************************************************************************
+int MAX20303::writeReg(registers_t reg, uint8_t value)
+{
+	int32_t ret;
+
+	char cmdData[2] = {reg, value};
+
+	ret = m_i2c->write(m_writeAddress, cmdData, sizeof(cmdData));
+	//printf("MAX20303 write reg[0x%X]=0x%X, ret=%d\r\n", (uint32_t)reg, value, ret)
+
+	if (ret != 0)
+		return MAX20303_ERROR;
+
+	return MAX20303_NO_ERROR;
+}
+
+
+//******************************************************************************
+int MAX20303::readReg(registers_t reg, uint8_t &value)
+{
+	int32_t ret;
+
+	char data = reg;
+
+	ret = m_i2c->write(m_writeAddress, &data, sizeof(data));
+	if (ret != 0) {
+		printf("%s - failed - ret: %d\n", __func__);
+		return MAX20303_ERROR;
+	}
+
+	ret = m_i2c->read(m_readAddress, &data, sizeof(data));
+	if (ret != 0) {
+		printf("%s - failed - ret: %d\n", __func__);
+		return MAX20303_ERROR;
+	}
+
+	value = data;
+	printf("MAX20303 read reg[0x%X]=0x%X, ret=%d\r\n", (uint32_t)reg, value, ret);
+	return MAX20303_NO_ERROR;
+}
+
+//******************************************************************************
+int MAX20303::readRegMulti(registers_t reg, uint8_t *value, uint8_t len){
+	int32_t ret;
+	char data = reg;
+
+	ret = m_i2c->write(m_writeAddress, &data, sizeof(data));
+	if (ret != 0) {
+		printf("%s - failed - ret: %d\n", __func__);
+		return MAX20303_ERROR;
+	}
+
+	ret = m_i2c->read(m_readAddress, (char *)value, len);
+	if (ret != 0) {
+		printf("%s - failed - ret: %d\n", __func__);
+		return MAX20303_ERROR;
+	}
+
+	printf("MAX20303 read reg[0x%X]=0x%X, ret=%d\r\n", (uint32_t)reg, value, ret);
+	return MAX20303_NO_ERROR;
+}
+
+//******************************************************************************
+int MAX20303::writeRegMulti(registers_t reg, uint8_t *value, uint8_t len){
+	int32_t ret;
+	i2cbuffer_[0] = reg;
+	memcpy(&i2cbuffer_[1], value, len);
+
+	ret = m_i2c->write(m_writeAddress, (char *)i2cbuffer_, (len+1));
+	//printf("MAX20303 write reg[0x%X]=0x%X, ret=%d\r\n", (uint32_t)reg, value, ret)
+
+	if (ret != 0)
+		return MAX20303_ERROR;
+
+	return MAX20303_NO_ERROR;
+}
+//******************************************************************************
+int MAX20303::mv2bits(int mV)
+{
+    int regBits;
+
+    if (( MAX20303_LDO_MIN_MV <= mV) && (mV <= MAX20303_LDO_MAX_MV)) {
+        regBits = (mV -  MAX20303_LDO_MIN_MV) /  MAX20303_LDO_STEP_MV;
+    } else {
+        return -1;
+    }
+
+    return regBits;
+}
+//******************************************************************************
+int MAX20303::PowerOffthePMIC(){
+	int ret;
+	appdatainoutbuffer_[0] = 0xB2;
+	appcmdoutvalue_ = 0x80;
+	ret = AppWrite(1);
+
+	if(appcmdoutvalue_ != 0x80){
+		ret |= MAX20303_ERROR;
+	}
+
+	return ret;
+}
+//******************************************************************************
+int MAX20303::PowerOffDelaythePMIC(){
+	int ret;
+	appdatainoutbuffer_[0] = 0xB2;
+	appcmdoutvalue_ = 0x84;
+	ret = AppWrite(1);
+
+	if(appcmdoutvalue_ != 0x80){
+		ret |= MAX20303_ERROR;
+	}
+
+	return ret;
+}
+
+//******************************************************************************
+int MAX20303::SoftResetthePMIC(){
+	int ret;
+	appdatainoutbuffer_[0] = 0xB3;
+	appcmdoutvalue_ = 0x81;
+	ret = AppWrite(1);
+
+	if(appcmdoutvalue_ != 0x81){
+		ret |= MAX20303_ERROR;
+	}
+
+	return ret;
+}
+//******************************************************************************
+int MAX20303::HardResetthePMIC(){
+	int ret;
+	appdatainoutbuffer_[0] = 0xB4;
+	appcmdoutvalue_ = 0x82;
+	ret = AppWrite(1);
+
+	if(appcmdoutvalue_ != 0x82){
+		ret |= MAX20303_ERROR;
+	}
+
+	return ret;
+}
+
+//******************************************************************************
+int MAX20303::AppWrite(uint8_t dataoutlen){
+	int ret;
+
+	ret = writeRegMulti(MAX20303::REG_AP_DATOUT0, appdatainoutbuffer_, dataoutlen);
+	ret |= writeReg(MAX20303::REG_AP_CMDOUT, appcmdoutvalue_);
+	wait_ms(10);
+	ret |= readReg(MAX20303::REG_AP_RESPONSE, appcmdoutvalue_);
+
+	if(ret != 0)
+		return MAX20303_ERROR;
+
+	return MAX20303_NO_ERROR;
+}
+
+
+//******************************************************************************
+int MAX20303::AppRead(uint8_t datainlen){
+	int ret;
+
+	ret = writeReg(MAX20303::REG_AP_CMDOUT, appcmdoutvalue_);
+	wait_ms(10);
+	ret |= readRegMulti(MAX20303::REG_AP_RESPONSE, i2cbuffer_, datainlen);
+	if(ret != 0)
+		return MAX20303_ERROR;
+
+	return MAX20303_NO_ERROR;
+}
+
+//******************************************************************************
+char MAX20303::CheckPMICHWID(){
+	int ret;
+	uint8_t value = 0x00;
+
+	ret = readReg(MAX20303::REG_HARDWARE_ID, value);
+	if(ret != MAX20303_NO_ERROR)
+		return false;
+
+	if(value == 0x02)
+		return true;
+	else
+		return false;
+}
+
+//******************************************************************************
+int MAX20303::CheckPMICStatusRegisters(unsigned char buf_results[5]){
+	int ret;
+	ret  = readReg(MAX20303::REG_STATUS0, buf_results[0]);
+	ret |= readReg(MAX20303::REG_STATUS1, buf_results[1]);
+	ret |= readReg(MAX20303::REG_STATUS2, buf_results[2]);
+	ret |= readReg(MAX20303::REG_STATUS3, buf_results[3]);
+	ret |= readReg(MAX20303::REG_SYSTEM_ERROR, buf_results[4]);
+	return ret;
+}
+
+//******************************************************************************
+int MAX20303::Max20303_BatteryGauge(unsigned char *batterylevel){
+    int ret;
+    char data[2];
+
+    data[0] = 0x04;
+    ret = m_i2c->write(MAX20303_I2C_ADDR_FUEL_GAUGE, data, 1);
+    if(ret != 0){
+        printf("Max20303_FuelGauge has failed\r\n");
+    }
+
+    ret = m_i2c->read(MAX20303_I2C_ADDR_FUEL_GAUGE | 1, data, 2);
+    if(ret != 0){
+        printf("Max20303_FuelGauge has failed\r\n");
+    }
+
+    // if the level is more than 100 assume the battery is not connected
+    if(data[0] > 100){
+        *batterylevel = 0;
+    } else{
+
+        *batterylevel = data[0];
+    }
+    return 0;
+}
+
+
+//******************************************************************************
+int MAX20303::led0on(char enable) {
+
+	if(enable)
+		return writeReg(REG_LED0_DIRECT, 0x21);
+	else
+		return writeReg(REG_LED0_DIRECT, 0x01);
+}
+
+//******************************************************************************
+int MAX20303::led1on(char enable) {
+	if(enable)
+		return writeReg(REG_LED1_DIRECT, 0x21);
+	else
+		return writeReg(REG_LED1_DIRECT, 0x01);
+}
+
+//******************************************************************************
+int MAX20303::led2on(char enable) {
+	if(enable)
+		return writeReg(REG_LED2_DIRECT, 0x21);
+	else
+		return writeReg(REG_LED2_DIRECT, 0x01);
+}
+
+
+//******************************************************************************
+int MAX20303::BoostEnable(void) {
+	writeReg(REG_AP_DATOUT3, 0x00);	// 00 : 5V
+	writeReg(REG_AP_DATOUT0, 0x01);	// Boost Enabled
+	writeReg(REG_AP_CMDOUT, 0x30);
+	return MAX20303_NO_ERROR;
+}
+
+//******************************************************************************
+int MAX20303::BuckBoostEnable(void)
+{
+	int ret = 0;
+
+	ret |= writeReg( REG_AP_DATOUT0,  0x00);    // Reserved = 0x00
+	ret |= writeReg( REG_AP_DATOUT1,  0x04);    // BBstlSet = 0b'100   Buck Boost Peak current Limit = 200mA
+	ret |= writeReg( REG_AP_DATOUT2,  0x19);    // BBstVSet = 0b'11001  Buck Boost Output Voltage = 5V
+	ret |= writeReg( REG_AP_DATOUT3,  0x01);    // BBstRipRed = 1 Ripple Reduction
+	// BBstAct    = 1 Actively discharged in Hard-Reset or Enable Low
+	// BBstPas    = 1 Passively discharged in Hard-Reset or Enable Low
+	// BBstMd     = 1 Damping Enabled
+	// BBstInd    = 0  Inductance is 4.7uH
+	// BBstEn     = 0b'01 Enabled
+	ret |= writeReg( REG_AP_CMDOUT, 0x70);
+	if (ret != 0)
+		return MAX20303_ERROR;
+
+	return MAX20303_NO_ERROR;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/platform/MAX20303.h	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,222 @@
+/*******************************************************************************
+ * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+ * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Maxim Integrated
+ * Products, Inc. shall not be used except as stated in the Maxim Integrated
+ * Products, Inc. Branding Policy.
+ *
+ * The mere transfer of this software does not imply any licenses
+ * of trade secrets, proprietary technology, copyrights, patents,
+ * trademarks, maskwork rights, or any other form of intellectual
+ * property whatsoever. Maxim Integrated Products, Inc. retains all
+ * ownership rights.
+ *******************************************************************************
+ */
+#ifndef __MAX20303_H_
+#define __MAX20303_H_
+
+#include "mbed.h"
+
+#define MAX20303_SLAVE_ADDR		(0x50 >> 1)
+#define MAX20303_SLAVE_WR_ADDR		((MAX20303_SLAVE_ADDR << 1))
+#define MAX20303_SLAVE_RD_ADDR		((MAX20303_SLAVE_ADDR << 1) | 1)
+
+
+#define MAX20303_NO_ERROR   0
+#define MAX20303_ERROR      -1
+
+#define MAX20303_I2C_ADDR_FUEL_GAUGE	0x6c
+#define MAX20303_I2C_ADDR_FUEL_GAUGE    0x6C
+
+#define MAX20303_LDO_MIN_MV 800
+#define MAX20303_LDO_MAX_MV 3600
+#define MAX20303_LDO_STEP_MV 100
+
+#define MAX20303_OFF_COMMAND 0xB2
+
+class MAX20303
+{
+
+public:
+	/**
+	 * @brief   Register Addresses
+	 * @details Enumerated MAX20303 register addresses
+	 */
+	enum registers_t {
+		REG_HARDWARE_ID		= 0x00,		///< HardwareID Register
+		REG_FIRMWARE_REV	= 0x01,		///< FirmwareID Register
+		//					= 0x02,		///<
+		REG_INT0			= 0x03,		///< Int0 Register
+		REG_INT1			= 0x04,		///< Int1 Register
+		REG_INT2			= 0x05,		///< Int2 Register
+		REG_STATUS0			= 0x06,		///< Status Register 0
+		REG_STATUS1			= 0x07,		///< Status Register 1
+		REG_STATUS2			= 0x08,		///< Status Register 2
+		REG_STATUS3			= 0x09,		///< Status Register 2
+		//					= 0x0A,		///<
+		REG_SYSTEM_ERROR	= 0x0B,		///< SystemError Register
+		REG_INT_MASK0		= 0x0C,		///< IntMask0 Register
+		REG_INT_MASK1		= 0x0D,		///< IntMask1 Register
+		REG_INT_MASK2		= 0x0E,		///< IntMask1 Register
+		REG_AP_DATOUT0		= 0x0F,     ///< APDataOut0 Register
+		REG_AP_DATOUT1		= 0x10,     ///< APDataOut1 Register
+		REG_AP_DATOUT2		= 0x11,     ///< APDataOut2 Register
+		REG_AP_DATOUT3		= 0x12,     ///< APDataOut3 Register
+		REG_AP_DATOUT4		= 0x13,     ///< APDataOut4 Register
+		REG_AP_DATOUT5		= 0x14,     ///< APDataOut5 Register
+		REG_AP_DATOUT6		= 0x15,     ///< APDataOut6 Register
+		REG_AP_CMDOUT		= 0x17,     ///< APCmdOut Register
+		REG_AP_RESPONSE		= 0x18,     ///< APResponse Register
+		REG_AP_DATAIN0		= 0x19,
+		REG_AP_DATAIN1		= 0x1A,
+		REG_AP_DATAIN2		= 0x1B,
+		REG_AP_DATAIN3		= 0x1C,
+		REG_AP_DATAIN4		= 0x1D,
+		REG_AP_DATAIN5		= 0x1E,
+		//					= 0x1F,		///<
+		REG_LDO_DIRECT		= 0x20,
+		REG_MPC_DIRECTWRITE	= 0x21,
+		REG_MPC_DIRECTRED	= 0x22,
+
+		REG_LED_STEP_DIRECT	= 0x2C,
+		REG_LED0_DIRECT		= 0x2D,
+		REG_LED1_DIRECT		= 0x2E,
+		REG_LED2_DIRECT		= 0x2F,
+
+
+		REG_LDO1_CONFIG_WRITE = 0x40,
+		REG_LDO1_CONFIG_READ  = 0x41,
+		REG_LDO2_CONFIG_WRITE = 0x42,
+		REG_LDO2_CONFIG_READ  = 0x43
+
+		/*
+		REG_CHG_TMR = 0x0C,   ///< Charger Timers
+		REG_BUCK1_CFG = 0x0D,   ///< Buck 1 Configuration
+		REG_BUCK1_VSET = 0x0E,   ///< Buck 1 Voltage Setting
+		REG_BUCK2_CFG = 0x0F,   ///< Buck 2 Configuration
+		REG_BUCK2_VSET = 0x10,   ///< Buck 2 Voltage Setting
+		REG_RSVD_11 = 0x11,   ///< Reserved 0x11
+		REG_LDO1_CFG = 0x12,   ///< LDO 1 Configuration
+		REG_LDO1_VSET = 0x13,   ///< LDO 1 Voltage Setting
+		REG_LDO2_CFG = 0x14,   ///< LDO 2 Configuration
+		REG_LDO2_VSET = 0x15,   ///< LDO 2 Voltage Setting
+		REG_LDO3_CFG = 0x16,   ///< LDO 3 Configuration
+		REG_LDO3_VSET = 0x17,   ///< LDO 3 Voltage Setting
+		REG_THRM_CFG = 0x18,   ///< Thermistor Configuration
+		REG_MON_CFG = 0x19,   ///< Monitor Multiplexer Configuration
+		REG_BOOT_CFG = 0x1A,   ///< Boot Configuration
+		REG_PIN_STATUS = 0x1B,   ///< Pin Status
+		REG_BUCK_EXTRA = 0x1C,   ///< Additional Buck Settings
+		REG_PWR_CFG = 0x1D,   ///< Power Configuration
+		REG_NULL = 0x1E,   ///< Reserved 0x1E
+		REG_PWR_OFF = 0x1F,   ///< Power Off Register
+		*/
+	};
+
+	/**
+	* @brief  Constructor using reference to I2C object
+	* @param i2c - Reference to I2C object
+	* @param slaveAddress - 7-bit I2C address
+	*/
+	MAX20303(I2C *i2c);
+
+	/** @brief Destructor */
+	~MAX20303(void);
+
+	int led0on(char enable);
+	int led1on(char enable);
+	int led2on(char enable);
+	int BoostEnable(void);
+	int BuckBoostEnable(void);
+
+	/// @brief Enable the 1.8V output rail **/
+	int LDO1Config(void);
+
+	/// @brief Enable the 3V output rail **/
+	int LDO2Config(void);
+
+
+	int mv2bits(int mV);
+
+	/** @brief Power Off the board
+	 */
+	int PowerOffthePMIC();
+
+	/** @brief Power Off the board with 30ms delay
+	 */
+	int PowerOffDelaythePMIC();
+
+	/** @brief Soft reset the PMIC
+	 */
+	int SoftResetthePMIC();
+
+	/** @brief Hard reset the PMIC
+	 */
+	int HardResetthePMIC();
+
+	/** @brief check if can communicate with max20303
+	*/
+	char CheckPMICHWID();
+
+	/** @brief CheckPMICStatusRegisters
+	*/
+	int CheckPMICStatusRegisters(unsigned char buf_results[5]);
+
+    int Max20303_BatteryGauge(unsigned char *batterylevel);
+
+private:
+
+	int writeReg(registers_t reg, uint8_t value);
+	int readReg(registers_t reg, uint8_t &value);
+
+	int writeRegMulti(registers_t reg, uint8_t *value, uint8_t len);
+	int readRegMulti(registers_t reg, uint8_t *value, uint8_t len);
+
+	/// I2C object
+	I2C  *m_i2c;
+
+	/// Device slave addresses
+	uint8_t m_writeAddress, m_readAddress;
+
+	// Application Processor Interface Related Variables
+	uint8_t i2cbuffer_[16];
+	uint8_t appdatainoutbuffer_[8];
+	uint8_t appcmdoutvalue_;
+
+
+	/** @brief API Related Functions ***/
+
+	/***
+	 *  @brief  starts writing from ApResponse register 0x0F
+	 *  check the datasheet to determine the value of dataoutlen
+	 */
+	int AppWrite(uint8_t dataoutlen);
+
+	/** @brief starts reading from ApResponse register 0x18
+	 *  check the datasheet to determine the value of datainlen
+	 *  the result values are written into i2cbuffer
+	 *
+	*/
+	int AppRead(uint8_t datainlen);
+};
+
+#endif /* __MAX20303_H_ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/platform/max32630hsp.cpp	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,236 @@
+/*******************************************************************************
+ * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+ * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Maxim Integrated
+ * Products, Inc. shall not be used except as stated in the Maxim Integrated
+ * Products, Inc. Branding Policy.
+ *
+ * The mere transfer of this software does not imply any licenses
+ * of trade secrets, proprietary technology, copyrights, patents,
+ * trademarks, maskwork rights, or any other form of intellectual
+ * property whatsoever. Maxim Integrated Products, Inc. retains all
+ * ownership rights.
+ *******************************************************************************
+ */
+
+#include "mbed.h"
+#include "max3263x.h"
+#include "ioman_regs.h"
+#include "PinNames.h"
+#include "max32630hsp.h"
+
+
+//******************************************************************************
+MAX32630HSP::MAX32630HSP() : i2c(P5_7, P6_0), max20303(&i2c)
+{
+}
+
+//******************************************************************************
+MAX32630HSP::MAX32630HSP(vio_t vio) : i2c(P5_7, P6_0), max20303(&i2c)
+{
+
+    init(vio);
+}
+
+//******************************************************************************
+MAX32630HSP::MAX32630HSP(vio_t vio, InterruptIn *max32630hsp3_powerButtonInterrupt) : i2c(P5_7, P6_0), max20303(&i2c), m_max32630hsp3_powerButtonInterrupt(max32630hsp3_powerButtonInterrupt)
+{
+    init(vio);
+
+    m_max32630hsp3_powerButtonInterrupt->disable_irq();
+    m_max32630hsp3_powerButtonInterrupt->rise(this, &MAX32630HSP::event_powerButtonReleased);
+    m_max32630hsp3_powerButtonInterrupt->mode(PullUp);
+	m_max32630hsp3_powerButtonInterrupt->enable_irq();
+}
+
+
+//******************************************************************************
+MAX32630HSP::~MAX32630HSP()
+{
+
+}
+
+
+//******************************************************************************
+int MAX32630HSP::init(vio_t hdrVio)
+{
+	/* Wait for pmic to settle down */
+	wait_ms(800);
+
+
+
+	/*Set LDO1 to 1.8v*/
+	max20303.LDO1Config();
+
+	/*Set LDO2 to 3v*/
+    max20303.LDO2Config();
+
+	//max20303.BoostEnable();
+	max20303.BuckBoostEnable();
+
+
+	max20303.led0on(0);
+	max20303.led1on(0);
+	max20303.led2on(0);
+
+	/* Wait for pmic to settle down */
+    wait_ms(200);
+
+    // Set LED pins to 3.3V
+    vddioh(P2_4, VIO_3V3);
+    vddioh(P2_5, VIO_3V3);
+    vddioh(P2_6, VIO_3V3);
+
+    // set i2c pins to 1.8V
+    vddioh(P3_4, VIO_1V8);
+    vddioh(P3_5, VIO_1V8);
+    //ble module pins to 1.8V
+    vddioh(P0_0, VIO_1V8);
+    vddioh(P0_1, VIO_1V8);
+    vddioh(P0_2, VIO_1V8);
+    vddioh(P0_3, VIO_1V8);
+
+    // Set header pins to hdrVio
+    vddioh(P3_0, hdrVio);
+    vddioh(P3_1, hdrVio);
+    vddioh(P3_2, hdrVio);
+    vddioh(P3_3, hdrVio);
+    vddioh(P4_0, hdrVio);
+    vddioh(P4_1, hdrVio);
+    vddioh(P4_2, hdrVio);
+    vddioh(P4_3, hdrVio);
+    vddioh(P4_4, hdrVio);
+    vddioh(P4_5, hdrVio);
+    vddioh(P4_6, hdrVio);
+    vddioh(P4_7, hdrVio);
+    vddioh(P5_0, hdrVio);
+    vddioh(P5_1, hdrVio);
+    vddioh(P5_2, hdrVio);
+    vddioh(P5_3, hdrVio);
+    vddioh(P5_4, hdrVio);
+    vddioh(P5_5, hdrVio);
+    vddioh(P5_6, hdrVio);
+
+
+    button_longpressdetected = false;
+
+    return 0;
+}
+
+
+void MAX32630HSP::event_powerButtonPressed(void) {
+
+	max20303.led0on(0);
+	max20303.led1on(0);
+	max20303.led2on(1);
+
+	/* Button press detected. Wait for button release */
+    m_max32630hsp3_powerButtonInterrupt->disable_irq();
+    m_max32630hsp3_powerButtonInterrupt->rise(this, &MAX32630HSP::event_powerButtonReleased);
+    m_max32630hsp3_powerButtonInterrupt->mode(PullUp);
+	m_max32630hsp3_powerButtonInterrupt->enable_irq();
+
+	/* Button press detected. Start Timeout object for checking long key press event */
+	button_timeout.attach( this, &MAX32630HSP::event_longpresscheck , 2.0 );
+
+	/* Button is pressed */
+	button_status = true;
+}
+
+//******************************************************************************
+void MAX32630HSP::event_powerButtonReleased(void) {
+
+
+	if ( button_longpressdetected ) {
+
+		/* Power of the PMIC if long key press is detected */
+		max20303.PowerOffDelaythePMIC();
+
+	}
+	else {
+
+		/* Button released before a long key press is detected */
+		button_status = false;
+
+	}
+
+	/* Button is released. Stop timeout object */
+	button_timeout.detach();
+
+	max20303.led0on(0);
+	max20303.led1on(0);
+	max20303.led2on(0);
+
+	/* Button is released. Expect for button press event next time */
+    m_max32630hsp3_powerButtonInterrupt->disable_irq();
+    m_max32630hsp3_powerButtonInterrupt->fall(this, &MAX32630HSP::event_powerButtonPressed);
+    m_max32630hsp3_powerButtonInterrupt->mode(PullUp);
+	m_max32630hsp3_powerButtonInterrupt->enable_irq();
+
+
+}
+
+void MAX32630HSP::event_longpresscheck(void) {
+
+	/* This is the callback for timeout object to detect long key press for power down */
+
+	if ( button_status == 1 ) {
+
+		/* If button_status is still 1 when timeout is triggered, it will be interpreted as a long key press */
+		button_longpressdetected = true;
+
+		/* The PMIC will be powered of when the button is released */
+		max20303.led0on(0);
+		max20303.led1on(1);
+		max20303.led2on(0);
+	}
+
+}
+
+void MAX32630HSP::enableDisplay(void)
+{
+	vddioh(P6_4, VIO_3V3); //EXTCOM
+	vddioh(P6_1, VIO_3V3); //SCLK
+	vddioh(P6_2, VIO_3V3); //MOSI1
+	vddioh(P6_5, VIO_3V3); //SCS
+	vddioh(P6_4, VIO_3V3); //EXTCOM
+	vddioh(P6_6, VIO_3V3); //DISP
+}
+
+//******************************************************************************
+int MAX32630HSP::vddioh(PinName pin, vio_t vio)
+{
+    __IO uint32_t *use_vddioh = &((mxc_ioman_regs_t *)MXC_IOMAN)->use_vddioh_0;
+
+    if (pin == NOT_CONNECTED) {
+        return -1;
+    }
+
+    use_vddioh += PINNAME_TO_PORT(pin) >> 2;
+    if (vio) {
+        *use_vddioh |= (1 << (PINNAME_TO_PIN(pin) + ((PINNAME_TO_PORT(pin) & 0x3) << 3)));
+    } else {
+        *use_vddioh &= ~(1 << (PINNAME_TO_PIN(pin) + ((PINNAME_TO_PORT(pin) & 0x3) << 3)));
+    }
+
+    return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/platform/max32630hsp.h	Mon Mar 18 14:09:48 2019 +0300
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+ * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Maxim Integrated
+ * Products, Inc. shall not be used except as stated in the Maxim Integrated
+ * Products, Inc. Branding Policy.
+ *
+ * The mere transfer of this software does not imply any licenses
+ * of trade secrets, proprietary technology, copyrights, patents,
+ * trademarks, maskwork rights, or any other form of intellectual
+ * property whatsoever. Maxim Integrated Products, Inc. retains all
+ * ownership rights.
+ *******************************************************************************
+ */
+
+#ifndef _MAX32630HSP_H_
+#define _MAX32630HSP_H_
+
+#include "mbed.h"
+#include "MAX20303.h"
+
+
+/**
+ * @brief MAX32630HSP Board Support Library
+ *
+ * @details The MAX32630HSP is a rapid development application board for
+ * ultra low power wearable applications.  It includes common peripherals and
+ * expansion connectors all power optimized for getting the longest life from
+ * the battery.  This library configures the power and I/O for the board.
+ * <br>https://www.maximintegrated.com/max32630hsp
+ *
+ * @code
+ * #include "mbed.h"
+ * #include "max32630hsp.h"
+ *
+ * DigitalOut led1(LED1);
+ * MAX32630HSP icarus(MAX32630HSP::VIO_3V3);
+ *
+ * // main() runs in its own thread in the OS
+ * // (note the calls to Thread::wait below for delays)
+ * int main()
+ * {
+ *     // initialize power and I/O on MAX32630HSP board
+ *     icarus.init();
+ *
+ *     while (true) {
+ *         led1 = !led1;
+ *         Thread::wait(500);
+ *     }
+ * }
+ * @endcode
+ */
+
+// Sharp LS013B7DH03 Memory Display
+#define SCK_PIN     		P6_1
+#define MOSI_PIN    		P6_2
+#define CS_PIN      		P6_5
+#define EXTCOM_PIN  		P6_4
+#define DISP_PIN    		P6_6
+#define DISPSEL_PIN 		NC
+#define	PIN_POWERBUTTON		P7_6
+#define	PIN_UPBUTTON		P2_3
+#define	PIN_DOWNBUTTON		P6_5
+
+class MAX32630HSP
+{
+public:
+// max32630hsp configuration utilities
+
+    /**
+      * @brief   IO Voltage
+      * @details Enumerated options for operating voltage
+      */
+    typedef enum {
+        VIO_1V8 = 0x00,    ///< 1.8V IO voltage at headers (from BUCK2)
+        VIO_3V3 = 0x01,    ///< 3.3V IO voltage at headers (from LDO2)
+    } vio_t;
+
+    enum ButtonStatus {
+    	BUTTONSTATUS_RELEASED = 1,
+		BUTTONSTATUS_PRESSED
+    } ;
+
+    /**
+        * MAX32630HSP constructor.
+        *
+        */
+    MAX32630HSP();
+
+    /**
+        * MAX32630HSP constructor.
+        *
+        */
+    MAX32630HSP(vio_t vio);
+
+    /**
+        * MAX32630HSP constructor.
+        *
+        */
+    MAX32630HSP(vio_t vio, InterruptIn *max32630hsp3_powerButtonInterrupt);
+
+    /**
+        * MAX32630HSP destructor.
+        */
+    ~MAX32630HSP();
+
+    //InterruptIn _interruptIn_PowerButton;
+
+    /**
+     * @brief   Initialize MAX32630HSP board
+     * @details Initializes PMIC and I/O on MAX32630HSP board.
+     *  Configures PMIC to enable LDO2 and LDO3 at 3.3V.
+     *  Disables resisitive pulldown on MON(AIN_0)
+     *  Sets default I/O voltages to 3V3 for micro SD card.
+     *  Sets I/O voltage for header pins to hdrVio specified.
+     * @param hdrVio I/O voltage for header pins
+     * @returns 0 if no errors, -1 if error.
+    */
+    int init(vio_t hdrVio);
+
+    /**
+     * @brief   Sets I/O Voltage
+     * @details Sets the voltage rail to be used for a given pin.
+     *  VIO_1V8 selects VDDIO which is supplied by Buck2, which is set at 1.8V,
+     *  VIO_3V3 selects VDDIOH which is supplied by LDO2, which is typically 3.3V/
+     * @param   pin Pin whose voltage supply is being assigned.
+     * @param   vio Voltage rail to be used for specified pin.
+     * @returns 0 if no errors, -1 if error.
+    */
+    int vddioh(PinName pin, vio_t vio);
+
+    /**Interrupt Hander for Power Button Press**/
+
+    //InterruptIn _interruptIn_UpButton(PIN_UPBUTTON);
+    //InterruptIn _interruptIn_DownButton(PIN_DOWNBUTTON);
+
+    /* Set vddio for Sharp LS013B7DH03 Display */
+	void enableDisplay(void);
+
+    /// Local I2C bus for configuring PMIC and accessing BMI160 IMU.
+    I2C i2c;
+
+    /// MAX20303 PMIC Instance
+    MAX20303 max20303;
+
+
+    InterruptIn *m_max32630hsp3_powerButtonInterrupt;
+    bool	button_status;
+    bool	button_longpressdetected;
+    Timeout	button_timeout;
+
+    ButtonStatus status_powerButton;
+    ButtonStatus status_upButton;
+    ButtonStatus status_downButton;
+    void event_powerButtonPressed(void);
+    void event_powerButtonReleased(void);
+    void event_longpresscheck(void);
+};
+
+#endif /* _MAX32630HSP_H_ */
+