Пример #1
0
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();

}
Пример #3
0
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;
}