#ifndef __IAP_H__ #define __IAP_H__ #include #include "common_types.h" class UartBus; #define IAP_APP_BASE_ADDR 0x08010000U #define IAP_BOOTLOADER_SIZE (64U * 1024U) #define IAP_FIRMWARE_MAX_SIZE (1024U * 1024U - IAP_BOOTLOADER_SIZE) #define IAP_BUFFER_SIZE (1024U * 1024U) class Iap { public: static Iap &instance(); RetCode init(); RetCode receiveFirmware(UartBus &uart, uint32_t timeout_ms = 120000); RetCode programFirmware(uint32_t flash_addr); RetCode verifyFirmware(uint32_t flash_addr); __attribute__((noreturn)) void jumpToApp(uint32_t app_addr); static bool isValidApp(uint32_t app_addr); static void bootFlagWrite(uint32_t magic); static uint32_t bootFlagRead(void); uint32_t firmwareSize() const { return firmware_size_; } const char *firmwareName() const { return firmware_name_; } private: Iap(); ~Iap() = default; Iap(const Iap &) = delete; Iap &operator=(const Iap &) = delete; static RetCode backupDomainEnable(void); RetCode ymodemReceive(UartBus &uart, uint32_t timeout_ms); int ymodemReadPacket(UartBus &uart, uint8_t *buf, uint32_t timeout_ms); void ymodemSend(UartBus &uart, uint8_t b); int ymodemRead(UartBus &uart, uint32_t timeout_ms); static uint16_t crc16(const uint8_t *data, uint32_t len); bool initialized_; uint32_t firmware_size_; char firmware_name_[32]; }; #endif