📄 flashd_efc.c
字号:
*pActualEnd = actualEnd;
}
// Compute page numbers
EFC_TranslateAddress(actualStart, &pStartEfc, &startPage, 0);
EFC_TranslateAddress(actualEnd, &pEndEfc, &endPage, 0);
// Lock all pages
// If there is an EFC crossover, lock all pages from first EFC
#if defined(AT91C_BASE_EFC1)
if (pStartEfc != pEndEfc) {
while (startPage < (AT91C_IFLASH_NB_OF_PAGES / 2)) {
error = EFC_PerformCommand(pStartEfc, AT91C_MC_FCMD_LOCK, startPage);
if (error) {
return error;
}
startPage += numPagesInRegion;
}
startPage = 0;
}
#endif
pEfc = pEndEfc;
// Lock remaining pages
while (startPage < endPage) {
error = EFC_PerformCommand(pEfc, AT91C_MC_FCMD_LOCK, startPage);
if (error) {
return error;
}
startPage += numPagesInRegion;
}
return 0;
}
//------------------------------------------------------------------------------
/// Unlocks all the regions in the given address range. The actual unlock range is
/// reported through two output parameters.
/// Returns 0 if successful; otherwise returns an error code.
/// \param start Start address of unlock range.
/// \param end End address of unlock range.
/// \param pActualStart Start address of the actual unlock range (optional).
/// \param pActualEnd End address of the actual unlock range (optional).
//------------------------------------------------------------------------------
unsigned char FLASHD_Unlock(
unsigned int start,
unsigned int end,
unsigned int *pActualStart,
unsigned int *pActualEnd)
{
AT91S_EFC *pStartEfc, *pEndEfc, *pEfc;
unsigned int actualStart, actualEnd;
unsigned short startPage, endPage;
unsigned char error;
unsigned short numPagesInRegion = AT91C_IFLASH_LOCK_REGION_SIZE / AT91C_IFLASH_PAGE_SIZE;
// Compute actual unlock range and store it
ComputeLockRange(start, end, &actualStart, &actualEnd);
if (pActualStart) {
*pActualStart = actualStart;
}
if (pActualEnd) {
*pActualEnd = actualEnd;
}
// Compute page numbers
EFC_TranslateAddress(actualStart, &pStartEfc, &startPage, 0);
EFC_TranslateAddress(actualEnd, &pEndEfc, &endPage, 0);
// Unlock all pages
// If there is an EFC crossover, unlock all pages from first EFC
#if defined(AT91C_BASE_EFC1)
if (pStartEfc != pEndEfc) {
while (startPage < (AT91C_IFLASH_NB_OF_PAGES / 2)) {
error = EFC_PerformCommand(pStartEfc, AT91C_MC_FCMD_UNLOCK, startPage);
if (error) {
return error;
}
startPage += numPagesInRegion;
}
startPage = 0;
}
#endif
pEfc = pEndEfc;
// Unlock remaining pages
while (startPage < endPage) {
error = EFC_PerformCommand(pEfc, AT91C_MC_FCMD_UNLOCK, startPage);
if (error) {
return error;
}
startPage += numPagesInRegion;
}
return 0;
}
//------------------------------------------------------------------------------
/// Returns the number of locked regions inside the given address range.
/// \param start Start address of range.
/// \param end End address of range.
//------------------------------------------------------------------------------
unsigned char FLASHD_IsLocked(unsigned int start, unsigned int end)
{
AT91S_EFC *pStartEfc, *pEndEfc, *pEfc;
unsigned short startPage, endPage;
unsigned char startRegion, endRegion;
unsigned int numPagesInRegion;
unsigned int numLockedRegions = 0;
unsigned int status;
// Get EFC & page values
EFC_TranslateAddress(start, &pStartEfc, &startPage, 0);
EFC_TranslateAddress(end, &pEndEfc, &endPage, 0);
// Compute region indexes
numPagesInRegion = AT91C_IFLASH_LOCK_REGION_SIZE / AT91C_IFLASH_PAGE_SIZE;
startRegion = startPage / numPagesInRegion;
endRegion = endPage / numPagesInRegion;
if ((endPage % numPagesInRegion) != 0) {
endRegion++;
}
// EFC cross-over, handle starting page -> end page of EFC0
#if defined(AT91C_BASE_EFC1)
if (pStartEfc != pEndEfc) {
status = EFC_GetStatus(pStartEfc);
while (startRegion < 16) {
if ((status & (1 << startRegion << 16)) != 0) {
numLockedRegions++;
}
startRegion++;
}
startRegion = 0;
}
#endif
pEfc = pEndEfc;
// Remaining regions / no EFC cross-over
status = EFC_GetStatus(pEfc);
while (startRegion < endRegion) {
if ((status & (1 << startRegion << 16)) != 0) {
numLockedRegions++;
}
startRegion++;
}
return numLockedRegions;
}
#if (EFC_NUM_GPNVMS > 0)
//------------------------------------------------------------------------------
/// Returns 1 if the given GPNVM bit is currently set; otherwise returns 0.
/// \param gpnvm GPNVM bit index.
//------------------------------------------------------------------------------
unsigned char FLASHD_IsGPNVMSet(unsigned char gpnvm)
{
AT91S_EFC *pEfc = AT91C_BASE_EFC0;
unsigned int status;
SANITY_CHECK(gpnvm < EFC_NUM_GPNVMS);
#ifdef AT91C_BASE_EFC1
// GPNVM in EFC1
if (gpnvm >= 8) {
pEfc = AT91C_BASE_EFC1;
gpnvm -= 8;
}
#endif
// Check if GPNVM is set
status = EFC_GetStatus(pEfc);
if ((status & (1 << gpnvm << 8)) != 0) {
return 1;
}
else {
return 0;
}
}
//------------------------------------------------------------------------------
/// Sets the selected GPNVM bit.
/// Returns 0 if successful; otherwise returns an error code.
/// \param gpnvm GPNVM index.
//------------------------------------------------------------------------------
unsigned char FLASHD_SetGPNVM(unsigned char gpnvm)
{
AT91S_EFC *pEfc = AT91C_BASE_EFC0;
SANITY_CHECK(gpnvm < EFC_NUM_GPNVMS);
if (!FLASHD_IsGPNVMSet(gpnvm)) {
#ifdef AT91C_BASE_EFC1
// GPNVM in EFC1
if (gpnvm >= 8) {
pEfc = AT91C_BASE_EFC1;
gpnvm -= 8;
}
#endif
return EFC_PerformCommand(pEfc, AT91C_MC_FCMD_SET_GP_NVM, gpnvm);
}
else {
return 0;
}
}
//------------------------------------------------------------------------------
/// Clears the selected GPNVM bit.
/// Returns 0 if successful; otherwise returns an error code.
/// \param gpnvm GPNVM index.
//------------------------------------------------------------------------------
unsigned char FLASHD_ClearGPNVM(unsigned char gpnvm)
{
AT91S_EFC *pEfc = AT91C_BASE_EFC0;
SANITY_CHECK(gpnvm < EFC_NUM_GPNVMS);
if (FLASHD_IsGPNVMSet(gpnvm)) {
#ifdef AT91C_BASE_EFC1
// GPNVM in EFC1
if (gpnvm >= 8) {
pEfc = AT91C_BASE_EFC1;
gpnvm -= 8;
}
#endif
return EFC_PerformCommand(pEfc, AT91C_MC_FCMD_CLR_GP_NVM, gpnvm);
}
else {
return 0;
}
}
#endif //#if (EFC_NUM_GPNVMS > 0)
#if !defined EFC_NO_SECURITY_BIT
//------------------------------------------------------------------------------
/// Returns 1 if the Security bit is currently set; otherwise returns 0.
//------------------------------------------------------------------------------
unsigned char FLASHD_IsSecurityBitSet(void)
{
AT91S_EFC *pEfc = AT91C_BASE_EFC0;
unsigned int status;
status = EFC_GetStatus(pEfc);
return ( ((status & AT91C_MC_SECURITY) != 0)?1:0 );
}
//------------------------------------------------------------------------------
/// Set Security Bit Command (SSB).
/// Returns 0 if successful; otherwise returns an error code.
//------------------------------------------------------------------------------
unsigned char FLASHD_SetSecurityBit(void)
{
AT91S_EFC *pEfc = AT91C_BASE_EFC0;
if( FLASHD_IsSecurityBitSet() == 0) {
return EFC_PerformCommand(pEfc, AT91C_MC_FCMD_SET_SECURITY, 0);
}
else {
return 0;
}
}
#endif //#if (!defined EFC_NO_SECURITY_BIT)
#endif //#ifdef BOARD_FLASH_EFC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -