static flash_err_t flash_erase_sectorinfo_locked(const sector_info_t *sinfo) { Fapi_StatusType status; uint32_t fsm_status; Fapi_FlashStatusWordType poFlashStatusWord; if (api_bank.bankId == sinfo->bankId) { return FLASH_ERR_PROTECT; } //while (Fapi_Status_FsmBusy == FAPI_CHECK_FSM_READY_BUSY) { // ////vTaskDelay(15 / portTICK_RATE_MS); //} if (currentBankId != sinfo->bankId) { status = Fapi_setActiveFlashBank(sinfo->bankId); if (Fapi_Status_Success != status) { return FLASH_ERR_INVALID; } currentBankId = sinfo->bankId; } if (Fapi_FLEE == sinfo->bankTech) { status = Fapi_enableEepromBankSectors(1 << sinfo->sectorId, 0); } else { status = Fapi_enableMainBankSectors(1 << sinfo->sectorId); } if (Fapi_Status_Success != status) { return FLASH_ERR_INVALID; } while (Fapi_Status_FsmReady != FAPI_CHECK_FSM_READY_BUSY) { ////vTaskDelay(15 / portTICK_RATE_MS); } status = Fapi_issueAsyncCommand(Fapi_ClearStatus); if (Fapi_Status_Success != status) { return FLASH_ERR_INVALID; } /* Wait for FSM to finish */ while (Fapi_Status_FsmBusy == FAPI_CHECK_FSM_READY_BUSY) { //vTaskDelay(15 / portTICK_RATE_MS); } /* Check the FSM Status to see if there were no errors */ fsm_status = FAPI_GET_FSM_STATUS; // log_report_fmt(LOG_FLASH, "flash_erase_sector(0x%08x, 0x%08x) EraseSector\r\n", sinfo->sectorStartAddress, sinfo->sectorSize); vPortEnterCritical(); status = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32_t *)sinfo->sectorStartAddress); //// do NOT use log_report*() here since we are running without IRQ if (Fapi_Status_Success != status) { vPortExitCritical(); return FLASH_ERR_INVALID; } /* Wait for FSM to finish */ while (Fapi_Status_FsmBusy == FAPI_CHECK_FSM_READY_BUSY) { //vTaskDelay(15 / portTICK_RATE_MS); } /* Check the FSM Status to see if there were no errors */ fsm_status = FAPI_GET_FSM_STATUS; vPortExitCritical(); /* black magic */ Fapi_flushPipeline(); if (fsm_status) { return FLASH_ERR_PROTOCOL; } status = Fapi_doBlankCheck((uint32_t *)sinfo->sectorStartAddress, sinfo->sectorSize / sizeof(uint32_t), &poFlashStatusWord); if (Fapi_Status_Success != status) { log_report_fmt(LOG_FLASH, "flash_erase_sector(0x%08x, 0x%08x) BlankCheck Fapi_Status:%d\r\n", sinfo->sectorStartAddress, sinfo->sectorSize, status); return FLASH_ERR_INVALID; } return FLASH_ERR_OK; }
void Example_CallFlashAPI(void) { uint32 u32Index = 0; uint16 i = 0; Fapi_StatusType oReturnCheck; Fapi_LibraryInfoType oLibInfo; Fapi_FlashStatusType oFlashStatus; Fapi_FlashBankSectorsType oFlashBankSectors; Fapi_FlashStatusWordType oFlashStatusWord; // Disable ECC. ECC does not have to be disabled to do FSM operations like // program and erase. // However, on Sonata Rev. 0 silicon, due to an OTP ECC errata, // disable ECC to avoid ECC errors while using Flash API functions that // read TI-OTP EALLOW; FlashEccRegs.ECC_ENABLE.bit.ENABLE = 0x0; EDIS; EALLOW; // This function is required to initialize the Flash API based on System // frequency before any other Flash API operation can be performed #if CPU_FRQ_150MHZ oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 150); #endif #if CPU_FRQ_100MHZ oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 100); #endif #if CPU_FRQ_60MHZ oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 60); #endif if(oReturnCheck |= Fapi_Status_Success) { // Check Flash API documentation for possible errors Example_Error(oReturnCheck); } // Fapi_getLibraryInfo function can be used to get the information specific // to the compiled version of the API library oLibInfo = Fapi_getLibraryInfo(); // Before performing FSM operations, set the waitstates for FSM operations // calculated using RWAIT = (SYSCLK/(2*24MHz))-1 // If RWAIT results in a fractional value, round it up to the nearest // integer. // Please note that RWAIT for read operation should be calculated // differently. See Internal Memory guide section in TRM for more details. #if CPU_FRQ_150MHZ FlashCtrlRegs.FRDCNTL.bit.RWAIT = 0x3; #endif #if CPU_FRQ_100MHZ FlashCtrlRegs.FRDCNTL.bit.RWAIT = 0x2; #endif #if CPU_FRQ_60MHZ FlashCtrlRegs.FRDCNTL.bit.RWAIT = 0x1; #endif // 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) { // Check Falsh API documentation for possible errors Example_Error(oReturnCheck); } // Fapi_getBankSectors function returns the bank starting address, number of // sectors, sector sizes, and bank technology type // Above information is returned in a structure oFlashBankSectors of type // Fapi_FlashBankSectorsType oReturnCheck = Fapi_getBankSectors(Fapi_FlashBank0,&oFlashBankSectors); if(oReturnCheck |= Fapi_Status_Success) { //Check Falsh API documentation for possible errors Example_Error(oReturnCheck); } // Erase Sector C // Sectors A and D have the example code so leave them programmed oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32 *)Bzero_SectorC_start); // 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 *)Bzero_SectorC_start, Bzero_16KSector_u32length, &oFlashStatusWord); if(oReturnCheck |= Fapi_Status_Success) { // Check Falsh API documentation for possible errors // If Erase command fails, use Fapi_getFsmStatus() function to get the // FMSTAT register contents to see if any of the EV bit, ESUSP bit, // CSTAT bit or VOLTSTAT bit is set (Refer to API documentation for // more details) Example_Error(oReturnCheck); } // Erase Sector B // Sector N has the example code so leave it programmed oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32 *)Bzero_SectorB_start); // Wait until FSM is done with erase sector operation while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){} // Verify that SectorK 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 *)Bzero_SectorB_start, Bzero_16KSector_u32length, &oFlashStatusWord); if(oReturnCheck |= Fapi_Status_Success) { // Check Flash API documentation for possible errors // If Erase command fails, use Fapi_getFsmStatus() function // to get the FMSTAT register contents // to see if any of the EV bit, ESUSP bit, CSTAT bit or VOLTSTAT // bit is set (Refer to API documentation for more details) Example_Error(oReturnCheck); } // A data buffer of max 8 words can be supplied to the program function. // Each word is programmed until the whole buffer is programmed or a // problem is found. However to program a buffer that has more than 8 // words, program function can be called in a loop to program 8 words for // each loop iteration until the whole buffer is programmed // Example: Program 0xFF bytes in Flash Sector C along with auto- // generated ECC // In this case just fill a buffer with data to program into the flash. for(i=0;i<=WORDS_IN_FLASH_BUFFER;i++) { Buffer[i] = i; } for(i=0, u32Index = Bzero_SectorC_start; (u32Index < (Bzero_SectorC_start + WORDS_IN_FLASH_BUFFER)) && (oReturnCheck == Fapi_Status_Success); i+= 8, u32Index+= 8) { oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,Buffer+i, 8, 0, 0, Fapi_AutoEccGeneration); while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy); if(oReturnCheck |= Fapi_Status_Success) { // Check Flash API documentation for possible errors Example_Error(oReturnCheck); } // 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 Example_Error(oReturnCheck); } } // Example: Program 0xFF bytes in Flash Sector B with out ECC // Disable ECC so that error is not generated when reading Flash contents // without ECC FlashEccRegs.ECC_ENABLE.bit.ENABLE = 0x0; for(i=0, u32Index = Bzero_SectorB_start; (u32Index < (Bzero_SectorB_start + WORDS_IN_FLASH_BUFFER)) && (oReturnCheck == Fapi_Status_Success); i+= 8, u32Index+= 8) { oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index, Buffer+i, 8, 0, 0, Fapi_DataOnly); while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy); if(oReturnCheck |= Fapi_Status_Success) { // Check Flash API documentation for possible errors Example_Error(oReturnCheck); } // 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 Example_Error(oReturnCheck); } } // Erase the sectors that we have programmed above // Erase Sector C // Sectors A and D have the example code so leave them programmed oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32 *)Bzero_SectorC_start); // 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 *)Bzero_SectorC_start, Bzero_16KSector_u32length, &oFlashStatusWord); if(oReturnCheck |= Fapi_Status_Success) { // Check Falsh API documentation for possible errors // If Erase command fails, use Fapi_getFsmStatus() function to get the // FMSTAT register contents // to see if any of the EV bit, ESUSP bit, CSTAT bit or VOLTSTAT bit is // set (Refer to API documentation for more details) Example_Error(oReturnCheck); } // Erase Sector B // Sector N has the example code so leave it programmed oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32 *)Bzero_SectorB_start); // Wait until FSM is done with erase sector operation while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){} // Verify that SectorK 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 *)Bzero_SectorB_start, Bzero_16KSector_u32length, &oFlashStatusWord); if(oReturnCheck |= Fapi_Status_Success) { // Check Flash API documentation for possible errors // If Erase command fails, use Fapi_getFsmStatus() function to get // the FMSTAT register contents to see if any of the EV bit, ESUSP bit, // CSTAT bit or VOLTSTAT bit is set (Refer to API documentation // for more details) Example_Error(oReturnCheck); } // Enable ECC FlashEccRegs.ECC_ENABLE.bit.ENABLE = 0xA; EDIS; // Leave control over flash pump FlashLeavePump(); // Example is done here Example_Done(); }
boolean TI_Fee_Format(uint32 u32FormatKey) { uint16 u16LoopIndex=0U; uint32 u32FlashStatus = 0U; uint16 u16Index=0U; Fapi_FlashSectorType oSectorStart,oSectorEnd; boolean bFlashStatus=FALSE; uint8 u8EEPIndex=0U; boolean bFormat = FALSE; while((u8EEPIndex<TI_FEE_NUMBER_OF_EEPS) && (u32FormatKey == 0xA5A5A5A5U)) { for(u16LoopIndex=0U;u16LoopIndex<TI_FEE_NUMBER_OF_VIRTUAL_SECTORS;u16LoopIndex++) { /* Determine the Start & End Address for the Virtual Sector */ if(u8EEPIndex==0U) { oSectorStart=Fee_VirtualSectorConfiguration[u16LoopIndex].FeeStartSector; oSectorEnd=Fee_VirtualSectorConfiguration[u16LoopIndex].FeeEndSector; /*SAFETYMCUSW 55 D MR:13.6 <REVIEWED> "Reason - u16LoopIndex is not modified here."*/ (TI_Fee_GlobalVariables[u8EEPIndex].Fee_au32VirtualSectorEraseCount[u16LoopIndex])++; TI_Fee_GlobalVariables[u8EEPIndex].Fee_au8VirtualSectorState[u16LoopIndex]=VsState_Invalid; } else { oSectorStart=Fee_VirtualSectorConfiguration[u16LoopIndex+TI_FEE_NUMBER_OF_VIRTUAL_SECTORS_EEP1].FeeStartSector; oSectorEnd=Fee_VirtualSectorConfiguration[u16LoopIndex+TI_FEE_NUMBER_OF_VIRTUAL_SECTORS_EEP1].FeeEndSector; (TI_Fee_GlobalVariables[u8EEPIndex].Fee_au32VirtualSectorEraseCount[u16LoopIndex+TI_FEE_NUMBER_OF_VIRTUAL_SECTORS_EEP1])++; TI_Fee_GlobalVariables[u8EEPIndex].Fee_au8VirtualSectorState[u16LoopIndex+TI_FEE_NUMBER_OF_VIRTUAL_SECTORS_EEP1]=VsState_Invalid; } TI_FeeInternal_GetVirtualSectorIndex(oSectorStart,oSectorEnd,(uint16)TI_Fee_GlobalVariables[u8EEPIndex].Fee_u8Bank,(boolean)TRUE,(uint8)u8EEPIndex); /* Erase the Virtual Sector */ for(u16Index=0U;u16Index<=(oSectorEnd-oSectorStart);u16Index++) { oSectorEnd-=u16Index; TI_Fee_GlobalVariables[u8EEPIndex].Fee_oVirtualSectorStartAddress=Device_FlashDevice.Device_BankInfo[TI_Fee_GlobalVariables[u8EEPIndex].Fee_u8Bank].Device_SectorInfo[TI_Fee_GlobalVariables[u8EEPIndex].Fee_u8VirtualSectorEnd].Device_SectorStartAddress; /*SAFETYMCUSW 496 S MR:8.1 <REVIEWED> "Reason - Fapi_issueAsyncCommandWithAddress is part of F021 and is included via F021.h."*/ if((Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, /*SAFETYMCUSW 95 S MR:11.1,11.4 <REVIEWED> "Reason - Casting is required here."*/ (uint32_t *)TI_Fee_GlobalVariables[u8EEPIndex].Fee_oVirtualSectorStartAddress ))==Fapi_Status_Success) { } else { /* For MISRA-C complaince */ } u32FlashStatus=TI_FeeInternal_PollFlashStatus(); if(u32FlashStatus!=0U) { /* Report Error if the erase failed */ TI_Fee_GlobalVariables[u8EEPIndex].Fee_Error=Error_EraseVS; TI_Fee_GlobalVariables[u8EEPIndex].Fee_oStatus=TI_FEE_ERROR; TI_Fee_GlobalVariables[u8EEPIndex].Fee_ModuleState=UNINIT; } else { bFlashStatus=TI_FeeInternal_BlankCheck(TI_Fee_GlobalVariables[u8EEPIndex].Fee_oVirtualSectorStartAddress, TI_Fee_GlobalVariables[u8EEPIndex].Fee_oVirtualSectorStartAddress+(Device_FlashDevice.Device_BankInfo[TI_Fee_GlobalVariables[u8EEPIndex].Fee_u8Bank].Device_SectorInfo[TI_Fee_GlobalVariables[u8EEPIndex].Fee_u8VirtualSectorEnd].Device_SectorLength), (uint16)TI_Fee_GlobalVariables[u8EEPIndex].Fee_u8Bank, u8EEPIndex); if(bFlashStatus!=TRUE) { /* Report Error if the erase failed */ TI_Fee_GlobalVariables[u8EEPIndex].Fee_Error=Error_EraseVS; TI_Fee_GlobalVariables[u8EEPIndex].Fee_oStatus=TI_FEE_ERROR; TI_Fee_GlobalVariables[u8EEPIndex].Fee_ModuleState=UNINIT; } else { /* For MISRA-C complaince */ } } } } u8EEPIndex++; } if(u32FormatKey != 0xA5A5A5A5U) { bFormat = TRUE; } else { bFormat = FALSE; } return(bFormat); }