YOSHIHISA TABUCHI / Mbed OS Host_Software_MAX32664GWEB_HR_EXTENDEDtest

Dependencies:   BMI160 max32630hsp3 MemoryLCD USBDevice

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SHComm.cpp Source File

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