4 * This file is part of BeRTOS.
6 * Bertos is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * As a special exception, you may use this file as part of a free software
21 * library without restriction. Specifically, if other files instantiate
22 * templates or use macros or inline functions from this file, or you compile
23 * this file and link it with other files to produce an executable, this
24 * file does not by itself cause the resulting executable to be covered by
25 * the GNU General Public License. This exception does not however
26 * invalidate any other reasons why the executable file might be covered by
27 * the GNU General Public License.
29 * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
33 * \brief Function library for AT45DB081D Flash memory.
36 * \version $Id: dflash.c 15379 2007-03-28 15:46:09Z asterix $
37 * \author Daniele Basile <asterix@develer.com>
41 #include <appconfig.h>
44 #include <cfg/macros.h>
45 #include <cfg/debug.h>
46 #include <cfg/module.h>
47 #include <drv/timer.h>
49 #include <drv/dflash.h>
54 * Send a generic command to data flash memory.
55 * This function send only 4 byte, for opcode, page address and
58 static void send_cmd(dflashAddr_t page_addr, dflashAddr_t byte_addr, DFlashOpcode opcode)
62 * Make sure to toggle CS signal in order,
63 * and reset dflash command decoder.
71 * To send one command to data flash memory, we send 4 byte.
72 * First byte is opcode command, second and third byte are
73 * page address, in last byte we write a byte page address.
74 * (see datasheet for more detail).
76 * \note Generaly a defaul memory page size is more than 256 byte.
77 * In this case we need for addressing a byte in one page more than
78 * 8 bit, so we put in fourth byte low part of address byte, and
79 * hight part of address byte in third byte togheter low par of page
94 spi_sendRecv((uint8_t)(page_addr >> (16 - DFLASH_PAGE_ADDRESS_BIT)));
95 spi_sendRecv((uint8_t)((page_addr << (DFLASH_PAGE_ADDRESS_BIT - 8)) + (byte_addr >> 8)));
99 * Send byte page address.
101 spi_sendRecv((uint8_t)byte_addr);
108 * Reset dataflash memory function.
110 * This function reset data flash memory
111 * with one pulse reset long about 10usec.
114 static void dflash_reset(void)
118 timer_delayHp(us_to_hptime(RESET_PULSE_WIDTH));
121 timer_delayHp(us_to_hptime(RESET_PULSE_WIDTH));
125 * dflash init function.
126 * This function initialize a micro pin and
127 * SPI driver, and test if data flash memory
128 * density is the same wich define in dflash.h.
131 static bool dflash_pin_init(void)
138 WRITE_ENABLE(); //pilot wp pin.
145 stat = dflash_stat();
150 * 2,3,4,5 bit of 1 byte status register
151 * indicate a device density of dflash memory
152 * (see datasheet for more detail.)
154 GET_ID_DESITY_DEVICE(stat);
156 if(stat == DFLASH_ID_DEVICE_DENSITY)
165 * Read status register of dataflah memory.
168 static uint8_t dflash_stat(void)
173 * Make sure to toggle CS signal in order,
174 * and reset dflash command decoder.
181 stat = spi_sendRecv(DFO_READ_STATUS);
182 stat = spi_sendRecv(0x00);
189 * Send one command to data flash memory, and
190 * return status register value.
193 static uint8_t dflash_cmd(dflashAddr_t page_addr, dflashAddr_t byte_addr, DFlashOpcode opcode)
196 send_cmd(page_addr, byte_addr, opcode);
202 * We chech data flash memory state, and wait until busy-flag
205 while(!(dflash_stat() & BUSY_BIT));
207 return (dflash_stat());
212 * Read one byte from main data flash memory or buffer data
215 static uint8_t dflash_read_byte(dflashAddr_t page_addr, dflashAddr_t byte_addr, DFlashOpcode opcode)
219 send_cmd(page_addr, byte_addr, opcode);
221 #if CONFIG_DATA_FLASH == AT45DB041B
222 if(opcode == DFO_READ_FLASH_MEM_BYTE)
225 * Send 24 don't care bit.
236 spi_sendRecv(0x00); //Send 8 don't care bit.
237 data = spi_sendRecv(0x00); //Read byte.
244 * Read \param len bytes from main data flash memory or buffer data
245 * flash memory, and put it in \param *block.
247 static void dflash_read_block(dflashAddr_t page_addr, dflashAddr_t byte_addr, DFlashOpcode opcode, uint8_t *block, dflashSize_t len)
250 send_cmd(page_addr, byte_addr, opcode);
252 if(opcode == DFO_READ_FLASH_MEM_BYTE)
255 * Send 24 don't care bit.
264 spi_sendRecv(0x00); //Send 8 don't care bit.
265 spi_read(block, len); //Read len bytes ad put in block buffer.
273 * Write one byte in buffer buffer data flash memory.
275 * \note Isn't possible to write byte directly in main memory data
276 * flash. To perform write in main memory you must before write in buffer
277 * data flash memory, an then send command to write page in main memory.
279 static void dflash_write_byte(dflashAddr_t byte_addr, DFlashOpcode opcode, uint8_t data)
281 send_cmd(0x00, byte_addr, opcode);
283 spi_sendRecv(data); //Write data byte.
289 * Write \param len bytes in buffer buffer data flash memory.
291 * \note Isn't possible to write bytes directly in main memory data
292 * flash. To perform write in main memory you must before write in buffer
293 * data flash memory, an then send command to write page in main memory.
295 static void dflash_write_block(dflashAddr_t byte_addr, DFlashOpcode opcode, uint8_t *block, dflashSize_t len)
299 send_cmd(0x00, byte_addr, opcode);
301 spi_write(block, len); //Write len bytes.
308 * Open data flash file \a fd
309 * \a name and \a mode are unused, cause flash memory is
310 * threated like one file.
312 static bool dflash_open(struct _KFile *fd, UNUSED_ARG(const char *, name), UNUSED_ARG(int, mode))
319 static bool dflash_close(UNUSED_ARG(struct _KFile *,fd))
324 * Move \a fd file seek position of \a offset bytes
325 * from current position.
327 static int32_t dflash_seek(struct _KFile *fd, int32_t offset, KSeekMode whence)
332 * Read from file \a fd \a size bytes and put it in buffer \a buf
333 * \return the number of bytes read.
335 static size_t dflash_read(struct _KFile *fd, void *buf, size_t size)
339 //TODO: deve ritornare un bool?
341 * Init data flash memory interface.
343 void dflash_init(struct _KFile *fd)
345 // Set up data flash programming functions.
346 fd->open = dflash_open;
347 fd->close = dflash_close;
348 fd->read = dflash_read;
349 fd->write = dflash_write;
350 fd->seek = dflash_seek;
352 // Init data flash memory and micro pin.