mt29f nand: fix kblock buffer initialization: load correctly all buffer.
[bertos.git] / bertos / cpu / cortex-m3 / drv / mt29f_sam3.c
index a8a3dcb5d1db5c6bac9df7eaecde3d5b991007b3..ce2fadedd8d9dac14a18a291701f5a14e21d9921 100644 (file)
@@ -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))
@@ -872,10 +882,13 @@ bool mt29f_init(Mt29f *chip, struct Heap *heap, unsigned chip_select)
        }
 
        // Load the first block in the cache
-       return mt29f_readDirect(&chip->fd, 0, chip->fd.priv.buf, 0, MT29F_DATA_SIZE);
+       return mt29f_readDirect(&chip->fd, 0, chip->fd.priv.buf, 0, chip->fd.blk_size);
 }
 
 
+/**
+ * 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;
 }
 
-