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

Dependencies:   max32630fthr USBDevice

Fork of MAXREFDES220_HEART_RATE_MONITOR by Maxim Integrated

Finger Heart Rate Monitor and SpO2 Monitor

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

Ordering information will be available soon.

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

Warning

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

MAXREFDES220 FeatherWing Pinout Connections

/media/uploads/phonemacro/maxrefdes220_pinouts_heart_rate_monitor.jpg

Committer:
keremsahin
Date:
Mon Jul 02 21:07:27 2018 +0000
Revision:
8:0f55f59ca341
Parent:
7:3e2a5545f1d8
MAX30001/MAX30205/MAX8614X driver updates; EcgComm/TempComm/MAX30101Comm updates; Bootloader updates; EventStats/LEDStatus updates

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Shaun Kelsey 0:da5f5b56060a 1 /*******************************************************************************
Shaun Kelsey 0:da5f5b56060a 2 * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
Shaun Kelsey 0:da5f5b56060a 3 *
Shaun Kelsey 0:da5f5b56060a 4 * Permission is hereby granted, free of charge, to any person obtaining a
Shaun Kelsey 0:da5f5b56060a 5 * copy of this software and associated documentation files (the "Software"),
Shaun Kelsey 0:da5f5b56060a 6 * to deal in the Software without restriction, including without limitation
Shaun Kelsey 0:da5f5b56060a 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
Shaun Kelsey 0:da5f5b56060a 8 * and/or sell copies of the Software, and to permit persons to whom the
Shaun Kelsey 0:da5f5b56060a 9 * Software is furnished to do so, subject to the following conditions:
Shaun Kelsey 0:da5f5b56060a 10 *
Shaun Kelsey 0:da5f5b56060a 11 * The above copyright notice and this permission notice shall be included
Shaun Kelsey 0:da5f5b56060a 12 * in all copies or substantial portions of the Software.
Shaun Kelsey 0:da5f5b56060a 13 *
Shaun Kelsey 0:da5f5b56060a 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
Shaun Kelsey 0:da5f5b56060a 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Shaun Kelsey 0:da5f5b56060a 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Shaun Kelsey 0:da5f5b56060a 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
Shaun Kelsey 0:da5f5b56060a 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
Shaun Kelsey 0:da5f5b56060a 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
Shaun Kelsey 0:da5f5b56060a 20 * OTHER DEALINGS IN THE SOFTWARE.
Shaun Kelsey 0:da5f5b56060a 21 *
Shaun Kelsey 0:da5f5b56060a 22 * Except as contained in this notice, the name of Maxim Integrated
Shaun Kelsey 0:da5f5b56060a 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
Shaun Kelsey 0:da5f5b56060a 24 * Products, Inc. Branding Policy.
Shaun Kelsey 0:da5f5b56060a 25 *
Shaun Kelsey 0:da5f5b56060a 26 * The mere transfer of this software does not imply any licenses
Shaun Kelsey 0:da5f5b56060a 27 * of trade secrets, proprietary technology, copyrights, patents,
Shaun Kelsey 0:da5f5b56060a 28 * trademarks, maskwork rights, or any other form of intellectual
Shaun Kelsey 0:da5f5b56060a 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
Shaun Kelsey 0:da5f5b56060a 30 * ownership rights.
Shaun Kelsey 0:da5f5b56060a 31 *******************************************************************************
Shaun Kelsey 0:da5f5b56060a 32 */
Shaun Kelsey 0:da5f5b56060a 33
Shaun Kelsey 0:da5f5b56060a 34 #include "DSInterface.h"
Shaun Kelsey 0:da5f5b56060a 35 #include "SSBootloaderComm.h"
Shaun Kelsey 0:da5f5b56060a 36 #include "SSInterface.h"
Shaun Kelsey 0:da5f5b56060a 37 #include "Peripherals.h"
Shaun Kelsey 0:da5f5b56060a 38 #include "assert.h"
Shaun Kelsey 0:da5f5b56060a 39 #include "utils.h"
Shaun Kelsey 0:da5f5b56060a 40
Shaun Kelsey 0:da5f5b56060a 41 static const char* const cmd_tbl[] = {
Shaun Kelsey 0:da5f5b56060a 42 "bootldr",
Shaun Kelsey 0:da5f5b56060a 43 "exit",
Shaun Kelsey 0:da5f5b56060a 44 "reset",
Shaun Kelsey 0:da5f5b56060a 45 "page_size",
Shaun Kelsey 0:da5f5b56060a 46 "num_pages",
Shaun Kelsey 0:da5f5b56060a 47 "set_iv",
Shaun Kelsey 0:da5f5b56060a 48 "set_auth",
Shaun Kelsey 0:da5f5b56060a 49 "erase",
Shaun Kelsey 5:e458409e913f 50 "page_erase",
Shaun Kelsey 0:da5f5b56060a 51 "flash",
Shaun Kelsey 5:e458409e913f 52 "set_cfg bl enter_mode",
Shaun Kelsey 5:e458409e913f 53 "set_cfg bl enter_pin",
Shaun Kelsey 5:e458409e913f 54 "set_cfg bl enter_pol",
Shaun Kelsey 5:e458409e913f 55 "set_cfg bl exit_mode",
Shaun Kelsey 5:e458409e913f 56 "set_cfg bl exit_to",
Shaun Kelsey 5:e458409e913f 57 "set_cfg bl save",
Shaun Kelsey 0:da5f5b56060a 58 };
Shaun Kelsey 0:da5f5b56060a 59
Shaun Kelsey 0:da5f5b56060a 60 SSBootloaderComm::SSBootloaderComm(USBSerial *USB, SSInterface* ssInterface, DSInterface* dsInterface)
Shaun Kelsey 5:e458409e913f 61 :SensorComm("bl", false), m_USB(USB), ss_int(ssInterface), ds_int(dsInterface)
Shaun Kelsey 0:da5f5b56060a 62 {
Shaun Kelsey 0:da5f5b56060a 63 }
Shaun Kelsey 0:da5f5b56060a 64
Shaun Kelsey 0:da5f5b56060a 65 int SSBootloaderComm::parse_auth(const char* cmd, uint8_t *auth_bytes)
Shaun Kelsey 0:da5f5b56060a 66 {
Shaun Kelsey 0:da5f5b56060a 67 char cmdStr[] = "set_auth ";
Shaun Kelsey 0:da5f5b56060a 68 int length = strlen(cmd);
Shaun Kelsey 0:da5f5b56060a 69 int expected_length = strlen(cmdStr) + 2*AES_AUTH_SIZE;
Shaun Kelsey 0:da5f5b56060a 70 if (length != expected_length) {
Shaun Kelsey 0:da5f5b56060a 71 pr_err("Couldn't parse Auth bytes, incorrect number of characters (len:%d, expected:%d)\n",
Shaun Kelsey 0:da5f5b56060a 72 length, expected_length);
Shaun Kelsey 0:da5f5b56060a 73 return COMM_INVALID_PARAM;
Shaun Kelsey 0:da5f5b56060a 74 }
Shaun Kelsey 0:da5f5b56060a 75
Shaun Kelsey 0:da5f5b56060a 76 const char* macPtr = cmd + strlen(cmdStr);
Shaun Kelsey 0:da5f5b56060a 77
Shaun Kelsey 0:da5f5b56060a 78 int num_found;
Shaun Kelsey 0:da5f5b56060a 79 int byteVal;
Shaun Kelsey 0:da5f5b56060a 80 for (int aidx = 0; aidx < AES_AUTH_SIZE; aidx++) {
Shaun Kelsey 0:da5f5b56060a 81 num_found = sscanf(macPtr, "%2X", &byteVal);
Shaun Kelsey 0:da5f5b56060a 82
Shaun Kelsey 0:da5f5b56060a 83 if (num_found != 1 || byteVal > 0xFF) {
Shaun Kelsey 0:da5f5b56060a 84 pr_err("Couldn't parse byte %d of Auth\n", aidx);
Shaun Kelsey 0:da5f5b56060a 85 return COMM_INVALID_PARAM;
Shaun Kelsey 0:da5f5b56060a 86 }
Shaun Kelsey 0:da5f5b56060a 87
Shaun Kelsey 0:da5f5b56060a 88 auth_bytes[aidx] = (uint8_t)byteVal;
Shaun Kelsey 0:da5f5b56060a 89 macPtr += 2;
Shaun Kelsey 0:da5f5b56060a 90 }
Shaun Kelsey 0:da5f5b56060a 91
Shaun Kelsey 0:da5f5b56060a 92 return COMM_SUCCESS;
Shaun Kelsey 0:da5f5b56060a 93 }
Shaun Kelsey 0:da5f5b56060a 94
Shaun Kelsey 0:da5f5b56060a 95 int SSBootloaderComm::parse_iv(const char* cmd, uint8_t* iv_bytes)
Shaun Kelsey 0:da5f5b56060a 96 {
Shaun Kelsey 0:da5f5b56060a 97 char cmdStr[] = "set_iv ";
Shaun Kelsey 0:da5f5b56060a 98 int length = strlen(cmd);
Shaun Kelsey 0:da5f5b56060a 99 int expected_length = strlen(cmdStr) + 2*AES_NONCE_SIZE;
Shaun Kelsey 0:da5f5b56060a 100 if (length != expected_length) {
Shaun Kelsey 0:da5f5b56060a 101 pr_err("Couldn't parse IV, incorrect number of characters (len:%d, expected:%d)\n",
Shaun Kelsey 0:da5f5b56060a 102 length, expected_length);
Shaun Kelsey 0:da5f5b56060a 103 return COMM_INVALID_PARAM;
Shaun Kelsey 0:da5f5b56060a 104 }
Shaun Kelsey 0:da5f5b56060a 105
Shaun Kelsey 0:da5f5b56060a 106 const char* ivPtr = cmd + strlen(cmdStr);
Shaun Kelsey 0:da5f5b56060a 107
Shaun Kelsey 0:da5f5b56060a 108 int num_found;
Shaun Kelsey 0:da5f5b56060a 109 int byteVal;
Shaun Kelsey 0:da5f5b56060a 110 for (int ividx = 0; ividx < AES_NONCE_SIZE; ividx++) {
Shaun Kelsey 0:da5f5b56060a 111 num_found = sscanf(ivPtr, "%2X", &byteVal);
Shaun Kelsey 0:da5f5b56060a 112
Shaun Kelsey 0:da5f5b56060a 113 if (num_found != 1 || byteVal > 0xFF) {
Shaun Kelsey 0:da5f5b56060a 114 pr_err("Couldn't parse byte %d of IV\n", ividx);
Shaun Kelsey 0:da5f5b56060a 115 return COMM_INVALID_PARAM;
Shaun Kelsey 0:da5f5b56060a 116 }
Shaun Kelsey 0:da5f5b56060a 117 iv_bytes[ividx] = (uint8_t)byteVal;
Shaun Kelsey 0:da5f5b56060a 118 ivPtr += 2;
Shaun Kelsey 0:da5f5b56060a 119 }
Shaun Kelsey 0:da5f5b56060a 120
Shaun Kelsey 0:da5f5b56060a 121 return COMM_SUCCESS;
Shaun Kelsey 0:da5f5b56060a 122 }
Shaun Kelsey 0:da5f5b56060a 123
Shaun Kelsey 0:da5f5b56060a 124 bool SSBootloaderComm::parse_command(const char* cmd)
Shaun Kelsey 0:da5f5b56060a 125 {
Shaun Kelsey 0:da5f5b56060a 126 int ret = EXIT_SUCCESS;
Shaun Kelsey 0:da5f5b56060a 127 bool recognizedCmd = false;
Shaun Kelsey 0:da5f5b56060a 128
Shaun Kelsey 0:da5f5b56060a 129 if (!ss_int) {
Shaun Kelsey 0:da5f5b56060a 130 pr_err("No SmartSensor Interface defined!");
Shaun Kelsey 0:da5f5b56060a 131 return false;
Shaun Kelsey 0:da5f5b56060a 132 }
Shaun Kelsey 0:da5f5b56060a 133 if (!ds_int) {
Shaun Kelsey 0:da5f5b56060a 134 pr_err("No DeviceStudio Interface defined!");
Shaun Kelsey 0:da5f5b56060a 135 return false;
Shaun Kelsey 0:da5f5b56060a 136 }
Shaun Kelsey 0:da5f5b56060a 137
Shaun Kelsey 0:da5f5b56060a 138 for (int i = 0; i < NUM_CMDS; i++) {
Shaun Kelsey 5:e458409e913f 139 if (starts_with(cmd, cmd_tbl[i])) {
Shaun Kelsey 0:da5f5b56060a 140 cmd_state_t user_cmd = (cmd_state_t)i;
Shaun Kelsey 0:da5f5b56060a 141 recognizedCmd = true;
Shaun Kelsey 0:da5f5b56060a 142
Shaun Kelsey 0:da5f5b56060a 143 switch (user_cmd) {
Shaun Kelsey 0:da5f5b56060a 144 case cmd_enter_bootldr:
Shaun Kelsey 0:da5f5b56060a 145 {
Shaun Kelsey 0:da5f5b56060a 146 SS_STATUS status;
Shaun Kelsey 0:da5f5b56060a 147 status = ss_int->reset_to_bootloader();
Shaun Kelsey 0:da5f5b56060a 148 if (status == SS_SUCCESS)
Shaun Kelsey 5:e458409e913f 149 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS);
Shaun Kelsey 0:da5f5b56060a 150 else
Shaun Kelsey 5:e458409e913f 151 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR);
Shaun Kelsey 5:e458409e913f 152
Shaun Kelsey 0:da5f5b56060a 153 ds_int->set_fw_platform(ss_int->get_ss_platform_name());
Shaun Kelsey 0:da5f5b56060a 154 ds_int->set_fw_version(ss_int->get_ss_fw_version());
Shaun Kelsey 0:da5f5b56060a 155 got_page_size = false;
Shaun Kelsey 0:da5f5b56060a 156 sent_num_pages = false;
Shaun Kelsey 0:da5f5b56060a 157 } break;
Shaun Kelsey 0:da5f5b56060a 158
Shaun Kelsey 0:da5f5b56060a 159 case cmd_exit_bootldr:
Shaun Kelsey 0:da5f5b56060a 160 {
Shaun Kelsey 0:da5f5b56060a 161 SS_STATUS status = ss_int->reset_to_main_app();
Shaun Kelsey 0:da5f5b56060a 162 if (status == SS_SUCCESS)
Shaun Kelsey 5:e458409e913f 163 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS);
Shaun Kelsey 0:da5f5b56060a 164 else
Shaun Kelsey 5:e458409e913f 165 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR);
Shaun Kelsey 0:da5f5b56060a 166
Shaun Kelsey 0:da5f5b56060a 167 ds_int->set_fw_platform(ss_int->get_ss_platform_name());
Shaun Kelsey 0:da5f5b56060a 168 ds_int->set_fw_version(ss_int->get_ss_fw_version());
Shaun Kelsey 0:da5f5b56060a 169
Shaun Kelsey 0:da5f5b56060a 170 } break;
Shaun Kelsey 0:da5f5b56060a 171
Shaun Kelsey 0:da5f5b56060a 172 case cmd_reset:
Shaun Kelsey 0:da5f5b56060a 173 {
Shaun Kelsey 0:da5f5b56060a 174 SS_STATUS status = ss_int->reset();
Shaun Kelsey 0:da5f5b56060a 175 if (status == SS_SUCCESS)
Shaun Kelsey 5:e458409e913f 176 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS);
Shaun Kelsey 0:da5f5b56060a 177 else
Shaun Kelsey 5:e458409e913f 178 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR);
Shaun Kelsey 5:e458409e913f 179 m_USB->printf("\r\n%s err=%d\r\n", cmd, ret);
Shaun Kelsey 0:da5f5b56060a 180
Shaun Kelsey 0:da5f5b56060a 181 ds_int->set_fw_platform(ss_int->get_ss_platform_name());
Shaun Kelsey 0:da5f5b56060a 182 ds_int->set_fw_version(ss_int->get_ss_fw_version());
Shaun Kelsey 0:da5f5b56060a 183
Shaun Kelsey 0:da5f5b56060a 184 } break;
Shaun Kelsey 0:da5f5b56060a 185
Shaun Kelsey 0:da5f5b56060a 186 case cmd_page_size:
Shaun Kelsey 0:da5f5b56060a 187 {
Shaun Kelsey 0:da5f5b56060a 188 uint8_t cmd_bytes[] = { SS_FAM_R_BOOTLOADER, SS_CMDIDX_PAGESIZE };
Shaun Kelsey 0:da5f5b56060a 189 uint8_t rxbuf[3];
Shaun Kelsey 0:da5f5b56060a 190
Shaun Kelsey 0:da5f5b56060a 191 SS_STATUS status = ss_int->read_cmd(
Shaun Kelsey 0:da5f5b56060a 192 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 193 0, 0,
Shaun Kelsey 0:da5f5b56060a 194 &rxbuf[0], ARRAY_SIZE(rxbuf));
Shaun Kelsey 0:da5f5b56060a 195
Shaun Kelsey 0:da5f5b56060a 196 if (status == SS_SUCCESS) {
Shaun Kelsey 0:da5f5b56060a 197 //rxbuf holds page size in big-endian format
Shaun Kelsey 0:da5f5b56060a 198 page_size = (256*(int)rxbuf[1]) + rxbuf[2];
Shaun Kelsey 0:da5f5b56060a 199 assert_msg(page_size <= MAX_PAGE_SIZE, "Page size exceeds maximum allowed");
Shaun Kelsey 0:da5f5b56060a 200
Shaun Kelsey 5:e458409e913f 201 m_USB->printf("\r\n%s value=%d err=%d\r\n", cmd, page_size, COMM_SUCCESS);
Shaun Kelsey 0:da5f5b56060a 202 got_page_size = true;
Shaun Kelsey 0:da5f5b56060a 203
Shaun Kelsey 0:da5f5b56060a 204 } else {
Shaun Kelsey 5:e458409e913f 205 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR);
Shaun Kelsey 0:da5f5b56060a 206 }
Shaun Kelsey 0:da5f5b56060a 207 } break;
Shaun Kelsey 0:da5f5b56060a 208
Shaun Kelsey 0:da5f5b56060a 209 case cmd_num_pages:
Shaun Kelsey 0:da5f5b56060a 210 {
Shaun Kelsey 5:e458409e913f 211 int num_tok = sscanf(cmd, "num_pages %d", &num_pages);
Shaun Kelsey 0:da5f5b56060a 212 if (num_tok != 1) {
Shaun Kelsey 5:e458409e913f 213 m_USB->printf("\r\n%s value=%d err=%d\r\n", cmd, 0, COMM_INVALID_PARAM);
Shaun Kelsey 5:e458409e913f 214 break;
Shaun Kelsey 0:da5f5b56060a 215 }
Shaun Kelsey 0:da5f5b56060a 216
Shaun Kelsey 0:da5f5b56060a 217 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETNUMPAGES };
Shaun Kelsey 0:da5f5b56060a 218 //num pages = 256*MSB + LSB
Shaun Kelsey 0:da5f5b56060a 219 uint8_t data[] = { (uint8_t)((num_pages >> 8) & 0xFF), (uint8_t)(num_pages & 0xFF) };
Shaun Kelsey 0:da5f5b56060a 220
Shaun Kelsey 0:da5f5b56060a 221 SS_STATUS status = ss_int->write_cmd(
Shaun Kelsey 0:da5f5b56060a 222 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 223 &data[0], ARRAY_SIZE(data));
Shaun Kelsey 0:da5f5b56060a 224
Shaun Kelsey 0:da5f5b56060a 225 if (status == SS_SUCCESS) {
Shaun Kelsey 5:e458409e913f 226 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS);
Shaun Kelsey 0:da5f5b56060a 227 sent_num_pages = true;
Shaun Kelsey 0:da5f5b56060a 228
Shaun Kelsey 0:da5f5b56060a 229 } else {
Shaun Kelsey 5:e458409e913f 230 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR);
Shaun Kelsey 0:da5f5b56060a 231 }
Shaun Kelsey 0:da5f5b56060a 232 } break;
Shaun Kelsey 0:da5f5b56060a 233
Shaun Kelsey 0:da5f5b56060a 234 case cmd_set_iv:
Shaun Kelsey 0:da5f5b56060a 235 {
Shaun Kelsey 0:da5f5b56060a 236 uint8_t iv_bytes[AES_NONCE_SIZE];
Shaun Kelsey 5:e458409e913f 237 ret = parse_iv(cmd, &iv_bytes[0]);
Shaun Kelsey 0:da5f5b56060a 238 if (ret != COMM_SUCCESS) {
Shaun Kelsey 5:e458409e913f 239 m_USB->printf("\r\n%s err=%d\r\n", cmd, ret);
Shaun Kelsey 0:da5f5b56060a 240 }
Shaun Kelsey 0:da5f5b56060a 241 else
Shaun Kelsey 0:da5f5b56060a 242 {
Shaun Kelsey 0:da5f5b56060a 243 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETIV };
Shaun Kelsey 0:da5f5b56060a 244
Shaun Kelsey 0:da5f5b56060a 245 SS_STATUS status = ss_int->write_cmd(
Shaun Kelsey 0:da5f5b56060a 246 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 247 &iv_bytes[0], ARRAY_SIZE(iv_bytes));
Shaun Kelsey 0:da5f5b56060a 248
Shaun Kelsey 0:da5f5b56060a 249 if (status == SS_SUCCESS) {
Shaun Kelsey 5:e458409e913f 250 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS);
Shaun Kelsey 0:da5f5b56060a 251
Shaun Kelsey 0:da5f5b56060a 252 } else {
Shaun Kelsey 5:e458409e913f 253 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR);
Shaun Kelsey 0:da5f5b56060a 254 }
Shaun Kelsey 0:da5f5b56060a 255 }
Shaun Kelsey 0:da5f5b56060a 256 } break;
Shaun Kelsey 0:da5f5b56060a 257
Shaun Kelsey 0:da5f5b56060a 258 case cmd_set_auth:
Shaun Kelsey 0:da5f5b56060a 259 {
Shaun Kelsey 0:da5f5b56060a 260 uint8_t auth_bytes[AES_AUTH_SIZE];
Shaun Kelsey 5:e458409e913f 261 ret = parse_auth(cmd, &auth_bytes[0]);
Shaun Kelsey 0:da5f5b56060a 262 if (ret != COMM_SUCCESS) {
Shaun Kelsey 5:e458409e913f 263 m_USB->printf("\r\n%s err=%d\r\n", cmd, ret);
Shaun Kelsey 0:da5f5b56060a 264 }
Shaun Kelsey 0:da5f5b56060a 265 else
Shaun Kelsey 0:da5f5b56060a 266 {
Shaun Kelsey 0:da5f5b56060a 267 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETAUTH };
Shaun Kelsey 0:da5f5b56060a 268
Shaun Kelsey 0:da5f5b56060a 269 SS_STATUS status = ss_int->write_cmd(
Shaun Kelsey 0:da5f5b56060a 270 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 271 &auth_bytes[0], ARRAY_SIZE(auth_bytes));
Shaun Kelsey 0:da5f5b56060a 272
Shaun Kelsey 0:da5f5b56060a 273 if (status == SS_SUCCESS) {
Shaun Kelsey 5:e458409e913f 274 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS);
Shaun Kelsey 0:da5f5b56060a 275
Shaun Kelsey 0:da5f5b56060a 276 } else {
Shaun Kelsey 5:e458409e913f 277 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR);
Shaun Kelsey 0:da5f5b56060a 278 }
Shaun Kelsey 0:da5f5b56060a 279 }
Shaun Kelsey 0:da5f5b56060a 280 } break;
Shaun Kelsey 0:da5f5b56060a 281
Shaun Kelsey 0:da5f5b56060a 282 case cmd_erase:
Shaun Kelsey 0:da5f5b56060a 283 {
Shaun Kelsey 0:da5f5b56060a 284 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_ERASE };
Shaun Kelsey 0:da5f5b56060a 285
Shaun Kelsey 0:da5f5b56060a 286 SS_STATUS status = ss_int->write_cmd(
Shaun Kelsey 0:da5f5b56060a 287 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 0:da5f5b56060a 288 0, 0,
Shaun Kelsey 0:da5f5b56060a 289 SS_BOOTLOADER_ERASE_DELAY);
Shaun Kelsey 0:da5f5b56060a 290 if (status == SS_SUCCESS)
Shaun Kelsey 5:e458409e913f 291 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS);
Shaun Kelsey 0:da5f5b56060a 292 else
Shaun Kelsey 5:e458409e913f 293 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR);
Shaun Kelsey 5:e458409e913f 294 } break;
Shaun Kelsey 5:e458409e913f 295
Shaun Kelsey 5:e458409e913f 296 case cmd_page_erase:
Shaun Kelsey 5:e458409e913f 297 {
Shaun Kelsey 5:e458409e913f 298 int page_num_to_erase;
Shaun Kelsey 5:e458409e913f 299 int num_tok = sscanf(cmd, "page_erase %d", &page_num_to_erase);
Shaun Kelsey 5:e458409e913f 300 if (num_tok != 1) {
Shaun Kelsey 5:e458409e913f 301 m_USB->printf("\r\n%s value=%d err=%d\r\n", cmd, 0, COMM_INVALID_PARAM);
Shaun Kelsey 5:e458409e913f 302 break;
Shaun Kelsey 5:e458409e913f 303 }
Shaun Kelsey 5:e458409e913f 304
Shaun Kelsey 5:e458409e913f 305 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_ERASE_PAGE };
Shaun Kelsey 5:e458409e913f 306 //num pages = 256*MSB + LSB
Shaun Kelsey 5:e458409e913f 307 uint8_t data[] = { (uint8_t)((page_num_to_erase >> 8) & 0xFF), (uint8_t)(page_num_to_erase & 0xFF) };
Shaun Kelsey 5:e458409e913f 308
Shaun Kelsey 5:e458409e913f 309 SS_STATUS status = ss_int->write_cmd(
Shaun Kelsey 5:e458409e913f 310 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 5:e458409e913f 311 &data[0], ARRAY_SIZE(data), 50);
Shaun Kelsey 5:e458409e913f 312
Shaun Kelsey 5:e458409e913f 313 if (status == SS_SUCCESS) {
Shaun Kelsey 5:e458409e913f 314 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS);
Shaun Kelsey 5:e458409e913f 315 sent_num_pages = true;
Shaun Kelsey 5:e458409e913f 316 } else {
Shaun Kelsey 5:e458409e913f 317 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR);
Shaun Kelsey 5:e458409e913f 318 }
Shaun Kelsey 0:da5f5b56060a 319 } break;
Shaun Kelsey 0:da5f5b56060a 320
Shaun Kelsey 0:da5f5b56060a 321 case cmd_flash:
Shaun Kelsey 0:da5f5b56060a 322 {
Shaun Kelsey 0:da5f5b56060a 323 if (got_page_size && sent_num_pages) {
Shaun Kelsey 5:e458409e913f 324 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS);
Shaun Kelsey 0:da5f5b56060a 325 flash_page_data();
Shaun Kelsey 0:da5f5b56060a 326 } else {
Shaun Kelsey 0:da5f5b56060a 327 pr_err("Can't enter flash mode. Need number of pages, and size of page"
Shaun Kelsey 0:da5f5b56060a 328 "(num_pages, page_size, commands)\r\n");
Shaun Kelsey 5:e458409e913f 329 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR);
Shaun Kelsey 0:da5f5b56060a 330 }
Shaun Kelsey 0:da5f5b56060a 331 } break;
Shaun Kelsey 0:da5f5b56060a 332
Shaun Kelsey 5:e458409e913f 333 case cmd_setcfg_bl_enter_mode:
Shaun Kelsey 5:e458409e913f 334 {
Shaun Kelsey 5:e458409e913f 335 uint8_t mode;
Shaun Kelsey 5:e458409e913f 336 ret = parse_cmd_data(cmd, cmd_tbl[i], &mode, 1, false);
Shaun Kelsey 5:e458409e913f 337 if (ret != 1) {
Shaun Kelsey 5:e458409e913f 338 pr_err("parse_cmd_data=%d\r\n", ret);
Shaun Kelsey 5:e458409e913f 339 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_INVALID_PARAM);
Shaun Kelsey 5:e458409e913f 340 break;
Shaun Kelsey 5:e458409e913f 341 }
Shaun Kelsey 5:e458409e913f 342
Shaun Kelsey 5:e458409e913f 343 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_ENTRY, SS_BL_CFG_ENTER_BL_MODE, mode };
Shaun Kelsey 5:e458409e913f 344 SS_STATUS status = ss_int->write_cmd(
Shaun Kelsey 5:e458409e913f 345 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 5:e458409e913f 346 0, 0);
Shaun Kelsey 5:e458409e913f 347 if (status == SS_SUCCESS)
Shaun Kelsey 5:e458409e913f 348 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS);
Shaun Kelsey 5:e458409e913f 349 else
Shaun Kelsey 5:e458409e913f 350 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR);
Shaun Kelsey 5:e458409e913f 351
Shaun Kelsey 5:e458409e913f 352 } break;
Shaun Kelsey 5:e458409e913f 353
Shaun Kelsey 5:e458409e913f 354 case cmd_setcfg_bl_ebl_pin:
Shaun Kelsey 5:e458409e913f 355 {
Shaun Kelsey 5:e458409e913f 356 uint8_t pin[2];
Shaun Kelsey 5:e458409e913f 357 ret = parse_cmd_data(cmd, cmd_tbl[i], &pin[0], 2, false);
Shaun Kelsey 5:e458409e913f 358 if (ret != 2) {
Shaun Kelsey 5:e458409e913f 359 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_INVALID_PARAM);
Shaun Kelsey 5:e458409e913f 360 break;
Shaun Kelsey 5:e458409e913f 361 }
Shaun Kelsey 5:e458409e913f 362
Shaun Kelsey 5:e458409e913f 363 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_ENTRY, SS_BL_CFG_EBL_PIN,
Shaun Kelsey 5:e458409e913f 364 pin[0], pin[1]};
Shaun Kelsey 5:e458409e913f 365 SS_STATUS status = ss_int->write_cmd(
Shaun Kelsey 5:e458409e913f 366 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 5:e458409e913f 367 0, 0);
Shaun Kelsey 5:e458409e913f 368 if (status == SS_SUCCESS)
Shaun Kelsey 5:e458409e913f 369 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS);
Shaun Kelsey 5:e458409e913f 370 else
Shaun Kelsey 5:e458409e913f 371 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR);
Shaun Kelsey 5:e458409e913f 372
Shaun Kelsey 5:e458409e913f 373 } break;
Shaun Kelsey 5:e458409e913f 374
Shaun Kelsey 5:e458409e913f 375 case cmd_setcfg_bl_ebl_pol:
Shaun Kelsey 5:e458409e913f 376 {
Shaun Kelsey 5:e458409e913f 377 uint8_t mode;
Shaun Kelsey 5:e458409e913f 378 ret = parse_cmd_data(cmd, cmd_tbl[i], &mode, 1, false);
Shaun Kelsey 5:e458409e913f 379 if (ret != 1) {
Shaun Kelsey 5:e458409e913f 380 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_INVALID_PARAM);
Shaun Kelsey 5:e458409e913f 381 break;
Shaun Kelsey 5:e458409e913f 382 }
Shaun Kelsey 5:e458409e913f 383
Shaun Kelsey 5:e458409e913f 384 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_ENTRY, SS_BL_CFG_EBL_POL, mode };
Shaun Kelsey 5:e458409e913f 385 SS_STATUS status = ss_int->write_cmd(
Shaun Kelsey 5:e458409e913f 386 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 5:e458409e913f 387 0, 0);
Shaun Kelsey 5:e458409e913f 388 if (status == SS_SUCCESS)
Shaun Kelsey 5:e458409e913f 389 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS);
Shaun Kelsey 5:e458409e913f 390 else
Shaun Kelsey 5:e458409e913f 391 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR);
Shaun Kelsey 5:e458409e913f 392
Shaun Kelsey 5:e458409e913f 393 } break;
Shaun Kelsey 5:e458409e913f 394
Shaun Kelsey 5:e458409e913f 395 case cmd_setcfg_bl_exit_mode:
Shaun Kelsey 5:e458409e913f 396 {
Shaun Kelsey 5:e458409e913f 397 uint8_t mode;
Shaun Kelsey 5:e458409e913f 398 ret = parse_cmd_data(cmd, cmd_tbl[i], &mode, 1, false);
Shaun Kelsey 5:e458409e913f 399 if (ret != 1) {
Shaun Kelsey 5:e458409e913f 400 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_INVALID_PARAM);
Shaun Kelsey 5:e458409e913f 401 break;
Shaun Kelsey 5:e458409e913f 402 }
Shaun Kelsey 5:e458409e913f 403
Shaun Kelsey 5:e458409e913f 404 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_EXIT, SS_BL_CFG_EXIT_BL_MODE, mode };
Shaun Kelsey 5:e458409e913f 405 SS_STATUS status = ss_int->write_cmd(
Shaun Kelsey 5:e458409e913f 406 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 5:e458409e913f 407 0, 0);
Shaun Kelsey 5:e458409e913f 408 if (status == SS_SUCCESS)
Shaun Kelsey 5:e458409e913f 409 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS);
Shaun Kelsey 5:e458409e913f 410 else
Shaun Kelsey 5:e458409e913f 411 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR);
Shaun Kelsey 5:e458409e913f 412
Shaun Kelsey 5:e458409e913f 413 } break;
Shaun Kelsey 5:e458409e913f 414 case cmd_setcfg_bl_timeout:
Shaun Kelsey 5:e458409e913f 415 {
Shaun Kelsey 5:e458409e913f 416 uint8_t to;
Shaun Kelsey 5:e458409e913f 417 ret = parse_cmd_data(cmd, cmd_tbl[i], &to, 1, false);
Shaun Kelsey 5:e458409e913f 418 if (ret != 1) {
Shaun Kelsey 5:e458409e913f 419 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_INVALID_PARAM);
Shaun Kelsey 5:e458409e913f 420 break;
Shaun Kelsey 5:e458409e913f 421 }
Shaun Kelsey 5:e458409e913f 422
Shaun Kelsey 5:e458409e913f 423 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_EXIT, SS_BL_CFG_TIMEOUT, to };
Shaun Kelsey 5:e458409e913f 424 SS_STATUS status = ss_int->write_cmd(
Shaun Kelsey 5:e458409e913f 425 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 5:e458409e913f 426 0, 0);
Shaun Kelsey 5:e458409e913f 427 if (status == SS_SUCCESS)
Shaun Kelsey 5:e458409e913f 428 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS);
Shaun Kelsey 5:e458409e913f 429 else
Shaun Kelsey 5:e458409e913f 430 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR);
Shaun Kelsey 5:e458409e913f 431
Shaun Kelsey 5:e458409e913f 432 } break;
Shaun Kelsey 5:e458409e913f 433 case cmd_setcfg_bl_save:
Shaun Kelsey 5:e458409e913f 434 {
Shaun Kelsey 5:e458409e913f 435 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_SAVE };
Shaun Kelsey 5:e458409e913f 436
Shaun Kelsey 5:e458409e913f 437 SS_STATUS status = ss_int->write_cmd(
Shaun Kelsey 5:e458409e913f 438 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes),
Shaun Kelsey 5:e458409e913f 439 0, 0, 50);
Shaun Kelsey 5:e458409e913f 440 if (status == SS_SUCCESS)
Shaun Kelsey 5:e458409e913f 441 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS);
Shaun Kelsey 5:e458409e913f 442 else
Shaun Kelsey 5:e458409e913f 443 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR);
Shaun Kelsey 5:e458409e913f 444
Shaun Kelsey 5:e458409e913f 445 } break;
Shaun Kelsey 5:e458409e913f 446
Shaun Kelsey 0:da5f5b56060a 447 default:
Shaun Kelsey 0:da5f5b56060a 448 {
Shaun Kelsey 0:da5f5b56060a 449 assert_msg(false, "Invalid switch case!");
Shaun Kelsey 0:da5f5b56060a 450 }
Shaun Kelsey 0:da5f5b56060a 451 }
Shaun Kelsey 0:da5f5b56060a 452 }
Shaun Kelsey 0:da5f5b56060a 453 }
Shaun Kelsey 0:da5f5b56060a 454
Shaun Kelsey 0:da5f5b56060a 455 return recognizedCmd;
Shaun Kelsey 0:da5f5b56060a 456 }
Shaun Kelsey 0:da5f5b56060a 457
Shaun Kelsey 0:da5f5b56060a 458 void SSBootloaderComm::flash_page_data(void)
Shaun Kelsey 0:da5f5b56060a 459 {
Shaun Kelsey 0:da5f5b56060a 460 int totalBytes = 0;
Shaun Kelsey 0:da5f5b56060a 461 int currentPage = 1;
Shaun Kelsey 0:da5f5b56060a 462
Shaun Kelsey 0:da5f5b56060a 463 static uint8_t tx_buf[MAX_PAGE_SIZE + CHECKBYTES_SIZE + 2] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SENDPAGE };
Shaun Kelsey 0:da5f5b56060a 464 uint8_t *data_buffer = &tx_buf[2];
Shaun Kelsey 0:da5f5b56060a 465
Shaun Kelsey 0:da5f5b56060a 466 while (currentPage <= num_pages) {
Shaun Kelsey 0:da5f5b56060a 467 pr_info("Waiting for page %d/%d data (%d bytes)...", currentPage, num_pages, page_size);
Shaun Kelsey 0:da5f5b56060a 468
Shaun Kelsey 0:da5f5b56060a 469 //Collect page data + checksum from PC/Android
Shaun Kelsey 0:da5f5b56060a 470 // totalBytes = 100;
Shaun Kelsey 0:da5f5b56060a 471 while (totalBytes < (page_size + CHECKBYTES_SIZE)) {
Shaun Kelsey 0:da5f5b56060a 472 data_buffer[totalBytes++] = m_USB->_getc();
Shaun Kelsey 0:da5f5b56060a 473 }
Shaun Kelsey 0:da5f5b56060a 474
Shaun Kelsey 0:da5f5b56060a 475 pr_info("Done\r\n");
Shaun Kelsey 0:da5f5b56060a 476
Shaun Kelsey 0:da5f5b56060a 477 //Send data to SmartSensor
Shaun Kelsey 0:da5f5b56060a 478 SS_STATUS status = ss_int->write_cmd(tx_buf, page_size + CHECKBYTES_SIZE + 2, 2000);
Shaun Kelsey 0:da5f5b56060a 479 pr_err("status: %d\r\n", status);
Shaun Kelsey 0:da5f5b56060a 480
Shaun Kelsey 0:da5f5b56060a 481 //Inform PC/Andoid of status
Shaun Kelsey 0:da5f5b56060a 482 if (status == SS_ERR_BTLDR_CHECKSUM) {
Shaun Kelsey 0:da5f5b56060a 483 pr_err("Verify checksum failed!\r\n");
Shaun Kelsey 0:da5f5b56060a 484 m_USB->printf("\r\npageFlashDone err=%d\r\n", FLASH_ERR_CHECKSUM);
Shaun Kelsey 0:da5f5b56060a 485 } else if (status != SS_SUCCESS) {
Shaun Kelsey 0:da5f5b56060a 486 pr_err("Page flash failed!\r\n");
Shaun Kelsey 0:da5f5b56060a 487 m_USB->printf("\r\npageFlashDone err=%d\r\n", FLASH_ERR_GENERAL);
Shaun Kelsey 0:da5f5b56060a 488 } else {
Shaun Kelsey 0:da5f5b56060a 489 currentPage++;
Shaun Kelsey 0:da5f5b56060a 490 pr_err("Page flash successful!\r\n");
Shaun Kelsey 0:da5f5b56060a 491 m_USB->printf("\r\npageFlashDone err=%d\r\n", COMM_SUCCESS);
Shaun Kelsey 0:da5f5b56060a 492 }
Shaun Kelsey 0:da5f5b56060a 493
Shaun Kelsey 0:da5f5b56060a 494 totalBytes = 0;
Shaun Kelsey 0:da5f5b56060a 495 }
Shaun Kelsey 0:da5f5b56060a 496 }