Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: USBDevice max32630fthr
Interfaces/SmartSensor/SSInterface.cpp@5:795cffb6f01a, 2018-05-24 (annotated)
- 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?
| User | Revision | Line number | New 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 | } |
Heart Rate SpO2 Algorithm EvKit Health Monitor Development System Board MAXREFDES220