#include "flash_counter.h"

typedef struct __attribute__((packed)) {
    uint32_t magic;
    uint32_t counter;
    uint32_t checksum;  // magic ^ counter，用于检测 Flash 损坏
} FlashCounterData_t;

HAL_StatusTypeDef FlashCounter_Init(uint32_t *counter)
{
    const FlashCounterData_t *p = (const FlashCounterData_t *)FLASH_COUNTER_ADDR;

    if (p->magic == FLASH_COUNTER_MAGIC &&
        (p->magic ^ p->counter) == p->checksum) {
        *counter = p->counter;
    } else {
        // 未初始化或校验失败，视为 0
        *counter = 0;
    }
    return HAL_OK;
}

HAL_StatusTypeDef FlashCounter_Write(uint32_t counter)
{
    FLASH_EraseInitTypeDef erase = {
        .TypeErase    = FLASH_TYPEERASE_SECTORS,
        .Sector       = FLASH_COUNTER_SECTOR,
        .NbSectors    = 1,
        .VoltageRange = FLASH_VOLTAGE_RANGE_3,  // 2.7 ~ 3.6 V
    };
    uint32_t sector_error = 0;

    HAL_FLASH_Unlock();

    if (HAL_FLASHEx_Erase(&erase, &sector_error) != HAL_OK) {
        HAL_FLASH_Lock();
        return HAL_ERROR;
    }

    FlashCounterData_t data = {
        .magic    = FLASH_COUNTER_MAGIC,
        .counter  = counter,
        .checksum = FLASH_COUNTER_MAGIC ^ counter,
    };

    uint32_t addr  = FLASH_COUNTER_ADDR;
    uint32_t *word = (uint32_t *)&data;

    for (uint8_t i = 0; i < sizeof(FlashCounterData_t) / 4; i++) {
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr, word[i]) != HAL_OK) {
            HAL_FLASH_Lock();
            return HAL_ERROR;
        }
        addr += 4;
    }

    HAL_FLASH_Lock();
    return HAL_OK;
}
