X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=cpu%2Favr%2Fdrv%2Fflash_avr.c;h=03740dd7c5c121a506fac670e9048103124a698d;hb=HEAD;hp=b461d95dd8e2335d15746dc7f09a1b4b7654dda0;hpb=f64bc4cd7adb89814dfa00260d78d65f64a04933;p=bertos.git diff --git a/cpu/avr/drv/flash_avr.c b/cpu/avr/drv/flash_avr.c deleted file mode 100644 index b461d95d..00000000 --- a/cpu/avr/drv/flash_avr.c +++ /dev/null @@ -1,296 +0,0 @@ -/** - * \file - * - * - * \brief Self programming routines. - * - * \version $Id$ - * \author Francesco Sacchi - * \author Daniele Basile - * - * This module implements a kfile-like access for Atmel avr - * internal flash. - * Internal flash writing access is controlled by BOOTSZ fuses, check - * datasheet for details. - */ - -#include "flash_avr.h" - -#include -#include -#include - -#include // MIN() -#include -#include -#include - -#include - -#include - -#include - -/** - * Definition of type for avr flash module. - */ -typedef uint16_t avr_page_addr_t; -typedef uint16_t avr_page_t; - -/** - * Temporary buffer cointaing data block to - * write on flash. - */ -static uint8_t page_buf[SPM_PAGESIZE]; - -/** - * Flag for checking if current page is modified. - */ -bool page_modified; - -/** - * Current buffered page. - */ -static avr_page_t curr_page = 0; - -/* - * Private avr flush funtion. - * - * Write current buffered page in flash memory (if modified). - * This function erase flash memory page before writing. - * - * This function is only use internaly in this module. - */ -static void flash_avr_flush(void) -{ - if (page_modified) - { - kprintf("Flushing page %d\n", curr_page); - - // Wait while the SPM instruction is busy. - boot_spm_busy_wait(); - - kprintf("Filling temparary page buffer..."); - - // Fill the temporary buffer of the AVR - for (avr_page_addr_t page_addr = 0; page_addr < SPM_PAGESIZE; page_addr += 2) - { - uint16_t word = ((uint16_t)page_buf[page_addr + 1] << 8) | page_buf[page_addr]; - - ATOMIC(boot_page_fill(page_addr, word)); - } - kprintf("Done.\n"); - - wdt_reset(); - - kprintf("Erasing page, addr %u...", curr_page * SPM_PAGESIZE); - - /* Page erase */ - ATOMIC(boot_page_erase(curr_page * SPM_PAGESIZE)); - - /* Wait until the memory is erased. */ - boot_spm_busy_wait(); - - kprintf("Done.\n"); - kprintf("Writing page, addr %u...", curr_page * SPM_PAGESIZE); - - /* Store buffer in flash page. */ - ATOMIC(boot_page_write(curr_page * SPM_PAGESIZE)); - boot_spm_busy_wait(); // Wait while the SPM instruction is busy. - - /* - * Reenable RWW-section again. We need this if we want to jump back - * to the application after bootloading. - */ - ATOMIC(boot_rww_enable()); - - page_modified = false; - kprintf("Done.\n"); - } -} - - -/** - * Flush avr flash function. - * - * Write current buffered page in flash memory (if modified). - * This function erase flash memory page before writing. - */ -static int flash_avr_kfileFlush(struct KFile * fd) -{ - KFILE_ASSERT_GENERIC(fd); - (void)fd; - flash_avr_flush(); - return 0; -} - - -/** - * Check current page and if \a page is different, load it in - * temporary buffer. - */ -static void flash_avr_loadPage(avr_page_t page) -{ - if (page != curr_page) - { - flash_avr_flush(); - // Load page - memcpy_P(page_buf, (const char *)(page * SPM_PAGESIZE), SPM_PAGESIZE); - curr_page = page; - kprintf("Loaded page %d\n", curr_page); - } -} - -/** - * Write program memory. - * Write \a size bytes from buffer \a _buf to file \a fd - * \note Write operations are buffered. - */ -static size_t flash_avr_write(struct KFile *fd, const void *_buf, size_t size) -{ - KFILE_ASSERT_GENERIC(fd); - const uint8_t *buf =(const uint8_t *)_buf; - - avr_page_t page; - avr_page_addr_t page_addr; - size_t total_write = 0; - - ASSERT(fd->seek_pos + size <= fd->size); - size = MIN((uint32_t)size, fd->size - fd->seek_pos); - - kprintf("Writing at pos[%u]\n", fd->seek_pos); - while (size) - { - page = fd->seek_pos / SPM_PAGESIZE; - page_addr = fd->seek_pos % SPM_PAGESIZE; - - flash_avr_loadPage(page); - - size_t wr_len = MIN(size, SPM_PAGESIZE - page_addr); - memcpy(page_buf + page_addr, buf, wr_len); - page_modified = true; - - buf += wr_len; - fd->seek_pos += wr_len; - size -= wr_len; - total_write += wr_len; - } - kprintf("written %u bytes\n", total_write); - return total_write; -} - -/** - * Open flash file \a fd - * \a name and \a mode are unused, cause flash memory is - * threated like one file. - */ -static void flash_avr_open(struct KFile *fd) -{ - KFILE_ASSERT_GENERIC(fd); - curr_page = 0; - memcpy_P(page_buf, (const char *)(curr_page * SPM_PAGESIZE), SPM_PAGESIZE); - - fd->seek_pos = 0; - fd->size = (uint16_t)(FLASHEND - CONFIG_BOOT_SIZE + 1); - page_modified = false; - - kprintf("Flash file opened\n"); -} - -/** - * Close file \a fd - */ -static int flash_avr_close(UNUSED_ARG(struct KFile *,fd)) -{ - KFILE_ASSERT_GENERIC(fd); - flash_avr_flush(); - kprintf("Flash file closed\n"); - return 0; -} - -/** - * Reopen file \a fd - */ -static struct KFile *flash_avr_reopen(struct KFile *fd) -{ - KFILE_ASSERT_GENERIC(fd); - flash_avr_close(fd); - flash_avr_open(fd); - return fd; -} - - -/** - * 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_avr_read(struct KFile *fd, void *buf, size_t size) -{ - KFILE_ASSERT_GENERIC(fd); - ASSERT(fd->seek_pos + size <= fd->size); - size = MIN((uint32_t)size, fd->size - fd->seek_pos); - - kprintf("Reading at pos[%u]\n", fd->seek_pos); - // Flush current buffered page (if modified). - flash_avr_flush(); - - /* - * AVR pointers are 16 bits wide, this hack is needed to avoid - * compiler warning, cause fd->seek_pos is a 32bit offset. - */ - const uint8_t *pgm_addr = (const uint8_t *)0; - pgm_addr += fd->seek_pos; - - memcpy_P(buf, pgm_addr, size); - fd->seek_pos += size; - kprintf("Read %u bytes\n", size); - return size; -} - -/** - * Init AVR flash read/write file. - */ -void flash_avr_init(struct KFile *fd) -{ - memset(fd, 0, sizeof(*fd)); - DB(fd->_type = KFT_GENERIC); - - // Set up flash programming functions. - fd->reopen = flash_avr_reopen; - fd->close = flash_avr_close; - fd->read = flash_avr_read; - fd->write = flash_avr_write; - fd->seek = kfile_genericSeek; - fd->flush = flash_avr_kfileFlush; - - flash_avr_open(fd); -} -