Source code for Maxim Sensor Hub Communications. Mostly C library for MAX32664 sensor hub communications.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SHComm.cpp Source File

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