Arun Raj / Mbed OS MAXREFDES101_SOURCE

Dependencies:   max32630fthr Adafruit_FeatherOLED USBDevice

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SSInterface.cpp Source File

SSInterface.cpp

00001 /***************************************************************************
00002 * Copyright (C) 2017 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 #include "SSInterface.h"
00035 
00036 #include "../../Utilities/mxm_assert.h"
00037 #include "Peripherals.h"
00038 #include "utils.h"
00039 #include "i2cm.h"
00040 
00041 #include "pwrman_regs.h"
00042 #include "ioman.h"
00043 
00044 
00045 
00046 SSInterface::SSInterface(I2C &i2cBus, PinName ss_mfio, PinName ss_reset)
00047     :m_i2cBus(&i2cBus), m_spiBus(NULL),
00048     mfio_pin(ss_mfio), reset_pin(ss_reset), irq_pin(ss_mfio)/*,
00049     irq_evt(1000000, "irq")*/
00050 {
00051     reset_pin.input();
00052     irq_pin.fall(callback(this, &SSInterface::irq_handler));
00053 
00054     //reset_to_main_app();
00055     //get_data_type(&data_type, &sc_en);
00056     ebl_mode = EBL_GPIO_TRIGGER_MODE;
00057 }
00058 
00059 SSInterface::SSInterface(SPI &spiBus, PinName ss_mfio, PinName ss_reset)
00060     :m_i2cBus(NULL), m_spiBus(&spiBus),
00061     mfio_pin(ss_mfio), reset_pin(ss_reset), irq_pin(ss_mfio)/*,
00062     irq_evt(1000000, "irq")*/
00063 {
00064     reset_pin.input();
00065     irq_pin.fall(callback(this, &SSInterface::irq_handler));
00066 
00067     //reset_to_main_app();
00068     //get_data_type(&data_type, &sc_en);
00069     ebl_mode = EBL_GPIO_TRIGGER_MODE;
00070 }
00071 
00072 SSInterface::~SSInterface()
00073 {
00074 }
00075 
00076 SS_STATUS SSInterface::reset_to_main_app()
00077 {
00078     SS_STATUS status;
00079     disable_irq();
00080 
00081     int bootldr = in_bootldr_mode();
00082     if (bootldr > 0) {
00083         status = exit_from_bootloader();
00084     } else if (bootldr == 0) {
00085         reset_pin.output();
00086 
00087             if (ebl_mode == EBL_GPIO_TRIGGER_MODE)
00088         cfg_mfio(PIN_OUTPUT);
00089 
00090         reset_pin.write(0);
00091         wait_ms(SS_RESET_TIME);
00092 
00093         if (ebl_mode == EBL_GPIO_TRIGGER_MODE)
00094             mfio_pin.write(1);
00095 
00096         reset_pin.write(1);
00097         wait_ms(SS_STARTUP_TO_MAIN_APP_TIME);
00098 
00099         if (ebl_mode == EBL_GPIO_TRIGGER_MODE)
00100             cfg_mfio(PIN_INPUT);
00101 
00102         reset_pin.input();
00103         status = SS_SUCCESS;
00104     } else
00105         status = SS_ERR_UNKNOWN;
00106     enable_irq();
00107     return status;
00108 }
00109 
00110 SS_STATUS SSInterface::reset_to_bootloader()
00111 {
00112     disable_irq();
00113     int bootldr = in_bootldr_mode();
00114     if (bootldr > 0) {
00115         enable_irq();
00116         return SS_SUCCESS;
00117     }
00118     reset_pin.output();
00119     if (ebl_mode == EBL_GPIO_TRIGGER_MODE)
00120         cfg_mfio(PIN_OUTPUT);
00121 
00122     reset_pin.write(0);
00123     wait_ms(SS_RESET_TIME);
00124     if (ebl_mode == EBL_GPIO_TRIGGER_MODE)
00125          mfio_pin.write(0);
00126 
00127     reset_pin.write(1);
00128     wait_ms(SS_STARTUP_TO_BTLDR_TIME);
00129     reset_pin.input();
00130 
00131     if (ebl_mode == EBL_CMD_TRIGGER_MODE)
00132         stay_in_bootloader();
00133 
00134     if (ebl_mode == EBL_GPIO_TRIGGER_MODE) {
00135         cfg_mfio(PIN_INPUT);
00136         stay_in_bootloader();
00137     }
00138 
00139      // Verify we entered bootloader mode
00140     if (in_bootldr_mode() < 0) {
00141         enable_irq();
00142         return SS_ERR_UNKNOWN;
00143     }
00144     enable_irq();
00145     return SS_SUCCESS;
00146 }
00147 
00148 SS_STATUS SSInterface::exit_from_bootloader()
00149 {
00150     uint8_t cmd_bytes[] = { SS_FAM_W_MODE, SS_CMDIDX_MODE };
00151     uint8_t data[] = { 0x00 };
00152 
00153     SS_STATUS status = write_cmd(
00154             &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00155             &data[0], ARRAY_SIZE(data));
00156 
00157     in_bootldr = (status == SS_SUCCESS) ? true : false;
00158     return status;
00159 }
00160 
00161 SS_STATUS SSInterface::stay_in_bootloader()
00162 {
00163     uint8_t cmd_bytes[] = { SS_FAM_W_MODE, SS_CMDIDX_MODE };
00164     uint8_t data[] = { SS_MASK_MODE_BOOTLDR };
00165 
00166     SS_STATUS status = write_cmd(
00167             &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00168             &data[0], ARRAY_SIZE(data));
00169 
00170     in_bootldr = (status == SS_SUCCESS) ? true : false;
00171     return status;
00172 }
00173 
00174 int SSInterface::get_ebl_mode()
00175 {
00176     return ebl_mode;
00177 }
00178 
00179 SS_STATUS SSInterface::set_ebl_mode(uint8_t mode)
00180 {
00181     if (mode == EBL_CMD_TRIGGER_MODE || mode == EBL_GPIO_TRIGGER_MODE) {
00182         ebl_mode = mode;
00183         return SS_SUCCESS;
00184     } else {
00185         return SS_ERR_INPUT_VALUE;
00186     }
00187 }
00188 
00189 SS_STATUS SSInterface::reset()
00190 {
00191     int bootldr = in_bootldr_mode();
00192     if (bootldr > 0)
00193         return reset_to_bootloader();
00194     else if (bootldr == 0)
00195         return reset_to_main_app();
00196     else
00197         return SS_ERR_UNKNOWN;
00198 }
00199 
00200 SS_STATUS SSInterface::self_test(int idx, uint8_t *result, int sleep_ms){
00201     uint8_t cmd_bytes[] = { SS_FAM_R_SELFTEST, (uint8_t)idx };
00202     uint8_t rxbuf[2];
00203     SS_STATUS ret;
00204 
00205     result[0] = 0xFF;
00206     ret = read_cmd(cmd_bytes, 2, (uint8_t *)0, 0, rxbuf, ARRAY_SIZE(rxbuf), sleep_ms);
00207     result[0] = rxbuf[1];
00208     return ret;
00209 }
00210 
00211 void SSInterface::cfg_mfio(PinDirection dir)
00212 {
00213     if (dir == PIN_INPUT) {
00214         mfio_pin.input();
00215         mfio_pin.mode(PullUp);
00216     } else {
00217         disable_irq();
00218         mfio_pin.output();
00219     }
00220 }
00221 
00222 void SSInterface::enable_irq()
00223 {
00224     irq_pin.enable_irq();
00225 }
00226 void SSInterface::disable_irq()
00227 {
00228     irq_pin.disable_irq();
00229 }
00230 
00231 void SSInterface::mfio_selftest(){
00232     disable_irq();
00233     irq_pin.fall(callback(this, &SSInterface::irq_handler_selftest));
00234     enable_irq();
00235 }
00236 
00237 int SSInterface::in_bootldr_mode()
00238 {
00239     uint8_t cmd_bytes[] = { SS_FAM_R_MODE, SS_CMDIDX_MODE };
00240     uint8_t rxbuf[2] = { 0 };
00241 
00242     SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00243             0, 0,
00244             &rxbuf[0], ARRAY_SIZE(rxbuf));
00245     if (status != SS_SUCCESS)
00246         return -1;
00247 
00248     return (rxbuf[1] & SS_MASK_MODE_BOOTLDR);
00249 }
00250 
00251 const char* SSInterface::get_ss_fw_version()
00252 {
00253     uint8_t cmd_bytes[2];
00254     uint8_t rxbuf[4];
00255 
00256     int bootldr = in_bootldr_mode();
00257 
00258     if (bootldr > 0) {
00259         cmd_bytes[0] = SS_FAM_R_BOOTLOADER;
00260         cmd_bytes[1] = SS_CMDIDX_BOOTFWVERSION;
00261     } else if (bootldr == 0) {
00262         cmd_bytes[0] = SS_FAM_R_IDENTITY;
00263         cmd_bytes[1] = SS_CMDIDX_FWVERSION;
00264     } else {
00265         return plat_name;
00266     }
00267 
00268     SS_STATUS status = read_cmd(
00269              &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00270              0, 0,
00271              &rxbuf[0], ARRAY_SIZE(rxbuf));
00272 
00273     if (status == SS_SUCCESS) {
00274         snprintf(fw_version, sizeof(fw_version),
00275             "%d.%d.%d", rxbuf[1], rxbuf[2], rxbuf[3]);
00276         pr_info("fw_version:%s\r\n", fw_version);
00277     }
00278 
00279     return &fw_version[0];
00280 }
00281 
00282 const char* SSInterface::get_ss_algo_version()
00283 {
00284     uint8_t cmd_bytes[3];
00285     uint8_t rxbuf[4];
00286 
00287     int bootldr = in_bootldr_mode();
00288 
00289     if (bootldr > 0) {
00290         cmd_bytes[0] = SS_FAM_R_BOOTLOADER;
00291         cmd_bytes[1] = SS_CMDIDX_BOOTFWVERSION;
00292         cmd_bytes[2] = 0;
00293     } else if (bootldr == 0) {
00294         cmd_bytes[0] = SS_FAM_R_IDENTITY;
00295         cmd_bytes[1] = SS_CMDIDX_ALGOVER;
00296         cmd_bytes[2] = SS_CMDIDX_AVAILSENSORS;
00297     } else {
00298         return plat_name;
00299     }
00300 
00301     SS_STATUS status = read_cmd(
00302              &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00303              0, 0,
00304              &rxbuf[0], ARRAY_SIZE(rxbuf));
00305 
00306     if (status == SS_SUCCESS) {
00307         snprintf(algo_version, sizeof(algo_version),
00308             "%d.%d.%d", rxbuf[1], rxbuf[2], rxbuf[3]);
00309         pr_info("algo_version:%s\r\n", fw_version);
00310     }
00311 
00312     return &algo_version[0];
00313 }
00314 const char* SSInterface::get_ss_platform_name()
00315 {
00316     uint8_t cmd_bytes[] = { SS_FAM_R_IDENTITY, SS_CMDIDX_PLATTYPE };
00317     uint8_t rxbuf[2];
00318 
00319     SS_STATUS status = read_cmd(
00320             &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00321             0, 0,
00322             &rxbuf[0], ARRAY_SIZE(rxbuf));
00323 
00324     if (status == SS_SUCCESS) {
00325         if (rxbuf[1] == SS_PLAT_MAX3263X) {
00326             if (in_bootldr_mode() > 0) {
00327                 plat_name = SS_BOOTLOADER_PLATFORM_MAX3263X;
00328             } else {
00329                 plat_name = SS_PLATFORM_MAX3263X;
00330             }
00331         } else if (rxbuf[1] == SS_PLAT_MAX32660) {
00332             if (in_bootldr_mode() > 0) {
00333                 plat_name = SS_BOOTLOADER_PLATFORM_MAX32660;
00334             } else {
00335                 plat_name = SS_PLATFORM_MAX32660;
00336             }
00337         }
00338     }
00339 
00340     return plat_name;
00341 }
00342 
00343 SS_STATUS SSInterface::write_cmd(uint8_t *cmd_bytes, int cmd_bytes_len,
00344     uint8_t *data, int data_len,
00345     int sleep_ms)
00346 {
00347     int total_len = data_len + cmd_bytes_len;
00348 
00349     if (total_len <= SS_SMALL_BUF_SIZE) {
00350         return write_cmd_small(cmd_bytes, cmd_bytes_len, data, data_len, sleep_ms);
00351     } else if (total_len <= SS_MED_BUF_SIZE) {
00352         return write_cmd_medium(cmd_bytes, cmd_bytes_len, data, data_len, sleep_ms);
00353     } else if (total_len <= SS_LARGE_BUF_SIZE) {
00354         return write_cmd_large(cmd_bytes, cmd_bytes_len, data, data_len, sleep_ms);
00355     } else {
00356         mxm_assert_msg(true, "Tried to send I2C tx larger than maximum allowed size\n");
00357         return SS_ERR_DATA_FORMAT; 
00358     }
00359 }
00360 
00361 #include "i2cm.h"
00362 void dump_i2c_regs(int idx)
00363 {
00364     mxc_i2cm_regs_t *i2cm = MXC_I2CM_GET_I2CM(idx);
00365     pr_err("****************************\r\n"
00366         "I2CM(%d) registers Dump\r\n"
00367         "i2cm: %p\r\n"
00368         "fs_clk_div : 0x%X\r\n"
00369         "timeout : 0x%X\r\n"
00370         "ctrl : 0x%X\r\n"
00371         "trans : 0x%X\r\n"
00372         "intfl : 0x%X\r\n"
00373         "inten : 0x%X\r\n"
00374         "bb : 0x%X\r\n"
00375         "****************************\r\n",
00376         idx,
00377         i2cm,
00378         i2cm->fs_clk_div,
00379         i2cm->timeout,
00380         i2cm->ctrl,
00381         i2cm->trans,
00382         i2cm->intfl,
00383         i2cm->inten,
00384         i2cm->bb);
00385 
00386     /* Clean flags */
00387     i2cm->intfl = i2cm->intfl;
00388 }
00389 
00390 SS_STATUS SSInterface::write_cmd(uint8_t *tx_buf, int tx_len, int sleep_ms)
00391 {
00392     pr_info("write_cmd: ");
00393     for (int i = 0; i < tx_len; i++) {
00394         pr_info("0x%02X ", tx_buf[i]);
00395     }
00396     pr_info("\r\n");
00397 
00398     int ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)tx_buf, tx_len);
00399 
00400     int retries = 4;
00401     while (ret != 0 && retries-- > 0) {
00402         pr_err("i2c wr retry\r\n");
00403         wait_ms(1);
00404     ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)tx_buf, tx_len);
00405     }
00406 
00407     if (ret != 0) {
00408         pr_err("m_i2cBus->write returned %d\r\n", ret);
00409 
00410         return SS_ERR_UNAVAILABLE;
00411     }
00412 
00413     wait_ms(sleep_ms);
00414 
00415     char status_byte;
00416     ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, &status_byte, 1);
00417     bool try_again = (status_byte == SS_ERR_TRY_AGAIN);
00418     while ((ret != 0 || try_again)
00419             && retries-- > 0) {
00420         pr_info("i2c rd retry\r\n");
00421         wait_ms(sleep_ms);
00422     ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, &status_byte, 1);
00423         try_again = (status_byte == SS_ERR_TRY_AGAIN);
00424     }
00425 
00426     if (ret != 0 || try_again) {
00427 
00428         pr_err("m_i2cBus->read returned %d, ss status_byte %d\r\n", ret, status_byte);
00429         return SS_ERR_UNAVAILABLE;
00430     }
00431 
00432     pr_info("status_byte: %d\r\n", status_byte);
00433 
00434     return (SS_STATUS)status_byte;
00435 }
00436 
00437 SS_STATUS SSInterface::write_cmd_small(uint8_t *cmd_bytes, int cmd_bytes_len,
00438                        uint8_t *data, int data_len,
00439                        int sleep_ms)
00440 {
00441     uint8_t write_buf[SS_SMALL_BUF_SIZE];
00442     memcpy(write_buf, cmd_bytes, cmd_bytes_len);
00443     memcpy(write_buf + cmd_bytes_len, data, data_len);
00444 
00445     SS_STATUS status = write_cmd(write_buf, cmd_bytes_len + data_len, sleep_ms);
00446     return status;
00447 }
00448 
00449 SS_STATUS SSInterface::write_cmd_medium(uint8_t *cmd_bytes, int cmd_bytes_len,
00450                        uint8_t *data, int data_len,
00451                        int sleep_ms)
00452 {
00453     uint8_t write_buf[SS_MED_BUF_SIZE];
00454     memcpy(write_buf, cmd_bytes, cmd_bytes_len);
00455     memcpy(write_buf + cmd_bytes_len, data, data_len);
00456 
00457     SS_STATUS status = write_cmd(write_buf, cmd_bytes_len + data_len, sleep_ms);
00458     return status;
00459 }
00460 
00461 SS_STATUS SSInterface::write_cmd_large(uint8_t *cmd_bytes, int cmd_bytes_len,
00462                        uint8_t *data, int data_len,
00463                        int sleep_ms)
00464 {
00465     uint8_t write_buf[SS_LARGE_BUF_SIZE];
00466     memcpy(write_buf, cmd_bytes, cmd_bytes_len);
00467     memcpy(write_buf + cmd_bytes_len, data, data_len);
00468 
00469     SS_STATUS status = write_cmd(write_buf, cmd_bytes_len + data_len, sleep_ms);
00470     return status;
00471 }
00472 
00473 SS_STATUS SSInterface::read_cmd(uint8_t *cmd_bytes, int cmd_bytes_len,
00474     uint8_t *data, int data_len,
00475     uint8_t *rxbuf, int rxbuf_sz,
00476     int sleep_ms)
00477 {
00478 #if 0
00479     pr_info("read_cmd: ");
00480     for (int i = 0; i < cmd_bytes_len; i++) {
00481         pr_info("0x%02X ", cmd_bytes[i]);
00482     }
00483     pr_info("\r\n");
00484 
00485 #endif
00486 
00487     int retries = 4;
00488 
00489     int ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)cmd_bytes, cmd_bytes_len, (data_len != 0));
00490 #ifdef SHOW_I2C_DEBUG_MESSAGES
00491     printf("ret1 : %d\rt\n",ret);
00492 #endif
00493     if (data_len != 0) {
00494         ret |= m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)data, data_len, false);
00495 #ifdef SHOW_I2C_DEBUG_MESSAGES
00496         printf("ret2 : %d\rt\n",ret);
00497 #endif
00498     }
00499 
00500     while (ret != 0 && retries-- > 0) {
00501 
00502         pr_err("i2c wr retry\r\n");
00503         wait_ms(1);
00504     ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)cmd_bytes, cmd_bytes_len, (data_len != 0));
00505 #ifdef SHOW_I2C_DEBUG_MESSAGES
00506     printf("ret3 : %d\rt\n",ret);
00507 #endif
00508         if (data_len != 0) {
00509             ret |= m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)data, data_len, false);
00510 #ifdef SHOW_I2C_DEBUG_MESSAGES
00511             printf("ret4 : %d\rt\n",ret);
00512 #endif
00513         }
00514     }
00515 
00516     if (ret != 0) {
00517         pr_err("m_i2cBus->write returned %d\r\n", ret);
00518 
00519         return SS_ERR_UNAVAILABLE;
00520     }
00521 
00522     wait_ms(sleep_ms);
00523 
00524     ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, (char*)rxbuf, rxbuf_sz);
00525     bool try_again = (rxbuf[0] == SS_ERR_TRY_AGAIN);
00526     while ((ret != 0 || try_again) && retries-- > 0) {
00527         pr_info("i2c rd retry\r\n");
00528         wait_ms(sleep_ms);
00529     ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, (char*)rxbuf, rxbuf_sz);
00530         try_again = (rxbuf[0] == SS_ERR_TRY_AGAIN);
00531     }
00532     if (ret != 0 || try_again) {
00533         pr_err("m_i2cBus->read returned %d, ss status_byte %d\r\n", ret, rxbuf[0]);
00534 
00535         return SS_ERR_UNAVAILABLE;
00536     }
00537 
00538     pr_info("status_byte: %d\r\n", rxbuf[0]);
00539     pr_info("data: ");
00540     for (int i = 1; i < rxbuf_sz; i++) {
00541         pr_info("0x%02X ", rxbuf[i]);
00542     }
00543     pr_info("\r\n");
00544 
00545     return (SS_STATUS)rxbuf[0];
00546 }
00547 
00548 SS_STATUS SSInterface::get_reg(int idx, uint8_t addr, uint32_t *val)
00549 {
00550     mxm_assert_msg((idx <= SS_MAX_SUPPORTED_SENSOR_NUM), "idx must be < SS_MAX_SUPPORTED_SENSOR_NUM, or update code to handle variable length idx values");
00551 
00552     uint8_t cmd_bytes[] = { SS_FAM_R_REGATTRIBS, (uint8_t)idx };
00553     uint8_t rx_reg_attribs[3] = {0};
00554 
00555     SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00556                                 0, 0,
00557                                 &rx_reg_attribs[0], ARRAY_SIZE(rx_reg_attribs));
00558 
00559     if (status != SS_SUCCESS)
00560         return status;
00561 
00562     int reg_width = rx_reg_attribs[1];
00563 
00564     uint8_t cmd_bytes2[] = { SS_FAM_R_READREG, (uint8_t)idx, addr };
00565     uint8_t rxbuf[5] = {0};
00566 
00567     status = read_cmd(&cmd_bytes2[0], ARRAY_SIZE(cmd_bytes2),
00568                         0, 0,
00569                         &rxbuf[0], reg_width + 1);
00570 
00571     if (status == SS_SUCCESS) {
00572         *val = 0;
00573         for (int i = 0; i < reg_width; i++) {
00574             *val = (*val << 8) | rxbuf[i + 1];
00575         }
00576     }
00577 
00578     return status;
00579 }
00580 
00581 SS_STATUS SSInterface::set_reg(int idx, uint8_t addr, uint32_t val, int byte_size)
00582 {
00583     mxm_assert_msg((idx <= SS_MAX_SUPPORTED_SENSOR_NUM), "idx must be < SS_MAX_SUPPORTED_SENSOR_NUM, or update code to handle variable length idx values");
00584 
00585     uint8_t cmd_bytes[] = { SS_FAM_W_WRITEREG, (uint8_t)idx, addr };
00586     uint8_t data_bytes[4];
00587     for (int i = 0; i < byte_size; i++) {
00588         data_bytes[i] = (val >> (8 * (byte_size - 1)) & 0xFF);
00589     }
00590 
00591     SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00592                                 &data_bytes[0], byte_size, SS_ENABLE_SENSOR_SLEEP_MS);
00593 
00594     return status;
00595 }
00596 
00597 SS_STATUS SSInterface::dump_reg(int idx, addr_val_pair* reg_vals, int reg_vals_sz, int* num_regs)
00598 {
00599     mxm_assert_msg((idx <= SS_MAX_SUPPORTED_SENSOR_NUM), "idx must be < SS_MAX_SUPPORTED_SENSOR_NUM, or update code to handle variable length idx values");
00600 
00601     uint8_t cmd_bytes[] = { SS_FAM_R_REGATTRIBS, (uint8_t)idx };
00602     uint8_t rx_reg_attribs[3] = {0};
00603 
00604     SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00605                                 0, 0,
00606                                 &rx_reg_attribs[0], ARRAY_SIZE(rx_reg_attribs));
00607 
00608     if (status != SS_SUCCESS)
00609         return status;
00610 
00611     int reg_width = rx_reg_attribs[1];
00612     *num_regs = rx_reg_attribs[2];
00613     mxm_assert_msg((*num_regs <= reg_vals_sz), "Need to increase reg_vals array to hold all dump_reg data");
00614     mxm_assert_msg(((size_t)reg_width <= sizeof(uint32_t)), "IC returned register values greater than 4 bytes in width");
00615 
00616     int dump_reg_sz = (*num_regs) * (reg_width + 1) + 1; //+1 to reg_width for address, +1 for status byte
00617 
00618     uint8_t rxbuf[512];
00619     mxm_assert_msg(((size_t)dump_reg_sz <= sizeof(rxbuf)), "Need to increase buffer size to receive dump_reg data");
00620 
00621     cmd_bytes[0] = SS_FAM_R_DUMPREG;
00622     status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00623                                 0, 0,
00624                                 &rxbuf[0], dump_reg_sz, SS_DUMP_REG_SLEEP_MS);
00625 
00626     if (status != SS_SUCCESS)
00627         return status;
00628 
00629     //rxbuf format is [status][addr0](reg_width x [val0])[addr1](reg_width x [val1])...
00630     for (int reg = 0; reg < *num_regs; reg++) {
00631         reg_vals[reg].addr = rxbuf[(reg * (reg_width + 1)) + 1];
00632         uint32_t *val = &(reg_vals[reg].val);
00633         *val = 0;
00634         for (int byte = 0; byte < reg_width; byte++) {
00635             *val = (*val << 8) | rxbuf[(reg * (reg_width + 1)) + byte + 2];
00636         }
00637     }
00638 
00639     return SS_SUCCESS;
00640 }
00641 
00642 SS_STATUS SSInterface::enable_sensor(int idx, int mode, ss_data_req *data_req, uint8_t ext_mode)
00643 {
00644     mxm_assert_msg((idx <= SS_MAX_SUPPORTED_SENSOR_NUM), "idx must be < SS_MAX_SUPPORTED_SENSOR_NUM, or update code to handle variable length idx values");
00645     mxm_assert_msg((mode <= SS_MAX_SUPPORTED_MODE_NUM), "mode must be < SS_MAX_SUPPORTED_MODE_NUM, or update code to handle variable length mode values");
00646     mxm_assert_msg((mode != 0), "Tried to enable sensor to mode 0, but mode 0 is disable");
00647 
00648 
00649     uint8_t cmd_bytes[] = { SS_FAM_W_SENSORMODE, (uint8_t)idx, (uint8_t)mode, ext_mode };
00650 
00651     SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 0, 0, 5 * SS_ENABLE_SENSOR_SLEEP_MS);
00652 
00653     if (status == SS_SUCCESS) {
00654         sensor_enabled_mode[idx] = mode;
00655         sensor_data_reqs[idx] = data_req;
00656     }
00657     return status;
00658 }
00659 
00660 SS_STATUS SSInterface::disable_sensor(int idx)
00661 {
00662     mxm_assert_msg((idx <= SS_MAX_SUPPORTED_SENSOR_NUM), "idx must be < SS_MAX_SUPPORTED_SENSOR_NUM, or update code to handle variable length idx values");
00663     uint8_t cmd_bytes[] = { SS_FAM_W_SENSORMODE, (uint8_t)idx, 0 };
00664 
00665     SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 0, 0, SS_ENABLE_SENSOR_SLEEP_MS);
00666 
00667     if (status == SS_SUCCESS) {
00668         sensor_enabled_mode[idx] = 0;
00669         sensor_data_reqs[idx] = 0;
00670     }
00671 
00672     return status;
00673 }
00674 
00675 SS_STATUS SSInterface::enable_algo(int idx, int mode, ss_data_req *data_req)
00676 {
00677     mxm_assert_msg((idx <= SS_MAX_SUPPORTED_ALGO_NUM), "idx must be < SS_MAX_SUPPORTED_ALGO_NUM, or update code to handle variable length idx values");
00678     mxm_assert_msg((mode <= SS_MAX_SUPPORTED_MODE_NUM), "mode must be < SS_MAX_SUPPORTED_MODE_NUM, or update code to handle variable length mode values");
00679     mxm_assert_msg((mode != 0), "Tried to enable algo to mode 0, but mode 0 is disable");
00680 
00681     uint8_t cmd_bytes[] = { SS_FAM_W_ALGOMODE, (uint8_t)idx, (uint8_t)mode };
00682 
00683     SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 0, 0, 25 * SS_ENABLE_SENSOR_SLEEP_MS);
00684 
00685     if (status == SS_SUCCESS) {
00686         algo_enabled_mode[idx] = mode;
00687         algo_data_reqs[idx] = data_req;
00688     }
00689 
00690     return status;
00691 }
00692 
00693 SS_STATUS SSInterface::disable_algo(int idx)
00694 {
00695     mxm_assert_msg((idx <= SS_MAX_SUPPORTED_ALGO_NUM), "idx must be < SS_MAX_SUPPORTED_ALGO_NUM, or update code to handle variable length idx values");
00696     uint8_t cmd_bytes[] = { SS_FAM_W_ALGOMODE, (uint8_t)idx, 0 };
00697 
00698     SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 0, 0, SS_ENABLE_SENSOR_SLEEP_MS);
00699 
00700     if (status == SS_SUCCESS) {
00701         algo_enabled_mode[idx] = 0;
00702         algo_data_reqs[idx] = 0;
00703     }
00704 
00705     return status;
00706 }
00707 
00708 SS_STATUS SSInterface::set_algo_cfg(int algo_idx, int cfg_idx, uint8_t *cfg, int cfg_sz)
00709 {
00710     mxm_assert_msg((algo_idx <= SS_MAX_SUPPORTED_ALGO_NUM), "idx must be < SS_MAX_SUPPORTED_ALGO_NUM, or update code to handle variable length idx values");
00711     mxm_assert_msg((cfg_idx <= SS_MAX_SUPPORTED_ALGO_CFG_NUM), "idx must be < SS_MAX_SUPPORTED_ALGO_CFG_NUM, or update code to handle variable length idx values");
00712 
00713     uint8_t cmd_bytes[] = { SS_FAM_W_ALGOCONFIG, (uint8_t)algo_idx, (uint8_t)cfg_idx };
00714     SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00715                                  cfg, cfg_sz);
00716 
00717     return status;
00718 }
00719 
00720 SS_STATUS SSInterface::get_algo_cfg(int algo_idx, int cfg_idx, uint8_t *cfg, int cfg_sz)
00721 {
00722     mxm_assert_msg((algo_idx <= SS_MAX_SUPPORTED_ALGO_NUM), "idx must be < SS_MAX_SUPPORTED_ALGO_NUM, or update code to handle variable length idx values");
00723     mxm_assert_msg((cfg_idx <= SS_MAX_SUPPORTED_ALGO_CFG_NUM), "idx must be < SS_MAX_SUPPORTED_ALGO_CFG_NUM, or update code to handle variable length idx values");
00724 
00725     uint8_t cmd_bytes[] = { SS_FAM_R_ALGOCONFIG, (uint8_t)algo_idx, (uint8_t)cfg_idx };
00726     SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00727                                 0, 0,
00728                                 cfg, cfg_sz);
00729 
00730     return status;
00731 }
00732 
00733 //--------------------------------------------------------------
00734 SS_STATUS SSInterface::send_raw(uint8_t *rawdata, int rawdata_sz)
00735 {
00736     SS_STATUS status = write_cmd(&rawdata[0], rawdata_sz, 5 * SS_ENABLE_SENSOR_SLEEP_MS);
00737     return status;
00738 }
00739 //---------------------------------------------------------------
00740 SS_STATUS SSInterface::set_data_type(int data_type, bool sc_en)
00741 {
00742     mxm_assert_msg((data_type >= 0) && (data_type <= 3), "Invalid value for data_type");
00743     uint8_t cmd_bytes[] = { SS_FAM_W_COMMCHAN, SS_CMDIDX_OUTPUTMODE };
00744     uint8_t data_bytes[] = { (uint8_t)((sc_en ? SS_MASK_OUTPUTMODE_SC_EN : 0) |
00745                             ((data_type << SS_SHIFT_OUTPUTMODE_DATATYPE) & SS_MASK_OUTPUTMODE_DATATYPE)) };
00746 
00747     SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00748                                 &data_bytes[0], ARRAY_SIZE(data_bytes));
00749 
00750     this->data_type = data_type;
00751     this->sc_en = sc_en;
00752 
00753     return status;
00754 }
00755 
00756 
00757 SS_STATUS SSInterface::get_data_type(int *data_type, bool *sc_en)
00758 {
00759     uint8_t cmd_bytes[] = { SS_FAM_R_COMMCHAN, SS_CMDIDX_OUTPUTMODE };
00760     uint8_t rxbuf[2] = {0};
00761 
00762     SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00763                                 0, 0,
00764                                 &rxbuf[0], ARRAY_SIZE(rxbuf));
00765     if (status == SS_SUCCESS) {
00766         *data_type =
00767             (rxbuf[1] & SS_MASK_OUTPUTMODE_DATATYPE) >> SS_SHIFT_OUTPUTMODE_DATATYPE;
00768         *sc_en =
00769             (bool)((rxbuf[1] & SS_MASK_OUTPUTMODE_SC_EN) >> SS_SHIFT_OUTPUTMODE_SC_EN);
00770     }
00771 
00772     return status;
00773 }
00774 
00775 SS_STATUS SSInterface::set_fifo_thresh(int thresh)
00776 {
00777     mxm_assert_msg((thresh > 0 && thresh <= 255), "Invalid value for fifo a full threshold");
00778     uint8_t cmd_bytes[] = { SS_FAM_W_COMMCHAN, SS_CMDIDX_FIFOAFULL };
00779     uint8_t data_bytes[] = { (uint8_t)thresh };
00780 
00781     SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00782                                 &data_bytes[0], ARRAY_SIZE(data_bytes));
00783     return status;
00784 }
00785 
00786 SS_STATUS SSInterface::get_fifo_thresh(int *thresh)
00787 {
00788     uint8_t cmd_bytes[] = { SS_FAM_R_COMMCHAN, SS_CMDIDX_FIFOAFULL };
00789     uint8_t rxbuf[2] = {0};
00790 
00791     SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00792                                 0, 0,
00793                                 &rxbuf[0], ARRAY_SIZE(rxbuf));
00794 
00795     if (status == SS_SUCCESS) {
00796         *thresh = rxbuf[1];
00797     }
00798 
00799     return status;
00800 }
00801 
00802 SS_STATUS SSInterface::ss_comm_check()
00803 {
00804     uint8_t cmd_bytes[] = { SS_FAM_R_IDENTITY, SS_CMDIDX_PLATTYPE };
00805     uint8_t rxbuf[2];
00806 
00807     SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00808                                 0, 0,
00809                                 &rxbuf[0], ARRAY_SIZE(rxbuf));
00810 
00811     int tries = 4;
00812     while (status == SS_ERR_TRY_AGAIN && tries--) {
00813         wait_ms(1000);
00814         status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00815                             0, 0,
00816                             &rxbuf[0], ARRAY_SIZE(rxbuf));
00817     }
00818 
00819     return status;
00820 }
00821 
00822 void SSInterface::fifo_sample_size(int data_type, int *sample_size)
00823 {
00824     *sample_size = 0;
00825 
00826     if (data_type == SS_DATATYPE_RAW || data_type == SS_DATATYPE_BOTH) {
00827         for (int i = 0; i < SS_MAX_SUPPORTED_SENSOR_NUM; i++) {
00828             if (sensor_enabled_mode[i]) {
00829                 mxm_assert_msg(sensor_data_reqs[i], "no ss_data_req found for enabled sensor");
00830                 *sample_size += sensor_data_reqs[i]->data_size;
00831             }
00832         }
00833     }
00834 
00835     if (data_type == SS_DATATYPE_ALGO || data_type == SS_DATATYPE_BOTH) {
00836         for (int i = 0; i < SS_MAX_SUPPORTED_ALGO_NUM; i++) {
00837             if (algo_enabled_mode[i]) {
00838                 mxm_assert_msg(algo_data_reqs[i], "no ss_data_req found for enabled algo");
00839                 *sample_size += algo_data_reqs[i]->data_size;
00840             }
00841         }
00842     }
00843 }
00844 
00845 
00846 SS_STATUS SSInterface::num_avail_samples(int *num_samples)
00847 {
00848     uint8_t cmd_bytes[] = { SS_FAM_R_OUTPUTFIFO, SS_CMDIDX_OUT_NUMSAMPLES };
00849     uint8_t rxbuf[2] = {0};
00850 
00851     SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00852                                 0, 0,
00853                                 &rxbuf[0], ARRAY_SIZE(rxbuf), SS_DEFAULT2_CMD_SLEEP_MS);
00854 
00855     if (status == SS_SUCCESS) {
00856         *num_samples = rxbuf[1];
00857     }
00858 
00859     return status;
00860 }
00861 
00862 SS_STATUS SSInterface::get_log_len(int *log_len)
00863 {
00864     uint8_t cmd_bytes[] = { SS_FAM_R_LOG, SS_CMDIDX_R_LOG_LEN };
00865     uint8_t rxbuf[2] = {0};
00866 
00867     SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00868                                 0, 0,
00869                                 &rxbuf[0], ARRAY_SIZE(rxbuf), 1);
00870 
00871     if (status == SS_SUCCESS) {
00872         *log_len = (rxbuf[1] << 8) | rxbuf[0];
00873     }
00874 
00875     return status;
00876 }
00877 
00878 
00879 SS_STATUS SSInterface::get_sensor_sample_size(uint8_t sensor_id, uint8_t *sample_size)
00880 {
00881     uint8_t cmd_bytes[] = { SS_FAM_R_INPUTFIFO, SS_CMDIDX_SAMPLE_SIZE, sensor_id };
00882     uint8_t rxbuf[2]; /* status + sample size */
00883 
00884     pr_info("[Reading external sample size for id: %d\n", sensor_id);
00885     SS_STATUS status = read_cmd(cmd_bytes, ARRAY_SIZE(cmd_bytes),
00886                                 NULL, 0,
00887                                 rxbuf, sizeof(rxbuf));
00888     *sample_size = rxbuf[1];
00889     return status;
00890 }
00891 
00892 SS_STATUS SSInterface::get_input_fifo_size(int *fifo_size)
00893 {
00894     uint8_t cmd_bytes[] = { SS_FAM_R_INPUTFIFO, SS_CMDIDX_INPUT_FIFO_SIZE};
00895     uint8_t rxbuf[3]; /* status + fifo size */
00896 
00897     pr_info("[Reading external Input FIFO size.\n");
00898     SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00899                                 NULL, 0,
00900                                 rxbuf, sizeof(rxbuf), SS_DEFAULT2_CMD_SLEEP_MS);
00901     *fifo_size = rxbuf[1] << 8 | rxbuf[2];
00902     return status;
00903 }
00904 
00905 SS_STATUS SSInterface::get_sensor_fifo_size(uint8_t sensor_id, int *fifo_size)
00906 {
00907     uint8_t cmd_bytes[] = { SS_FAM_R_INPUTFIFO, SS_CMDIDX_SENSOR_FIFO_SIZE, sensor_id};
00908     uint8_t rxbuf[3]; /* status + fifo size */
00909 
00910     pr_info("[Reading sensor's FIFO size for id: %d\n", sensor_id);
00911     SS_STATUS status = read_cmd(cmd_bytes, ARRAY_SIZE(cmd_bytes),
00912                                 NULL, 0,
00913                                 rxbuf, sizeof(rxbuf));
00914     *fifo_size = rxbuf[1] << 8 | rxbuf[2];
00915     return status;
00916 }
00917 
00918 SS_STATUS SSInterface::get_num_samples_in_sensor_fifo(uint8_t sensor_id, int *fifo_size)
00919 {
00920     uint8_t cmd_bytes[] = { SS_FAM_R_INPUTFIFO, SS_CMDIDX_NUM_SAMPLES_SENSOR_FIFO, sensor_id};
00921     uint8_t rxbuf[3]; /* status + fifo size */
00922 
00923     pr_info("[Reading sensor's FIFO size for id: %d\n", sensor_id);
00924     SS_STATUS status = read_cmd(cmd_bytes, ARRAY_SIZE(cmd_bytes),
00925                                 NULL, 0,
00926                                 rxbuf, sizeof(rxbuf));
00927     *fifo_size = rxbuf[1] << 8 | rxbuf[2];
00928     return status;
00929 }
00930 
00931 SS_STATUS SSInterface::get_num_bytes_in_input_fifo(int *fifo_size)
00932 {
00933     uint8_t cmd_bytes[] = { SS_FAM_R_INPUTFIFO, SS_CMDIDX_NUM_SAMPLES_INPUT_FIFO};
00934     uint8_t rxbuf[3]; /* status + fifo size */
00935 
00936     pr_info("[Reading input FIFO size for id\n");
00937     SS_STATUS status = read_cmd(cmd_bytes, ARRAY_SIZE(cmd_bytes),
00938                                 NULL, 0,
00939                                 rxbuf, sizeof(rxbuf),
00940                                 SS_DEFAULT2_CMD_SLEEP_MS);
00941     *fifo_size = rxbuf[1] << 8 | rxbuf[2];
00942     return status;
00943 }
00944 
00945 SS_STATUS SSInterface::feed_to_input_fifo(uint8_t *tx_buf, int tx_buf_sz, int *nb_written)
00946 {
00947     int ret;
00948     uint8_t rxbuf[3];
00949 
00950     tx_buf[0] = SS_FAM_W_INPUTFIFO;
00951     tx_buf[1] = SS_CMDIDX_WRITE_FIFO;
00952 
00953     ret = read_cmd(&tx_buf[0], tx_buf_sz,
00954             NULL, 0,
00955             rxbuf, sizeof(rxbuf), SS_DEFAULT3_CMD_SLEEP_MS);
00956 
00957     *nb_written = rxbuf[1] * 256 + rxbuf[2];
00958     return (SS_STATUS)ret;
00959 }
00960 
00961 SS_STATUS SSInterface::read_fifo_data(int num_samples, int sample_size,
00962     uint8_t* databuf, int databuf_sz)
00963 {
00964     int bytes_to_read = num_samples * sample_size + 1; //+1 for status byte
00965     mxm_assert_msg((bytes_to_read <= databuf_sz), "databuf too small");
00966 
00967     uint8_t cmd_bytes[] = { SS_FAM_R_OUTPUTFIFO, SS_CMDIDX_READFIFO };
00968 
00969     pr_info("[reading %d bytes (%d samples)\r\n", bytes_to_read, num_samples);
00970 
00971     SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00972                                 0, 0,
00973                                 databuf, bytes_to_read, 10);
00974 
00975     return status;
00976 }
00977 
00978 SS_STATUS SSInterface::read_ss_log(int num_bytes, uint8_t *log_buf, int log_buf_sz)
00979 {
00980     int bytes_to_read = num_bytes + 1; //+1 for status byte
00981     mxm_assert_msg((bytes_to_read <= log_buf_sz), "log_buf too small");
00982 
00983     uint8_t cmd_bytes[] = { SS_FAM_R_LOG, SS_CMDIDX_R_LOG_DATA };
00984 
00985     pr_info("[reading %d bytes (%d samples)\r\n", bytes_to_read, bytes_to_read);
00986 
00987     SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
00988                                 0, 0,
00989                                 log_buf, bytes_to_read, 5);
00990 
00991     return status;
00992 }
00993 
00994 static uint8_t databuf[512];
00995 void SSInterface::ss_execute_once(){
00996 
00997     if(m_irq_received_ == false)
00998         return;
00999 
01000     uint8_t sample_count;
01001     m_irq_received_ = false;
01002     uint8_t cmd_bytes[] = { SS_FAM_R_STATUS, SS_CMDIDX_STATUS };
01003     uint8_t rxbuf[2] = {0};
01004 
01005     //irq_evt.start();
01006 
01007     disable_irq();
01008 
01009     SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
01010                                 0, 0,
01011                                 &rxbuf[0], ARRAY_SIZE(rxbuf), SS_DEFAULT2_CMD_SLEEP_MS);
01012     pr_info("ss_int: %2X", rxbuf[1]);
01013 
01014     if (status != SS_SUCCESS) {
01015         pr_err("Couldn't read status byte of SmartSensor!");
01016         enable_irq();
01017         //irq_evt.stop();
01018         return;
01019     }
01020 
01021     if (rxbuf[1] & SS_MASK_STATUS_ERR) {
01022         pr_err("SmartSensor status error: %d", rxbuf[1] & SS_MASK_STATUS_ERR);
01023     }
01024     if (rxbuf[1] & SS_MASK_STATUS_FIFO_OUT_OVR) {
01025         pr_err("SmartSensor Output FIFO overflow!");
01026     }
01027     if (rxbuf[1] & SS_MASK_STATUS_FIFO_IN_OVR) {
01028         pr_err("SmartSensor Input FIFO overflow!");
01029     }
01030 
01031     if (rxbuf[1] & SS_MASK_STATUS_LOG_OVR) {
01032         pr_err("SmartSensor log overflow!");
01033     }
01034 
01035     if (rxbuf[1] & SS_MASK_STATUS_LOG_RDY) {
01036         pr_err("SmartSensor Log ready");
01037         int log_len;
01038         status = get_log_len(&log_len);
01039         if (status != SS_SUCCESS)
01040         {
01041             pr_err("Couldn't read log lenght");
01042             enable_irq();
01043             //irq_evt.stop();
01044             return;
01045         }
01046 
01047         mxm_assert_msg((log_len <= sizeof(databuf)), "log size in SS longer than buffer");
01048         status = read_ss_log(log_len, &databuf[0], sizeof(databuf));
01049         if (status != SS_SUCCESS)
01050         {
01051             pr_err("Couldn't read from SmartSensor Log");
01052             enable_irq();
01053             //irq_evt.stop();
01054             return;
01055         }
01056 
01057         databuf[log_len] = 0;
01058         Peripherals::usbSerial()->printf("\r\n%s", (char *)databuf);
01059     }
01060 
01061     if (rxbuf[1] & SS_MASK_STATUS_DATA_RDY) {
01062         int num_samples = 1;
01063         status = num_avail_samples(&num_samples);
01064         if (status != SS_SUCCESS)
01065         {
01066             pr_err("Couldn't read number of available samples in SmartSensor Output FIFO");
01067             enable_irq();
01068             //irq_evt.stop();
01069             return;
01070         }
01071 
01072         int sample_size;
01073         fifo_sample_size(data_type, &sample_size);
01074 
01075         int bytes_to_read = num_samples * sample_size + 1; //+1 for status byte
01076         if ((uint32_t)bytes_to_read > sizeof(databuf)) {
01077             //Reduce number of samples to read to fit in buffer
01078             num_samples = (sizeof(databuf) - 1) / sample_size;
01079         }
01080 
01081         wait_ms(5);
01082         status = read_fifo_data(num_samples, sample_size, &databuf[0], sizeof(databuf));
01083         if (status != SS_SUCCESS)
01084         {
01085             pr_err("Couldn't read from SmartSensor Output FIFO");
01086             enable_irq();
01087             //irq_evt.stop();
01088             return;
01089         }
01090 
01091         //Skip status byte
01092         uint8_t *data_ptr = &databuf[1];
01093 
01094         int i = 0;
01095         for (i = 0; i < num_samples; i++) {
01096             if (sc_en) {
01097                 sample_count = *data_ptr++;
01098                 pr_info("Received sample #%d", sample_count);
01099             }
01100 
01101             //Chop up data and send to modules with enabled sensors
01102             if (data_type == SS_DATATYPE_RAW || data_type == SS_DATATYPE_BOTH) {
01103                 for (int i = 0; i < SS_MAX_SUPPORTED_SENSOR_NUM; i++) {
01104                     if (sensor_enabled_mode[i]) {
01105                         mxm_assert_msg(sensor_data_reqs[i],
01106                                 "no ss_data_req found for enabled sensor");
01107                         sensor_data_reqs[i]->callback(data_ptr);
01108                         data_ptr += sensor_data_reqs[i]->data_size;
01109                     }
01110                 }
01111             }
01112             if (data_type == SS_DATATYPE_ALGO || data_type == SS_DATATYPE_BOTH) {
01113                 for (int i = 0; i < SS_MAX_SUPPORTED_ALGO_NUM; i++) {
01114                     if (algo_enabled_mode[i]) {
01115                     mxm_assert_msg(algo_data_reqs[i],
01116                                 "no ss_data_req found for enabled algo");
01117                         algo_data_reqs[i]->callback(data_ptr);
01118                         data_ptr += algo_data_reqs[i]->data_size;
01119                     }
01120                 }
01121             }
01122         }
01123     }
01124     enable_irq();
01125     //irq_evt.stop();
01126 }
01127 
01128 void SSInterface::ss_clear_interrupt_flag(){
01129     m_irq_received_ = false;
01130 }
01131 
01132 void SSInterface::irq_handler()
01133 {
01134     m_irq_received_ = true;
01135 }
01136 
01137 void SSInterface::irq_handler_selftest(){
01138     mfio_int_happened = true;
01139 }
01140 
01141 bool SSInterface::reset_mfio_irq(){
01142     bool ret = mfio_int_happened;
01143     mfio_int_happened = false;
01144     disable_irq();
01145     irq_pin.fall(callback(this, &SSInterface::irq_handler));
01146     enable_irq();
01147     return ret;
01148 }