Source code for Maxim Sensor Hub Communications. Mostly C library for MAX32664 sensor hub communications.
Embed:
(wiki syntax)
Show/hide line numbers
SHComm.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 00034 /* 00035 #ifdef __cplusplus 00036 extern "C" { 00037 #endif 00038 */ 00039 00040 #include <events/mbed_events.h> 00041 #include <mbed.h> 00042 #include "mbed.h" 00043 00044 #include "SHComm.h" 00045 00046 00047 #define SS_I2C_8BIT_SLAVE_ADDR 0xAA 00048 #define SENSORHUB_I2C_ADRESS SS_I2C_8BIT_SLAVE_ADDR 00049 00050 #define ENABLED ((int)(1)) 00051 #define DISABLED ((int)(0)) 00052 00053 #define SS_DUMP_REG_SLEEP_MS (100) 00054 #define SS_ENABLE_SENSOR_SLEEP_MS (20) 00055 #define SS_DEFAULT_CMD_SLEEP_MS (2) 00056 #define SS_WAIT_BETWEEN_TRIES_MS (2) 00057 #define SS_CMD_WAIT_PULLTRANS_MS (5) 00058 #define SS_FEEDFIFO_CMD_SLEEP_MS (30) 00059 00060 00061 #define SS_DEFAULT_RETRIES ((int) (4)) 00062 #define SS_ZERO_DELAY 0 00063 #define SS_ZERO_BYTES 0 00064 00065 00066 /*define sample size of algorithm and raw sensor data in bytes*/ 00067 #define SH_ALGO_WHRM_SAMPLE_DATABYTES 4 00068 #define SH_ALGO_SP02_SAMPLE_DATABYTES 4 00069 00070 00071 /*define command sequences given in Maxim ME32664 user manual*/ 00072 #define SH_GET_HUB_STATUS_CMDSEQ {0x00,0x00} 00073 #define SH_SET_OPERATING_MODE_CMDSEQ(opMode) {0x01,0x00,opMode} 00074 #define SH_SET_OPERATING_MODE_BOOTLOADER_CMDSEQ {0x02,0x00,0x08} 00075 #define SH_SET_OPERATING_MODE_APPLICATION_CMDSEQ {0x02,0x00,0x00} 00076 #define SH_SET_OPERATING_MODE_RESET_CMDSEQ {0x02,0x00,0x02} 00077 #define SH_GET_OPERATING_MODE_CMDSEQ {0x02,0x00} 00078 00079 #define SH_SET_OUTPUT_MODE_CMDSEQ( outMode) {0x10,0x00, outMode} 00080 #define SH_SET_OUTMODE_NODATA_CMDSEQ {0x10,0x00,0x00} 00081 #define SH_SET_OUTMODE_SENSORDATA_CMDSEQ {0x10,0x00,0x01} 00082 #define SH_SET_OUTMODE_ALGODATA_CMDSEQ {0x10,0x00,0x02} 00083 #define SH_SET_OUTMODE_PAUSE_CMDSEQ {0x10,0x00,0x04} 00084 #define SH_SET_OUTMODE_SENSAMPLECNT_CMDSEQ {0x10,0x00,0x05} 00085 #define SH_SET_OUTMODE_ALGOSAMPLECNT_CMDSEQ {0x10,0x00,0x06} 00086 #define SH_SET_OUTMODE_ALGOSENSAMPLECNT_CMDSEQ {0x10,0x00,0x07} 00087 00088 #define SH_GET_OUTPUT_MODE_CMDSEQ {0x11,0x00} 00089 00090 #define SH_DFIFO_SET_INT_THRESHOLD_CMDSEQ( ucThreshold ) {0x10,0x01,ucThreshold} 00091 #define SH_DFIFO_GET_INT_THRESHOLD_CMDSEQ {0x11,0x01} 00092 00093 #define SH_DFIFO_GET_NSAMPLES_CMDSEQ {0x12,0x00} 00094 #define SH_DFIFO_PULL_SAMPLE_CMDSEQ {0x12,0x01} 00095 #define SH_GET_EXTINPUT_FIFOSZ_CMDSEQ {0x13,0x01} 00096 #define SH_GET_SAMPLEBYTECNT_INPUTFIFO_CMDSEQ {0x13,0x04} 00097 #define SH_FEED_TO_INPUTFIFO_CMDSEQ {0x14,0x00} 00098 00099 #define SH_WRITE_SENSORREG_CMDSEQ( sensorIdx , regAddr ) { 0x40, sensorIdx , regAddr} 00100 #define SH_READ_SENSORREG_CMDSEQ( sensorIdx , regAddr ) { 0x41, sensorIdx , regAddr} 00101 #define SH_READ_AFE_ATTRIBUTES_CMDSEQ(sensorIdx) { 0x42, sensorIdx} 00102 #define SH_READ_ALLREGISTERS_CMDSEQ(sensorIdx) { 0x43, sensorIdx} 00103 00104 #define SH_ENABLE_SENSOR_CMDSEQ(sensorIdx , extMode) {0x44, sensorIdx, 0x01 , extMode } 00105 #define SH_DISABLE_SENSOR_CMDSEQ(sensorIdx) {0x44, sensorIdx, 0x00} 00106 00107 00108 #define SH_AGC_SET_ADCRANGE_CMDSEQ( uiPercentage) {0x50, 0x00, 0x00 , uiPercentage} 00109 #define SH_AGC_SET_STEPSZ_CMDSEQ( uiPercentage) {0x50, 0x00, 0x01 , uiPercentage} 00110 #define SH_AGC_SET_SENSITIVITY_CMDSEQ( uiPercentage) {0x50, 0x00, 0x02 , uiPercentage} 00111 #define SH_AGC_SET_NSAMPLESAVRAGING_CMDSEQ( ucNsamples) {0x50, 0x00, 0x03 , uiNsamples} 00112 #define SH_WHRM_SET_SAMPRATE_CMDSEQ( ucNsamples) {0x50, 0x02, 0x03 , uiNsamples} 00113 00114 00115 #define SH_ENABLE_ALGO_CMDSEQ( algoIdx) { 0x52, algoIdx , 0x01} 00116 #define SH_DISABLE_ALGO_CMDSEQ( algoIdx) { 0x52, algoIdx , 0x00} 00117 00118 #define SH_SET_ALGO_CONFIGURATION_CMDSEQ( algoIdx, cgfIdx) { 0x50 , algoIdx, cgfIdx } 00119 #define SH_GET_ALGO_CONFIGURATION_CMDSEQ( algoIdx, cgfIdx) { 0x51 , algoIdx, cgfIdx } 00120 00121 #define SH_COMM_CHECK_CMDSEQ {0xFF, 0x00} 00122 00123 /* 00124 * define the "platform specific" hardware interface which SSinterface requires: 00125 * 1. master i2c port 00126 * 2. interrupt attachable I/O pin (mfio) 00127 * 3. I/O pin for reset 00128 * Note: Definitions below are for MAX32630FTR Pagasus board . Modify for your platform. 00129 **/ 00130 I2C *m_i2cBus; /*i2c bus sensor hub is connected to*/ 00131 00132 PinName ss_mfio(P5_4); /* platform specific mfio event pin */ 00133 PinName ss_reset(P5_6); /* platform specific sensor hub reset pin */ 00134 DigitalInOut mfio_pin(ss_mfio); /* mfio pin mode be I/O */ 00135 DigitalInOut reset_pin(ss_reset); /* reset pin mode be I/O */ 00136 InterruptIn irq_pin(ss_mfio); /* define mfio pin interrupt attachable*/ 00137 00138 00139 /* 00140 * SSI API funcions 00141 * NOTE: Generic functions for any platform. 00142 * exceptions: below needs needs modification according to platform and HAL drivers 00143 * 1. Hard reset function 00144 * 2. Enable/disable mfio event interrput 00145 * 3. mfio pin interrupt routine 00146 * 00147 * **/ 00148 00149 /*global buffer for sensor i2c commands+data*/ 00150 uint8_t sh_write_buf[512]; 00151 static volatile bool m_irq_received_ = false; 00152 static volatile bool mfio_int_happened = false; 00153 00154 /* sensor hub states */ 00155 static bool sc_en = false; 00156 static int data_type = 0; 00157 static int is_sensor_enabled[SS_MAX_SUPPORTED_SENSOR_NUM] = {0}; 00158 static int is_algo_enabled[SS_MAX_SUPPORTED_ALGO_NUM] = {0}; 00159 static int sensor_sample_sz[SS_MAX_SUPPORTED_SENSOR_NUM] = {0}; 00160 static int algo_sample_sz[SS_MAX_SUPPORTED_ALGO_NUM] = {0}; 00161 00162 00163 00164 /* desc : 00165 * Func to init master i2c hardware comm interface with sennor hub 00166 * init mfio interrupt pin and attach irq to pin 00167 * init reset pin 00168 * params: 00169 * N/A 00170 */ 00171 00172 00173 void sh_irq_handler(); 00174 void sh_init_hwcomm_interface(){ 00175 static I2C ssI2C(P3_4, P3_5); /*set up sensor hub i2c communication at 400 kHz*/ 00176 ssI2C.frequency(400000); 00177 m_i2cBus = &ssI2C; 00178 00179 reset_pin.input(); 00180 reset_pin.mode(PullUp); 00181 mfio_pin.input(); /*set mfio as input for getting mfio event reporting when sesnor hub is on application mode */ 00182 mfio_pin.mode(PullUp); 00183 00184 irq_pin.fall(sh_irq_handler); /*attach falling edge interrupt to mfio pin for mfio event reporting */ 00185 00186 return; 00187 } 00188 00189 /* mfio pin event reporting related interrupt functions*/ 00190 /* 00191 * data ready event reporting isr from sensor hub 00192 * 00193 * params: 00194 * N/A 00195 * */ 00196 void sh_irq_handler() 00197 { 00198 m_irq_received_ = true; 00199 } 00200 void sh_clear_mfio_event_flag(void){ 00201 m_irq_received_ = false; 00202 } 00203 00204 bool sh_has_mfio_event(void){ 00205 return m_irq_received_; 00206 } 00207 00208 /* desc: 00209 * func to enable event reporting from sensor hub 00210 * 00211 * params: 00212 * N/A 00213 * */ 00214 void sh_enable_irq_mfioevent(void) 00215 { 00216 irq_pin.enable_irq(); 00217 } 00218 00219 /* desc: 00220 * func to disable event reporting from sensor hub 00221 * 00222 * params: 00223 * N/A 00224 * */ 00225 void sh_disable_irq_mfioevent(void) 00226 { 00227 irq_pin.disable_irq(); 00228 } 00229 00230 /* desc: 00231 * reset event reporting process from sensor hub 00232 * 00233 * params: 00234 * N/A 00235 **/ 00236 bool sh_reset_mfio_irq(){ 00237 bool ret = mfio_int_happened; 00238 mfio_int_happened = false; 00239 sh_disable_irq_mfioevent(); 00240 irq_pin.fall(sh_irq_handler); 00241 sh_enable_irq_mfioevent(); 00242 return ret; 00243 } 00244 00245 00246 /* 00247 * desc: 00248 * function to reset sensor hub and put to application mode after reset interface and get data format. 00249 * 00250 * params: 00251 * 00252 * __I wakeupMode : 0x00 : application mode 00253 * 0x08 : bootloader mode 00254 * */ 00255 int sh_hard_reset(int wakeupMode){ 00256 00257 int status; 00258 sh_disable_irq_mfioevent(); 00259 reset_pin.output(); 00260 mfio_pin.output(); 00261 00262 reset_pin.write(0); 00263 wait_ms(SS_RESET_TIME); 00264 00265 if( (wakeupMode & 0xFF) == 0 ) { 00266 00267 mfio_pin.write(1); 00268 reset_pin.write(1); 00269 wait_ms(SS_STARTUP_TO_MAIN_APP_TIME); 00270 00271 }else { 00272 00273 mfio_pin.write(0); 00274 reset_pin.write(1); 00275 wait_ms(SS_STARTUP_TO_BTLDR_TIME); 00276 } 00277 mfio_pin.input(); 00278 mfio_pin.mode(PullUp); 00279 reset_pin.input(); 00280 sh_enable_irq_mfioevent(); 00281 } 00282 00283 00284 /* 00285 * desc: 00286 * function to init sensor comm interface and get data format. 00287 * 00288 * */ 00289 void sh_init_hubinterface(void){ 00290 00291 sh_init_hwcomm_interface(); 00292 //sh_get_data_type(&data_type, &sc_en); 00293 return; 00294 } 00295 00296 00297 00298 00299 00300 /* 00301 * 00302 * SENSOR HUB COMMUNICATION INTERFACE ( Defined in MAX32664 User Guide ) API FUNCTIONS 00303 * 00304 * 00305 * */ 00306 00307 int sh_write_cmd( uint8_t *tx_buf, 00308 int tx_len, 00309 int sleep_ms) 00310 { 00311 int retries = SS_DEFAULT_RETRIES; 00312 int ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)tx_buf, tx_len); 00313 while (ret != 0 && retries-- > 0) { 00314 00315 wait_ms(1); 00316 ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)tx_buf, tx_len); 00317 } 00318 if (ret != 0) 00319 return SS_ERR_UNAVAILABLE; 00320 00321 00322 wait_ms(sleep_ms); 00323 00324 char status_byte; 00325 ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, &status_byte, 1); 00326 bool try_again = (status_byte == SS_ERR_TRY_AGAIN); 00327 while ((ret != 0 || try_again) 00328 && retries-- > 0) { 00329 wait_ms(sleep_ms); 00330 ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, &status_byte, 1); 00331 try_again = (status_byte == SS_ERR_TRY_AGAIN); 00332 } 00333 00334 if (ret != 0 || try_again) 00335 return SS_ERR_UNAVAILABLE; 00336 00337 return (int) (SS_STATUS)status_byte; 00338 } 00339 00340 00341 int sh_write_cmd_with_data(uint8_t *cmd_bytes, 00342 int cmd_bytes_len, 00343 uint8_t *data, 00344 int data_len, 00345 int cmd_delay_ms) 00346 { 00347 memcpy(sh_write_buf, cmd_bytes, cmd_bytes_len); 00348 memcpy(sh_write_buf + cmd_bytes_len, data, data_len); 00349 int status = sh_write_cmd(sh_write_buf,cmd_bytes_len + data_len, cmd_delay_ms); 00350 return status; 00351 } 00352 00353 00354 int sh_read_cmd( uint8_t *cmd_bytes, 00355 int cmd_bytes_len, 00356 uint8_t *data, 00357 int data_len, 00358 uint8_t *rxbuf, 00359 int rxbuf_sz, 00360 int sleep_ms ) 00361 { 00362 00363 int retries = SS_DEFAULT_RETRIES; 00364 00365 int ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)cmd_bytes, cmd_bytes_len, (data_len != 0)); 00366 if (data_len != 0) 00367 ret |= m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)data, data_len, false); 00368 00369 00370 while (ret != 0 && retries-- > 0) { 00371 wait_ms(1); 00372 ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)cmd_bytes, cmd_bytes_len, (data_len != 0)); 00373 if (data_len != 0) 00374 ret |= m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)data, data_len, false); 00375 00376 } 00377 if (ret != 0) 00378 return SS_ERR_UNAVAILABLE; 00379 00380 00381 wait_ms(sleep_ms); 00382 00383 ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, (char*)rxbuf, rxbuf_sz); 00384 bool try_again = (rxbuf[0] == SS_ERR_TRY_AGAIN); 00385 while ((ret != 0 || try_again) && retries-- > 0) { 00386 wait_ms(sleep_ms); 00387 ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, (char*)rxbuf, rxbuf_sz); 00388 try_again = (rxbuf[0] == SS_ERR_TRY_AGAIN); 00389 } 00390 if (ret != 0 || try_again) 00391 return SS_ERR_UNAVAILABLE; 00392 00393 return (int) ((SS_STATUS)rxbuf[0]); 00394 } 00395 00396 00397 00398 int sh_get_sensorhub_status(uint8_t *hubStatus){ 00399 00400 uint8_t ByteSeq[] = SH_GET_HUB_STATUS_CMDSEQ; 00401 uint8_t rxbuf[2] = { 0 }; 00402 00403 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 00404 0, 0, 00405 &rxbuf[0], sizeof(rxbuf), 00406 SS_DEFAULT_CMD_SLEEP_MS); 00407 00408 *hubStatus = rxbuf[1]; 00409 return status; 00410 } 00411 00412 00413 int sh_get_sensorhub_operating_mode(uint8_t *hubMode){ 00414 00415 uint8_t ByteSeq[] = SH_GET_OPERATING_MODE_CMDSEQ; 00416 uint8_t rxbuf[2] = { 0 }; 00417 00418 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 00419 0, 0, 00420 &rxbuf[0], sizeof(rxbuf), 00421 SS_DEFAULT_CMD_SLEEP_MS); 00422 00423 *hubMode = rxbuf[1]; 00424 return status; 00425 } 00426 00427 00428 int sh_set_sensorhub_operating_mode(uint8_t hubMode){ 00429 00430 uint8_t ByteSeq[] = SH_SET_OPERATING_MODE_CMDSEQ(hubMode); 00431 int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), SS_DEFAULT_CMD_SLEEP_MS); 00432 return status; 00433 00434 } 00435 00436 00437 //int sh_set_data_type( uint8_t outMode) 00438 int sh_set_data_type(int data_type_, bool sc_en_) 00439 { 00440 00441 #if 0 00442 uint8_t dataTypeSc = (uint8_t)((sc_en ? SS_MASK_OUTPUTMODE_SC_EN : 0) | ((data_type << SS_SHIFT_OUTPUTMODE_DATATYPE) & SS_MASK_OUTPUTMODE_DATATYPE)); 00443 uint8_t ByteSeq[] = SH_SET_OUTPUT_MODE_CMDSEQ( dataTypeSc); 00444 int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), SS_DEFAULT_CMD_SLEEP_MS); 00445 if( status == 0x00){ 00446 data_type = data_type_; 00447 sc_en = sc_en_; 00448 } 00449 #endif 00450 00451 uint8_t cmd_bytes[] = { SS_FAM_W_COMMCHAN, SS_CMDIDX_OUTPUTMODE }; 00452 uint8_t data_bytes[] = { (uint8_t)((sc_en_ ? SS_MASK_OUTPUTMODE_SC_EN : 0) | 00453 ((data_type_ << SS_SHIFT_OUTPUTMODE_DATATYPE) & SS_MASK_OUTPUTMODE_DATATYPE)) }; 00454 00455 int status = sh_write_cmd_with_data(&cmd_bytes[0], sizeof(cmd_bytes), 00456 &data_bytes[0], sizeof(data_bytes), 00457 SS_DEFAULT_CMD_SLEEP_MS); 00458 data_type = data_type_; 00459 sc_en = sc_en_; 00460 00461 return status; 00462 } 00463 00464 00465 int sh_get_data_type(int *data_type_, bool *sc_en_){ 00466 00467 uint8_t ByteSeq[] = SH_GET_OUTPUT_MODE_CMDSEQ; 00468 uint8_t rxbuf[2] = {0}; 00469 int status = sh_read_cmd( &ByteSeq[0], sizeof(ByteSeq), 00470 0, 0, 00471 &rxbuf[0], sizeof(rxbuf), 00472 SS_DEFAULT_CMD_SLEEP_MS); 00473 if (status == 0x00 /*SS_SUCCESS*/) { 00474 *data_type_ = 00475 (rxbuf[1] & SS_MASK_OUTPUTMODE_DATATYPE) >> SS_SHIFT_OUTPUTMODE_DATATYPE; 00476 *sc_en_ = 00477 (bool)((rxbuf[1] & SS_MASK_OUTPUTMODE_SC_EN) >> SS_SHIFT_OUTPUTMODE_SC_EN); 00478 00479 } 00480 00481 return status; 00482 00483 } 00484 00485 00486 int sh_set_fifo_thresh( int threshold ){ 00487 00488 #if 0 00489 uint8_t ucThresh = (uint8_t) (threshold & 0xFF); 00490 uint8_t ByteSeq[] = SH_DFIFO_SET_INT_THRESHOLD_CMDSEQ(ucThresh ); 00491 int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), SS_DEFAULT_CMD_SLEEP_MS); 00492 return status; 00493 #endif 00494 00495 uint8_t cmd_bytes[] = { SS_FAM_W_COMMCHAN, SS_CMDIDX_FIFOAFULL }; 00496 uint8_t data_bytes[] = { (uint8_t)threshold }; 00497 00498 int status = sh_write_cmd_with_data(&cmd_bytes[0], sizeof(cmd_bytes), 00499 &data_bytes[0], sizeof(data_bytes), 00500 SS_DEFAULT_CMD_SLEEP_MS 00501 ); 00502 return status; 00503 00504 } 00505 00506 00507 int sh_get_fifo_thresh(int *thresh){ 00508 00509 uint8_t ByteSeq[] = SH_DFIFO_GET_INT_THRESHOLD_CMDSEQ; 00510 uint8_t rxbuf[2] = {0}; 00511 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 00512 0, 0, 00513 &rxbuf[0], sizeof(rxbuf), 00514 SS_DEFAULT_CMD_SLEEP_MS); 00515 00516 *thresh = (int) rxbuf[1]; 00517 00518 return status; 00519 00520 } 00521 00522 00523 int sh_ss_comm_check(void){ 00524 00525 00526 uint8_t ByteSeq[] = SH_COMM_CHECK_CMDSEQ; 00527 uint8_t rxbuf[2]; 00528 00529 int status = sh_read_cmd( &ByteSeq[0], sizeof(ByteSeq), 00530 0, 0, 00531 &rxbuf[0], sizeof(rxbuf), 00532 SS_DEFAULT_CMD_SLEEP_MS ); 00533 00534 int tries = 4; 00535 while (status == SS_ERR_TRY_AGAIN && tries--) { 00536 wait_ms(1000); 00537 status = sh_read_cmd( &ByteSeq[0], sizeof(ByteSeq), 00538 0, 0, 00539 &rxbuf[0], sizeof(rxbuf), 00540 SS_DEFAULT_CMD_SLEEP_MS ); 00541 00542 } 00543 00544 return status; 00545 } 00546 00547 00548 int sh_num_avail_samples(int *numSamples) { 00549 00550 uint8_t ByteSeq[] = SH_DFIFO_GET_NSAMPLES_CMDSEQ; 00551 uint8_t rxbuf[2] = {0}; 00552 00553 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 00554 0, 0, 00555 &rxbuf[0], sizeof(rxbuf), 00556 1); 00557 00558 *numSamples = (int) rxbuf[1]; 00559 00560 return status; 00561 } 00562 00563 00564 int sh_read_fifo_data( int numSamples, 00565 int sampleSize, 00566 uint8_t* databuf, 00567 int databufSz) { 00568 00569 int bytes_to_read = numSamples * sampleSize + 1; //+1 for status byte 00570 00571 uint8_t ByteSeq[] = SH_DFIFO_PULL_SAMPLE_CMDSEQ; 00572 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 00573 0, 0, 00574 databuf, bytes_to_read, 00575 10); 00576 00577 return status; 00578 } 00579 00580 00581 /* 00582 * desc: 00583 * func to read sample size for SmartSensor input FIFO for extrenal accel data 00584 * 00585 * params: 00586 * __O sampSize: size of data sample struct in bytes 00587 * returns: 00588 * 1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success 00589 * 00590 **/ 00591 int sh_read_input_fifo_samplesz( int *sampSize){ 00592 00593 /* NOT IMPLEMENTED IN SS INTERFACE */ 00594 00595 } 00596 00597 /* 00598 * desc: 00599 * func to write data samples to SmartSensor input FIFO for extrenal accel data 00600 * 00601 * params: 00602 ... 00603 * returns: 00604 * 1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success 00605 */ 00606 int sh_write_input_fifo( void *arg){ 00607 00608 /* NOT IMPLEMENTED IN SS INTERFACE */ 00609 00610 } 00611 00612 00613 int sh_set_reg(int idx, uint8_t addr, uint32_t val, int regSz){ 00614 00615 uint8_t ByteSeq[] = SH_WRITE_SENSORREG_CMDSEQ( ((uint8_t)idx) , addr ); 00616 uint8_t data_bytes[4]; 00617 for (int i = 0; i < regSz; i++) { 00618 data_bytes[i] = (val >> (8 * (regSz - 1)) & 0xFF); 00619 } 00620 int status = sh_write_cmd_with_data( &ByteSeq[0], sizeof(ByteSeq), 00621 &data_bytes[0], (uint8_t) regSz, 00622 SS_DEFAULT_CMD_SLEEP_MS); 00623 00624 return status; 00625 } 00626 00627 00628 int sh_get_reg(int idx, uint8_t addr, uint32_t *val){ 00629 00630 00631 uint32_t i32tmp; 00632 uint8_t ByteSeq[] = SH_READ_AFE_ATTRIBUTES_CMDSEQ(((uint8_t) idx)); 00633 uint8_t rxbuf[3] = {0}; 00634 00635 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 00636 0, 0, 00637 &rxbuf[0], sizeof(rxbuf), 00638 SS_DEFAULT_CMD_SLEEP_MS); 00639 00640 00641 if(status == 0x00 /* SS_SUCCESS */) { 00642 00643 int reg_width = rxbuf[1]; 00644 uint8_t ByteSeq2[] = SH_READ_SENSORREG_CMDSEQ( ((uint8_t)idx) , addr ); 00645 uint8_t rxbuf2[5] = {0}; 00646 status = sh_read_cmd(&ByteSeq2[0], sizeof(ByteSeq2), 00647 0, 0, 00648 &rxbuf2[0], reg_width + 1, 00649 SS_DEFAULT_CMD_SLEEP_MS); 00650 00651 if (status == 0x00 /* SS_SUCCESS */) { 00652 i32tmp = 0; 00653 for (int i = 0; i < reg_width; i++) { 00654 i32tmp = (i32tmp << 8) | rxbuf2[i + 1]; 00655 } 00656 *val = i32tmp; 00657 } 00658 } 00659 00660 return status; 00661 00662 } 00663 00664 00665 int sh_sensor_enable( int idx , int sensorSampleSz , uint8_t ext_mode ){ 00666 00667 uint8_t ByteSeq[] = SH_ENABLE_SENSOR_CMDSEQ( ((uint8_t) idx) , ((uint8_t) ext_mode)); 00668 int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), 5 * SS_ENABLE_SENSOR_SLEEP_MS); 00669 if(status == 0x00){ 00670 00671 is_sensor_enabled[idx] = ENABLED; 00672 sensor_sample_sz[idx] = sensorSampleSz; 00673 } 00674 return status; 00675 00676 } 00677 00678 00679 int sh_sensor_disable( int idx ){ 00680 00681 uint8_t ByteSeq[] = SH_DISABLE_SENSOR_CMDSEQ( ((uint8_t) idx)); 00682 int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), SS_ENABLE_SENSOR_SLEEP_MS); 00683 if(status == 0x00){ 00684 00685 is_sensor_enabled[idx] = DISABLED; 00686 } 00687 return status; 00688 00689 } 00690 00691 00692 int sh_get_input_fifo_size(int *fifo_size) 00693 { 00694 00695 uint8_t ByteSeq[] = SH_GET_EXTINPUT_FIFOSZ_CMDSEQ; 00696 uint8_t rxbuf[3]; /* status + fifo size */ 00697 00698 00699 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 00700 0, 0, 00701 rxbuf, sizeof(rxbuf), 2*SS_DEFAULT_CMD_SLEEP_MS); 00702 00703 *fifo_size = rxbuf[1] << 8 | rxbuf[2]; 00704 return status; 00705 } 00706 00707 00708 int sh_feed_to_input_fifo(uint8_t *tx_buf, int tx_buf_sz, int *nb_written) 00709 { 00710 int status; 00711 00712 uint8_t ByteSeq[] = SH_FEED_TO_INPUTFIFO_CMDSEQ; 00713 uint8_t rxbuf[3]; 00714 00715 tx_buf[0] = 0x14; 00716 tx_buf[1] = 0x00; 00717 00718 status= sh_read_cmd(tx_buf, tx_buf_sz, 00719 0, 0, 00720 rxbuf, sizeof(rxbuf), SS_FEEDFIFO_CMD_SLEEP_MS); 00721 00722 *nb_written = rxbuf[1] * 256 + rxbuf[2]; 00723 return status; 00724 } 00725 00726 00727 int sh_get_num_bytes_in_input_fifo(int *fifo_size) 00728 { 00729 00730 uint8_t ByteSeq[] = SH_GET_SAMPLEBYTECNT_INPUTFIFO_CMDSEQ; 00731 uint8_t rxbuf[3]; /* status + fifo size */ 00732 00733 00734 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 00735 0, 0, 00736 rxbuf, sizeof(rxbuf), 00737 2*SS_DEFAULT_CMD_SLEEP_MS); 00738 00739 *fifo_size = rxbuf[1] << 8 | rxbuf[2]; 00740 return status; 00741 } 00742 00743 00744 /* 00745 * ALGARITIM RELATED FUNCTIONS :) 00746 * 00747 * 00748 * 00749 * 00750 * 00751 * */ 00752 00753 00754 int sh_enable_algo(int idx , int algoSampleSz){ 00755 00756 uint8_t ByteSeq[] = SH_ENABLE_ALGO_CMDSEQ( ((uint8_t) idx) ); 00757 int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), 25 * SS_ENABLE_SENSOR_SLEEP_MS); 00758 if(status == 0x00){ 00759 00760 is_algo_enabled[idx] = ENABLED; 00761 algo_sample_sz[idx] = algoSampleSz; 00762 } 00763 return status; 00764 00765 } 00766 00767 00768 int sh_disable_algo(int idx){ 00769 00770 uint8_t ByteSeq[] = SH_DISABLE_ALGO_CMDSEQ( ((uint8_t) idx) ); 00771 int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), SS_ENABLE_SENSOR_SLEEP_MS ); 00772 if(status == 0x00){ 00773 00774 is_algo_enabled[idx] = DISABLED; 00775 } 00776 return status; 00777 00778 } 00779 00780 00781 int sh_set_algo_cfg(int algo_idx, int cfg_idx, uint8_t *cfg, int cfg_sz){ 00782 00783 uint8_t ByteSeq[] = SH_SET_ALGO_CONFIGURATION_CMDSEQ( ((uint8_t) algo_idx) , ((uint8_t) cfg_idx) ); 00784 int status = sh_write_cmd_with_data( &ByteSeq[0], sizeof(ByteSeq), 00785 cfg, cfg_sz, 00786 SS_DEFAULT_CMD_SLEEP_MS); 00787 00788 return status; 00789 00790 } 00791 00792 00793 int sh_get_algo_cfg(int algo_idx, int cfg_idx, uint8_t *cfg, int cfg_sz){ 00794 00795 uint8_t ByteSeq[] = SH_GET_ALGO_CONFIGURATION_CMDSEQ( ((uint8_t) algo_idx) , ((uint8_t) cfg_idx) ); 00796 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 00797 0, 0, 00798 cfg, cfg_sz, 00799 SS_DEFAULT_CMD_SLEEP_MS); 00800 return status; 00801 00802 } 00803 00804 00805 /* 00806 * desc: 00807 * func to get active cumulative sample size of sensor hub in order to 00808 * calculate number of bytes to be read from sensor hub report data buffer 00809 * 00810 * params: 00811 * __I data_type : active data type of sensor hub -> no data :0 (SS_DATATYPE_PAUSE) 00812 * raw sensor data only :1 (SS_DATATYPE_RAW) 00813 * algo data only :2 (SS_DATATYPE_ALGO) 00814 * algo+raw data :3 (SS_DATATYPE_BOTH) 00815 * __O sample_size : calculated active cumulative sample size 00816 00817 * returns: 00818 * N/A 00819 * 00820 **/ 00821 static void fifo_sample_size(int data_type_, int *sample_size) 00822 { 00823 00824 int tmpSz = 0; 00825 //*sample_size = 0; 00826 00827 if (data_type_ == SS_DATATYPE_RAW || data_type_ == SS_DATATYPE_BOTH) { 00828 for (int i = 0; i < SS_MAX_SUPPORTED_SENSOR_NUM; i++) { 00829 if (is_sensor_enabled[i]) { 00830 tmpSz += sensor_sample_sz[i]; 00831 //*sample_size += sensor_data_reqs[i]->data_size; 00832 } 00833 } 00834 } 00835 00836 if (data_type_ == SS_DATATYPE_ALGO || data_type_ == SS_DATATYPE_BOTH) { 00837 for (int i = 0; i < SS_MAX_SUPPORTED_ALGO_NUM; i++) { 00838 if (is_algo_enabled[i]) { 00839 tmpSz += algo_sample_sz[i]; 00840 //*sample_size += algo_data_reqs[i]->data_size; 00841 } 00842 } 00843 } 00844 00845 *sample_size = tmpSz; 00846 } 00847 00848 00849 void sh_ss_execute_once( uint8_t *databuf , int databufLen , int *nSamplesRead){ 00850 00851 if(m_irq_received_ == false) { 00852 *nSamplesRead = 0; 00853 return; 00854 } 00855 00856 uint8_t sample_count; 00857 00858 sh_disable_irq_mfioevent(); 00859 sh_clear_mfio_event_flag(); 00860 00861 uint8_t hubStatus = 0; 00862 int status = sh_get_sensorhub_status(&hubStatus); 00863 if(status != 0x00 /*SS_SUCCESS*/){ 00864 sh_enable_irq_mfioevent(); 00865 return; 00866 } 00867 00868 if (hubStatus & SS_MASK_STATUS_DATA_RDY) { 00869 00870 int num_samples = 1; 00871 status = sh_num_avail_samples(&num_samples); 00872 if (status != 0x00 /*SS_SUCCESS*/){ 00873 sh_enable_irq_mfioevent(); 00874 return; 00875 } 00876 00877 00878 int sample_size; 00879 fifo_sample_size(data_type, &sample_size); 00880 /*DEBUG */// 00881 //printf("____DATA READY %d %d \n", (int)num_samples, sample_size); 00882 00883 int bytes_to_read = num_samples * sample_size + 1; //+1 for status byte 00884 if ((uint32_t)bytes_to_read > databufLen) { 00885 //Reduce number of samples to read to fit in buffer 00886 num_samples = (databufLen - 1) / sample_size; 00887 } 00888 wait_ms(5); 00889 status = sh_read_fifo_data(num_samples, sample_size, &databuf[0], databufLen); 00890 if(status != 0x00 /*SS_SUCCESS*/){ 00891 *nSamplesRead = 0; 00892 sh_enable_irq_mfioevent(); 00893 return; 00894 } 00895 *nSamplesRead = num_samples; 00896 00897 } 00898 00899 sh_enable_irq_mfioevent(); 00900 return; 00901 } 00902 00903 00904 00905 00906 00907 00908 /* 00909 #ifdef __cplusplus 00910 } 00911 #endif 00912 */ 00913
Generated on Wed Jul 13 2022 21:47:33 by 1.7.2