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
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 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_STAY_IN_BTLRD }; 00154 status = ss_int->write_cmd( 00155 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00156 0, 0); 00157 if (status == SS_SUCCESS) 00158 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00159 else 00160 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00161 00162 00163 ds_int->set_fw_platform(ss_int->get_ss_platform_name()); 00164 ds_int->set_fw_version(ss_int->get_ss_fw_version()); 00165 00166 got_page_size = false; 00167 sent_num_pages = false; 00168 } break; 00169 00170 case cmd_exit_bootldr: 00171 { 00172 SS_STATUS status = ss_int->reset_to_main_app(); 00173 if (status == SS_SUCCESS) 00174 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00175 else 00176 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00177 00178 ds_int->set_fw_platform(ss_int->get_ss_platform_name()); 00179 ds_int->set_fw_version(ss_int->get_ss_fw_version()); 00180 00181 } break; 00182 00183 case cmd_reset: 00184 { 00185 SS_STATUS status = ss_int->reset(); 00186 if (status == SS_SUCCESS) 00187 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00188 else 00189 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00190 m_USB->printf("\r\n%s err=%d\r\n", cmd, ret); 00191 00192 ds_int->set_fw_platform(ss_int->get_ss_platform_name()); 00193 ds_int->set_fw_version(ss_int->get_ss_fw_version()); 00194 00195 } break; 00196 00197 case cmd_page_size: 00198 { 00199 uint8_t cmd_bytes[] = { SS_FAM_R_BOOTLOADER, SS_CMDIDX_PAGESIZE }; 00200 uint8_t rxbuf[3]; 00201 00202 SS_STATUS status = ss_int->read_cmd( 00203 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00204 0, 0, 00205 &rxbuf[0], ARRAY_SIZE(rxbuf)); 00206 00207 if (status == SS_SUCCESS) { 00208 //rxbuf holds page size in big-endian format 00209 page_size = (256*(int)rxbuf[1]) + rxbuf[2]; 00210 assert_msg(page_size <= MAX_PAGE_SIZE, "Page size exceeds maximum allowed"); 00211 00212 m_USB->printf("\r\n%s value=%d err=%d\r\n", cmd, page_size, COMM_SUCCESS); 00213 got_page_size = true; 00214 00215 } else { 00216 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00217 } 00218 } break; 00219 00220 case cmd_num_pages: 00221 { 00222 int num_tok = sscanf(cmd, "num_pages %d", &num_pages); 00223 if (num_tok != 1) { 00224 m_USB->printf("\r\n%s value=%d err=%d\r\n", cmd, 0, COMM_INVALID_PARAM); 00225 break; 00226 } 00227 00228 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETNUMPAGES }; 00229 //num pages = 256*MSB + LSB 00230 uint8_t data[] = { (uint8_t)((num_pages >> 8) & 0xFF), (uint8_t)(num_pages & 0xFF) }; 00231 00232 SS_STATUS status = ss_int->write_cmd( 00233 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00234 &data[0], ARRAY_SIZE(data)); 00235 00236 if (status == SS_SUCCESS) { 00237 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00238 sent_num_pages = true; 00239 00240 } else { 00241 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00242 } 00243 } break; 00244 00245 case cmd_set_iv: 00246 { 00247 uint8_t iv_bytes[AES_NONCE_SIZE]; 00248 ret = parse_iv(cmd, &iv_bytes[0]); 00249 if (ret != COMM_SUCCESS) { 00250 m_USB->printf("\r\n%s err=%d\r\n", cmd, ret); 00251 } 00252 else 00253 { 00254 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETIV }; 00255 00256 SS_STATUS status = ss_int->write_cmd( 00257 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00258 &iv_bytes[0], ARRAY_SIZE(iv_bytes)); 00259 00260 if (status == SS_SUCCESS) { 00261 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00262 00263 } else { 00264 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00265 } 00266 } 00267 } break; 00268 00269 case cmd_set_auth: 00270 { 00271 uint8_t auth_bytes[AES_AUTH_SIZE]; 00272 ret = parse_auth(cmd, &auth_bytes[0]); 00273 if (ret != COMM_SUCCESS) { 00274 m_USB->printf("\r\n%s err=%d\r\n", cmd, ret); 00275 } 00276 else 00277 { 00278 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETAUTH }; 00279 00280 SS_STATUS status = ss_int->write_cmd( 00281 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00282 &auth_bytes[0], ARRAY_SIZE(auth_bytes)); 00283 00284 if (status == SS_SUCCESS) { 00285 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00286 00287 } else { 00288 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00289 } 00290 } 00291 } break; 00292 00293 case cmd_erase: 00294 { 00295 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_ERASE }; 00296 00297 SS_STATUS status = ss_int->write_cmd( 00298 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00299 0, 0, 00300 SS_BOOTLOADER_ERASE_DELAY); 00301 if (status == SS_SUCCESS) 00302 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00303 else 00304 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00305 } break; 00306 00307 case cmd_page_erase: 00308 { 00309 int page_num_to_erase; 00310 int num_tok = sscanf(cmd, "page_erase %d", &page_num_to_erase); 00311 if (num_tok != 1) { 00312 m_USB->printf("\r\n%s value=%d err=%d\r\n", cmd, 0, COMM_INVALID_PARAM); 00313 break; 00314 } 00315 00316 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_ERASE_PAGE }; 00317 //num pages = 256*MSB + LSB 00318 uint8_t data[] = { (uint8_t)((page_num_to_erase >> 8) & 0xFF), (uint8_t)(page_num_to_erase & 0xFF) }; 00319 00320 SS_STATUS status = ss_int->write_cmd( 00321 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00322 &data[0], ARRAY_SIZE(data), 50); 00323 00324 if (status == SS_SUCCESS) { 00325 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00326 sent_num_pages = true; 00327 } else { 00328 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00329 } 00330 } break; 00331 00332 case cmd_flash: 00333 { 00334 if (got_page_size && sent_num_pages) { 00335 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00336 flash_page_data(); 00337 } else { 00338 pr_err("Can't enter flash mode. Need number of pages, and size of page" 00339 "(num_pages, page_size, commands)\r\n"); 00340 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00341 } 00342 } break; 00343 00344 case cmd_setcfg_bl_enter_mode: 00345 { 00346 uint8_t mode; 00347 ret = parse_cmd_data(cmd, cmd_tbl[i], &mode, 1, false); 00348 if (ret != 1) { 00349 pr_err("parse_cmd_data=%d\r\n", ret); 00350 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_INVALID_PARAM); 00351 break; 00352 } 00353 00354 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_ENTRY, SS_BL_CFG_ENTER_BL_MODE, mode }; 00355 SS_STATUS status = ss_int->write_cmd( 00356 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00357 0, 0); 00358 if (status == SS_SUCCESS) 00359 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00360 else 00361 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00362 00363 } break; 00364 00365 case cmd_setcfg_bl_ebl_pin: 00366 { 00367 uint8_t pin[2]; 00368 ret = parse_cmd_data(cmd, cmd_tbl[i], &pin[0], 2, false); 00369 if (ret != 2) { 00370 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_INVALID_PARAM); 00371 break; 00372 } 00373 00374 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_ENTRY, SS_BL_CFG_EBL_PIN, 00375 pin[0], pin[1]}; 00376 SS_STATUS status = ss_int->write_cmd( 00377 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00378 0, 0); 00379 if (status == SS_SUCCESS) 00380 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00381 else 00382 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00383 00384 } break; 00385 00386 case cmd_setcfg_bl_ebl_pol: 00387 { 00388 uint8_t mode; 00389 ret = parse_cmd_data(cmd, cmd_tbl[i], &mode, 1, false); 00390 if (ret != 1) { 00391 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_INVALID_PARAM); 00392 break; 00393 } 00394 00395 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_ENTRY, SS_BL_CFG_EBL_POL, mode }; 00396 SS_STATUS status = ss_int->write_cmd( 00397 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00398 0, 0); 00399 if (status == SS_SUCCESS) 00400 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00401 else 00402 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00403 00404 } break; 00405 00406 case cmd_setcfg_bl_exit_mode: 00407 { 00408 uint8_t mode; 00409 ret = parse_cmd_data(cmd, cmd_tbl[i], &mode, 1, false); 00410 if (ret != 1) { 00411 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_INVALID_PARAM); 00412 break; 00413 } 00414 00415 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_EXIT, SS_BL_CFG_EXIT_BL_MODE, mode }; 00416 SS_STATUS status = ss_int->write_cmd( 00417 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00418 0, 0); 00419 if (status == SS_SUCCESS) 00420 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00421 else 00422 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00423 00424 } break; 00425 case cmd_setcfg_bl_timeout: 00426 { 00427 uint8_t to; 00428 ret = parse_cmd_data(cmd, cmd_tbl[i], &to, 1, false); 00429 if (ret != 1) { 00430 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_INVALID_PARAM); 00431 break; 00432 } 00433 00434 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_EXIT, SS_BL_CFG_TIMEOUT, to }; 00435 SS_STATUS status = ss_int->write_cmd( 00436 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00437 0, 0); 00438 if (status == SS_SUCCESS) 00439 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00440 else 00441 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00442 00443 } break; 00444 case cmd_setcfg_bl_save: 00445 { 00446 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER_CFG, SS_CMDIDX_BL_SAVE }; 00447 00448 SS_STATUS status = ss_int->write_cmd( 00449 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00450 0, 0, 50); 00451 if (status == SS_SUCCESS) 00452 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_SUCCESS); 00453 else 00454 m_USB->printf("\r\n%s err=%d\r\n", cmd, COMM_GENERAL_ERROR); 00455 00456 } break; 00457 00458 default: 00459 { 00460 assert_msg(false, "Invalid switch case!"); 00461 } 00462 } 00463 } 00464 } 00465 00466 return recognizedCmd; 00467 } 00468 00469 void SSBootloaderComm::flash_page_data(void) 00470 { 00471 int totalBytes = 0; 00472 int currentPage = 1; 00473 00474 static uint8_t tx_buf[MAX_PAGE_SIZE + CHECKBYTES_SIZE + 2] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SENDPAGE }; 00475 uint8_t *data_buffer = &tx_buf[2]; 00476 00477 while (currentPage <= num_pages) { 00478 pr_info("Waiting for page %d/%d data (%d bytes)...", currentPage, num_pages, page_size); 00479 00480 //Collect page data + checksum from PC/Android 00481 // totalBytes = 100; 00482 while (totalBytes < (page_size + CHECKBYTES_SIZE)) { 00483 data_buffer[totalBytes++] = m_USB->_getc(); 00484 } 00485 00486 pr_info("Done\r\n"); 00487 00488 //Send data to SmartSensor 00489 SS_STATUS status = ss_int->write_cmd(tx_buf, page_size + CHECKBYTES_SIZE + 2, 2000); 00490 pr_err("status: %d\r\n", status); 00491 00492 //Inform PC/Andoid of status 00493 if (status == SS_ERR_BTLDR_CHECKSUM) { 00494 pr_err("Verify checksum failed!\r\n"); 00495 m_USB->printf("\r\npageFlashDone err=%d\r\n", FLASH_ERR_CHECKSUM); 00496 } else if (status != SS_SUCCESS) { 00497 pr_err("Page flash failed!\r\n"); 00498 m_USB->printf("\r\npageFlashDone err=%d\r\n", FLASH_ERR_GENERAL); 00499 } else { 00500 currentPage++; 00501 pr_err("Page flash successful!\r\n"); 00502 m_USB->printf("\r\npageFlashDone err=%d\r\n", COMM_SUCCESS); 00503 } 00504 00505 totalBytes = 0; 00506 } 00507 }
Generated on Sat Jul 16 2022 17:57:31 by
1.7.2
Heart Rate SpO2 Algorithm EvKit Health Monitor Development System Board MAXREFDES220