mirror of
https://github.com/apache/nuttx.git
synced 2026-09-21 21:47:28 +08:00
Finishes up NAND software ECC logic
This commit is contained in:
@@ -3041,6 +3041,28 @@ config SAMA5_EBICS0_NAND
|
||||
select MTD_NAND
|
||||
|
||||
endchoice # CS0 Memory Type
|
||||
|
||||
if SAMA5_EBICS0_NAND && MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC
|
||||
config SAMA5_EBICS0_HWECC
|
||||
bool "NAND H/W ECC support"
|
||||
default n
|
||||
---help---
|
||||
Enable hardware assisted support for ECC calculations
|
||||
|
||||
if SAMA5_EBICS0_HWECC
|
||||
choice
|
||||
prompt "H/W ECC method"
|
||||
default SAMA5_EBICS0_PMECC
|
||||
|
||||
config SAMA5_EBICS0_PMECC
|
||||
bool "PMECC"
|
||||
|
||||
config SAMA5_EBICS0_HSIAO
|
||||
bool "HSIAO ECC"
|
||||
|
||||
endchoice # H/W ECC method
|
||||
endif # SAMA5_EBICS0_HWECC
|
||||
endif # SAMA5_EBICS0_NAND && MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC
|
||||
endif # SAMA5_EBICS0
|
||||
|
||||
config SAMA5_EBICS1
|
||||
@@ -3092,6 +3114,28 @@ config SAMA5_EBICS1_NAND
|
||||
select MTD_NAND
|
||||
|
||||
endchoice # CS1 Memory Type
|
||||
|
||||
if SAMA5_EBICS1_NAND && MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC
|
||||
config SAMA5_EBICS1_HWECC
|
||||
bool "NAND H/W ECC support"
|
||||
default n
|
||||
---help---
|
||||
Enable hardware assisted support for ECC calculations
|
||||
|
||||
if SAMA5_EBICS1_HWECC
|
||||
choice
|
||||
prompt "H/W ECC method"
|
||||
default SAMA5_EBICS1_PMECC
|
||||
|
||||
config SAMA5_EBICS1_PMECC
|
||||
bool "PMECC"
|
||||
|
||||
config SAMA5_EBICS1_HSIAO
|
||||
bool "HSIAO ECC"
|
||||
|
||||
endchoice # H/W ECC method
|
||||
endif # SAMA5_EBICS1_HWECC
|
||||
endif # SAMA5_EBICS1_NAND && MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC
|
||||
endif # SAMA5_EBICS1
|
||||
|
||||
config SAMA5_EBICS2
|
||||
@@ -3143,6 +3187,28 @@ config SAMA5_EBICS2_NAND
|
||||
select MTD_NAND
|
||||
|
||||
endchoice # CS2 Memory Type
|
||||
|
||||
if SAMA5_EBICS2_NAND && MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC
|
||||
config SAMA5_EBICS2_HWECC
|
||||
bool "NAND H/W ECC support"
|
||||
default n
|
||||
---help---
|
||||
Enable hardware assisted support for ECC calculations
|
||||
|
||||
if SAMA5_EBICS2_HWECC
|
||||
choice
|
||||
prompt "H/W ECC method"
|
||||
default SAMA5_EBICS2_PMECC
|
||||
|
||||
config SAMA5_EBICS2_PMECC
|
||||
bool "PMECC"
|
||||
|
||||
config SAMA5_EBICS2_HSIAO
|
||||
bool "HSIAO ECC"
|
||||
|
||||
endchoice # H/W ECC method
|
||||
endif # SAMA5_EBICS2_HWECC
|
||||
endif # SAMA5_EBICS2_NAND && MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC
|
||||
endif # SAMA5_EBICS2
|
||||
|
||||
config SAMA5_EBICS3
|
||||
@@ -3194,6 +3260,28 @@ config SAMA5_EBICS3_NAND
|
||||
select MTD_NAND
|
||||
|
||||
endchoice # CS3 Memory Type
|
||||
|
||||
if SAMA5_EBICS3_NAND && MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC
|
||||
config SAMA5_EBICS3_HWECC
|
||||
bool "NAND H/W ECC support"
|
||||
default n
|
||||
---help---
|
||||
Enable hardware assisted support for ECC calculations
|
||||
|
||||
if SAMA5_EBICS3_HWECC
|
||||
choice
|
||||
prompt "H/W ECC method"
|
||||
default SAMA5_EBICS3_PMECC
|
||||
|
||||
config SAMA5_EBICS3_PMECC
|
||||
bool "PMECC"
|
||||
|
||||
config SAMA5_EBICS3_HSIAO
|
||||
bool "HSIAO ECC"
|
||||
|
||||
endchoice # H/W ECC method
|
||||
endif # SAMA5_EBICS3_HWECC
|
||||
endif # SAMA5_EBICS3_NAND && MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC
|
||||
endif # SAMA5_EBICS3
|
||||
|
||||
if SAMA5_EBICS0_NAND || SAMA5_EBICS1_NAND || SAMA5_EBICS2_NAND || SAMA5_EBICS3_NAND
|
||||
|
||||
@@ -88,6 +88,24 @@ struct sam_rawnand_s
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
/* NAND Helpers */
|
||||
|
||||
static int nand_readpage_noecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, void *data, void *spare);
|
||||
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
static int nand_readpage_hwecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, void *data, void *spare);
|
||||
static int nand_readpage_pmecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, void *data, void *spare);
|
||||
#endif
|
||||
static int nand_writepage_noecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, const void *data, const void *spare);
|
||||
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
static int nand_writepage_hwecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, const void *data, const void *spare);
|
||||
static int nand_writepage_pmecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, const void *data, const void *spare);
|
||||
#endif
|
||||
|
||||
/* MTD driver methods */
|
||||
|
||||
@@ -121,6 +139,171 @@ static struct sam_rawnand_s g_cs3nand;
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_readpage_noecc
|
||||
*
|
||||
* Description:
|
||||
* Reads the data and/or the spare areas of a page of a NAND FLASH into the
|
||||
* provided buffers. The raw NAND contents are returned with no ECC
|
||||
* corrections.
|
||||
*
|
||||
* Input parameters:
|
||||
* priv - Lower-half, private NAND FLASH device state
|
||||
* block - Number of the block where the page to read resides.
|
||||
* page - Number of the page to read inside the given block.
|
||||
* data - Buffer where the data area will be stored.
|
||||
* spare - Buffer where the spare area will be stored.
|
||||
*
|
||||
* Returned value.
|
||||
* OK is returned in succes; a negated errno value is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int nand_readpage_noecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, void *data, void *spare)
|
||||
{
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_readpage_hwecc
|
||||
*
|
||||
* Description:
|
||||
* Reads the data and/or the spare areas of a page of a NAND FLASH into the
|
||||
* provided buffers. HSIAO ECC is used
|
||||
*
|
||||
* Input parameters:
|
||||
* priv - Lower-half, private NAND FLASH device state
|
||||
* block - Number of the block where the page to read resides.
|
||||
* page - Number of the page to read inside the given block.
|
||||
* data - Buffer where the data area will be stored.
|
||||
* spare - Buffer where the spare area will be stored.
|
||||
*
|
||||
* Returned value.
|
||||
* OK is returned in succes; a negated errno value is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
static int nand_readpage_hwecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, void *data, void *spare)
|
||||
{
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_MTD_NAND_BLOCKCHECK */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_readpage_pmecc
|
||||
*
|
||||
* Description:
|
||||
* Reads the data and/or the spare areas of a page of a NAND FLASH into the
|
||||
* provided buffers. PMECC is used
|
||||
*
|
||||
* Input parameters:
|
||||
* priv - Lower-half, private NAND FLASH device state
|
||||
* block - Number of the block where the page to read resides.
|
||||
* page - Number of the page to read inside the given block.
|
||||
* data - Buffer where the data area will be stored.
|
||||
* spare - Buffer where the spare area will be stored.
|
||||
*
|
||||
* Returned value.
|
||||
* OK is returned in succes; a negated errno value is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
static int nand_readpage_pmecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, void *data, void *spare)
|
||||
{
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_MTD_NAND_BLOCKCHECK */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_writepage_noecc
|
||||
*
|
||||
* Description:
|
||||
* Writes the data and/or the spare area of a page on a NAND FLASH chip.
|
||||
* No ECC calculations are performed.
|
||||
*
|
||||
* Input parameters:
|
||||
* priv - Lower-half, private NAND FLASH device state
|
||||
* block - Number of the block where the page to write resides.
|
||||
* page - Number of the page to write inside the given block.
|
||||
* data - Buffer containing the data to be writting
|
||||
* spare - Buffer conatining the spare data to be written.
|
||||
*
|
||||
* Returned value.
|
||||
* OK is returned in succes; a negated errno value is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int nand_writepage_noecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, const void *data, const void *spare)
|
||||
{
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_writepage_noecc
|
||||
*
|
||||
* Description:
|
||||
* Writes the data and/or the spare area of a page on a NAND FLASH chip.
|
||||
* HSIAO ECC calculations are performed.
|
||||
*
|
||||
* Input parameters:
|
||||
* priv - Lower-half, private NAND FLASH device state
|
||||
* block - Number of the block where the page to write resides.
|
||||
* page - Number of the page to write inside the given block.
|
||||
* data - Buffer containing the data to be writting
|
||||
* spare - Buffer conatining the spare data to be written.
|
||||
*
|
||||
* Returned value.
|
||||
* OK is returned in succes; a negated errno value is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
static int nand_writepage_hwecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, const void *data, const void *spare)
|
||||
{
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_MTD_NAND_BLOCKCHECK */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_writepage_noecc
|
||||
*
|
||||
* Description:
|
||||
* Writes the data and/or the spare area of a page on a NAND FLASH chip.
|
||||
* PMECC calculations are performed.
|
||||
*
|
||||
* Input parameters:
|
||||
* priv - Lower-half, private NAND FLASH device state
|
||||
* block - Number of the block where the page to write resides.
|
||||
* page - Number of the page to write inside the given block.
|
||||
* data - Buffer containing the data to be writting
|
||||
* spare - Buffer conatining the spare data to be written.
|
||||
*
|
||||
* Returned value.
|
||||
* OK is returned in succes; a negated errno value is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
static int nand_writepage_pmecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, const void *data, const void *spare)
|
||||
{
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_MTD_NAND_BLOCKCHECK */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_eraseblock
|
||||
*
|
||||
@@ -168,8 +351,25 @@ static int nand_readpage(struct nand_raw_s *raw, off_t block,
|
||||
{
|
||||
struct sam_rawnand_s *priv = (struct sam_rawnand_s *)raw;
|
||||
DEBUGASSERT(raw);
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
|
||||
#ifndef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
return nand_readpage_noecc(priv, block, page, data, spare);
|
||||
#else
|
||||
DEBUGASSERT(raw->ecctype != NANDECC_SWECC);
|
||||
switch (raw->ecctype)
|
||||
{
|
||||
case NANDECC_NONE:
|
||||
return nand_readpage_noecc(priv, block, page, data, spare);
|
||||
case NANDECC_HWECC:
|
||||
return nand_readpage_hwecc(priv, block, page, data, spare);
|
||||
case NANDECC_PMECC:
|
||||
return nand_readpage_pmecc(priv, block, page, data, spare);
|
||||
|
||||
case NANDECC_SWECC:
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -196,8 +396,25 @@ static int nand_writepage(struct nand_raw_s *raw, off_t block,
|
||||
{
|
||||
struct sam_rawnand_s *priv = (struct sam_rawnand_s *)raw;
|
||||
DEBUGASSERT(raw);
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
|
||||
#ifndef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
return nand_writepage_noecc(priv, block, page, data, spare);
|
||||
#else
|
||||
DEBUGASSERT(raw->ecctype != NANDECC_SWECC);
|
||||
switch (raw->ecctype)
|
||||
{
|
||||
case NANDECC_NONE:
|
||||
return nand_writepage_noecc(priv, block, page, data, spare);
|
||||
case NANDECC_HWECC:
|
||||
return nand_writepage_hwecc(priv, block, page, data, spare);
|
||||
case NANDECC_PMECC:
|
||||
return nand_writepage_pmecc(priv, block, page, data, spare);
|
||||
|
||||
case NANDECC_SWECC:
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -226,7 +443,7 @@ static int nand_writepage(struct nand_raw_s *raw, off_t block,
|
||||
struct mtd_dev_s *sam_nand_initialize(int cs)
|
||||
{
|
||||
struct sam_rawnand_s *priv;
|
||||
struct mtd_s *mtd;
|
||||
struct mtd_dev_s *mtd;
|
||||
uintptr_t cmdaddr;
|
||||
uintptr_t addraddr;
|
||||
uintptr_t dataaddr;
|
||||
|
||||
+8
-6
@@ -139,12 +139,6 @@ config MTD_NAND_HWECC
|
||||
---help---
|
||||
Build in logic to support hardware calculation of ECC.
|
||||
|
||||
config MTD_NAND_MAXSPAREEXTRABYTES
|
||||
int "Max extra free bytes"
|
||||
default 206
|
||||
---help---
|
||||
Maximum number of extra free bytes inside the spare area of a page.
|
||||
|
||||
config MTD_NAND_MAX_HWECCSIZE
|
||||
int "Max H/W ECC size"
|
||||
default 200
|
||||
@@ -152,6 +146,14 @@ config MTD_NAND_MAX_HWECCSIZE
|
||||
---help---
|
||||
Maximum HW ECC size
|
||||
|
||||
config MTD_NAND_MAXSPAREEXTRABYTES
|
||||
int "Max extra free bytes"
|
||||
default 206
|
||||
---help---
|
||||
Maximum number of extra free bytes inside the spare area of a page.
|
||||
|
||||
endif # MTD_NAND_BLOCKCHECK
|
||||
|
||||
config MTD_NAND_EMBEDDEDECC
|
||||
bool "Support devices with Embedded ECC"
|
||||
default n
|
||||
|
||||
@@ -407,7 +407,7 @@ void hamming_compute256x(FAR const uint8_t *data, size_t size, uint8_t *code)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int hamming_verify256x(uint8_t *data, size_t size, const uint8_t *code)
|
||||
int hamming_verify256x(FAR uint8_t *data, size_t size, FAR const uint8_t *code)
|
||||
{
|
||||
ssize_t remaining = (ssize_t)size;
|
||||
int result = HAMMING_SUCCESS;
|
||||
|
||||
@@ -432,7 +432,7 @@ static int nand_readpage(FAR struct nand_dev_s *nand, off_t block,
|
||||
/* nandecc_readpage will handle the software ECC case */
|
||||
|
||||
DEBUGASSERT(nand && nand->raw);
|
||||
if (nand->raw->ecc == NANDECC_SWECC)
|
||||
if (nand->raw->ecctype == NANDECC_SWECC)
|
||||
{
|
||||
/* Read data with software ECC verification */
|
||||
|
||||
@@ -485,7 +485,7 @@ static int nand_writepage(FAR struct nand_dev_s *nand, off_t block,
|
||||
/* nandecc_writepage will handle the software ECC case */
|
||||
|
||||
DEBUGASSERT(nand && nand->raw);
|
||||
if (nand->raw->ecc == NANDECC_SWECC)
|
||||
if (nand->raw->ecctype == NANDECC_SWECC)
|
||||
{
|
||||
/* Write data with software ECC calculation */
|
||||
|
||||
|
||||
+121
-4
@@ -48,10 +48,14 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/mtd/nand.h>
|
||||
#include <nuttx/mtd/hamming.h>
|
||||
#include <nuttx/mtd/nand_scheme.h>
|
||||
#include <nuttx/mtd/nand_ecc.h>
|
||||
|
||||
/****************************************************************************
|
||||
@@ -86,8 +90,68 @@
|
||||
int nandecc_readpage(FAR struct nand_dev_s *nand, off_t block,
|
||||
unsigned int page, FAR void *data, FAR void *spare)
|
||||
{
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
FAR struct nand_raw_s *raw;
|
||||
FAR struct nand_model_s *model;
|
||||
FAR const struct nand_scheme_s *scheme;
|
||||
unsigned int pagesize;
|
||||
unsigned int sparesize;
|
||||
int ret;
|
||||
|
||||
/* Get convenience pointers */
|
||||
|
||||
DEBUGASSERT(nand && nand->raw);
|
||||
raw = nand->raw;
|
||||
model = &raw->model;
|
||||
|
||||
/* Get size parameters */
|
||||
|
||||
pagesize = nandmodel_getpagesize(model);
|
||||
sparesize = nandmodel_getsparesize(model);
|
||||
|
||||
/* Store code in spare buffer, either the buffer provided by the caller or
|
||||
* the scatch buffer in the raw NAND structure.
|
||||
*/
|
||||
|
||||
if (!spare)
|
||||
{
|
||||
spare = raw->spare;
|
||||
memset(spare, 0xff, sparesize);
|
||||
}
|
||||
|
||||
/* Start by reading the spare data */
|
||||
|
||||
ret = NAND_READPAGE(raw, block, page, 0, spare);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: Failed to read page:d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Then reading the data */
|
||||
|
||||
ret = NAND_READPAGE(nand->raw, block, page, data, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: Failed to read page:d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Retrieve ECC information from page */
|
||||
|
||||
scheme = nandmodel_getscheme(model);
|
||||
nandscheme_readecc(scheme, spare, raw->ecc);
|
||||
|
||||
/* Use the ECC data to verify the page */
|
||||
|
||||
ret = hamming_verify256x(data, pagesize, raw->ecc);
|
||||
if (ret && (ret != HAMMING_ERROR_SINGLEBIT))
|
||||
{
|
||||
fdbg("ERROR: Blockd paged Unrecoverable error:d\n",
|
||||
block, page, ret);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -116,6 +180,59 @@ int nandecc_writepage(FAR struct nand_dev_s *nand, off_t block,
|
||||
unsigned int page, FAR const void *data,
|
||||
FAR void *spare)
|
||||
{
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
FAR struct nand_raw_s *raw;
|
||||
FAR struct nand_model_s *model;
|
||||
FAR const struct nand_scheme_s *scheme;
|
||||
unsigned int pagesize;
|
||||
unsigned int sparesize;
|
||||
int ret;
|
||||
|
||||
/* Get convenience pointers */
|
||||
|
||||
DEBUGASSERT(nand && nand->raw);
|
||||
raw = nand->raw;
|
||||
model = &raw->model;
|
||||
|
||||
/* Get size parameters */
|
||||
|
||||
pagesize = nandmodel_getpagesize(model);
|
||||
sparesize = nandmodel_getsparesize(model);
|
||||
|
||||
/* Set hamming code set to 0xffff.. to keep existing bytes */
|
||||
|
||||
memset(raw->ecc, 0xff, CONFIG_MTD_NAND_MAXSPAREECCBYTES);
|
||||
|
||||
/* Compute ECC on the new data, if provided */
|
||||
|
||||
if (data)
|
||||
{
|
||||
/* Compute hamming code on data */
|
||||
|
||||
hamming_compute256x(data, pagesize, raw->ecc);
|
||||
}
|
||||
|
||||
/* Store code in spare buffer, either the buffer provided by the caller or
|
||||
* the scatch buffer in the raw NAND structure.
|
||||
*/
|
||||
|
||||
if (!spare)
|
||||
{
|
||||
spare = raw->spare;
|
||||
memset(spare, 0xff, sparesize);
|
||||
}
|
||||
|
||||
/* Write the ECC */
|
||||
|
||||
scheme = nandmodel_getscheme(model);
|
||||
nandscheme_writeecc(scheme, spare, raw->ecc);
|
||||
|
||||
/* Perform page write operation */
|
||||
|
||||
ret = NAND_WRITEPAGE(nand->raw, block, page, data, spare);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: Failed to write page:d\n", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -96,6 +96,46 @@ extern "C"
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hamming_compute256x
|
||||
*
|
||||
* Description:
|
||||
* Computes 3-bytes hamming codes for a data block whose size is multiple
|
||||
* of 256 bytes. Each 256 bytes block gets its own code.
|
||||
*
|
||||
* Input Parameters:
|
||||
* data - Data to compute code for
|
||||
* size - Data size in bytes
|
||||
* code - Codes buffer
|
||||
*
|
||||
* Returned Values:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void hamming_compute256x(FAR const uint8_t *data, size_t size, uint8_t *code);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hamming_verify256x
|
||||
*
|
||||
* Description:
|
||||
* Verifies 3-bytes hamming codes for a data block whose size is multiple
|
||||
* of 256 bytes. Each 256-bytes block is verified with its own code.
|
||||
*
|
||||
* Input Parameters:
|
||||
* data - Data buffer to verify
|
||||
* size - Size of the data in bytes
|
||||
* code - Original codes
|
||||
*
|
||||
* Returned Values:
|
||||
* Return 0 if the data is correct, HAMMING_ERROR_SINGLEBIT if one or more
|
||||
* block(s) have had a single bit corrected, or either HAMMING_ERROR_ECC
|
||||
* or HAMMING_ERROR_MULTIPLEBITS.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int hamming_verify256x(FAR uint8_t *data, size_t size, FAR const uint8_t *code);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ struct nand_dev_s
|
||||
{
|
||||
struct mtd_dev_s mtd; /* Externally visible part of the driver */
|
||||
FAR struct nand_raw_s *raw; /* Retained reference to the lower half */
|
||||
sem_t exclsem; /* For exclusive access to the NAND flas */
|
||||
sem_t exclsem; /* For exclusive access to the NAND FLASH */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/mtd/nand_config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
@@ -81,13 +82,19 @@
|
||||
#define COMMAND_READ_A 0x00
|
||||
#define COMMAND_READ_C 0x50
|
||||
|
||||
/* Type of ECC to be performed (must be enabled in the configuration)
|
||||
/* Type of ECC to be performed (may also need to be enabled in the
|
||||
* configuration)
|
||||
*
|
||||
* NANDECC_NONE No ECC, only raw NAND FLASH accesses
|
||||
* NANDECC_SWECC Software ECC. Handled by the common MTD logic.
|
||||
* NANDECC_HWECC Values >= 2 are various hardware ECC implementations
|
||||
* all handled by the lower-half, raw NAND FLASH driver.
|
||||
* These hardware ECC types may be extended beginning
|
||||
* with the value NANDECC_HWECC.
|
||||
*
|
||||
* Software ECC is performed by common, upper-half MTD logic; All
|
||||
* hardware assisted ECC operations are handled by the platform-specific,
|
||||
* lower-half driver.
|
||||
*/
|
||||
|
||||
#define NANDECC_NONE 0
|
||||
@@ -191,12 +198,6 @@ struct nand_raw_s
|
||||
uintptr_t addraddr; /* NAND address address base */
|
||||
uintptr_t dataaddr; /* NAND data address */
|
||||
|
||||
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
/* ECC */
|
||||
|
||||
uint8_t ecc; /* See enum nand_ecc_e */
|
||||
#endif
|
||||
|
||||
/* NAND operations */
|
||||
|
||||
CODE int (*eraseblock)(FAR struct nand_raw_s *raw, off_t block);
|
||||
@@ -205,6 +206,15 @@ struct nand_raw_s
|
||||
CODE int (*writepage)(FAR struct nand_raw_s *raw, off_t block,
|
||||
unsigned int page, FAR const void *data,
|
||||
FAR const void *spare);
|
||||
|
||||
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
/* ECC */
|
||||
|
||||
uint8_t ecctype; /* See enum nand_ecc_e */
|
||||
uint8_t spare[CONFIG_MTD_NAND_MAXPAGESPARESIZE];
|
||||
uint8_t ecc[CONFIG_MTD_NAND_MAXSPAREECCBYTES];
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
Reference in New Issue
Block a user