dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
main.c
Go to the documentation of this file.
1 
11 /*
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful, but
18  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20  * for more details.
21  *
22  * You should have received a copy of the GNU General Public License along
23  * with this program; if not, see <http://www.gnu.org/licenses/>
24  */
25 
26 #include <pios.h>
27 #include <pios_board_info.h> /* struct pios_board_info */
28 #include <stdbool.h> /* bool */
29 #include "pios_iap.h" /* PIOS_IAP_* */
30 #include "pios_com_msg.h" /* PIOS_COM_MSG_* */
31 #include "pios_usbhook.h" /* PIOS_USBHOOK_* */
32 
33 #include "pios_bl_helper.h" /* PIOS_BL_HELPER_* */
34 
35 #include "led_pwm.h" /* led_pwm_* */
36 #include "bl_messages.h" /* struct bl_messages */
37 #include "bl_xfer.h" /* bl_xfer_* */
38 
39 extern void PIOS_Board_Init(void);
40 
41 #define MSEC_TO_USEC(ms) ((ms) * 1000)
42 #define SEC_TO_MSEC(s) ((s) * 1000)
43 #define SEC_TO_USEC(s) ((s) * 1000 * 1000)
44 
45 #define BL_DETECT_BREAK_TO_BL_TIMER_WITH_VSENSE MSEC_TO_USEC(2)
46 #define BL_DETECT_BREAK_TO_BL_TIMER_NO_VSENSE MSEC_TO_USEC(500)
47 
48 #define BL_WAIT_FOR_DFU_TIMER SEC_TO_USEC(6)
49 #define BL_RECOVER_FROM_FAULT_TIMER SEC_TO_USEC(10)
50 
51 enum bl_states {
52  BL_STATE_FSM_FAULT = 0, /* Must be zero so undefined transitions land here */
63 
64  BL_STATE_NUM_STATES /* Must be last */
65 };
66 
68  DFU_IDLE = 0,
69  DFU_WRITING, /* Uploading */
74  DFU_READING, /* Downloading */
77  DFU_WRITE_START, /* Upload Starting */
81 };
82 
83 /* Map from internal bootloader states to the legacy states that the old bootloaders advertised */
84 static const uint8_t fsm_to_dfu_state_map[] = {
96 };
97 
98 enum bl_events {
111 
112  BL_EVENT_NUM_EVENTS /* Must be last */
113 };
114 
117 
118  /* Received packet */
119  struct bl_messages msg;
120 
121  /* FSM timer */
124 
125  /* LED state */
127 
128  /* Transfer state */
130  struct xfer_state xfer;
131 };
132 
134 
136  void (*entry_fn) (struct bl_fsm_context * context);
138 };
139 
140 static void go_fsm_fault(struct bl_fsm_context * context);
141 static void go_detect_break_to_bl(struct bl_fsm_context * context);
142 static void go_wait_for_dfu(struct bl_fsm_context * context);
143 static void go_jumping_to_app(struct bl_fsm_context * context);
144 static void go_dfu_idle(struct bl_fsm_context * context);
145 static void go_read_in_progress(struct bl_fsm_context * context);
146 static void go_write_in_progress(struct bl_fsm_context * context);
147 static void go_dfu_operation_ok(struct bl_fsm_context * context);
148 static void go_dfu_operation_failed(struct bl_fsm_context * context);
149 
151  [BL_STATE_FSM_FAULT] = {
153  .next_state = {
155  }
156  },
157  [BL_STATE_INIT] = {
158  .entry_fn = NULL,
159  .next_state = {
161  },
162  },
164  .entry_fn = go_detect_break_to_bl,
165  .next_state = {
171  },
172  },
174  .entry_fn = go_wait_for_dfu,
175  .next_state = {
181  },
182  },
184  .entry_fn = go_jumping_to_app,
185  .next_state = {
187  },
188  },
190  .entry_fn = NULL,
191  .next_state = {
193  },
194  },
195  [BL_STATE_DFU_IDLE] = {
196  .entry_fn = go_dfu_idle,
197  .next_state = {
203 #ifdef F1_UPGRADER
206 #else
209 #endif
210  },
211  },
213  .entry_fn = go_read_in_progress,
214  .next_state = {
220  },
221  },
222 
224  .entry_fn = go_write_in_progress,
225  .next_state = {
230  },
231  },
232 
234  .entry_fn = go_dfu_operation_ok,
235  .next_state = {
243  },
244  },
245 
247  .entry_fn = go_dfu_operation_failed,
248  .next_state = {
251  },
252  },
253 };
254 
255 static enum bl_states bl_fsm_get_state(struct bl_fsm_context * context)
256 {
257  return context->curr_state;
258 }
259 
260 static void bl_fsm_timer_start(struct bl_fsm_context * context, uint32_t timer_duration_us)
261 {
262  context->fsm_timer_remaining_us = timer_duration_us;
263  context->fsm_timer_enabled = true;
264 }
265 
266 static void bl_fsm_timer_cancel(struct bl_fsm_context * context)
267 {
268  context->fsm_timer_enabled = false;
269 }
270 
271 static void bl_fsm_timer_add_ticks(struct bl_fsm_context * context, uint32_t elapsed_us)
272 {
273  if (context->fsm_timer_enabled) {
274  if (elapsed_us >= context->fsm_timer_remaining_us) {
275  /* Timer has expired */
276  context->fsm_timer_remaining_us = 0;
277  } else {
278  /* Timer is still running, account for the elapsed time */
279  context->fsm_timer_remaining_us -= elapsed_us;
280  }
281  }
282 }
283 
284 static bool bl_fsm_timer_expired_p(struct bl_fsm_context * context)
285 {
286  if ((context->fsm_timer_enabled) && (context->fsm_timer_remaining_us == 0))
287  return true;
288 
289  return false;
290 }
291 
292 static void go_fsm_fault(struct bl_fsm_context * context)
293 {
295  led_pwm_config(&context->leds, 2500, 100, 2500, 100);
296 }
297 
298 static void go_detect_break_to_bl(struct bl_fsm_context * context)
299 {
300  /* Start a timer for how long to wait for a USB host to appear */
301  if (have_vsense) {
302  bl_fsm_timer_start(context,
304  } else {
305  bl_fsm_timer_start(context,
307  }
308 
309  led_pwm_config(&context->leds, 0, 0, 0, 0);
311 }
312 
313 static void go_wait_for_dfu(struct bl_fsm_context * context)
314 {
315  /* Start a timer for how long to wait for DFU mode to be activated */
317  led_pwm_config(&context->leds, 0, 0, 0, 0);
319 }
320 
321 static void go_jumping_to_app(struct bl_fsm_context * context)
322 {
323  bl_fsm_timer_cancel(context);
324 
326 
327  /* Recover a pointer to the bootloader board info blob */
328  const struct pios_board_info * bdinfo = &pios_board_info_blob;
329 
330  /* Load the application's PC and SP from the beginning of the firmware flash bank */
331  uintptr_t initial_sp = *((__IO uint32_t*) bdinfo->fw_base);
332  uintptr_t initial_pc = *((__IO uint32_t*) (bdinfo->fw_base + 4));
333 
334  /* Simple sanity check to make sure that the SP actually points to RAM */
335  if (((initial_sp & 0x2FFE0000) != 0x20000000) && ((initial_sp & 0x1FFE0000) != 0x10000000)) {
336  /* sp is not sane, don't attempt the jump */
337  return;
338  }
339 
340  /* Simple sanity check to make sure that the PC actually points to FLASH */
341  if ((initial_pc & 0x08000000) != 0x08000000) {
342  /* pc is not sane, don't attempt the jump */
343  return;
344  }
345 
346  /*
347  * pc and sp are sane, try the jump to the application
348  */
349 
350  /* Disable USB */
352 
353  /* Re-lock the internal flash */
354  FLASH_Lock();
355 
356  /* Reset all peripherals */
357  RCC_APB2PeriphResetCmd(0xffffffff, ENABLE);
358  RCC_APB1PeriphResetCmd(0xffffffff, ENABLE);
359  RCC_APB2PeriphResetCmd(0xffffffff, DISABLE);
360  RCC_APB1PeriphResetCmd(0xffffffff, DISABLE);
361 
362  /* Initialize user application's stack pointer */
363  __set_MSP(initial_sp);
364 
365  /* Jump to the application entry point */
366  asm volatile("bx %r0" : : "r" (initial_pc) : );
367 }
368 
369 static void go_dfu_idle(struct bl_fsm_context * context)
370 {
371  bl_fsm_timer_cancel(context);
372  led_pwm_config(&context->leds, 5000, 100, 0, 0);
373 }
374 
375 static void go_read_in_progress(struct bl_fsm_context * context)
376 {
377  bl_fsm_timer_cancel(context);
378  led_pwm_config(&context->leds, 5000, 100, 2500, 50);
379 }
380 
381 static void go_write_in_progress(struct bl_fsm_context * context)
382 {
383  bl_fsm_timer_cancel(context);
384  led_pwm_config(&context->leds, 2500, 50, 0, 0);
385 }
386 
387 static void go_dfu_operation_ok(struct bl_fsm_context * context)
388 {
389  bl_fsm_timer_cancel(context);
390  led_pwm_config(&context->leds, 5000, 100, 0, 0);
391 }
392 
393 static void go_dfu_operation_failed(struct bl_fsm_context * context)
394 {
395  bl_fsm_timer_cancel(context);
396  led_pwm_config(&context->leds, 5000, 100, 0, 0);
397 }
398 
399 static void bl_fsm_process_auto(struct bl_fsm_context *context)
400 {
401  while (bl_transitions[context->curr_state].next_state[BL_EVENT_AUTO]) {
402  context->curr_state = bl_transitions[context->curr_state].next_state[BL_EVENT_AUTO];
403 
404  /* Call the entry function (if any) for the next state. */
405  if (bl_transitions[context->curr_state].entry_fn) {
406  bl_transitions[context->curr_state].entry_fn(context);
407  }
408  }
409 }
410 
411 static void bl_fsm_inject_event(struct bl_fsm_context * context, enum bl_events event)
412 {
413  /*
414  * Move to the next state
415  *
416  * This is done prior to calling the new state's entry function to
417  * guarantee that the entry function never depends on the previous
418  * state. This way, it cannot ever know what the previous state was.
419  */
420  context->curr_state = bl_transitions[context->curr_state].next_state[event];
421 
422  /* Call the entry function (if any) for the next state. */
423  if (bl_transitions[context->curr_state].entry_fn) {
424  bl_transitions[context->curr_state].entry_fn(context);
425  }
426 
427  /* Process any AUTO transitions in the FSM */
428  bl_fsm_process_auto(context);
429 }
430 
431 static void bl_fsm_init(struct bl_fsm_context *context)
432 {
433  memset(context, 0, sizeof(*context));
434 
435  context->curr_state = BL_STATE_INIT;
436  bl_fsm_process_auto(context);
437 }
438 
439 static void process_packet_rx(struct bl_fsm_context * context, const struct bl_messages * msg);
440 
441 int main(void)
442 {
443  /* Interrupts are OK immediately for the loader */
444  __enable_irq();
445 
446  /* Configure and enable system clocks */
447  PIOS_SYS_Init();
448 
449  /* Initialize the board-specific HW configuration */
450  PIOS_Board_Init();
451 
452  /* Adapt delays based on whether target has vsense */
454 
455  /* Initialize the bootloader FSM */
456  struct bl_fsm_context bl_fsm_context;
457  bl_fsm_init(&bl_fsm_context);
458 
459  /* Check if the user has requested that we boot into DFU mode */
460  PIOS_IAP_Init();
461 
462 #ifdef F1_UPGRADER
464  bl_fsm_inject_event(&bl_fsm_context, BL_EVENT_ENTER_DFU);
465 #else
466  if (PIOS_IAP_CheckRequest() == true) {
467  /* User has requested that we boot into DFU mode */
469  bl_fsm_inject_event(&bl_fsm_context, BL_EVENT_ENTER_DFU);
470  } else if (PIOS_Boot_CheckRequest() == true) {
471  /* User has requested that we boot into firmware */
473  PIOS_DELAY_WaitmS(1000);//needed so OS can detect FW USB disconnect
474  bl_fsm_inject_event(&bl_fsm_context, BL_EVENT_FORCE_BOOT);
475  }
476 #endif
477 
478  /* Assume no USB connected */
479  bool usb_connected = false;
480 
481  uint32_t prev_ticks = PIOS_DELAY_GetuS();
482  while (1) {
483  uint32_t elapsed_ticks = PIOS_DELAY_GetuSSince(prev_ticks);
484 
485  /* Run the fsm timer */
486  if (elapsed_ticks) {
487  bl_fsm_timer_add_ticks(&bl_fsm_context, elapsed_ticks);
488  if (bl_fsm_timer_expired_p(&bl_fsm_context) == true) {
489  /* Timer has expired, inject an expiry event */
490  bl_fsm_inject_event(&bl_fsm_context, BL_EVENT_TIMER_EXPIRY);
491  }
492 
493  /* pulse the LEDs */
494  led_pwm_add_ticks(&bl_fsm_context.leds, elapsed_ticks);
495  led_pwm_update_leds(&bl_fsm_context.leds);
496 
497  prev_ticks += elapsed_ticks;
498  }
499 
500  /* check for changes in USB connection state */
501  if (!usb_connected) {
502  if (PIOS_USB_CableConnected(0)) {
504  usb_connected = true;
505  }
506  } else {
507  if (!PIOS_USB_CableConnected(0)) {
509  usb_connected = false;
510  }
511  }
512 
513  /* Manage any active read transfers */
514  if (bl_fsm_get_state(&bl_fsm_context) == BL_STATE_DFU_READ_IN_PROGRESS) {
515  if (bl_xfer_send_next_read_packet(&bl_fsm_context.xfer)) {
516  /* Sent a packet. Are we finished? */
517  if (bl_xfer_completed_p(&bl_fsm_context.xfer)) {
518  /* Transfer is finished */
520  }
521  } else {
522  /* Failed to send packet, fail the transfer */
524  }
525  }
526 
527  /* check for an incoming packet */
528  bool packet_available = PIOS_COM_MSG_Receive(PIOS_COM_TELEM_USB,
529  (uint8_t *)&bl_fsm_context.msg,
530  sizeof(bl_fsm_context.msg));
531  if (packet_available) {
532  process_packet_rx(&bl_fsm_context, &bl_fsm_context.msg);
533  }
534  }
535 }
536 
537 static bool bl_select_dfu_device(struct bl_fsm_context * context, uint8_t device_number)
538 {
539  if (device_number != 0) {
540  /* BL currently only deals with device number 0 (ie. self) so refuse any other device */
541  return false;
542  }
543 
544  /* TODO: Should check if we're in the right state for this */
545 
546  context->dfu_device_number = device_number;
547 
548  return true;
549 }
550 
551 static bool bl_send_status(struct bl_fsm_context * context)
552 {
553  struct bl_messages msg = {
555  .v.status_rep = {
556  .current_state = fsm_to_dfu_state_map[context->curr_state],
557  },
558  };
559 
560  PIOS_COM_MSG_Send(PIOS_COM_TELEM_USB, (uint8_t *)&msg, sizeof(msg));
561 
562  return true;
563 }
564 
565 static bool bl_send_capabilities(struct bl_fsm_context * context, uint8_t device_number)
566 {
567  if (device_number == 0) {
568  /* Return capabilities of all devices */
569  struct bl_messages msg = {
571  .v.cap_rep_all = {
572  .number_of_devices = CPU_TO_BE16(1),
573  .wrflags = CPU_TO_BE16(0x3),
574  },
575  };
576  PIOS_COM_MSG_Send(PIOS_COM_TELEM_USB, (uint8_t *)&msg, sizeof(msg));
577  } else if (device_number == 1) {
579  } else {
580  return false;
581  }
582 
583  return true;
584 }
585 
586 static void process_packet_rx(struct bl_fsm_context * context, const struct bl_messages * msg)
587 {
588  /* Sanity checks */
589  if (!msg)
590  return;
591 
592  /* Split the flags_command field into flags and command */
593  uint8_t flags = msg->flags_command & BL_MSG_FLAGS_MASK;
594  uint8_t command = msg->flags_command & BL_MSG_COMMAND_MASK;
595 
596  struct bl_messages echo;
597  if (flags & BL_MSG_FLAGS_ECHO_REQ) {
598  /* Request should be echoed back to the sender. Make a copy of the request */
599  memcpy (&echo, msg, sizeof(echo));
600  }
601 
602  switch (command) {
603  case BL_MSG_CAP_REQ:
604  bl_send_capabilities(context, msg->v.cap_req.device_number);
605  break;
606  case BL_MSG_ENTER_DFU:
607  if (bl_select_dfu_device(context, msg->v.enter_dfu.device_number)) {
609  } else {
610  /* Failed to select the requested device */
611  }
612  break;
613  case BL_MSG_JUMP_FW:
614  if (BE16_TO_CPU(msg->v.jump_fw.safe_word) == 0x5afe) {
615  /* Force board into safe mode */
616  PIOS_IAP_WriteBootCount(0xFFFF);
617  }
619  break;
620  case BL_MSG_RESET:
622  PIOS_DELAY_WaitmS(1500);
623 
624  PIOS_SYS_Reset();
625  break;
626  case BL_MSG_OP_ABORT:
628  break;
629 
630  case BL_MSG_WRITE_START:
631  if (bl_xfer_write_start(&context->xfer, &(msg->v.xfer_start))) {
633  } else {
634  /* Failed to start the write */
635  }
636  break;
637  case BL_MSG_WRITE_CONT:
639  if (!bl_xfer_write_cont(&context->xfer, &(msg->v.xfer_cont))) {
640  /* Invalid packet, fail the transfer */
642  }
643  }
644  break;
645 
646  case BL_MSG_OP_END:
648  if (bl_xfer_completed_p(&context->xfer)) {
649  /* Transfer is finished, check the CRC */
650  if (bl_xfer_crc_ok_p(&context->xfer)) {
652  } else {
653  /* Mismatched CRC */
655  }
656  }
657  }
658  break;
659 
660  case BL_MSG_READ_START:
661  if (bl_xfer_read_start(&context->xfer, &(msg->v.xfer_start))) {
663  } else {
664  /* Failed to start the read */
665  }
666  break;
667 
668  case BL_MSG_STATUS_REQ:
669  bl_send_status(context);
670  break;
671 
674  break;
675 
676  case BL_MSG_CAP_REP:
677  case BL_MSG_STATUS_REP:
678  case BL_MSG_READ_CONT:
679  /* We've received a *reply* packet when we expected a request. */
680  break;
681  case BL_MSG_RESERVED:
682  /* We've received an reserved command. Ignore this packet. */
683  break;
684 
685  default:
686  /* We've received an unknown command. Ignore this packet. */
687  break;
688  }
689 
690  if (flags & BL_MSG_FLAGS_ECHO_REQ) {
691  /* Reflect the original message back to the originator as an echo reply */
692  echo.flags_command &= ~(BL_MSG_FLAGS_MASK);
694 
695  PIOS_COM_MSG_Send(PIOS_COM_TELEM_USB, (uint8_t *)&echo, sizeof(echo));
696  }
697 
698 }
699 
bool bl_xfer_completed_p(const struct xfer_state *xfer)
Definition: bl_xfer.c:66
uint32_t PIOS_IAP_CheckRequest(void)
Determines if an In-Application-Programming request has been made.
Definition: pios_iap.c:57
enum bl_states curr_state
Definition: main.c:116
static void bl_fsm_inject_event(struct bl_fsm_context *context, enum bl_events event)
Definition: main.c:411
uint16_t PIOS_COM_MSG_Receive(uintptr_t com_id, uint8_t *buf, uint16_t buf_len)
static bool bl_fsm_timer_expired_p(struct bl_fsm_context *context)
Definition: main.c:284
struct bl_messages msg
Definition: main.c:119
struct bl_messages::@23::msg_enter_dfu enter_dfu
int32_t PIOS_COM_MSG_Send(uintptr_t com_id, const uint8_t *msg, uint16_t msg_len)
int main(void)
Definition: main.c:441
struct bl_messages::@23::msg_xfer_start xfer_start
uint32_t PIOS_DELAY_GetuS()
Query the Delay timer for the current uS.
Definition: pios_delay.c:173
struct bl_messages::@23::msg_wipe_partition wipe_partition
Main PiOS header to include all the compiled in PiOS options.
bool bl_xfer_read_start(struct xfer_state *xfer, const struct msg_xfer_start *xfer_start)
Definition: bl_xfer.c:85
static void go_jumping_to_app(struct bl_fsm_context *context)
Definition: main.c:321
bool led_pwm_update_leds(struct led_pwm_state *leds)
Definition: led_pwm.c:82
#define BL_MSG_FLAGS_ECHO_REQ
Definition: bl_messages.h:55
#define CPU_TO_BE16(x)
Definition: pios.h:199
bool bl_xfer_wipe_partition(const struct msg_wipe_partition *wipe_partition)
Definition: bl_xfer.c:314
uint8_t dfu_device_number
Definition: main.c:129
struct led_pwm_state leds
Definition: main.c:126
APIs for PIOS_USBHOOK layer.
bool bl_xfer_send_next_read_packet(struct xfer_state *xfer)
Definition: bl_xfer.c:149
#define BL_DETECT_BREAK_TO_BL_TIMER_WITH_VSENSE
Definition: main.c:45
bool have_vsense
Definition: main.c:133
static void go_write_in_progress(struct bl_fsm_context *context)
Definition: main.c:381
void PIOS_USBHOOK_Deactivate(void)
Definition: pios_usbhook.c:84
struct xfer_state xfer
Definition: main.c:130
static void go_fsm_fault(struct bl_fsm_context *context)
Definition: main.c:292
uint32_t PIOS_DELAY_GetuSSince(uint32_t t)
Calculate time in microseconds since a previous time.
Definition: pios_delay.c:183
void PIOS_SYS_Init(void)
uint16_t flags
Definition: uavtalk_priv.h:52
bool bl_xfer_crc_ok_p(const struct xfer_state *xfer)
Definition: bl_xfer.c:71
#define BL_WAIT_FOR_DFU_TIMER
Definition: main.c:48
#define PIOS_COM_TELEM_USB
Definition: pios_board.h:114
void(* entry_fn)(struct bl_fsm_context *context)
Definition: main.c:136
#define BE16_TO_CPU(x)
Definition: pios.h:221
const struct pios_board_info pios_board_info_blob
static void bl_fsm_timer_start(struct bl_fsm_context *context, uint32_t timer_duration_us)
Definition: main.c:260
#define BL_RECOVER_FROM_FAULT_TIMER
Definition: main.c:49
static void process_packet_rx(struct bl_fsm_context *context, const struct bl_messages *msg)
Definition: main.c:586
void led_pwm_add_ticks(struct led_pwm_state *leds, uint32_t elapsed_us)
Definition: led_pwm.c:77
bl_states
Definition: main.c:51
void PIOS_Board_Init(void)
Definition: pios_board.c:44
static void bl_fsm_timer_cancel(struct bl_fsm_context *context)
Definition: main.c:266
bool bl_xfer_write_start(struct xfer_state *xfer, const struct msg_xfer_start *xfer_start)
Definition: bl_xfer.c:189
#define BL_DETECT_BREAK_TO_BL_TIMER_NO_VSENSE
Definition: main.c:46
#define BL_MSG_COMMAND_MASK
Definition: bl_messages.h:58
static void go_dfu_idle(struct bl_fsm_context *context)
Definition: main.c:369
static void go_dfu_operation_ok(struct bl_fsm_context *context)
Definition: main.c:387
static void go_dfu_operation_failed(struct bl_fsm_context *context)
Definition: main.c:393
void PIOS_IAP_Init(void)
PIOS_IAP_Init - performs required initializations for iap module.
Definition: pios_iap.c:44
bool bl_xfer_write_cont(struct xfer_state *xfer, const struct msg_xfer_cont *xfer_cont)
Definition: bl_xfer.c:270
void led_pwm_config(struct led_pwm_state *leds, uint32_t pwm_1_period_us, uint32_t pwm_1_sweep_steps, uint32_t pwm_2_period_us, uint32_t pwm_2_sweep_steps)
Definition: led_pwm.c:51
static bool bl_send_status(struct bl_fsm_context *context)
Definition: main.c:551
Definition: main.c:68
static void bl_fsm_process_auto(struct bl_fsm_context *context)
Definition: main.c:399
static bool bl_select_dfu_device(struct bl_fsm_context *context, uint8_t device_number)
Definition: main.c:537
void PIOS_ANNUNC_On(uint32_t annunc_id)
struct bl_messages::@23::msg_capabilities_req cap_req
static const uint8_t fsm_to_dfu_state_map[]
Definition: main.c:84
static void go_read_in_progress(struct bl_fsm_context *context)
Definition: main.c:375
COM MSG layer functions header.
uint32_t fsm_timer_remaining_us
Definition: main.c:123
int32_t PIOS_SYS_Reset(void)
#define BL_MSG_FLAGS_MASK
Definition: bl_messages.h:57
struct bl_messages::@23::msg_xfer_cont xfer_cont
static const struct bl_transition bl_transitions[BL_STATE_NUM_STATES]
Definition: main.c:150
int32_t PIOS_IRQ_Disable(void)
Definition: pios_irq.c:40
bool PIOS_USB_HaveVSense(uintptr_t id)
uint8_t flags_command
Definition: bl_messages.h:78
void PIOS_IAP_ClearRequest(void)
Definition: pios_iap.c:89
uint32_t PIOS_Boot_CheckRequest(void)
Determines if a boot request has been made.
Definition: pios_iap.c:63
static void bl_fsm_timer_add_ticks(struct bl_fsm_context *context, uint32_t elapsed_us)
Definition: main.c:271
bool fsm_timer_enabled
Definition: main.c:122
uint8_t device_number
Definition: bl_messages.h:71
static void go_wait_for_dfu(struct bl_fsm_context *context)
Definition: main.c:313
static bool bl_send_capabilities(struct bl_fsm_context *context, uint8_t device_number)
Definition: main.c:565
enum bl_states next_state[BL_EVENT_NUM_EVENTS]
Definition: main.c:137
void PIOS_IAP_WriteBootCount(uint16_t)
Definition: pios_iap.c:98
struct bl_messages::@23::msg_jump_fw jump_fw
bl_events
Definition: main.c:98
bool PIOS_USB_CableConnected(uintptr_t id)
#define BL_MSG_FLAGS_ECHO_REP
Definition: bl_messages.h:56
static void go_detect_break_to_bl(struct bl_fsm_context *context)
Definition: main.c:298
static void bl_fsm_init(struct bl_fsm_context *context)
Definition: main.c:431
legacy_dfu_states
Definition: main.c:67
int32_t PIOS_DELAY_WaitmS(uint32_t mS)
Definition: pios_delay.c:140
static enum bl_states bl_fsm_get_state(struct bl_fsm_context *context)
Definition: main.c:255
bool bl_xfer_send_capabilities_self(void)
Definition: bl_xfer.c:354
In application programming functions.
#define PIOS_LED_HEARTBEAT
Definition: pios_board.h:85