static flash_err_t flash_write_sector_locked(const void *addr, const void *data, int len_in_bytes) // TODO arg: err_addr { Fapi_StatusType status; uint32_t fsm_status; sector_info_t p, *sinfo = &p; int bytes; uint32_t *paddr = (uint32_t *)addr; // TODO align? uint8_t *pdata = (uint8_t *)data; #if 0 if (!(((uint32_t)addr) & ~3)) { return FLASH_ERR_INVALID; // FIXME necessary? } #endif if (false == get_sector_info((uint32_t)addr, &p)) { log_report_fmt(LOG_FLASH, "flash_write_sector ERROR unknown sector (addr:0x%08x)\n", (uint32_t)addr); return FLASH_ERR_INVALID; } if (api_bank.bankId == sinfo->bankId) { log_report_fmt(LOG_FLASH, "flash_write_sector ERROR api_bank.bankId=%d\n", api_bank.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) { log_report_fmt(LOG_FLASH, "flash_write_sector ERROR Fapi_setActiveFlashBank(bankId:%d) status=%d\n", sinfo->bankId, 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) { log_report_fmt(LOG_FLASH, "flash_write_sector ERROR Fapi_enable*BankSectors(sectorId:%d) status=%d\n", sinfo->sectorId, 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_write_sector(0x%08x, 0x%06x, src=0x%08x) Programming...\r\n", (uint32_t)addr, len_in_bytes, (uint32_t)data); vPortEnterCritical(); while (len_in_bytes > 0) { if (len_in_bytes > WORDSIZE) { bytes = WORDSIZE; } else { bytes = len_in_bytes; } status = Fapi_issueProgrammingCommand(paddr, pdata, bytes, NULL, 0, Fapi_DataOnly); if (Fapi_Status_Success != status) { vPortExitCritical(); log_report_fmt(LOG_FLASH, "flash_write_sector(0x%08x, still:0x%06x) ERROR1 Program Fapi_Status:%d\r\n", (uint32_t)paddr, len_in_bytes, 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; if (fsm_status) { // see FMSTAT_BITS //if INVDAT: status = Fapi_issueAsyncCommand(Fapi_ClearStatus); if (Fapi_Status_Success != status) { vPortExitCritical(); log_report_fmt(LOG_FLASH, "flash_write_sector(0x%08x, still:0x%06x) ERROR2 fsm_status:%d Fapi_Status:%d\r\n", (uint32_t)paddr, len_in_bytes, fsm_status, 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; vPortExitCritical(); log_report_fmt(LOG_FLASH, "flash_write_sector(0x%08x, still:0x%06x) ERROR3 fsm_status:%d\r\n", (uint32_t)paddr, len_in_bytes, fsm_status); return FLASH_ERR_PROTOCOL; } len_in_bytes -= bytes; pdata += bytes; paddr++; } Fapi_flushPipeline(); vPortExitCritical(); log_report_fmt(LOG_FLASH, "flash_write_sector(0x%08x, src=0x%08x) Done.\r\n", (uint32_t)addr, (uint32_t)data); 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(); }
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; }