X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=drv%2Fdataflash.c;h=69b4bdf06c3b64ddc674509cb89e429780920ba1;hb=HEAD;hp=9742e557a7823f4c319bc41eefa774beabf3d734;hpb=4e59a3961d59e6aef45e50630bf9e66a6e19e9d4;p=bertos.git diff --git a/drv/dataflash.c b/drv/dataflash.c deleted file mode 100644 index 9742e557..00000000 --- a/drv/dataflash.c +++ /dev/null @@ -1,515 +0,0 @@ -/** - * \file - * - * - * \brief Function library for AT45DBXX Data Flash memory. - * - * - * \version $Id: dataflash.c 15379 2007-03-28 15:46:09Z asterix $ - * \author Daniele Basile - */ - - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "hw_spi.h" - - -/** - * Global variable for store current and previous data - * flash memory page address during operation of writing. - */ -dataflash_t previous_page = 0; -bool page_modified = false; - - -/** - * Send a generic command to data flash memory. - * This function send only 4 byte, for opcode, page address and - * byte address. - */ -static void send_cmd(dataflash_t page_addr, dataflash_t byte_addr, DataFlashOpcode opcode) -{ - - /* - * Make sure to toggle CS signal in order, - * and reset dataflash command decoder. - * - * \note This is equivalent to CS_DISABLE() immediately followed by CS_ENABLE() - */ - CS_TOGGLE(); - - - /* - * To send one command to data flash memory, we send 4 byte. - * First byte is opcode command, second and third byte are - * page address, in last byte we write a byte page address. - * (see datasheet for more detail). - * - * \note Generaly a defaul memory page size is more than 256 byte. - * In this case we need for addressing a byte in one page more than - * 8 bit, so we put in fourth byte low part of address byte, and - * hight part of address byte in third byte togheter low par of page - * address. - * - * \{ - */ - - /* - * Send opcode. - */ - spi_sendRecv(opcode); - - /* - * Send page address. - * \{ - */ - spi_sendRecv((uint8_t)(page_addr >> (16 - DATAFLASH_PAGE_ADDRESS_BIT))); - spi_sendRecv((uint8_t)((page_addr << (DATAFLASH_PAGE_ADDRESS_BIT - 8)) + (byte_addr >> 8))); - /*\}*/ - - /* - * Send byte page address. - */ - spi_sendRecv((uint8_t)byte_addr); - - /* \} */ - -} - -/** - * Reset dataflash memory function. - * - * This function reset data flash memory - * with one pulse reset long about 10usec. - * - */ -static void dataflash_reset(void) -{ - CS_ENABLE(); - RESET_ENABLE(); - timer_delayHp(us_to_hptime(RESET_PULSE_WIDTH)); - CS_DISABLE(); - RESET_DISABLE(); - timer_delayHp(us_to_hptime(RESET_PULSE_WIDTH)); -} - -/** - * dataflash init function. - * This function initialize a micro pin and - * SPI driver, and test if data flash memory - * density is the same wich define in dataflash.h. - */ -MOD_DEFINE(dataflash); -static bool dataflash_pin_init(void) -{ - uint8_t stat; - - MOD_CHECK(spi); - - RESET_DISABLE(); - WRITE_ENABLE(); //pilot wp pin. - - RESET_OUT(); - WP_OUT(); - - dataflash_reset(); - - stat = dataflash_stat(); - - MOD_INIT(dataflash); - - /* - * 2,3,4,5 bits of 1 byte status register - * indicate a device density of dataflash memory - * (see datasheet for more detail.) - */ - GET_ID_DESITY_DEVICE(stat); - - if(stat == DATAFLASH_ID_DEVICE_DENSITY) - return true; - else - return false; - -} - - -/** - * Read status register of dataflah memory. - * - */ -static uint8_t dataflash_stat(void) -{ - uint8_t stat; - - /* - * Make sure to toggle CS signal in order, - * and reset dataflash command decoder. - * \{ - */ - CS_TOGGLE(); - - stat = spi_sendRecv(DFO_READ_STATUS); - stat = spi_sendRecv(0x00); - - return stat; -} - - -/** - * Send one command to data flash memory, and - * return status register value. - * - */ -static uint8_t dataflash_cmd(dataflash_t page_addr, dataflash_t byte_addr, DataFlashOpcode opcode) -{ - - send_cmd(page_addr, byte_addr, opcode); - - CS_DISABLE(); - CS_ENABLE(); - - /* - * We chech data flash memory state, and wait until busy-flag - * is hight. - */ - while(!(dataflash_stat() & BUSY_BIT)); - - return (dataflash_stat()); - -} - -/** - * Read one byte from main data flash memory or buffer data - * flash memory. - */ -static uint8_t dataflash_read_byte(dataflash_t page_addr, dataflash_t byte_addr, DataFlashOpcode opcode) -{ - uint8_t data; - - send_cmd(page_addr, byte_addr, opcode); - -#if CONFIG_DATA_FLASH == DATAFLASH_AT45DB041B - if(opcode == DFO_READ_FLASH_MEM_BYTE) - { - /* - * Send 24 don't care bit. - * \{ - */ - spi_sendRecv(0x00); - spi_sendRecv(0x00); - spi_sendRecv(0x00); - /* \} */ - - } -#endif - - spi_sendRecv(0x00); //Send 8 don't care bit. - data = spi_sendRecv(0x00); //Read byte. - CS_DISABLE(); - - return data; -} - -/** - * Read \a len bytes from main data flash memory or buffer data - * flash memory, and put it in \a *block. - */ -static void dataflash_read_block(dataflash_t page_addr, dataflash_t byte_addr, DataFlashOpcode opcode, uint8_t *block, dataflashSize_t len) -{ - - send_cmd(page_addr, byte_addr, opcode); - - if(opcode == DFO_READ_FLASH_MEM_BYTE) - { - /* - * Send 24 don't care bit. - * \{ - */ - spi_sendRecv(0x00); - spi_sendRecv(0x00); - spi_sendRecv(0x00); - /* \} */ - } - - spi_sendRecv(0x00); //Send 8 don't care bit. - spi_read(block, len); //Read len bytes ad put in block buffer. - - - CS_DISABLE(); - -} - - -/** - * Write \a len bytes in buffer buffer data flash memory. - * - * \note Isn't possible to write bytes directly in main memory data - * flash. To perform write in main memory you must before write in buffer - * data flash memory, an then send command to write page in main memory. - */ -static void dataflash_write_block(dataflash_t byte_addr, DataFlashOpcode opcode, uint8_t *block, dataflashSize_t len) -{ - - send_cmd(0x00, byte_addr, opcode); - - spi_write(block, len); //Write len bytes. - - CS_DISABLE(); - -} - - -/** - * Load selct page from dataflash memory to buffer. - */ -static void dataflash_loadPage(dataflash_t page_addr) -{ - dataflash_cmd(page_addr, 0x00, DFO_MOV_MEM_TO_BUFF1); - - CS_DISABLE(); -} - -/** - * Flush select page (stored in buffer) in data flash main memory page. - */ -void dataflash_flush(void) -{ - if (page_modified) - { - dataflash_cmd(previous_page, 0x00, DFO_WRITE_BUFF1_TO_MEM_E); - - CS_DISABLE(); - page_modified = false; - - kprintf("\n::=> Flush page:... <%ld>\n", previous_page); - } -} - -/* Kfile interface section */ - -/** - * Open data flash file \a fd - * \a name and \a mode are unused, cause flash memory is - * threated like one file. - */ -static bool dataflash_open(struct _KFile *fd, UNUSED_ARG(const char *, name), UNUSED_ARG(int, mode)) -{ - MOD_CHECK(dataflash); - - previous_page = 0; - fd->seek_pos = 0; - fd->size = (dataflashAddr_t)DATAFLASH_PAGE_SIZE * (dataflashAddr_t)DATAFLASH_NUM_PAGE; - - /* Load select page memory from data flash memory*/ - dataflash_loadPage(previous_page); - - kprintf("dataflash file opened\n"); - return true; -} - -/** - * Close file \a fd - */ -static bool dataflash_close(UNUSED_ARG(struct _KFile *,fd)) -{ - dataflash_flush(); - kprintf("dataflash file closed\n"); - return true; -} - -/** - * Move \a fd file seek position of \a offset bytes - * from current position. - */ -static int32_t dataflash_seek(struct _KFile *fd, int32_t offset, KSeekMode whence) -{ - uint32_t seek_pos; - - switch(whence) - { - case KSM_SEEK_SET: - seek_pos = 0; - break; - case KSM_SEEK_END: - seek_pos = fd->size - 1; - break; - case KSM_SEEK_CUR: - seek_pos = fd->seek_pos; - break; - default: - ASSERT(0); - return -1; - break; - } - - /* Bound check */ - if (seek_pos + offset > fd->size) - { - ASSERT(0); - return -1; - } - - fd->seek_pos = seek_pos + offset; - kprintf("Flash seek to [%u]\n", fd->seek_pos); - - return fd->seek_pos; -} - -/** - * Read from file \a fd \a size bytes and put it in buffer \a buf - * \return the number of bytes read. - */ -static size_t dataflash_read(struct _KFile *fd, void *buf, size_t size) -{ - dataflashAddr_t byte_addr; - dataflashAddr_t page_addr; - uin8_t *data = (uint8_t *)buf; - - - 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); - - /* - * We select from absolute address page address - * and byte address in page. - * \{ - */ - page_addr = fd->seek_pos / (dataflashAddr_t)DATAFLASH_PAGE_SIZE; - byte_addr = fd->seek_pos % (dataflashAddr_t)DATAFLASH_PAGE_SIZE; - /* \} */ - - kprintf(" [page-<%ld>, byte-<%ld>]", page_addr, byte_addr); - - /* - * Flush current page in main memory if - * we had been written a byte in memory - */ - dataflash_flush(); - - /* - * Read byte in main page data flash memory. - */ - dataflash_read_block(page_addr, byte_addr, DFO_READ_FLASH_MEM_BYTE, data, size); - - fd->seek_pos += size; - kprintf(" ::=> Read data: %02x\n",data); - - return size; -} - -/** - * Write program memory. - * Write \a size bytes from buffer \a _buf to file \a fd - * \note Write operations are buffered. - */ -static size_t dataflash_write(struct _KFile *fd, const void *_buf, size_t size) -{ - - dataflashAddr_t byte_addr; - dataflashAddr_t current_page; - - uint8_t *data = (uint8_t *) _buf; - - 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) - { - /* - * We select from absolute address page address - * and byte address in page. - * \{ - */ - current_page = fd->seek_pos / (dataflashAddr_t)DATAFLASH_PAGE_SIZE; - byte_addr = fd->seek_pos % (dataflashAddr_t)DATAFLASH_PAGE_SIZE; - /* \} */ - - size_t wr_len = MIN(size, DATAFLASH_PAGE_SIZE - byte_addr); - - kprintf(" [page-<%ld>, byte-<%ld>]",current_page, byte_addr); - - if (current_page != previous_page) - { - /* Flush current page in main memory*/ - dataflash_flush(); - /* Load select page memory from data flash memory*/ - dataflash_loadPage(current_page); - - previous_page = current_page; - kprintf(" >> Load page: <%ld> ",current_page); - } - /* - * Write byte in current page, and set true - * page_modified flag. - *\{ - */ - dataflash_write_byte(byte_addr, DFO_WRITE_BUFF1, data); - page_modified = true; - /* \} */ - - data += wr_len; - fd->seek_pos += wr_len; - size -= wr_len; - total_write += wr_len; - } - - kprintf("written %u bytes\n", total_write); - return total_write; -} - -/** - * Init data flash memory interface. - */ -void dataflash_init(struct _KFile *fd) -{ - // Set up data flash programming functions. - fd->open = dataflash_open; - fd->close = dataflash_close; - fd->read = dataflash_read; - fd->write = dataflash_write; - fd->seek = dataflash_seek; - - // Init data flash memory and micro pin. - ASSERT(dataflash_pin_init()); -} \ No newline at end of file