summaryrefslogtreecommitdiff
path: root/MakefileBasedBuild/Atmel/sam3x/sam3x-ek/libraries/memories/nandflash/SkipBlockNandFlash.c
diff options
context:
space:
mode:
Diffstat (limited to 'MakefileBasedBuild/Atmel/sam3x/sam3x-ek/libraries/memories/nandflash/SkipBlockNandFlash.c')
-rw-r--r--MakefileBasedBuild/Atmel/sam3x/sam3x-ek/libraries/memories/nandflash/SkipBlockNandFlash.c495
1 files changed, 0 insertions, 495 deletions
diff --git a/MakefileBasedBuild/Atmel/sam3x/sam3x-ek/libraries/memories/nandflash/SkipBlockNandFlash.c b/MakefileBasedBuild/Atmel/sam3x/sam3x-ek/libraries/memories/nandflash/SkipBlockNandFlash.c
deleted file mode 100644
index f954b80..0000000
--- a/MakefileBasedBuild/Atmel/sam3x/sam3x-ek/libraries/memories/nandflash/SkipBlockNandFlash.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/* ----------------------------------------------------------------------------
- * ATMEL Microcontroller Software Support
- * ----------------------------------------------------------------------------
- * Copyright (c) 2010, 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.
- * ----------------------------------------------------------------------------
- */
-
-/**
- * \file
- *
- * SkipBlockNandFlash layer supplies application a set of interface to operate nandflash.
- * which include initialize, block erase, block write/read, page write/read. \n
- * This layer is to just skip over the bad blocks and place the data in the known good blocks.
- * The algorithm starts by reading the entire spare area of the entire memory. The addresses
- * of the factory-marked bad blocks are then collected in the programmer RAM. Next, the image is
- * sequentially programmed (page by page) into the target device. When the target address
- * corresponds to a bad block address, these pages are stored in the next good block, skipping
- * the bad block.
- * The SkipBlocks method is a very generic and well-performing strategy. When a bad block is
- * encountered, the algorithm simply skips ahead to the next good block.
- */
-
-/*----------------------------------------------------------------------------
- * Headers
- *----------------------------------------------------------------------------*/
-
-#include "memories.h"
-
-#include <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)
-
-
-/*----------------------------------------------------------------------------
- * Exported functions
- *----------------------------------------------------------------------------*/
-
-/**
- * \brief Check if the given block of a nandflash device is bad.
- *
- * \param skipBlock Pointer to a SkipBlockNandFlash instance.
- * \param block Number of block to check.
- * \return GOODBLOCK if the block is good; or returns a NandCommon_ERROR code.
- */
-uint8_t SkipBlockNandFlash_CheckBlock(
- const struct SkipBlockNandFlash *skipBlock,
- uint16_t block)
-{
- #if !defined (OP_BOOTSTRAP_on)
- uint8_t spare[NandCommon_MAXPAGESPARESIZE];
- uint8_t error;
- uint8_t 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;
-}
-
-/**
- * \brief 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.
- */
-uint8_t SkipBlockNandFlash_Initialize(
- struct SkipBlockNandFlash *skipBlock,
- const struct NandFlashModel *model,
- uint32_t commandAddress,
- uint32_t addressAddress,
- uint32_t dataAddress,
- const Pin pinChipEnable,
- const Pin pinReadyBusy)
-{
- uint8_t error;
- #if !defined(OP_BOOTSTRAP_on)
- uint32_t numBlocks;
- uint32_t 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 = SkipBlockNandFlash_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;
-}
-
-/**
- * \brief Erases a block of a SkipBlock NandFlash.
- *
- * \param skipBlock Pointer to a SkipBlockNandFlash instance.
- * \param block Number of block to erase.
- * \return the RawNandFlash_EraseBlock code or NandCommon_ERROR_WRONGSTATUS.
- */
-uint8_t SkipBlockNandFlash_EraseBlock(
- struct SkipBlockNandFlash *skipBlock,
- uint16_t block,
- uint32_t eraseType)
-{
- uint8_t error;
- const struct NandSpareScheme *scheme;
- uint8_t spare[NandCommon_MAXPAGESPARESIZE];
-
- // TRACE_INFO("SkipBlockNandFlash_EraseBlock(%d)\n\r", block);
-
- if (eraseType != SCRUB_ERASE) {
- /* Check block status */
- if (SkipBlockNandFlash_CheckBlock(skipBlock, block) != GOODBLOCK) {
-
- TRACE_INFO("SkipBlockNandFlash_EraseBlock: Block is BAD\n\r");
- return NandCommon_ERROR_BADBLOCK;
- }
- }
-
- /* Erase block */
- error = RawNandFlash_EraseBlock(RAW(skipBlock), block);
- if (error) {
-
- /* Try to mark the block as BAD */
- TRACE_ERROR("SkipBlockNandFlash_EraseBlock: Cannot erase block, try to mark it BAD\n\r");
-
- /* Retrieve model scheme */
- scheme = NandFlashModel_GetScheme(MODEL(skipBlock));
-
- memset(spare, 0xFF, NandCommon_MAXPAGESPARESIZE);
- NandSpareScheme_WriteBadBlockMarker(scheme, spare, NandBlockStatus_BAD_skip);
- return RawNandFlash_WritePage(RAW(skipBlock), block, 0, 0, spare);
- }
-
- return 0;
-}
-
-
-/**
- * \brief Reads the data and/or the spare area of a page on a SkipBlock nandflash.
- *
- * \param skipBlock Pointer to a SkipBlockNandFlash instance.
- * \param block Number of block to read page from.
- * \param page Number of page to read inside the given block.
- * \param data Data area buffer, can be 0.
- * \param spare Spare area buffer, can be 0.
- * \note If one of the buffer pointer is 0, then the block MUST not be BAD.
- * \return NandCommon_ERROR_BADBLOCK if the block is BAD; Otherwise, returns EccNandFlash_ReadPage().
- */
-uint8_t SkipBlockNandFlash_ReadPage(
- const struct SkipBlockNandFlash *skipBlock,
- uint16_t block,
- uint16_t page,
- void *data,
- void *spare)
-{
- #if !defined(OP_BOOTSTRAP_on)
- /* Check that the block is not BAD if data is requested */
- if (SkipBlockNandFlash_CheckBlock(skipBlock, block) != GOODBLOCK) {
-
- TRACE_ERROR("SkipBlockNandFlash_ReadPage: Block is BAD.\n\r");
- return NandCommon_ERROR_BADBLOCK;
- }
-
- /* Read data with ECC verification */
- return EccNandFlash_ReadPage(ECC(skipBlock), block, page, data, spare);
- #else
- return RawNandFlash_ReadPage(RAW(skipBlock), block, page, data, spare);
- #endif
-}
-
-/**
- * \brief Reads the data of a whole block on a SkipBlock nandflash.
- *
- * \param skipBlock Pointer to a SkipBlockNandFlash instance.
- * \param block Number of block to read page from.
- * \param page Number of page to read inside the given block.
- * \param data Data area buffer, can be 0.
- * \param spare Spare area buffer, can be 0.
- * \return NandCommon_ERROR_BADBLOCK if the block is BAD; Otherwise, returns EccNandFlash_ReadPage().
- */
-uint8_t SkipBlockNandFlash_ReadBlock(
- const struct SkipBlockNandFlash *skipBlock,
- uint16_t block,
- void *data)
-{
- /* Number of pages per block */
- uint32_t numPagesPerBlock, pageSize;
- /* Page index */
- uint16_t i;
- /* Error returned by SkipBlockNandFlash_WritePage */
- uint8_t error = 0;
-
- /* Retrieve model information */
- pageSize = NandFlashModel_GetPageDataSize(MODEL(skipBlock));
- numPagesPerBlock = NandFlashModel_GetBlockSizeInPages(MODEL(skipBlock));
-
- /* Check that the block is not BAD if data is requested */
- if (SkipBlockNandFlash_CheckBlock(skipBlock, block) != GOODBLOCK) {
-
- TRACE_ERROR("SkipBlockNandFlash_ReadBlock: Block is BAD.\n\r");
- return NandCommon_ERROR_BADBLOCK;
- }
-
- /* Read all the pages of the block */
- for (i = 0; i < numPagesPerBlock; i++) {
- error = EccNandFlash_ReadPage(ECC(skipBlock), block, i, data, 0);
- if (error) {
-
- TRACE_ERROR("SkipBlockNandFlash_ReadBlock: Cannot read page %d of block %d.\n\r", i, block);
- return error;
- }
- data = (void *) ((uint8_t *) data + pageSize);
- }
-
- return 0;
-}
-
-/**
- * \brief Writes the data and/or spare area of a page on a SkipBlock NandFlash.
- *
- * \param skipBlock Pointer to a SkipBlockNandFlash instance.
- * \param block Number of the block to write.
- * \param page Number of the page to write inside the given block.
- * \param data Data area buffer.
- * \param spare Spare area buffer.
- * \return NandCommon_ERROR_BADBLOCK if the block is BAD; Otherwise, returns EccNandFlash_WritePage().
- */
-uint8_t SkipBlockNandFlash_WritePage(
- const struct SkipBlockNandFlash *skipBlock,
- uint16_t block,
- uint16_t page,
- void *data,
- void *spare)
-{
- /* Check that the block is LIVE */
- if (SkipBlockNandFlash_CheckBlock(skipBlock, block) != GOODBLOCK) {
-
- TRACE_ERROR("SkipBlockNandFlash_WritePage: Block is BAD.\n\r");
- return NandCommon_ERROR_BADBLOCK;
- }
-
- /* Write data with ECC calculation */
- return EccNandFlash_WritePage(ECC(skipBlock), block, page, data, spare);
-}
-
-/**
- * \brief Writes the data of a whole block on a SkipBlock nandflash.
- *
- * \param skipBlock Pointer to a SkipBlockNandFlash instance.
- * \param block Number of the block to write.
- * \param data Data area buffer.
- * \return NandCommon_ERROR_BADBLOCK if the block is BAD; Otherwise, returns EccNandFlash_WritePage().
- */
-uint8_t SkipBlockNandFlash_WriteBlock(
- const struct SkipBlockNandFlash *skipBlock,
- uint16_t block,
- void *data)
-{
- /* Number of pages per block */
- uint32_t numPagesPerBlock;
- /* Page size */
- uint32_t pageSize;
- /* Page index*/
- uint16_t i;
- /* Error returned by SkipBlockNandFlash_WritePage*/
- uint8_t error = 0;
-
- /* Retrieve model information*/
- pageSize = NandFlashModel_GetPageDataSize(MODEL(skipBlock));
- numPagesPerBlock = NandFlashModel_GetBlockSizeInPages(MODEL(skipBlock));
-
- /* Check that the block is LIVE*/
- if (SkipBlockNandFlash_CheckBlock(skipBlock, block) != GOODBLOCK) {
-
- TRACE_ERROR("SkipBlockNandFlash_WriteBlock: Block is BAD.\n\r");
- return NandCommon_ERROR_BADBLOCK;
- }
-
- for (i = 0; i < numPagesPerBlock; i++) {
- error = EccNandFlash_WritePage(ECC(skipBlock), block, i, data, 0);
- if (error) {
-
- TRACE_ERROR("SkipBlockNandFlash_WriteBlock: Cannot write page %d of block %d.\n\r", i, block);
- return NandCommon_ERROR_CANNOTWRITE;
- }
- data = (void *) ((uint8_t *) data + pageSize);
- }
-
- return 0;
-}
-
-/**
- * \brief Writes the data of a whole block on a SkipBlock nandflash.
- *
- * \param skipBlock Pointer to a SkipBlockNandFlash instance.
- * \param block Number of the block to write.
- * \param pageOffsetInBlock Number of the page to write inside the given block.
- * \param data Data area buffer.
- * \param numPages number of pages to write.
- * \return NandCommon_ERROR_BADBLOCK if the block is BAD; Otherwise, returns EccNandFlash_WritePage().
- */
-uint8_t SkipBlockNandFlash_WriteBlockUnaligned(
- const struct SkipBlockNandFlash *skipBlock,
- uint16_t block,
- uint16_t pageOffsetInBlock,
- uint16_t numPages,
- void *data
- )
-{
- /* Page size*/
- uint32_t pageSize;
- /* Page index */
- uint16_t i;
- /* Error returned by SkipBlockNandFlash_WritePage */
- uint8_t error = 0;
-
- /* Retrieve model information */
- pageSize = NandFlashModel_GetPageDataSize(MODEL(skipBlock));
-
- for (i = pageOffsetInBlock; i < pageOffsetInBlock + numPages; i++) {
- error = SkipBlockNandFlash_WritePage(skipBlock, block, i, data, 0);
- if (error == NandCommon_ERROR_BADBLOCK) {
-
- TRACE_ERROR("SkipBlockNandFlash_WriteBlock: Block is BAD.\n\r");
- return NandCommon_ERROR_BADBLOCK;
- }
- else if (error) {
-
- TRACE_ERROR("SkipBlockNandFlash_WriteBlock: Cannot write page %d of block %d.\n\r", i, block);
- return NandCommon_ERROR_CANNOTWRITE;
- }
- data = (void *) ((uint8_t *) data + pageSize);
- }
-
- return 0;
-}
-
-/**
- * \brief Read the data of a whole block on a SkipBlock nandflash.
- *
- * \param skipBlock Pointer to a SkipBlockNandFlash instance.
- * \param block Number of the block to read.
- * \param pageOffsetInBlock Number of the page to read inside the given block.
- * \param data Data area buffer.
- * \param numPages number of pages to read.
- * \return NandCommon_ERROR_BADBLOCK if the block is BAD; Otherwise, returns EccNandFlash_WritePage().
- */
-uint8_t SkipBlockNandFlash_ReadBlockUnaligned(
- const struct SkipBlockNandFlash *skipBlock,
- uint16_t block,
- uint16_t pageOffsetInBlock,
- uint16_t numPages,
- void *data
- )
-{
- /* Page size*/
- uint32_t pageSize;
- /* Page index*/
- uint16_t i;
- /* Error returned by SkipBlockNandFlash_ReadPage*/
- uint8_t error = 0;
-
- /* Retrieve model information*/
- pageSize = NandFlashModel_GetPageDataSize(MODEL(skipBlock));
-
- for (i = pageOffsetInBlock; i < pageOffsetInBlock + numPages; i++) {
- error = SkipBlockNandFlash_ReadPage(skipBlock, block, i, data, 0);
- if (error == NandCommon_ERROR_BADBLOCK) {
-
- TRACE_ERROR("SkipBlockNandFlash_ReadBlock: Block is BAD.\n\r");
- return NandCommon_ERROR_BADBLOCK;
- }
- else if (error) {
-
- TRACE_ERROR("SkipBlockNandFlash_ReadBlock: Cannot read page %d of block %d.\n\r", i, block);
- return NandCommon_ERROR_CANNOTREAD;
- }
- data = (void *) ((uint8_t *) data + pageSize);
- }
-
- return 0;
-}
-