#ifndef OTA_H #define OTA_H #include #include /* * OTA firmware update — Issue #124 * * DFU entry triggered by JLINK_CMD_DFU_ENTER (0x06) or USB CDC 'R' command. * Uses RTC backup register OTA_DFU_BKP_IDX to pass magic across the soft reset. * * RTC BKP register map: * BKP0R–BKP5R : BNO055 calibration offsets (PR #150) * BKP6R : BNO055 magic (0xB055CA10, PR #150) * BKP7R–BKP14R : Reserved * BKP15R : OTA DFU magic (this module) * * Using BKP15R avoids collision with BNO055 (BKP0–6) and the old BKP0R * that the original request_bootloader() used before this module. * * Dual-bank note: STM32F722 has single-bank flash (512 KB). Hardware A/B * rollback is not supported without a custom bootloader. DFU via the ST * system bootloader at 0x1FF00000 is the supported update path. Rollback * is handled by the host-side flash_firmware.py script, which keeps a * backup of the previous binary. */ /* RTC backup register index used for DFU magic — avoids BNO055 BKP0–6 */ #define OTA_DFU_BKP_IDX 15u /* Magic value written before reset to trigger DFU entry on next boot */ #define OTA_DFU_MAGIC 0xDEADBEEFu /* STM32F722 internal flash: 512 KB starting at 0x08000000 */ #define OTA_FLASH_BASE 0x08000000u #define OTA_FLASH_SIZE 0x00080000u /* 512 KB */ /* * ota_enter_dfu(is_armed) * * Request entry to USB DFU mode (ST system bootloader at 0x1FF00000). * Returns false without side effects if is_armed is true. * Otherwise: enables backup domain, writes OTA_DFU_MAGIC to BKP15R, * disables IRQs, calls NVIC_SystemReset(). Never returns on success. * * Call from the main loop only (not from ISR context). */ bool ota_enter_dfu(bool is_armed); /* * ota_fw_crc32() * * Compute a CRC-32/MPEG-2 checksum of the full flash region using the * STM32 hardware CRC peripheral (poly 0x04C11DB7, init 0xFFFFFFFF, * 32-bit words, no reflection). Covers OTA_FLASH_SIZE bytes from * OTA_FLASH_BASE including erased padding. * * Takes ~0.5 ms at 216 MHz. Call only while disarmed. */ uint32_t ota_fw_crc32(void); #endif /* OTA_H */