⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flashd_efc.c

📁 Include startup files and peripherial devices Code for Atmel ARM7 development
💻 C
📖 第 1 页 / 共 2 页
字号:

        *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 + -