* signal.
* Return true for edge detection, false in case of timeout.
*/
-bool nand_waitReadyBusy(UNUSED_ARG(Mt29f *, chip), time_t timeout)
+bool nand_waitReadyBusy(UNUSED_ARG(Nand *, chip), time_t timeout)
{
time_t start = timer_clock();
* Wait for transfer to complete until timeout.
* If transfer completes return true, false in case of timeout.
*/
-bool nand_waitTransferComplete(UNUSED_ARG(Mt29f *, chip), time_t timeout)
+bool nand_waitTransferComplete(UNUSED_ARG(Nand *, chip), time_t timeout)
{
time_t start = timer_clock();
/*
* Send command to NAND and wait for completion.
*/
-void nand_sendCommand(Mt29f *chip,
+void nand_sendCommand(Nand *chip,
uint32_t cmd1, uint32_t cmd2,
int num_cycles, uint32_t cycle0, uint32_t cycle1234)
{
* NOTE: this is global between different chip selects, so returns
* the status register of the last used NAND chip.
*/
-uint8_t nand_getChipStatus(UNUSED_ARG(Mt29f *, chip))
+uint8_t nand_getChipStatus(UNUSED_ARG(Nand *, chip))
{
return (uint8_t)HWREG(NFC_CMD_BASE_ADDR);
}
-void *nand_dataBuffer(UNUSED_ARG(Mt29f *, chip))
+void *nand_dataBuffer(UNUSED_ARG(Nand *, chip))
{
return (void *)NFC_SRAM_BASE_ADDR;
}
-bool nand_checkEcc(Mt29f *chip)
+bool nand_checkEcc(Nand *chip)
{
uint32_t sr1 = SMC_ECC_SR1;
if (sr1)
* \param ecc pointer to buffer where computed ECC is stored
* \param ecc_size max size for ecc buffer
*/
-void nand_computeEcc(UNUSED_ARG(Mt29f *, chip),
+void nand_computeEcc(UNUSED_ARG(Nand *, chip),
UNUSED_ARG(const void *, buf), UNUSED_ARG(size_t, size), uint32_t *ecc, size_t ecc_size)
{
size_t i;
}
-void nand_hwInit(UNUSED_ARG(Mt29f *, chip))
+void nand_hwInit(UNUSED_ARG(Nand *, chip))
{
// FIXME: Parameters specific for MT29F8G08AAD
}
-static void chipReset(Mt29f *chip)
+static void chipReset(Nand *chip)
{
nand_sendCommand(chip, NAND_CMD_RESET, 0, 0, 0, 0);
nand_waitReadyBusy(chip, CONFIG_NAND_TMOUT);
}
-static bool isOperationComplete(Mt29f *chip)
+static bool isOperationComplete(Nand *chip)
{
uint8_t status;
/**
* Erase the whole block.
*/
-int nand_blockErase(Mt29f *chip, uint16_t block)
+int nand_blockErase(Nand *chip, uint16_t block)
{
uint32_t cycle0;
uint32_t cycle1234;
/**
* Read Device ID and configuration codes.
*/
-bool nand_getDevId(Mt29f *chip, uint8_t dev_id[5])
+bool nand_getDevId(Nand *chip, uint8_t dev_id[5])
{
nand_sendCommand(chip, NAND_CMD_READID, 0, 1, 0, 0);
}
-static bool nand_readPage(Mt29f *chip, uint32_t page, uint16_t offset)
+static bool nand_readPage(Nand *chip, uint32_t page, uint16_t offset)
{
uint32_t cycle0;
uint32_t cycle1234;
* Read page data and ECC, checking for errors.
* TODO: fix errors with ECC when possible.
*/
-static bool nand_read(Mt29f *chip, uint32_t page, void *buf, uint16_t offset, uint16_t size)
+static bool nand_read(Nand *chip, uint32_t page, void *buf, uint16_t offset, uint16_t size)
{
struct RemapInfo remap_info;
uint32_t remapped_page = PAGE(chip->block_map[BLOCK(page)]) + PAGE_IN_BLOCK(page);
* spare data in one write, at this point the last ECC_PR is correct and
* ECC data can be written in the spare area with a second program operation.
*/
-static bool nand_writePage(Mt29f *chip, uint32_t page, uint16_t offset)
+static bool nand_writePage(Nand *chip, uint32_t page, uint16_t offset)
{
uint32_t cycle0;
uint32_t cycle1234;
* For 2048 bytes pages and 1 ECC word each 256 bytes,
* 24 bytes of ECC data are stored.
*/
-static bool nand_write(Mt29f *chip, uint32_t page, const void *buf, size_t size)
+static bool nand_write(Nand *chip, uint32_t page, const void *buf, size_t size)
{
struct RemapInfo remap_info;
uint32_t *nand_buf = (uint32_t *)nand_dataBuffer(chip);
* that bad block are marked with "00" bytes on the spare area of the
* first page in block.
*/
-static bool blockIsGood(Mt29f *chip, uint16_t blk)
+static bool blockIsGood(Nand *chip, uint16_t blk)
{
uint8_t *first_byte = (uint8_t *)nand_dataBuffer(chip);
bool good;
* Return the main partition block remapped on given block in the remap
* partition (dest_blk).
*/
-static int getBadBlockFromRemapBlock(Mt29f *chip, uint16_t dest_blk)
+static int getBadBlockFromRemapBlock(Nand *chip, uint16_t dest_blk)
{
struct RemapInfo *remap_info = (struct RemapInfo *)nand_dataBuffer(chip);
* Set a block remapping: src_blk (a block in main data partition) is remappend
* on dest_blk (block in reserved remapped blocks partition).
*/
-static bool setMapping(Mt29f *chip, uint32_t src_blk, uint32_t dest_blk)
+static bool setMapping(Nand *chip, uint32_t src_blk, uint32_t dest_blk)
{
struct RemapInfo *remap_info = (struct RemapInfo *)nand_dataBuffer(chip);
* Get a new block from the remap partition to use as a substitute
* for a bad block.
*/
-static uint16_t getFreeRemapBlock(Mt29f *chip)
+static uint16_t getFreeRemapBlock(Nand *chip)
{
int blk;
/*
* Check if NAND is initialized.
*/
-static bool chipIsMarked(Mt29f *chip)
+static bool chipIsMarked(Nand *chip)
{
return getBadBlockFromRemapBlock(chip, NAND_NUM_USER_BLOCKS) != -1;
}
* All bad blocks found are remapped to the remap partition: each
* block in the remap partition used to remap bad blocks is marked.
*/
-static void initBlockMap(Mt29f *chip)
+static void initBlockMap(Nand *chip)
{
int b, last;
* \note DON'T USE on production chips: this function will try to erase
* factory marked bad blocks too.
*/
-void nand_format(Mt29f *chip)
+void nand_format(Nand *chip)
{
int b;
/*
* Create some bad blocks, erasing them and writing the bad block mark.
*/
-void nand_ruinSomeBlocks(Mt29f *chip)
+void nand_ruinSomeBlocks(Nand *chip)
{
int bads[] = { 7, 99, 555, 1003, 1004, 1432 };
unsigned i;
#endif
-static bool commonInit(Mt29f *chip, struct Heap *heap, unsigned chip_select)
+static bool commonInit(Nand *chip, struct Heap *heap, unsigned chip_select)
{
- memset(chip, 0, sizeof(Mt29f));
+ memset(chip, 0, sizeof(Nand));
DB(chip->fd.priv.type = KBT_NAND);
chip->fd.blk_size = NAND_BLOCK_SIZE;
static int nand_error(struct KBlock *kblk)
{
- Mt29f *chip = NAND_CAST(kblk);
+ Nand *chip = NAND_CAST(kblk);
return chip->status;
}
static void nand_clearError(struct KBlock *kblk)
{
- Mt29f *chip = NAND_CAST(kblk);
+ Nand *chip = NAND_CAST(kblk);
chip->status = 0;
}
/**
* Initialize NAND kblock driver in buffered mode.
*/
-bool nand_init(Mt29f *chip, struct Heap *heap, unsigned chip_select)
+bool nand_init(Nand *chip, struct Heap *heap, unsigned chip_select)
{
if (!commonInit(chip, heap, chip_select))
return false;
/**
* Initialize NAND kblock driver in unbuffered mode.
*/
-bool nand_initUnbuffered(Mt29f *chip, struct Heap *heap, unsigned chip_select)
+bool nand_initUnbuffered(Nand *chip, struct Heap *heap, unsigned chip_select)
{
if (!commonInit(chip, heap, chip_select))
return false;
/**
* NAND context.
*/
-typedef struct Mt29f
+typedef struct Nand
{
KBlock fd; // KBlock descriptor
uint16_t *block_map; // For bad blocks remapping
uint16_t remap_start; // First unused remap block
-} Mt29f;
+} Nand;
/*
* Kblock id.
/**
* Convert + ASSERT from generic KBlock to NAND context.
*/
-INLINE Mt29f *NAND_CAST(KBlock *kb)
+INLINE Nand *NAND_CAST(KBlock *kb)
{
ASSERT(kb->priv.type == KBT_NAND);
- return (Mt29f *)kb;
+ return (Nand *)kb;
}
struct Heap;
// Kblock interface
-bool nand_init(Mt29f *chip, struct Heap *heap, unsigned chip_select);
-bool nand_initUnbuffered(Mt29f *chip, struct Heap *heap, unsigned chip_select);
+bool nand_init(Nand *chip, struct Heap *heap, unsigned chip_select);
+bool nand_initUnbuffered(Nand *chip, struct Heap *heap, unsigned chip_select);
// NAND specific functions
-bool nand_getDevId(Mt29f *chip, uint8_t dev_id[5]);
-int nand_blockErase(Mt29f *chip, uint16_t block);
-void nand_format(Mt29f *chip);
+bool nand_getDevId(Nand *chip, uint8_t dev_id[5]);
+int nand_blockErase(Nand *chip, uint16_t block);
+void nand_format(Nand *chip);
#ifdef _DEBUG
-void nand_ruinSomeBlocks(Mt29f *chip);
+void nand_ruinSomeBlocks(Nand *chip);
#endif
// Hardware specific functions, implemented by cpu specific module
-bool nand_waitReadyBusy(Mt29f *chip, time_t timeout);
-bool nand_waitTransferComplete(Mt29f *chip, time_t timeout);
-void nand_sendCommand(Mt29f *chip, uint32_t cmd1, uint32_t cmd2,
+bool nand_waitReadyBusy(Nand *chip, time_t timeout);
+bool nand_waitTransferComplete(Nand *chip, time_t timeout);
+void nand_sendCommand(Nand *chip, uint32_t cmd1, uint32_t cmd2,
int num_cycles, uint32_t cycle0, uint32_t cycle1234);
-uint8_t nand_getChipStatus(Mt29f *chip);
-void *nand_dataBuffer(Mt29f *chip);
-bool nand_checkEcc(Mt29f *chip);
-void nand_computeEcc(Mt29f *chip, const void *buf, size_t size, uint32_t *ecc, size_t ecc_size);
-void nand_hwInit(Mt29f *chip);
+uint8_t nand_getChipStatus(Nand *chip);
+void *nand_dataBuffer(Nand *chip);
+bool nand_checkEcc(Nand *chip);
+void nand_computeEcc(Nand *chip, const void *buf, size_t size, uint32_t *ecc, size_t ecc_size);
+void nand_hwInit(Nand *chip);
#endif /* DRV_NAND_H */