Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BMI160 max32630hsp3 MemoryLCD USBDevice
Fork of Host_Software_MAX32664GWEC_SpO2_HR-_EXTE by
Revision 0:b259fd1a88f5, committed 2019-03-18
- 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
--- /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 = µUSB;
+ 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_ */
+
