#include <string.h>
#include "Flash_User.h"

/*传入的数据长度需为字节数*/
void Flash_Data_Read(uint32_t u32Addr, uint16_t u16Data[], uint32_t u32Len)
{
    uint32_t addr = 0U;

    for (uint32_t i = 0U; i < (u32Len / 2U); i++ )
    {
        u16Data[i] = HW16_REG(u32Addr + addr);
        addr += 2U;
    }
}

/*传入的数据长度需为字节数*/
Flash_User_Result_en_t Flash_Data_Write(uint32_t u32Addr, uint16_t u16Data[], uint32_t u32Len)
{
    // LoadBalancing_NVM_Data_st_t TestData;
    static uint32_t copyData[64];
    memset (copyData, 0, sizeof(copyData));
    uint32_t flash_program_start = u32Addr;                 /* flash program start address */
    uint32_t flash_program_end = 0U;                        /* flash program end address */

    if (u32Len < 512u)
    {
        for (uint32_t i = 0; i < (u32Len / 4U); i++)
        {
            copyData[i] = ((u16Data[(2 * i) + 1] << 16U) + u16Data[2 * i]);
        }
        flash_program_end = u32Addr + 256U;
        uint32_t *src = (uint32_t *)copyData;

        /* Unlock Flash */
        HAL_FLASH_Unlock();

        while (flash_program_start < flash_program_end)
        {
            if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_PAGE, flash_program_start, src) == HAL_OK)/* Program */
            {
                flash_program_start += FLASH_PAGE_SIZE; /* flash Start point first page */
                src += FLASH_PAGE_SIZE / 4;             /* Update data point */
            }
            else
            {
                /* Lock Flash */
                HAL_FLASH_Lock();
                return FLASH_CONTROL_FAIL;
            }
        }
        /* Lock Flash */
        HAL_FLASH_Lock();
    }

    return FLASH_CONTROL_PASS;
}

Flash_User_Result_en_t Flash_Data_PageErase(uint32_t u32StartAddr, uint32_t u32EndAddr)
{
    uint32_t PAGEError = 0;
    FLASH_EraseInitTypeDef EraseInitStruct = {0};

    /* Unlock Flash */
    HAL_FLASH_Unlock();
  
    EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGEERASE;        /* Erase type FLASH_TYPEERASE_PAGEERASE=Page erase, FLASH_TYPEERASE_SECTORERASE=Sector Erase */
    EraseInitStruct.PageAddress = u32StartAddr;                               /* Erase Start Address */
    EraseInitStruct.NbPages  = ((u32EndAddr + 1 - u32StartAddr) / 0x100);    /* Number of pages that need to be erased */
    if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)  /* Executing page erasure, PAGEError returns the page with the erasure error and 0xFFFFFFFF, indicating successful erasure */
    {
        /* Lock Flash */
        HAL_FLASH_Lock();
        return FLASH_CONTROL_FAIL;
    }
    else
    {
        ;
    }
    /* Lock Flash */
    HAL_FLASH_Lock();
    return FLASH_CONTROL_PASS;
}

Flash_User_Result_en_t Flash_Data_SectorErase(uint32_t u32StartAddr, uint32_t u32EndAddr)
{
    uint32_t PAGEError = 0;
    FLASH_EraseInitTypeDef EraseInitStruct = {0};

    /* Unlock Flash */
    HAL_FLASH_Unlock();
  
    EraseInitStruct.TypeErase   = FLASH_TYPEERASE_SECTORERASE;        /* Erase type FLASH_TYPEERASE_PAGEERASE=Page erase, FLASH_TYPEERASE_SECTORERASE=Sector Erase */
    EraseInitStruct.SectorAddress = u32StartAddr;
    EraseInitStruct.NbSectors = ((u32EndAddr + 1 - u32StartAddr) / 0x2000);
    if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)  /* Executing page erasure, PAGEError returns the page with the erasure error and 0xFFFFFFFF, indicating successful erasure */
    {
        /* Lock Flash */
        HAL_FLASH_Lock();
        return FLASH_CONTROL_FAIL;
    }
    else
    {
        ;
    }
    /* Lock Flash */
    HAL_FLASH_Lock();
    return FLASH_CONTROL_PASS;
}

uint32_t Flash_Data_CheckBlank(uint32_t u32StartAddr, uint32_t u32EndAddr)
{
    /*如果查空的范围内，数据不连续，混杂着空值。那就从检测到空值开始认为整个空间都是空的，后续的值也是垃圾数据，使用时先将选定区域全擦除，再写入值*/
    uint32_t addr = 0;
    uint32_t addroffset = 0U;
    uint8_t  blankFlag = 0U;
    uint32_t Count = (u32EndAddr - u32StartAddr + 1) / 4;

    for (uint32_t i = 0; i < Count; i++)
    {
        if (0xFFFFFFFFUL == HW32_REG(u32StartAddr + addr))
        {
            addroffset = addr;
            /*遇到4字节数据是空，再往下查3个4字节看看是不是也是空*/
            for (uint32_t j = 0; j < 3; j++)
            {
                addroffset += 4;
                if ((u32StartAddr + addroffset) >= u32EndAddr)
                {
                    blankFlag = 1U;
                    break;
                }
                else if (0xFFFFFFFFUL != HW32_REG(u32StartAddr + addroffset))
                {
                    break;
                }
                if (j == 2)
                {
                    blankFlag = 1U;
                    break;
                }
            }
            if (blankFlag == 1U)
            {
                break;
            }
        
        }
        addr += 4;
    }

    printf("cha kong shi,ci shi de  u32Addr zhi wei:%x\n\r",addr);
    if (addr == 0)
    {
        /*如果偏移量为0，则整个区域都没有使用过，返回0xFFFFFFFF*/
        addr = 0xFFFFFFFFUL;
    }
    else if ((addr + u32StartAddr) > (u32EndAddr + 1U))
    {
        addr = 0;
    }
    /*返回当前内存区域内有多少字节的空间没有使用*/
    return addr;
}

