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

📄 skipblocknandflash.c

📁 at91sam9263 keilv3 一级启动代码,其中晶振频率为16m
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ----------------------------------------------------------------------------
 *         ATMEL Microcontroller Software Support 
 * ----------------------------------------------------------------------------
 * Copyright (c) 2008, Atmel Corporation
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the disclaimer below.
 *
 * Atmel's name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ----------------------------------------------------------------------------
 */

//------------------------------------------------------------------------------
//         Headers
//------------------------------------------------------------------------------

#include "SkipBlockNandFlash.h"
#include "NandSpareScheme.h"
#include "NandFlashModel.h"
#include "RawNandFlash.h"
#include <utility/trace.h>
#include <utility/assert.h>

#include <string.h>

//------------------------------------------------------------------------------
//         Internal definitions
//------------------------------------------------------------------------------

// Casts
#define ECC(skipBlock)    ((struct EccNandFlash *) skipBlock)
#define RAW(skipBlock)    ((struct RawNandFlash *) skipBlock)
#define MODEL(skipBlock)  ((struct NandFlashModel *) skipBlock)

// Values returned by the CheckBlock() function
#define BADBLOCK        255
#define GOODBLOCK       254


//------------------------------------------------------------------------------
//         Internal functions
//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
/// Returns BADBLOCK if the given block of a nandflash device is bad; returns
/// GOODBLOCK if the block is good; or returns a NandCommon_ERROR code.
/// \param skipBlock  Pointer to a SkipBlockNandFlash instance.
/// \param block  Number of block to check.
//------------------------------------------------------------------------------
static unsigned char CheckBlock(
    const struct SkipBlockNandFlash *skipBlock,
    unsigned short block)
{
	#if !defined (OP_BOOTSTRAP_on)
    unsigned char spare[NandCommon_MAXPAGESPARESIZE];
    unsigned char error;
    unsigned char badBlockMarker;
    const struct NandSpareScheme *scheme;


    // Retrieve model scheme
    scheme = NandFlashModel_GetScheme(MODEL(skipBlock));
    
    // Read spare area of first page of block
    error = RawNandFlash_ReadPage(RAW(skipBlock), block, 0, 0, spare);
    if (error) {

        TRACE_ERROR("CheckBlock: Cannot read page #0 of block #%d\n\r", block);
        return error;
    }

    NandSpareScheme_ReadBadBlockMarker(scheme, spare, &badBlockMarker);
    if (badBlockMarker != 0xFF) {

        return BADBLOCK;
    }

    // Read spare area of second page of block
    error = RawNandFlash_ReadPage(RAW(skipBlock), block, 1, 0, spare);
    if (error) {

        TRACE_ERROR("CheckBlock: Cannot read page #1 of block #%d\n\r", block);
        return error;
    }

    NandSpareScheme_ReadBadBlockMarker(scheme, spare, &badBlockMarker);
    if (badBlockMarker != 0xFF) {

        return BADBLOCK;
    }
	#endif

    return GOODBLOCK;
}


//------------------------------------------------------------------------------
//         Exported functions
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
/// Initializes a SkipBlockNandFlash instance. Scans the device to retrieve or
/// create block status information.
/// \param skipBlock  Pointer to a SkipBlockNandFlash instance.
/// \param model  Pointer to the underlying nand chip model. Can be 0.
/// \param commandAddress  Address at which commands are sent.
/// \param addressAddress  Address at which addresses are sent.
/// \param dataAddress  Address at which data is sent.
/// \param pinChipEnable  Pin controlling the CE signal of the NandFlash.
/// \param pinReadyBusy  Pin used to monitor the ready/busy signal of the Nand.
//------------------------------------------------------------------------------
unsigned char SkipBlockNandFlash_Initialize(
    struct SkipBlockNandFlash *skipBlock,
    const struct NandFlashModel *model,
    unsigned int commandAddress,
    unsigned int addressAddress,
    unsigned int dataAddress,
    const Pin pinChipEnable,
    const Pin pinReadyBusy)
{
    unsigned char error;
	#if !defined(OP_BOOTSTRAP_on)
    unsigned int numBlocks;
    unsigned int block;
	#endif

    TRACE_DEBUG("SkipBlockNandFlash_Initialize()\n\r");

    // Initialize SkipBlockNandFlash
    #if !defined(OP_BOOTSTRAP_on)
    error = EccNandFlash_Initialize(ECC(skipBlock),
    								model,
                                    commandAddress,
                                    addressAddress,
                                    dataAddress,
                                    pinChipEnable,
                                    pinReadyBusy);
    #else
    error = RawNandFlash_Initialize(RAW(skipBlock),
                                    model,
                                    commandAddress,
                                    addressAddress,
                                    dataAddress,
                                    pinChipEnable,
                                    pinReadyBusy);
	#endif

	#if !defined(OP_BOOTSTRAP_on)
    if (error) {

        return error;
    }

    // Retrieve model information
    numBlocks = NandFlashModel_GetDeviceSizeInBlocks(MODEL(skipBlock));

    // Initialize block statuses
    TRACE_DEBUG("Retrieving bad block information ...\n\r");

    // Retrieve block status from their first page spare area
    for (block = 0; block < numBlocks; block++) {

        // Read spare of first page
        error = CheckBlock(skipBlock, block);

        if (error != GOODBLOCK) {
            
            if (error == BADBLOCK) {
                
                TRACE_DEBUG("Block #%d is bad\n\r", block);
            }
            else {
                
                TRACE_ERROR(
                "SkipBlockNandFlash_Initialize: Cannot retrieve info from block #%u\n\r", block);
            }
        }
    }
	#endif

    return 0;
}


//------------------------------------------------------------------------------
/// Erases a block of a SkipBlock NandFlash.
/// Returns the RawNandFlash_EraseBlock code or NandCommon_ERROR_WRONGSTATUS.
/// \param skipBlock  Pointer to a SkipBlockNandFlash instance.
/// \param block  Number of block to erase.
//------------------------------------------------------------------------------
unsigned char SkipBlockNandFlash_EraseBlock(
    struct SkipBlockNandFlash *skipBlock,
    unsigned short block,
    unsigned int eraseType)
{
    unsigned char error;
    const struct NandSpareScheme *scheme;
    unsigned char spare[NandCommon_MAXPAGESPARESIZE];

//    TRACE_INFO("SkipBlockNandFlash_EraseBlock(%d)\n\r", block);

    if (eraseType != SCRUB_ERASE) {
        // Check block status
        if (CheckBlock(skipBlock, block) != GOODBLOCK) {
    
            TRACE_INFO("SkipBlockNandFlash_EraseBlock: Block is BAD\n\r");
            return NandCommon_ERROR_BADBLOCK;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -