Maxim Integrated / Mbed OS MAXREFDES220_HR_SPO2_MONITOR

Dependencies:   max32630fthr USBDevice

Fork of MAXREFDES220_HEART_RATE_MONITOR by Maxim Integrated

Finger Heart Rate Monitor and SpO2 Monitor

The MAXREFDES220 Smart Sensor FeatherWing board is a integrated solution for providing finger-based heart rate measurements and SpO2 (blood oxygen saturation). This evaluation board interfaces to the host computer using the I2C interface. Heart rate outpu is available in beats per minute (BPM) and SpO2 is reported in percentages.; the PPG (photoplethysmography) raw data is also available. The board has an MAX30101 chip which is a low power heart rate monitor with adjustable sample rates and adjustable LED currents. The low cost MAX32664 microcontroller is pre-flashed with C code for finger-based pulse rate and SpO2 monitoring. Bootloader software is included to allow for future algorithms or updates to the algorithm from Maxim Integrated.

Ordering information will be available soon.

Note: SpO2 values are not calibrated. Calibration should be performed using the final end product.

Warning

The MAXREFDES220 source code listed is dated and only compatible with the 1.2.8a.msbl. The latest sample host source code is available on the MAX32664 website.

MAXREFDES220 FeatherWing Pinout Connections

/media/uploads/phonemacro/maxrefdes220_pinouts_heart_rate_monitor.jpg

Committer:
Ismail Kose
Date:
Mon Aug 20 19:25:24 2018 -0700
Revision:
10:022b2cad9e9b
Parent:
8:0f55f59ca341
Child:
14:3fdc09d9017b
Fixing i2c comm issuess with bootloader, and remove unused code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Shaun Kelsey 0:da5f5b56060a 1 /***************************************************************************
Shaun Kelsey 0:da5f5b56060a 2 * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
Shaun Kelsey 0:da5f5b56060a 3 *
Shaun Kelsey 0:da5f5b56060a 4 * Permission is hereby granted, free of charge, to any person obtaining a
Shaun Kelsey 0:da5f5b56060a 5 * copy of this software and associated documentation files (the "Software"),
Shaun Kelsey 0:da5f5b56060a 6 * to deal in the Software without restriction, including without limitation
Shaun Kelsey 0:da5f5b56060a 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
Shaun Kelsey 0:da5f5b56060a 8 * and/or sell copies of the Software, and to permit persons to whom the
Shaun Kelsey 0:da5f5b56060a 9 * Software is furnished to do so, subject to the following conditions:
Shaun Kelsey 0:da5f5b56060a 10 *
Shaun Kelsey 0:da5f5b56060a 11 * The above copyright notice and this permission notice shall be included
Shaun Kelsey 0:da5f5b56060a 12 * in all copies or substantial portions of the Software.
Shaun Kelsey 0:da5f5b56060a 13 *
Shaun Kelsey 0:da5f5b56060a 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
Shaun Kelsey 0:da5f5b56060a 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Shaun Kelsey 0:da5f5b56060a 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Shaun Kelsey 0:da5f5b56060a 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
Shaun Kelsey 0:da5f5b56060a 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
Shaun Kelsey 0:da5f5b56060a 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
Shaun Kelsey 0:da5f5b56060a 20 * OTHER DEALINGS IN THE SOFTWARE.
Shaun Kelsey 0:da5f5b56060a 21 *
Shaun Kelsey 0:da5f5b56060a 22 * Except as contained in this notice, the name of Maxim Integrated
Shaun Kelsey 0:da5f5b56060a 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
Shaun Kelsey 0:da5f5b56060a 24 * Products, Inc. Branding Policy.
Shaun Kelsey 0:da5f5b56060a 25 *
Shaun Kelsey 0:da5f5b56060a 26 * The mere transfer of this software does not imply any licenses
Shaun Kelsey 0:da5f5b56060a 27 * of trade secrets, proprietary technology, copyrights, patents,
Shaun Kelsey 0:da5f5b56060a 28 * trademarks, maskwork rights, or any other form of intellectual
Shaun Kelsey 0:da5f5b56060a 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
Shaun Kelsey 0:da5f5b56060a 30 * ownership rights.
Shaun Kelsey 0:da5f5b56060a 31 ****************************************************************************
Shaun Kelsey 0:da5f5b56060a 32 */
Shaun Kelsey 0:da5f5b56060a 33
Shaun Kelsey 0:da5f5b56060a 34 #include "SSInterface.h"
Shaun Kelsey 0:da5f5b56060a 35 #include "Peripherals.h"
Shaun Kelsey 0:da5f5b56060a 36 #include "assert.h"
Shaun Kelsey 0:da5f5b56060a 37 #include "utils.h"
Shaun Kelsey 5:e458409e913f 38 #include "i2cm.h"
Shaun Kelsey 0:da5f5b56060a 39
Shaun Kelsey 0:da5f5b56060a 40 SSInterface::SSInterface(I2C &i2cBus, PinName ss_mfio, PinName ss_reset)
Shaun Kelsey 5:e458409e913f 41 :m_i2cBus(&i2cBus), m_spiBus(NULL),
Ismail Kose 10:022b2cad9e9b 42 mfio_pin(ss_mfio), reset_pin(ss_reset), irq_pin(ss_mfio),
Ismail Kose 10:022b2cad9e9b 43 irq_evt(1000000, "irq")
Shaun Kelsey 0:da5f5b56060a 44 {
Shaun Kelsey 0:da5f5b56060a 45 reset_pin.input();
Shaun Kelsey 0:da5f5b56060a 46 irq_pin.fall(callback(this, &SSInterface::irq_handler));
Shaun Kelsey 0:da5f5b56060a 47
Shaun Kelsey 0:da5f5b56060a 48 reset_to_main_app();
Shaun Kelsey 0:da5f5b56060a 49 get_data_type(&data_type, &sc_en);
Shaun Kelsey 0:da5f5b56060a 50 }
Shaun Kelsey 0:da5f5b56060a 51
Shaun Kelsey 0:da5f5b56060a 52 SSInterface::SSInterface(SPI &spiBus, PinName ss_mfio, PinName ss_reset)
Shaun Kelsey 5:e458409e913f 53 :m_i2cBus(NULL), m_spiBus(&spiBus),
Ismail Kose 10:022b2cad9e9b 54 mfio_pin(ss_mfio), reset_pin(ss_reset), irq_pin(ss_mfio),
Ismail Kose 10:022b2cad9e9b 55 irq_evt(1000000, "irq")
Shaun Kelsey 0:da5f5b56060a 56 {
Shaun Kelsey 0:da5f5b56060a 57 reset_pin.input();
Shaun Kelsey 0:da5f5b56060a 58 irq_pin.fall(callback(this, &SSInterface::irq_handler));
Shaun Kelsey 0:da5f5b56060a 59
Shaun Kelsey 0:da5f5b56060a 60 reset_to_main_app();
Shaun Kelsey 0:da5f5b56060a 61 get_data_type(&data_type, &sc_en);
Shaun Kelsey 0:da5f5b56060a 62 }
Shaun Kelsey 0:da5f5b56060a 63
Shaun Kelsey 0:da5f5b56060a 64 SSInterface::~SSInterface()
Shaun Kelsey 0:da5f5b56060a 65 {
Shaun Kelsey 0:da5f5b56060a 66 }
Shaun Kelsey 0:da5f5b56060a 67
Shaun Kelsey 0:da5f5b56060a 68 SS_STATUS SSInterface::reset_to_main_app()
Shaun Kelsey 0:da5f5b56060a 69 {
Ismail Kose 10:022b2cad9e9b 70 irq_pin.disable_irq();
keremsahin 8:0f55f59ca341 71 #if defined(BOOTLOADER_USES_MFIO)
Shaun Kelsey 0:da5f5b56060a 72 reset_pin.output();
Shaun Kelsey 0:da5f5b56060a 73 cfg_mfio(PIN_OUTPUT);
Shaun Kelsey 0:da5f5b56060a 74 reset_pin.write(0);
Shaun Kelsey 0:da5f5b56060a 75 wait_ms(SS_RESET_TIME);
Shaun Kelsey 0:da5f5b56060a 76 mfio_pin.write(1);
Shaun Kelsey 0:da5f5b56060a 77 reset_pin.write(1);
keremsahin 8:0f55f59ca341 78 wait_ms(SS_STARTUP_TO_MAIN_APP_TIME);
Shaun Kelsey 0:da5f5b56060a 79 cfg_mfio(PIN_INPUT);
Shaun Kelsey 0:da5f5b56060a 80 reset_pin.input();
Ismail Kose 10:022b2cad9e9b 81 irq_pin.enable_irq();
Shaun Kelsey 0:da5f5b56060a 82 // Verify we exited bootloader mode
Shaun Kelsey 0:da5f5b56060a 83 if (in_bootldr_mode() == 0)
Shaun Kelsey 0:da5f5b56060a 84 return SS_SUCCESS;
Shaun Kelsey 0:da5f5b56060a 85 else
Shaun Kelsey 0:da5f5b56060a 86 return SS_ERR_UNKNOWN;
keremsahin 8:0f55f59ca341 87 #else
keremsahin 8:0f55f59ca341 88 SS_STATUS status = exit_from_bootloader();
Ismail Kose 10:022b2cad9e9b 89 irq_pin.enable_irq();
keremsahin 8:0f55f59ca341 90 return status;
Shaun Kelsey 0:da5f5b56060a 91 #endif
Shaun Kelsey 0:da5f5b56060a 92 }
Shaun Kelsey 0:da5f5b56060a 93
Shaun Kelsey 0:da5f5b56060a 94 SS_STATUS SSInterface::reset_to_bootloader()
Shaun Kelsey 0:da5f5b56060a 95 {
Ismail Kose 10:022b2cad9e9b 96 irq_pin.disable_irq();
keremsahin 8:0f55f59ca341 97 #if defined(BOOTLOADER_USES_MFIO)
Shaun Kelsey 0:da5f5b56060a 98 reset_pin.output();
Shaun Kelsey 0:da5f5b56060a 99 cfg_mfio(PIN_OUTPUT);
Shaun Kelsey 0:da5f5b56060a 100 reset_pin.write(0);
Shaun Kelsey 0:da5f5b56060a 101 wait_ms(SS_RESET_TIME);
Shaun Kelsey 0:da5f5b56060a 102 mfio_pin.write(0);
Shaun Kelsey 0:da5f5b56060a 103 reset_pin.write(1);
keremsahin 8:0f55f59ca341 104 wait_ms(SS_STARTUP_TO_BTLDR_TIME);
Shaun Kelsey 0:da5f5b56060a 105 cfg_mfio(PIN_INPUT);
Shaun Kelsey 0:da5f5b56060a 106 reset_pin.input();
Ismail Kose 10:022b2cad9e9b 107 irq_pin.enable_irq();
Ismail Kose 7:3e2a5545f1d8 108 stay_in_bootloader();
keremsahin 8:0f55f59ca341 109
Shaun Kelsey 0:da5f5b56060a 110 // Verify we entered bootloader mode
Shaun Kelsey 0:da5f5b56060a 111 if (in_bootldr_mode() < 0)
Shaun Kelsey 0:da5f5b56060a 112 return SS_ERR_UNKNOWN;
Shaun Kelsey 0:da5f5b56060a 113 return SS_SUCCESS;
keremsahin 8:0f55f59ca341 114 #else
keremsahin 8:0f55f59ca341 115 stay_in_bootloader();
Ismail Kose 10:022b2cad9e9b 116 irq_pin.enable_irq();
keremsahin 8:0f55f59ca341 117 return SS_SUCCESS;
Shaun Kelsey 0:da5f5b56060a 118 #endif
Shaun Kelsey 0:da5f5b56060a 119 }
Shaun Kelsey 0:da5f5b56060a 120
Ismail Kose 7:3e2a5545f1d8 121 SS_STATUS SSInterface::exit_from_bootloader()
Ismail Kose 7:3e2a5545f1d8 122 {
Ismail Kose 7:3e2a5545f1d8 123 uint8_t cmd_bytes[] = { SS_FAM_W_MODE, SS_CMDIDX_MODE };
Ismail Kose 7:3e2a5545f1d8 124 uint8_t data[] = { 0x00 };
Ismail Kose 7:3e2a5545f1d8 125
Ismail Kose 7:3e2a5545f1d8 126 SS_STATUS status = write_cmd(
Ismail Kose 7:3e2a5545f1d8 127 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Ismail Kose 7:3e2a5545f1d8 128 &data[0], ARRAY_SIZE(data));
Ismail Kose 7:3e2a5545f1d8 129
Ismail Kose 7:3e2a5545f1d8 130 in_bootldr = (status == SS_SUCCESS) ? true : false;
Ismail Kose 7:3e2a5545f1d8 131 return status;
Ismail Kose 7:3e2a5545f1d8 132 }
Ismail Kose 7:3e2a5545f1d8 133
Ismail Kose 7:3e2a5545f1d8 134 SS_STATUS SSInterface::stay_in_bootloader()
Ismail Kose 7:3e2a5545f1d8 135 {
Ismail Kose 7:3e2a5545f1d8 136 uint8_t cmd_bytes[] = { SS_FAM_W_MODE, SS_CMDIDX_MODE };
Ismail Kose 7:3e2a5545f1d8 137 uint8_t data[] = { SS_MASK_MODE_BOOTLDR };
Ismail Kose 7:3e2a5545f1d8 138
Ismail Kose 7:3e2a5545f1d8 139 SS_STATUS status = write_cmd(
Ismail Kose 7:3e2a5545f1d8 140 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Ismail Kose 7:3e2a5545f1d8 141 &data[0], ARRAY_SIZE(data));
Ismail Kose 7:3e2a5545f1d8 142
Ismail Kose 7:3e2a5545f1d8 143 in_bootldr = (status == SS_SUCCESS) ? true : false;
Ismail Kose 7:3e2a5545f1d8 144 return status;
Ismail Kose 7:3e2a5545f1d8 145 }
Ismail Kose 7:3e2a5545f1d8 146
Shaun Kelsey 0:da5f5b56060a 147 SS_STATUS SSInterface::reset()
Shaun Kelsey 0:da5f5b56060a 148 {
Shaun Kelsey 0:da5f5b56060a 149 int bootldr = in_bootldr_mode();
Shaun Kelsey 0:da5f5b56060a 150 if (bootldr > 0)
Shaun Kelsey 0:da5f5b56060a 151 return reset_to_bootloader();
Shaun Kelsey 0:da5f5b56060a 152 else if (bootldr == 0)
Shaun Kelsey 0:da5f5b56060a 153 return reset_to_main_app();
Shaun Kelsey 0:da5f5b56060a 154 else
Shaun Kelsey 0:da5f5b56060a 155 return SS_ERR_UNKNOWN;
Shaun Kelsey 0:da5f5b56060a 156 }
Shaun Kelsey 0:da5f5b56060a 157
Shaun Kelsey 0:da5f5b56060a 158 SS_STATUS SSInterface::self_test(int idx, uint8_t *result, int sleep_ms){
Shaun Kelsey 5:e458409e913f 159 uint8_t cmd_bytes[] = { SS_FAM_R_SELFTEST, (uint8_t)idx };
Shaun Kelsey 0:da5f5b56060a 160 uint8_t rxbuf[2];
Shaun Kelsey 0:da5f5b56060a 161 SS_STATUS ret;
Shaun Kelsey 0:da5f5b56060a 162
Shaun Kelsey 0:da5f5b56060a 163 result[0] = 0xFF;
Shaun Kelsey 0:da5f5b56060a 164 ret = read_cmd(cmd_bytes, 2, (uint8_t *)0, 0, rxbuf, ARRAY_SIZE(rxbuf), sleep_ms);
Shaun Kelsey 0:da5f5b56060a 165 result[0] = rxbuf[1];
Shaun Kelsey 0:da5f5b56060a 166 return ret;
Shaun Kelsey 0:da5f5b56060a 167 }
Shaun Kelsey 0:da5f5b56060a 168
Shaun Kelsey 0:da5f5b56060a 169 void SSInterface::cfg_mfio(PinDirection dir)
Shaun Kelsey 0:da5f5b56060a 170 {
Shaun Kelsey 0:da5f5b56060a 171 if (dir == PIN_INPUT) {
Shaun Kelsey 0:da5f5b56060a 172 mfio_pin.input();
Shaun Kelsey 0:da5f5b56060a 173 mfio_pin.mode(PullUp);
Shaun Kelsey 0:da5f5b56060a 174 } else {
Shaun Kelsey 0:da5f5b56060a 175 mfio_pin.output();
Shaun Kelsey 0:da5f5b56060a 176 }
Shaun Kelsey 0:da5f5b56060a 177 }
Shaun Kelsey 0:da5f5b56060a 178
Shaun Kelsey 0:da5f5b56060a 179 void SSInterface::enable_irq()
Shaun Kelsey 0:da5f5b56060a 180 {
Shaun Kelsey 0:da5f5b56060a 181 irq_pin.enable_irq();
Shaun Kelsey 0:da5f5b56060a 182 }
Shaun Kelsey 0:da5f5b56060a 183 void SSInterface::disable_irq()
Shaun Kelsey 0:da5f5b56060a 184 {
Shaun Kelsey 0:da5f5b56060a 185 irq_pin.disable_irq();
Shaun Kelsey 0:da5f5b56060a 186 }
Shaun Kelsey 0:da5f5b56060a 187
Shaun Kelsey 0:da5f5b56060a 188 void SSInterface::mfio_selftest(){
Shaun Kelsey 0:da5f5b56060a 189 disable_irq();
Shaun Kelsey 0:da5f5b56060a 190 irq_pin.fall(callback(this, &SSInterface::irq_handler_selftest));
Shaun Kelsey 0:da5f5b56060a 191 enable_irq();
Shaun Kelsey 0:da5f5b56060a 192 }
Shaun Kelsey 0:da5f5b56060a 193
Shaun Kelsey 0:da5f5b56060a 194 int SSInterface::in_bootldr_mode()
Shaun Kelsey 0:da5f5b56060a 195 {
Shaun Kelsey 0:da5f5b56060a 196 uint8_t cmd_bytes[] = { SS_FAM_R_MODE, SS_CMDIDX_MODE };
Shaun Kelsey 0:da5f5b56060a 197 uint8_t rxbuf[2] = { 0 };
Shaun Kelsey 0:da5f5b56060a 198
Shaun Kelsey 0:da5f5b56060a 199 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 200 0, 0,
Shaun Kelsey 0:da5f5b56060a 201 &rxbuf[0], ARRAY_SIZE(rxbuf));
Shaun Kelsey 0:da5f5b56060a 202 if (status != SS_SUCCESS)
Shaun Kelsey 0:da5f5b56060a 203 return -1;
Shaun Kelsey 0:da5f5b56060a 204
Shaun Kelsey 0:da5f5b56060a 205 return (rxbuf[1] & SS_MASK_MODE_BOOTLDR);
Shaun Kelsey 0:da5f5b56060a 206 }
Shaun Kelsey 0:da5f5b56060a 207
Shaun Kelsey 0:da5f5b56060a 208 const char* SSInterface::get_ss_fw_version()
Shaun Kelsey 0:da5f5b56060a 209 {
Shaun Kelsey 0:da5f5b56060a 210 uint8_t cmd_bytes[2];
Shaun Kelsey 0:da5f5b56060a 211 uint8_t rxbuf[4];
Shaun Kelsey 0:da5f5b56060a 212
Shaun Kelsey 0:da5f5b56060a 213 int bootldr = in_bootldr_mode();
Shaun Kelsey 0:da5f5b56060a 214
Shaun Kelsey 0:da5f5b56060a 215 if (bootldr > 0) {
Shaun Kelsey 0:da5f5b56060a 216 cmd_bytes[0] = SS_FAM_R_BOOTLOADER;
Shaun Kelsey 0:da5f5b56060a 217 cmd_bytes[1] = SS_CMDIDX_BOOTFWVERSION;
Shaun Kelsey 0:da5f5b56060a 218 } else if (bootldr == 0) {
Shaun Kelsey 0:da5f5b56060a 219 cmd_bytes[0] = SS_FAM_R_IDENTITY;
Shaun Kelsey 0:da5f5b56060a 220 cmd_bytes[1] = SS_CMDIDX_FWVERSION;
Shaun Kelsey 0:da5f5b56060a 221 } else {
Shaun Kelsey 0:da5f5b56060a 222 return plat_name;
Shaun Kelsey 0:da5f5b56060a 223 }
Shaun Kelsey 0:da5f5b56060a 224
Shaun Kelsey 0:da5f5b56060a 225 SS_STATUS status = read_cmd(
Shaun Kelsey 0:da5f5b56060a 226 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 227 0, 0,
Shaun Kelsey 0:da5f5b56060a 228 &rxbuf[0], ARRAY_SIZE(rxbuf));
Shaun Kelsey 0:da5f5b56060a 229
Shaun Kelsey 0:da5f5b56060a 230 if (status == SS_SUCCESS) {
Shaun Kelsey 0:da5f5b56060a 231 snprintf(fw_version, sizeof(fw_version),
Shaun Kelsey 0:da5f5b56060a 232 "%d.%d.%d", rxbuf[1], rxbuf[2], rxbuf[3]);
Shaun Kelsey 0:da5f5b56060a 233 pr_info("fw_version:%s\r\n", fw_version);
Shaun Kelsey 0:da5f5b56060a 234 }
Shaun Kelsey 0:da5f5b56060a 235
Shaun Kelsey 0:da5f5b56060a 236 return &fw_version[0];
Shaun Kelsey 0:da5f5b56060a 237 }
Shaun Kelsey 0:da5f5b56060a 238
keremsahin 8:0f55f59ca341 239 const char* SSInterface::get_ss_algo_version()
keremsahin 8:0f55f59ca341 240 {
keremsahin 8:0f55f59ca341 241 uint8_t cmd_bytes[3];
keremsahin 8:0f55f59ca341 242 uint8_t rxbuf[4];
keremsahin 8:0f55f59ca341 243
keremsahin 8:0f55f59ca341 244 int bootldr = in_bootldr_mode();
keremsahin 8:0f55f59ca341 245
keremsahin 8:0f55f59ca341 246 if (bootldr > 0) {
keremsahin 8:0f55f59ca341 247 cmd_bytes[0] = SS_FAM_R_BOOTLOADER;
keremsahin 8:0f55f59ca341 248 cmd_bytes[1] = SS_CMDIDX_BOOTFWVERSION;
keremsahin 8:0f55f59ca341 249 cmd_bytes[2] = 0;
keremsahin 8:0f55f59ca341 250 } else if (bootldr == 0) {
keremsahin 8:0f55f59ca341 251 cmd_bytes[0] = SS_FAM_R_IDENTITY;
keremsahin 8:0f55f59ca341 252 cmd_bytes[1] = SS_CMDIDX_ALGOVER;
keremsahin 8:0f55f59ca341 253 cmd_bytes[2] = SS_CMDIDX_AVAILSENSORS;
keremsahin 8:0f55f59ca341 254 } else {
keremsahin 8:0f55f59ca341 255 return plat_name;
keremsahin 8:0f55f59ca341 256 }
keremsahin 8:0f55f59ca341 257
keremsahin 8:0f55f59ca341 258 SS_STATUS status = read_cmd(
keremsahin 8:0f55f59ca341 259 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
keremsahin 8:0f55f59ca341 260 0, 0,
keremsahin 8:0f55f59ca341 261 &rxbuf[0], ARRAY_SIZE(rxbuf));
keremsahin 8:0f55f59ca341 262
keremsahin 8:0f55f59ca341 263 if (status == SS_SUCCESS) {
keremsahin 8:0f55f59ca341 264 snprintf(algo_version, sizeof(algo_version),
keremsahin 8:0f55f59ca341 265 "%d.%d.%d", rxbuf[1], rxbuf[2], rxbuf[3]);
keremsahin 8:0f55f59ca341 266 pr_info("algo_version:%s\r\n", fw_version);
keremsahin 8:0f55f59ca341 267 }
keremsahin 8:0f55f59ca341 268
keremsahin 8:0f55f59ca341 269 return &algo_version[0];
keremsahin 8:0f55f59ca341 270 }
Shaun Kelsey 0:da5f5b56060a 271 const char* SSInterface::get_ss_platform_name()
Shaun Kelsey 0:da5f5b56060a 272 {
Shaun Kelsey 0:da5f5b56060a 273 uint8_t cmd_bytes[] = { SS_FAM_R_IDENTITY, SS_CMDIDX_PLATTYPE };
Shaun Kelsey 0:da5f5b56060a 274 uint8_t rxbuf[2];
Shaun Kelsey 0:da5f5b56060a 275
Shaun Kelsey 0:da5f5b56060a 276 SS_STATUS status = read_cmd(
Shaun Kelsey 0:da5f5b56060a 277 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 278 0, 0,
Shaun Kelsey 0:da5f5b56060a 279 &rxbuf[0], ARRAY_SIZE(rxbuf));
Shaun Kelsey 0:da5f5b56060a 280
Shaun Kelsey 0:da5f5b56060a 281 if (status == SS_SUCCESS) {
Shaun Kelsey 0:da5f5b56060a 282 if (rxbuf[1] == SS_PLAT_MAX3263X) {
Shaun Kelsey 0:da5f5b56060a 283 if (in_bootldr_mode() > 0) {
Shaun Kelsey 0:da5f5b56060a 284 plat_name = SS_BOOTLOADER_PLATFORM_MAX3263X;
Shaun Kelsey 0:da5f5b56060a 285 } else {
Shaun Kelsey 0:da5f5b56060a 286 plat_name = SS_PLATFORM_MAX3263X;
Shaun Kelsey 0:da5f5b56060a 287 }
Shaun Kelsey 0:da5f5b56060a 288 } else if (rxbuf[1] == SS_PLAT_MAX32660) {
Shaun Kelsey 0:da5f5b56060a 289 if (in_bootldr_mode() > 0) {
Shaun Kelsey 0:da5f5b56060a 290 plat_name = SS_BOOTLOADER_PLATFORM_MAX32660;
Shaun Kelsey 0:da5f5b56060a 291 } else {
Shaun Kelsey 0:da5f5b56060a 292 plat_name = SS_PLATFORM_MAX32660;
Shaun Kelsey 0:da5f5b56060a 293 }
Shaun Kelsey 0:da5f5b56060a 294 }
Shaun Kelsey 0:da5f5b56060a 295 }
Shaun Kelsey 0:da5f5b56060a 296
Shaun Kelsey 0:da5f5b56060a 297 return plat_name;
Shaun Kelsey 0:da5f5b56060a 298 }
Shaun Kelsey 0:da5f5b56060a 299
Shaun Kelsey 0:da5f5b56060a 300 SS_STATUS SSInterface::write_cmd(uint8_t *cmd_bytes, int cmd_bytes_len,
Shaun Kelsey 0:da5f5b56060a 301 uint8_t *data, int data_len,
Shaun Kelsey 0:da5f5b56060a 302 int sleep_ms)
Shaun Kelsey 0:da5f5b56060a 303 {
Shaun Kelsey 0:da5f5b56060a 304 int total_len = data_len + cmd_bytes_len;
Shaun Kelsey 0:da5f5b56060a 305
Shaun Kelsey 0:da5f5b56060a 306 if (total_len <= SS_SMALL_BUF_SIZE) {
Shaun Kelsey 0:da5f5b56060a 307 return write_cmd_small(cmd_bytes, cmd_bytes_len, data, data_len, sleep_ms);
Shaun Kelsey 5:e458409e913f 308 } else if (total_len <= SS_MED_BUF_SIZE) {
Shaun Kelsey 5:e458409e913f 309 return write_cmd_medium(cmd_bytes, cmd_bytes_len, data, data_len, sleep_ms);
Shaun Kelsey 0:da5f5b56060a 310 } else if (total_len <= SS_LARGE_BUF_SIZE) {
Shaun Kelsey 0:da5f5b56060a 311 return write_cmd_large(cmd_bytes, cmd_bytes_len, data, data_len, sleep_ms);
Shaun Kelsey 0:da5f5b56060a 312 } else {
Shaun Kelsey 0:da5f5b56060a 313 assert_msg(true, "Tried to send I2C tx larger than maximum allowed size\n");
Shaun Kelsey 0:da5f5b56060a 314 return SS_ERR_DATA_FORMAT;
Shaun Kelsey 0:da5f5b56060a 315 }
Shaun Kelsey 0:da5f5b56060a 316 }
Shaun Kelsey 0:da5f5b56060a 317
Shaun Kelsey 0:da5f5b56060a 318 SS_STATUS SSInterface::write_cmd(uint8_t *tx_buf, int tx_len, int sleep_ms)
Shaun Kelsey 0:da5f5b56060a 319 {
Shaun Kelsey 0:da5f5b56060a 320 pr_info("write_cmd: ");
Shaun Kelsey 0:da5f5b56060a 321 for (int i = 0; i < tx_len; i++) {
Shaun Kelsey 0:da5f5b56060a 322 pr_info("0x%02X ", tx_buf[i]);
Shaun Kelsey 0:da5f5b56060a 323 }
Shaun Kelsey 0:da5f5b56060a 324 pr_info("\r\n");
Shaun Kelsey 0:da5f5b56060a 325
Shaun Kelsey 5:e458409e913f 326 int ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)tx_buf, tx_len);
Shaun Kelsey 5:e458409e913f 327
Shaun Kelsey 5:e458409e913f 328 int retries = 4;
Shaun Kelsey 5:e458409e913f 329 while (ret != 0 && retries-- > 0) {
Shaun Kelsey 5:e458409e913f 330 pr_err("i2c wr retry\r\n");
Shaun Kelsey 5:e458409e913f 331 wait_ms(1);
Shaun Kelsey 5:e458409e913f 332 ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)tx_buf, tx_len);
Shaun Kelsey 5:e458409e913f 333 }
Shaun Kelsey 0:da5f5b56060a 334
Shaun Kelsey 0:da5f5b56060a 335 if (ret != 0) {
Shaun Kelsey 0:da5f5b56060a 336 pr_err("m_i2cBus->write returned %d\r\n", ret);
Shaun Kelsey 0:da5f5b56060a 337 return SS_ERR_UNAVAILABLE;
Shaun Kelsey 0:da5f5b56060a 338 }
Shaun Kelsey 0:da5f5b56060a 339
Shaun Kelsey 0:da5f5b56060a 340 wait_ms(sleep_ms);
Shaun Kelsey 0:da5f5b56060a 341
Shaun Kelsey 0:da5f5b56060a 342 char status_byte;
Shaun Kelsey 5:e458409e913f 343 ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, &status_byte, 1);
Shaun Kelsey 5:e458409e913f 344 bool try_again = (status_byte == SS_ERR_TRY_AGAIN);
Shaun Kelsey 5:e458409e913f 345 while ((ret != 0 || try_again)
Shaun Kelsey 5:e458409e913f 346 && retries-- > 0) {
Shaun Kelsey 5:e458409e913f 347 pr_info("i2c rd retry\r\n");
Shaun Kelsey 5:e458409e913f 348 wait_ms(sleep_ms);
Shaun Kelsey 5:e458409e913f 349 ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, &status_byte, 1);
Shaun Kelsey 5:e458409e913f 350 try_again = (status_byte == SS_ERR_TRY_AGAIN);
Shaun Kelsey 5:e458409e913f 351 }
Shaun Kelsey 0:da5f5b56060a 352
Shaun Kelsey 5:e458409e913f 353 if (ret != 0 || try_again) {
Shaun Kelsey 5:e458409e913f 354 pr_err("m_i2cBus->read returned %d, ss status_byte %d\r\n", ret, status_byte);
Shaun Kelsey 0:da5f5b56060a 355 return SS_ERR_UNAVAILABLE;
Shaun Kelsey 0:da5f5b56060a 356 }
Shaun Kelsey 0:da5f5b56060a 357
Shaun Kelsey 0:da5f5b56060a 358 pr_info("status_byte: %d\r\n", status_byte);
Shaun Kelsey 0:da5f5b56060a 359
Shaun Kelsey 0:da5f5b56060a 360 return (SS_STATUS)status_byte;
Shaun Kelsey 0:da5f5b56060a 361 }
Shaun Kelsey 0:da5f5b56060a 362
Shaun Kelsey 0:da5f5b56060a 363 SS_STATUS SSInterface::write_cmd_small(uint8_t *cmd_bytes, int cmd_bytes_len,
Shaun Kelsey 0:da5f5b56060a 364 uint8_t *data, int data_len,
Shaun Kelsey 0:da5f5b56060a 365 int sleep_ms)
Shaun Kelsey 0:da5f5b56060a 366 {
Shaun Kelsey 0:da5f5b56060a 367 uint8_t write_buf[SS_SMALL_BUF_SIZE];
Shaun Kelsey 0:da5f5b56060a 368 memcpy(write_buf, cmd_bytes, cmd_bytes_len);
Shaun Kelsey 0:da5f5b56060a 369 memcpy(write_buf + cmd_bytes_len, data, data_len);
Shaun Kelsey 0:da5f5b56060a 370
Shaun Kelsey 0:da5f5b56060a 371 SS_STATUS status = write_cmd(write_buf, cmd_bytes_len + data_len, sleep_ms);
Shaun Kelsey 0:da5f5b56060a 372 return status;
Shaun Kelsey 0:da5f5b56060a 373 }
Shaun Kelsey 0:da5f5b56060a 374
Shaun Kelsey 5:e458409e913f 375 SS_STATUS SSInterface::write_cmd_medium(uint8_t *cmd_bytes, int cmd_bytes_len,
Shaun Kelsey 5:e458409e913f 376 uint8_t *data, int data_len,
Shaun Kelsey 5:e458409e913f 377 int sleep_ms)
Shaun Kelsey 5:e458409e913f 378 {
Shaun Kelsey 5:e458409e913f 379 uint8_t write_buf[SS_MED_BUF_SIZE];
Shaun Kelsey 5:e458409e913f 380 memcpy(write_buf, cmd_bytes, cmd_bytes_len);
Shaun Kelsey 5:e458409e913f 381 memcpy(write_buf + cmd_bytes_len, data, data_len);
Shaun Kelsey 5:e458409e913f 382
Shaun Kelsey 5:e458409e913f 383 SS_STATUS status = write_cmd(write_buf, cmd_bytes_len + data_len, sleep_ms);
Shaun Kelsey 5:e458409e913f 384 return status;
Shaun Kelsey 5:e458409e913f 385 }
Shaun Kelsey 5:e458409e913f 386
Shaun Kelsey 0:da5f5b56060a 387 SS_STATUS SSInterface::write_cmd_large(uint8_t *cmd_bytes, int cmd_bytes_len,
Shaun Kelsey 0:da5f5b56060a 388 uint8_t *data, int data_len,
Shaun Kelsey 0:da5f5b56060a 389 int sleep_ms)
Shaun Kelsey 0:da5f5b56060a 390 {
Shaun Kelsey 0:da5f5b56060a 391 uint8_t write_buf[SS_LARGE_BUF_SIZE];
Shaun Kelsey 0:da5f5b56060a 392 memcpy(write_buf, cmd_bytes, cmd_bytes_len);
Shaun Kelsey 0:da5f5b56060a 393 memcpy(write_buf + cmd_bytes_len, data, data_len);
Shaun Kelsey 0:da5f5b56060a 394
Shaun Kelsey 0:da5f5b56060a 395 SS_STATUS status = write_cmd(write_buf, cmd_bytes_len + data_len, sleep_ms);
Shaun Kelsey 0:da5f5b56060a 396 return status;
Shaun Kelsey 0:da5f5b56060a 397 }
Shaun Kelsey 0:da5f5b56060a 398
Shaun Kelsey 0:da5f5b56060a 399 SS_STATUS SSInterface::read_cmd(uint8_t *cmd_bytes, int cmd_bytes_len,
Shaun Kelsey 0:da5f5b56060a 400 uint8_t *data, int data_len,
Shaun Kelsey 0:da5f5b56060a 401 uint8_t *rxbuf, int rxbuf_sz,
Shaun Kelsey 0:da5f5b56060a 402 int sleep_ms)
Shaun Kelsey 0:da5f5b56060a 403 {
Shaun Kelsey 0:da5f5b56060a 404 pr_info("read_cmd: ");
Shaun Kelsey 0:da5f5b56060a 405 for (int i = 0; i < cmd_bytes_len; i++) {
Shaun Kelsey 0:da5f5b56060a 406 pr_info("0x%02X ", cmd_bytes[i]);
Shaun Kelsey 0:da5f5b56060a 407 }
Shaun Kelsey 0:da5f5b56060a 408 pr_info("\r\n");
Shaun Kelsey 0:da5f5b56060a 409
Shaun Kelsey 5:e458409e913f 410
Shaun Kelsey 5:e458409e913f 411 int retries = 4;
Shaun Kelsey 5:e458409e913f 412
Shaun Kelsey 5:e458409e913f 413 int ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)cmd_bytes, cmd_bytes_len, (data_len != 0));
Ismail Kose 10:022b2cad9e9b 414
Shaun Kelsey 0:da5f5b56060a 415 if (data_len != 0) {
Shaun Kelsey 0:da5f5b56060a 416 ret |= m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)data, data_len, false);
Shaun Kelsey 0:da5f5b56060a 417 }
Shaun Kelsey 0:da5f5b56060a 418
Shaun Kelsey 5:e458409e913f 419 while (ret != 0 && retries-- > 0) {
Shaun Kelsey 5:e458409e913f 420 pr_err("i2c wr retry\r\n");
Shaun Kelsey 5:e458409e913f 421 wait_ms(1);
Shaun Kelsey 5:e458409e913f 422 ret = m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)cmd_bytes, cmd_bytes_len, (data_len != 0));
Shaun Kelsey 5:e458409e913f 423 if (data_len != 0) {
Shaun Kelsey 5:e458409e913f 424 ret |= m_i2cBus->write(SS_I2C_8BIT_SLAVE_ADDR, (char*)data, data_len, false);
Shaun Kelsey 5:e458409e913f 425 }
Shaun Kelsey 5:e458409e913f 426 }
Shaun Kelsey 5:e458409e913f 427
Shaun Kelsey 0:da5f5b56060a 428 if (ret != 0) {
Shaun Kelsey 0:da5f5b56060a 429 pr_err("m_i2cBus->write returned %d\r\n", ret);
Shaun Kelsey 0:da5f5b56060a 430 return SS_ERR_UNAVAILABLE;
Shaun Kelsey 0:da5f5b56060a 431 }
Shaun Kelsey 0:da5f5b56060a 432
Shaun Kelsey 0:da5f5b56060a 433 wait_ms(sleep_ms);
Shaun Kelsey 0:da5f5b56060a 434
Shaun Kelsey 5:e458409e913f 435 ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, (char*)rxbuf, rxbuf_sz);
Shaun Kelsey 5:e458409e913f 436 bool try_again = (rxbuf[0] == SS_ERR_TRY_AGAIN);
Shaun Kelsey 5:e458409e913f 437 while ((ret != 0 || try_again) && retries-- > 0) {
Shaun Kelsey 5:e458409e913f 438 pr_info("i2c rd retry\r\n");
Shaun Kelsey 5:e458409e913f 439 wait_ms(sleep_ms);
Shaun Kelsey 5:e458409e913f 440 ret = m_i2cBus->read(SS_I2C_8BIT_SLAVE_ADDR, (char*)rxbuf, rxbuf_sz);
Shaun Kelsey 5:e458409e913f 441 try_again = (rxbuf[0] == SS_ERR_TRY_AGAIN);
Shaun Kelsey 5:e458409e913f 442 }
Shaun Kelsey 5:e458409e913f 443 if (ret != 0 || try_again) {
Shaun Kelsey 5:e458409e913f 444 pr_err("m_i2cBus->read returned %d, ss status_byte %d\r\n", ret, rxbuf[0]);
Shaun Kelsey 0:da5f5b56060a 445 return SS_ERR_UNAVAILABLE;
Shaun Kelsey 0:da5f5b56060a 446 }
Shaun Kelsey 0:da5f5b56060a 447
Shaun Kelsey 0:da5f5b56060a 448 pr_info("status_byte: %d\r\n", rxbuf[0]);
Shaun Kelsey 0:da5f5b56060a 449 pr_info("data: ");
Shaun Kelsey 0:da5f5b56060a 450 for (int i = 1; i < rxbuf_sz; i++) {
Shaun Kelsey 0:da5f5b56060a 451 pr_info("0x%02X ", rxbuf[i]);
Shaun Kelsey 0:da5f5b56060a 452 }
Shaun Kelsey 0:da5f5b56060a 453 pr_info("\r\n");
Shaun Kelsey 0:da5f5b56060a 454
Shaun Kelsey 0:da5f5b56060a 455 return (SS_STATUS)rxbuf[0];
Shaun Kelsey 0:da5f5b56060a 456 }
Shaun Kelsey 0:da5f5b56060a 457
Shaun Kelsey 0:da5f5b56060a 458 SS_STATUS SSInterface::get_reg(int idx, uint8_t addr, uint32_t *val)
Shaun Kelsey 0:da5f5b56060a 459 {
Shaun Kelsey 0:da5f5b56060a 460 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");
Shaun Kelsey 0:da5f5b56060a 461
Shaun Kelsey 0:da5f5b56060a 462 uint8_t cmd_bytes[] = { SS_FAM_R_REGATTRIBS, (uint8_t)idx };
Shaun Kelsey 0:da5f5b56060a 463 uint8_t rx_reg_attribs[3] = {0};
Shaun Kelsey 0:da5f5b56060a 464
Shaun Kelsey 0:da5f5b56060a 465 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 466 0, 0,
Shaun Kelsey 0:da5f5b56060a 467 &rx_reg_attribs[0], ARRAY_SIZE(rx_reg_attribs));
Shaun Kelsey 0:da5f5b56060a 468
Shaun Kelsey 0:da5f5b56060a 469 if (status != SS_SUCCESS)
Shaun Kelsey 0:da5f5b56060a 470 return status;
Shaun Kelsey 0:da5f5b56060a 471
Shaun Kelsey 0:da5f5b56060a 472 int reg_width = rx_reg_attribs[1];
Shaun Kelsey 0:da5f5b56060a 473
Shaun Kelsey 0:da5f5b56060a 474 uint8_t cmd_bytes2[] = { SS_FAM_R_READREG, (uint8_t)idx, addr };
Shaun Kelsey 0:da5f5b56060a 475 uint8_t rxbuf[5] = {0};
Shaun Kelsey 0:da5f5b56060a 476
Shaun Kelsey 0:da5f5b56060a 477 status = read_cmd(&cmd_bytes2[0], ARRAY_SIZE(cmd_bytes2),
Shaun Kelsey 0:da5f5b56060a 478 0, 0,
Shaun Kelsey 5:e458409e913f 479 &rxbuf[0], reg_width + 1);
Shaun Kelsey 0:da5f5b56060a 480
Shaun Kelsey 0:da5f5b56060a 481 if (status == SS_SUCCESS) {
Shaun Kelsey 0:da5f5b56060a 482 *val = 0;
Shaun Kelsey 0:da5f5b56060a 483 for (int i = 0; i < reg_width; i++) {
Shaun Kelsey 0:da5f5b56060a 484 *val = (*val << 8) | rxbuf[i + 1];
Shaun Kelsey 0:da5f5b56060a 485 }
Shaun Kelsey 0:da5f5b56060a 486 }
Shaun Kelsey 0:da5f5b56060a 487
Shaun Kelsey 0:da5f5b56060a 488 return status;
Shaun Kelsey 0:da5f5b56060a 489 }
Shaun Kelsey 0:da5f5b56060a 490
Shaun Kelsey 0:da5f5b56060a 491 SS_STATUS SSInterface::set_reg(int idx, uint8_t addr, uint32_t val, int byte_size)
Shaun Kelsey 0:da5f5b56060a 492 {
Shaun Kelsey 0:da5f5b56060a 493 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");
Shaun Kelsey 0:da5f5b56060a 494
Shaun Kelsey 0:da5f5b56060a 495 uint8_t cmd_bytes[] = { SS_FAM_W_WRITEREG, (uint8_t)idx, addr };
Shaun Kelsey 0:da5f5b56060a 496 uint8_t data_bytes[4];
Shaun Kelsey 0:da5f5b56060a 497 for (int i = 0; i < byte_size; i++) {
Shaun Kelsey 0:da5f5b56060a 498 data_bytes[i] = (val >> (8 * (byte_size - 1)) & 0xFF);
Shaun Kelsey 0:da5f5b56060a 499 }
Shaun Kelsey 0:da5f5b56060a 500
Shaun Kelsey 0:da5f5b56060a 501 SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 502 &data_bytes[0], byte_size);
Shaun Kelsey 0:da5f5b56060a 503
Shaun Kelsey 0:da5f5b56060a 504 return status;
Shaun Kelsey 0:da5f5b56060a 505 }
Shaun Kelsey 0:da5f5b56060a 506
Shaun Kelsey 0:da5f5b56060a 507 SS_STATUS SSInterface::dump_reg(int idx, addr_val_pair* reg_vals, int reg_vals_sz, int* num_regs)
Shaun Kelsey 0:da5f5b56060a 508 {
Shaun Kelsey 0:da5f5b56060a 509 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");
Shaun Kelsey 0:da5f5b56060a 510
Shaun Kelsey 0:da5f5b56060a 511 uint8_t cmd_bytes[] = { SS_FAM_R_REGATTRIBS, (uint8_t)idx };
Shaun Kelsey 0:da5f5b56060a 512 uint8_t rx_reg_attribs[3] = {0};
Shaun Kelsey 0:da5f5b56060a 513
Shaun Kelsey 0:da5f5b56060a 514 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 515 0, 0,
Shaun Kelsey 0:da5f5b56060a 516 &rx_reg_attribs[0], ARRAY_SIZE(rx_reg_attribs));
Shaun Kelsey 0:da5f5b56060a 517
Shaun Kelsey 0:da5f5b56060a 518 if (status != SS_SUCCESS)
Shaun Kelsey 0:da5f5b56060a 519 return status;
Shaun Kelsey 0:da5f5b56060a 520
Shaun Kelsey 0:da5f5b56060a 521 int reg_width = rx_reg_attribs[1];
Shaun Kelsey 0:da5f5b56060a 522 *num_regs = rx_reg_attribs[2];
Shaun Kelsey 0:da5f5b56060a 523 assert_msg((*num_regs <= reg_vals_sz), "Need to increase reg_vals array to hold all dump_reg data");
Shaun Kelsey 0:da5f5b56060a 524 assert_msg(((size_t)reg_width <= sizeof(uint32_t)), "IC returned register values greater than 4 bytes in width");
Shaun Kelsey 0:da5f5b56060a 525
Shaun Kelsey 0:da5f5b56060a 526 int dump_reg_sz = (*num_regs) * (reg_width + 1) + 1; //+1 to reg_width for address, +1 for status byte
Shaun Kelsey 0:da5f5b56060a 527
Shaun Kelsey 0:da5f5b56060a 528 uint8_t rxbuf[512];
Shaun Kelsey 0:da5f5b56060a 529 assert_msg(((size_t)dump_reg_sz <= sizeof(rxbuf)), "Need to increase buffer size to receive dump_reg data");
Shaun Kelsey 0:da5f5b56060a 530
Shaun Kelsey 0:da5f5b56060a 531 cmd_bytes[0] = SS_FAM_R_DUMPREG;
Shaun Kelsey 0:da5f5b56060a 532 status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 533 0, 0,
Shaun Kelsey 0:da5f5b56060a 534 &rxbuf[0], dump_reg_sz, SS_DUMP_REG_SLEEP_MS);
Shaun Kelsey 0:da5f5b56060a 535
Shaun Kelsey 0:da5f5b56060a 536 if (status != SS_SUCCESS)
Shaun Kelsey 0:da5f5b56060a 537 return status;
Shaun Kelsey 0:da5f5b56060a 538
Shaun Kelsey 0:da5f5b56060a 539 //rxbuf format is [status][addr0](reg_width x [val0])[addr1](reg_width x [val1])...
Shaun Kelsey 0:da5f5b56060a 540 for (int reg = 0; reg < *num_regs; reg++) {
Shaun Kelsey 0:da5f5b56060a 541 reg_vals[reg].addr = rxbuf[(reg * (reg_width + 1)) + 1];
Shaun Kelsey 0:da5f5b56060a 542 uint32_t *val = &(reg_vals[reg].val);
Shaun Kelsey 0:da5f5b56060a 543 *val = 0;
Shaun Kelsey 0:da5f5b56060a 544 for (int byte = 0; byte < reg_width; byte++) {
Shaun Kelsey 0:da5f5b56060a 545 *val = (*val << 8) | rxbuf[(reg * (reg_width + 1)) + byte + 2];
Shaun Kelsey 0:da5f5b56060a 546 }
Shaun Kelsey 0:da5f5b56060a 547 }
Shaun Kelsey 0:da5f5b56060a 548
Shaun Kelsey 0:da5f5b56060a 549 return SS_SUCCESS;
Shaun Kelsey 0:da5f5b56060a 550 }
Shaun Kelsey 0:da5f5b56060a 551
Shaun Kelsey 0:da5f5b56060a 552 SS_STATUS SSInterface::enable_sensor(int idx, int mode, ss_data_req *data_req)
Shaun Kelsey 0:da5f5b56060a 553 {
Shaun Kelsey 0:da5f5b56060a 554 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");
Shaun Kelsey 0:da5f5b56060a 555 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");
Shaun Kelsey 0:da5f5b56060a 556 assert_msg((mode != 0), "Tried to enable sensor to mode 0, but mode 0 is disable");
Shaun Kelsey 0:da5f5b56060a 557
Shaun Kelsey 5:e458409e913f 558
Shaun Kelsey 0:da5f5b56060a 559 uint8_t cmd_bytes[] = { SS_FAM_W_SENSORMODE, (uint8_t)idx, (uint8_t)mode };
Shaun Kelsey 0:da5f5b56060a 560
Shaun Kelsey 0:da5f5b56060a 561 SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 0, 0, SS_ENABLE_SENSOR_SLEEP_MS);
Shaun Kelsey 0:da5f5b56060a 562
Shaun Kelsey 0:da5f5b56060a 563 if (status == SS_SUCCESS) {
Shaun Kelsey 0:da5f5b56060a 564 sensor_enabled_mode[idx] = mode;
Shaun Kelsey 0:da5f5b56060a 565 sensor_data_reqs[idx] = data_req;
Shaun Kelsey 0:da5f5b56060a 566 }
Shaun Kelsey 0:da5f5b56060a 567 return status;
Shaun Kelsey 0:da5f5b56060a 568 }
Shaun Kelsey 0:da5f5b56060a 569
Shaun Kelsey 0:da5f5b56060a 570 SS_STATUS SSInterface::disable_sensor(int idx)
Shaun Kelsey 0:da5f5b56060a 571 {
Shaun Kelsey 0:da5f5b56060a 572 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");
Shaun Kelsey 0:da5f5b56060a 573 uint8_t cmd_bytes[] = { SS_FAM_W_SENSORMODE, (uint8_t)idx, 0 };
Shaun Kelsey 0:da5f5b56060a 574
Shaun Kelsey 0:da5f5b56060a 575 SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 0, 0, SS_ENABLE_SENSOR_SLEEP_MS);
Shaun Kelsey 0:da5f5b56060a 576
Shaun Kelsey 0:da5f5b56060a 577 if (status == SS_SUCCESS) {
Shaun Kelsey 0:da5f5b56060a 578 sensor_enabled_mode[idx] = 0;
Shaun Kelsey 0:da5f5b56060a 579 sensor_data_reqs[idx] = 0;
Shaun Kelsey 0:da5f5b56060a 580 }
Shaun Kelsey 0:da5f5b56060a 581
Shaun Kelsey 0:da5f5b56060a 582 return status;
Shaun Kelsey 0:da5f5b56060a 583 }
Shaun Kelsey 0:da5f5b56060a 584
Shaun Kelsey 0:da5f5b56060a 585 SS_STATUS SSInterface::enable_algo(int idx, int mode, ss_data_req *data_req)
Shaun Kelsey 0:da5f5b56060a 586 {
Shaun Kelsey 0:da5f5b56060a 587 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");
Shaun Kelsey 0:da5f5b56060a 588 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");
Shaun Kelsey 0:da5f5b56060a 589 assert_msg((mode != 0), "Tried to enable algo to mode 0, but mode 0 is disable");
Shaun Kelsey 0:da5f5b56060a 590
Shaun Kelsey 0:da5f5b56060a 591 uint8_t cmd_bytes[] = { SS_FAM_W_ALGOMODE, (uint8_t)idx, (uint8_t)mode };
Shaun Kelsey 0:da5f5b56060a 592
Shaun Kelsey 5:e458409e913f 593 SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 0, 0, 4*SS_ENABLE_SENSOR_SLEEP_MS);
Shaun Kelsey 0:da5f5b56060a 594
Shaun Kelsey 0:da5f5b56060a 595 if (status == SS_SUCCESS) {
Shaun Kelsey 0:da5f5b56060a 596 algo_enabled_mode[idx] = mode;
Shaun Kelsey 0:da5f5b56060a 597 algo_data_reqs[idx] = data_req;
Shaun Kelsey 0:da5f5b56060a 598 }
Shaun Kelsey 0:da5f5b56060a 599
Shaun Kelsey 0:da5f5b56060a 600 return status;
Shaun Kelsey 0:da5f5b56060a 601 }
Shaun Kelsey 0:da5f5b56060a 602
Shaun Kelsey 0:da5f5b56060a 603 SS_STATUS SSInterface::disable_algo(int idx)
Shaun Kelsey 0:da5f5b56060a 604 {
Shaun Kelsey 0:da5f5b56060a 605 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");
Shaun Kelsey 0:da5f5b56060a 606 uint8_t cmd_bytes[] = { SS_FAM_W_ALGOMODE, (uint8_t)idx, 0 };
Shaun Kelsey 0:da5f5b56060a 607
Shaun Kelsey 0:da5f5b56060a 608 SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 0, 0, SS_ENABLE_SENSOR_SLEEP_MS);
Shaun Kelsey 0:da5f5b56060a 609
Shaun Kelsey 0:da5f5b56060a 610 if (status == SS_SUCCESS) {
Shaun Kelsey 0:da5f5b56060a 611 algo_enabled_mode[idx] = 0;
Shaun Kelsey 0:da5f5b56060a 612 algo_data_reqs[idx] = 0;
Shaun Kelsey 0:da5f5b56060a 613 }
Shaun Kelsey 0:da5f5b56060a 614
Shaun Kelsey 0:da5f5b56060a 615 return status;
Shaun Kelsey 0:da5f5b56060a 616 }
Shaun Kelsey 0:da5f5b56060a 617
Shaun Kelsey 5:e458409e913f 618 SS_STATUS SSInterface::set_algo_cfg(int algo_idx, int cfg_idx, uint8_t *cfg, int cfg_sz)
Shaun Kelsey 5:e458409e913f 619 {
Shaun Kelsey 5:e458409e913f 620 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");
Shaun Kelsey 5:e458409e913f 621 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");
Shaun Kelsey 5:e458409e913f 622
Shaun Kelsey 5:e458409e913f 623 uint8_t cmd_bytes[] = { SS_FAM_W_ALGOCONFIG, (uint8_t)algo_idx, (uint8_t)cfg_idx };
Shaun Kelsey 5:e458409e913f 624 SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 5:e458409e913f 625 cfg, cfg_sz);
Shaun Kelsey 5:e458409e913f 626
Shaun Kelsey 5:e458409e913f 627 return status;
Shaun Kelsey 5:e458409e913f 628 }
Shaun Kelsey 5:e458409e913f 629
Shaun Kelsey 5:e458409e913f 630 SS_STATUS SSInterface::get_algo_cfg(int algo_idx, int cfg_idx, uint8_t *cfg, int cfg_sz)
Shaun Kelsey 5:e458409e913f 631 {
Shaun Kelsey 5:e458409e913f 632 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");
Shaun Kelsey 5:e458409e913f 633 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");
Shaun Kelsey 5:e458409e913f 634
Shaun Kelsey 5:e458409e913f 635 uint8_t cmd_bytes[] = { SS_FAM_R_ALGOCONFIG, (uint8_t)algo_idx, (uint8_t)cfg_idx };
Shaun Kelsey 5:e458409e913f 636 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 5:e458409e913f 637 0, 0,
Shaun Kelsey 5:e458409e913f 638 cfg, cfg_sz);
Shaun Kelsey 5:e458409e913f 639
Shaun Kelsey 5:e458409e913f 640 return status;
Shaun Kelsey 5:e458409e913f 641 }
Shaun Kelsey 5:e458409e913f 642
Shaun Kelsey 0:da5f5b56060a 643 SS_STATUS SSInterface::set_data_type(int data_type, bool sc_en)
Shaun Kelsey 0:da5f5b56060a 644 {
Shaun Kelsey 0:da5f5b56060a 645 assert_msg((data_type >= 0) && (data_type <= 3), "Invalid value for data_type");
Shaun Kelsey 0:da5f5b56060a 646 uint8_t cmd_bytes[] = { SS_FAM_W_COMMCHAN, SS_CMDIDX_OUTPUTMODE };
Shaun Kelsey 1:7a55c0c7d6d9 647 uint8_t data_bytes[] = { (uint8_t)((sc_en ? SS_MASK_OUTPUTMODE_SC_EN : 0) |
Shaun Kelsey 1:7a55c0c7d6d9 648 ((data_type << SS_SHIFT_OUTPUTMODE_DATATYPE) & SS_MASK_OUTPUTMODE_DATATYPE)) };
Shaun Kelsey 0:da5f5b56060a 649
Shaun Kelsey 0:da5f5b56060a 650 SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 651 &data_bytes[0], ARRAY_SIZE(data_bytes));
Shaun Kelsey 0:da5f5b56060a 652
Shaun Kelsey 0:da5f5b56060a 653 this->data_type = data_type;
Shaun Kelsey 0:da5f5b56060a 654 this->sc_en = sc_en;
Shaun Kelsey 0:da5f5b56060a 655
Shaun Kelsey 0:da5f5b56060a 656 return status;
Shaun Kelsey 0:da5f5b56060a 657 }
Shaun Kelsey 0:da5f5b56060a 658
Shaun Kelsey 0:da5f5b56060a 659
Shaun Kelsey 0:da5f5b56060a 660 SS_STATUS SSInterface::get_data_type(int *data_type, bool *sc_en)
Shaun Kelsey 0:da5f5b56060a 661 {
Shaun Kelsey 0:da5f5b56060a 662 uint8_t cmd_bytes[] = { SS_FAM_R_COMMCHAN, SS_CMDIDX_OUTPUTMODE };
Shaun Kelsey 0:da5f5b56060a 663 uint8_t rxbuf[2] = {0};
Shaun Kelsey 0:da5f5b56060a 664
Shaun Kelsey 0:da5f5b56060a 665 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 666 0, 0,
Shaun Kelsey 0:da5f5b56060a 667 &rxbuf[0], ARRAY_SIZE(rxbuf));
Shaun Kelsey 0:da5f5b56060a 668 if (status == SS_SUCCESS) {
Shaun Kelsey 0:da5f5b56060a 669 *data_type =
Shaun Kelsey 0:da5f5b56060a 670 (rxbuf[1] & SS_MASK_OUTPUTMODE_DATATYPE) >> SS_SHIFT_OUTPUTMODE_DATATYPE;
Shaun Kelsey 0:da5f5b56060a 671 *sc_en =
Shaun Kelsey 0:da5f5b56060a 672 (bool)((rxbuf[1] & SS_MASK_OUTPUTMODE_SC_EN) >> SS_SHIFT_OUTPUTMODE_SC_EN);
Shaun Kelsey 0:da5f5b56060a 673 }
Shaun Kelsey 0:da5f5b56060a 674
Shaun Kelsey 0:da5f5b56060a 675 return status;
Shaun Kelsey 0:da5f5b56060a 676 }
Shaun Kelsey 0:da5f5b56060a 677
Shaun Kelsey 5:e458409e913f 678 SS_STATUS SSInterface::set_fifo_thresh(int thresh)
Shaun Kelsey 5:e458409e913f 679 {
Shaun Kelsey 5:e458409e913f 680 assert_msg((thresh > 0 && thresh <= 255), "Invalid value for fifo a full threshold");
Shaun Kelsey 5:e458409e913f 681 uint8_t cmd_bytes[] = { SS_FAM_W_COMMCHAN, SS_CMDIDX_FIFOAFULL };
Shaun Kelsey 5:e458409e913f 682 uint8_t data_bytes[] = { (uint8_t)thresh };
Shaun Kelsey 5:e458409e913f 683
Shaun Kelsey 5:e458409e913f 684 SS_STATUS status = write_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 5:e458409e913f 685 &data_bytes[0], ARRAY_SIZE(data_bytes));
Shaun Kelsey 5:e458409e913f 686 return status;
Shaun Kelsey 5:e458409e913f 687 }
Shaun Kelsey 5:e458409e913f 688
Shaun Kelsey 5:e458409e913f 689 SS_STATUS SSInterface::get_fifo_thresh(int *thresh)
Shaun Kelsey 5:e458409e913f 690 {
Shaun Kelsey 5:e458409e913f 691 uint8_t cmd_bytes[] = { SS_FAM_R_COMMCHAN, SS_CMDIDX_FIFOAFULL };
Shaun Kelsey 5:e458409e913f 692 uint8_t rxbuf[2] = {0};
Shaun Kelsey 5:e458409e913f 693
Shaun Kelsey 5:e458409e913f 694 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 5:e458409e913f 695 0, 0,
Shaun Kelsey 5:e458409e913f 696 &rxbuf[0], ARRAY_SIZE(rxbuf));
Shaun Kelsey 5:e458409e913f 697
Shaun Kelsey 5:e458409e913f 698 if (status == SS_SUCCESS) {
Shaun Kelsey 5:e458409e913f 699 *thresh = rxbuf[1];
Shaun Kelsey 5:e458409e913f 700 }
Shaun Kelsey 5:e458409e913f 701
Shaun Kelsey 5:e458409e913f 702 return status;
Shaun Kelsey 5:e458409e913f 703 }
Shaun Kelsey 5:e458409e913f 704
Shaun Kelsey 5:e458409e913f 705 SS_STATUS SSInterface::ss_comm_check()
Shaun Kelsey 5:e458409e913f 706 {
Shaun Kelsey 5:e458409e913f 707 uint8_t cmd_bytes[] = { SS_FAM_R_IDENTITY, SS_CMDIDX_PLATTYPE };
Shaun Kelsey 5:e458409e913f 708 uint8_t rxbuf[2];
Shaun Kelsey 5:e458409e913f 709
Shaun Kelsey 5:e458409e913f 710 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 5:e458409e913f 711 0, 0,
Shaun Kelsey 5:e458409e913f 712 &rxbuf[0], ARRAY_SIZE(rxbuf));
Shaun Kelsey 5:e458409e913f 713
Shaun Kelsey 5:e458409e913f 714 int tries = 4;
Shaun Kelsey 5:e458409e913f 715 while (status == SS_ERR_TRY_AGAIN && tries--) {
Shaun Kelsey 5:e458409e913f 716 wait_ms(1000);
Shaun Kelsey 5:e458409e913f 717 status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 5:e458409e913f 718 0, 0,
Shaun Kelsey 5:e458409e913f 719 &rxbuf[0], ARRAY_SIZE(rxbuf));
Shaun Kelsey 5:e458409e913f 720 }
Shaun Kelsey 5:e458409e913f 721
Shaun Kelsey 5:e458409e913f 722 return status;
Shaun Kelsey 5:e458409e913f 723 }
Shaun Kelsey 5:e458409e913f 724
Shaun Kelsey 0:da5f5b56060a 725 void SSInterface::fifo_sample_size(int data_type, int *sample_size)
Shaun Kelsey 0:da5f5b56060a 726 {
Shaun Kelsey 0:da5f5b56060a 727 *sample_size = 0;
Shaun Kelsey 0:da5f5b56060a 728
Shaun Kelsey 0:da5f5b56060a 729 if (data_type == SS_DATATYPE_RAW || data_type == SS_DATATYPE_BOTH) {
Shaun Kelsey 0:da5f5b56060a 730 for (int i = 0; i < SS_MAX_SUPPORTED_SENSOR_NUM; i++) {
Shaun Kelsey 0:da5f5b56060a 731 if (sensor_enabled_mode[i]) {
Shaun Kelsey 0:da5f5b56060a 732 assert_msg(sensor_data_reqs[i], "no ss_data_req found for enabled sensor");
Shaun Kelsey 0:da5f5b56060a 733 *sample_size += sensor_data_reqs[i]->data_size;
Shaun Kelsey 0:da5f5b56060a 734 }
Shaun Kelsey 0:da5f5b56060a 735 }
Shaun Kelsey 0:da5f5b56060a 736 }
Shaun Kelsey 0:da5f5b56060a 737
Shaun Kelsey 0:da5f5b56060a 738 if (data_type == SS_DATATYPE_ALGO || data_type == SS_DATATYPE_BOTH) {
Shaun Kelsey 0:da5f5b56060a 739 for (int i = 0; i < SS_MAX_SUPPORTED_ALGO_NUM; i++) {
Shaun Kelsey 0:da5f5b56060a 740 if (algo_enabled_mode[i]) {
Shaun Kelsey 0:da5f5b56060a 741 assert_msg(algo_data_reqs[i], "no ss_data_req found for enabled algo");
Shaun Kelsey 0:da5f5b56060a 742 *sample_size += algo_data_reqs[i]->data_size;
Shaun Kelsey 0:da5f5b56060a 743 }
Shaun Kelsey 0:da5f5b56060a 744 }
Shaun Kelsey 0:da5f5b56060a 745 }
Shaun Kelsey 0:da5f5b56060a 746 }
Shaun Kelsey 0:da5f5b56060a 747
Shaun Kelsey 0:da5f5b56060a 748 SS_STATUS SSInterface::num_avail_samples(int *num_samples)
Shaun Kelsey 0:da5f5b56060a 749 {
Shaun Kelsey 0:da5f5b56060a 750 uint8_t cmd_bytes[] = { SS_FAM_R_OUTPUTFIFO, SS_CMDIDX_OUT_NUMSAMPLES };
Shaun Kelsey 0:da5f5b56060a 751 uint8_t rxbuf[2] = {0};
Shaun Kelsey 0:da5f5b56060a 752
Shaun Kelsey 0:da5f5b56060a 753 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 754 0, 0,
Shaun Kelsey 5:e458409e913f 755 &rxbuf[0], ARRAY_SIZE(rxbuf), 1);
Shaun Kelsey 0:da5f5b56060a 756
Shaun Kelsey 0:da5f5b56060a 757 if (status == SS_SUCCESS) {
Shaun Kelsey 0:da5f5b56060a 758 *num_samples = rxbuf[1];
Shaun Kelsey 0:da5f5b56060a 759 }
Shaun Kelsey 0:da5f5b56060a 760
Shaun Kelsey 0:da5f5b56060a 761 return status;
Shaun Kelsey 0:da5f5b56060a 762 }
Shaun Kelsey 0:da5f5b56060a 763
Shaun Kelsey 0:da5f5b56060a 764 SS_STATUS SSInterface::read_fifo_data(
Shaun Kelsey 0:da5f5b56060a 765 int num_samples, int sample_size,
Shaun Kelsey 0:da5f5b56060a 766 uint8_t* databuf, int databuf_sz)
Shaun Kelsey 0:da5f5b56060a 767 {
Shaun Kelsey 0:da5f5b56060a 768 int bytes_to_read = num_samples * sample_size + 1; //+1 for status byte
Shaun Kelsey 0:da5f5b56060a 769 assert_msg((bytes_to_read <= databuf_sz), "databuf too small");
Shaun Kelsey 0:da5f5b56060a 770
Shaun Kelsey 0:da5f5b56060a 771 uint8_t cmd_bytes[] = { SS_FAM_R_OUTPUTFIFO, SS_CMDIDX_READFIFO };
Shaun Kelsey 0:da5f5b56060a 772
Shaun Kelsey 5:e458409e913f 773 pr_info("[reading %d bytes (%d samples)\r\n", bytes_to_read, num_samples);
Shaun Kelsey 0:da5f5b56060a 774
Shaun Kelsey 0:da5f5b56060a 775 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 776 0, 0,
Shaun Kelsey 5:e458409e913f 777 databuf, bytes_to_read, 5);
Shaun Kelsey 0:da5f5b56060a 778
Shaun Kelsey 0:da5f5b56060a 779 return status;
Shaun Kelsey 0:da5f5b56060a 780 }
Shaun Kelsey 0:da5f5b56060a 781
Shaun Kelsey 5:e458409e913f 782 static uint8_t databuf[512];
Shaun Kelsey 5:e458409e913f 783 void SSInterface::ss_execute_once(){
Shaun Kelsey 5:e458409e913f 784
Shaun Kelsey 5:e458409e913f 785 if(m_irq_received_ == false)
Shaun Kelsey 5:e458409e913f 786 return;
Shaun Kelsey 5:e458409e913f 787
Shaun Kelsey 0:da5f5b56060a 788 uint8_t sample_count;
Shaun Kelsey 5:e458409e913f 789 m_irq_received_ = false;
Shaun Kelsey 0:da5f5b56060a 790 uint8_t cmd_bytes[] = { SS_FAM_R_STATUS, SS_CMDIDX_STATUS };
Shaun Kelsey 0:da5f5b56060a 791 uint8_t rxbuf[2] = {0};
Shaun Kelsey 0:da5f5b56060a 792
Ismail Kose 10:022b2cad9e9b 793 irq_evt.start();
Shaun Kelsey 5:e458409e913f 794
Ismail Kose 10:022b2cad9e9b 795 irq_pin.disable_irq();
Shaun Kelsey 0:da5f5b56060a 796
Shaun Kelsey 0:da5f5b56060a 797 SS_STATUS status = read_cmd(&cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 798 0, 0,
Shaun Kelsey 0:da5f5b56060a 799 &rxbuf[0], ARRAY_SIZE(rxbuf));
Shaun Kelsey 0:da5f5b56060a 800
Shaun Kelsey 0:da5f5b56060a 801 if (status != SS_SUCCESS) {
Shaun Kelsey 0:da5f5b56060a 802 pr_err("Couldn't read status byte of SmartSensor!");
Ismail Kose 10:022b2cad9e9b 803 irq_pin.enable_irq();
Ismail Kose 10:022b2cad9e9b 804 irq_evt.stop();
Shaun Kelsey 0:da5f5b56060a 805 return;
Shaun Kelsey 0:da5f5b56060a 806 }
Shaun Kelsey 0:da5f5b56060a 807
Shaun Kelsey 0:da5f5b56060a 808 if (rxbuf[1] & SS_MASK_STATUS_ERR) {
Shaun Kelsey 0:da5f5b56060a 809 pr_err("SmartSensor status error: %d", rxbuf[1] & SS_MASK_STATUS_ERR);
Shaun Kelsey 0:da5f5b56060a 810 }
Shaun Kelsey 0:da5f5b56060a 811 if (rxbuf[1] & SS_MASK_STATUS_FIFO_OUT_OVR) {
Shaun Kelsey 0:da5f5b56060a 812 pr_err("SmartSensor Output FIFO overflow!");
Shaun Kelsey 0:da5f5b56060a 813 }
Shaun Kelsey 0:da5f5b56060a 814 if (rxbuf[1] & SS_MASK_STATUS_FIFO_IN_OVR) {
Shaun Kelsey 0:da5f5b56060a 815 pr_err("SmartSensor Input FIFO overflow!");
Shaun Kelsey 0:da5f5b56060a 816 }
Shaun Kelsey 0:da5f5b56060a 817
Shaun Kelsey 0:da5f5b56060a 818 if (rxbuf[1] & SS_MASK_STATUS_DATA_RDY) {
Shaun Kelsey 5:e458409e913f 819 int num_samples = 1;
Shaun Kelsey 0:da5f5b56060a 820 status = num_avail_samples(&num_samples);
Shaun Kelsey 0:da5f5b56060a 821 if (status != SS_SUCCESS)
Shaun Kelsey 0:da5f5b56060a 822 {
Shaun Kelsey 0:da5f5b56060a 823 pr_err("Couldn't read number of available samples in SmartSensor Output FIFO");
Ismail Kose 10:022b2cad9e9b 824 irq_pin.enable_irq();
Ismail Kose 10:022b2cad9e9b 825 irq_evt.stop();
Shaun Kelsey 0:da5f5b56060a 826 return;
Shaun Kelsey 0:da5f5b56060a 827 }
Shaun Kelsey 0:da5f5b56060a 828
Shaun Kelsey 0:da5f5b56060a 829 int sample_size;
Shaun Kelsey 0:da5f5b56060a 830 fifo_sample_size(data_type, &sample_size);
Shaun Kelsey 0:da5f5b56060a 831
Shaun Kelsey 5:e458409e913f 832 int bytes_to_read = num_samples * sample_size + 1; //+1 for status byte
Shaun Kelsey 5:e458409e913f 833 if ((uint32_t)bytes_to_read > sizeof(databuf)) {
Shaun Kelsey 0:da5f5b56060a 834 //Reduce number of samples to read to fit in buffer
Shaun Kelsey 0:da5f5b56060a 835 num_samples = (sizeof(databuf) - 1) / sample_size;
Shaun Kelsey 0:da5f5b56060a 836 }
Shaun Kelsey 0:da5f5b56060a 837
Shaun Kelsey 5:e458409e913f 838 wait_ms(5);
Shaun Kelsey 0:da5f5b56060a 839 status = read_fifo_data(num_samples, sample_size, &databuf[0], sizeof(databuf));
Shaun Kelsey 0:da5f5b56060a 840 if (status != SS_SUCCESS)
Shaun Kelsey 0:da5f5b56060a 841 {
Shaun Kelsey 0:da5f5b56060a 842 pr_err("Couldn't read from SmartSensor Output FIFO");
Ismail Kose 10:022b2cad9e9b 843 irq_pin.enable_irq();
Ismail Kose 10:022b2cad9e9b 844 irq_evt.stop();
Shaun Kelsey 0:da5f5b56060a 845 return;
Shaun Kelsey 0:da5f5b56060a 846 }
Shaun Kelsey 0:da5f5b56060a 847
Ismail Kose 10:022b2cad9e9b 848 pr_info("read %d samples\r\n", num_samples);
Ismail Kose 10:022b2cad9e9b 849
Shaun Kelsey 0:da5f5b56060a 850 //Skip status byte
Shaun Kelsey 0:da5f5b56060a 851 uint8_t *data_ptr = &databuf[1];
Shaun Kelsey 0:da5f5b56060a 852
Shaun Kelsey 0:da5f5b56060a 853 int i = 0;
Shaun Kelsey 0:da5f5b56060a 854 for (i = 0; i < num_samples; i++) {
Shaun Kelsey 0:da5f5b56060a 855 if (sc_en) {
Shaun Kelsey 0:da5f5b56060a 856 sample_count = *data_ptr++;
Shaun Kelsey 0:da5f5b56060a 857 pr_info("Received sample #%d", sample_count);
Shaun Kelsey 0:da5f5b56060a 858 }
Shaun Kelsey 0:da5f5b56060a 859
Shaun Kelsey 0:da5f5b56060a 860 //Chop up data and send to modules with enabled sensors
Shaun Kelsey 0:da5f5b56060a 861 if (data_type == SS_DATATYPE_RAW || data_type == SS_DATATYPE_BOTH) {
Shaun Kelsey 0:da5f5b56060a 862 for (int i = 0; i < SS_MAX_SUPPORTED_SENSOR_NUM; i++) {
Shaun Kelsey 0:da5f5b56060a 863 if (sensor_enabled_mode[i]) {
Shaun Kelsey 0:da5f5b56060a 864 assert_msg(sensor_data_reqs[i],
Shaun Kelsey 0:da5f5b56060a 865 "no ss_data_req found for enabled sensor");
Shaun Kelsey 0:da5f5b56060a 866 sensor_data_reqs[i]->callback(data_ptr);
Shaun Kelsey 0:da5f5b56060a 867 data_ptr += sensor_data_reqs[i]->data_size;
Shaun Kelsey 0:da5f5b56060a 868 }
Shaun Kelsey 0:da5f5b56060a 869 }
Shaun Kelsey 0:da5f5b56060a 870 }
Shaun Kelsey 0:da5f5b56060a 871 if (data_type == SS_DATATYPE_ALGO || data_type == SS_DATATYPE_BOTH) {
Shaun Kelsey 0:da5f5b56060a 872 for (int i = 0; i < SS_MAX_SUPPORTED_ALGO_NUM; i++) {
Shaun Kelsey 0:da5f5b56060a 873 if (algo_enabled_mode[i]) {
Shaun Kelsey 0:da5f5b56060a 874 assert_msg(algo_data_reqs[i],
Shaun Kelsey 0:da5f5b56060a 875 "no ss_data_req found for enabled algo");
Shaun Kelsey 0:da5f5b56060a 876 algo_data_reqs[i]->callback(data_ptr);
Shaun Kelsey 0:da5f5b56060a 877 data_ptr += algo_data_reqs[i]->data_size;
Shaun Kelsey 0:da5f5b56060a 878 }
Shaun Kelsey 0:da5f5b56060a 879 }
Shaun Kelsey 0:da5f5b56060a 880 }
Shaun Kelsey 0:da5f5b56060a 881 }
Shaun Kelsey 0:da5f5b56060a 882 }
Ismail Kose 10:022b2cad9e9b 883 irq_pin.enable_irq();
Ismail Kose 10:022b2cad9e9b 884 irq_evt.stop();
Shaun Kelsey 5:e458409e913f 885 }
Shaun Kelsey 5:e458409e913f 886
Shaun Kelsey 5:e458409e913f 887 void SSInterface::ss_clear_interrupt_flag(){
Shaun Kelsey 5:e458409e913f 888 m_irq_received_ = false;
Shaun Kelsey 5:e458409e913f 889 }
Shaun Kelsey 5:e458409e913f 890
Shaun Kelsey 5:e458409e913f 891 void SSInterface::irq_handler()
Shaun Kelsey 5:e458409e913f 892 {
Shaun Kelsey 5:e458409e913f 893 m_irq_received_ = true;
Shaun Kelsey 0:da5f5b56060a 894 }
Shaun Kelsey 0:da5f5b56060a 895
Shaun Kelsey 0:da5f5b56060a 896 void SSInterface::irq_handler_selftest(){
Shaun Kelsey 0:da5f5b56060a 897 mfio_int_happened = true;
Shaun Kelsey 0:da5f5b56060a 898 }
Shaun Kelsey 0:da5f5b56060a 899
Shaun Kelsey 0:da5f5b56060a 900 bool SSInterface::reset_mfio_irq(){
Shaun Kelsey 0:da5f5b56060a 901 bool ret = mfio_int_happened;
Shaun Kelsey 0:da5f5b56060a 902 mfio_int_happened = false;
Ismail Kose 10:022b2cad9e9b 903 irq_pin.disable_irq();
Shaun Kelsey 0:da5f5b56060a 904 irq_pin.fall(callback(this, &SSInterface::irq_handler));
Ismail Kose 10:022b2cad9e9b 905 irq_pin.enable_irq();
Shaun Kelsey 0:da5f5b56060a 906 return ret;
Shaun Kelsey 0:da5f5b56060a 907 }