Host software for the MAXREFDES220 Heart Rate Monitor Smart Sensor. Hosted on the MAX32630FTHR.

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:
keremsahin
Date:
Mon Jul 02 21:07:27 2018 +0000
Revision:
8:0f55f59ca341
Parent:
7:3e2a5545f1d8
Child:
10:022b2cad9e9b
MAX30001/MAX30205/MAX8614X driver updates; EcgComm/TempComm/MAX30101Comm updates; Bootloader updates; EventStats/LEDStatus updates

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