#ifndef OTA_H
#define OTA_H

#include <stdint.h>
#include <stdbool.h>

/*
 * 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 */
