Sync betaflight to Gitea
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* OBL DFU loop entry points called from main.c's boot decision.
|
||||
*
|
||||
* Both run the same OBL middleware loop (OpenBootloader_Init +
|
||||
* OpenBootloader_ProtocolDetection in a busy loop). They differ in how
|
||||
* the DFU memory map is configured before the loop starts:
|
||||
* - normal mode protects the OBL slot (advertise @External_Flash from
|
||||
* nor0 0x100000 onwards — BF slot only);
|
||||
* - recovery mode exposes nor0 from offset 0 so the host can rewrite
|
||||
* OBL itself.
|
||||
*
|
||||
* The mode is communicated to USB_DFU_If_* in usbd_dfu_if.c via the
|
||||
* obl_recovery_mode flag below — checked when DFU initialises its memory
|
||||
* descriptor string.
|
||||
*
|
||||
* Once a host completes a DFU download, our patched usbd_dfu.c sets
|
||||
* dfu_leave_pending; the loop below detaches USB and triggers a system
|
||||
* reset so the freshly-flashed BF runs without manual NRST.
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "app_openbootloader.h"
|
||||
#include "usbd_core.h"
|
||||
|
||||
#include "flash_iface.h"
|
||||
|
||||
bool obl_recovery_mode;
|
||||
|
||||
extern void obl_dfu_apply_mode(bool recovery);
|
||||
extern volatile bool dfu_leave_pending;
|
||||
extern volatile uint32_t dfu_last_write_tick;
|
||||
extern USBD_HandleTypeDef hUsbDeviceFS;
|
||||
|
||||
/* Time for the host's final GET_STATUS to return dfuMANIFEST-WAIT-RESET
|
||||
* before the device disappears off the bus. dfu-util prints a clean
|
||||
* "File downloaded successfully" once the manifest poll loop completes
|
||||
* within ~250 ms; 400 ms is generous. */
|
||||
#define DFU_LEAVE_DRAIN_MS 400U
|
||||
|
||||
/* Auto-reboot after this many ms of write inactivity once at least one
|
||||
* data block has landed. dfu-util without --reset finishes the download
|
||||
* and exits without triggering manifest, so we infer "host is done" from
|
||||
* a stretch of silence. 1500 ms is comfortably above the gap between
|
||||
* dfu-util's per-block transfers (~ms) and below any reasonable interactive
|
||||
* wait. */
|
||||
#define DFU_IDLE_REBOOT_MS 1500U
|
||||
|
||||
static __attribute__((noreturn)) void run_obl_loop(bool recovery)
|
||||
{
|
||||
obl_recovery_mode = recovery;
|
||||
/* Patch the DFU descriptor string before USB enumeration starts so
|
||||
* the host sees the right memory geometry on first GET_DESCRIPTOR. */
|
||||
obl_dfu_apply_mode(recovery);
|
||||
|
||||
OpenBootloader_Init();
|
||||
|
||||
/* IWDG is NOT started in DFU mode — host upload can take tens of
|
||||
* seconds and the BF watchdog window (~30 s) is too tight for that.
|
||||
* The watchdog is armed only when handing off to BF (iwdg_start in
|
||||
* main.c). */
|
||||
while (1) {
|
||||
OpenBootloader_ProtocolDetection();
|
||||
|
||||
const bool leave_request = dfu_leave_pending;
|
||||
const uint32_t last_tick = dfu_last_write_tick;
|
||||
const bool idle_complete = (last_tick != 0U)
|
||||
&& ((HAL_GetTick() - last_tick) >= DFU_IDLE_REBOOT_MS);
|
||||
|
||||
if (leave_request || idle_complete) {
|
||||
HAL_Delay(DFU_LEAVE_DRAIN_MS);
|
||||
(void)USBD_Stop(&hUsbDeviceFS);
|
||||
(void)USBD_DeInit(&hUsbDeviceFS);
|
||||
HAL_Delay(50U);
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noreturn)) void OBL_run_dfu_normal(void)
|
||||
{
|
||||
run_obl_loop(false);
|
||||
}
|
||||
|
||||
__attribute__((noreturn)) void OBL_run_dfu_recovery(void)
|
||||
{
|
||||
run_obl_loop(true);
|
||||
}
|
||||
Reference in New Issue
Block a user