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 May 28 17:31:55 2018 -0700
Revision:
7:3e2a5545f1d8
Parent:
5:e458409e913f
Child:
8:0f55f59ca341
support timeout mode in bootloader

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