#include "../include/hal_lksmcu_flash.h"
#include "../include/hal_lksmcu_reg.h"
#include "hal_lks32mc09x.h"
/**
 * @brief 模块复位，预留接口
 * @param flash 模块类型
 */
void HAL_FLASH_Reset(HAL_FLASH_x flash)
{
}

/**
 * @brief 模块打开，预留接口
 * @param flash 模块类型
 */
void HAL_FLASH_Enable(HAL_FLASH_x flash)
{
}

/**
 * @brief 模块关闭，预留接口
 * @param flash 模块类型
 */
void HAL_FLASH_Disable(HAL_FLASH_x flash)
{
}

/**
 * @brief 使能flash缓存加速
 * @param flash 模块类型
 */
void HAL_FLASH_EnableCache(HAL_FLASH_x flash)
{
    HAL_REG_SET(FLASH_CFG, BIT19);
}

/**
 * @brief 关闭flash缓存加速
 * @param flash 模块类型
 */
void HAL_FLASH_DisableCache(HAL_FLASH_x flash)
{
    HAL_REG_RESET(FLASH_CFG, BIT19);
}

/**
 * @brief 获取一个扇区的大小，和HAL_FLASH_SECTOR_SIZE等效
 * @param flash 模块类型
 * @return uint32_t 扇区大小
 */
uint32_t HAL_FLASH_ReadSectorSize(HAL_FLASH_x flash)
{
    return 512;
}

/**
 * @brief 扇区擦除，len只能是扇区大小的整数倍，不够一个扇区的部分会被忽略
 * @param flash 模块类型
 * @param flashaddr flash地址
 * @param len 擦除长度
 */
void HAL_FLASH_Erase(HAL_FLASH_x flash, uint32_t flashaddr, uint32_t len)
{
    int len1 = len;
    HAL_REG_WRITE_BIT(FLASH_CFG, BIT31 | BIT15 | BIT11, BIT31);
    for (; len1 > 0; len1 -= 512, flashaddr += 512)
    {
        HAL_REG_WRITE(FLASH_ADDR, flashaddr);
        HAL_REG_WRITE(FLASH_ERASE, 0x7654dcba);
    }
    HAL_REG_WRITE_BIT(FLASH_CFG, BIT31 | BIT15 | BIT11, 0);
}

/**
 * @brief 编程
 * @param flash 模块类型
 * @param flashaddr flash地址，低两位会被忽略
 * @param data 数据指针
 * @param len 数据长度
 */
void HAL_FLASH_Program(HAL_FLASH_x flash, uint32_t flashaddr, uint8_t *data, uint32_t len)
{
    int len1 = len;
    HAL_REG_WRITE_BIT(FLASH_CFG, BIT27 | BIT23 | BIT11, BIT27 | BIT23);
    flashaddr &= ~0x3;
    for (; len1 > 0; len1 -= 4, flashaddr += 4)
    {
        uint32_t val;
        val = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
        HAL_REG_WRITE(FLASH_ADDR, flashaddr);
        HAL_REG_WRITE(FLASH_WDATA, val);
    }
    HAL_REG_WRITE_BIT(FLASH_CFG, BIT27 | BIT23 | BIT11, 0);
}

/**
 * @brief 更新数据，等效先擦除再编程
 * @param flash 模块类型
 * @param flashaddr flash地址
 * @param data 数据指针
 * @param len 数据长度
 */
void HAL_FLASH_Update(HAL_FLASH_x flash, uint32_t flashaddr, uint8_t *data, uint32_t len)
{
    HAL_FLASH_Erase(flash, flashaddr, len);
    HAL_FLASH_Program(flash, flashaddr, data, len);
}
