// cpu内部Flash业务驱动
// 杭州秒寻科技有限公司
// 周涛
// 2023-09-26

#include "includes.h"

static DRIVERAPP_UPGRADE_T gDriverapp_stUpgrade = {0};

// 模块初始化
void driverapp_cpuflash_init()
{
    memset(&gDriverapp_stUpgrade, 0, sizeof(DRIVERAPP_UPGRADE_T));
    gDriverapp_stUpgrade.dwNextFrameNo = 1;
    gDriverapp_stUpgrade.dwMemAddress = DRIVERAPP_APP_UPGRADE_ADDRESS1;
}

// 从flash中读出OAM参数
// pdwData(返回参数):数据，需要4字节对齐
// wLen:需要读出的数据长度
uint8 driverapp_cpuflash_read_oam_param(uint32 *pdwData, uint16 wLen)
{
    uint8 byFlag = 0;
    byFlag = driver_cpuflash_read_word_data(DRIVERAPP_OAM_PARAM_ADDRESS, wLen, pdwData);
    if (!byFlag)
    {
        return 0;
    }

    return 1;
}

// 将OAM参数写入flash
// pdwData:数据，4字节对齐
// wLen:数据长度
uint8 driverapp_cpuflash_save_oam_param(uint32 *pdwData, uint16 wLen)
{
    uint8 byFlag = 0;
    uint8 bySector = 0;

    // 获得所在扇区
    byFlag = driver_cpuflash_get_sector(DRIVERAPP_OAM_PARAM_ADDRESS, &bySector);
    if (!byFlag)
    {
        return 0;
    }

    // 擦除扇区
    byFlag = driver_cpuflash_erase_sector(bySector);
    if (!byFlag)
    {
        return 0;
    }

    byFlag = driver_cpuflash_write_word_data(DRIVERAPP_OAM_PARAM_ADDRESS, (uint32 *)pdwData, (uint32)wLen);
    if (!byFlag)
    {
        return byFlag;
    }

    return 1;
}

// 擦除下载区
uint8 driverapp_cpuflash_upgrade_erase_download_block()
{
    uint8 byFlag = 0;
    uint8 bySector = 0;

    // 擦除扇区1
    byFlag = driver_cpuflash_get_sector(DRIVERAPP_APP_UPGRADE_ADDRESS1, &bySector);
    if (!byFlag)
    {
        return byFlag;
    }
    byFlag = driver_cpuflash_erase_sector(bySector);
    if (!byFlag)
    {
        return byFlag;
    }

    // 擦除扇区2
    byFlag = driver_cpuflash_get_sector(DRIVERAPP_APP_UPGRADE_ADDRESS2, &bySector);
    if (!byFlag)
    {
        return byFlag;
    }
    byFlag = driver_cpuflash_erase_sector(bySector);
    if (!byFlag)
    {
        return byFlag;
    }

    return 1;
}

// 通知升级文件信息
// dwFileSize:文件大小
// dwTotalTimes:传输次数
uint8 driverapp_cpuflash_upgrade_notice_file_info(uint32 dwFileSize)
{
    // 文件大小超过存储容量
    if (dwFileSize > OAM_UPGRADE_MAX_FILE_SIZE)
    {
        return 0;
    }

    // 初始化管理结构
    driverapp_cpuflash_init();

    // 保存文件信息
    gDriverapp_stUpgrade.dwFileSize = dwFileSize;

    return 1;
}

// 将数据写入升级区
// dwCurrentFrameNo:当前帧号
// pbyData:数据
// byLen:数据长度
uint8 driverapp_cpuflash_upgrade_write_data(uint32 dwCurrentFrameNo, uint32 *pdwData, uint16 wLen)
{
    uint8 byFlag = 0;
    uint32 dwWordLen = wLen / 4;

    // 当前帧号与期望的帧号不同
    if (dwCurrentFrameNo != gDriverapp_stUpgrade.dwNextFrameNo)
    {
        driverapp_cpuflash_init();
        return 0;
    }

    // 写入数据
    byFlag = driver_cpuflash_write_word_data(gDriverapp_stUpgrade.dwMemAddress, pdwData, dwWordLen);
    if (!byFlag)
    {
        driverapp_cpuflash_init();
        return byFlag;
    }

    // 存储地址偏移byLen字节
    gDriverapp_stUpgrade.dwMemAddress += wLen;
    gDriverapp_stUpgrade.dwNextFrameNo += 1;

    return 1;
}

// 更新升级标识符
// byUpgradeFlag:升级标识符，0:未升级，1：已升级
uint8 driverapp_cpuflash_upgrade_update_flag(uint8 byUpgradeFlag, uint32 dwFileSize)
{
    uint8 byFlag = 0;
    uint8 bySector = 0;

    uint32 adwData[2] = {0};
    adwData[0] = (int32)byUpgradeFlag; // 升级标识符
    adwData[1] = dwFileSize;           // 文件大小

    // 擦除扇区1
    byFlag = driver_cpuflash_get_sector(DRIVERAPP_UPGRADE_PARAM_ADDRESS, &bySector);
    if (!byFlag)
    {
        return byFlag;
    }
    byFlag = driver_cpuflash_erase_sector(bySector);
    if (!byFlag)
    {
        return byFlag;
    }

    // 写入数据
    byFlag = driver_cpuflash_write_word_data(DRIVERAPP_UPGRADE_PARAM_ADDRESS, adwData, 2);
    if (!byFlag)
    {
        return byFlag;
    }

    return 1;
}

// 将数据从下载区拷贝到程序区，同时更新升级标识符
uint8 driverapp_cpuflash_copy_data_from_download_block()
{
    uint8 byFlag = 0;
    uint32 dwUpgradeFlag = 0;
    uint32 dwFileSize = 0;
    int32 dwStartAddress = DRIVERAPP_UPGRADE_PARAM_ADDRESS;

    // 获取升级标识符
    dwUpgradeFlag = *(uint32 *)dwStartAddress;
    if (dwUpgradeFlag == 0 || dwUpgradeFlag == 0xFFFFFFFF)
    { // 未升级，直接返回
        return 0;
    }

    // 获得升级文件大小
    dwStartAddress += 4;
    dwFileSize = *(uint32 *)dwStartAddress;
    dwFileSize /= 4; // 四字节对齐

    // 擦除程序区
    byFlag = driver_cpuflash_upgrade_erase_app_block();
    if (!byFlag)
    {
        return byFlag;
    }

    // 复制数据
    byFlag = driver_cpuflash_write_word_data(DRIVERAPP_APP_ADDRESS1, (uint32 *)DRIVERAPP_APP_UPGRADE_ADDRESS1, dwFileSize);
    if (!byFlag)
    {
        return byFlag;
    }

    // 更新升级标志位
    byFlag = driverapp_cpuflash_upgrade_update_flag(0, 0);
    if (!byFlag)
    {
        return byFlag;
    }

    return 1;
}

// 擦除程序区
uint8 driver_cpuflash_upgrade_erase_app_block()
{
    uint8 byFlag = 0;
    uint8 bySector = 0;

    byFlag = driver_cpuflash_get_sector(DRIVERAPP_APP_ADDRESS1, &bySector);
    if (!byFlag)
    {
        return byFlag;
    }
    byFlag = driver_cpuflash_erase_sector(bySector);
    if (!byFlag)
    {
        return byFlag;
    }

    byFlag = driver_cpuflash_get_sector(DRIVERAPP_APP_ADDRESS2, &bySector);
    if (!byFlag)
    {
        return byFlag;
    }
    byFlag = driver_cpuflash_erase_sector(bySector);
    if (!byFlag)
    {
        return byFlag;
    }

    return 1;
}