Maxim Integrated / Mbed OS MAXREFDES220#

Dependencies:   USBDevice max32630fthr

Committer:
Shaun Kelsey
Date:
Thu May 24 14:40:48 2018 -0700
Revision:
5:795cffb6f01a
Parent:
1:7a55c0c7d6d9
Bootloader feature additions

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