bl.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. /****************************************************************************
  2. *
  3. * Copyright (c) 2012-2014 PX4 Development Team. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in
  13. * the documentation and/or other materials provided with the
  14. * distribution.
  15. * 3. Neither the name PX4 nor the names of its contributors may be
  16. * used to endorse or promote products derived from this software
  17. * without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  27. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  29. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30. * POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. ****************************************************************************/
  33. /**
  34. * @file bl.c
  35. *
  36. * Common bootloader logic.
  37. *
  38. * Aside from the header includes below, this file should have no board-specific logic.
  39. */
  40. #include "hw_config.h"
  41. #include <inttypes.h>
  42. #include <stdlib.h>
  43. # include <libopencm3/stm32/rcc.h>
  44. # include <libopencm3/stm32/gpio.h>
  45. # include <libopencm3/stm32/flash.h>
  46. #include <libopencm3/cm3/scb.h>
  47. #include <libopencm3/cm3/systick.h>
  48. #include "bl.h"
  49. #include "cdcacm.h"
  50. #include "uart.h"
  51. // bootloader flash update protocol.
  52. //
  53. // Command format:
  54. //
  55. // <opcode>[<command_data>]<EOC>
  56. //
  57. // Reply format:
  58. //
  59. // [<reply_data>]<INSYNC><status>
  60. //
  61. // The <opcode> and <status> values come from the PROTO_ defines below,
  62. // the <*_data> fields is described only for opcodes that transfer data;
  63. // in all other cases the field is omitted.
  64. //
  65. // Expected workflow (protocol 3) is:
  66. //
  67. // GET_SYNC verify that the board is present
  68. // GET_DEVICE determine which board (select firmware to upload)
  69. // CHIP_ERASE erase the program area and reset address counter
  70. // loop:
  71. // PROG_MULTI program bytes
  72. // GET_CRC verify CRC of entire flashable area
  73. // RESET finalise flash programming, reset chip and starts application
  74. //
  75. #define BL_PROTOCOL_VERSION 5 // The revision of the bootloader protocol
  76. //* Next revision needs to update
  77. // protocol bytes
  78. #define PROTO_INSYNC 0x12 // 'in sync' byte sent before status
  79. #define PROTO_EOC 0x20 // end of command
  80. // Reply bytes
  81. #define PROTO_OK 0x10 // INSYNC/OK - 'ok' response
  82. #define PROTO_FAILED 0x11 // INSYNC/FAILED - 'fail' response
  83. #define PROTO_INVALID 0x13 // INSYNC/INVALID - 'invalid' response for bad commands
  84. #define PROTO_BAD_SILICON_REV 0x14 // On the F4 series there is an issue with < Rev 3 silicon
  85. #define PROTO_RESERVED_0X15 0x15 // Reserved
  86. // see https://pixhawk.org/help/errata
  87. // Command bytes
  88. #define PROTO_GET_SYNC 0x21 // NOP for re-establishing sync
  89. #define PROTO_GET_DEVICE 0x22 // get device ID bytes
  90. #define PROTO_CHIP_ERASE 0x23 // erase program area and reset program address
  91. #define PROTO_PROG_MULTI 0x27 // write bytes at program address and increment
  92. #define PROTO_GET_CRC 0x29 // compute & return a CRC
  93. #define PROTO_GET_OTP 0x2a // read a byte from OTP at the given address
  94. #define PROTO_GET_SN 0x2b // read a word from UDID area ( Serial) at the given address
  95. #define PROTO_GET_CHIP 0x2c // read chip version (MCU IDCODE)
  96. #define PROTO_SET_DELAY 0x2d // set minimum boot delay
  97. #define PROTO_GET_CHIP_DES 0x2e // read chip version In ASCII
  98. #define PROTO_BOOT 0x30 // boot the application
  99. #define PROTO_DEBUG 0x31 // emit debug information - format not defined
  100. #define PROTO_SET_BAUD 0x33 // set baud rate on uart
  101. #define PROTO_RESERVED_0X36 0x36 // Reserved
  102. #define PROTO_RESERVED_0X37 0x37 // Reserved
  103. #define PROTO_RESERVED_0X38 0x38 // Reserved
  104. #define PROTO_RESERVED_0X39 0x39 // Reserved
  105. #define PROTO_PROG_MULTI_MAX 64 // maximum PROG_MULTI size
  106. #define PROTO_READ_MULTI_MAX 255 // size of the size field
  107. /* argument values for PROTO_GET_DEVICE */
  108. #define PROTO_DEVICE_BL_REV 1 // bootloader revision
  109. #define PROTO_DEVICE_BOARD_ID 2 // board ID
  110. #define PROTO_DEVICE_BOARD_REV 3 // board revision
  111. #define PROTO_DEVICE_FW_SIZE 4 // size of flashable area
  112. #define PROTO_DEVICE_VEC_AREA 5 // contents of reserved vectors 7-10
  113. static uint8_t bl_type;
  114. static uint8_t last_input;
  115. inline void cinit(void *config, uint8_t interface)
  116. {
  117. #if INTERFACE_USB
  118. if (interface == USB) {
  119. return usb_cinit();
  120. }
  121. #endif
  122. #if INTERFACE_USART
  123. if (interface == USART) {
  124. return uart_cinit(config);
  125. }
  126. #endif
  127. }
  128. inline void cfini(void)
  129. {
  130. #if INTERFACE_USB
  131. usb_cfini();
  132. #endif
  133. #if INTERFACE_USART
  134. uart_cfini();
  135. #endif
  136. }
  137. inline int cin(uint32_t devices)
  138. {
  139. #if INTERFACE_USB
  140. if ((bl_type == NONE || bl_type == USB) && (devices & USB0_DEV) != 0) {
  141. int usb_in = usb_cin();
  142. if (usb_in >= 0) {
  143. last_input = USB;
  144. return usb_in;
  145. }
  146. }
  147. #endif
  148. #if INTERFACE_USART
  149. if ((bl_type == NONE || bl_type == USART) && (devices & SERIAL0_DEV) != 0) {
  150. int uart_in = uart_cin();
  151. if (uart_in >= 0) {
  152. last_input = USART;
  153. return uart_in;
  154. }
  155. }
  156. #endif
  157. return -1;
  158. }
  159. inline void cout(uint8_t *buf, unsigned len)
  160. {
  161. #if INTERFACE_USB
  162. if (bl_type == USB) {
  163. usb_cout(buf, len);
  164. }
  165. #endif
  166. #if INTERFACE_USART
  167. if (bl_type == USART) {
  168. uart_cout(buf, len);
  169. }
  170. #endif
  171. }
  172. static const uint32_t bl_proto_rev = BL_PROTOCOL_VERSION; // value returned by PROTO_DEVICE_BL_REV
  173. static unsigned head, tail;
  174. static uint8_t rx_buf[256] USB_DATA_ALIGN;
  175. static enum led_state {LED_BLINK, LED_ON, LED_OFF} _led_state;
  176. void sys_tick_handler(void);
  177. void
  178. buf_put(uint8_t b)
  179. {
  180. unsigned next = (head + 1) % sizeof(rx_buf);
  181. if (next != tail) {
  182. rx_buf[head] = b;
  183. head = next;
  184. }
  185. }
  186. int
  187. buf_get(void)
  188. {
  189. int ret = -1;
  190. if (tail != head) {
  191. ret = rx_buf[tail];
  192. tail = (tail + 1) % sizeof(rx_buf);
  193. }
  194. return ret;
  195. }
  196. static void
  197. do_jump(uint32_t stacktop, uint32_t entrypoint)
  198. {
  199. asm volatile(
  200. "msr msp, %0 \n"
  201. "bx %1 \n"
  202. : : "r"(stacktop), "r"(entrypoint) :);
  203. // just to keep noreturn happy
  204. for (;;) ;
  205. }
  206. void
  207. jump_to_app()
  208. {
  209. const uint32_t *app_base = (const uint32_t *)APP_LOAD_ADDRESS;
  210. /*
  211. * We refuse to program the first word of the app until the upload is marked
  212. * complete by the host. So if it's not 0xffffffff, we should try booting it.
  213. */
  214. if (app_base[0] == 0xffffffff) {
  215. return;
  216. }
  217. /*
  218. * The second word of the app is the entrypoint; it must point within the
  219. * flash area (or we have a bad flash).
  220. */
  221. if (app_base[1] < APP_LOAD_ADDRESS) {
  222. return;
  223. }
  224. if (app_base[1] >= (APP_LOAD_ADDRESS + board_info.fw_size)) {
  225. return;
  226. }
  227. /* just for paranoia's sake */
  228. flash_lock();
  229. /* kill the systick interrupt */
  230. systick_interrupt_disable();
  231. systick_counter_disable();
  232. /* deinitialise the interface */
  233. cfini();
  234. /* reset the clock */
  235. clock_deinit();
  236. /* deinitialise the board */
  237. board_deinit();
  238. /* switch exception handlers to the application */
  239. SCB_VTOR = APP_LOAD_ADDRESS;
  240. /* extract the stack and entrypoint from the app vector table and go */
  241. do_jump(app_base[0], app_base[1]);
  242. }
  243. volatile unsigned timer[NTIMERS];
  244. void
  245. sys_tick_handler(void)
  246. {
  247. unsigned i;
  248. for (i = 0; i < NTIMERS; i++)
  249. if (timer[i] > 0) {
  250. timer[i]--;
  251. }
  252. if ((_led_state == LED_BLINK) && (timer[TIMER_LED] == 0)) {
  253. led_toggle(LED_BOOTLOADER);
  254. timer[TIMER_LED] = 50;
  255. }
  256. }
  257. void
  258. delay(unsigned msec)
  259. {
  260. timer[TIMER_DELAY] = msec;
  261. while (timer[TIMER_DELAY] > 0)
  262. ;
  263. }
  264. static void
  265. led_set(enum led_state state)
  266. {
  267. _led_state = state;
  268. switch (state) {
  269. case LED_OFF:
  270. led_off(LED_BOOTLOADER);
  271. break;
  272. case LED_ON:
  273. led_on(LED_BOOTLOADER);
  274. break;
  275. case LED_BLINK:
  276. /* restart the blink state machine ASAP */
  277. timer[TIMER_LED] = 0;
  278. break;
  279. }
  280. }
  281. static void
  282. sync_response(void)
  283. {
  284. uint8_t data[] = {
  285. PROTO_INSYNC, // "in sync"
  286. PROTO_OK // "OK"
  287. };
  288. cout(data, sizeof(data));
  289. }
  290. #if defined(TARGET_HW_PX4_FMU_V4)
  291. static void
  292. bad_silicon_response(void)
  293. {
  294. uint8_t data[] = {
  295. PROTO_INSYNC, // "in sync"
  296. PROTO_BAD_SILICON_REV // "issue with < Rev 3 silicon"
  297. };
  298. cout(data, sizeof(data));
  299. }
  300. #endif
  301. static void
  302. invalid_response(void)
  303. {
  304. uint8_t data[] = {
  305. PROTO_INSYNC, // "in sync"
  306. PROTO_INVALID // "invalid command"
  307. };
  308. cout(data, sizeof(data));
  309. }
  310. static void
  311. failure_response(void)
  312. {
  313. uint8_t data[] = {
  314. PROTO_INSYNC, // "in sync"
  315. PROTO_FAILED // "command failed"
  316. };
  317. cout(data, sizeof(data));
  318. }
  319. static volatile unsigned cin_count;
  320. static int
  321. cin_wait(unsigned timeout)
  322. {
  323. int c = -1;
  324. /* start the timeout */
  325. timer[TIMER_CIN] = timeout;
  326. do {
  327. c = cin(board_get_devices());
  328. if (c >= 0) {
  329. cin_count++;
  330. break;
  331. }
  332. } while (timer[TIMER_CIN] > 0);
  333. return c;
  334. }
  335. /**
  336. * Function to wait for EOC
  337. *
  338. * @param timeout length of time in ms to wait for the EOC to be received
  339. * @return true if the EOC is returned within the timeout perio, else false
  340. */
  341. inline static bool
  342. wait_for_eoc(unsigned timeout)
  343. {
  344. return cin_wait(timeout) == PROTO_EOC;
  345. }
  346. static void
  347. cout_word(uint32_t val)
  348. {
  349. cout((uint8_t *)&val, 4);
  350. }
  351. static int
  352. cin_word(uint32_t *wp, unsigned timeout)
  353. {
  354. union {
  355. uint32_t w;
  356. uint8_t b[4];
  357. } u;
  358. for (unsigned i = 0; i < 4; i++) {
  359. int c = cin_wait(timeout);
  360. if (c < 0) {
  361. return c;
  362. }
  363. u.b[i] = c & 0xff;
  364. }
  365. *wp = u.w;
  366. return 0;
  367. }
  368. static uint32_t
  369. crc32(const uint8_t *src, unsigned len, unsigned state)
  370. {
  371. static uint32_t crctab[256];
  372. /* check whether we have generated the CRC table yet */
  373. /* this is much smaller than a static table */
  374. if (crctab[1] == 0) {
  375. for (unsigned i = 0; i < 256; i++) {
  376. uint32_t c = i;
  377. for (unsigned j = 0; j < 8; j++) {
  378. if (c & 1) {
  379. c = 0xedb88320U ^ (c >> 1);
  380. } else {
  381. c = c >> 1;
  382. }
  383. }
  384. crctab[i] = c;
  385. }
  386. }
  387. for (unsigned i = 0; i < len; i++) {
  388. state = crctab[(state ^ src[i]) & 0xff] ^ (state >> 8);
  389. }
  390. return state;
  391. }
  392. void
  393. bootloader(unsigned timeout)
  394. {
  395. bl_type = NONE; // The type of the bootloader, whether loading from USB or USART, will be determined by on what port the bootloader recevies its first valid command.
  396. uint32_t address = board_info.fw_size; /* force erase before upload will work */
  397. uint32_t first_word = 0xffffffff;
  398. /* (re)start the timer system */
  399. systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
  400. systick_set_reload(board_info.systick_mhz * 1000); /* 1ms tick, magic number */
  401. systick_interrupt_enable();
  402. systick_counter_enable();
  403. /* if we are working with a timeout, start it running */
  404. if (timeout) {
  405. timer[TIMER_BL_WAIT] = timeout;
  406. }
  407. /* make the LED blink while we are idle */
  408. led_set(LED_BLINK);
  409. while (true) {
  410. volatile int c;
  411. int arg;
  412. static union {
  413. uint8_t c[256];
  414. uint32_t w[64];
  415. } flash_buffer;
  416. // Wait for a command byte
  417. led_off(LED_ACTIVITY);
  418. do {
  419. /* if we have a timeout and the timer has expired, return now */
  420. if (timeout && !timer[TIMER_BL_WAIT]) {
  421. return;
  422. }
  423. /* try to get a byte from the host */
  424. c = cin_wait(0);
  425. } while (c < 0);
  426. led_on(LED_ACTIVITY);
  427. // handle the command byte
  428. switch (c) {
  429. // sync
  430. //
  431. // command: GET_SYNC/EOC
  432. // reply: INSYNC/OK
  433. //
  434. case PROTO_GET_SYNC:
  435. /* expect EOC */
  436. if (!wait_for_eoc(2)) {
  437. goto cmd_bad;
  438. }
  439. break;
  440. // get device info
  441. //
  442. // command: GET_DEVICE/<arg:1>/EOC
  443. // BL_REV reply: <revision:4>/INSYNC/EOC
  444. // BOARD_ID reply: <board type:4>/INSYNC/EOC
  445. // BOARD_REV reply: <board rev:4>/INSYNC/EOC
  446. // FW_SIZE reply: <firmware size:4>/INSYNC/EOC
  447. // VEC_AREA reply <vectors 7-10:16>/INSYNC/EOC
  448. // bad arg reply: INSYNC/INVALID
  449. //
  450. case PROTO_GET_DEVICE:
  451. /* expect arg then EOC */
  452. arg = cin_wait(1000);
  453. if (arg < 0) {
  454. goto cmd_bad;
  455. }
  456. if (!wait_for_eoc(2)) {
  457. goto cmd_bad;
  458. }
  459. switch (arg) {
  460. case PROTO_DEVICE_BL_REV:
  461. cout((uint8_t *)&bl_proto_rev, sizeof(bl_proto_rev));
  462. break;
  463. case PROTO_DEVICE_BOARD_ID:
  464. cout((uint8_t *)&board_info.board_type, sizeof(board_info.board_type));
  465. break;
  466. case PROTO_DEVICE_BOARD_REV:
  467. cout((uint8_t *)&board_info.board_rev, sizeof(board_info.board_rev));
  468. break;
  469. case PROTO_DEVICE_FW_SIZE:
  470. cout((uint8_t *)&board_info.fw_size, sizeof(board_info.fw_size));
  471. break;
  472. case PROTO_DEVICE_VEC_AREA:
  473. for (unsigned p = 7; p <= 10; p++) {
  474. uint32_t bytes = flash_func_read_word(p * 4);
  475. cout((uint8_t *)&bytes, sizeof(bytes));
  476. }
  477. break;
  478. default:
  479. goto cmd_bad;
  480. }
  481. break;
  482. // erase and prepare for programming
  483. //
  484. // command: ERASE/EOC
  485. // success reply: INSYNC/OK
  486. // erase failure: INSYNC/FAILURE
  487. //
  488. case PROTO_CHIP_ERASE:
  489. /* expect EOC */
  490. if (!wait_for_eoc(2)) {
  491. goto cmd_bad;
  492. }
  493. #if defined(TARGET_HW_PX4_FMU_V4)
  494. if (check_silicon()) {
  495. goto bad_silicon;
  496. }
  497. #endif
  498. // clear the bootloader LED while erasing - it stops blinking at random
  499. // and that's confusing
  500. led_set(LED_ON);
  501. // erase all sectors
  502. flash_unlock();
  503. for (int i = 0; flash_func_sector_size(i) != 0; i++) {
  504. flash_func_erase_sector(i);
  505. }
  506. // disable the LED while verifying the erase
  507. led_set(LED_OFF);
  508. // verify the erase
  509. for (address = 0; address < board_info.fw_size; address += 4)
  510. if (flash_func_read_word(address) != 0xffffffff) {
  511. goto cmd_fail;
  512. }
  513. address = 0;
  514. // resume blinking
  515. led_set(LED_BLINK);
  516. break;
  517. // program bytes at current address
  518. //
  519. // command: PROG_MULTI/<len:1>/<data:len>/EOC
  520. // success reply: INSYNC/OK
  521. // invalid reply: INSYNC/INVALID
  522. // readback failure: INSYNC/FAILURE
  523. //
  524. case PROTO_PROG_MULTI: // program bytes
  525. // expect count
  526. arg = cin_wait(50);
  527. if (arg < 0) {
  528. goto cmd_bad;
  529. }
  530. // sanity-check arguments
  531. if (arg % 4) {
  532. goto cmd_bad;
  533. }
  534. if ((address + arg) > board_info.fw_size) {
  535. goto cmd_bad;
  536. }
  537. if (arg > sizeof(flash_buffer.c)) {
  538. goto cmd_bad;
  539. }
  540. for (int i = 0; i < arg; i++) {
  541. c = cin_wait(1000);
  542. if (c < 0) {
  543. goto cmd_bad;
  544. }
  545. flash_buffer.c[i] = c;
  546. }
  547. if (!wait_for_eoc(200)) {
  548. goto cmd_bad;
  549. }
  550. if (address == 0) {
  551. #if defined(TARGET_HW_PX4_FMU_V4)
  552. if (check_silicon()) {
  553. goto bad_silicon;
  554. }
  555. #endif
  556. // save the first word and don't program it until everything else is done
  557. first_word = flash_buffer.w[0];
  558. // replace first word with bits we can overwrite later
  559. flash_buffer.w[0] = 0xffffffff;
  560. }
  561. arg /= 4;
  562. for (int i = 0; i < arg; i++) {
  563. // program the word
  564. flash_func_write_word(address, flash_buffer.w[i]);
  565. // do immediate read-back verify
  566. if (flash_func_read_word(address) != flash_buffer.w[i]) {
  567. goto cmd_fail;
  568. }
  569. address += 4;
  570. }
  571. break;
  572. // fetch CRC of the entire flash area
  573. //
  574. // command: GET_CRC/EOC
  575. // reply: <crc:4>/INSYNC/OK
  576. //
  577. case PROTO_GET_CRC:
  578. // expect EOC
  579. if (!wait_for_eoc(2)) {
  580. goto cmd_bad;
  581. }
  582. // compute CRC of the programmed area
  583. uint32_t sum = 0;
  584. for (unsigned p = 0; p < board_info.fw_size; p += 4) {
  585. uint32_t bytes;
  586. if ((p == 0) && (first_word != 0xffffffff)) {
  587. bytes = first_word;
  588. } else {
  589. bytes = flash_func_read_word(p);
  590. }
  591. sum = crc32((uint8_t *)&bytes, sizeof(bytes), sum);
  592. }
  593. cout_word(sum);
  594. break;
  595. // read a word from the OTP
  596. //
  597. // command: GET_OTP/<addr:4>/EOC
  598. // reply: <value:4>/INSYNC/OK
  599. case PROTO_GET_OTP:
  600. // expect argument
  601. {
  602. uint32_t index = 0;
  603. if (cin_word(&index, 100)) {
  604. goto cmd_bad;
  605. }
  606. // expect EOC
  607. if (!wait_for_eoc(2)) {
  608. goto cmd_bad;
  609. }
  610. cout_word(flash_func_read_otp(index));
  611. }
  612. break;
  613. // read the SN from the UDID
  614. //
  615. // command: GET_SN/<addr:4>/EOC
  616. // reply: <value:4>/INSYNC/OK
  617. case PROTO_GET_SN:
  618. // expect argument
  619. {
  620. uint32_t index = 0;
  621. if (cin_word(&index, 100)) {
  622. goto cmd_bad;
  623. }
  624. // expect EOC
  625. if (!wait_for_eoc(2)) {
  626. goto cmd_bad;
  627. }
  628. cout_word(flash_func_read_sn(index));
  629. }
  630. break;
  631. // read the chip ID code
  632. //
  633. // command: GET_CHIP/EOC
  634. // reply: <value:4>/INSYNC/OK
  635. case PROTO_GET_CHIP: {
  636. // expect EOC
  637. if (!wait_for_eoc(2)) {
  638. goto cmd_bad;
  639. }
  640. cout_word(get_mcu_id());
  641. }
  642. break;
  643. // read the chip description
  644. //
  645. // command: GET_CHIP_DES/EOC
  646. // reply: <value:4>/INSYNC/OK
  647. case PROTO_GET_CHIP_DES: {
  648. uint8_t buffer[MAX_DES_LENGTH];
  649. unsigned len = MAX_DES_LENGTH;
  650. // expect EOC
  651. if (!wait_for_eoc(2)) {
  652. goto cmd_bad;
  653. }
  654. len = get_mcu_desc(len, buffer);
  655. cout_word(len);
  656. cout(buffer, len);
  657. }
  658. break;
  659. #ifdef BOOT_DELAY_ADDRESS
  660. case PROTO_SET_DELAY: {
  661. /*
  662. Allow for the bootloader to setup a
  663. boot delay signature which tells the
  664. board to delay for at least a
  665. specified number of seconds on boot.
  666. */
  667. int v = cin_wait(100);
  668. if (v < 0) {
  669. goto cmd_bad;
  670. }
  671. uint8_t boot_delay = v & 0xFF;
  672. if (boot_delay > BOOT_DELAY_MAX) {
  673. goto cmd_bad;
  674. }
  675. // expect EOC
  676. if (!wait_for_eoc(2)) {
  677. goto cmd_bad;
  678. }
  679. uint32_t sig1 = flash_func_read_word(BOOT_DELAY_ADDRESS);
  680. uint32_t sig2 = flash_func_read_word(BOOT_DELAY_ADDRESS + 4);
  681. if (sig1 != BOOT_DELAY_SIGNATURE1 ||
  682. sig2 != BOOT_DELAY_SIGNATURE2) {
  683. goto cmd_bad;
  684. }
  685. uint32_t value = (BOOT_DELAY_SIGNATURE1 & 0xFFFFFF00) | boot_delay;
  686. flash_func_write_word(BOOT_DELAY_ADDRESS, value);
  687. if (flash_func_read_word(BOOT_DELAY_ADDRESS) != value) {
  688. goto cmd_fail;
  689. }
  690. }
  691. break;
  692. #endif
  693. // finalise programming and boot the system
  694. //
  695. // command: BOOT/EOC
  696. // reply: INSYNC/OK
  697. //
  698. case PROTO_BOOT:
  699. // expect EOC
  700. if (!wait_for_eoc(1000)) {
  701. goto cmd_bad;
  702. }
  703. // program the deferred first word
  704. if (first_word != 0xffffffff) {
  705. flash_func_write_word(0, first_word);
  706. if (flash_func_read_word(0) != first_word) {
  707. goto cmd_fail;
  708. }
  709. // revert in case the flash was bad...
  710. first_word = 0xffffffff;
  711. }
  712. // send a sync and wait for it to be collected
  713. sync_response();
  714. delay(100);
  715. // quiesce and jump to the app
  716. return;
  717. case PROTO_DEBUG:
  718. // XXX reserved for ad-hoc debugging as required
  719. break;
  720. default:
  721. continue;
  722. }
  723. // we got a command worth syncing, so kill the timeout because
  724. // we are probably talking to the uploader
  725. timeout = 0;
  726. // Set the bootloader port based on the port from which we received the first valid command
  727. if (bl_type == NONE) {
  728. bl_type = last_input;
  729. }
  730. // send the sync response for this command
  731. sync_response();
  732. continue;
  733. cmd_bad:
  734. // send an 'invalid' response but don't kill the timeout - could be garbage
  735. invalid_response();
  736. continue;
  737. cmd_fail:
  738. // send a 'command failed' response but don't kill the timeout - could be garbage
  739. failure_response();
  740. continue;
  741. #if defined(TARGET_HW_PX4_FMU_V4)
  742. bad_silicon:
  743. // send the bad silicon response but don't kill the timeout - could be garbage
  744. bad_silicon_response();
  745. continue;
  746. #endif
  747. }
  748. }