Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: max32630fthr Adafruit_FeatherOLED USBDevice
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 }
Generated on Tue Jul 12 2022 20:09:29 by
