From 82467ee43e75a2e14a23f5638fa0adc86e5895de Mon Sep 17 00:00:00 2001 From: aleph Date: Mon, 9 May 2011 10:56:27 +0000 Subject: [PATCH] mt29f nand: allow read (through kblock interface) at arbitrary offset and sizes, i.e. not multiple of the page size. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4883 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/cpu/cortex-m3/drv/mt29f_sam3.c | 40 +++++++++++++++++---------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/bertos/cpu/cortex-m3/drv/mt29f_sam3.c b/bertos/cpu/cortex-m3/drv/mt29f_sam3.c index a8a3dcb5..03f5109f 100644 --- a/bertos/cpu/cortex-m3/drv/mt29f_sam3.c +++ b/bertos/cpu/cortex-m3/drv/mt29f_sam3.c @@ -346,10 +346,12 @@ static bool mt29f_readPage(Mt29f *chip, uint32_t page, uint16_t offset) * Read page data and ECC, checking for errors. * TODO: fix errors with ECC when possible. */ -static bool mt29f_read(Mt29f *chip, uint32_t page, void *buf, uint16_t size) +static bool mt29f_read(Mt29f *chip, uint32_t page, void *buf, uint16_t offset, uint16_t size) { uint32_t remapped_page = PAGE(chip->block_map[BLOCK(page)]) + PAGE_IN_BLOCK(page); + //LOG_INFO("mt29f_read: page=%ld, offset=%d, size=%d\n", page, offset, size); + if (page != remapped_page) { LOG_INFO("mt29f_read: remapped block: blk %d->%d, pg %ld->%ld\n", @@ -360,7 +362,7 @@ static bool mt29f_read(Mt29f *chip, uint32_t page, void *buf, uint16_t size) if (!mt29f_readPage(chip, page, 0)) return false; - memcpy(buf, (void *)NFC_SRAM_BASE_ADDR, size); + memcpy(buf, (void *)(NFC_SRAM_BASE_ADDR + offset), size); return checkEcc(chip); } @@ -775,7 +777,7 @@ static size_t mt29f_writeDirect(struct KBlock *kblk, block_idx_t idx, const void ASSERT(size <= MT29F_BLOCK_SIZE); ASSERT(size % MT29F_DATA_SIZE == 0); - LOG_INFO("mt29f_writeDirect: blk=%ld\n", idx); + //LOG_INFO("mt29f_writeDirect: idx=%ld offset=%d size=%d\n", idx, offset, size); mt29f_blockErase(MT29F_CAST(kblk), idx); @@ -796,25 +798,30 @@ static size_t mt29f_writeDirect(struct KBlock *kblk, block_idx_t idx, const void static size_t mt29f_readDirect(struct KBlock *kblk, block_idx_t idx, void *buf, size_t offset, size_t size) { - ASSERT(offset <= MT29F_BLOCK_SIZE); - ASSERT(offset % MT29F_DATA_SIZE == 0); + uint32_t page; + size_t read_size; + size_t read_offset; + size_t nread = 0; + + ASSERT(offset < MT29F_BLOCK_SIZE); ASSERT(size <= MT29F_BLOCK_SIZE); - ASSERT(size % MT29F_DATA_SIZE == 0); - LOG_INFO("mt29f_readDirect: blk=%ld\n", idx); + //LOG_INFO("mt29f_readDirect: idx=%ld offset=%d size=%d\n", idx, offset, size); - while (offset < size) + while (nread < size) { - uint32_t page = PAGE(idx) + (offset / MT29F_DATA_SIZE); + page = PAGE(idx) + (offset / MT29F_DATA_SIZE); + read_offset = offset % MT29F_DATA_SIZE; + read_size = MIN(size, MT29F_DATA_SIZE - read_offset); - if (!mt29f_read(MT29F_CAST(kblk), page, buf, MT29F_DATA_SIZE)) + if (!mt29f_read(MT29F_CAST(kblk), page, (char *)buf + nread, read_offset, read_size)) break; - offset += MT29F_DATA_SIZE; - buf = (char *)buf + MT29F_DATA_SIZE; + offset += read_size; + nread += read_size; } - return offset; + return nread; } @@ -856,6 +863,9 @@ static const KBlockVTable mt29f_unbuffered_vt = }; +/** + * Initialize NAND kblock driver in buffered mode. + */ bool mt29f_init(Mt29f *chip, struct Heap *heap, unsigned chip_select) { if (!commonInit(chip, heap, chip_select)) @@ -876,6 +886,9 @@ bool mt29f_init(Mt29f *chip, struct Heap *heap, unsigned chip_select) } +/** + * Initialize NAND kblock driver in unbuffered mode. + */ bool mt29f_initUnbuffered(Mt29f *chip, struct Heap *heap, unsigned chip_select) { if (!commonInit(chip, heap, chip_select)) @@ -885,4 +898,3 @@ bool mt29f_initUnbuffered(Mt29f *chip, struct Heap *heap, unsigned chip_select) return true; } - -- 2.25.1