test
Dependencies: BMI160 max32630hsp3 MemoryLCD USBDevice
SH_Max8614x_BareMetal.cpp
00001 /******************************************************************************* 00002 * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 * OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * Except as contained in this notice, the name of Maxim Integrated 00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 * Products, Inc. Branding Policy. 00025 * 00026 * The mere transfer of this software does not imply any licenses 00027 * of trade secrets, proprietary technology, copyrights, patents, 00028 * trademarks, maskwork rights, or any other form of intellectual 00029 * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 * ownership rights. 00031 ******************************************************************************* 00032 */ 00033 #include "SH_Max8614x_BareMetal.h" 00034 #include "SHComm.h" 00035 #include "HostAccelHelper.h" 00036 #include <string.h> //for memset 00037 #include <stdint.h> 00038 00039 #include "demoDefinitions.h" 00040 00041 /* Do not warn sign/unsigned miss alignment*/ 00042 //#pragma warning (disable : 4018 ) 00043 00044 uint16_t HrmResult = 0; 00045 uint8_t HrmConfidence = 0; 00046 00047 //#define SERIALOUT printf 00048 #define DEBUG_INFO 00049 00050 #if defined(DEBUG_INFO) 00051 #define __DBGMESSAGE( str , val ) {printf(str, val);} 00052 #else 00053 #define __DBGMESSAGE( str , val ) 00054 #endif 00055 00056 00057 // Defines 00058 #define SSMAX8614X_REG_SIZE 1 00059 #define SSMAX8614X_MODE1_DATASIZE 18 //Taken from API doc 00060 #define SSWHRM_MODE1_DATASIZE 6 //Taken from API doc 00061 #define SSACCEL_MODE1_DATASIZE 6 //Taken from API doc 00062 #define SSAGC_MODE1_DATASIZE 0 //Taken from API doc 00063 #define SSBPT_MODE1_2_DATASIZE 4 //Taken from API doc /* TODO */ 00064 00065 #define MIN_MACRO(a,b) ((a)<(b)?(a):(b)) 00066 00067 // sensor configuration 00068 //#define ENABLE_SENSOR_HUB_ACCEL 00069 #define USE_HOST_ACCEL 00070 // end of senor and algorithm configuration 00071 #define MAX_NUM_WR_ACC_SAMPLES 5 00072 #define BMI160_SAMPLE_RATE 25 00073 // end of defines 00074 00075 //function pointer use to perform arithmetic operation 00076 typedef void (*rx_data_callback)(uint8_t *); 00077 typedef struct { 00078 int data_size; 00079 rx_data_callback rx_data_parser; 00080 } ss_data_req; 00081 00082 typedef struct { 00083 int16_t x; 00084 int16_t y; 00085 int16_t z; 00086 } accel_mode1_data; 00087 00088 typedef struct { 00089 uint32_t led1; 00090 uint32_t led2; 00091 uint32_t led3; 00092 uint32_t led4; 00093 uint32_t led5; 00094 uint32_t led6; 00095 } max8614x_mode1_data; 00096 00097 typedef struct { 00098 uint16_t hr; 00099 uint8_t hr_conf; 00100 uint16_t RESERVED; 00101 uint8_t status; 00102 } whrm_mode1_data; 00103 00104 00105 typedef struct Max86140_SH_Status_Tracker { 00106 uint8_t sensor_data_from_host; 00107 uint8_t data_type_enabled; // what type of data is enabled 00108 uint8_t sample_count_enabled; // does me11 provide sample count 00109 uint32_t sample_count; 00110 uint8_t data_buf_storage[512]; // store data read from SH 00111 ss_data_req algo_callbacks[SH_NUM_CURRENT_ALGOS]; 00112 ss_data_req sensor_callbacks[SH_NUM_CURRENT_SENSORS]; 00113 uint8_t sensor_enabled_mode[SH_NUM_CURRENT_SENSORS]; 00114 uint8_t algo_enabled_mode[SH_NUM_CURRENT_ALGOS]; 00115 int input_fifo_size; 00116 } Max86140_SH_Status_Tracker_t; 00117 00118 // Max8614x Default Callbacks 00119 void max8614x_data_rx(uint8_t* data_ptr) 00120 { 00121 max8614x_mode1_data sample; 00122 sample.led1 = (data_ptr[0] << 16) | (data_ptr[1] << 8) | data_ptr[2]; 00123 sample.led2 = (data_ptr[3] << 16) | (data_ptr[4] << 8) | data_ptr[5]; 00124 sample.led3 = (data_ptr[6] << 16) | (data_ptr[7] << 8) | data_ptr[8]; 00125 sample.led4 = (data_ptr[9] << 16) | (data_ptr[10] << 8) | data_ptr[11]; 00126 sample.led5 = (data_ptr[12] << 16) | (data_ptr[13] << 8) | data_ptr[14]; 00127 sample.led6 = (data_ptr[15] << 16) | (data_ptr[16] << 8) | data_ptr[17]; 00128 00129 //SERIALOUT("led1=%.6X led2=%.6X led3=%.6X led4=%.6X led5=%.6X led6=%.6X\r\n", 00130 // sample.led1, sample.led2, sample.led3, sample.led4, sample.led5, sample.led6); 00131 00132 //enqueue(&max8614x_queue, &sample); 00133 } 00134 void whrm_data_rx(uint8_t* data_ptr) { 00135 //See API doc for data format 00136 whrm_mode1_data sample; 00137 sample.hr = (data_ptr[0] << 8) | data_ptr[1]; 00138 sample.hr_conf = data_ptr[2]; 00139 sample.RESERVED = (data_ptr[3] << 8) | data_ptr[4]; 00140 sample.status = data_ptr[5]; 00141 HrmResult = sample.hr / 10; 00142 HrmConfidence = sample.hr_conf; 00143 SERIALOUT("hr_c=%d\r\n", HrmResult); 00144 #if defined(DEBUG_INFO) 00145 SERIALOUT("hr=%.1f conf=%d status=%d\r\n", (float)sample.hr / 10.0, sample.hr_conf, sample.status); 00146 #endif 00147 //enqueue(&whrm_queue, &sample); 00148 } 00149 00150 void accel_data_rx(uint8_t* data_ptr) { 00151 //See API doc for data format 00152 accel_mode1_data sample; 00153 sample.x = (data_ptr[0] << 8) | data_ptr[1]; 00154 sample.y = (data_ptr[2] << 8) | data_ptr[3]; 00155 sample.z = (data_ptr[4] << 8) | data_ptr[5]; 00156 #if defined(DEBUG_INFO) 00157 //SERIALOUT("x:%d, y:%d, z:%d\r\n", sample.x, sample.y, sample.z); 00158 #endif 00159 } 00160 00161 void agc_data_rx(uint8_t* data_ptr) { 00162 //NOP: AGC does not collect data 00163 } 00164 // end of Max8614x Default Callbacks 00165 00166 00167 static Max86140_SH_Status_Tracker * get_config_struct() { 00168 00169 /* assigns a static adress to configuration struct*/ 00170 static Max86140_SH_Status_Tracker glbl_max8614x_status_track; 00171 return &glbl_max8614x_status_track; 00172 } 00173 00174 void initialize_config_struct() { 00175 Max86140_SH_Status_Tracker *p_glbl_max8614x_status_track = get_config_struct(); 00176 /* 00177 * Desc: Configuration init flow, Perform this action at init stage of data acquisition. Raw sesnsor data buffer pointer is input to each 00178 * enabled sensor/algorithm,s funtion that is responsible to extract numeric data from data byte stream from sensor hub. 00179 * 00180 * - Append Sensor Raw Data structure with raw sensor data sample size and pointer to function of sensor that is reposible to parse 00181 * data byte stream from sesnor hub and extract sensor numeric data. 00182 * - Append accompanying sensors to main state of sensor. ie Accelerometer from Host with sensor data sample size and pointer to function of 00183 * sensor that is reposible to parse data byte stream from sesnor hub and extract sensor numeric data. 00184 * - Append algorithms to be enabled with algorithm data sample size and pointer to function of 00185 * algorithm that is reposible to parse data byte stream from sensor hub and extract sensor numeric data. 00186 * 00187 * */ 00188 00189 //set all the values to 0 00190 memset(p_glbl_max8614x_status_track, 0, sizeof(*p_glbl_max8614x_status_track)); 00191 // max8614x 00192 p_glbl_max8614x_status_track->sensor_callbacks[SH_SENSORIDX_MAX8614X].data_size = SSMAX8614X_MODE1_DATASIZE; 00193 p_glbl_max8614x_status_track->sensor_callbacks[SH_SENSORIDX_MAX8614X].rx_data_parser = &max8614x_data_rx; 00194 // accelerometer 00195 p_glbl_max8614x_status_track->sensor_callbacks[SH_SENSORIDX_ACCEL].data_size = SSACCEL_MODE1_DATASIZE; 00196 p_glbl_max8614x_status_track->sensor_callbacks[SH_SENSORIDX_ACCEL].rx_data_parser = &accel_data_rx; 00197 // whrm NOTE: do not register aec and scd as they do not have data reporter callbacks and defined within WHRM suite. Look at 8614c command table for aec/scd on/off !!!! 00198 p_glbl_max8614x_status_track->algo_callbacks[SH_ALGOIDX_WHRM].data_size = SSWHRM_MODE1_DATASIZE; 00199 p_glbl_max8614x_status_track->algo_callbacks[SH_ALGOIDX_WHRM].rx_data_parser = &whrm_data_rx; 00200 00201 } 00202 00203 00204 void SH_Max8614x_get_reg(uint8_t addr, uint32_t *val) { 00205 int status = sh_get_reg(SH_SENSORIDX_MAX8614X, addr, val); 00206 00207 if (status == 0) { 00208 __DBGMESSAGE("\r\n reg_val=%02X err=0 \r\n", ((uint8_t)*val)) 00209 } else { 00210 __DBGMESSAGE("\r\n err=%d\r\n", -1) 00211 } 00212 00213 return; 00214 } 00215 00216 int CSTMR_SH_FeedAccDataIntoSH(Max86140_SH_Status_Tracker_t *p_max8614x_status_track) { 00217 static accel_data_t peek_buf[MAX_NUM_WR_ACC_SAMPLES]; 00218 static uint8_t tx_buf[MAX_NUM_WR_ACC_SAMPLES * sizeof(accel_mode1_data) + 2]; // 2 bytes for the command 00219 if(!p_max8614x_status_track->sensor_data_from_host) { 00220 return -1; 00221 } else { 00222 accel_data_t accel_data = {0}; 00223 accel_mode1_data acc_sample; 00224 int num_tx, num_samples, num_bytes = 0, num_wr_bytes = 0; 00225 int num_written_samples, nb_expected; 00226 int ret = 0; 00227 00228 // get accelerometer data 00229 ret = CSTMR_SH_HostAccelerometerGet_sensor_xyz(&accel_data); 00230 if (ret < 0) 00231 return ret; 00232 00233 if(CSTMR_SH_HostAccelerometerEnqueueData(&accel_data) != 0) { 00234 __DBGMESSAGE("Thrown an accel sample\n", NULL) 00235 } 00236 00237 if(CSTMR_SH_HostAccelerometerGetDataCount() < MAX_NUM_WR_ACC_SAMPLES) { 00238 return -1; 00239 } 00240 00241 ret = sh_get_num_bytes_in_input_fifo(&num_bytes); 00242 if (ret != 0) { 00243 __DBGMESSAGE("Unable to read num bytes in input fifo\r\n", NULL) 00244 return -1; 00245 } 00246 num_tx = p_max8614x_status_track->input_fifo_size - num_bytes; 00247 if (num_tx <= 0) { 00248 __DBGMESSAGE("num_tx can't be negative\r\n",NULL) 00249 return -1; 00250 } 00251 num_samples = num_tx / sizeof(accel_mode1_data); 00252 num_samples = MIN_MACRO(num_samples, MAX_NUM_WR_ACC_SAMPLES); 00253 num_tx = num_samples * sizeof(accel_mode1_data); 00254 if (num_samples == 0) { 00255 __DBGMESSAGE("Input FIFO is Full\r\n",NULL) 00256 return -1; 00257 } 00258 00259 for(int i = 0; i < num_samples; ++i) { 00260 ret |= CSTMR_SH_HostAccelerometerDequeuData(&peek_buf[i]); 00261 } 00262 if (ret != 0) { 00263 __DBGMESSAGE("CSTMR_SH_HostAccelerometerDequeuData failed\r\n",NULL) 00264 return -1; 00265 } 00266 00267 00268 for (int i = 2, j = 0; j < num_samples; i+= sizeof(accel_mode1_data), j++) { 00269 accel_data = peek_buf[j]; 00270 acc_sample.x = (int16_t)(accel_data.x*1000); 00271 acc_sample.y = (int16_t)(accel_data.y*1000); 00272 acc_sample.z = (int16_t)(accel_data.z*1000); 00273 tx_buf[i] = acc_sample.x; 00274 tx_buf[i + 1] = acc_sample.x >> 8; 00275 tx_buf[i + 2] = acc_sample.y; 00276 tx_buf[i + 3] = acc_sample.y >> 8; 00277 tx_buf[i + 4] = acc_sample.z; 00278 tx_buf[i + 5] = acc_sample.z >> 8; 00279 00280 } 00281 00282 ret = sh_feed_to_input_fifo(tx_buf, num_tx + 2, &num_wr_bytes); 00283 if(ret != 0) { 00284 __DBGMESSAGE("sh_feed_to_input_fifo\r\n",NULL) 00285 return -1; 00286 } 00287 num_written_samples = num_wr_bytes / sizeof(accel_mode1_data); 00288 if(num_written_samples != num_samples) { 00289 __DBGMESSAGE("num_written_samples failed\r\n",NULL) 00290 return -1; 00291 } 00292 } 00293 return 0; 00294 } 00295 00296 00297 void SH_Max8614x_set_reg(uint8_t addr, uint32_t val) { 00298 int status; 00299 status = sh_set_reg(SH_SENSORIDX_MAX8614X, addr, val, SSMAX8614X_REG_SIZE); 00300 __DBGMESSAGE("\r\n err=%d\r\n", status); 00301 } 00302 00303 00304 00305 int SH_Max8614x_data_report_execute(void) { 00306 00307 int num_samples, databufLen; 00308 uint8_t *databuf; 00309 00310 00311 Max86140_SH_Status_Tracker_t *p_glbl_max8614x_status_track = get_config_struct(); 00312 00313 // prepare the buffer to store the results 00314 databuf = p_glbl_max8614x_status_track->data_buf_storage; 00315 databufLen = sizeof(p_glbl_max8614x_status_track->data_buf_storage); 00316 00317 // poll SH 00318 sh_ss_execute_once(databuf, databufLen, &num_samples); 00319 //__DBGMESSAGE( "nsamplesFIFO: %d \r\n" , num_samples) 00320 00321 if(num_samples > 0 && num_samples <255) { 00322 //Skip status byte 00323 uint8_t *data_ptr = &databuf[1]; 00324 00325 int i = 0; 00326 for (i = 0; i < num_samples; i++) { 00327 int sh_data_type = p_glbl_max8614x_status_track->data_type_enabled; 00328 if (p_glbl_max8614x_status_track->sample_count_enabled) { 00329 p_glbl_max8614x_status_track->sample_count = *data_ptr++; 00330 } 00331 //Chop up data and send to modules with enabled sensors 00332 if (sh_data_type == SS_DATATYPE_RAW || sh_data_type == SS_DATATYPE_BOTH) { 00333 for (int i = 0; i < SH_NUM_CURRENT_SENSORS; i++) { 00334 if (p_glbl_max8614x_status_track->sensor_enabled_mode[i]) { 00335 p_glbl_max8614x_status_track->sensor_callbacks[i].rx_data_parser(data_ptr); 00336 data_ptr += p_glbl_max8614x_status_track->sensor_callbacks[i].data_size; 00337 } 00338 } 00339 } 00340 if (sh_data_type == SS_DATATYPE_ALGO || sh_data_type == SS_DATATYPE_BOTH) { 00341 for (int i = 0; i < SH_NUM_CURRENT_ALGOS; i++) { 00342 if (p_glbl_max8614x_status_track->algo_enabled_mode[i]) { 00343 p_glbl_max8614x_status_track->algo_callbacks[i].rx_data_parser(data_ptr); 00344 data_ptr += p_glbl_max8614x_status_track->algo_callbacks[i].data_size; 00345 } 00346 } 00347 } 00348 } 00349 /* JUST*/ 00350 CSTMR_SH_FeedAccDataIntoSH(p_glbl_max8614x_status_track); 00351 } 00352 // feed accelerometer into me11 00353 //////////////////CSTMR_SH_FeedAccDataIntoSH(p_glbl_max8614x_status_track); 00354 00355 00356 return num_samples; 00357 } 00358 00359 int SH_Max8614x_algo_init(enum enAlgoMode paramAlgoMode) { 00360 00361 /* 00362 * 00363 * */ 00364 int status; 00365 Max86140_SH_Status_Tracker_t *p_glbl_max8614x_status_track = get_config_struct(); 00366 if(p_glbl_max8614x_status_track->algo_enabled_mode[SH_ALGOIDX_WHRM]) { 00367 __DBGMESSAGE("\r\n Algo already enabled\r\n",NULL) 00368 return -1; 00369 } 00370 00371 if(paramAlgoMode == kAlgoModeHeartRate) { 00372 status = sh_enable_algo(SH_ALGOIDX_WHRM, SSWHRM_MODE1_DATASIZE); 00373 if (status != SS_SUCCESS) { 00374 __DBGMESSAGE("\r\n err=%d\r\n", COMM_GENERAL_ERROR) 00375 __DBGMESSAGE("FAILED at line %d, enable whrm\n", __LINE__) 00376 return status; 00377 } 00378 p_glbl_max8614x_status_track->algo_enabled_mode[SH_ALGOIDX_WHRM] = 0x01; 00379 } 00380 } 00381 00382 00383 00384 int SH_Max8614x_default_init(enum enAlgoMode paramAlgoMode) { 00385 /* 00386 * Desc: Initialization flow to get algorithm estimation results: 00387 * 1. initialize algorithm config struct 00388 * 2. enable data type to both raw sensor and algorithm data 00389 * 3. get input fifo size to learn fifo capacity 00390 * 4. set fifo threshold for mfio event frequency 00391 * 5. enable sensor to acquire ppg data 00392 * 6. enable accompanying accel sensor 00393 * 7. enable algorithm 00394 * 8. Sensor Hub now starts to write raw sensor/algorithm data to its data report FIFO which 00395 * reports mfio event when data size determined by fifo threshold is written to report fifo 00396 * data can be read by SH_Max8614x_data_report_execute function. 00397 * 00398 * */ 00399 00400 int status; 00401 00402 // first initialize the global config struct 00403 initialize_config_struct(); 00404 Max86140_SH_Status_Tracker_t *p_glbl_max8614x_status_track = get_config_struct(); 00405 00406 // get input fifo size 00407 status = sh_get_input_fifo_size(&p_glbl_max8614x_status_track->input_fifo_size); 00408 if (status != SS_SUCCESS) { 00409 __DBGMESSAGE("\r\n err=%d\r\n", COMM_GENERAL_ERROR) 00410 __DBGMESSAGE("FAILED at line %d\n", __LINE__) 00411 return COMM_GENERAL_ERROR;; 00412 } 00413 00414 // enable both data stype 00415 p_glbl_max8614x_status_track->data_type_enabled = SS_DATATYPE_BOTH; 00416 p_glbl_max8614x_status_track->sample_count_enabled = false; 00417 status = sh_set_data_type(p_glbl_max8614x_status_track->data_type_enabled, 00418 p_glbl_max8614x_status_track->sample_count_enabled); 00419 if (status != 0) { 00420 __DBGMESSAGE("\r\n err=%d\r\n", COMM_GENERAL_ERROR) 00421 __DBGMESSAGE("FAILED at line %d\n", __LINE__) 00422 return COMM_GENERAL_ERROR; 00423 } 00424 00425 status = sh_set_fifo_thresh(5); 00426 if (status != 0) { 00427 __DBGMESSAGE("\r\n err=%d\r\n", COMM_GENERAL_ERROR) 00428 __DBGMESSAGE("FAILED at line %d\n", __LINE__) 00429 return COMM_GENERAL_ERROR; 00430 } 00431 00432 00433 00434 status = sh_sensor_enable(SH_SENSORIDX_MAX8614X, SSMAX8614X_MODE1_DATASIZE, SH_INPUT_DATA_DIRECT_SENSOR); 00435 if (status != 0) { 00436 __DBGMESSAGE("\r\n err=%d\r\n", COMM_GENERAL_ERROR) 00437 __DBGMESSAGE("FAILED at line %d\n", __LINE__) 00438 return COMM_GENERAL_ERROR; 00439 } 00440 p_glbl_max8614x_status_track->sensor_enabled_mode[SH_SENSORIDX_MAX8614X] = 0x01; 00441 00442 #ifdef ENABLE_SENSOR_HUB_ACCEL 00443 status = sh_sensor_enable(SH_SENSORIDX_ACCEL, SSACCEL_MODE1_DATASIZE, SH_INPUT_DATA_DIRECT_SENSOR); 00444 if (status != SS_SUCCESS) { 00445 __DBGMESSAGE("\r\n err=%d\r\n", COMM_GENERAL_ERROR) 00446 __DBGMESSAGE("FAILED at line %d\n", __LINE__) 00447 } 00448 p_glbl_max8614x_status_track->sensor_data_from_host = false; 00449 p_glbl_max8614x_status_track->sensor_enabled_mode[SH_SENSORIDX_ACCEL] = 0x01; 00450 #elif defined(USE_HOST_ACCEL) 00451 CSTMR_SH_HostAccelerometerInitialize(); 00452 CSTMR_SH_HostAccelerometerSetDefaults(); 00453 status = CSTMR_SH_HostAccelerometerSetSampleRate(BMI160_SAMPLE_RATE); 00454 if (status != 0) { 00455 __DBGMESSAGE("Unable to set BMI160's sample rate\n",NULL) 00456 __DBGMESSAGE("\r\n err=%d\r\n", COMM_GENERAL_ERROR) 00457 __DBGMESSAGE("FAILED at line %d\n", __LINE__) 00458 return status; 00459 } 00460 00461 status = CSTMR_SH_HostAccelerometerEnableDataReadyInterrupt(); 00462 if(status != 0){ 00463 __DBGMESSAGE("Unable to enable BMI160 Interrupt, ret: %d\n", status) 00464 return status; 00465 } 00466 00467 status = sh_sensor_enable(SH_SENSORIDX_ACCEL, SSACCEL_MODE1_DATASIZE, SH_INPUT_DATA_FROM_HOST); 00468 if (status != 0) { 00469 __DBGMESSAGE("\r\n err=%d\r\n", COMM_GENERAL_ERROR) 00470 __DBGMESSAGE("FAILED at line %d\n", __LINE__) 00471 return status; 00472 } 00473 p_glbl_max8614x_status_track->sensor_data_from_host = true; 00474 p_glbl_max8614x_status_track->sensor_enabled_mode[SH_SENSORIDX_ACCEL] = 0x01; 00475 #endif 00476 status = SH_Max8614x_algo_init(paramAlgoMode); 00477 if(status != 0) { 00478 __DBGMESSAGE("AlgoInitFailed\r\n",NULL) 00479 } 00480 00481 __DBGMESSAGE("\r\n err=%d\r\n", status) 00482 return status; 00483 } 00484 00485 void SH_Max8614x_stop() { 00486 00487 sh_disable_irq_mfioevent(); 00488 Max86140_SH_Status_Tracker_t *p_glbl_max8614x_status_track = get_config_struct(); 00489 00490 for(int i = 0; i < SH_NUM_CURRENT_SENSORS; ++i) { 00491 if(p_glbl_max8614x_status_track->sensor_enabled_mode[i]) { 00492 p_glbl_max8614x_status_track->sensor_enabled_mode[i] = 0; 00493 sh_sensor_disable(i); 00494 } 00495 00496 } 00497 00498 for(int i = 0; i < SH_NUM_CURRENT_ALGOS; ++i) { 00499 if(p_glbl_max8614x_status_track->algo_enabled_mode[i]) { 00500 p_glbl_max8614x_status_track->algo_enabled_mode[i] = 0; 00501 sh_disable_algo(i); 00502 } 00503 } 00504 00505 if(p_glbl_max8614x_status_track->sensor_data_from_host) { 00506 CSTMR_SH_HostAccelerometerInitialize(); 00507 p_glbl_max8614x_status_track->sensor_data_from_host = 0; 00508 } 00509 00510 sh_clear_mfio_event_flag(); 00511 sh_enable_irq_mfioevent(); 00512 } 00513 00514 00515 00516 00517 00518 00519 /* ********************************************************************************************** 00520 * * 00521 * COMMAND INTERFACE RELATED METHODS * 00522 * * 00523 * **********************************************************************************************/ 00524 00525 00526 00527 //MYG: CHECK FOR STDIN WITH SSCANF < WHY THEY NEEDED PARSE_CMD????? PAY ATTENTION: HEX AND/OR DECIMAL PARAMETER ENRTY!!! 00528 00529 00530 static int SH_Max8614x_set_singleparamcfg_(const char *cfg , const int algo_idx, const int cfg_idx , const int paramsz){ 00531 int status = -1; 00532 uint32_t val; 00533 if(paramsz == 1 || paramsz == 2) { 00534 if( sscanf(cfg, "%*s %*s %*s %10x", &val) == 1 ){ 00535 uint8_t Temp[2] = { (uint8_t)((val >> 8) & 0xFF), (uint8_t) (val & 0xFF) }; 00536 status = sh_set_algo_cfg(algo_idx, cfg_idx , &Temp[2-paramsz], paramsz); 00537 } 00538 } 00539 return status; // if command error return -1 if operational error return >0 error 00540 } 00541 00542 00543 static int SH_Max8614x_get_singleparamcfg_( const int algo_idx, const int cfg_idx ,const int paramsz, int *val){ 00544 // CMD: get_cfg spo2 samplerate 00545 00546 int tmp; 00547 int status = -1; 00548 uint8_t rxBuff[3]; // first byte is status 1/2 bytes cfgparam asked for. 00549 if(paramsz == 1 || paramsz == 2) { 00550 status = sh_get_algo_cfg(algo_idx, cfg_idx, &rxBuff[0], paramsz+1); 00551 if( status == 0){ 00552 tmp = (int)((rxBuff[1]<<(8*(paramsz-1))) + rxBuff[2]*(paramsz-1)); // MYG: CHECK IF TRUE! 00553 }else 00554 tmp = -1; 00555 }else 00556 tmp = -1; 00557 00558 *val = tmp; 00559 return status; 00560 } 00561 00562 00563 00564 00565 00566 int SH_Max8614x_set_ppgreg(const char *addr_value_args){ 00567 00568 //CMD: set_reg ppgsensor 0xAA 0xAA 00569 int addr,val,status; 00570 if( sscanf(addr_value_args,"%*s %*s %4x %10x", &addr , &addr ) == 2 ){ 00571 status = sh_set_reg(SH_SENSORIDX_MAX8614X, (uint8_t) addr, (uint32_t) val, SSMAX8614X_REG_SIZE); 00572 if(status == 0) 00573 SERIALOUT("OK \r\n"); 00574 }else 00575 SERIALOUT("ERR \r\n"); 00576 00577 return status; 00578 } 00579 00580 int SH_Max8614x_get_ppgreg(const char *addr_arg){ 00581 00582 //CMD: get_reg ppgsensor 0xAA 00583 int addr; 00584 int status = -1; 00585 uint32_t val; 00586 00587 if( sscanf(addr_arg,"%*s %*s %4x", &addr) == 1 ){ 00588 int status = sh_get_reg(SH_SENSORIDX_MAX8614X, (uint8_t) addr, &val); 00589 if(status == 0) 00590 SERIALOUT("reg_val=%02X \r\n",val); 00591 }else 00592 SERIALOUT("ERR \r\n"); 00593 00594 return status; 00595 } 00596 00597 int SH_Max8614x_self_test_ppg(const char *null_arg){ 00598 00599 // MYG: mfio interaction needed! 00600 return -1; 00601 } 00602 00603 int SH_Max8614x_self_test_acc(const char *null_arg){ 00604 // MYG: mfio interaction needed! 00605 return -1; 00606 } 00607 00608 //************************************WHRM METHODS***********************************************/ 00609 00610 int SH_Max8614x_get_whrm_dataformat(const char *null_arg){ 00611 00612 SERIALOUT("\r\n format={smpleCnt,16}," 00613 "{grnCnt,20},{grn2Cnt,20},{accelX,14,3},{accelY,14,3}," 00614 "{accelZ,14,3},{hr,12},{hrconf,8},{spo2,11,1},{activity,8} err=0\r\n" ); 00615 return 0; 00616 } 00617 00618 int SH_Max8614x_measure_whrm(const char *null_arg){ 00619 00620 int status; 00621 SH_Max8614x_stop(); 00622 status = SH_Max8614x_default_init(kAlgoModeHeartRate); 00623 if(status == 0) 00624 SERIALOUT("whrm started \r\n"); 00625 else 00626 SERIALOUT("ERR"); 00627 00628 return status; 00629 } 00630 00631 int SH_Max8614x_set_whrm_aecusage(const char *onoff_arg){ 00632 00633 int status = SH_Max8614x_set_singleparamcfg_( onoff_arg , SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_AEC_ENABLE , 1 ); 00634 if( status == 0) 00635 SERIALOUT("OK \r\n"); 00636 else { 00637 if( status == -1) 00638 SERIALOUT("CMDERR \r\n"); 00639 else 00640 SERIALOUT("ERR \r\n"); 00641 } 00642 return status; 00643 00644 } 00645 00646 int SH_Max8614x_get_whrm_aecusage(const char *null_arg){ 00647 00648 int val; 00649 int status = SH_Max8614x_get_singleparamcfg_( SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_AEC_ENABLE, 1 , &val); 00650 if(val != -1) 00651 SERIALOUT("whrm_aec_usage= %d", val); 00652 else 00653 SERIALOUT("ERR \r\n"); 00654 00655 return status; 00656 00657 } 00658 00659 int SH_Max8614x_set_whrm_scdusage(const char *onoff_arg){ 00660 00661 int status = SH_Max8614x_set_singleparamcfg_( onoff_arg , SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_SCD_ENABLE, 1 ); 00662 if( status == 0) 00663 SERIALOUT("OK \r\n"); 00664 else { 00665 if( status == -1) 00666 SERIALOUT("CMDERR \r\n"); 00667 else 00668 SERIALOUT("ERR \r\n"); 00669 } 00670 return status; 00671 00672 } 00673 00674 00675 int SH_Max8614x_get_whrm_scdusage(const char *null_arg){ 00676 00677 int val; 00678 int status = SH_Max8614x_get_singleparamcfg_( SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_SCD_ENABLE, 1 , &val); 00679 if(val != -1) 00680 SERIALOUT("whrm_scd_usage= %d", val); 00681 else 00682 SERIALOUT("ERR \r\n"); 00683 00684 return status; 00685 00686 } 00687 00688 int SH_Max8614x_set_whrm_scdadjperiod(const char *period_arg){ 00689 00690 int status = SH_Max8614x_set_singleparamcfg_(period_arg , SH_ALGOIDX_WHRM , SS_CFGIDX_WHRM_ADJ_TARGET_PD_CURRENT_PERIOD , 2); 00691 if( status == 0) 00692 SERIALOUT("OK \r\n"); 00693 else { 00694 if( status == -1) 00695 SERIALOUT("CMDERR \r\n"); 00696 else 00697 SERIALOUT("ERR \r\n"); 00698 } 00699 return status; 00700 } 00701 00702 int SH_Max8614x_get_whrm_scdadjperiod(const char *null_arg){ 00703 00704 int val; 00705 int status = SH_Max8614x_get_singleparamcfg_( SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_ADJ_TARGET_PD_CURRENT_PERIOD, 2, &val); 00706 if(val != -1) 00707 SERIALOUT("whrm_scd_adjperiod= 0x%x", val); 00708 else 00709 SERIALOUT("ERR \r\n"); 00710 00711 return status; 00712 00713 } 00714 00715 int SH_Max8614x_set_whrm_scddebouncewin(const char *dwindow_arg){ 00716 00717 int status = SH_Max8614x_set_singleparamcfg_(dwindow_arg , SH_ALGOIDX_WHRM , SS_CFGIDX_WHRM_SCD_DEBOUNCE_WINDOW , 2); 00718 if( status == 0) 00719 SERIALOUT("OK \r\n"); 00720 else { 00721 if( status == -1) 00722 SERIALOUT("CMDERR \r\n"); 00723 else 00724 SERIALOUT("ERR \r\n"); 00725 } 00726 return status; 00727 00728 } 00729 int SH_Max8614x_get_whrm_scddebouncewin(const char *null_arg){ 00730 00731 int val; 00732 int status = SH_Max8614x_get_singleparamcfg_( SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_SCD_DEBOUNCE_WINDOW , 2, &val); 00733 if(val != -1) 00734 SERIALOUT("whrm_scd_debouncewin= 0x%x", val); 00735 else 00736 SERIALOUT("ERR \r\n"); 00737 00738 return status; 00739 00740 } 00741 00742 int SH_Max8614x_set_whrm_motionthresh(const char *motion_arg){ 00743 00744 int status = SH_Max8614x_set_singleparamcfg_(motion_arg , SH_ALGOIDX_WHRM , SS_CFGIDX_WHRM_MOTION_MAG_THRESHOLD , 2); 00745 if( status == 0) 00746 SERIALOUT("OK \r\n"); 00747 else { 00748 if( status == -1) 00749 SERIALOUT("CMDERR \r\n"); 00750 else 00751 SERIALOUT("ERR \r\n"); 00752 } 00753 return status; 00754 00755 } 00756 00757 int SH_Max8614x_get_whrm_motionthresh(const char *null_arg){ 00758 00759 int val; 00760 int status = SH_Max8614x_get_singleparamcfg_( SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_MOTION_MAG_THRESHOLD , 2, &val); 00761 if(val != -1) 00762 SERIALOUT("whrm_motion_threshold= 0x%x", val); 00763 else 00764 SERIALOUT("ERR \r\n"); 00765 00766 return status; 00767 00768 } 00769 00770 int SH_Max8614x_set_whrm_minpdiodecurr(const char *curr_arg){ 00771 00772 int status = SH_Max8614x_set_singleparamcfg_(curr_arg, SH_ALGOIDX_WHRM , SS_CFGIDX_WHRM_MIN_PD_CURRENT , 2); 00773 if( status == 0) 00774 SERIALOUT("OK \r\n"); 00775 else { 00776 if( status == -1) 00777 SERIALOUT("CMDERR \r\n"); 00778 else 00779 SERIALOUT("ERR \r\n"); 00780 } 00781 return status; 00782 00783 } 00784 00785 int SH_Max8614x_get_whrm_minpdiodecurr(const char *null_arg){ 00786 00787 int val; 00788 int status = SH_Max8614x_get_singleparamcfg_( SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_MIN_PD_CURRENT , 2, &val); 00789 if(val != -1) 00790 SERIALOUT("whrm_currentrange= %d", val); // MYG: CHECKIF EXPRESSION IS TRUE! 00791 else 00792 SERIALOUT("ERR \r\n"); 00793 00794 return status; 00795 00796 } 00797 00798 int SH_Max8614x_set_whrm_pdiodeconfig(const char *cfg_arg){ 00799 00800 int status = SH_Max8614x_set_singleparamcfg_( cfg_arg , SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_PD_CONFIG , 1 ); 00801 if( status == 0) 00802 SERIALOUT("OK \r\n"); 00803 else { 00804 if( status == -1) 00805 SERIALOUT("CMDERR \r\n"); 00806 else 00807 SERIALOUT("ERR \r\n"); 00808 } 00809 return status; 00810 00811 } 00812 00813 int SH_Max8614x_get_whrm_pdiodeconfig(const char *null_arg){ 00814 00815 int val; 00816 int status = SH_Max8614x_get_singleparamcfg_( SH_ALGOIDX_WHRM, SS_CFGIDX_WHRM_PD_CONFIG, 1 , &val); 00817 if(val != -1) 00818 SERIALOUT("whrm_pdiode_config= %d", val); 00819 else 00820 SERIALOUT("ERR \r\n"); 00821 00822 return status; 00823 00824 } 00825 00826 int SH_Max8614x_stop_acquisition(const char *null_arg){ 00827 SH_Max8614x_stop(); 00828 } 00829 00830 00831 00832 /*FOR THIS DEMO PURPOSE*/ 00833 int Max8614x_Set_WSPO2Mode(int mode){ 00834 00835 uint8_t Temp[1] = { (uint8_t)(mode) }; 00836 int status = sh_set_algo_cfg(SH_ALGOIDX_WSPO2, SS_CFGIDX_WSPO2_ALGO_MODE , &Temp[0], 1); 00837 return status; 00838 00839 } 00840 00841 00842 #if defined(RAW_DATA_ONLY) 00843 00844 int SH_Max8614x_disable_whrm (const char *onoff_arg){ 00845 00846 int status = sh_disable_algo(SH_ALGOIDX_WHRM); 00847 if( status == 0) 00848 SERIALOUT("OK \r\n"); 00849 else { 00850 SERIALOUT("ERR \r\n"); 00851 } 00852 return status; 00853 00854 } 00855 00856 int SH_Max8614x_enable_pureraw(const char *onoff_arg){ 00857 00858 int status; 00859 00860 status = sh_disable_algo(SH_ALGOIDX_WHRM); 00861 wait_ms(500); 00862 status = sh_set_data_type(SS_DATATYPE_RAW , false); 00863 status = sh_set_fifo_thresh(5); 00864 status = sh_sensor_enable(SH_SENSORIDX_MAX8614X, SSMAX8614X_MODE1_DATASIZE, SH_INPUT_DATA_DIRECT_SENSOR); 00865 00866 if( status == 0) 00867 SERIALOUT("OK \r\n"); 00868 else { 00869 SERIALOUT("ERR \r\n"); 00870 } 00871 return status; 00872 00873 } 00874 #endif 00875 00876 00877 00878 00879 00880 00881 00882 00883 00884 00885 00886 00887
Generated on Fri Jul 15 2022 22:42:36 by
1.7.2