TI中文支持网
TI专业的中文技术问题搜集分享网站

28377d Flash 执行擦除后芯片复位

各位好,如题!
问题说明:将Flash用来实现设备参数掉电保存,待保存参数按顺序写入目标Flash sector中,本次写入不覆盖上次写入的区域,当本sector不足时,将sector擦除,从头开始写。现在的问题是,只要一执行erase操作,芯片就复位,programme写入操作却没有问题,请知情者协助~~

FLASH配置代码如下:
void InitFlash(void)
{
    EALLOW;
    //
    // Set VREADST to the proper value for the flash banks to power up
    // properly. This sets the bank power up delay.
    //
    Flash0CtrlRegs.FBAC.bit.VREADST = 0x14;
    //
    // At reset bank and pump are in sleep. A Flash access will power up the
    // bank and pump automatically.
    //
    // After a Flash access, bank and pump go to low power mode (configurable
    // in FBFALLBACK/FPAC1 registers) if there is no further access to flash.
    //
    // Power up Flash bank and pump. This also sets the fall back mode of
    // flash and pump as active.
    //
    Flash0CtrlRegs.FPAC1.bit.PMPPWR = 0x1;
    Flash0CtrlRegs.FBFALLBACK.bit.BNKPWR0 = 0x3;
    //
    // Disable Cache and prefetch mechanism before changing wait states
    //
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 0;
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 0;
    //
    // Set waitstates according to frequency
    //
    //      *CAUTION*
    // Minimum waitstates required for the flash operating at a given CPU rate
    // must be characterized by TI. Refer to the datasheet for the latest
    // information.
    //
    #if CPU_FRQ_200MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x3;
    #endif
    #if CPU_FRQ_150MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
    #endif
    #if CPU_FRQ_120MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
    #endif
    //
    // Enable Cache and prefetch mechanism to improve performance of code
    // executed from Flash.
    //
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 1;
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 1;
    //
    // At reset, ECC is enabled. If it is disabled by application software and
    // if application again wants to enable ECC.
    //
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    EDIS;
    //
    // Force a pipeline flush to ensure that the write to the last register
    // configured occurs before returning.
    //
    __asm(" RPT #7 || NOP");
}

//
// SeizeFlashPump – Wait until the flash pump is available. Then take control
//                  of it using the flash pump Semaphore.
//
void SeizeFlashPump(void)
{
    EALLOW;
    #ifdef CPU1
        while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x2)
        {
            FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x2;
        }
    #elif defined(CPU2)
        while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x1)
        {
            FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x1;
        }
    #endif
    EDIS;
}

//
// Init_Flash_Sectors – Initialize flash API and active flash bank sectors
//
void Init_Flash_Sectors(void)
{
    EALLOW;
    Flash0EccRegs.ERR_THRESHOLD.bit.ERR_THRESHOLD = 0x1;
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0x0;
    Fapi_StatusType oReturnCheck;
    //
    // This function is required to initialize the Flash API based on System
    // frequency before any other Flash API operation can be performed
    //
    oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 200);
    if(oReturnCheck != Fapi_Status_Success)
    {
        Example_Error(oReturnCheck);
    }
    //
    // Fapi_setActiveFlashBank function sets the Flash bank and FMC for further
    // Flash operations to be performed on the bank
    //
    oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    if(oReturnCheck != Fapi_Status_Success)
    {
        Example_Error(oReturnCheck);
    }
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    EDIS;
}

erase和programme操作如下:
#pragma CODE_SECTION(StoreData2Flash, ramFuncSection);
int StoreData2Flash(Uint16 *start, Uint32 size, Uint16 sector)
{
//1. declare the variables used for programming flash
    Fapi_StatusType oReturnCheck = 0;// Status structure
    Fapi_FlashStatusWordType oFlashStatusWord;
    volatile Fapi_FlashStatusType oFlashStatus;
    uint32 u32Index = 0;
    uint16 i = 0;
Uint32 lTemp;
Uint32 lSectorAddr;
uint32 *Buffer32 = (uint32 *)start;
    EALLOW;
DINT;  // disable global interrupt
//2. check if the sector storing data record is full. if yes then erase the sector
switch(sector)
{
  case SECTORK: lSectorAddr = Bzero_SectorK_start; break;
  case SECTORL: lSectorAddr = Bzero_SectorL_start; break;
  case SECTORM: lSectorAddr = Bzero_SectorM_start; break;
  case SECTORN: lSectorAddr = Bzero_SectorN_start; break;
  default:   EINT;
  return 1;
}
lTemp = lSectorAddr;
//  search for the most recent data ration record in flash
while(*(unsigned long*)lTemp != 0xFFFFFFFF)  // the value at lTemp is not 0xFFFFFFFF which means the location at lTemp is not programmed with some value
{
  lTemp += size;
}
if(lSectorAddr + 0x2000 – lTemp < size) // if the flash is full, erase the sector
{
     // Erase Sector
  //
  oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(uint32 *)lSectorAddr);
   // Wait until FSM is done with erase sector operation
  while(Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
      // Verify that SectorL is erased.  The Erase step itself does a
      // verify as it goes.  This verify is a 2nd verification that can be done.
  oReturnCheck = Fapi_doBlankCheck((uint32 *)lSectorAddr,Bzero_16KSector_u32length,&oFlashStatusWord);
  if(oReturnCheck != Fapi_Status_Success)
  {
      EINT;
   return 1;
   }
  lTemp = lSectorAddr;
}
//3. program the data record to flash
    for(i=0, u32Index = lTemp;
       (u32Index < (lTemp + size)) &&
       (oReturnCheck == Fapi_Status_Success); i+= 8, u32Index+= 8)
    {
  oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,start+i,
              8,
              0,
              0,
              Fapi_AutoEccGeneration);
  while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);
  if(oReturnCheck != Fapi_Status_Success)
  {
   //
   // Check Flash API documentation for possible errors
   //
   EINT;
   return 1;
  }
  //
  // Read FMSTAT register contents to know the status of FSM after
  // program command for any debug
  //
  oFlashStatus = Fapi_getFsmStatus();
  //
  // Verify the values programmed.  The Program step itself does a verify
  // as it goes.  This verify is a 2nd verification that can be done.
  //
  oReturnCheck = Fapi_doVerify((uint32 *)u32Index,
          4, Buffer32+(i/2),
          &oFlashStatusWord);
  if(oReturnCheck != Fapi_Status_Success)
  {
   //
   // Check Flash API documentation for possible errors
   //
   EINT;
   return 1;
  }
    }
EINT;
return 0;
}

Eric Ma:"问题说明:将Flash用来实现设备参数掉电保存,待保存参数按顺序写入目标Flash sector中,本次写入不覆盖上次写入的区域,当本sector不足时,将sector擦除,从头开始写。现在的问题是,只要一执行erase操作,芯片就复位,programme写入操作却没有问题,请知情者协助~"

ERIC:
有没有把flash API的函数都放到RAM中运行。
另外,flash的擦出是按扇区擦除的。GROUP{ramfuncs{ -l F021_API_F2837xS_FPU32.lib}} LOAD = FLASHD,RUN= RAMLS03, LOAD_START(_RamfuncsLoadStart),LOAD_SIZE(_RamfuncsLoadSize),LOAD_END(_RamfuncsLoadEnd),RUN_START(_RamfuncsRunStart),RUN_SIZE(_RamfuncsRunSize),RUN_END(_RamfuncsRunEnd),PAGE = 0

各位好,如题!
问题说明:将Flash用来实现设备参数掉电保存,待保存参数按顺序写入目标Flash sector中,本次写入不覆盖上次写入的区域,当本sector不足时,将sector擦除,从头开始写。现在的问题是,只要一执行erase操作,芯片就复位,programme写入操作却没有问题,请知情者协助~~

FLASH配置代码如下:
void InitFlash(void)
{
    EALLOW;
    //
    // Set VREADST to the proper value for the flash banks to power up
    // properly. This sets the bank power up delay.
    //
    Flash0CtrlRegs.FBAC.bit.VREADST = 0x14;
    //
    // At reset bank and pump are in sleep. A Flash access will power up the
    // bank and pump automatically.
    //
    // After a Flash access, bank and pump go to low power mode (configurable
    // in FBFALLBACK/FPAC1 registers) if there is no further access to flash.
    //
    // Power up Flash bank and pump. This also sets the fall back mode of
    // flash and pump as active.
    //
    Flash0CtrlRegs.FPAC1.bit.PMPPWR = 0x1;
    Flash0CtrlRegs.FBFALLBACK.bit.BNKPWR0 = 0x3;
    //
    // Disable Cache and prefetch mechanism before changing wait states
    //
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 0;
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 0;
    //
    // Set waitstates according to frequency
    //
    //      *CAUTION*
    // Minimum waitstates required for the flash operating at a given CPU rate
    // must be characterized by TI. Refer to the datasheet for the latest
    // information.
    //
    #if CPU_FRQ_200MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x3;
    #endif
    #if CPU_FRQ_150MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
    #endif
    #if CPU_FRQ_120MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
    #endif
    //
    // Enable Cache and prefetch mechanism to improve performance of code
    // executed from Flash.
    //
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 1;
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 1;
    //
    // At reset, ECC is enabled. If it is disabled by application software and
    // if application again wants to enable ECC.
    //
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    EDIS;
    //
    // Force a pipeline flush to ensure that the write to the last register
    // configured occurs before returning.
    //
    __asm(" RPT #7 || NOP");
}

//
// SeizeFlashPump – Wait until the flash pump is available. Then take control
//                  of it using the flash pump Semaphore.
//
void SeizeFlashPump(void)
{
    EALLOW;
    #ifdef CPU1
        while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x2)
        {
            FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x2;
        }
    #elif defined(CPU2)
        while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x1)
        {
            FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x1;
        }
    #endif
    EDIS;
}

//
// Init_Flash_Sectors – Initialize flash API and active flash bank sectors
//
void Init_Flash_Sectors(void)
{
    EALLOW;
    Flash0EccRegs.ERR_THRESHOLD.bit.ERR_THRESHOLD = 0x1;
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0x0;
    Fapi_StatusType oReturnCheck;
    //
    // This function is required to initialize the Flash API based on System
    // frequency before any other Flash API operation can be performed
    //
    oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 200);
    if(oReturnCheck != Fapi_Status_Success)
    {
        Example_Error(oReturnCheck);
    }
    //
    // Fapi_setActiveFlashBank function sets the Flash bank and FMC for further
    // Flash operations to be performed on the bank
    //
    oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    if(oReturnCheck != Fapi_Status_Success)
    {
        Example_Error(oReturnCheck);
    }
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    EDIS;
}

erase和programme操作如下:
#pragma CODE_SECTION(StoreData2Flash, ramFuncSection);
int StoreData2Flash(Uint16 *start, Uint32 size, Uint16 sector)
{
//1. declare the variables used for programming flash
    Fapi_StatusType oReturnCheck = 0;// Status structure
    Fapi_FlashStatusWordType oFlashStatusWord;
    volatile Fapi_FlashStatusType oFlashStatus;
    uint32 u32Index = 0;
    uint16 i = 0;
Uint32 lTemp;
Uint32 lSectorAddr;
uint32 *Buffer32 = (uint32 *)start;
    EALLOW;
DINT;  // disable global interrupt
//2. check if the sector storing data record is full. if yes then erase the sector
switch(sector)
{
  case SECTORK: lSectorAddr = Bzero_SectorK_start; break;
  case SECTORL: lSectorAddr = Bzero_SectorL_start; break;
  case SECTORM: lSectorAddr = Bzero_SectorM_start; break;
  case SECTORN: lSectorAddr = Bzero_SectorN_start; break;
  default:   EINT;
  return 1;
}
lTemp = lSectorAddr;
//  search for the most recent data ration record in flash
while(*(unsigned long*)lTemp != 0xFFFFFFFF)  // the value at lTemp is not 0xFFFFFFFF which means the location at lTemp is not programmed with some value
{
  lTemp += size;
}
if(lSectorAddr + 0x2000 – lTemp < size) // if the flash is full, erase the sector
{
     // Erase Sector
  //
  oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(uint32 *)lSectorAddr);
   // Wait until FSM is done with erase sector operation
  while(Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
      // Verify that SectorL is erased.  The Erase step itself does a
      // verify as it goes.  This verify is a 2nd verification that can be done.
  oReturnCheck = Fapi_doBlankCheck((uint32 *)lSectorAddr,Bzero_16KSector_u32length,&oFlashStatusWord);
  if(oReturnCheck != Fapi_Status_Success)
  {
      EINT;
   return 1;
   }
  lTemp = lSectorAddr;
}
//3. program the data record to flash
    for(i=0, u32Index = lTemp;
       (u32Index < (lTemp + size)) &&
       (oReturnCheck == Fapi_Status_Success); i+= 8, u32Index+= 8)
    {
  oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,start+i,
              8,
              0,
              0,
              Fapi_AutoEccGeneration);
  while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);
  if(oReturnCheck != Fapi_Status_Success)
  {
   //
   // Check Flash API documentation for possible errors
   //
   EINT;
   return 1;
  }
  //
  // Read FMSTAT register contents to know the status of FSM after
  // program command for any debug
  //
  oFlashStatus = Fapi_getFsmStatus();
  //
  // Verify the values programmed.  The Program step itself does a verify
  // as it goes.  This verify is a 2nd verification that can be done.
  //
  oReturnCheck = Fapi_doVerify((uint32 *)u32Index,
          4, Buffer32+(i/2),
          &oFlashStatusWord);
  if(oReturnCheck != Fapi_Status_Success)
  {
   //
   // Check Flash API documentation for possible errors
   //
   EINT;
   return 1;
  }
    }
EINT;
return 0;
}

Eric Ma:"问题说明:将Flash用来实现设备参数掉电保存,待保存参数按顺序写入目标Flash sector中,本次写入不覆盖上次写入的区域,当本sector不足时,将sector擦除,从头开始写。现在的问题是,只要一执行erase操作,芯片就复位,programme写入操作却没有问题,请知情者协助~"

ERIC:
有没有把flash API的函数都放到RAM中运行。
另外,flash的擦出是按扇区擦除的。GROUP{ramfuncs{ -l F021_API_F2837xS_FPU32.lib}} LOAD = FLASHD,RUN= RAMLS03, LOAD_START(_RamfuncsLoadStart),LOAD_SIZE(_RamfuncsLoadSize),LOAD_END(_RamfuncsLoadEnd),RUN_START(_RamfuncsRunStart),RUN_SIZE(_RamfuncsRunSize),RUN_END(_RamfuncsRunEnd),PAGE = 0

各位好,如题!
问题说明:将Flash用来实现设备参数掉电保存,待保存参数按顺序写入目标Flash sector中,本次写入不覆盖上次写入的区域,当本sector不足时,将sector擦除,从头开始写。现在的问题是,只要一执行erase操作,芯片就复位,programme写入操作却没有问题,请知情者协助~~

FLASH配置代码如下:
void InitFlash(void)
{
    EALLOW;
    //
    // Set VREADST to the proper value for the flash banks to power up
    // properly. This sets the bank power up delay.
    //
    Flash0CtrlRegs.FBAC.bit.VREADST = 0x14;
    //
    // At reset bank and pump are in sleep. A Flash access will power up the
    // bank and pump automatically.
    //
    // After a Flash access, bank and pump go to low power mode (configurable
    // in FBFALLBACK/FPAC1 registers) if there is no further access to flash.
    //
    // Power up Flash bank and pump. This also sets the fall back mode of
    // flash and pump as active.
    //
    Flash0CtrlRegs.FPAC1.bit.PMPPWR = 0x1;
    Flash0CtrlRegs.FBFALLBACK.bit.BNKPWR0 = 0x3;
    //
    // Disable Cache and prefetch mechanism before changing wait states
    //
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 0;
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 0;
    //
    // Set waitstates according to frequency
    //
    //      *CAUTION*
    // Minimum waitstates required for the flash operating at a given CPU rate
    // must be characterized by TI. Refer to the datasheet for the latest
    // information.
    //
    #if CPU_FRQ_200MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x3;
    #endif
    #if CPU_FRQ_150MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
    #endif
    #if CPU_FRQ_120MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
    #endif
    //
    // Enable Cache and prefetch mechanism to improve performance of code
    // executed from Flash.
    //
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 1;
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 1;
    //
    // At reset, ECC is enabled. If it is disabled by application software and
    // if application again wants to enable ECC.
    //
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    EDIS;
    //
    // Force a pipeline flush to ensure that the write to the last register
    // configured occurs before returning.
    //
    __asm(" RPT #7 || NOP");
}

//
// SeizeFlashPump – Wait until the flash pump is available. Then take control
//                  of it using the flash pump Semaphore.
//
void SeizeFlashPump(void)
{
    EALLOW;
    #ifdef CPU1
        while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x2)
        {
            FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x2;
        }
    #elif defined(CPU2)
        while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x1)
        {
            FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x1;
        }
    #endif
    EDIS;
}

//
// Init_Flash_Sectors – Initialize flash API and active flash bank sectors
//
void Init_Flash_Sectors(void)
{
    EALLOW;
    Flash0EccRegs.ERR_THRESHOLD.bit.ERR_THRESHOLD = 0x1;
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0x0;
    Fapi_StatusType oReturnCheck;
    //
    // This function is required to initialize the Flash API based on System
    // frequency before any other Flash API operation can be performed
    //
    oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 200);
    if(oReturnCheck != Fapi_Status_Success)
    {
        Example_Error(oReturnCheck);
    }
    //
    // Fapi_setActiveFlashBank function sets the Flash bank and FMC for further
    // Flash operations to be performed on the bank
    //
    oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    if(oReturnCheck != Fapi_Status_Success)
    {
        Example_Error(oReturnCheck);
    }
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    EDIS;
}

erase和programme操作如下:
#pragma CODE_SECTION(StoreData2Flash, ramFuncSection);
int StoreData2Flash(Uint16 *start, Uint32 size, Uint16 sector)
{
//1. declare the variables used for programming flash
    Fapi_StatusType oReturnCheck = 0;// Status structure
    Fapi_FlashStatusWordType oFlashStatusWord;
    volatile Fapi_FlashStatusType oFlashStatus;
    uint32 u32Index = 0;
    uint16 i = 0;
Uint32 lTemp;
Uint32 lSectorAddr;
uint32 *Buffer32 = (uint32 *)start;
    EALLOW;
DINT;  // disable global interrupt
//2. check if the sector storing data record is full. if yes then erase the sector
switch(sector)
{
  case SECTORK: lSectorAddr = Bzero_SectorK_start; break;
  case SECTORL: lSectorAddr = Bzero_SectorL_start; break;
  case SECTORM: lSectorAddr = Bzero_SectorM_start; break;
  case SECTORN: lSectorAddr = Bzero_SectorN_start; break;
  default:   EINT;
  return 1;
}
lTemp = lSectorAddr;
//  search for the most recent data ration record in flash
while(*(unsigned long*)lTemp != 0xFFFFFFFF)  // the value at lTemp is not 0xFFFFFFFF which means the location at lTemp is not programmed with some value
{
  lTemp += size;
}
if(lSectorAddr + 0x2000 – lTemp < size) // if the flash is full, erase the sector
{
     // Erase Sector
  //
  oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(uint32 *)lSectorAddr);
   // Wait until FSM is done with erase sector operation
  while(Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
      // Verify that SectorL is erased.  The Erase step itself does a
      // verify as it goes.  This verify is a 2nd verification that can be done.
  oReturnCheck = Fapi_doBlankCheck((uint32 *)lSectorAddr,Bzero_16KSector_u32length,&oFlashStatusWord);
  if(oReturnCheck != Fapi_Status_Success)
  {
      EINT;
   return 1;
   }
  lTemp = lSectorAddr;
}
//3. program the data record to flash
    for(i=0, u32Index = lTemp;
       (u32Index < (lTemp + size)) &&
       (oReturnCheck == Fapi_Status_Success); i+= 8, u32Index+= 8)
    {
  oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,start+i,
              8,
              0,
              0,
              Fapi_AutoEccGeneration);
  while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);
  if(oReturnCheck != Fapi_Status_Success)
  {
   //
   // Check Flash API documentation for possible errors
   //
   EINT;
   return 1;
  }
  //
  // Read FMSTAT register contents to know the status of FSM after
  // program command for any debug
  //
  oFlashStatus = Fapi_getFsmStatus();
  //
  // Verify the values programmed.  The Program step itself does a verify
  // as it goes.  This verify is a 2nd verification that can be done.
  //
  oReturnCheck = Fapi_doVerify((uint32 *)u32Index,
          4, Buffer32+(i/2),
          &oFlashStatusWord);
  if(oReturnCheck != Fapi_Status_Success)
  {
   //
   // Check Flash API documentation for possible errors
   //
   EINT;
   return 1;
  }
    }
EINT;
return 0;
}

user5253370:

回复 Eric Ma:

多谢回复~ 你提到的这点,我检查了,已经把flash的API放到RAM了,如下: 但问题还是没有消失~ RAMGS8_11 : origin = 0x014000, length = 0x004000 #ifdef __TI_COMPILER_VERSION__ #if __TI_COMPILER_VERSION__ >= 15009000 GROUP { .TI.ramfunc { -l F021_API_F2837xD_FPU32.lib} } LOAD = FLASHA, RUN = RAMGS8_11, LOAD_START(_RamfuncsLoadStart), LOAD_SIZE(_RamfuncsLoadSize), LOAD_END(_RamfuncsLoadEnd), RUN_START(_RamfuncsRunStart), RUN_SIZE(_RamfuncsRunSize), RUN_END(_RamfuncsRunEnd), PAGE = 0 #else GROUP { ramfuncs { -l F021_API_F2837xD_FPU32.lib} } LOAD = FLASHA, RUN = RAMGS8_11, LOAD_START(_RamfuncsLoadStart), LOAD_SIZE(_RamfuncsLoadSize), LOAD_END(_RamfuncsLoadEnd), RUN_START(_RamfuncsRunStart), RUN_SIZE(_RamfuncsRunSize), RUN_END(_RamfuncsRunEnd), PAGE = 0 #endif #endif

编译后的map文件如下:

.TI.ramfunc * 0 00080002 00000895 RUN ADDR = 00015d82 00080002 00000259 F021_API_F2837xD_FPU32.lib : FlashStateMachine.obj (.text:__Fapi_setupFlashStateMachine) 0008025b 0000019d : Program.obj (.text:_Fapi_issueProgrammingCommand) 000803f8 00000088 : Read.obj (.text:__Fapi_loopRegionForValue) 00080480 0000007f : Read.obj (.text:__Fapi_checkRegionForValue) 000804ff 00000042 : BlankCheck.obj (.text:_Fapi_doBlankCheck) 00080541 00000034 : Init.obj (.text:_Fapi_initializeAPI) 00080575 0000002e : Utilities.obj (.text:_Fapi_calculateFletcherChecksum) 000805a3 0000002d : FlashStateMachine.obj (.text:__Fapi_issueFsmCommand) 000805d0 0000002c : Utilities.obj (.text:__Fapi_divideUnsignedLong) 000805fc 00000025 : FlashStateMachine.obj (.text:_Fapi_setActiveFlashBank) 00080621 00000022 : FlashStateMachine.obj (.text:_Fapi_isAddressEcc) 00080643 00000022 : FlashStateMachine.obj (.text:__Fapi_setupSectorsForWrite) 00080665 00000020 : Async.obj (.text:_Fapi_issueAsyncCommandWithAddress) 00080685 0000001a : Utilities.obj (.text:_Fapi_waitDelay) 0008069f 00000016 : Read.obj (.text:_Fapi_flushPipeline) 000806b5 0000000f : Verify.obj (.text:_Fapi_doVerify) 000806c4 0000000d : Utilities.obj (.text:__Fapi_scaleCycleValues) 000806d1 00000001 –HOLE– [fill = 0] 000806d2 0000000c : Init.obj (.ebss) [fill = 0] 000806de 0000000b : Utilities.obj (.text:__Fapi_calculateOtpChecksum) 000806e9 0000000a : FlashStateMachine.obj (.text:_Fapi_checkFsmForReady) 000806f3 00000006 : FlashStateMachine.obj (.text:_Fapi_getFsmStatus) 000806f9 000000be App_Setting.obj (.TI.ramfunc) 000807b7 00000094 Fapi_UserDefinedFunctions.obj (.TI.ramfunc) 0008084b 00000048 F2837xD_SysCtrl.obj (.TI.ramfunc) 00080893 00000004 F2837xD_usDelay.obj (.TI.ramfunc)

各位好,如题!
问题说明:将Flash用来实现设备参数掉电保存,待保存参数按顺序写入目标Flash sector中,本次写入不覆盖上次写入的区域,当本sector不足时,将sector擦除,从头开始写。现在的问题是,只要一执行erase操作,芯片就复位,programme写入操作却没有问题,请知情者协助~~

FLASH配置代码如下:
void InitFlash(void)
{
    EALLOW;
    //
    // Set VREADST to the proper value for the flash banks to power up
    // properly. This sets the bank power up delay.
    //
    Flash0CtrlRegs.FBAC.bit.VREADST = 0x14;
    //
    // At reset bank and pump are in sleep. A Flash access will power up the
    // bank and pump automatically.
    //
    // After a Flash access, bank and pump go to low power mode (configurable
    // in FBFALLBACK/FPAC1 registers) if there is no further access to flash.
    //
    // Power up Flash bank and pump. This also sets the fall back mode of
    // flash and pump as active.
    //
    Flash0CtrlRegs.FPAC1.bit.PMPPWR = 0x1;
    Flash0CtrlRegs.FBFALLBACK.bit.BNKPWR0 = 0x3;
    //
    // Disable Cache and prefetch mechanism before changing wait states
    //
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 0;
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 0;
    //
    // Set waitstates according to frequency
    //
    //      *CAUTION*
    // Minimum waitstates required for the flash operating at a given CPU rate
    // must be characterized by TI. Refer to the datasheet for the latest
    // information.
    //
    #if CPU_FRQ_200MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x3;
    #endif
    #if CPU_FRQ_150MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
    #endif
    #if CPU_FRQ_120MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
    #endif
    //
    // Enable Cache and prefetch mechanism to improve performance of code
    // executed from Flash.
    //
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 1;
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 1;
    //
    // At reset, ECC is enabled. If it is disabled by application software and
    // if application again wants to enable ECC.
    //
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    EDIS;
    //
    // Force a pipeline flush to ensure that the write to the last register
    // configured occurs before returning.
    //
    __asm(" RPT #7 || NOP");
}

//
// SeizeFlashPump – Wait until the flash pump is available. Then take control
//                  of it using the flash pump Semaphore.
//
void SeizeFlashPump(void)
{
    EALLOW;
    #ifdef CPU1
        while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x2)
        {
            FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x2;
        }
    #elif defined(CPU2)
        while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x1)
        {
            FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x1;
        }
    #endif
    EDIS;
}

//
// Init_Flash_Sectors – Initialize flash API and active flash bank sectors
//
void Init_Flash_Sectors(void)
{
    EALLOW;
    Flash0EccRegs.ERR_THRESHOLD.bit.ERR_THRESHOLD = 0x1;
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0x0;
    Fapi_StatusType oReturnCheck;
    //
    // This function is required to initialize the Flash API based on System
    // frequency before any other Flash API operation can be performed
    //
    oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 200);
    if(oReturnCheck != Fapi_Status_Success)
    {
        Example_Error(oReturnCheck);
    }
    //
    // Fapi_setActiveFlashBank function sets the Flash bank and FMC for further
    // Flash operations to be performed on the bank
    //
    oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    if(oReturnCheck != Fapi_Status_Success)
    {
        Example_Error(oReturnCheck);
    }
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    EDIS;
}

erase和programme操作如下:
#pragma CODE_SECTION(StoreData2Flash, ramFuncSection);
int StoreData2Flash(Uint16 *start, Uint32 size, Uint16 sector)
{
//1. declare the variables used for programming flash
    Fapi_StatusType oReturnCheck = 0;// Status structure
    Fapi_FlashStatusWordType oFlashStatusWord;
    volatile Fapi_FlashStatusType oFlashStatus;
    uint32 u32Index = 0;
    uint16 i = 0;
Uint32 lTemp;
Uint32 lSectorAddr;
uint32 *Buffer32 = (uint32 *)start;
    EALLOW;
DINT;  // disable global interrupt
//2. check if the sector storing data record is full. if yes then erase the sector
switch(sector)
{
  case SECTORK: lSectorAddr = Bzero_SectorK_start; break;
  case SECTORL: lSectorAddr = Bzero_SectorL_start; break;
  case SECTORM: lSectorAddr = Bzero_SectorM_start; break;
  case SECTORN: lSectorAddr = Bzero_SectorN_start; break;
  default:   EINT;
  return 1;
}
lTemp = lSectorAddr;
//  search for the most recent data ration record in flash
while(*(unsigned long*)lTemp != 0xFFFFFFFF)  // the value at lTemp is not 0xFFFFFFFF which means the location at lTemp is not programmed with some value
{
  lTemp += size;
}
if(lSectorAddr + 0x2000 – lTemp < size) // if the flash is full, erase the sector
{
     // Erase Sector
  //
  oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(uint32 *)lSectorAddr);
   // Wait until FSM is done with erase sector operation
  while(Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
      // Verify that SectorL is erased.  The Erase step itself does a
      // verify as it goes.  This verify is a 2nd verification that can be done.
  oReturnCheck = Fapi_doBlankCheck((uint32 *)lSectorAddr,Bzero_16KSector_u32length,&oFlashStatusWord);
  if(oReturnCheck != Fapi_Status_Success)
  {
      EINT;
   return 1;
   }
  lTemp = lSectorAddr;
}
//3. program the data record to flash
    for(i=0, u32Index = lTemp;
       (u32Index < (lTemp + size)) &&
       (oReturnCheck == Fapi_Status_Success); i+= 8, u32Index+= 8)
    {
  oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,start+i,
              8,
              0,
              0,
              Fapi_AutoEccGeneration);
  while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);
  if(oReturnCheck != Fapi_Status_Success)
  {
   //
   // Check Flash API documentation for possible errors
   //
   EINT;
   return 1;
  }
  //
  // Read FMSTAT register contents to know the status of FSM after
  // program command for any debug
  //
  oFlashStatus = Fapi_getFsmStatus();
  //
  // Verify the values programmed.  The Program step itself does a verify
  // as it goes.  This verify is a 2nd verification that can be done.
  //
  oReturnCheck = Fapi_doVerify((uint32 *)u32Index,
          4, Buffer32+(i/2),
          &oFlashStatusWord);
  if(oReturnCheck != Fapi_Status_Success)
  {
   //
   // Check Flash API documentation for possible errors
   //
   EINT;
   return 1;
  }
    }
EINT;
return 0;
}

Eric Ma:

回复 user5253370:

在擦除的时候,有没有把中断关掉。建议整个flash操作过程都关掉FLASH API。
另外,从排查问题的角度上来讲,建议屏蔽掉一些代码,只做擦出操作。进行对比测试。
还有,和例程做进一步对比。
C:\ti\controlSUITE\device_support\F2837xD\v210\F2837xD_examples_Dual\flash_programming
ERIC

各位好,如题!
问题说明:将Flash用来实现设备参数掉电保存,待保存参数按顺序写入目标Flash sector中,本次写入不覆盖上次写入的区域,当本sector不足时,将sector擦除,从头开始写。现在的问题是,只要一执行erase操作,芯片就复位,programme写入操作却没有问题,请知情者协助~~

FLASH配置代码如下:
void InitFlash(void)
{
    EALLOW;
    //
    // Set VREADST to the proper value for the flash banks to power up
    // properly. This sets the bank power up delay.
    //
    Flash0CtrlRegs.FBAC.bit.VREADST = 0x14;
    //
    // At reset bank and pump are in sleep. A Flash access will power up the
    // bank and pump automatically.
    //
    // After a Flash access, bank and pump go to low power mode (configurable
    // in FBFALLBACK/FPAC1 registers) if there is no further access to flash.
    //
    // Power up Flash bank and pump. This also sets the fall back mode of
    // flash and pump as active.
    //
    Flash0CtrlRegs.FPAC1.bit.PMPPWR = 0x1;
    Flash0CtrlRegs.FBFALLBACK.bit.BNKPWR0 = 0x3;
    //
    // Disable Cache and prefetch mechanism before changing wait states
    //
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 0;
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 0;
    //
    // Set waitstates according to frequency
    //
    //      *CAUTION*
    // Minimum waitstates required for the flash operating at a given CPU rate
    // must be characterized by TI. Refer to the datasheet for the latest
    // information.
    //
    #if CPU_FRQ_200MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x3;
    #endif
    #if CPU_FRQ_150MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
    #endif
    #if CPU_FRQ_120MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
    #endif
    //
    // Enable Cache and prefetch mechanism to improve performance of code
    // executed from Flash.
    //
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 1;
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 1;
    //
    // At reset, ECC is enabled. If it is disabled by application software and
    // if application again wants to enable ECC.
    //
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    EDIS;
    //
    // Force a pipeline flush to ensure that the write to the last register
    // configured occurs before returning.
    //
    __asm(" RPT #7 || NOP");
}

//
// SeizeFlashPump – Wait until the flash pump is available. Then take control
//                  of it using the flash pump Semaphore.
//
void SeizeFlashPump(void)
{
    EALLOW;
    #ifdef CPU1
        while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x2)
        {
            FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x2;
        }
    #elif defined(CPU2)
        while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x1)
        {
            FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x1;
        }
    #endif
    EDIS;
}

//
// Init_Flash_Sectors – Initialize flash API and active flash bank sectors
//
void Init_Flash_Sectors(void)
{
    EALLOW;
    Flash0EccRegs.ERR_THRESHOLD.bit.ERR_THRESHOLD = 0x1;
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0x0;
    Fapi_StatusType oReturnCheck;
    //
    // This function is required to initialize the Flash API based on System
    // frequency before any other Flash API operation can be performed
    //
    oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 200);
    if(oReturnCheck != Fapi_Status_Success)
    {
        Example_Error(oReturnCheck);
    }
    //
    // Fapi_setActiveFlashBank function sets the Flash bank and FMC for further
    // Flash operations to be performed on the bank
    //
    oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    if(oReturnCheck != Fapi_Status_Success)
    {
        Example_Error(oReturnCheck);
    }
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    EDIS;
}

erase和programme操作如下:
#pragma CODE_SECTION(StoreData2Flash, ramFuncSection);
int StoreData2Flash(Uint16 *start, Uint32 size, Uint16 sector)
{
//1. declare the variables used for programming flash
    Fapi_StatusType oReturnCheck = 0;// Status structure
    Fapi_FlashStatusWordType oFlashStatusWord;
    volatile Fapi_FlashStatusType oFlashStatus;
    uint32 u32Index = 0;
    uint16 i = 0;
Uint32 lTemp;
Uint32 lSectorAddr;
uint32 *Buffer32 = (uint32 *)start;
    EALLOW;
DINT;  // disable global interrupt
//2. check if the sector storing data record is full. if yes then erase the sector
switch(sector)
{
  case SECTORK: lSectorAddr = Bzero_SectorK_start; break;
  case SECTORL: lSectorAddr = Bzero_SectorL_start; break;
  case SECTORM: lSectorAddr = Bzero_SectorM_start; break;
  case SECTORN: lSectorAddr = Bzero_SectorN_start; break;
  default:   EINT;
  return 1;
}
lTemp = lSectorAddr;
//  search for the most recent data ration record in flash
while(*(unsigned long*)lTemp != 0xFFFFFFFF)  // the value at lTemp is not 0xFFFFFFFF which means the location at lTemp is not programmed with some value
{
  lTemp += size;
}
if(lSectorAddr + 0x2000 – lTemp < size) // if the flash is full, erase the sector
{
     // Erase Sector
  //
  oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(uint32 *)lSectorAddr);
   // Wait until FSM is done with erase sector operation
  while(Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
      // Verify that SectorL is erased.  The Erase step itself does a
      // verify as it goes.  This verify is a 2nd verification that can be done.
  oReturnCheck = Fapi_doBlankCheck((uint32 *)lSectorAddr,Bzero_16KSector_u32length,&oFlashStatusWord);
  if(oReturnCheck != Fapi_Status_Success)
  {
      EINT;
   return 1;
   }
  lTemp = lSectorAddr;
}
//3. program the data record to flash
    for(i=0, u32Index = lTemp;
       (u32Index < (lTemp + size)) &&
       (oReturnCheck == Fapi_Status_Success); i+= 8, u32Index+= 8)
    {
  oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,start+i,
              8,
              0,
              0,
              Fapi_AutoEccGeneration);
  while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);
  if(oReturnCheck != Fapi_Status_Success)
  {
   //
   // Check Flash API documentation for possible errors
   //
   EINT;
   return 1;
  }
  //
  // Read FMSTAT register contents to know the status of FSM after
  // program command for any debug
  //
  oFlashStatus = Fapi_getFsmStatus();
  //
  // Verify the values programmed.  The Program step itself does a verify
  // as it goes.  This verify is a 2nd verification that can be done.
  //
  oReturnCheck = Fapi_doVerify((uint32 *)u32Index,
          4, Buffer32+(i/2),
          &oFlashStatusWord);
  if(oReturnCheck != Fapi_Status_Success)
  {
   //
   // Check Flash API documentation for possible errors
   //
   EINT;
   return 1;
  }
    }
EINT;
return 0;
}

user5253370:

回复 Eric Ma:

已确认过CPU1的WD禁用了。
发现复位的源头在CPU2,NmiIntruptRegs.NMISHDFLG.all == 512。
CPU2的WD确实时启用了,但FLASH都是CPU1在操作,CPU2没有参与,不明白为啥?

各位好,如题!
问题说明:将Flash用来实现设备参数掉电保存,待保存参数按顺序写入目标Flash sector中,本次写入不覆盖上次写入的区域,当本sector不足时,将sector擦除,从头开始写。现在的问题是,只要一执行erase操作,芯片就复位,programme写入操作却没有问题,请知情者协助~~

FLASH配置代码如下:
void InitFlash(void)
{
    EALLOW;
    //
    // Set VREADST to the proper value for the flash banks to power up
    // properly. This sets the bank power up delay.
    //
    Flash0CtrlRegs.FBAC.bit.VREADST = 0x14;
    //
    // At reset bank and pump are in sleep. A Flash access will power up the
    // bank and pump automatically.
    //
    // After a Flash access, bank and pump go to low power mode (configurable
    // in FBFALLBACK/FPAC1 registers) if there is no further access to flash.
    //
    // Power up Flash bank and pump. This also sets the fall back mode of
    // flash and pump as active.
    //
    Flash0CtrlRegs.FPAC1.bit.PMPPWR = 0x1;
    Flash0CtrlRegs.FBFALLBACK.bit.BNKPWR0 = 0x3;
    //
    // Disable Cache and prefetch mechanism before changing wait states
    //
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 0;
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 0;
    //
    // Set waitstates according to frequency
    //
    //      *CAUTION*
    // Minimum waitstates required for the flash operating at a given CPU rate
    // must be characterized by TI. Refer to the datasheet for the latest
    // information.
    //
    #if CPU_FRQ_200MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x3;
    #endif
    #if CPU_FRQ_150MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
    #endif
    #if CPU_FRQ_120MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
    #endif
    //
    // Enable Cache and prefetch mechanism to improve performance of code
    // executed from Flash.
    //
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 1;
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 1;
    //
    // At reset, ECC is enabled. If it is disabled by application software and
    // if application again wants to enable ECC.
    //
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    EDIS;
    //
    // Force a pipeline flush to ensure that the write to the last register
    // configured occurs before returning.
    //
    __asm(" RPT #7 || NOP");
}

//
// SeizeFlashPump – Wait until the flash pump is available. Then take control
//                  of it using the flash pump Semaphore.
//
void SeizeFlashPump(void)
{
    EALLOW;
    #ifdef CPU1
        while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x2)
        {
            FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x2;
        }
    #elif defined(CPU2)
        while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x1)
        {
            FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x1;
        }
    #endif
    EDIS;
}

//
// Init_Flash_Sectors – Initialize flash API and active flash bank sectors
//
void Init_Flash_Sectors(void)
{
    EALLOW;
    Flash0EccRegs.ERR_THRESHOLD.bit.ERR_THRESHOLD = 0x1;
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0x0;
    Fapi_StatusType oReturnCheck;
    //
    // This function is required to initialize the Flash API based on System
    // frequency before any other Flash API operation can be performed
    //
    oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 200);
    if(oReturnCheck != Fapi_Status_Success)
    {
        Example_Error(oReturnCheck);
    }
    //
    // Fapi_setActiveFlashBank function sets the Flash bank and FMC for further
    // Flash operations to be performed on the bank
    //
    oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    if(oReturnCheck != Fapi_Status_Success)
    {
        Example_Error(oReturnCheck);
    }
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    EDIS;
}

erase和programme操作如下:
#pragma CODE_SECTION(StoreData2Flash, ramFuncSection);
int StoreData2Flash(Uint16 *start, Uint32 size, Uint16 sector)
{
//1. declare the variables used for programming flash
    Fapi_StatusType oReturnCheck = 0;// Status structure
    Fapi_FlashStatusWordType oFlashStatusWord;
    volatile Fapi_FlashStatusType oFlashStatus;
    uint32 u32Index = 0;
    uint16 i = 0;
Uint32 lTemp;
Uint32 lSectorAddr;
uint32 *Buffer32 = (uint32 *)start;
    EALLOW;
DINT;  // disable global interrupt
//2. check if the sector storing data record is full. if yes then erase the sector
switch(sector)
{
  case SECTORK: lSectorAddr = Bzero_SectorK_start; break;
  case SECTORL: lSectorAddr = Bzero_SectorL_start; break;
  case SECTORM: lSectorAddr = Bzero_SectorM_start; break;
  case SECTORN: lSectorAddr = Bzero_SectorN_start; break;
  default:   EINT;
  return 1;
}
lTemp = lSectorAddr;
//  search for the most recent data ration record in flash
while(*(unsigned long*)lTemp != 0xFFFFFFFF)  // the value at lTemp is not 0xFFFFFFFF which means the location at lTemp is not programmed with some value
{
  lTemp += size;
}
if(lSectorAddr + 0x2000 – lTemp < size) // if the flash is full, erase the sector
{
     // Erase Sector
  //
  oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(uint32 *)lSectorAddr);
   // Wait until FSM is done with erase sector operation
  while(Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
      // Verify that SectorL is erased.  The Erase step itself does a
      // verify as it goes.  This verify is a 2nd verification that can be done.
  oReturnCheck = Fapi_doBlankCheck((uint32 *)lSectorAddr,Bzero_16KSector_u32length,&oFlashStatusWord);
  if(oReturnCheck != Fapi_Status_Success)
  {
      EINT;
   return 1;
   }
  lTemp = lSectorAddr;
}
//3. program the data record to flash
    for(i=0, u32Index = lTemp;
       (u32Index < (lTemp + size)) &&
       (oReturnCheck == Fapi_Status_Success); i+= 8, u32Index+= 8)
    {
  oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,start+i,
              8,
              0,
              0,
              Fapi_AutoEccGeneration);
  while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);
  if(oReturnCheck != Fapi_Status_Success)
  {
   //
   // Check Flash API documentation for possible errors
   //
   EINT;
   return 1;
  }
  //
  // Read FMSTAT register contents to know the status of FSM after
  // program command for any debug
  //
  oFlashStatus = Fapi_getFsmStatus();
  //
  // Verify the values programmed.  The Program step itself does a verify
  // as it goes.  This verify is a 2nd verification that can be done.
  //
  oReturnCheck = Fapi_doVerify((uint32 *)u32Index,
          4, Buffer32+(i/2),
          &oFlashStatusWord);
  if(oReturnCheck != Fapi_Status_Success)
  {
   //
   // Check Flash API documentation for possible errors
   //
   EINT;
   return 1;
  }
    }
EINT;
return 0;
}

Eric Ma:

回复 user5253370:


发现复位的源头在CPU2,NmiIntruptRegs.NMISHDFLG.all == 512。
CPU2的WD确实时启用了,但FLASH都是CPU1在操作,CPU2没有参与,不明白为啥?

ERIC:
你要检查一下,是否CPU2有哪些地方和CPU1进行通信交换数据,导致卡住,然后看门狗没有喂狗。

各位好,如题!
问题说明:将Flash用来实现设备参数掉电保存,待保存参数按顺序写入目标Flash sector中,本次写入不覆盖上次写入的区域,当本sector不足时,将sector擦除,从头开始写。现在的问题是,只要一执行erase操作,芯片就复位,programme写入操作却没有问题,请知情者协助~~

FLASH配置代码如下:
void InitFlash(void)
{
    EALLOW;
    //
    // Set VREADST to the proper value for the flash banks to power up
    // properly. This sets the bank power up delay.
    //
    Flash0CtrlRegs.FBAC.bit.VREADST = 0x14;
    //
    // At reset bank and pump are in sleep. A Flash access will power up the
    // bank and pump automatically.
    //
    // After a Flash access, bank and pump go to low power mode (configurable
    // in FBFALLBACK/FPAC1 registers) if there is no further access to flash.
    //
    // Power up Flash bank and pump. This also sets the fall back mode of
    // flash and pump as active.
    //
    Flash0CtrlRegs.FPAC1.bit.PMPPWR = 0x1;
    Flash0CtrlRegs.FBFALLBACK.bit.BNKPWR0 = 0x3;
    //
    // Disable Cache and prefetch mechanism before changing wait states
    //
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 0;
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 0;
    //
    // Set waitstates according to frequency
    //
    //      *CAUTION*
    // Minimum waitstates required for the flash operating at a given CPU rate
    // must be characterized by TI. Refer to the datasheet for the latest
    // information.
    //
    #if CPU_FRQ_200MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x3;
    #endif
    #if CPU_FRQ_150MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
    #endif
    #if CPU_FRQ_120MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
    #endif
    //
    // Enable Cache and prefetch mechanism to improve performance of code
    // executed from Flash.
    //
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 1;
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 1;
    //
    // At reset, ECC is enabled. If it is disabled by application software and
    // if application again wants to enable ECC.
    //
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    EDIS;
    //
    // Force a pipeline flush to ensure that the write to the last register
    // configured occurs before returning.
    //
    __asm(" RPT #7 || NOP");
}

//
// SeizeFlashPump – Wait until the flash pump is available. Then take control
//                  of it using the flash pump Semaphore.
//
void SeizeFlashPump(void)
{
    EALLOW;
    #ifdef CPU1
        while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x2)
        {
            FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x2;
        }
    #elif defined(CPU2)
        while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x1)
        {
            FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x1;
        }
    #endif
    EDIS;
}

//
// Init_Flash_Sectors – Initialize flash API and active flash bank sectors
//
void Init_Flash_Sectors(void)
{
    EALLOW;
    Flash0EccRegs.ERR_THRESHOLD.bit.ERR_THRESHOLD = 0x1;
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0x0;
    Fapi_StatusType oReturnCheck;
    //
    // This function is required to initialize the Flash API based on System
    // frequency before any other Flash API operation can be performed
    //
    oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 200);
    if(oReturnCheck != Fapi_Status_Success)
    {
        Example_Error(oReturnCheck);
    }
    //
    // Fapi_setActiveFlashBank function sets the Flash bank and FMC for further
    // Flash operations to be performed on the bank
    //
    oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    if(oReturnCheck != Fapi_Status_Success)
    {
        Example_Error(oReturnCheck);
    }
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    EDIS;
}

erase和programme操作如下:
#pragma CODE_SECTION(StoreData2Flash, ramFuncSection);
int StoreData2Flash(Uint16 *start, Uint32 size, Uint16 sector)
{
//1. declare the variables used for programming flash
    Fapi_StatusType oReturnCheck = 0;// Status structure
    Fapi_FlashStatusWordType oFlashStatusWord;
    volatile Fapi_FlashStatusType oFlashStatus;
    uint32 u32Index = 0;
    uint16 i = 0;
Uint32 lTemp;
Uint32 lSectorAddr;
uint32 *Buffer32 = (uint32 *)start;
    EALLOW;
DINT;  // disable global interrupt
//2. check if the sector storing data record is full. if yes then erase the sector
switch(sector)
{
  case SECTORK: lSectorAddr = Bzero_SectorK_start; break;
  case SECTORL: lSectorAddr = Bzero_SectorL_start; break;
  case SECTORM: lSectorAddr = Bzero_SectorM_start; break;
  case SECTORN: lSectorAddr = Bzero_SectorN_start; break;
  default:   EINT;
  return 1;
}
lTemp = lSectorAddr;
//  search for the most recent data ration record in flash
while(*(unsigned long*)lTemp != 0xFFFFFFFF)  // the value at lTemp is not 0xFFFFFFFF which means the location at lTemp is not programmed with some value
{
  lTemp += size;
}
if(lSectorAddr + 0x2000 – lTemp < size) // if the flash is full, erase the sector
{
     // Erase Sector
  //
  oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(uint32 *)lSectorAddr);
   // Wait until FSM is done with erase sector operation
  while(Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
      // Verify that SectorL is erased.  The Erase step itself does a
      // verify as it goes.  This verify is a 2nd verification that can be done.
  oReturnCheck = Fapi_doBlankCheck((uint32 *)lSectorAddr,Bzero_16KSector_u32length,&oFlashStatusWord);
  if(oReturnCheck != Fapi_Status_Success)
  {
      EINT;
   return 1;
   }
  lTemp = lSectorAddr;
}
//3. program the data record to flash
    for(i=0, u32Index = lTemp;
       (u32Index < (lTemp + size)) &&
       (oReturnCheck == Fapi_Status_Success); i+= 8, u32Index+= 8)
    {
  oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,start+i,
              8,
              0,
              0,
              Fapi_AutoEccGeneration);
  while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);
  if(oReturnCheck != Fapi_Status_Success)
  {
   //
   // Check Flash API documentation for possible errors
   //
   EINT;
   return 1;
  }
  //
  // Read FMSTAT register contents to know the status of FSM after
  // program command for any debug
  //
  oFlashStatus = Fapi_getFsmStatus();
  //
  // Verify the values programmed.  The Program step itself does a verify
  // as it goes.  This verify is a 2nd verification that can be done.
  //
  oReturnCheck = Fapi_doVerify((uint32 *)u32Index,
          4, Buffer32+(i/2),
          &oFlashStatusWord);
  if(oReturnCheck != Fapi_Status_Success)
  {
   //
   // Check Flash API documentation for possible errors
   //
   EINT;
   return 1;
  }
    }
EINT;
return 0;
}

user5253370:

回复 Eric Ma:

CPU1和2的中断都使用了ADC中断源,ADC是配给CPU1的,当CPU1操作FLASH时,仅关掉了全局中断,DINT。
我理解的是CPU2会继续响应ADC的中断,继续去喂狗,但实际上CPU2却没再进中断。
查看datasheet,没发现相关描述,控制中断源的CPU如果关掉全局中断,会影响另一个CPU响应中断吗?

各位好,如题!
问题说明:将Flash用来实现设备参数掉电保存,待保存参数按顺序写入目标Flash sector中,本次写入不覆盖上次写入的区域,当本sector不足时,将sector擦除,从头开始写。现在的问题是,只要一执行erase操作,芯片就复位,programme写入操作却没有问题,请知情者协助~~

FLASH配置代码如下:
void InitFlash(void)
{
    EALLOW;
    //
    // Set VREADST to the proper value for the flash banks to power up
    // properly. This sets the bank power up delay.
    //
    Flash0CtrlRegs.FBAC.bit.VREADST = 0x14;
    //
    // At reset bank and pump are in sleep. A Flash access will power up the
    // bank and pump automatically.
    //
    // After a Flash access, bank and pump go to low power mode (configurable
    // in FBFALLBACK/FPAC1 registers) if there is no further access to flash.
    //
    // Power up Flash bank and pump. This also sets the fall back mode of
    // flash and pump as active.
    //
    Flash0CtrlRegs.FPAC1.bit.PMPPWR = 0x1;
    Flash0CtrlRegs.FBFALLBACK.bit.BNKPWR0 = 0x3;
    //
    // Disable Cache and prefetch mechanism before changing wait states
    //
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 0;
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 0;
    //
    // Set waitstates according to frequency
    //
    //      *CAUTION*
    // Minimum waitstates required for the flash operating at a given CPU rate
    // must be characterized by TI. Refer to the datasheet for the latest
    // information.
    //
    #if CPU_FRQ_200MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x3;
    #endif
    #if CPU_FRQ_150MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
    #endif
    #if CPU_FRQ_120MHZ
    Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
    #endif
    //
    // Enable Cache and prefetch mechanism to improve performance of code
    // executed from Flash.
    //
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 1;
    Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 1;
    //
    // At reset, ECC is enabled. If it is disabled by application software and
    // if application again wants to enable ECC.
    //
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    EDIS;
    //
    // Force a pipeline flush to ensure that the write to the last register
    // configured occurs before returning.
    //
    __asm(" RPT #7 || NOP");
}

//
// SeizeFlashPump – Wait until the flash pump is available. Then take control
//                  of it using the flash pump Semaphore.
//
void SeizeFlashPump(void)
{
    EALLOW;
    #ifdef CPU1
        while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x2)
        {
            FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x2;
        }
    #elif defined(CPU2)
        while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x1)
        {
            FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x1;
        }
    #endif
    EDIS;
}

//
// Init_Flash_Sectors – Initialize flash API and active flash bank sectors
//
void Init_Flash_Sectors(void)
{
    EALLOW;
    Flash0EccRegs.ERR_THRESHOLD.bit.ERR_THRESHOLD = 0x1;
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0x0;
    Fapi_StatusType oReturnCheck;
    //
    // This function is required to initialize the Flash API based on System
    // frequency before any other Flash API operation can be performed
    //
    oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 200);
    if(oReturnCheck != Fapi_Status_Success)
    {
        Example_Error(oReturnCheck);
    }
    //
    // Fapi_setActiveFlashBank function sets the Flash bank and FMC for further
    // Flash operations to be performed on the bank
    //
    oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    if(oReturnCheck != Fapi_Status_Success)
    {
        Example_Error(oReturnCheck);
    }
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
    EDIS;
}

erase和programme操作如下:
#pragma CODE_SECTION(StoreData2Flash, ramFuncSection);
int StoreData2Flash(Uint16 *start, Uint32 size, Uint16 sector)
{
//1. declare the variables used for programming flash
    Fapi_StatusType oReturnCheck = 0;// Status structure
    Fapi_FlashStatusWordType oFlashStatusWord;
    volatile Fapi_FlashStatusType oFlashStatus;
    uint32 u32Index = 0;
    uint16 i = 0;
Uint32 lTemp;
Uint32 lSectorAddr;
uint32 *Buffer32 = (uint32 *)start;
    EALLOW;
DINT;  // disable global interrupt
//2. check if the sector storing data record is full. if yes then erase the sector
switch(sector)
{
  case SECTORK: lSectorAddr = Bzero_SectorK_start; break;
  case SECTORL: lSectorAddr = Bzero_SectorL_start; break;
  case SECTORM: lSectorAddr = Bzero_SectorM_start; break;
  case SECTORN: lSectorAddr = Bzero_SectorN_start; break;
  default:   EINT;
  return 1;
}
lTemp = lSectorAddr;
//  search for the most recent data ration record in flash
while(*(unsigned long*)lTemp != 0xFFFFFFFF)  // the value at lTemp is not 0xFFFFFFFF which means the location at lTemp is not programmed with some value
{
  lTemp += size;
}
if(lSectorAddr + 0x2000 – lTemp < size) // if the flash is full, erase the sector
{
     // Erase Sector
  //
  oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(uint32 *)lSectorAddr);
   // Wait until FSM is done with erase sector operation
  while(Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
      // Verify that SectorL is erased.  The Erase step itself does a
      // verify as it goes.  This verify is a 2nd verification that can be done.
  oReturnCheck = Fapi_doBlankCheck((uint32 *)lSectorAddr,Bzero_16KSector_u32length,&oFlashStatusWord);
  if(oReturnCheck != Fapi_Status_Success)
  {
      EINT;
   return 1;
   }
  lTemp = lSectorAddr;
}
//3. program the data record to flash
    for(i=0, u32Index = lTemp;
       (u32Index < (lTemp + size)) &&
       (oReturnCheck == Fapi_Status_Success); i+= 8, u32Index+= 8)
    {
  oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,start+i,
              8,
              0,
              0,
              Fapi_AutoEccGeneration);
  while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);
  if(oReturnCheck != Fapi_Status_Success)
  {
   //
   // Check Flash API documentation for possible errors
   //
   EINT;
   return 1;
  }
  //
  // Read FMSTAT register contents to know the status of FSM after
  // program command for any debug
  //
  oFlashStatus = Fapi_getFsmStatus();
  //
  // Verify the values programmed.  The Program step itself does a verify
  // as it goes.  This verify is a 2nd verification that can be done.
  //
  oReturnCheck = Fapi_doVerify((uint32 *)u32Index,
          4, Buffer32+(i/2),
          &oFlashStatusWord);
  if(oReturnCheck != Fapi_Status_Success)
  {
   //
   // Check Flash API documentation for possible errors
   //
   EINT;
   return 1;
  }
    }
EINT;
return 0;
}

user5253370:

回复 Eric Ma:

我在CPU2的中断里驱动一个输出信号(1ms翻转1次),用示波器观察,在CPU1执行FLASH擦除的操作时,CPU2的中断停了45ms左右(输出信号没有翻转)。
不知道是不是CPU1和CPU2共用一个中断源(ADC),CPU1关全局中断的时候,CPU2也收不到中断了?
还是CPU1在执行FLASH擦除操作时,CPU2无法从FLASH中读取指令了?

赞(0)
未经允许不得转载:TI中文支持网 » 28377d Flash 执行擦除后芯片复位
分享到: 更多 (0)