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: USBDevice max32630fthr
Fork of MAXREFDES220# by
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 #include "Peripherals.h" 00036 #include "assert.h" 00037 #include "utils.h" 00038 00039 SSInterface::SSInterface(I2C &i2cBus, PinName ss_mfio, PinName ss_reset) 00040 :m_i2cBus(&i2cBus), m_spiBus(NULL), mfio_pin(ss_mfio), reset_pin(ss_reset), irq_pin(ss_mfio) 00041 { 00042 reset_pin.input(); 00043 irq_pin.fall(callback(this, &SSInterface::irq_handler)); 00044 00045 reset_to_main_app(); 00046 get_data_type(&data_type, &sc_en); 00047 } 00048 00049 SSInterface::SSInterface(SPI &spiBus, PinName ss_mfio, PinName ss_reset) 00050 :m_i2cBus(NULL), m_spiBus(&spiBus), mfio_pin(ss_mfio), reset_pin(ss_reset), irq_pin(ss_mfio) 00051 { 00052 reset_pin.input(); 00053 irq_pin.fall(callback(this, &SSInterface::irq_handler)); 00054 00055 reset_to_main_app(); 00056 get_data_type(&data_type, &sc_en); 00057 } 00058 00059 SSInterface::~SSInterface() 00060 { 00061 } 00062 00063 SS_STATUS SSInterface::reset_to_main_app() 00064 { 00065 irq_pin.disable_irq(); 00066 #if 0 00067 uint8_t cmd_bytes[] = { SS_FAM_W_MODE, SS_CMDIDX_MODE }; 00068 uint8_t data[] = { 0x00 }; 00069 00070 SS_STATUS status = ss_int->write_cmd( 00071 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00072 &data[0], ARRAY_SIZE(data), 00073 SS_STARTUP_TIME); 00074 if (status == SS_SUCCESS) 00075 in_bootldr = false; 00076 return status; 00077 #else 00078 reset_pin.output(); 00079 cfg_mfio(PIN_OUTPUT); 00080 reset_pin.write(0); 00081 wait_ms(SS_RESET_TIME); 00082 mfio_pin.write(1); 00083 reset_pin.write(1); 00084 wait_ms(SS_STARTUP_TIME); 00085 cfg_mfio(PIN_INPUT); 00086 reset_pin.input(); 00087 // Verify we exited bootloader mode 00088 if (in_bootldr_mode() == 0) 00089 return SS_SUCCESS; 00090 else 00091 return SS_ERR_UNKNOWN; 00092 #endif 00093 00094 irq_pin.enable_irq(); 00095 } 00096 00097 SS_STATUS SSInterface::reset_to_bootloader() 00098 { 00099 irq_pin.disable_irq(); 00100 #if 0 00101 uint8_t cmd_bytes[] = { SS_FAM_W_MODE, SS_CMDIDX_MODE }; 00102 uint8_t data[] = { SS_MASK_MODE_BOOTLDR }; 00103 00104 SS_STATUS status = ss_int->write_cmd( 00105 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00106 &data[0], ARRAY_SIZE(data), 00107 SS_STARTUP_TIME); 00108 if (status == SS_SUCCESS) 00109 in_bootldr = true; 00110 return status; 00111 #else 00112 reset_pin.output(); 00113 cfg_mfio(PIN_OUTPUT); 00114 reset_pin.write(0); 00115 wait_ms(SS_RESET_TIME); 00116 mfio_pin.write(0); 00117 reset_pin.write(1); 00118 wait_ms(SS_STARTUP_TIME); 00119 cfg_mfio(PIN_INPUT); 00120 reset_pin.input(); 00121 // Verify we entered bootloader mode 00122 if (in_bootldr_mode() < 0) 00123 return SS_ERR_UNKNOWN; 00124 return SS_SUCCESS; 00125 #endif 00126 00127 irq_pin.disable_irq(); 00128 } 00129 00130 SS_STATUS SSInterface::reset() 00131 { 00132 int bootldr = in_bootldr_mode(); 00133 if (bootldr > 0) 00134 return reset_to_bootloader(); 00135 else if (bootldr == 0) 00136 return reset_to_main_app(); 00137 else 00138 return SS_ERR_UNKNOWN; 00139 } 00140 00141 SS_STATUS SSInterface::self_test(int idx, uint8_t *result, int sleep_ms){ 00142 uint8_t cmd_bytes[] = {SS_FAM_R_SELFTEST, idx}; 00143 uint8_t rxbuf[2]; 00144 SS_STATUS ret; 00145 00146 result[0] = 0xFF; 00147 ret = read_cmd(cmd_bytes, 2, (uint8_t *)0, 0, rxbuf, ARRAY_SIZE(rxbuf), sleep_ms); 00148 result[0] = rxbuf[1]; 00149 return ret; 00150 } 00151 00152 void SSInterface::cfg_mfio(PinDirection dir) 00153 { 00154 if (dir == PIN_INPUT) { 00155 mfio_pin.input(); 00156 mfio_pin.mode(PullUp); 00157 } else { 00158 mfio_pin.output(); 00159 } 00160 } 00161 00162 void SSInterface::enable_irq() 00163 { 00164 irq_pin.enable_irq(); 00165 } 00166 void SSInterface::disable_irq() 00167 { 00168 irq_pin.disable_irq(); 00169 } 00170 00171 void SSInterface::mfio_selftest(){ 00172 disable_irq(); 00173 irq_pin.fall(callback(this, &SSInterface::irq_handler_selftest)); 00174 enable_irq(); 00175 } 00176 00177 int SSInterface::in_bootldr_mode() 00178 { 00179 uint8_t cmd_bytes[] = { SS_FAM_R_MODE, SS_CMDIDX_MODE }; 00180 uint8_t rxbuf[2] = { 0 }; 00181 00182 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00183 0, 0, 00184 &rxbuf[0], ARRAY_SIZE(rxbuf)); 00185 if (status != SS_SUCCESS) 00186 return -1; 00187 00188 return (rxbuf[1] & SS_MASK_MODE_BOOTLDR); 00189 } 00190 00191 const char* SSInterface::get_ss_fw_version() 00192 { 00193 uint8_t cmd_bytes[2]; 00194 uint8_t rxbuf[4]; 00195 00196 int bootldr = in_bootldr_mode(); 00197 00198 if (bootldr > 0) { 00199 cmd_bytes[0] = SS_FAM_R_BOOTLOADER; 00200 cmd_bytes[1] = SS_CMDIDX_BOOTFWVERSION; 00201 } else if (bootldr == 0) { 00202 cmd_bytes[0] = SS_FAM_R_IDENTITY; 00203 cmd_bytes[1] = SS_CMDIDX_FWVERSION; 00204 } else { 00205 return plat_name; 00206 } 00207 00208 SS_STATUS status = read_cmd( 00209 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00210 0, 0, 00211 &rxbuf[0], ARRAY_SIZE(rxbuf)); 00212 00213 if (status == SS_SUCCESS) { 00214 snprintf(fw_version, sizeof(fw_version), 00215 "%d.%d.%d", rxbuf[1], rxbuf[2], rxbuf[3]); 00216 pr_info("fw_version:%s\r\n", fw_version); 00217 } 00218 00219 return &fw_version[0]; 00220 } 00221 00222 const char* SSInterface::get_ss_platform_name() 00223 { 00224 uint8_t cmd_bytes[] = { SS_FAM_R_IDENTITY, SS_CMDIDX_PLATTYPE }; 00225 uint8_t rxbuf[2]; 00226 00227 SS_STATUS status = read_cmd( 00228 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00229 0, 0, 00230 &rxbuf[0], ARRAY_SIZE(rxbuf)); 00231 00232 if (status == SS_SUCCESS) { 00233 if (rxbuf[1] == SS_PLAT_MAX3263X) { 00234 if (in_bootldr_mode() > 0) { 00235 plat_name = SS_BOOTLOADER_PLATFORM_MAX3263X; 00236 } else { 00237 plat_name = SS_PLATFORM_MAX3263X; 00238 } 00239 } else if (rxbuf[1] == SS_PLAT_MAX32660) { 00240 if (in_bootldr_mode() > 0) { 00241 plat_name = SS_BOOTLOADER_PLATFORM_MAX32660; 00242 } else { 00243 plat_name = SS_PLATFORM_MAX32660; 00244 } 00245 } 00246 } 00247 00248 return plat_name; 00249 } 00250 00251 SS_STATUS SSInterface::write_cmd(uint8_t *cmd_bytes, int cmd_bytes_len, 00252 uint8_t *data, int data_len, 00253 int sleep_ms) 00254 { 00255 int total_len = data_len + cmd_bytes_len; 00256 00257 if (total_len <= SS_SMALL_BUF_SIZE) { 00258 return write_cmd_small(cmd_bytes, cmd_bytes_len, data, data_len, sleep_ms); 00259 } else if (total_len <= SS_LARGE_BUF_SIZE) { 00260 return write_cmd_large(cmd_bytes, cmd_bytes_len, data, data_len, sleep_ms); 00261 } else { 00262 assert_msg(true, "Tried to send I2C tx larger than maximum allowed size\n"); 00263 return SS_ERR_DATA_FORMAT; 00264 } 00265 } 00266 00267 SS_STATUS SSInterface::write_cmd(uint8_t *tx_buf, int tx_len, int sleep_ms) 00268 { 00269 pr_info("write_cmd: "); 00270 for (int i = 0; i < tx_len; i++) { 00271 pr_info("0x%02X ", tx_buf[i]); 00272 } 00273 pr_info("\r\n"); 00274 00275 int ret = 0; 00276 ret |= m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)tx_buf, tx_len); 00277 00278 if (ret != 0) { 00279 pr_err("m_i2cBus->write returned %d\r\n", ret); 00280 return SS_ERR_UNAVAILABLE; 00281 } 00282 00283 wait_ms(sleep_ms); 00284 00285 char status_byte; 00286 ret |= m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, &status_byte, 1); 00287 00288 if (ret != 0) { 00289 pr_err("m_i2cBus->read returned %d\r\n", ret); 00290 return SS_ERR_UNAVAILABLE; 00291 } 00292 00293 pr_info("status_byte: %d\r\n", status_byte); 00294 00295 return (SS_STATUS)status_byte; 00296 } 00297 00298 SS_STATUS SSInterface::write_cmd_small(uint8_t *cmd_bytes, int cmd_bytes_len, 00299 uint8_t *data, int data_len, 00300 int sleep_ms) 00301 { 00302 uint8_t write_buf[SS_SMALL_BUF_SIZE]; 00303 memcpy(write_buf, cmd_bytes, cmd_bytes_len); 00304 memcpy(write_buf + cmd_bytes_len, data, data_len); 00305 00306 SS_STATUS status = write_cmd(write_buf, cmd_bytes_len + data_len, sleep_ms); 00307 return status; 00308 } 00309 00310 SS_STATUS SSInterface::write_cmd_large(uint8_t *cmd_bytes, int cmd_bytes_len, 00311 uint8_t *data, int data_len, 00312 int sleep_ms) 00313 { 00314 uint8_t write_buf[SS_LARGE_BUF_SIZE]; 00315 memcpy(write_buf, cmd_bytes, cmd_bytes_len); 00316 memcpy(write_buf + cmd_bytes_len, data, data_len); 00317 00318 SS_STATUS status = write_cmd(write_buf, cmd_bytes_len + data_len, sleep_ms); 00319 return status; 00320 } 00321 00322 SS_STATUS SSInterface::read_cmd(uint8_t *cmd_bytes, int cmd_bytes_len, 00323 uint8_t *data, int data_len, 00324 uint8_t *rxbuf, int rxbuf_sz, 00325 int sleep_ms) 00326 { 00327 int ret = 0; 00328 00329 pr_info("read_cmd: "); 00330 for (int i = 0; i < cmd_bytes_len; i++) { 00331 pr_info("0x%02X ", cmd_bytes[i]); 00332 } 00333 pr_info("\r\n"); 00334 00335 ret |= m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)cmd_bytes, cmd_bytes_len, (data_len != 0)); 00336 00337 if (data_len != 0) { 00338 ret |= m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)data, data_len, false); 00339 } 00340 00341 if (ret != 0) { 00342 pr_err("m_i2cBus->write returned %d\r\n", ret); 00343 return SS_ERR_UNAVAILABLE; 00344 } 00345 00346 wait_ms(sleep_ms); 00347 00348 ret |= m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, (char*)rxbuf, rxbuf_sz); 00349 00350 if (ret != 0) { 00351 pr_err("m_i2cBus->read returned %d\r\n", ret); 00352 return SS_ERR_UNAVAILABLE; 00353 } 00354 00355 wait_ms(sleep_ms); 00356 pr_info("status_byte: %d\r\n", rxbuf[0]); 00357 pr_info("data: "); 00358 for (int i = 1; i < rxbuf_sz; i++) { 00359 pr_info("0x%02X ", rxbuf[i]); 00360 } 00361 pr_info("\r\n"); 00362 00363 return (SS_STATUS)rxbuf[0]; 00364 } 00365 00366 SS_STATUS SSInterface::get_reg(int idx, uint8_t addr, uint32_t *val) 00367 { 00368 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"); 00369 00370 uint8_t cmd_bytes[] = { SS_FAM_R_REGATTRIBS, (uint8_t)idx }; 00371 uint8_t rx_reg_attribs[3] = {0}; 00372 00373 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00374 0, 0, 00375 &rx_reg_attribs[0], ARRAY_SIZE(rx_reg_attribs)); 00376 00377 if (status != SS_SUCCESS) 00378 return status; 00379 00380 int reg_width = rx_reg_attribs[1]; 00381 00382 uint8_t cmd_bytes2[] = { SS_FAM_R_READREG, (uint8_t)idx, addr }; 00383 uint8_t rxbuf[5] = {0}; 00384 00385 status = read_cmd(&cmd_bytes2[0], ARRAY_SIZE(cmd_bytes2), 00386 0, 0, 00387 &rxbuf[0], ARRAY_SIZE(rxbuf)); 00388 00389 if (status == SS_SUCCESS) { 00390 *val = 0; 00391 for (int i = 0; i < reg_width; i++) { 00392 *val = (*val << 8) | rxbuf[i + 1]; 00393 } 00394 } 00395 00396 return status; 00397 } 00398 00399 SS_STATUS SSInterface::set_reg(int idx, uint8_t addr, uint32_t val, int byte_size) 00400 { 00401 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"); 00402 00403 uint8_t cmd_bytes[] = { SS_FAM_W_WRITEREG, (uint8_t)idx, addr }; 00404 uint8_t data_bytes[4]; 00405 for (int i = 0; i < byte_size; i++) { 00406 data_bytes[i] = (val >> (8 * (byte_size - 1)) & 0xFF); 00407 } 00408 00409 SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00410 &data_bytes[0], byte_size); 00411 00412 return status; 00413 } 00414 00415 SS_STATUS SSInterface::dump_reg(int idx, addr_val_pair* reg_vals, int reg_vals_sz, int* num_regs) 00416 { 00417 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"); 00418 00419 uint8_t cmd_bytes[] = { SS_FAM_R_REGATTRIBS, (uint8_t)idx }; 00420 uint8_t rx_reg_attribs[3] = {0}; 00421 00422 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00423 0, 0, 00424 &rx_reg_attribs[0], ARRAY_SIZE(rx_reg_attribs)); 00425 00426 if (status != SS_SUCCESS) 00427 return status; 00428 00429 int reg_width = rx_reg_attribs[1]; 00430 *num_regs = rx_reg_attribs[2]; 00431 assert_msg((*num_regs <= reg_vals_sz), "Need to increase reg_vals array to hold all dump_reg data"); 00432 assert_msg(((size_t)reg_width <= sizeof(uint32_t)), "IC returned register values greater than 4 bytes in width"); 00433 00434 int dump_reg_sz = (*num_regs) * (reg_width + 1) + 1; //+1 to reg_width for address, +1 for status byte 00435 00436 uint8_t rxbuf[512]; 00437 assert_msg(((size_t)dump_reg_sz <= sizeof(rxbuf)), "Need to increase buffer size to receive dump_reg data"); 00438 00439 cmd_bytes[0] = SS_FAM_R_DUMPREG; 00440 status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00441 0, 0, 00442 &rxbuf[0], dump_reg_sz, SS_DUMP_REG_SLEEP_MS); 00443 00444 if (status != SS_SUCCESS) 00445 return status; 00446 00447 //rxbuf format is [status][addr0](reg_width x [val0])[addr1](reg_width x [val1])... 00448 for (int reg = 0; reg < *num_regs; reg++) { 00449 reg_vals[reg].addr = rxbuf[(reg * (reg_width + 1)) + 1]; 00450 uint32_t *val = &(reg_vals[reg].val); 00451 *val = 0; 00452 for (int byte = 0; byte < reg_width; byte++) { 00453 *val = (*val << 8) | rxbuf[(reg * (reg_width + 1)) + byte + 2]; 00454 } 00455 } 00456 00457 return SS_SUCCESS; 00458 } 00459 00460 SS_STATUS SSInterface::enable_sensor(int idx, int mode, ss_data_req *data_req) 00461 { 00462 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"); 00463 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"); 00464 assert_msg((mode != 0), "Tried to enable sensor to mode 0, but mode 0 is disable"); 00465 00466 uint8_t cmd_bytes[] = { SS_FAM_W_SENSORMODE, (uint8_t)idx, (uint8_t)mode }; 00467 00468 SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 0, 0, SS_ENABLE_SENSOR_SLEEP_MS); 00469 00470 if (status == SS_SUCCESS) { 00471 sensor_enabled_mode[idx] = mode; 00472 sensor_data_reqs[idx] = data_req; 00473 } 00474 return status; 00475 } 00476 00477 SS_STATUS SSInterface::disable_sensor(int idx) 00478 { 00479 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"); 00480 uint8_t cmd_bytes[] = { SS_FAM_W_SENSORMODE, (uint8_t)idx, 0 }; 00481 00482 SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 0, 0, SS_ENABLE_SENSOR_SLEEP_MS); 00483 00484 if (status == SS_SUCCESS) { 00485 sensor_enabled_mode[idx] = 0; 00486 sensor_data_reqs[idx] = 0; 00487 } 00488 00489 return status; 00490 } 00491 00492 SS_STATUS SSInterface::enable_algo(int idx, int mode, ss_data_req *data_req) 00493 { 00494 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"); 00495 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"); 00496 assert_msg((mode != 0), "Tried to enable algo to mode 0, but mode 0 is disable"); 00497 00498 uint8_t cmd_bytes[] = { SS_FAM_W_ALGOMODE, (uint8_t)idx, (uint8_t)mode }; 00499 00500 SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 0, 0, SS_ENABLE_SENSOR_SLEEP_MS); 00501 00502 if (status == SS_SUCCESS) { 00503 algo_enabled_mode[idx] = mode; 00504 algo_data_reqs[idx] = data_req; 00505 } 00506 00507 return status; 00508 } 00509 00510 SS_STATUS SSInterface::disable_algo(int idx) 00511 { 00512 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"); 00513 uint8_t cmd_bytes[] = { SS_FAM_W_ALGOMODE, (uint8_t)idx, 0 }; 00514 00515 SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 0, 0, SS_ENABLE_SENSOR_SLEEP_MS); 00516 00517 if (status == SS_SUCCESS) { 00518 algo_enabled_mode[idx] = 0; 00519 algo_data_reqs[idx] = 0; 00520 } 00521 00522 return status; 00523 } 00524 00525 SS_STATUS SSInterface::set_data_type(int data_type, bool sc_en) 00526 { 00527 assert_msg((data_type >= 0) && (data_type <= 3), "Invalid value for data_type"); 00528 uint8_t cmd_bytes[] = { SS_FAM_W_COMMCHAN, SS_CMDIDX_OUTPUTMODE }; 00529 uint8_t data_bytes[] = { (uint8_t)((sc_en ? SS_MASK_OUTPUTMODE_SC_EN : 0) | 00530 ((data_type << SS_SHIFT_OUTPUTMODE_DATATYPE) & SS_MASK_OUTPUTMODE_DATATYPE)) }; 00531 00532 SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00533 &data_bytes[0], ARRAY_SIZE(data_bytes)); 00534 00535 this->data_type = data_type; 00536 this->sc_en = sc_en; 00537 00538 return status; 00539 } 00540 00541 00542 SS_STATUS SSInterface::get_data_type(int *data_type, bool *sc_en) 00543 { 00544 uint8_t cmd_bytes[] = { SS_FAM_R_COMMCHAN, SS_CMDIDX_OUTPUTMODE }; 00545 uint8_t rxbuf[2] = {0}; 00546 00547 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00548 0, 0, 00549 &rxbuf[0], ARRAY_SIZE(rxbuf)); 00550 if (status == SS_SUCCESS) { 00551 *data_type = 00552 (rxbuf[1] & SS_MASK_OUTPUTMODE_DATATYPE) >> SS_SHIFT_OUTPUTMODE_DATATYPE; 00553 *sc_en = 00554 (bool)((rxbuf[1] & SS_MASK_OUTPUTMODE_SC_EN) >> SS_SHIFT_OUTPUTMODE_SC_EN); 00555 } 00556 00557 return status; 00558 } 00559 00560 void SSInterface::fifo_sample_size(int data_type, int *sample_size) 00561 { 00562 *sample_size = 0; 00563 00564 if (data_type == SS_DATATYPE_RAW || data_type == SS_DATATYPE_BOTH) { 00565 for (int i = 0; i < SS_MAX_SUPPORTED_SENSOR_NUM; i++) { 00566 if (sensor_enabled_mode[i]) { 00567 assert_msg(sensor_data_reqs[i], "no ss_data_req found for enabled sensor"); 00568 *sample_size += sensor_data_reqs[i]->data_size; 00569 } 00570 } 00571 } 00572 00573 if (data_type == SS_DATATYPE_ALGO || data_type == SS_DATATYPE_BOTH) { 00574 for (int i = 0; i < SS_MAX_SUPPORTED_ALGO_NUM; i++) { 00575 if (algo_enabled_mode[i]) { 00576 assert_msg(algo_data_reqs[i], "no ss_data_req found for enabled algo"); 00577 *sample_size += algo_data_reqs[i]->data_size; 00578 } 00579 } 00580 } 00581 } 00582 00583 SS_STATUS SSInterface::num_avail_samples(int *num_samples) 00584 { 00585 uint8_t cmd_bytes[] = { SS_FAM_R_OUTPUTFIFO, SS_CMDIDX_OUT_NUMSAMPLES }; 00586 uint8_t rxbuf[2] = {0}; 00587 00588 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00589 0, 0, 00590 &rxbuf[0], ARRAY_SIZE(rxbuf)); 00591 00592 if (status == SS_SUCCESS) { 00593 *num_samples = rxbuf[1]; 00594 } 00595 00596 return status; 00597 } 00598 00599 SS_STATUS SSInterface::read_fifo_data( 00600 int num_samples, int sample_size, 00601 uint8_t* databuf, int databuf_sz) 00602 { 00603 int bytes_to_read = num_samples * sample_size + 1; //+1 for status byte 00604 assert_msg((bytes_to_read <= databuf_sz), "databuf too small"); 00605 00606 uint8_t cmd_bytes[] = { SS_FAM_R_OUTPUTFIFO, SS_CMDIDX_READFIFO }; 00607 00608 pr_err("[reading %d bytes (%d samples)\r\n", bytes_to_read, num_samples); 00609 00610 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00611 0, 0, 00612 databuf, bytes_to_read, 15); 00613 00614 return status; 00615 } 00616 00617 void SSInterface::irq_handler() 00618 { 00619 uint8_t databuf[512]; 00620 uint8_t sample_count; 00621 00622 uint8_t cmd_bytes[] = { SS_FAM_R_STATUS, SS_CMDIDX_STATUS }; 00623 uint8_t rxbuf[2] = {0}; 00624 00625 irq_pin.disable_irq(); 00626 00627 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00628 0, 0, 00629 &rxbuf[0], ARRAY_SIZE(rxbuf)); 00630 00631 if (status != SS_SUCCESS) { 00632 pr_err("Couldn't read status byte of SmartSensor!"); 00633 irq_pin.enable_irq(); 00634 return; 00635 } 00636 00637 if (rxbuf[1] & SS_MASK_STATUS_ERR) { 00638 pr_err("SmartSensor status error: %d", rxbuf[1] & SS_MASK_STATUS_ERR); 00639 } 00640 if (rxbuf[1] & SS_MASK_STATUS_FIFO_OUT_OVR) { 00641 pr_err("SmartSensor Output FIFO overflow!"); 00642 } 00643 if (rxbuf[1] & SS_MASK_STATUS_FIFO_IN_OVR) { 00644 pr_err("SmartSensor Input FIFO overflow!"); 00645 } 00646 00647 if (rxbuf[1] & SS_MASK_STATUS_DATA_RDY) { 00648 int num_samples; 00649 status = num_avail_samples(&num_samples); 00650 if (status != SS_SUCCESS) 00651 { 00652 pr_err("Couldn't read number of available samples in SmartSensor Output FIFO"); 00653 irq_pin.enable_irq(); 00654 return; 00655 } 00656 00657 if (num_samples <= 0) 00658 { 00659 irq_pin.enable_irq(); 00660 return; 00661 } 00662 00663 00664 int sample_size; 00665 fifo_sample_size(data_type, &sample_size); 00666 00667 size_t bytes_to_read = num_samples * sample_size + 1; //+1 for status byte 00668 if (bytes_to_read > sizeof(databuf)) { 00669 //Reduce number of samples to read to fit in buffer 00670 num_samples = (sizeof(databuf) - 1) / sample_size; 00671 } 00672 00673 status = read_fifo_data(num_samples, sample_size, &databuf[0], sizeof(databuf)); 00674 if (status != SS_SUCCESS) 00675 { 00676 pr_err("Couldn't read from SmartSensor Output FIFO"); 00677 irq_pin.enable_irq(); 00678 return; 00679 } 00680 00681 //Skip status byte 00682 uint8_t *data_ptr = &databuf[1]; 00683 00684 int i = 0; 00685 for (i = 0; i < num_samples; i++) { 00686 if (sc_en) { 00687 sample_count = *data_ptr++; 00688 pr_info("Received sample #%d", sample_count); 00689 } 00690 00691 //Chop up data and send to modules with enabled sensors 00692 if (data_type == SS_DATATYPE_RAW || data_type == SS_DATATYPE_BOTH) { 00693 for (int i = 0; i < SS_MAX_SUPPORTED_SENSOR_NUM; i++) { 00694 if (sensor_enabled_mode[i]) { 00695 assert_msg(sensor_data_reqs[i], 00696 "no ss_data_req found for enabled sensor"); 00697 sensor_data_reqs[i]->callback(data_ptr); 00698 data_ptr += sensor_data_reqs[i]->data_size; 00699 } 00700 } 00701 } 00702 if (data_type == SS_DATATYPE_ALGO || data_type == SS_DATATYPE_BOTH) { 00703 for (int i = 0; i < SS_MAX_SUPPORTED_ALGO_NUM; i++) { 00704 if (algo_enabled_mode[i]) { 00705 assert_msg(algo_data_reqs[i], 00706 "no ss_data_req found for enabled algo"); 00707 algo_data_reqs[i]->callback(data_ptr); 00708 data_ptr += algo_data_reqs[i]->data_size; 00709 } 00710 } 00711 } 00712 } 00713 } 00714 irq_pin.enable_irq(); 00715 } 00716 00717 void SSInterface::irq_handler_selftest(){ 00718 mfio_int_happened = true; 00719 } 00720 00721 bool SSInterface::reset_mfio_irq(){ 00722 bool ret = mfio_int_happened; 00723 mfio_int_happened = false; 00724 irq_pin.disable_irq(); 00725 irq_pin.fall(callback(this, &SSInterface::irq_handler)); 00726 irq_pin.enable_irq(); 00727 return ret; 00728 }
Generated on Mon Jul 18 2022 23:37:28 by
