?? eccnandflash.c
字號:
/* ----------------------------------------------------------------------------
* 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 "EccNandFlash.h"
#include "NandCommon.h"
#include "NandSpareScheme.h"
#include <utility/trace.h>
#include <utility/hamming.h>
#include <utility/assert.h>
#include <string.h>
//------------------------------------------------------------------------------
// Internal definitions
//------------------------------------------------------------------------------
/// Custom INFO trace level for the current file.
#define INFO trace_INFO
/// Custom DEBUG trace level for the current file.
#define DEBUG trace_DEBUG
/// Casts
#define MODEL(ecc) ((struct NandFlashModel *) ecc)
#define RAW(ecc) ((struct RawNandFlash *) ecc)
//------------------------------------------------------------------------------
// Exported functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Initializes an EccNandFlash instance.
/// \param ecc Pointer to an EccNandFlash 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 EccNandFlash_Initialize(
struct EccNandFlash *ecc,
const struct NandFlashModel *model,
unsigned int commandAddress,
unsigned int addressAddress,
unsigned int dataAddress,
const Pin pinChipEnable,
const Pin pinReadyBusy)
{
return RawNandFlash_Initialize(RAW(ecc),
model,
commandAddress,
addressAddress,
dataAddress,
pinChipEnable,
pinReadyBusy);
}
//------------------------------------------------------------------------------
/// Reads the data and/or spare of a page of a nandflash chip, and verify that
/// the data is valid using the ECC information contained in the spare. If one
/// buffer pointer is 0, the corresponding area is not saved.
/// Returns 0 if the data has been read and is valid; otherwise returns either
/// NandCommon_ERROR_CORRUPTEDDATA or ...
/// \param ecc Pointer to an EccNandFlash instance.
/// \param block Number of block to read from.
/// \param page Number of page to read inside given block.
/// \param data Data area buffer.
/// \param spare Spare area buffer.
//------------------------------------------------------------------------------
unsigned char EccNandFlash_ReadPage(
const struct EccNandFlash *ecc,
unsigned short block,
unsigned short page,
void *data,
void *spare)
{
unsigned char tmpData[NandCommon_MAXPAGEDATASIZE];
unsigned char tmpSpare[NandCommon_MAXPAGESPARESIZE];
unsigned char error;
unsigned char hamming[NandCommon_MAXSPAREECCBYTES];
unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(ecc));
unsigned char pageSpareSize = NandFlashModel_GetPageSpareSize(MODEL(ecc));
trace_LOG(DEBUG, "EccNandFlash_ReadPage(B#%d:P#%d)\n\r", block, page);
// Start by reading the spare and the data
error = RawNandFlash_ReadPage(RAW(ecc), block, page, tmpData, tmpSpare);
if (error) {
trace_LOG(trace_ERROR, "EccNandFlash_ReadPage: Failed to read page\n\r");
return error;
}
// Retrieve ECC information from page and verify the data
NandSpareScheme_ReadEcc(NandFlashModel_GetScheme(MODEL(ecc)), tmpSpare, hamming);
error = Hamming_Verify256x(tmpData, pageDataSize, hamming);
if (error && (error != Hamming_ERROR_SINGLEBIT)) {
trace_LOG(trace_ERROR, "EccNandFlash_ReadPage: Unrecoverable data\n\r");
return NandCommon_ERROR_CORRUPTEDDATA;
}
// Copy data and/or spare into final buffers
if (data) {
memcpy(data, tmpData, pageDataSize);
}
if (spare) {
memcpy(spare, tmpSpare, pageSpareSize);
}
return 0;
}
//------------------------------------------------------------------------------
/// Writes the data and/or spare area of a nandflash page, after calculating an
/// ECC for the data area and storing it in the spare. If no data buffer is
/// provided, the ECC is read from the existing page spare. If no spare buffer
/// is provided, the spare area is still written with the ECC information
/// calculated on the data buffer.
/// Returns 0 if successful; otherwise returns an error code.
/// \param ecc Pointer to an EccNandFlash instance.
/// \param block Number of the block to write in.
/// \param page Number of the page to write inside the given block.
/// \param data Data area buffer, can be 0.
/// \param spare Spare area buffer, can be 0.
//------------------------------------------------------------------------------
unsigned char EccNandFlash_WritePage(
const struct EccNandFlash *ecc,
unsigned short block,
unsigned short page,
void *data,
void *spare)
{
unsigned char error;
unsigned char tmpSpare[NandCommon_MAXPAGESPARESIZE];
unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(ecc));
unsigned short pageSpareSize = NandFlashModel_GetPageSpareSize(MODEL(ecc));
unsigned char hamming[NandCommon_MAXSPAREECCBYTES];
ASSERT(data || spare, "EccNandFlash_WritePage: At least one area must be written\n\r");
trace_LOG(DEBUG, "EccNandFlash_WritePage(B#%d:P#%d)\n\r", block, page);
// Compute ECC on the new data, if provided
// If not provided, hamming code set to 0xFFFF.. to keep existing bytes
memset(hamming, 0xFF, NandCommon_MAXSPAREECCBYTES);
if (data) {
// Compute hamming code on data
Hamming_Compute256x(data, pageDataSize, hamming);
}
// Store code in spare buffer (if no buffer provided, use a temp. one)
if (!spare) {
spare = tmpSpare;
memset(spare, 0xFF, pageSpareSize);
}
NandSpareScheme_WriteEcc(NandFlashModel_GetScheme(MODEL(ecc)), spare, hamming);
// Perform write operation
error = RawNandFlash_WritePage(RAW(ecc), block, page, data, spare);
if (error) {
trace_LOG(trace_ERROR, "EccNandFlash_WritePage: Failed to write page\n\r");
return error;
}
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -