X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;ds=sidebyside;f=bertos%2Fcpu%2Fcortex-m3%2Fdrv%2Fflash_sam3.c;h=e26c39ece21b00e8ecb9a764a4494470170faafa;hb=2f2be617c1e2ccc0aaefbb2e56fb34046c645126;hp=fdafc2ae51ecb07b2a16f3977f94144fa145c03f;hpb=2d7a00fd39d1926c60ecfe615e100714797a5a79;p=bertos.git diff --git a/bertos/cpu/cortex-m3/drv/flash_sam3.c b/bertos/cpu/cortex-m3/drv/flash_sam3.c index fdafc2ae..e26c39ec 100644 --- a/bertos/cpu/cortex-m3/drv/flash_sam3.c +++ b/bertos/cpu/cortex-m3/drv/flash_sam3.c @@ -61,11 +61,6 @@ #include -#define FLASH_MEM_SIZE 0x80000UL ///< Internal flash memory size -#define FLASH_PAGE_SIZE_BYTES 256 ///< Size of cpu flash memory page in bytes -#define FLASH_BANKS_NUM 2 ///< Number of flash banks -#define FLASH_BASE 0x0 - struct FlashHardware { uint8_t status; @@ -79,7 +74,7 @@ struct FlashHardware * executing code from flash while a writing process * is in progress is forbidden. */ -RAM_FUNC NOINLINE static void write_page(uint32_t page) +RAM_FUNC NOINLINE static void write_page_bank(uint32_t page) { // Send the 'write page' command EEFC0_FCR = EEFC_FCR_FKEY | EFC_FCR_FCMD_EWP | EEFC_FCR_FARG(page); @@ -91,6 +86,20 @@ RAM_FUNC NOINLINE static void write_page(uint32_t page) } } +#if FLASH_BANKS_NUM > 1 +RAM_FUNC NOINLINE static void write_page_bank1(uint32_t page) +{ + // Send the 'write page' command + EEFC1_FCR = EEFC_FCR_FKEY | EFC_FCR_FCMD_EWP | EEFC_FCR_FARG(page); + + // Wait for the end of command + while(!(EEFC1_FSR & BV(EEFC_FSR_FRDY))) + { + //NOP; + } +} +#endif + /** * Send write command. @@ -102,45 +111,28 @@ INLINE void flash_sendWRcmd(uint32_t page) { cpu_flags_t flags; - LOG_INFO("Writing page %ld...\n", page); - - IRQ_SAVE_DISABLE(flags); - write_page(page); - - IRQ_RESTORE(flags); - LOG_INFO("Done\n"); -} - -/** - * Return true if no error are occurred after flash memory - * read or write operation, otherwise return error code. - */ -static bool flash_getStatus(struct KBlock *blk) -{ - 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(EEFC0_FSR & BV(EEFC_FSR_FCMDE)) + #if FLASH_BANKS_NUM > 1 + if (page >= FLASH_PAGES_FOR_BANK) { - fls->hw->status |= FLASH_WR_ERR; - LOG_ERR("flash not erased..\n"); - return false; - } + page &= 0x3FF; + LOG_INFO("Writing page %ld on bank 1\n", page); - /* - * This bit is set to one if we programming of at least one locked lock - * region. - */ - if(EEFC0_FSR & BV(EEFC_FSR_FLOCKE)) + IRQ_SAVE_DISABLE(flags); + write_page_bank1(page); + IRQ_RESTORE(flags); + } + else + #endif { - fls->hw->status |= FLASH_WR_PROTECT; - LOG_ERR("wr protect..\n"); - return false; + LOG_INFO("Writing page %ld on bank 0\n", page); + + IRQ_SAVE_DISABLE(flags); + write_page_bank(page); + IRQ_RESTORE(flags); } - return true; + + LOG_INFO("Done\n"); } static size_t sam3_flash_readDirect(struct KBlock *blk, block_idx_t idx, void *buf, size_t offset, size_t size) @@ -172,8 +164,28 @@ static size_t sam3_flash_writeDirect(struct KBlock *blk, block_idx_t idx, const flash_sendWRcmd(idx); - if (!flash_getStatus(blk)) + Flash *fls = FLASH_CAST(blk); + uint32_t status = (uint32_t)&EEFC0_FSR; + #if FLASH_BANKS_NUM > 1 + if (idx > FLASH_PAGES_FOR_BANK) + { + status = (uint32_t)&EEFC1_FSR; + } + #endif + + if(status & BV(EEFC_FSR_FCMDE)) + { + fls->hw->status |= FLASH_WR_ERR; + LOG_ERR("flash not erased..\n"); return 0; + } + + if(status & BV(EEFC_FSR_FLOCKE)) + { + fls->hw->status |= FLASH_WR_PROTECT; + LOG_ERR("wr protect..\n"); + return 0; + } return blk->blk_size; }