#include "Include.h"








 NVMUpdateCtrlStruct NVMUpdateCtrl;

 //¶AE?OC±i»u±??AI?//Ei?¬O???°?±??A?¬Aa???A
uint8_t Write_Base_DATA_FROM_FLASH(uint32_t Adrr, uint8_t *Data,uint8_t len)
{
    uint8_t status  = OK;
    status = DFLASH_Erase_Sector(Adrr);
    if(status!=OK)
    {
        status = ACCESS_ERROR;
    }
    else
    {
        status = DFLASH_N_Program(Adrr, Data, len);
        if(status != OK) 
        {
          status = ACCESS_ERROR;
        }
    }
  return status;/**/
}




void NVM_Init(void)
{
  uint8_t   i;
  uint8_t   j;
  
  uint8_t   *pData;
  uint8_t   *pDefaultValue;
  uint8_t   Len;
  
  #if NVM_USE_EEPROM
  
  uint8_t   Type;
  uint16_t  Addr;
    
  uint8_t   InitStatus;
  EEPROMAccessStatusEnum    Status;

  NVMUpdateCtrl.Enable  = 0;
  NVMUpdateCtrl.Current = 0xFF;             
  for (i = 0; i < NVM_TOTAL_DATA_NUM; i++)
    NVMUpdateCtrl.Req[i] = 0;
  
  pData  = NVMDataAttributeTable[NVM_INIT_DATA].pData;
  Len    = NVMDataAttributeTable[NVM_INIT_DATA].Len;
  Type   = NVMDataAttributeTable[NVM_INIT_DATA].DataType;
  Addr   = NVMDataAttributeTable[NVM_INIT_DATA].Addr;
  
  Status = EEPROM_Startup_Data_Read(Type, Addr, pData, Len);
  
  if (Status == EEPROM_DATA_OK)
  {
    NVM_EEPROM_FAULT = 0;
    InitStatus       = 1;
  }
  else if (Status == EEPROM_DATA_PARTIAL_LOST)
  {
    NVM_EEPROM_FAULT = 0;
    InitStatus       = 1;
    NVM_Data_Update(NVM_INIT_DATA);
  }
  else if (Status == EEPROM_DATA_LOST)
  {
    NVM_EEPROM_FAULT = 0;
    InitStatus       = 0;
  }
  else
  {
    NVM_EEPROM_FAULT = 1;
    InitStatus       = 0;
  }
  
  if (InitStatus)
  {
    i = 0;
    pDefaultValue = NVMDataAttributeTable[NVM_INIT_DATA].pDefaultValue;
    
    while (i < Len)
    {
      if (pData[i] != pDefaultValue[i])
      {
        InitStatus = 0;
        break;
      }
      
      i++;
    }
  }
  
  if (InitStatus)                                 //????????????»???,????????????¶???????
  {
   // #pragma MESSAGE DISABLE C4000 
    if (NVM_TOTAL_DATA_NUM > 1)
    {
      for (i = 1; i < NVM_TOTAL_DATA_NUM; i++)
      {
        pData  = NVMDataAttributeTable[i].pData;
        Len    = NVMDataAttributeTable[i].Len;
        Type   = NVMDataAttributeTable[i].DataType;
        Addr   = NVMDataAttributeTable[i].Addr;
  
        //¶???????
        Status = EEPROM_Startup_Data_Read(Type, Addr, pData, Len);    // NVMDataAttributeTable[i].pData?AAE
        
        if (Status == EEPROM_DATA_PARTIAL_LOST)   //??????·?¶??§,????¶???µ?????,????????????????
        {
          NVM_Data_Update(i);
        }
        else if (Status != EEPROM_DATA_OK)        //?????»??±»???¦¶???,?????¬???µ,????????????
        {
          pDefaultValue = NVMDataAttributeTable[i].pDefaultValue;
          
          for (j = 0; j < Len; j++)
            pData[j] = pDefaultValue[j];
          
          NVM_Data_Update(i);          
        }
      }
    }
  }
  else                                            //????????????»???,???????????¬???µ,??????????µ???????
  {
    for (i = 0; i < NVM_TOTAL_DATA_NUM; i++)
    {
      pData         = NVMDataAttributeTable[i].pData;
      pDefaultValue = NVMDataAttributeTable[i].pDefaultValue;
      Len           = NVMDataAttributeTable[i].Len;

      for (j = 0; j < Len; j++)
        pData[j] = pDefaultValue[j];
      
      NVM_Data_Update(i);
    }
  }
  
  #else                                             
    
  NVM_EEPROM_FAULT = 0;
  
  for (i = 0; i < NVM_TOTAL_DATA_NUM; i++)
  {
    pData         = NVMDataAttributeTable[i].pData;
    pDefaultValue = NVMDataAttributeTable[i].pDefaultValue;
    Len           = NVMDataAttributeTable[i].Len;

    for (j = 0; j < Len; j++)
      pData[j] = pDefaultValue[j];
  }
  
  #endif
}

void NVM_Data_Update(uint8_t DataName)
{
  #if NVM_USE_EEPROM
  
  if (NVM_EEPROM_FAULT == 0)                //????????????·???????
  {
    if (DataName < NVM_TOTAL_DATA_NUM)
    {
      NVMUpdateCtrl.Req[DataName] = 1;
      NVMUpdateCtrl.Enable = 1;
    }
  }
  
  #endif
}


void NVM_Data_Update_Service(void)
{
  #if NVM_USE_EEPROM
  uint8_t   i;
  uint8_t   *pData;
  uint8_t   Len;
  uint8_t   Type;
  uint16_t  Addr;
  
  EEPROMAccessStatusEnum Status;
  
  if (NVMUpdateCtrl.Enable)
  {
    if (NVMUpdateCtrl.Current < NVM_TOTAL_DATA_NUM)   //???­·?????????????
    {
      Status = EEPROM_Get_Data_Write_Status();
      
      if (Status == EEPROM_DATA_OK)                   //???????¦????,????????????
        NVMUpdateCtrl.Req[NVMUpdateCtrl.Current] = 0;
      else if (Status == EEPROM_MEMORY_BUSY)          //??????????????,?±??·µ»?
        return;
    }
    
    NVMUpdateCtrl.Current = 0xFF;
    
    //????????????µ?????,????????????????????????????»?????
    i = NVM_TOTAL_DATA_NUM;
    
    while (i)
    {
      i--;
      
      if (NVMUpdateCtrl.Req[i])
      {
        pData  = NVMDataAttributeTable[i].pData;
        Len    = NVMDataAttributeTable[i].Len;
        Type   = NVMDataAttributeTable[i].DataType;
        Addr   = NVMDataAttributeTable[i].Addr;
        
        Status = EEPROM_Data_Write(Type, Addr, pData, Len);
        
        if (Status == EEPROM_DATA_OK)
          NVMUpdateCtrl.Current = i;
        
        return;
      }
    }
    
    NVMUpdateCtrl.Enable  = 0;
  }
  
  #endif
}
void Delay_Ms(INT8U Time)
{
    INT16U Delay = Time;
    Delay *= 1000 / API_INT_CYCLE;
    Delay += API_ROLLING_COUNTER;
    while (Delay != API_ROLLING_COUNTER);
}