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

// #include "main.h"

// MileageData_un_t FlashData;


/*len是数组的长度*/
void Test_Flash_AppointAddress_Read(uint32_t u32Addr, uint32_t u32Data[], uint32_t u32Len)
{
    uint32_t addr = 0U;

    for (uint32_t i = 0U; i < u32Len; i++ )
    {
      u32Data[i] = HW32_REG(u32Addr + addr);
      addr += 4;
    }
    
    return ;
}

// uint32_t TestData[8] =
// {
//     0xABACADAE, 0x18176527, 0x90901990, 0xDDDDCCCC, 0x98765432, 0xAFA1A5A8, 0xC8C7C5C3, 0x20250227
// };

uint32_t TestData[8] =
{
    0x00000001, 0xABCDEF88, 0x10101010, 0x2B2B2B2B, 0x3C3C3C3C, 0xFEFEFEFE, 0x95959595, 0x20250304
};

uint32_t TestData1[8] =
{
    0xAAAAAAAA, 0xBBBBBBBB, 0xCCCCCCCC, 0xDDDDDDDD, 0xEEEEEEEE, 0xFFFFFFFF, 0x99999999, 0x20250304
};
uint32_t TestData2[8] =
{
    0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555, 0x66666666, 0x77777777, 0x88888888
};

void Test_Flash_AppointAddress_Write(uint32_t u32Addr, uint32_t u32Data[], uint32_t u32Len)
{
    // LoadBalancing_NVM_Data_st_t TestData;
    static uint32_t copyData[256];
    memset(copyData,0,sizeof(copyData));
    uint32_t flash_program_start = u32Addr;                /* flash program start address */
    uint32_t flash_program_end = 0U; // (SECTOR_15_START_ADDR + sizeof(TestData));  /* flash program end address */

    /* Unlock Flash */
    HAL_FLASH_Unlock();

    if (u32Len < 256u)
    {
      for(uint32_t i = 0; i < (256 / 4); i++)
      {
        copyData[i] = u32Data[i];
      }
    }
    flash_program_end = u32Addr + 256U;

    printf("flash_program_start:%x\n\r",flash_program_start);
    printf("flash_program_end:%x\n\r",flash_program_end);

    // uint32_t *src = (uint32_t *) &TestData;                                     /* Program data */
    uint32_t *src = (uint32_t *)copyData;
    while (flash_program_start < flash_program_end)
    {
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_PAGE, flash_program_start, src) == HAL_OK)/* Program */
        {
          printf("xie ru cheng gong le ,hahahahaha\n\r");
          flash_program_start += FLASH_PAGE_SIZE; /* flash Start point first page */
          src += FLASH_PAGE_SIZE / 4;             /* Update data point */
        }
        else
        {
          break;
        }
    }
    /* Lock Flash */
    HAL_FLASH_Lock();
    // EEPROM_Mem_Access_Complete_Callback();
}

void Test_Flash_AppointAddress_Erase(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 */
    {
        // APP_ErrorHandler();
        printf("shan qu ca chu shi bai le!!!!!!!!!\n\r");
        /* Lock Flash */
    }
    else
    {
      
      ;
    }
    /* Lock Flash */
    HAL_FLASH_Lock();
    // EEPROM_Mem_Access_Complete_Callback();
}

void Test_Flash_AppointSector_Erase(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 */
    {
        // APP_ErrorHandler();
        printf("shan qu ca chu shi bai le!!!!!!!!!\n\r");
        /* Lock Flash */
    }
    else
    {
        ;
    }
    /* Lock Flash */
    HAL_FLASH_Lock();
}

void Data_Create_Service(void)
{
    // LoadBalancing_NVM_Data_st_t TestData;
    // TestData.mileage1 = 0xABACADAE;
    // TestData.mileage2 = 0x18176527;
    // TestData.mileage3 = 0x90901990;
    // TestData.mileage4 = 0xDDDDCCCC;
    // TestData.maintenance1 = 0x98765432;
    // TestData.maintenance2 = 0xAFA1A5A8;
    // TestData.maintenance3 = 0xC8C7C5C3;
    // TestData.maintenance4 = 0x20250227;
}

/**
  * @brief  Flash Check
  * @param  None
  * @retval None
  */
 uint32_t Test_APP_FlashBlank(uint32_t u32StartAddr, uint32_t u32EndAddr)
{
    uint32_t addr = 0;
    uint32_t addroffset = 0U;
    uint8_t  blankFlag = 0U;
    // uint32_t u32Addr = 0xFFFFFFFFU;
    uint32_t Count = (u32EndAddr - u32StartAddr + 1) / 4;


    for (uint32_t i = 0; i < Count; i++)
    {
        if (0xFFFFFFFF == HW32_REG(u32StartAddr + addr))
        {
        addroffset = addr;
        for (uint32_t j = 0; j < 3; j++)
        {
            addroffset += 4;
            if (0xFFFFFFFF != 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);
    // return u32Addr;
    if (addr == 0)
    {
        /*如果偏移量为0，则整个区域都没有使用过，返回0xFFFFFFFF*/
        addr = 0xFFFFFFFF;
    }
    else if ((addr + u32StartAddr) > (u32EndAddr + 1U))
    {
        addr = 0;
    }
    /*返回当前内存区域内有多少字节的空间没有使用*/
    return addr;
}
 
 /**
   * @brief  Flash Verify
   * @param  None
   * @retval None
   */
// void Test_APP_FlashVerify(void)
//  {
//    uint32_t addr = 0;
 
//    while (addr < sizeof(DATA))
//    {
//      if (DATA[addr / 4] != HW32_REG(FLASH_USER_START_ADDR + addr))
//      {
//        APP_ErrorHandler();
//      }
//      addr += 4;
//    }
//  }





/*传入的数据长度需为字节数*/
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;
    }
}

/*传入的数据长度需为字节数*/
void 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
            {
                break;
            }
        }
        /* Lock Flash */
        HAL_FLASH_Lock();
    }
}

void 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 */
    {
        // APP_ErrorHandler();
        printf("shan qu ca chu shi bai le!!!!!!!!!\n\r");
        /* Lock Flash */
    }
    else
    {
        ;
    }
    /* Lock Flash */
    HAL_FLASH_Lock();
    // EEPROM_Mem_Access_Complete_Callback();
}

void 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 */
    {
        // APP_ErrorHandler();
        printf("shan qu ca chu shi bai le!!!!!!!!!\n\r");
        /* Lock Flash */
    }
    else
    {
        ;
    }
    /* Lock Flash */
    HAL_FLASH_Lock();
}

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 u32Addr = 0xFFFFFFFFU;
    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);
    // return u32Addr;
    if (addr == 0)
    {
        /*如果偏移量为0，则整个区域都没有使用过，返回0xFFFFFFFF*/
        addr = 0xFFFFFFFFUL;
    }
    else if ((addr + u32StartAddr) > (u32EndAddr + 1U))
    {
        addr = 0;
    }
    /*返回当前内存区域内有多少字节的空间没有使用*/
    return addr;
}



 /**
   * @brief  This function is executed in case of error occurrence.
   * @param  None
   * @retval None
   */
 void Test_APP_ErrorHandler(void)
 {
    while (1)
    {
    }
 }

