#ifndef BOOTLOADER_H
#define BOOTLOADER_H

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

/* Flash geometry, fixed for the part: 128 KB of main flash in 256 B sectors.
 * 0x00000..0x01FFF   8 KB      boot                   (crc_header at end of boot)
 * 0x02000..0x10FFF   60 KB     app                    (240 sectors)
 * 0x11000..0x1FFFF   60 KB     download               (240 sectors)
 */

#define APP_BASE          0x00002000u
#define DOWNLOAD_BASE     (APP_BASE + 0x0000F000u)
#define IMAGE_BASE        (DOWNLOAD_BASE + BOOT_SECTORS * FLASH_SECTOR_SIZE)

#define CRC_HEADER        0x00001F00u

#define BOOT_SECTORS      32u
#define DOWNLOAD_SECTORS  240u
#define FLASH_SECTOR_SIZE 256u

#define APP_MAGIC         0x57350BAD

#define CRC_FLAG_PENDING  0x00u   /* staged and complete; bootloader should copy */
#define CRC_FLAG_FAILED   0xAAu   /* copy ran, verify failed                     */
#define CRC_FLAG_PASSED   0xAFu   /* copy ran and verified                       */

void Boot_Entry(void);

struct app_header {
  uint32_t entry; // pointer to Reset_Handler
  uint32_t magic;
};

struct crc_header {
  uint32_t slength;
  uint16_t crc_key;
  /*  0x00 if the bootloader should do update
   *  0xAA if update finished but crc failed
   *  0xAF update passed
   */
  uint8_t  flag;
};

uint16_t crc_gen(const uint8_t *data, uint32_t len);

#endif
