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: max32630fthr USBDevice
Fork of MAXREFDES220_HEART_RATE_MONITOR by
SSBootloaderComm.cpp
00001 /******************************************************************************* 00002 * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 * OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * Except as contained in this notice, the name of Maxim Integrated 00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 * Products, Inc. Branding Policy. 00025 * 00026 * The mere transfer of this software does not imply any licenses 00027 * of trade secrets, proprietary technology, copyrights, patents, 00028 * trademarks, maskwork rights, or any other form of intellectual 00029 * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 * ownership rights. 00031 ******************************************************************************* 00032 */ 00033 00034 #include "DSInterface.h" 00035 #include "SSBootloaderComm.h" 00036 #include "SSInterface.h" 00037 #include "Peripherals.h" 00038 #include "assert.h" 00039 #include "utils.h" 00040 00041 static const char* const cmd_tbl[] = { 00042 "bootldr", 00043 "exit", 00044 "reset", 00045 "page_size", 00046 "num_pages", 00047 "set_iv", 00048 "set_auth", 00049 "erase", 00050 "page_erase", 00051 "flash", 00052 "set_cfg bl enter_mode", 00053 "set_cfg bl enter_pin", 00054 "set_cfg bl enter_pol", 00055 "set_cfg bl exit_mode", 00056 "set_cfg bl exit_to", 00057 "set_cfg bl save", 00058 }; 00059 00060 SSBootloaderComm::SSBootloaderComm(USBSerial *USB, SSInterface* ssInterface, DSInterface* dsInterface) 00061 :SensorComm("bl", false), m_USB(USB), ss_int(ssInterface), ds_int(dsInterface) 00062 { 00063 } 00064 00065 int SSBootloaderComm::parse_auth(const char* cmd, uint8_t *auth_bytes) 00066 { 00067 char cmdStr[] = "set_auth "; 00068 int length = strlen(cmd); 00069 int expected_length = strlen(cmdStr) + 2*AES_AUTH_SIZE; 00070 if (length != expected_length) { 00071 pr_err("Couldn't parse Auth bytes, incorrect number of characters (len:%d, expected:%d)\n", 00072 length, expected_length); 00073 return COMM_INVALID_PARAM; 00074 } 00075 00076 const char* macPtr = cmd + strlen(cmdStr); 00077 00078 int num_found; 00079 int byteVal; 00080 for (int aidx = 0; aidx < AES_AUTH_SIZE; aidx++) { 00081 num_found = sscanf(macPtr, "%2X", &byteVal); 00082 00083 if (num_found != 1 || byteVal > 0xFF) { 00084 pr_err("Couldn't parse byte %d of Auth\n", aidx); 00085 return COMM_INVALID_PARAM; 00086 } 00087 00088 auth_bytes[aidx] = (uint8_t)byteVal; 00089 macPtr += 2; 00090 } 00091 00092 return COMM_SUCCESS; 00093 } 00094 00095 int SSBootloaderComm::parse_iv(const char* cmd, uint8_t* iv_bytes) 00096 { 00097 char cmdStr[] = "set_iv "; 00098 int length = strlen(cmd); 00099 int expected_length = strlen(cmdStr) + 2*AES_NONCE_SIZE; 00100 if (length != expected_length) { 00101 pr_err("Couldn't parse IV, incorrect number of characters (len:%d, expected:%d)\n", 00102 length, expected_length); 00103 return COMM_INVALID_PARAM; 00104 } 00105 00106 const char* ivPtr = cmd + strlen(cmdStr); 00107 00108 int num_found; 00109 int byteVal; 00110 for (int ividx = 0; ividx < AES_NONCE_SIZE; ividx++) { 00111 num_found = sscanf(ivPtr, "%2X", &byteVal); 00112 00113 if (num_found != 1 || byteVal > 0xFF) { 00114 pr_err("Couldn't parse byte %d of IV\n", ividx); 00115 return COMM_INVALID_PARAM; 00116 } 00117 iv_bytes[ividx] = (uint8_t)byteVal; 00118 ivPtr += 2; 00119 } 00120 00121 return COMM_SUCCESS; 00122 } 00123 00124 bool SSBootloaderComm::parse_command(const char* cmd) 00125 { 00126 int ret = EXIT_SUCCESS; 00127 bool recognizedCmd = false; 00128 00129 if (!ss_int) { 00130 pr_err("No SmartSensor Interface defined!"); 00131 return false; 00132 } 00133 if (!ds_int) { 00134 pr_err("No DeviceStudio Interface defined!"); 00135 return false; 00136 } 00137 00138 for (int i = 0; i < NUM_CMDS; i++) { 00139 if (starts_with(cmd, cmd_tbl[i])) { 00140 cmd_state_t user_cmd = (cmd_state_t)i; 00141 recognizedCmd = true; 00142 00143 switch (user_cmd) { 00144 case cmd_enter_bootldr: 00145 { 00146 SS_STATUS status; 00147 status = ss_int->reset_to_bootloader(); 00148 if (status == SS_SUCCESS) 00149 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00150 else 00151 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00152 00153 ds_int->set_fw_platform(ss_int->get_ss_platform_name()); 00154 ds_int->set_fw_version(ss_int->get_ss_fw_version()); 00155 got_page_size = false; 00156 sent_num_pages = false; 00157 } break; 00158 00159 case cmd_exit_bootldr: 00160 { 00161 SS_STATUS status = ss_int->reset_to_main_app(); 00162 if (status == SS_SUCCESS) 00163 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00164 else 00165 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00166 00167 ds_int->set_fw_platform(ss_int->get_ss_platform_name()); 00168 ds_int->set_fw_version(ss_int->get_ss_fw_version()); 00169 00170 } break; 00171 00172 case cmd_reset: 00173 { 00174 SS_STATUS status = ss_int->reset(); 00175 if (status == SS_SUCCESS) 00176 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00177 else 00178 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00179 m_USB->printf("\r\n%s err=%d\r\n", cmd, ret); 00180 00181 ds_int->set_fw_platform(ss_int->get_ss_platform_name()); 00182 ds_int->set_fw_version(ss_int->get_ss_fw_version()); 00183 00184 } break; 00185 00186 case cmd_page_size: 00187 { 00188 uint8_t cmd_bytes[] = { SS_FAM_R_BOOTLOADER, SS_CMDIDX_PAGESIZE }; 00189 uint8_t rxbuf[3]; 00190 00191 SS_STATUS status = ss_int->read_cmd( 00192 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00193 0, 0, 00194 &rxbuf[0], ARRAY_SIZE(rxbuf)); 00195 00196 if (status == SS_SUCCESS) { 00197 //rxbuf holds page size in big-endian format 00198 page_size = (256*(int)rxbuf[1]) + rxbuf[2]; 00199 assert_msg(page_size <= MAX_PAGE_SIZE, "Page size exceeds maximum allowed"); 00200 00201 m_USB->printf("\r\n%s value=%d err=%d\r\n", cmd, page_size, COMM_SUCCESS); 00202 got_page_size = true; 00203 00204 } else { 00205 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00206 } 00207 } break; 00208 00209 case cmd_num_pages: 00210 { 00211 int num_tok = sscanf(cmd, "num_pages %d", &num_pages); 00212 if (num_tok != 1) { 00213 m_USB->printf("\r\n%s value=%d err=%d\r\n", cmd, 0, COMM_INVALID_PARAM); 00214 break; 00215 } 00216 00217 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETNUMPAGES }; 00218 //num pages = 256*MSB + LSB 00219 uint8_t data[] = { (uint8_t)((num_pages >> 8) & 0xFF), (uint8_t)(num_pages & 0xFF) }; 00220 00221 SS_STATUS status = ss_int->write_cmd( 00222 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00223 &data[0], ARRAY_SIZE(data)); 00224 00225 if (status == SS_SUCCESS) { 00226 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00227 sent_num_pages = true; 00228 00229 } else { 00230 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00231 } 00232 } break; 00233 00234 case cmd_set_iv: 00235 { 00236 uint8_t iv_bytes[AES_NONCE_SIZE]; 00237 ret = parse_iv(cmd, &iv_bytes[0]); 00238 if (ret != COMM_SUCCESS) { 00239 m_USB->printf("\r\n%s err=%d\r\n", cmd, ret); 00240 } 00241 else 00242 { 00243 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETIV }; 00244 00245 SS_STATUS status = ss_int->write_cmd( 00246 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00247 &iv_bytes[0], ARRAY_SIZE(iv_bytes)); 00248 00249 if (status == SS_SUCCESS) { 00250 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00251 00252 } else { 00253 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00254 } 00255 } 00256 } break; 00257 00258 case cmd_set_auth: 00259 { 00260 uint8_t auth_bytes[AES_AUTH_SIZE]; 00261 ret = parse_auth(cmd, &auth_bytes[0]); 00262 if (ret != COMM_SUCCESS) { 00263 m_USB->printf("\r\n%s err=%d\r\n", cmd, ret); 00264 } 00265 else 00266 { 00267 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETAUTH }; 00268 00269 SS_STATUS status = ss_int->write_cmd( 00270 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00271 &auth_bytes[0], ARRAY_SIZE(auth_bytes)); 00272 00273 if (status == SS_SUCCESS) { 00274 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00275 00276 } else { 00277 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00278 } 00279 } 00280 } break; 00281 00282 case cmd_erase: 00283 { 00284 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_ERASE }; 00285 00286 SS_STATUS status = ss_int->write_cmd( 00287 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00288 0, 0, 00289 SS_BOOTLOADER_ERASE_DELAY); 00290 if (status == SS_SUCCESS) 00291 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00292 else 00293 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00294 } break; 00295 00296 case cmd_page_erase: 00297 { 00298 int page_num_to_erase; 00299 int num_tok = sscanf(cmd, "page_erase %d", &page_num_to_erase); 00300 if (num_tok != 1) { 00301 m_USB->printf("\r\n%s value=%d err=%d\r\n", cmd, 0, COMM_INVALID_PARAM); 00302 break; 00303 } 00304 00305 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_ERASE_PAGE }; 00306 //num pages = 256*MSB + LSB 00307 uint8_t data[] = { (uint8_t)((page_num_to_erase >> 8) & 0xFF), (uint8_t)(page_num_to_erase & 0xFF) }; 00308 00309 SS_STATUS status = ss_int->write_cmd( 00310 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00311 &data[0], ARRAY_SIZE(data), 50); 00312 00313 if (status == SS_SUCCESS) { 00314 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00315 sent_num_pages = true; 00316 } else { 00317 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00318 } 00319 } break; 00320 00321 case cmd_flash: 00322 { 00323 if (got_page_size && sent_num_pages) { 00324 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00325 flash_page_data(); 00326 } else { 00327 pr_err("Can't enter flash mode. Need number of pages, and size of page" 00328 "(num_pages, page_size, commands)\r\n"); 00329 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00330 } 00331 } break; 00332 00333 case cmd_setcfg_bl_enter_mode: 00334 { 00335 uint8_t mode; 00336 ret = parse_cmd_data(cmd, cmd_tbl[i], &mode, 1, false); 00337 if (ret != 1) { 00338 pr_err("parse_cmd_data=%d\r\n", ret); 00339 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_INVALID_PARAM); 00340 break; 00341 } 00342 00343 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_ENTRY, SS_BL_CFG_ENTER_BL_MODE, mode }; 00344 SS_STATUS status = ss_int->write_cmd( 00345 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00346 0, 0); 00347 if (status == SS_SUCCESS) 00348 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00349 else 00350 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00351 00352 } break; 00353 00354 case cmd_setcfg_bl_ebl_pin: 00355 { 00356 uint8_t pin[2]; 00357 ret = parse_cmd_data(cmd, cmd_tbl[i], &pin[0], 2, false); 00358 if (ret != 2) { 00359 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_INVALID_PARAM); 00360 break; 00361 } 00362 00363 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_ENTRY, SS_BL_CFG_EBL_PIN, 00364 pin[0], pin[1]}; 00365 SS_STATUS status = ss_int->write_cmd( 00366 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00367 0, 0); 00368 if (status == SS_SUCCESS) 00369 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00370 else 00371 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00372 00373 } break; 00374 00375 case cmd_setcfg_bl_ebl_pol: 00376 { 00377 uint8_t mode; 00378 ret = parse_cmd_data(cmd, cmd_tbl[i], &mode, 1, false); 00379 if (ret != 1) { 00380 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_INVALID_PARAM); 00381 break; 00382 } 00383 00384 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_ENTRY, SS_BL_CFG_EBL_POL, mode }; 00385 SS_STATUS status = ss_int->write_cmd( 00386 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00387 0, 0); 00388 if (status == SS_SUCCESS) 00389 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00390 else 00391 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00392 00393 } break; 00394 00395 case cmd_setcfg_bl_exit_mode: 00396 { 00397 uint8_t mode; 00398 ret = parse_cmd_data(cmd, cmd_tbl[i], &mode, 1, false); 00399 if (ret != 1) { 00400 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_INVALID_PARAM); 00401 break; 00402 } 00403 00404 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_EXIT, SS_BL_CFG_EXIT_BL_MODE, mode }; 00405 SS_STATUS status = ss_int->write_cmd( 00406 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00407 0, 0); 00408 if (status == SS_SUCCESS) 00409 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00410 else 00411 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00412 00413 } break; 00414 case cmd_setcfg_bl_timeout: 00415 { 00416 uint8_t to; 00417 ret = parse_cmd_data(cmd, cmd_tbl[i], &to, 1, false); 00418 if (ret != 1) { 00419 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_INVALID_PARAM); 00420 break; 00421 } 00422 00423 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_EXIT, SS_BL_CFG_TIMEOUT, to }; 00424 SS_STATUS status = ss_int->write_cmd( 00425 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00426 0, 0); 00427 if (status == SS_SUCCESS) 00428 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00429 else 00430 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00431 00432 } break; 00433 case cmd_setcfg_bl_save: 00434 { 00435 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_SAVE }; 00436 00437 SS_STATUS status = ss_int->write_cmd( 00438 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00439 0, 0, 50); 00440 if (status == SS_SUCCESS) 00441 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00442 else 00443 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00444 00445 } break; 00446 00447 default: 00448 { 00449 assert_msg(false, "Invalid switch case!"); 00450 } 00451 } 00452 } 00453 } 00454 00455 return recognizedCmd; 00456 } 00457 00458 void SSBootloaderComm::flash_page_data(void) 00459 { 00460 int totalBytes = 0; 00461 int currentPage = 1; 00462 00463 static uint8_t tx_buf[MAX_PAGE_SIZE + CHECKBYTES_SIZE + 2] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SENDPAGE }; 00464 uint8_t *data_buffer = &tx_buf[2]; 00465 00466 while (currentPage <= num_pages) { 00467 pr_info("Waiting for page %d/%d data (%d bytes)...", currentPage, num_pages, page_size); 00468 00469 //Collect page data + checksum from PC/Android 00470 // totalBytes = 100; 00471 while (totalBytes < (page_size + CHECKBYTES_SIZE)) { 00472 data_buffer[totalBytes++] = m_USB->_getc(); 00473 } 00474 00475 pr_info("Done\r\n"); 00476 00477 //Send data to SmartSensor 00478 SS_STATUS status = ss_int->write_cmd(tx_buf, page_size + CHECKBYTES_SIZE + 2, 2000); 00479 pr_err("status: %d\r\n", status); 00480 00481 //Inform PC/Andoid of status 00482 if (status == SS_ERR_BTLDR_CHECKSUM) { 00483 pr_err("Verify checksum failed!\r\n"); 00484 m_USB->printf("\r\npageFlashDone err=%d\r\n", FLASH_ERR_CHECKSUM); 00485 } else if (status != SS_SUCCESS) { 00486 pr_err("Page flash failed!\r\n"); 00487 m_USB->printf("\r\npageFlashDone err=%d\r\n", FLASH_ERR_GENERAL); 00488 } else { 00489 currentPage++; 00490 pr_err("Page flash successful!\r\n"); 00491 m_USB->printf("\r\npageFlashDone err=%d\r\n", COMM_SUCCESS); 00492 } 00493 00494 totalBytes = 0; 00495 } 00496 }
Generated on Tue Jul 12 2022 10:59:32 by
1.7.2

Heart Rate SpO2 Algorithm EvKit Health Monitor Development System Board MAXREFDES220