Example Host software for integration of MAX3266x chips (, MAX32664GWEB) equipped with Heart Rate from Wrist Algorithm. This is “stand-alone” software that runs on the MAX32630 low-power microcontroller to display heart rate on the display of the MAXREFDES101 reference design. It is intended provide a simple example of how to initialize and communicate with the sensor hub. Windows and Android communications are not supported.
Dependencies: Maxim_Sensor_Hub_Communications BMI160 whrmDemoUI max32630hsp3
Fork of Host_Software_MAX32664GWEB_HR_wrist by
Revision 13:3d1a6b947396, committed 2019-01-10
- Comitter:
- gmehmet
- Date:
- Thu Jan 10 11:06:01 2019 +0300
- Parent:
- 12:9e3de2ece9c4
- Child:
- 14:b2e4b71a9980
- Commit message:
- Code for evaluating Max3266x Heart Rate from Wrist Agorithm
Changed in this revision
--- a/SHMAX8614X/HostAccelHelper.cpp Thu Jan 03 09:48:12 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-/*******************************************************************************
- * 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;
-}
-
-
--- a/SHMAX8614X/HostAccelHelper.h Thu Jan 03 09:48:12 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/*******************************************************************************
- * 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
--- a/SHMAX8614X/SH_Max8614x_BareMetal.cpp Thu Jan 03 09:48:12 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,547 +0,0 @@
-/*******************************************************************************
- * 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>
-
-uint16_t HrmResult = 0;
-uint16_t SPO2Result = 0;
-uint8_t HrmConfidence = 0;
-uint8_t SPo2Confidence = 0;
-
-
-
-#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];
-
- //printf("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;
- //printf("hr_c=%d\r\n", HrmResult);
-#if defined(DEBUG_INFO)
- printf("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)
- printf("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];
- //printf("x:%d, y:%d, z:%d\r\n", sample.x, sample.y, sample.z);
-}
-
-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);
-
- // feed accelerometer into me11
- CSTMR_SH_FeedAccDataIntoSH(p_glbl_max8614x_status_track);
-
- if(num_samples) {
- //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;
- }
- }
- }
- }
- }
- return num_samples;
-}
-
-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_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(15);
- 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();
-}
-
-
--- a/SHMAX8614X/SH_Max8614x_BareMetal.h Thu Jan 03 09:48:12 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-/*******************************************************************************
- * 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>
-
-#define COMM_SUCCESS 0
-#define COMM_GENERAL_ERROR -1
-#define COMM_INVALID_PARAM -254
-#define COMM_NOT_RECOGNIZED -255
-
-enum enAlgoMode{
- kAlgoModeHeartRate = 0,
- kAlgoModeSPO2
-};
-
-/**
- * @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);
-
-
-extern uint16_t HrmResult;
-extern uint16_t SPO2Result;
-extern uint8_t HrmConfidence;
-extern uint8_t SPo2Confidence;
-
-/* define to see debug messages*/
-#define DEBUG_INFO
-
-
-
-#endif
-
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SHMAX8614X_WHRM/HostAccelHelper.cpp Thu Jan 10 11:06:01 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 "../SHMAX8614X_WHRM/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_WHRM/HostAccelHelper.h Thu Jan 10 11:06:01 2019 +0300
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * 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_WHRM/SH_Max8614x_WHRM.cpp Thu Jan 10 11:06:01 2019 +0300
@@ -0,0 +1,500 @@
+/*******************************************************************************
+ * 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_WHRM.h"
+
+#include "SHComm.h"
+#include <string.h> //for memset
+#include <stdint.h>
+#include "HostAccelHelper.h"
+
+
+#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 SSACCEL_MODE1_DATASIZE 6 //Taken from API doc
+
+
+#define MIN_MACRO(a,b) ((a)<(b)?(a):(b))
+
+// sensor configuration
+//#define ENABLE_SENSOR_HUB_ACCEL
+#define USE_HOST_ACCEL
+
+// end of senor and algorithm configuration
+#define MAX_NUM_WR_ACC_SAMPLES 5
+#define BMI160_SAMPLE_RATE 25
+// end of defines
+
+
+uint16_t HrmResult = 0;
+uint8_t HrmConfidence = 0;
+
+
+//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 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];
+
+ //printf("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;
+ //printf("hr_c=%d\r\n", HrmResult);
+#if defined(DEBUG_INFO)
+ printf("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 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)
+ //printf("x:%d, y:%d, z:%d\r\n", sample.x, sample.y, sample.z);
+#endif
+}
+
+
+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;
+ // 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;
+
+}
+
+
+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;
+}
+
+int SH_Max8614x_whrm_init(void) {
+
+
+ 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]) {
+ __DBGMESSAGE("\r\n Algo already enabled\r\n",NULL)
+ return -1;
+ }
+
+ 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;
+
+
+}
+
+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_whrm_init();
+ 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();
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SHMAX8614X_WHRM/SH_Max8614x_WHRM.h Thu Jan 10 11:06:01 2019 +0300
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * 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_WHRM_H_
+#define SH_Max8614x_WHRM_H_
+
+#include <stdint.h>
+#include <stdio.h>
+
+#define COMM_SUCCESS 0
+#define COMM_GENERAL_ERROR -1
+#define COMM_INVALID_PARAM -254
+#define COMM_NOT_RECOGNIZED -255
+
+enum enAlgoMode{
+ kAlgoModeHeartRate = 0,
+ kAlgoModeHeartRateReinit = 1
+};
+
+/**
+ * @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);
+
+
+extern uint16_t HrmResult;
+extern uint8_t HrmConfidence;
+
+
+/* define to see debug messages*/
+#define DEBUG_INFO
+
+
+
+
+
+#endif
+
+
--- a/demoUI.lib Thu Jan 03 09:48:12 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -https://os.mbed.com/users/gmehmet/code/demoUI/#195eea2324de
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/demoUI/screen/BufferedDisplay.cpp Thu Jan 10 11:06:01 2019 +0300
@@ -0,0 +1,139 @@
+/***************************************************************************//**
+ * @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 Thu Jan 10 11:06:01 2019 +0300
@@ -0,0 +1,81 @@
+/***************************************************************************//**
+ * @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 Thu Jan 10 11:06:01 2019 +0300
@@ -0,0 +1,456 @@
+/* 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 Thu Jan 10 11:06:01 2019 +0300
@@ -0,0 +1,68 @@
+/* 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 Thu Jan 10 11:06:01 2019 +0300 @@ -0,0 +1,29 @@ +#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 Thu Jan 10 11:06:01 2019 +0300
@@ -0,0 +1,245 @@
+/***************************************************************************//**
+ * @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 Thu Jan 10 11:06:01 2019 +0300
@@ -0,0 +1,123 @@
+/***************************************************************************//**
+ * @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 Thu Jan 10 11:06:01 2019 +0300
@@ -0,0 +1,93 @@
+/* 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 Thu Jan 10 11:06:01 2019 +0300
@@ -0,0 +1,92 @@
+/* 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/demoUI/whrmDemoUI.cpp Thu Jan 10 11:06:01 2019 +0300
@@ -0,0 +1,336 @@
+
+
+/*
+ * 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 "screen/LS013B7DH03.h"
+#include "whrmDemoUI.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;
+
+ 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)
+{
+
+
+ //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_REINITWHRM:
+ /* Displays nothing, just for supply reinit state chang in main loop */
+ break;
+
+ }
+#if defined(USE_BIGFONT)
+ demoUIDEV->display->locate(10,42);
+#else
+ demoUIDEV->display->locate(2,6);
+#endif
+ 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_REINITWHRM;
+}
+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){
+ demoUI_display_algo_estimations_(&demoUIDEV,integer);
+ 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);
+}
+
+
+
+
+
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/demoUI/whrmDemoUI.h Thu Jan 10 11:06:01 2019 +0300
@@ -0,0 +1,45 @@
+/*
+ * demoUI.h
+ *
+ * Created on: Nov 29, 2018
+ * Author: Yagmur.Gok
+ */
+
+#ifndef SOURCE_DEMOUI_WHRMDEMOUI_H_
+#define SOURCE_DEMOUI_WHRMDEMOUI_H_
+
+#include <events/mbed_events.h>
+#include <mbed.h>
+
+#include "screen/LS013B7DH03.h"
+
+enum{
+ DISPLAY_WHRM = 0,
+ DISPLAY_REINITWHRM = 1
+};
+
+#define USE_DEMO_DISPDEV
+#if defined(USE_DEMO_DISPDEV)
+
+
+ void demoUI_init();
+ void demoUI_display_algo_estimations(int integer);
+ void demoUI_display_set_algoMode(int algo);
+ int demoUI_display_get_mode(void);
+ void demoUI_display(int algoResult);
+
+
+
+#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_WHRMDEMOUI_H_ */
--- a/main.cpp Thu Jan 03 09:48:12 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,208 +0,0 @@
-/*******************************************************************************
- * 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 "demoUI.h"
-
-
-extern uint16_t HrmResult;
-extern uint16_t SPO2Result;
-extern uint8_t HrmConfidence;
-extern uint8_t SPo2Confidence;
-
-DigitalOut led1(LED1, 1);
-// Hardware serial port over DAPLink
-Serial daplink(USBTX, USBRX, 115200);
-// 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;
-
-int main() {
-
- wait_ms(WAIT_SENSORHUB_STABLE_BOOTUP_MS);
- //demoUI_display_set_algoMode(kAlgoModeHeartRate);
-
- demoUI_init();
-
- sh_init_hwcomm_interface();
- sh_disable_irq_mfioevent();
- sh_clear_mfio_event_flag();
- sh_enable_irq_mfioevent();
- int i = 0;
-
-#if 1
-
- int displayMode;
- uint16_t resultToDisplay;
- uint8_t confidenceToDisplay;
-
- while(1) {
-
- displayMode = demoUI_display_get_mode();
-
- if( displayMode == kAlgoModeHeartRate ){
- if( !isWhrmInitialized){
-#if defined(DEBUG_INFO)
- printf(" WHRM inititalized \r\n");
-#endif
- SH_Max8614x_stop();
- SH_Max8614x_default_init(kAlgoModeHeartRate);
- isWhrmInitialized = true;
- isSpo2Initialized = false;
- wait_ms(1000); /* for display screen*/
- }
- resultToDisplay = HrmResult;
- confidenceToDisplay = HrmConfidence;
-
- }else{
- if( !isSpo2Initialized){
-#if defined(DEBUG_INFO)
- printf(" WSPo2 inititalized \r\n");
-#endif
- SH_Max8614x_stop();
- SH_Max8614x_default_init(kAlgoModeSPO2);
- isWhrmInitialized = false;
- isSpo2Initialized = true;
- wait_ms(1000); /* for display screen*/
- }
- resultToDisplay = SPO2Result;
- confidenceToDisplay = SPo2Confidence;
- }
-
- int cumSampleCNt = SH_Max8614x_data_report_execute();
- if(cumSampleCNt){
-#if defined(DEBUG_INFO)
- printf("estimate: =%d conf: %d dispMode: %d \r\n", resultToDisplay , confidenceToDisplay, displayMode);
-#endif
- demoUI_display_algo_estimations(resultToDisplay);
- //printf(" Display Mode : %d \r\n", displayMode );
- }
-
-
-
- }
-
-
-
-
-
-#else
-
- while(1) {
- SH_Max8614x_default_init(kAlgoModeHeartRate);
-
- while(1){
- ++i;
- int cumSampleCNt = SH_Max8614x_data_report_execute();
- if(cumSampleCNt)
- printf("hr_cttt=%d %d\r\n", HrmResult , HrmConfidence);
- wait_ms(2);
- led1 = !led1;
- if(i == 24000) {
- break;
- }
- }
- i = 0;
- SH_Max8614x_stop();
- printf("Stopped\r\n");
- while(1){
- ++i;
- SH_Max8614x_data_report_execute();
- wait_ms(2);
- led1 = !led1;
- if(i == 4000) {
- break;
- }
- }
- i = 0;
- }
-#endif
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/whrmMain.cpp Thu Jan 10 11:06:01 2019 +0300
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * 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( WHRM) from sensor hub and display
+ * it on screen. Example starts by monitoring heart rate
+ * and reinits algorithm via two consecutive button presses (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
+ * 3. Parses buffer(1) data to extract numeric sensor and algorithm samples according to enabled algorithms.
+ * look: whrm_data_rx() , max8614x_data_rx() and sample structs whrm_mode1_data and max8614x_mode1_data
+ *
+ * 6. numeric values are written to HrmResult, 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 "bmi160.h"
+#include "whrmDemoUI.h"
+
+#include "SH_Max8614x_WHRM.h"
+
+
+extern uint16_t HrmResult;
+extern uint8_t HrmConfidence;
+
+
+DigitalOut led1(LED1, 1);
+// Hardware serial port over DAPLink
+Serial daplink(USBTX, USBRX, 115200);
+// 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;
+
+
+int main() {
+
+ wait_ms(WAIT_SENSORHUB_STABLE_BOOTUP_MS);
+ 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) {
+
+ displayMode = demoUI_display_get_mode();
+
+ if( displayMode == kAlgoModeHeartRate ){
+ if( !isWhrmInitialized){
+#if defined(DEBUG_INFO)
+ printf(" WHRM inititalized \r\n");
+#endif
+ SH_Max8614x_stop();
+ SH_Max8614x_default_init(kAlgoModeHeartRate);
+ isWhrmInitialized = true;
+ wait_ms(1000); /* for display screen*/
+ }
+ resultToDisplay = HrmResult;
+ confidenceToDisplay = HrmConfidence;
+
+ }else{
+
+ demoUI_display_set_algoMode(kAlgoModeHeartRate);
+ isWhrmInitialized = false;
+ }
+
+ int cumSampleCNt = SH_Max8614x_data_report_execute();
+ if(cumSampleCNt){
+#if defined(DEBUG_INFO)
+ printf("estimate: =%d conf: %d dispMode: %d \r\n", resultToDisplay , confidenceToDisplay, displayMode);
+#endif
+ demoUI_display_algo_estimations(resultToDisplay);
+
+ }
+
+
+
+ }
+
+}

Health Sensor Board Embedded Heart Rate Algorithm Sensor Hub + ECG, Wearables Ev Kit MAXREFDES101#