Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BMI160 max32630hsp3 MemoryLCD USBDevice
SHComm.cpp
00001 /* 00002 * SHcomm.cpp 00003 * 00004 * Created on: Nov 16, 2018 00005 * Author: Yagmur.Gok 00006 */ 00007 00008 /* 00009 #ifdef __cplusplus 00010 extern "C" { 00011 #endif 00012 */ 00013 00014 #include <events/mbed_events.h> 00015 #include <mbed.h> 00016 #include "mbed.h" 00017 00018 #include "SHComm.h" 00019 00020 00021 #define SS_I2C_8BIT_SLAVE_ADDR 0xAA 00022 #define SENSORHUB_I2C_ADRESS SS_I2C_8BIT_SLAVE_ADDR 00023 00024 #define ENABLED ((int)(1)) 00025 #define DISABLED ((int)(0)) 00026 00027 #define SS_DUMP_REG_SLEEP_MS (100) 00028 #define SS_ENABLE_SENSOR_SLEEP_MS (20) 00029 #define SS_DEFAULT_CMD_SLEEP_MS (2) 00030 #define SS_WAIT_BETWEEN_TRIES_MS (2) 00031 #define SS_CMD_WAIT_PULLTRANS_MS (5) 00032 #define SS_FEEDFIFO_CMD_SLEEP_MS (30) 00033 00034 00035 #define SS_DEFAULT_RETRIES ((int) (4)) 00036 #define SS_ZERO_DELAY 0 00037 #define SS_ZERO_BYTES 0 00038 00039 00040 /*define sample size of algorithm and raw sensor data in bytes*/ 00041 #define SH_ALGO_WHRM_SAMPLE_DATABYTES 4 00042 #define SH_ALGO_SP02_SAMPLE_DATABYTES 4 00043 00044 00045 /*define command sequences given in Maxim ME32664 user manual*/ 00046 #define SH_GET_HUB_STATUS_CMDSEQ {0x00,0x00} 00047 #define SH_SET_OPERATING_MODE_CMDSEQ(opMode) {0x01,0x00,opMode} 00048 #define SH_SET_OPERATING_MODE_BOOTLOADER_CMDSEQ {0x02,0x00,0x08} 00049 #define SH_SET_OPERATING_MODE_APPLICATION_CMDSEQ {0x02,0x00,0x00} 00050 #define SH_SET_OPERATING_MODE_RESET_CMDSEQ {0x02,0x00,0x02} 00051 #define SH_GET_OPERATING_MODE_CMDSEQ {0x02,0x00} 00052 00053 #define SH_SET_OUTPUT_MODE_CMDSEQ( outMode) {0x10,0x00, outMode} 00054 #define SH_SET_OUTMODE_NODATA_CMDSEQ {0x10,0x00,0x00} 00055 #define SH_SET_OUTMODE_SENSORDATA_CMDSEQ {0x10,0x00,0x01} 00056 #define SH_SET_OUTMODE_ALGODATA_CMDSEQ {0x10,0x00,0x02} 00057 #define SH_SET_OUTMODE_PAUSE_CMDSEQ {0x10,0x00,0x04} 00058 #define SH_SET_OUTMODE_SENSAMPLECNT_CMDSEQ {0x10,0x00,0x05} 00059 #define SH_SET_OUTMODE_ALGOSAMPLECNT_CMDSEQ {0x10,0x00,0x06} 00060 #define SH_SET_OUTMODE_ALGOSENSAMPLECNT_CMDSEQ {0x10,0x00,0x07} 00061 00062 #define SH_GET_OUTPUT_MODE_CMDSEQ {0x11,0x00} 00063 00064 #define SH_DFIFO_SET_INT_THRESHOLD_CMDSEQ( ucThreshold ) {0x10,0x01,ucThreshold} 00065 #define SH_DFIFO_GET_INT_THRESHOLD_CMDSEQ {0x11,0x01} 00066 00067 #define SH_DFIFO_GET_NSAMPLES_CMDSEQ {0x12,0x00} 00068 #define SH_DFIFO_PULL_SAMPLE_CMDSEQ {0x12,0x01} 00069 #define SH_GET_EXTINPUT_FIFOSZ_CMDSEQ {0x13,0x01} 00070 #define SH_GET_SAMPLEBYTECNT_INPUTFIFO_CMDSEQ {0x13,0x04} 00071 #define SH_FEED_TO_INPUTFIFO_CMDSEQ {0x14,0x00} 00072 00073 #define SH_WRITE_SENSORREG_CMDSEQ( sensorIdx , regAddr ) { 0x40, sensorIdx , regAddr} 00074 #define SH_READ_SENSORREG_CMDSEQ( sensorIdx , regAddr ) { 0x41, sensorIdx , regAddr} 00075 #define SH_READ_AFE_ATTRIBUTES_CMDSEQ(sensorIdx) { 0x42, sensorIdx} 00076 #define SH_READ_ALLREGISTERS_CMDSEQ(sensorIdx) { 0x43, sensorIdx} 00077 00078 #define SH_ENABLE_SENSOR_CMDSEQ(sensorIdx , extMode) {0x44, sensorIdx, 0x01 , extMode } 00079 #define SH_DISABLE_SENSOR_CMDSEQ(sensorIdx) {0x44, sensorIdx, 0x00} 00080 00081 00082 #define SH_AGC_SET_ADCRANGE_CMDSEQ( uiPercentage) {0x50, 0x00, 0x00 , uiPercentage} 00083 #define SH_AGC_SET_STEPSZ_CMDSEQ( uiPercentage) {0x50, 0x00, 0x01 , uiPercentage} 00084 #define SH_AGC_SET_SENSITIVITY_CMDSEQ( uiPercentage) {0x50, 0x00, 0x02 , uiPercentage} 00085 #define SH_AGC_SET_NSAMPLESAVRAGING_CMDSEQ( ucNsamples) {0x50, 0x00, 0x03 , uiNsamples} 00086 #define SH_WHRM_SET_SAMPRATE_CMDSEQ( ucNsamples) {0x50, 0x02, 0x03 , uiNsamples} 00087 00088 00089 #define SH_ENABLE_ALGO_CMDSEQ( algoIdx) { 0x52, algoIdx , 0x01} 00090 #define SH_DISABLE_ALGO_CMDSEQ( algoIdx) { 0x52, algoIdx , 0x00} 00091 00092 #define SH_SET_ALGO_CONFIGURATION_CMDSEQ( algoIdx, cgfIdx) { 0x50 , algoIdx, cgfIdx } 00093 #define SH_GET_ALGO_CONFIGURATION_CMDSEQ( algoIdx, cgfIdx) { 0x51 , algoIdx, cgfIdx } 00094 00095 #define SH_COMM_CHECK_CMDSEQ {0xFF, 0x00} 00096 00097 00098 00099 //phase2 additions 00100 #define SH_CHECKIF_BOOTLDRMODE_CMDSEQ { 0x02, 0x00 } 00101 #define SH_SELFTEST_CMDSEQ(idx) { 0x70, (uint8_t)idx } 00102 #define SH_EXIT_BOOTLDRMODE_CMDSEQ { 0x01, 0x00 } 00103 #define SH_GETLOGSIZE_CMDSEQ { 0x90, 0x01 } 00104 #define SH_READHUBLOGS_CMDSEQ { 0x90, 0x00 } 00105 00106 #define SH_GET_BOOTLDRPAGESIZE_CMDSEQ { 0x81, 0x01 } 00107 #define SH_SET_BOOTLDRPAGECOUNT_CMDSEQ { 0x80, 0x02 } 00108 00109 #define BOOTLOADER_MAX_PAGE_SIZE 8192 00110 00111 /* BOOTLOADER HOST */ 00112 #define EBL_CMD_TRIGGER_MODE 0 00113 #define EBL_GPIO_TRIGGER_MODE 1 00114 00115 00116 00117 /* 00118 * define the "platform specific" hardware interface which SSinterface requires: 00119 * 1. master i2c port 00120 * 2. interrupt attachable I/O pin (mfio) 00121 * 3. I/O pin for reset 00122 * Note: Definitions below are for MAX32630FTR Pagasus board . Modify for your platform. 00123 **/ 00124 00125 I2C *m_i2cBus; /*i2c bus sensor hub is connected to*/ 00126 00127 PinName ss_mfio(P5_4); /* platform specific mfio event pin */ 00128 PinName ss_reset(P5_6); /* platform specific sensor hub reset pin */ 00129 DigitalInOut mfio_pin(ss_mfio); /* mfio pin mode be I/O */ 00130 DigitalInOut reset_pin(ss_reset); /* reset pin mode be I/O */ 00131 InterruptIn irq_pin(ss_mfio); /* define mfio pin interrupt attachable*/ 00132 00133 00134 /* 00135 * SSI API funcions 00136 * NOTE: Generic functions for any platform. 00137 * exceptions: below needs needs modification according to platform and HAL drivers 00138 * 1. Hard reset function 00139 * 2. Enable/disable mfio event interrput 00140 * 3. mfio pin interrupt routine 00141 * 00142 * **/ 00143 00144 /*global buffer for sensor i2c commands+data*/ 00145 uint8_t sh_write_buf[512]; 00146 static volatile bool m_irq_received_ = false; 00147 static volatile bool mfio_int_happened = false; 00148 00149 /* sensor hub states */ 00150 static bool sc_en = false; 00151 static int data_type = 0; 00152 static int is_sensor_enabled[SS_MAX_SUPPORTED_SENSOR_NUM] = {0}; 00153 static int is_algo_enabled[SS_MAX_SUPPORTED_ALGO_NUM] = {0}; 00154 static int enabled_algo_mode[SS_MAX_SUPPORTED_ALGO_NUM] = {0}; 00155 static int sensor_sample_sz[SS_MAX_SUPPORTED_SENSOR_NUM] = {0}; 00156 static int algo_sample_sz[SS_MAX_SUPPORTED_ALGO_NUM] = {0}; 00157 00158 /* Mode to control sesnor hub resets. ie via GPIO based hard reset or Command based soft reset*/ 00159 static uint8_t ebl_mode = EBL_GPIO_TRIGGER_MODE; 00160 00161 /* desc : 00162 * Func to init master i2c hardware comm interface with sennor hub 00163 * init mfio interrupt pin and attach irq to pin 00164 * init reset pin 00165 * params: 00166 * N/A 00167 */ 00168 00169 00170 void sh_irq_handler(); 00171 void sh_init_hwcomm_interface(){ 00172 static I2C ssI2C(P3_4, P3_5); /*set up sensor hub i2c communication at 400 kHz*/ 00173 ssI2C.frequency(400000); 00174 m_i2cBus = &ssI2C; 00175 00176 reset_pin.input(); 00177 reset_pin.mode(PullUp); 00178 mfio_pin.input(); /*set mfio as input for getting mfio event reporting when sesnor hub is on application mode */ 00179 mfio_pin.mode(PullUp); 00180 00181 irq_pin.fall(sh_irq_handler); /*attach falling edge interrupt to mfio pin for mfio event reporting */ 00182 00183 return; 00184 } 00185 00186 /* mfio pin event reporting related interrupt functions*/ 00187 /* 00188 * data ready event reporting isr from sensor hub 00189 * 00190 * params: 00191 * N/A 00192 * */ 00193 void sh_irq_handler() 00194 { 00195 m_irq_received_ = true; 00196 } 00197 void sh_clear_mfio_event_flag(void){ 00198 m_irq_received_ = false; 00199 } 00200 00201 bool sh_has_mfio_event(void){ 00202 return m_irq_received_; 00203 } 00204 00205 /* desc: 00206 * func to enable event reporting from sensor hub 00207 * 00208 * params: 00209 * N/A 00210 * */ 00211 void sh_enable_irq_mfioevent(void) 00212 { 00213 irq_pin.enable_irq(); 00214 } 00215 00216 /* desc: 00217 * func to disable event reporting from sensor hub 00218 * 00219 * params: 00220 * N/A 00221 * */ 00222 void sh_disable_irq_mfioevent(void) 00223 { 00224 irq_pin.disable_irq(); 00225 } 00226 00227 /* desc: 00228 * reset event reporting process from sensor hub, on host side 00229 * 00230 * params: 00231 * N/A 00232 **/ 00233 bool sh_reset_mfio_irq(){ 00234 bool ret = mfio_int_happened; 00235 mfio_int_happened = false; 00236 sh_disable_irq_mfioevent(); 00237 irq_pin.fall(sh_irq_handler); 00238 sh_enable_irq_mfioevent(); 00239 return ret; 00240 } 00241 00242 00243 /* 00244 * desc: 00245 * function to reset sensor hub and put to application mode after reset interface and get data format. 00246 * 00247 * params: 00248 * 00249 * __I wakeupMode : 0x00 : application mode 00250 * 0x08 : bootloader mode 00251 * */ 00252 int sh_hard_reset(int wakeupMode){ 00253 00254 int status; 00255 sh_disable_irq_mfioevent(); 00256 reset_pin.output(); 00257 mfio_pin.output(); 00258 00259 reset_pin.write(0); 00260 wait_ms(SS_RESET_TIME); 00261 00262 if( (wakeupMode & 0xFF) == 0 ) { 00263 00264 mfio_pin.write(1); 00265 reset_pin.write(1); 00266 wait_ms(SS_STARTUP_TO_MAIN_APP_TIME); 00267 00268 }else { 00269 00270 mfio_pin.write(0); 00271 reset_pin.write(1); 00272 wait_ms(SS_STARTUP_TO_BTLDR_TIME); 00273 } 00274 mfio_pin.input(); 00275 mfio_pin.mode(PullUp); 00276 reset_pin.input(); 00277 sh_enable_irq_mfioevent(); 00278 00279 00280 } 00281 00282 00283 int sh_set_ebl_mode(const uint8_t mode) 00284 { 00285 int status; 00286 if (mode == EBL_CMD_TRIGGER_MODE || mode == EBL_GPIO_TRIGGER_MODE) { 00287 ebl_mode = mode; 00288 status = SS_SUCCESS; 00289 } else 00290 status = SS_ERR_INPUT_VALUE; 00291 00292 return status; 00293 } 00294 00295 const int sh_get_ebl_mode(void) 00296 { 00297 return ebl_mode; 00298 } 00299 00300 int sh_reset_to_bootloader(void){ 00301 00302 int status; 00303 uint8_t hubMode; 00304 00305 if(ebl_mode == EBL_GPIO_TRIGGER_MODE) 00306 sh_hard_reset(0x08); 00307 if(ebl_mode == EBL_CMD_TRIGGER_MODE) 00308 status = sh_set_sensorhub_operating_mode(0x08); 00309 00310 status = sh_get_sensorhub_operating_mode(&hubMode); 00311 if( status != 0x00 /*SS_SUCCESS*/ || hubMode != 0x08 ){ 00312 status = -1; 00313 } 00314 00315 return status; 00316 00317 } 00318 00319 static bool in_bootldr; 00320 00321 00322 int in_bootldr_mode() 00323 { 00324 uint8_t cmd_bytes[] = { SS_FAM_R_MODE, SS_CMDIDX_MODE }; 00325 uint8_t rxbuf[2] = { 0 }; 00326 00327 int status = sh_read_cmd(&cmd_bytes[0], sizeof(cmd_bytes), 00328 0, 0, 00329 &rxbuf[0], sizeof(rxbuf), SS_DEFAULT_CMD_SLEEP_MS); 00330 if (status != SS_SUCCESS) 00331 return -1; 00332 00333 return (rxbuf[1] & SS_MASK_MODE_BOOTLDR); 00334 } 00335 00336 int exit_from_bootloader(void) 00337 { 00338 uint8_t cmd_bytes[] = { SS_FAM_W_MODE, SS_CMDIDX_MODE }; 00339 uint8_t data[] = { 0x00 }; 00340 00341 int status = sh_write_cmd_with_data( &cmd_bytes[0], sizeof(cmd_bytes), 00342 &data[0], 1 /*sizeof(data)*/, 00343 10*SS_DEFAULT_CMD_SLEEP_MS); 00344 00345 in_bootldr = (status == SS_SUCCESS) ? true : false; 00346 00347 return status; 00348 } 00349 00350 static int stay_in_bootloader() 00351 { 00352 uint8_t cmd_bytes[] = { SS_FAM_W_MODE, SS_CMDIDX_MODE }; 00353 uint8_t data[] = { SS_MASK_MODE_BOOTLDR }; 00354 00355 int status = sh_write_cmd_with_data( 00356 &cmd_bytes[0], sizeof(cmd_bytes), 00357 &data[0], sizeof(data), SS_DEFAULT_CMD_SLEEP_MS); 00358 00359 in_bootldr = (status == SS_SUCCESS) ? true : false; 00360 return status; 00361 } 00362 00363 00364 static void cfg_mfio(PinDirection dir) 00365 { 00366 if (dir == PIN_INPUT) { 00367 mfio_pin.input(); 00368 mfio_pin.mode(PullUp); 00369 } else { 00370 sh_enable_irq_mfioevent(); 00371 mfio_pin.output(); 00372 } 00373 } 00374 00375 int sh_debug_reset_to_bootloader(void) 00376 { 00377 00378 int status = -1; 00379 00380 sh_disable_irq_mfioevent(); 00381 if (ebl_mode == EBL_GPIO_TRIGGER_MODE) { 00382 00383 reset_pin.output(); 00384 cfg_mfio(PIN_OUTPUT); 00385 reset_pin.write(0); 00386 wait_ms(SS_RESET_TIME); 00387 mfio_pin.write(0); 00388 reset_pin.write(1); 00389 wait_ms(SS_STARTUP_TO_BTLDR_TIME); 00390 cfg_mfio(PIN_INPUT); 00391 reset_pin.input(); 00392 sh_enable_irq_mfioevent(); 00393 stay_in_bootloader(); 00394 if (in_bootldr_mode() < 0) 00395 status = SS_ERR_UNKNOWN; 00396 else 00397 status = SS_SUCCESS; 00398 00399 }else{ 00400 stay_in_bootloader(); 00401 sh_enable_irq_mfioevent(); 00402 status = SS_SUCCESS; 00403 00404 } 00405 00406 return status; 00407 } 00408 00409 00410 int sh_reset_to_main_app(void) 00411 { 00412 int status = -1; 00413 sh_disable_irq_mfioevent(); 00414 if (ebl_mode == EBL_GPIO_TRIGGER_MODE) { 00415 00416 reset_pin.output(); 00417 cfg_mfio(PIN_OUTPUT); 00418 mfio_pin.write(0); 00419 wait_ms(SS_RESET_TIME - 5); 00420 reset_pin.write(0); 00421 wait_ms(SS_RESET_TIME - 5); 00422 mfio_pin.write(1); 00423 wait_ms(SS_RESET_TIME - 5); 00424 reset_pin.write(1); 00425 //wait_ms(50); 00426 //mfio_pin.write(0); 00427 wait_ms(2*SS_STARTUP_TO_MAIN_APP_TIME); 00428 cfg_mfio(PIN_INPUT); 00429 reset_pin.input(); 00430 00431 sh_enable_irq_mfioevent(); 00432 // Verify we exited bootloader mode 00433 if (in_bootldr_mode() == 0) 00434 status = SS_SUCCESS; 00435 else 00436 status = SS_ERR_UNKNOWN; 00437 }else{ 00438 status = exit_from_bootloader(); 00439 sh_enable_irq_mfioevent(); 00440 } 00441 00442 return status; 00443 00444 } 00445 00446 /* 00447 * desc: 00448 * function to init sensor comm interface and get data format. 00449 * 00450 * */ 00451 void sh_init_hubinterface(void){ 00452 00453 sh_init_hwcomm_interface(); 00454 //sh_get_data_type(&data_type, &sc_en); 00455 return; 00456 } 00457 00458 00459 /* 00460 * 00461 * SENSOR HUB COMMUNICATION INTERFACE ( Defined in MAX32664 User Guide ) API FUNCTIONS 00462 * 00463 * 00464 * */ 00465 00466 00467 //PHASE2 ADDITIONS: 00468 00469 int sh_self_test(int idx, uint8_t *result, int sleep_ms){ 00470 00471 uint8_t cmd_bytes[] = { SS_FAM_R_SELFTEST, (uint8_t)idx }; // = SH_SELFTEST_CMDSEQ; 00472 uint8_t rxbuf[2]; 00473 result[0] = 0xFF; 00474 00475 int status = sh_read_cmd(&cmd_bytes[0],sizeof(cmd_bytes) , 00476 0, 0, 00477 &rxbuf[0], sizeof(rxbuf), 00478 sleep_ms ); 00479 00480 if (status != SS_SUCCESS) 00481 return SS_ERR_TRY_AGAIN; 00482 00483 result[0] = rxbuf[1]; 00484 return status; 00485 } 00486 00487 const char* sh_get_hub_fw_version(void) 00488 { 00489 uint8_t cmd_bytes[2]; 00490 uint8_t rxbuf[4]; 00491 00492 static char fw_version[32] = "SENSORHUB"; 00493 00494 int bootldr = sh_checkif_bootldr_mode(); 00495 00496 if (bootldr > 0) { 00497 cmd_bytes[0] = SS_FAM_R_BOOTLOADER; 00498 cmd_bytes[1] = SS_CMDIDX_BOOTFWVERSION; 00499 } else if (bootldr == 0) { 00500 cmd_bytes[0] = SS_FAM_R_IDENTITY; 00501 cmd_bytes[1] = SS_CMDIDX_FWVERSION; 00502 } else { 00503 00504 return &fw_version[0]; 00505 } 00506 00507 int status = sh_read_cmd( &cmd_bytes[0], sizeof(cmd_bytes), 00508 0, 0, 00509 &rxbuf[0], sizeof(rxbuf), 00510 SS_DEFAULT_CMD_SLEEP_MS ); 00511 00512 if (status == SS_SUCCESS) { 00513 snprintf(fw_version, sizeof(fw_version), 00514 "%d.%d.%d", rxbuf[1], rxbuf[2], rxbuf[3]); 00515 } 00516 00517 return &fw_version[0]; 00518 } 00519 00520 00521 const char* sh_get_hub_algo_version(void) 00522 { 00523 uint8_t cmd_bytes[3]; 00524 uint8_t rxbuf[4]; 00525 00526 static char algo_version[64] = "SENSORHUBALGORITHMS"; 00527 00528 int bootldr = sh_checkif_bootldr_mode(); 00529 00530 if (bootldr > 0) { 00531 cmd_bytes[0] = SS_FAM_R_BOOTLOADER; 00532 cmd_bytes[1] = SS_CMDIDX_BOOTFWVERSION; 00533 cmd_bytes[2] = 0; 00534 } else if (bootldr == 0) { 00535 cmd_bytes[0] = SS_FAM_R_IDENTITY; 00536 cmd_bytes[1] = SS_CMDIDX_ALGOVER; 00537 cmd_bytes[2] = SS_CMDIDX_AVAILSENSORS; 00538 } else { 00539 00540 return &algo_version[0]; 00541 } 00542 00543 int status = sh_read_cmd( &cmd_bytes[0], sizeof(cmd_bytes), 00544 0, 0, 00545 &rxbuf[0], sizeof(rxbuf), 00546 SS_DEFAULT_CMD_SLEEP_MS ); 00547 00548 if (status == SS_SUCCESS) { 00549 snprintf(algo_version, sizeof(algo_version), 00550 "%d.%d.%d", rxbuf[1], rxbuf[2], rxbuf[3]); 00551 00552 } 00553 00554 return &algo_version[0]; 00555 } 00556 00557 int sh_send_raw(uint8_t *rawdata, int rawdata_sz) 00558 { 00559 return sh_write_cmd(&rawdata[0], rawdata_sz, 5 * SS_ENABLE_SENSOR_SLEEP_MS); 00560 } 00561 00562 int sh_get_log_len(int *log_len) 00563 { 00564 uint8_t cmd_bytes[] = { SS_FAM_R_LOG, SS_CMDIDX_R_LOG_LEN }; // = SH_GETLOGSIZE_CMDSEQ; 00565 uint8_t rxbuf[2] = {0}; 00566 int logLen = 0; 00567 00568 int status = sh_read_cmd(&cmd_bytes[0], sizeof(cmd_bytes), 00569 0, 0, 00570 &rxbuf[0], sizeof(rxbuf), 00571 SS_DEFAULT_CMD_SLEEP_MS ); 00572 00573 if (status == SS_SUCCESS) { 00574 logLen = (rxbuf[1] << 8) | rxbuf[0]; 00575 } 00576 *log_len = logLen; 00577 00578 return status; 00579 } 00580 00581 int sh_read_ss_log(int num_bytes, uint8_t *log_buf, int log_buf_sz) 00582 { 00583 int bytes_to_read = num_bytes + 1; //+1 for status byte 00584 //mxm_assert_msg((bytes_to_read <= log_buf_sz), "log_buf too small"); 00585 00586 uint8_t cmd_bytes[] = { SS_FAM_R_LOG, SS_CMDIDX_R_LOG_DATA }; // = SH_READHUBLOGS_CMDSEQ; 00587 00588 int status = sh_read_cmd(&cmd_bytes[0], sizeof(cmd_bytes), 00589 0, 0, 00590 log_buf, bytes_to_read, 00591 SS_CMD_WAIT_PULLTRANS_MS ); 00592 00593 return status; 00594 } 00595 00596 // END OF PHASE2 ADDITIONS 00597 00598 00599 00600 00601 int sh_write_cmd( uint8_t *tx_buf, 00602 int tx_len, 00603 int sleep_ms) 00604 { 00605 int retries = SS_DEFAULT_RETRIES; 00606 int ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)tx_buf, tx_len); 00607 while (ret != 0 && retries-- > 0) { 00608 00609 wait_ms(1); 00610 ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)tx_buf, tx_len); 00611 } 00612 if (ret != 0) 00613 return SS_ERR_UNAVAILABLE; 00614 00615 00616 wait_ms(sleep_ms); 00617 00618 char status_byte; 00619 ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, &status_byte, 1); 00620 bool try_again = (status_byte == SS_ERR_TRY_AGAIN); 00621 while ((ret != 0 || try_again) 00622 && retries-- > 0) { 00623 wait_ms(sleep_ms); 00624 ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, &status_byte, 1); 00625 try_again = (status_byte == SS_ERR_TRY_AGAIN); 00626 } 00627 00628 if (ret != 0 || try_again) 00629 return SS_ERR_UNAVAILABLE; 00630 00631 return (int) (SS_STATUS)status_byte; 00632 } 00633 00634 00635 int sh_write_cmd_with_data(uint8_t *cmd_bytes, 00636 int cmd_bytes_len, 00637 uint8_t *data, 00638 int data_len, 00639 int cmd_delay_ms) 00640 { 00641 memcpy(sh_write_buf, cmd_bytes, cmd_bytes_len); 00642 memcpy(sh_write_buf + cmd_bytes_len, data, data_len); 00643 int status = sh_write_cmd(sh_write_buf,cmd_bytes_len + data_len, cmd_delay_ms); 00644 return status; 00645 } 00646 00647 00648 int sh_read_cmd( uint8_t *cmd_bytes, 00649 int cmd_bytes_len, 00650 uint8_t *data, 00651 int data_len, 00652 uint8_t *rxbuf, 00653 int rxbuf_sz, 00654 int sleep_ms ) 00655 { 00656 00657 int retries = SS_DEFAULT_RETRIES; 00658 00659 int ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)cmd_bytes, cmd_bytes_len, (data_len != 0)); 00660 if (data_len != 0) 00661 ret |= m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)data, data_len, false); 00662 00663 00664 while (ret != 0 && retries-- > 0) { 00665 wait_ms(1); 00666 ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)cmd_bytes, cmd_bytes_len, (data_len != 0)); 00667 if (data_len != 0) 00668 ret |= m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)data, data_len, false); 00669 00670 } 00671 if (ret != 0) 00672 return SS_ERR_UNAVAILABLE; 00673 00674 00675 wait_ms(sleep_ms); 00676 00677 ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, (char*)rxbuf, rxbuf_sz); 00678 bool try_again = (rxbuf[0] == SS_ERR_TRY_AGAIN); 00679 while ((ret != 0 || try_again) && retries-- > 0) { 00680 wait_ms(sleep_ms); 00681 ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, (char*)rxbuf, rxbuf_sz); 00682 try_again = (rxbuf[0] == SS_ERR_TRY_AGAIN); 00683 } 00684 if (ret != 0 || try_again) 00685 return SS_ERR_UNAVAILABLE; 00686 00687 return (int) ((SS_STATUS)rxbuf[0]); 00688 } 00689 00690 00691 00692 int sh_get_sensorhub_status(uint8_t *hubStatus){ 00693 00694 uint8_t ByteSeq[] = SH_GET_HUB_STATUS_CMDSEQ; 00695 uint8_t rxbuf[2] = { 0 }; 00696 00697 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 00698 0, 0, 00699 &rxbuf[0], sizeof(rxbuf), 00700 SS_DEFAULT_CMD_SLEEP_MS); 00701 00702 *hubStatus = rxbuf[1]; 00703 return status; 00704 } 00705 00706 00707 int sh_get_sensorhub_operating_mode(uint8_t *hubMode){ 00708 00709 uint8_t ByteSeq[] = SH_GET_OPERATING_MODE_CMDSEQ; 00710 uint8_t rxbuf[2] = { 0 }; 00711 00712 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 00713 0, 0, 00714 &rxbuf[0], sizeof(rxbuf), 00715 SS_DEFAULT_CMD_SLEEP_MS); 00716 00717 *hubMode = rxbuf[1]; 00718 return status; 00719 } 00720 00721 00722 int sh_set_sensorhub_operating_mode(uint8_t hubMode){ 00723 00724 uint8_t ByteSeq[] = SH_SET_OPERATING_MODE_CMDSEQ(hubMode); 00725 int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), SS_DEFAULT_CMD_SLEEP_MS); 00726 return status; 00727 00728 } 00729 00730 00731 //int sh_set_data_type( uint8_t outMode) 00732 int sh_set_data_type(int data_type_, bool sc_en_) 00733 { 00734 00735 #if 0 00736 uint8_t dataTypeSc = (uint8_t)((sc_en ? SS_MASK_OUTPUTMODE_SC_EN : 0) | ((data_type << SS_SHIFT_OUTPUTMODE_DATATYPE) & SS_MASK_OUTPUTMODE_DATATYPE)); 00737 uint8_t ByteSeq[] = SH_SET_OUTPUT_MODE_CMDSEQ( dataTypeSc); 00738 int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), SS_DEFAULT_CMD_SLEEP_MS); 00739 if( status == 0x00){ 00740 data_type = data_type_; 00741 sc_en = sc_en_; 00742 } 00743 #endif 00744 00745 uint8_t cmd_bytes[] = { SS_FAM_W_COMMCHAN, SS_CMDIDX_OUTPUTMODE }; 00746 uint8_t data_bytes[] = { (uint8_t)((sc_en_ ? SS_MASK_OUTPUTMODE_SC_EN : 0) | 00747 ((data_type_ << SS_SHIFT_OUTPUTMODE_DATATYPE) & SS_MASK_OUTPUTMODE_DATATYPE)) }; 00748 00749 int status = sh_write_cmd_with_data(&cmd_bytes[0], sizeof(cmd_bytes), 00750 &data_bytes[0], sizeof(data_bytes), 00751 SS_DEFAULT_CMD_SLEEP_MS); 00752 data_type = data_type_; 00753 sc_en = sc_en_; 00754 00755 return status; 00756 } 00757 00758 00759 int sh_get_data_type(int *data_type_, bool *sc_en_){ 00760 00761 uint8_t ByteSeq[] = SH_GET_OUTPUT_MODE_CMDSEQ; 00762 uint8_t rxbuf[2] = {0}; 00763 int status = sh_read_cmd( &ByteSeq[0], sizeof(ByteSeq), 00764 0, 0, 00765 &rxbuf[0], sizeof(rxbuf), 00766 SS_DEFAULT_CMD_SLEEP_MS); 00767 if (status == 0x00 /*SS_SUCCESS*/) { 00768 *data_type_ = 00769 (rxbuf[1] & SS_MASK_OUTPUTMODE_DATATYPE) >> SS_SHIFT_OUTPUTMODE_DATATYPE; 00770 *sc_en_ = 00771 (bool)((rxbuf[1] & SS_MASK_OUTPUTMODE_SC_EN) >> SS_SHIFT_OUTPUTMODE_SC_EN); 00772 00773 } 00774 00775 return status; 00776 00777 } 00778 00779 00780 int sh_set_fifo_thresh( int threshold ){ 00781 00782 #if 0 00783 uint8_t ucThresh = (uint8_t) (threshold & 0xFF); 00784 uint8_t ByteSeq[] = SH_DFIFO_SET_INT_THRESHOLD_CMDSEQ(ucThresh ); 00785 int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), SS_DEFAULT_CMD_SLEEP_MS); 00786 return status; 00787 #endif 00788 00789 uint8_t cmd_bytes[] = { SS_FAM_W_COMMCHAN, SS_CMDIDX_FIFOAFULL }; 00790 uint8_t data_bytes[] = { (uint8_t)threshold }; 00791 00792 int status = sh_write_cmd_with_data(&cmd_bytes[0], sizeof(cmd_bytes), 00793 &data_bytes[0], sizeof(data_bytes), 00794 SS_DEFAULT_CMD_SLEEP_MS 00795 ); 00796 return status; 00797 00798 } 00799 00800 00801 int sh_get_fifo_thresh(int *thresh){ 00802 00803 uint8_t ByteSeq[] = SH_DFIFO_GET_INT_THRESHOLD_CMDSEQ; 00804 uint8_t rxbuf[2] = {0}; 00805 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 00806 0, 0, 00807 &rxbuf[0], sizeof(rxbuf), 00808 SS_DEFAULT_CMD_SLEEP_MS); 00809 00810 *thresh = (int) rxbuf[1]; 00811 00812 return status; 00813 00814 } 00815 00816 00817 int sh_ss_comm_check(void){ 00818 00819 00820 uint8_t ByteSeq[] = SH_COMM_CHECK_CMDSEQ; 00821 uint8_t rxbuf[2]; 00822 00823 int status = sh_read_cmd( &ByteSeq[0], sizeof(ByteSeq), 00824 0, 0, 00825 &rxbuf[0], sizeof(rxbuf), 00826 SS_DEFAULT_CMD_SLEEP_MS ); 00827 00828 int tries = 4; 00829 while (status == SS_ERR_TRY_AGAIN && tries--) { 00830 wait_ms(1000); 00831 status = sh_read_cmd( &ByteSeq[0], sizeof(ByteSeq), 00832 0, 0, 00833 &rxbuf[0], sizeof(rxbuf), 00834 SS_DEFAULT_CMD_SLEEP_MS ); 00835 00836 } 00837 00838 return status; 00839 } 00840 00841 00842 int sh_num_avail_samples(int *numSamples) { 00843 00844 uint8_t ByteSeq[] = SH_DFIFO_GET_NSAMPLES_CMDSEQ; 00845 uint8_t rxbuf[2] = {0}; 00846 00847 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 00848 0, 0, 00849 &rxbuf[0], sizeof(rxbuf), 00850 1); 00851 00852 *numSamples = (int) rxbuf[1]; 00853 00854 return status; 00855 } 00856 00857 00858 int sh_read_fifo_data( int numSamples, 00859 int sampleSize, 00860 uint8_t* databuf, 00861 int databufSz) { 00862 00863 int bytes_to_read = numSamples * sampleSize + 1; //+1 for status byte 00864 00865 uint8_t ByteSeq[] = SH_DFIFO_PULL_SAMPLE_CMDSEQ; 00866 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 00867 0, 0, 00868 databuf, bytes_to_read, 00869 10); 00870 00871 return status; 00872 } 00873 00874 00875 /* 00876 * desc: 00877 * func to read sample size for SmartSensor input FIFO for extrenal accel data 00878 * 00879 * params: 00880 * __O sampSize: size of data sample struct in bytes 00881 * returns: 00882 * 1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success 00883 * 00884 **/ 00885 int sh_read_input_fifo_samplesz( int *sampSize){ 00886 00887 /* NOT IMPLEMENTED IN SS INTERFACE */ 00888 00889 } 00890 00891 /* 00892 * desc: 00893 * func to write data samples to SmartSensor input FIFO for extrenal accel data 00894 * 00895 * params: 00896 ... 00897 * returns: 00898 * 1 byte status (SS_STATUS) : 0x00 (SS_SUCCESS) on success 00899 */ 00900 int sh_write_input_fifo( void *arg){ 00901 00902 /* NOT IMPLEMENTED IN SS INTERFACE */ 00903 00904 } 00905 00906 00907 int sh_set_reg(int idx, uint8_t addr, uint32_t val, int regSz){ 00908 00909 uint8_t ByteSeq[] = SH_WRITE_SENSORREG_CMDSEQ( ((uint8_t)idx) , addr ); 00910 uint8_t data_bytes[4]; 00911 for (int i = 0; i < regSz; i++) { 00912 data_bytes[i] = (val >> (8 * (regSz - 1)) & 0xFF); 00913 } 00914 int status = sh_write_cmd_with_data( &ByteSeq[0], sizeof(ByteSeq), 00915 &data_bytes[0], (uint8_t) regSz, 00916 SS_DEFAULT_CMD_SLEEP_MS); 00917 00918 return status; 00919 } 00920 00921 00922 int sh_get_reg(int idx, uint8_t addr, uint32_t *val){ 00923 00924 00925 uint32_t i32tmp; 00926 uint8_t ByteSeq[] = SH_READ_AFE_ATTRIBUTES_CMDSEQ(((uint8_t) idx)); 00927 uint8_t rxbuf[3] = {0}; 00928 00929 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 00930 0, 0, 00931 &rxbuf[0], sizeof(rxbuf), 00932 SS_DEFAULT_CMD_SLEEP_MS); 00933 00934 00935 if(status == 0x00 /* SS_SUCCESS */) { 00936 00937 int reg_width = rxbuf[1]; 00938 uint8_t ByteSeq2[] = SH_READ_SENSORREG_CMDSEQ( ((uint8_t)idx) , addr ); 00939 uint8_t rxbuf2[5] = {0}; 00940 status = sh_read_cmd(&ByteSeq2[0], sizeof(ByteSeq2), 00941 0, 0, 00942 &rxbuf2[0], reg_width + 1, 00943 SS_DEFAULT_CMD_SLEEP_MS); 00944 00945 if (status == 0x00 /* SS_SUCCESS */) { 00946 i32tmp = 0; 00947 for (int i = 0; i < reg_width; i++) { 00948 i32tmp = (i32tmp << 8) | rxbuf2[i + 1]; 00949 } 00950 *val = i32tmp; 00951 } 00952 } 00953 00954 return status; 00955 00956 } 00957 00958 00959 int sh_sensor_enable( int idx , int sensorSampleSz , uint8_t ext_mode ){ 00960 00961 uint8_t ByteSeq[] = SH_ENABLE_SENSOR_CMDSEQ( ((uint8_t) idx) , ((uint8_t) ext_mode)); 00962 int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), 5 * SS_ENABLE_SENSOR_SLEEP_MS); 00963 if(status == 0x00){ 00964 00965 is_sensor_enabled[idx] = ENABLED; 00966 sensor_sample_sz[idx] = sensorSampleSz; 00967 } 00968 return status; 00969 00970 } 00971 00972 00973 int sh_sensor_disable( int idx ){ 00974 00975 uint8_t ByteSeq[] = SH_DISABLE_SENSOR_CMDSEQ( ((uint8_t) idx)); 00976 int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), SS_ENABLE_SENSOR_SLEEP_MS); 00977 if(status == 0x00){ 00978 00979 is_sensor_enabled[idx] = DISABLED; 00980 } 00981 return status; 00982 00983 } 00984 00985 00986 int sh_get_input_fifo_size(int *fifo_size) 00987 { 00988 00989 uint8_t ByteSeq[] = SH_GET_EXTINPUT_FIFOSZ_CMDSEQ; 00990 uint8_t rxbuf[3]; /* status + fifo size */ 00991 00992 00993 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 00994 0, 0, 00995 rxbuf, sizeof(rxbuf), 2*SS_DEFAULT_CMD_SLEEP_MS); 00996 00997 *fifo_size = rxbuf[1] << 8 | rxbuf[2]; 00998 return status; 00999 } 01000 01001 01002 int sh_feed_to_input_fifo(uint8_t *tx_buf, int tx_buf_sz, int *nb_written) 01003 { 01004 int status; 01005 01006 uint8_t ByteSeq[] = SH_FEED_TO_INPUTFIFO_CMDSEQ; 01007 uint8_t rxbuf[3]; 01008 01009 tx_buf[0] = 0x14; 01010 tx_buf[1] = 0x00; 01011 01012 status= sh_read_cmd(tx_buf, tx_buf_sz, 01013 0, 0, 01014 rxbuf, sizeof(rxbuf), SS_FEEDFIFO_CMD_SLEEP_MS); 01015 01016 *nb_written = rxbuf[1] * 256 + rxbuf[2]; 01017 return status; 01018 } 01019 01020 01021 int sh_get_num_bytes_in_input_fifo(int *fifo_size) 01022 { 01023 01024 uint8_t ByteSeq[] = SH_GET_SAMPLEBYTECNT_INPUTFIFO_CMDSEQ; 01025 uint8_t rxbuf[3]; /* status + fifo size */ 01026 01027 01028 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 01029 0, 0, 01030 rxbuf, sizeof(rxbuf), 01031 2*SS_DEFAULT_CMD_SLEEP_MS); 01032 01033 *fifo_size = rxbuf[1] << 8 | rxbuf[2]; 01034 return status; 01035 } 01036 01037 01038 /* 01039 * ALGARITIM RELATED FUNCTIONS :) 01040 * 01041 * 01042 * 01043 * 01044 * 01045 * */ 01046 01047 01048 int sh_enable_algo(int idx , int algoSampleSz){ 01049 01050 uint8_t ByteSeq[] = SH_ENABLE_ALGO_CMDSEQ( ((uint8_t) idx) ); 01051 int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), 25 * SS_ENABLE_SENSOR_SLEEP_MS); 01052 if(status == 0x00){ 01053 01054 is_algo_enabled[idx] = ENABLED; 01055 algo_sample_sz[idx] = algoSampleSz; 01056 } 01057 return status; 01058 01059 } 01060 01061 01062 int sh_enable_algo_withmode(int idx, int mode, int algoSampleSz) 01063 { 01064 01065 uint8_t cmd_bytes[] = { SS_FAM_W_ALGOMODE, (uint8_t)idx, (uint8_t)mode }; 01066 01067 int status = sh_write_cmd_with_data(&cmd_bytes[0], sizeof(cmd_bytes), 0, 0, 25 * SS_ENABLE_SENSOR_SLEEP_MS); 01068 01069 if (status == SS_SUCCESS) { 01070 is_algo_enabled[idx] = ENABLED; 01071 algo_sample_sz[idx] = algoSampleSz; 01072 enabled_algo_mode[idx] = mode; 01073 } 01074 01075 return status; 01076 } 01077 01078 01079 01080 int sh_disable_algo(int idx){ 01081 01082 uint8_t ByteSeq[] = SH_DISABLE_ALGO_CMDSEQ( ((uint8_t) idx) ); 01083 int status = sh_write_cmd( &ByteSeq[0],sizeof(ByteSeq), SS_ENABLE_SENSOR_SLEEP_MS ); 01084 if(status == 0x00){ 01085 01086 is_algo_enabled[idx] = DISABLED; 01087 } 01088 return status; 01089 01090 } 01091 01092 01093 int sh_set_algo_cfg(int algo_idx, int cfg_idx, uint8_t *cfg, int cfg_sz){ 01094 01095 uint8_t ByteSeq[] = SH_SET_ALGO_CONFIGURATION_CMDSEQ( ((uint8_t) algo_idx) , ((uint8_t) cfg_idx) ); 01096 int status = sh_write_cmd_with_data( &ByteSeq[0], sizeof(ByteSeq), 01097 cfg, cfg_sz, 01098 SS_DEFAULT_CMD_SLEEP_MS); 01099 01100 return status; 01101 01102 } 01103 01104 01105 int sh_get_algo_cfg(int algo_idx, int cfg_idx, uint8_t *cfg, int cfg_sz){ 01106 01107 uint8_t ByteSeq[] = SH_GET_ALGO_CONFIGURATION_CMDSEQ( ((uint8_t) algo_idx) , ((uint8_t) cfg_idx) ); 01108 int status = sh_read_cmd(&ByteSeq[0], sizeof(ByteSeq), 01109 0, 0, 01110 cfg, cfg_sz, 01111 SS_DEFAULT_CMD_SLEEP_MS); 01112 return status; 01113 01114 } 01115 01116 01117 /* 01118 * desc: 01119 * func to get active cumulative sample size of sensor hub in order to 01120 * calculate number of bytes to be read from sensor hub report data buffer 01121 * 01122 * params: 01123 * __I data_type : active data type of sensor hub -> no data :0 (SS_DATATYPE_PAUSE) 01124 * raw sensor data only :1 (SS_DATATYPE_RAW) 01125 * algo data only :2 (SS_DATATYPE_ALGO) 01126 * algo+raw data :3 (SS_DATATYPE_BOTH) 01127 * __O sample_size : calculated active cumulative sample size 01128 01129 * returns: 01130 * N/A 01131 * 01132 **/ 01133 static void fifo_sample_size(int data_type_, int *sample_size) 01134 { 01135 01136 int tmpSz = 0; 01137 //*sample_size = 0; 01138 01139 if (data_type_ == SS_DATATYPE_RAW || data_type_ == SS_DATATYPE_BOTH) { 01140 for (int i = 0; i < SS_MAX_SUPPORTED_SENSOR_NUM; i++) { 01141 if (is_sensor_enabled[i]) { 01142 tmpSz += sensor_sample_sz[i]; 01143 //*sample_size += sensor_data_reqs[i]->data_size; 01144 } 01145 } 01146 } 01147 01148 if (data_type_ == SS_DATATYPE_ALGO || data_type_ == SS_DATATYPE_BOTH) { 01149 for (int i = 0; i < SS_MAX_SUPPORTED_ALGO_NUM; i++) { 01150 if (is_algo_enabled[i]) { 01151 tmpSz += algo_sample_sz[i]; 01152 //*sample_size += algo_data_reqs[i]->data_size; 01153 } 01154 } 01155 } 01156 01157 *sample_size = tmpSz; 01158 } 01159 01160 01161 int sh_ss_execute_once( uint8_t *databuf , int databufLen , int *nSamplesRead){ 01162 01163 if(m_irq_received_ == false) { 01164 *nSamplesRead = 0; 01165 return -1; 01166 } 01167 01168 uint8_t sample_count; 01169 01170 sh_disable_irq_mfioevent(); 01171 sh_clear_mfio_event_flag(); 01172 01173 uint8_t hubStatus = 0; 01174 int status = sh_get_sensorhub_status(&hubStatus); 01175 if(status != 0x00 /*SS_SUCCESS*/){ 01176 *nSamplesRead = 0; 01177 sh_enable_irq_mfioevent(); 01178 return status; 01179 } 01180 01181 if (hubStatus & SS_MASK_STATUS_DATA_RDY) { 01182 01183 int num_samples = 1; 01184 status = sh_num_avail_samples(&num_samples); 01185 if (status != 0x00 /*SS_SUCCESS*/){ 01186 *nSamplesRead = 0; 01187 sh_enable_irq_mfioevent(); 01188 return status; 01189 } 01190 01191 01192 int sample_size; 01193 fifo_sample_size(data_type, &sample_size); 01194 /*DEBUG */// 01195 01196 01197 int bytes_to_read = num_samples * sample_size + 1; //+1 for status byte 01198 if ( bytes_to_read > databufLen) { 01199 //Reduce number of samples to read to fit in buffer 01200 num_samples = (databufLen - 1) / sample_size; 01201 } 01202 01203 01204 wait_ms(5); 01205 status = sh_read_fifo_data(num_samples, sample_size, &databuf[0], databufLen); 01206 if(status != 0x00 /*SS_SUCCESS*/){ 01207 *nSamplesRead = 0; 01208 sh_enable_irq_mfioevent(); 01209 return status; 01210 } 01211 *nSamplesRead = num_samples; 01212 } 01213 01214 sh_enable_irq_mfioevent(); 01215 return status; 01216 } 01217 01218 01219 01220 /* 01221 * BOOTLOADER RELATED FUNCTIONS 01222 * 01223 * 01224 * */ 01225 01226 static const int aes_nonce_sz = 11; 01227 static const int aes_auth_sz = 16; 01228 static int bl_comm_delay_factor = 1; 01229 01230 01231 01232 int sh_set_bootloader_delayfactor(const int factor ) { 01233 01234 int status = -1; 01235 if( factor >= 1 && factor < 51){ 01236 bl_comm_delay_factor = factor; 01237 status = 0x00; 01238 } 01239 01240 return status; 01241 01242 } 01243 01244 const int sh_get_bootloader_delayfactor(void){ 01245 01246 return bl_comm_delay_factor; 01247 } 01248 01249 int sh_exit_from_bootloader(void) 01250 { 01251 01252 return sh_reset_to_main_app(); //sh_set_sensorhub_operating_mode(0x00); 01253 } 01254 01255 int sh_put_in_bootloader(void) 01256 { 01257 return sh_set_sensorhub_operating_mode( 0x08); 01258 } 01259 01260 int sh_checkif_bootldr_mode(void) 01261 { 01262 uint8_t hubMode; 01263 int status = sh_get_sensorhub_operating_mode(&hubMode); 01264 return (status != SS_SUCCESS)? -1:(hubMode & SS_MASK_MODE_BOOTLDR); 01265 } 01266 01267 int sh_get_bootloader_pagesz(int *pagesz){ 01268 01269 //uint8_t ByteSeq[]= SH_GET_BOOTLDRPAGESIZE_CMDSEQ; 01270 uint8_t ByteSeq[]= { SS_FAM_R_BOOTLOADER, SS_CMDIDX_PAGESIZE }; 01271 uint8_t rxbuf[3]; 01272 int sz = 0; 01273 01274 int status = sh_read_cmd( &ByteSeq[0], sizeof(ByteSeq), 01275 0, 0, 01276 &rxbuf[0], sizeof(rxbuf), 01277 SS_DEFAULT_CMD_SLEEP_MS); 01278 if (status == 0x00) { 01279 //rxbuf holds page size in big-endian format 01280 sz = (256*(int)rxbuf[1]) + rxbuf[2]; 01281 if(sz > BOOTLOADER_MAX_PAGE_SIZE ) { 01282 sz = -2; 01283 } 01284 } 01285 01286 *pagesz = sz; 01287 01288 return status; 01289 01290 } 01291 01292 int sh_set_bootloader_numberofpages(const int pageCount){ 01293 01294 //uint8_t ByteSeq[] = SH_SET_BOOTLDRPAGECOUNT_CMDSEQ; 01295 uint8_t ByteSeq[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETNUMPAGES }; 01296 //num pages = 256*MSB + LSB 01297 uint8_t data_bytes[] = { (uint8_t)((pageCount >> 8) & 0xFF), (uint8_t)(pageCount & 0xFF) }; 01298 01299 int status = sh_write_cmd_with_data(&ByteSeq[0], sizeof(ByteSeq), 01300 &data_bytes[0], sizeof(data_bytes), 01301 bl_comm_delay_factor * SS_DEFAULT_CMD_SLEEP_MS ); 01302 01303 return status; 01304 01305 } 01306 01307 int sh_set_bootloader_iv(uint8_t iv_bytes[aes_nonce_sz]){ 01308 01309 uint8_t ByteSeq[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETIV }; 01310 int status = sh_write_cmd_with_data( &ByteSeq[0], sizeof(ByteSeq), 01311 &iv_bytes[0], aes_nonce_sz /*sizeof(iv_bytes)*/, 01312 bl_comm_delay_factor * SS_DEFAULT_CMD_SLEEP_MS 01313 ); 01314 01315 return status; 01316 01317 } 01318 01319 01320 int sh_set_bootloader_auth(uint8_t auth_bytes[aes_auth_sz]){ 01321 01322 uint8_t ByteSeq[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETAUTH }; 01323 int status = sh_write_cmd_with_data( &ByteSeq[0], sizeof(ByteSeq), 01324 &auth_bytes[0], aes_auth_sz /*sizeof(auth_bytes)*/, 01325 bl_comm_delay_factor * SS_DEFAULT_CMD_SLEEP_MS 01326 ); 01327 01328 return status; 01329 01330 } 01331 01332 01333 int sh_set_bootloader_erase(void){ 01334 01335 uint8_t ByteSeq[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_ERASE }; 01336 01337 int status = sh_write_cmd_with_data(&ByteSeq[0], sizeof(ByteSeq), 01338 0, 0, 01339 bl_comm_delay_factor * SS_BOOTLOADER_ERASE_DELAY); 01340 01341 return status; 01342 01343 } 01344 01345 01346 int sh_bootloader_flashpage(uint8_t *flashDataPreceedByCmdBytes , const int page_size){ 01347 01348 static const int flash_cmdbytes_len = 2; 01349 static const int check_bytes_len = 16; 01350 static const int page_write_time_ms = 200; 01351 01352 //static const uint8_t ByteSeq[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SENDPAGE }; 01353 int status = -1; 01354 01355 if( (*flashDataPreceedByCmdBytes == SS_FAM_W_BOOTLOADER) && ( *(flashDataPreceedByCmdBytes+1) == SS_CMDIDX_SENDPAGE ) ) { 01356 01357 /* We do not use sh_write_cmd_with_data function because internal buffers of the function 01358 is limited to 512 bytes which does not support if flashing page size is bigger */ 01359 status = sh_write_cmd(flashDataPreceedByCmdBytes, page_size + check_bytes_len + flash_cmdbytes_len, bl_comm_delay_factor * page_write_time_ms); 01360 01361 } 01362 return status; 01363 01364 } 01365 01366 01367 int sh_get_ss_fw_version(uint8_t *fwDesciptor , uint8_t *descSize) 01368 { 01369 01370 int status = -1; 01371 uint8_t cmd_bytes[2]; 01372 uint8_t rxbuf[4]; 01373 01374 int bootldr = in_bootldr_mode(); 01375 01376 if (bootldr > 0) { 01377 cmd_bytes[0] = SS_FAM_R_BOOTLOADER; 01378 cmd_bytes[1] = SS_CMDIDX_BOOTFWVERSION; 01379 } else if (bootldr == 0) { 01380 cmd_bytes[0] = SS_FAM_R_IDENTITY; 01381 cmd_bytes[1] = SS_CMDIDX_FWVERSION; 01382 } else { 01383 return -1; 01384 } 01385 01386 status = sh_read_cmd( &cmd_bytes[0], sizeof(cmd_bytes), 01387 0, 0, 01388 &rxbuf[0], sizeof(rxbuf) , 01389 SS_DEFAULT_CMD_SLEEP_MS ); 01390 01391 if (status == 0x00 /*SS_SUCCESS*/) { 01392 *fwDesciptor = rxbuf[1]; 01393 *(fwDesciptor + 1) = rxbuf[2]; 01394 *(fwDesciptor + 2) = rxbuf[3]; 01395 *descSize = 3; 01396 }else{ 01397 *descSize = 0; 01398 } 01399 01400 return status; 01401 01402 } 01403 01404 01405 /* 01406 #ifdef __cplusplus 01407 } 01408 #endif 01409 */ 01410 01411
Generated on Fri Jul 15 2022 22:42:36 by
