#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;
//    }
//  }
 
 /**
   * @brief  This function is executed in case of error occurrence.
   * @param  None
   * @retval None
   */
 void Test_APP_ErrorHandler(void)
 {
    while (1)
    {
    }
 }

