Reformat to kblock api.
authorasterix <asterix@38d2e660-2303-0410-9eaa-f027e97ec537>
Wed, 11 Aug 2010 14:41:57 +0000 (14:41 +0000)
committerasterix <asterix@38d2e660-2303-0410-9eaa-f027e97ec537>
Wed, 11 Aug 2010 14:41:57 +0000 (14:41 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4166 38d2e660-2303-0410-9eaa-f027e97ec537

bertos/cpu/arm/drv/flash_at91.c
bertos/cpu/arm/drv/flash_at91.h

index 83cc73b7aaf110505f286a03291336b56bb024a8..50b8ccb4041c2cd1f409a58757f6a500bd71361d 100644 (file)
 
 #include "flash_at91.h"
 
-#include "cfg/cfg_flash_at91.h"
+#include "cfg/cfg_emb_flash.h"
 #include <cfg/macros.h>
 
-#include "hw/hw_boot.h"
-
 // Define log settings for cfg/log.h
-#define LOG_LEVEL    CONFIG_FLASH_AT91_LOG_LEVEL
-#define LOG_FORMAT   CONFIG_FLASH_AT91_LOG_FORMAT
+#define LOG_LEVEL    CONFIG_FLASH_EMB_LOG_LEVEL
+#define LOG_FORMAT   CONFIG_FLASH_EMB_LOG_FORMAT
 #include <cfg/log.h>
 
-
 #include <cpu/irq.h>
 #include <cpu/attr.h>
 #include <cpu/power.h>
 
 #include <io/kfile.h>
-
+#include <io/kblock.h>
 #include <io/arm.h>
 
 #include <drv/timer.h>
 
 #include <string.h>
 
-#define FLASH_START_PAGE DIV_ROUNDUP(FLASH_BOOT_SIZE, FLASH_PAGE_SIZE_BYTES)
-#define FLASH_START_ADDR (FLASH_START_PAGE * FLASH_PAGE_SIZE_BYTES)
+struct FlashHardware
+{
+       uint8_t status;
+};
+
 
 /**
  * Really send the flash write command.
- * 
- * \note This function has to be placed in RAM because 
+ *
+ * \note This function has to be placed in RAM because
  *       executing code from flash while a writing process
  *       is in progress is forbidden.
- */ 
+ */
 RAM_FUNC NOINLINE static void write_page(uint32_t page)
 {
        // Send the 'write page' command
@@ -90,9 +90,9 @@ RAM_FUNC NOINLINE static void write_page(uint32_t page)
  * Send write command.
  *
  * After WR command cpu write bufferd page into flash memory.
- * 
+ *
  */
-INLINE void flash_at91_sendWRcmd(uint32_t page)
+INLINE void flash_sendWRcmd(uint32_t page)
 {
        cpu_flags_t flags;
 
@@ -106,173 +106,137 @@ INLINE void flash_at91_sendWRcmd(uint32_t page)
 }
 
 /**
- * Return 0 if no error are occurred after flash memory
+ * Return true if no error are occurred after flash memory
  * read or write operation, otherwise return error code.
  */
-static int flash_at91_getStatus(UNUSED_ARG(struct KFile *, _fd))
+static bool flash_getStatus(struct KBlock *blk)
 {
-       /*
-        * This bit is set to one if we programming of at least one locked lock
-        * region.
-        */
-       if(MC_FSR & BV(MC_LOCKE))
-               return -1;
-
+       Flash *fls = FLASH_CAST(blk);
        /*
         * This bit is set to one if an invalid command and/or a bad keywords was/were
         * written in the Flash Command Register.
         */
        if(MC_FSR & BV(MC_PROGE))
-               return -2;
-
-       return 0;
-}
-
-
-/**
- * Write modified page on internal latch, and then send write command to
- * flush page to internal flash.
- */
-static int flash_at91_flush(KFile *_fd)
-{
-       Flash *fd = FLASH_CAST(_fd);
-       if (fd->page_dirty)
        {
-               //Compute page address of current page.
-               page_addr_t *addr = (page_addr_t *)((fd->curr_page * FLASH_PAGE_SIZE_BYTES) + FLASH_BASE);
-
-               //Copy modified page into internal latch.
-               for (page_addr_t page_addr = 0; page_addr < FLASH_PAGE_SIZE_BYTES; page_addr += 4)
-               {
-                       // This is needed in order to have a single 32bit write instruction in addr.
-                       // (8 and 16 writes cause unpredictable results).
-                       uint32_t data;
-                       memcpy(&data, &fd->page_buf[page_addr], sizeof(data));
-                       *addr++ = data;
-               }
-
-               // Send write command to transfer page from latch to internal flash memory.
-               flash_at91_sendWRcmd(fd->curr_page);
-               fd->page_dirty = false;
+               fls->hw->status |= FLASH_WR_ERR;
+               LOG_ERR("flash not erased..\n");
+               return false;
        }
-       return 0;
-}
-
 
-/**
- * Check current page and if \a page is different, load it in
- * temporary buffer.
- */
-static void flash_at91_loadPage(Flash *fd, page_t page)
-{
-       if (page != fd->curr_page)
+       /*
+        * This bit is set to one if we programming of at least one locked lock
+        * region.
+        */
+       if(MC_FSR & BV(MC_LOCKE))
        {
-               flash_at91_flush(&fd->fd);
-               // Load page
-               memcpy(fd->page_buf, (char *)((page * FLASH_PAGE_SIZE_BYTES) + FLASH_BASE), FLASH_PAGE_SIZE_BYTES);
-               fd->curr_page = page;
-               LOG_INFO("Loaded page %lu\n", fd->curr_page);
+               fls->hw->status |= FLASH_WR_PROTECT;
+               LOG_ERR("wr protect..\n");
+               return false;
        }
-}
 
+       return true;
+}
 
-/**
- * Write program memory.
- * Write \a size bytes from buffer \a _buf to file \a fd
- * \note Write operations are buffered.
- */
-static size_t flash_at91_write(struct KFile *_fd, const void *_buf, size_t size)
+static size_t at91_flash_readDirect(struct KBlock *blk, block_idx_t idx, void *buf, size_t offset, size_t size)
 {
-       Flash *fd = FLASH_CAST(_fd);
-       const uint8_t *buf =(const uint8_t *)_buf;
+       ASSERT(offset == 0);
+       ASSERT(size == blk->blk_size);
 
-       page_t page;
-       page_addr_t page_addr;
-       size_t total_write = 0;
+       memcpy(buf, (void *)(idx * blk->blk_size), size);
+       return size;
+}
 
-       size = MIN((kfile_off_t)size, fd->fd.size - fd->fd.seek_pos);
+static size_t at91_flash_writeDirect(struct KBlock *blk, block_idx_t idx, const void *_buf, size_t offset, size_t size)
+{
+       ASSERT(offset == 0);
+       ASSERT(size == blk->blk_size);
+
+       uint32_t *addr = (uint32_t *)(idx * blk->blk_size);
+       const uint8_t *buf = (const uint8_t *)_buf;
 
-       LOG_INFO("Writing at pos[%lu]\n", fd->fd.seek_pos);
        while (size)
        {
-               page = (fd->fd.seek_pos + FLASH_START_ADDR) / FLASH_PAGE_SIZE_BYTES;
-               page_addr = (fd->fd.seek_pos + FLASH_START_ADDR) % FLASH_PAGE_SIZE_BYTES;
+               uint32_t data = (*(buf + 3) << 24) |
+                                               (*(buf + 2) << 16) |
+                                               (*(buf + 1) << 8)  |
+                                               *buf;
+               *addr = data;
+
+               size -= 4;
+               buf += 4;
+               addr += 4;
+       }
 
-               flash_at91_loadPage(fd, page);
+       flash_sendWRcmd(idx);
 
-               size_t wr_len = MIN(size, (size_t)(FLASH_PAGE_SIZE_BYTES - page_addr));
+       if (!flash_getStatus(blk))
+               return 0;
 
-               memcpy(fd->page_buf + page_addr, buf, wr_len);
-               fd->page_dirty = true;
+       return blk->blk_size;
+}
 
-               buf += wr_len;
-               fd->fd.seek_pos += wr_len;
-               size -= wr_len;
-               total_write += wr_len;
-       }
-       LOG_INFO("written %u bytes\n", total_write);
-       return total_write;
+
+static int at91_flash_error(struct KBlock *blk)
+{
+       Flash *fls = FLASH_CAST(blk);
+       return fls->hw->status;
 }
 
-/**
- * Open flash file \a fd
- * \a name and \a mode are unused, cause flash memory is
- * threated like one file.
- */
-static void flash_at91_open(struct Flash *fd)
+static void at91_flash_clearerror(struct KBlock *blk)
 {
-       fd->curr_page = FLASH_START_PAGE;
-       fd->fd.size = FLASH_MEM_SIZE - fd->curr_page * FLASH_PAGE_SIZE_BYTES;
-       fd->fd.seek_pos = 0;
-       
-       memcpy(fd->page_buf, (char *)((fd->curr_page * FLASH_PAGE_SIZE_BYTES) + FLASH_BASE), FLASH_PAGE_SIZE_BYTES);
-
-       fd->page_dirty = false;
-       LOG_INFO("Flash file opened, pos %ld, size %ld\n", fd->fd.seek_pos, fd->fd.size);
+       Flash *fls = FLASH_CAST(blk);
+       fls->hw->status = 0;
 }
 
-/**
- * Read from file \a fd \a size bytes and put it in buffer \a buf
- * \return the number of bytes read.
- */
-static size_t flash_at91_read(struct KFile *_fd, void *_buf, size_t size)
+static const KBlockVTable flash_at91_buffered_vt =
 {
-       Flash *fd = FLASH_CAST(_fd);
-       uint8_t *buf =(uint8_t *)_buf;
+       .readDirect = at91_flash_readDirect,
+       .writeDirect = at91_flash_writeDirect,
 
-       size = MIN((kfile_off_t)size, fd->fd.size - fd->fd.seek_pos);
+       .readBuf = kblock_swReadBuf,
+       .writeBuf = kblock_swWriteBuf,
+       .load = kblock_swLoad,
+       .store = kblock_swStore,
 
-       LOG_INFO("Reading at pos[%lu]\n", fd->fd.seek_pos);
+       .error = at91_flash_error,
+       .clearerr = at91_flash_clearerror,
+};
 
-       // Flush current buffered page (if modified).
-       flash_at91_flush(&fd->fd);
+static const KBlockVTable flash_at91_unbuffered_vt =
+{
+       .readDirect = at91_flash_readDirect,
+       .writeDirect = at91_flash_writeDirect,
 
-       kfile_off_t *addr = (kfile_off_t *)(fd->fd.seek_pos + FLASH_START_ADDR);
-       memcpy(buf, addr, size);
+       .error = at91_flash_error,
+       .clearerr = at91_flash_clearerror,
+};
 
-       fd->fd.seek_pos += size;
+static struct FlashHardware flash_at91_hw;
+static uint8_t flash_buf[FLASH_PAGE_SIZE_BYTES];
+
+static void common_init(Flash *fls)
+{
+       memset(fls, 0, sizeof(*fls));
+       DB(fls->blk.priv.type = KBT_FLASH);
+
+       fls->hw = &flash_at91_hw;
+
+       fls->blk.blk_size = FLASH_PAGE_SIZE_BYTES;
+       fls->blk.blk_cnt = FLASH_MEM_SIZE / FLASH_PAGE_SIZE_BYTES;
 
-       LOG_INFO("Read %u bytes\n", size);
-       return size;
 }
 
+void flash_hw_init(Flash *fls)
+{
+       common_init(fls);
+       fls->blk.priv.vt = &flash_at91_buffered_vt;
+       fls->blk.priv.flags |= KB_BUFFERED | KB_PARTIAL_WRITE;
+       fls->blk.priv.buf = flash_buf;
+}
 
-/**
- * Init module to perform write and read operation on internal
- * flash memory.
- */
-void flash_hw_init(struct Flash *fd)
+void flash_hw_initUnbuffered(Flash *fls)
 {
-       memset(fd, 0, sizeof(*fd));
-       // Init base class.
-       kfile_init(&fd->fd);
-       DB(fd->fd._type = KFT_FLASH);
-
-       // Set up flash programming functions.
-       fd->fd.write = flash_at91_write;
-       fd->fd.read = flash_at91_read;
-       fd->fd.error = flash_at91_getStatus;
-       fd->fd.flush = flash_at91_flush;
-
-       flash_at91_open(fd);
+       common_init(fls);
+       fls->blk.priv.vt = &flash_at91_unbuffered_vt;
 }
+
index 1bb7d94b4fb63777f8d63e6355723161d3e9fb0d..a706e5e5d10a8c4d2e431170e809d5dc89f67702 100644 (file)
 #ifndef FLASH_AT91_H
 #define FLASH_AT91_H
 
-#include <cpu/types.h>
+#include "cfg/cfg_emb_flash.h"
 
-#include <io/kfile.h>
+#if !CONFIG_FLASH_DISABLE_OLD_API
 
-#include <io/arm.h>
-
-
-#define FLASH_PAGE_SIZE FLASH_PAGE_SIZE_BYTES
-
-/**
- * Define data type to manage page and memory address.
- */
-typedef uint32_t page_t;
-typedef uint32_t page_addr_t;
-
-struct Flash;
-
-/**
- * FlashAt91 KFile context structure.
- *
- * DEPREACTED STRUCTURE!
- * Use EmbFlash instead
- *
- * \{
- */
-typedef struct FlashAt91
-{
-       /**
-        * File descriptor.
-        */
-       KFile fd;
-
-       /**
-        * Flag for checking if current page is modified.
-        */
-       bool page_dirty;
-
-       /**
-        * Current buffered page.
-        */
-       page_t curr_page;
-
-       /**
-        * Temporary buffer cointaing data block to
-        * write on flash.
-        */
-       uint8_t page_buf[FLASH_PAGE_SIZE_BYTES];
-} FlashAt91;
-/* \} */
-
-void flash_hw_init(struct Flash *fd);
-
-/**
- * WARNING!
- * This function is DEPRECADED!
- * use the emb_flash module instead.
- */
-INLINE void flash_at91_init(struct FlashAt91 *fd)
-{
-       flash_hw_init((struct Flash *)fd);
-}
+       /* For backwards compatibility */
+       #define FlashAt91  Flash
+       #define flash_at91_init(fls)   flash_init(fls);
+#endif /* !CONFIG_FLASH_DISABLE_OLD_API */
 
 #endif /* DRV_FLASH_ARM_H */