#ifndef IMU_CAL_FLASH_H
#define IMU_CAL_FLASH_H

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

/*
 * IMU mount angle calibration flash storage (Issue #680).
 *
 * Sector 7 (128 KB at 0x08060000) layout:
 *   0x0807FF00  imu_cal_flash_t   (64 bytes)  ← this module
 *   0x0807FF40  pid_sched_flash_t (128 bytes) ← pid_flash.c
 *   0x0807FFC0  pid_flash_t       (64 bytes)  ← pid_flash.c
 *
 * Calibration flow:
 *   1. Mount robot at its installed angle, power on, let IMU converge (~5s).
 *   2. Send 'O' via USB CDC (dev-only path).
 *   3. Firmware captures current pitch + roll as mount offsets, saves to flash.
 *   4. mpu6000_read() subtracts offsets from output on every subsequent read.
 *
 * The sector erase preserves existing PID data by reading it first.
 */

#define IMU_CAL_FLASH_ADDR    0x0807FF00UL
#define IMU_CAL_FLASH_MAGIC   0x534C5403UL   /* 'SLT\x03' — version 3 */

typedef struct __attribute__((packed)) {
    uint32_t magic;           /* IMU_CAL_FLASH_MAGIC when valid */
    float    pitch_offset;    /* degrees subtracted from IMU pitch output */
    float    roll_offset;     /* degrees subtracted from IMU roll output */
    uint8_t  _pad[52];        /* padding to 64 bytes */
} imu_cal_flash_t;            /* 64 bytes total */

/*
 * imu_cal_flash_load() — read saved mount offsets from flash.
 * Returns true and fills *pitch_offset / *roll_offset if magic is valid.
 * Returns false if no valid calibration stored (caller keeps 0.0f defaults).
 */
bool imu_cal_flash_load(float *pitch_offset, float *roll_offset);

/*
 * imu_cal_flash_save() — erase sector 7 and write all three records atomically:
 *   imu_cal_flash_t at 0x0807FF00
 *   pid_sched_flash_t at 0x0807FF40 (preserved from existing flash)
 *   pid_flash_t at 0x0807FFC0       (preserved from existing flash)
 * Must be called while disarmed — sector erase stalls CPU ~1s.
 * Returns true on success.
 */
bool imu_cal_flash_save(float pitch_offset, float roll_offset);

#endif /* IMU_CAL_FLASH_H */
