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
Fork of MAXREFDES220# 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 "flash", 00051 }; 00052 00053 SSBootloaderComm::SSBootloaderComm(USBSerial *USB, SSInterface* ssInterface, DSInterface* dsInterface) 00054 :SensorComm("bootldr", false), m_USB(USB), ss_int(ssInterface), ds_int(dsInterface) 00055 { 00056 } 00057 00058 int SSBootloaderComm::parse_auth(const char* cmd, uint8_t *auth_bytes) 00059 { 00060 char cmdStr[] = "set_auth "; 00061 int length = strlen(cmd); 00062 int expected_length = strlen(cmdStr) + 2*AES_AUTH_SIZE; 00063 if (length != expected_length) { 00064 pr_err("Couldn't parse Auth bytes, incorrect number of characters (len:%d, expected:%d)\n", 00065 length, expected_length); 00066 return COMM_INVALID_PARAM; 00067 } 00068 00069 const char* macPtr = cmd + strlen(cmdStr); 00070 00071 int num_found; 00072 int byteVal; 00073 for (int aidx = 0; aidx < AES_AUTH_SIZE; aidx++) { 00074 num_found = sscanf(macPtr, "%2X", &byteVal); 00075 00076 if (num_found != 1 || byteVal > 0xFF) { 00077 pr_err("Couldn't parse byte %d of Auth\n", aidx); 00078 return COMM_INVALID_PARAM; 00079 } 00080 00081 auth_bytes[aidx] = (uint8_t)byteVal; 00082 macPtr += 2; 00083 } 00084 00085 return COMM_SUCCESS; 00086 } 00087 00088 int SSBootloaderComm::parse_iv(const char* cmd, uint8_t* iv_bytes) 00089 { 00090 char cmdStr[] = "set_iv "; 00091 int length = strlen(cmd); 00092 int expected_length = strlen(cmdStr) + 2*AES_NONCE_SIZE; 00093 if (length != expected_length) { 00094 pr_err("Couldn't parse IV, incorrect number of characters (len:%d, expected:%d)\n", 00095 length, expected_length); 00096 return COMM_INVALID_PARAM; 00097 } 00098 00099 const char* ivPtr = cmd + strlen(cmdStr); 00100 00101 int num_found; 00102 int byteVal; 00103 for (int ividx = 0; ividx < AES_NONCE_SIZE; ividx++) { 00104 num_found = sscanf(ivPtr, "%2X", &byteVal); 00105 00106 if (num_found != 1 || byteVal > 0xFF) { 00107 pr_err("Couldn't parse byte %d of IV\n", ividx); 00108 return COMM_INVALID_PARAM; 00109 } 00110 iv_bytes[ividx] = (uint8_t)byteVal; 00111 ivPtr += 2; 00112 } 00113 00114 return COMM_SUCCESS; 00115 } 00116 00117 bool SSBootloaderComm::parse_command(const char* cmd) 00118 { 00119 const char *ptr_ch = NULL; 00120 int ret = EXIT_SUCCESS; 00121 bool recognizedCmd = false; 00122 00123 if (!ss_int) { 00124 pr_err("No SmartSensor Interface defined!"); 00125 return false; 00126 } 00127 if (!ds_int) { 00128 pr_err("No DeviceStudio Interface defined!"); 00129 return false; 00130 } 00131 00132 for (int i = 0; i < NUM_CMDS; i++) { 00133 ptr_ch = strstr(cmd, cmd_tbl[i]); 00134 00135 if (*ptr_ch) { 00136 cmd_state_t user_cmd = (cmd_state_t)i; 00137 recognizedCmd = true; 00138 00139 switch (user_cmd) { 00140 case cmd_enter_bootldr: 00141 { 00142 SS_STATUS status; 00143 status = ss_int->reset_to_bootloader(); 00144 if (status == SS_SUCCESS) 00145 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_SUCCESS); 00146 else 00147 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_GENERAL_ERROR); 00148 00149 ds_int->set_fw_platform(ss_int->get_ss_platform_name()); 00150 ds_int->set_fw_version(ss_int->get_ss_fw_version()); 00151 00152 got_page_size = false; 00153 sent_num_pages = false; 00154 } break; 00155 00156 case cmd_exit_bootldr: 00157 { 00158 SS_STATUS status = ss_int->reset_to_main_app(); 00159 if (status == SS_SUCCESS) 00160 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_SUCCESS); 00161 else 00162 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_GENERAL_ERROR); 00163 00164 ds_int->set_fw_platform(ss_int->get_ss_platform_name()); 00165 ds_int->set_fw_version(ss_int->get_ss_fw_version()); 00166 00167 } break; 00168 00169 case cmd_reset: 00170 { 00171 SS_STATUS status = ss_int->reset(); 00172 if (status == SS_SUCCESS) 00173 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_SUCCESS); 00174 else 00175 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_GENERAL_ERROR); 00176 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, ret); 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_page_size: 00184 { 00185 uint8_t cmd_bytes[] = { SS_FAM_R_BOOTLOADER, SS_CMDIDX_PAGESIZE }; 00186 uint8_t rxbuf[3]; 00187 00188 SS_STATUS status = ss_int->read_cmd( 00189 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00190 0, 0, 00191 &rxbuf[0], ARRAY_SIZE(rxbuf)); 00192 00193 if (status == SS_SUCCESS) { 00194 //rxbuf holds page size in big-endian format 00195 page_size = (256*(int)rxbuf[1]) + rxbuf[2]; 00196 assert_msg(page_size <= MAX_PAGE_SIZE, "Page size exceeds maximum allowed"); 00197 00198 m_USB->printf("\r\n%s value=%d err=%d\r\n", ptr_ch, page_size, COMM_SUCCESS); 00199 got_page_size = true; 00200 00201 } else { 00202 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_GENERAL_ERROR); 00203 } 00204 } break; 00205 00206 case cmd_num_pages: 00207 { 00208 int num_tok = sscanf(ptr_ch, "num_pages %d", &num_pages); 00209 if (num_tok != 1) { 00210 m_USB->printf("\r\n%s value=%d err=%d\r\n", ptr_ch, 0, COMM_INVALID_PARAM); 00211 } 00212 00213 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETNUMPAGES }; 00214 //num pages = 256*MSB + LSB 00215 uint8_t data[] = { (uint8_t)((num_pages >> 8) & 0xFF), (uint8_t)(num_pages & 0xFF) }; 00216 00217 SS_STATUS status = ss_int->write_cmd( 00218 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00219 &data[0], ARRAY_SIZE(data)); 00220 00221 if (status == SS_SUCCESS) { 00222 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_SUCCESS); 00223 sent_num_pages = true; 00224 00225 } else { 00226 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_GENERAL_ERROR); 00227 } 00228 } break; 00229 00230 case cmd_set_iv: 00231 { 00232 uint8_t iv_bytes[AES_NONCE_SIZE]; 00233 ret = parse_iv(ptr_ch, &iv_bytes[0]); 00234 if (ret != COMM_SUCCESS) { 00235 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, ret); 00236 } 00237 else 00238 { 00239 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETIV }; 00240 00241 SS_STATUS status = ss_int->write_cmd( 00242 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00243 &iv_bytes[0], ARRAY_SIZE(iv_bytes)); 00244 00245 if (status == SS_SUCCESS) { 00246 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_SUCCESS); 00247 00248 } else { 00249 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_GENERAL_ERROR); 00250 } 00251 } 00252 } break; 00253 00254 case cmd_set_auth: 00255 { 00256 uint8_t auth_bytes[AES_AUTH_SIZE]; 00257 ret = parse_auth(ptr_ch, &auth_bytes[0]); 00258 if (ret != COMM_SUCCESS) { 00259 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, ret); 00260 } 00261 else 00262 { 00263 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SETAUTH }; 00264 00265 SS_STATUS status = ss_int->write_cmd( 00266 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00267 &auth_bytes[0], ARRAY_SIZE(auth_bytes)); 00268 00269 if (status == SS_SUCCESS) { 00270 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_SUCCESS); 00271 00272 } else { 00273 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_GENERAL_ERROR); 00274 } 00275 } 00276 } break; 00277 00278 case cmd_erase: 00279 { 00280 uint8_t cmd_bytes[] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_ERASE }; 00281 00282 SS_STATUS status = ss_int->write_cmd( 00283 &cmd_bytes[0], ARRAY_SIZE(cmd_bytes), 00284 0, 0, 00285 SS_BOOTLOADER_ERASE_DELAY); 00286 if (status == SS_SUCCESS) 00287 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_SUCCESS); 00288 else 00289 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_GENERAL_ERROR); 00290 } break; 00291 00292 case cmd_flash: 00293 { 00294 if (got_page_size && sent_num_pages) { 00295 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_SUCCESS); 00296 flash_page_data(); 00297 } else { 00298 pr_err("Can't enter flash mode. Need number of pages, and size of page" 00299 "(num_pages, page_size, commands)\r\n"); 00300 m_USB->printf("\r\n%s err=%d\r\n", ptr_ch, COMM_GENERAL_ERROR); 00301 } 00302 } break; 00303 00304 default: 00305 { 00306 assert_msg(false, "Invalid switch case!"); 00307 } 00308 } 00309 } 00310 } 00311 00312 return recognizedCmd; 00313 } 00314 00315 void SSBootloaderComm::flash_page_data(void) 00316 { 00317 int totalBytes = 0; 00318 int currentPage = 1; 00319 00320 static uint8_t tx_buf[MAX_PAGE_SIZE + CHECKBYTES_SIZE + 2] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SENDPAGE }; 00321 uint8_t *data_buffer = &tx_buf[2]; 00322 00323 while (currentPage <= num_pages) { 00324 pr_info("Waiting for page %d/%d data (%d bytes)...", currentPage, num_pages, page_size); 00325 00326 //Collect page data + checksum from PC/Android 00327 // totalBytes = 100; 00328 while (totalBytes < (page_size + CHECKBYTES_SIZE)) { 00329 data_buffer[totalBytes++] = m_USB->_getc(); 00330 } 00331 00332 pr_info("Done\r\n"); 00333 00334 //Send data to SmartSensor 00335 SS_STATUS status = ss_int->write_cmd(tx_buf, page_size + CHECKBYTES_SIZE + 2, 2000); 00336 pr_err("status: %d\r\n", status); 00337 00338 //Inform PC/Andoid of status 00339 if (status == SS_ERR_BTLDR_CHECKSUM) { 00340 pr_err("Verify checksum failed!\r\n"); 00341 m_USB->printf("\r\npageFlashDone err=%d\r\n", FLASH_ERR_CHECKSUM); 00342 } else if (status != SS_SUCCESS) { 00343 pr_err("Page flash failed!\r\n"); 00344 m_USB->printf("\r\npageFlashDone err=%d\r\n", FLASH_ERR_GENERAL); 00345 } else { 00346 currentPage++; 00347 pr_err("Page flash successful!\r\n"); 00348 m_USB->printf("\r\npageFlashDone err=%d\r\n", COMM_SUCCESS); 00349 } 00350 00351 totalBytes = 0; 00352 } 00353 }
Generated on Mon Jul 18 2022 23:37:28 by
