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/)
32 * \brief Function library for serial Flash memory.
34 * Module provide a kfile interface, that ensure an abstraction
35 * from comunication channel and give a standard interface.
36 * Typicaly this kind of memory use an SPI bus, but you should
37 * use another comunication channel you have defined.
40 * \author Daniele Basile <asterix@develer.com>
44 * We use a spi bus, thus include hardware specific definition.
45 * If you use another channel you must redefine this macros.
47 #include "hw/hw_spi.h"
49 #include <cfg/macros.h>
50 #include <cfg/debug.h>
52 #include <drv/timer.h>
53 #include <drv/flash25.h>
55 #include <kern/kfile.h>
57 #include <cpu/power.h> /* cpu_relax() */
59 #warning FIXME:This file was change, but is untest!
62 * Wait until flash memory is ready.
64 static void flash25_waitReady(Flash25 *fd)
72 kfile_putc(FLASH25_RDSR, fd->channel);
73 stat = kfile_getc(fd->channel);
77 if (!(stat & RDY_BIT))
85 * Send a single command to serial flash memory.
87 static void flash25_sendCmd(Flash25 *fd, Flash25Opcode cmd)
91 kfile_putc(cmd, fd->channel);
97 * flash25 init function.
98 * This function init a comunication channel and
99 * try to read manufacturer id of serial memory,
100 * then check if is equal to selected type.
102 static bool flash25_pin_init(Flash25 *fd)
105 uint8_t manufacturer;
111 * Send read id productor opcode on
112 * comunication channel
113 * TODO:controllare se ha senso
115 kfile_putc(FLASH25_RDID, fd->channel);
117 manufacturer = kfile_getc(fd->channel);
118 device_id = kfile_getc(fd->channel);
122 if((FLASH25_MANUFACTURER_ID == manufacturer) &&
123 (FLASH25_DEVICE_ID == device_id))
130 * Reopen a serial memory interface.
132 * For serial memory this function reinit only
133 * the size and seek_pos in kfile stucture.
134 * Return a kfile pointer, after assert check.
136 static KFile * flash25_reopen(struct KFile *_fd)
138 Flash25 *fd = FLASH25_CAST(_fd);
141 fd->fd.size = FLASH25_MEM_SIZE;
143 kprintf("flash25 file opened\n");
148 * Close a serial memory interface.
150 * For serial memory this funtion do nothing,
151 * and return always 0.
153 static int flash25_close(UNUSED_ARG(struct KFile *,fd))
155 kprintf("flash25 file closed\n");
160 * Read \a _buf lenght \a size byte from serial flash memmory.
162 * For read in serial flash memory we
163 * enble cs pin and send one byte of read opcode,
164 * and then 3 byte of address of memory cell we
165 * want to read. After the last byte of address we
166 * can read data from so pin.
168 * \return the number of bytes read.
170 static size_t flash25_read(struct KFile *_fd, void *buf, size_t size)
172 uint8_t *data = (uint8_t *)buf;
174 Flash25 *fd = FLASH25_CAST(_fd);
176 ASSERT(fd->fd.seek_pos + (kfile_off_t)size <= fd->fd.size);
177 size = MIN((kfile_off_t)size, fd->fd.size - fd->fd.seek_pos);
179 //kprintf("Reading at addr[%lu], size[%d]\n", fd->seek_pos, size);
182 kfile_putc(FLASH25_READ, fd->channel);
186 * Address that we want to read.
188 kfile_putc((fd->fd.seek_pos >> 16) & 0xFF, fd->channel);
189 kfile_putc((fd->fd.seek_pos >> 8) & 0xFF, fd->channel);
190 kfile_putc(fd->fd.seek_pos & 0xFF, fd->channel);
192 kfile_read(fd->channel, data, size);
196 fd->fd.seek_pos += size;
202 * Write \a _buf in serial flash memory
204 * Before to write data into flash we must enable
205 * memory writing. To do this we send a WRE command opcode.
206 * After this command the flash is ready to be write, and so
207 * we send a PROGRAM opcode followed to 3 byte of
208 * address memory, at the end of last address byte
209 * we can send the data.
210 * When we finish to send all data, we disable cs
211 * and flash write received data bytes on its memory.
213 * \note: WARNING: you could write only on erased memory section!
214 * Each write time you could write max a memory page size,
215 * because if you write more than memory page size the
216 * address roll over to first byte of page.
218 * \return the number of bytes write.
220 static size_t flash25_write(struct KFile *_fd, const void *_buf, size_t size)
222 flash25Offset_t offset;
223 flash25Size_t total_write = 0;
224 flash25Size_t wr_len;
225 const uint8_t *data = (const uint8_t *) _buf;
227 Flash25 *fd = FLASH25_CAST(_fd);
229 ASSERT(fd->fd.seek_pos + (kfile_off_t)size <= fd->fd.size);
231 size = MIN((kfile_off_t)size, fd->fd.size - fd->fd.seek_pos);
235 offset = fd->fd.seek_pos % (flash25Size_t)FLASH25_PAGE_SIZE;
236 wr_len = MIN((flash25Size_t)size, FLASH25_PAGE_SIZE - (flash25Size_t)offset);
238 kprintf("[seek_pos-<%lu>, offset-<%d>]\n", fd->fd.seek_pos, offset);
241 * We check serial flash memory state, and wait until ready-flag
244 flash25_waitReady(fd);
248 * We could write only data not more long than one
251 * To write on serial flash memory we must first
252 * enable write with a WREN opcode command, before
253 * the PROGRAM opcode.
255 * \note: the same byte cannot be reprogrammed without
256 * erasing the whole sector first.
258 flash25_sendCmd(fd, FLASH25_WREN);
261 kfile_putc(FLASH25_PROGRAM, fd->channel);
264 * Address that we want to write.
266 kfile_putc((fd->fd.seek_pos >> 16) & 0xFF, fd->channel);
267 kfile_putc((fd->fd.seek_pos >> 8) & 0xFF, fd->channel);
268 kfile_putc(fd->fd.seek_pos & 0xFF, fd->channel);
270 kfile_write(fd->channel, data, wr_len);
275 fd->fd.seek_pos += wr_len;
277 total_write += wr_len;
280 kprintf("written %lu bytes\n", total_write);
285 * Sector erase function.
287 * Erase a select \p sector of serial flash memory.
289 * \note A sector size is FLASH25_SECTOR_SIZE.
290 * This operation could take a while.
292 void flash25_sectorErase(Flash25 *fd, Flash25Sector sector)
296 * Erase a sector could take a while,
297 * for debug we measure that time
298 * see datasheet to compare this time.
300 DB(ticks_t start_time = timer_clock());
305 * To erase a sector of serial flash memory we must first
306 * enable write with a WREN opcode command, before
307 * the SECTOR_ERASE opcode. Sector is automatically
308 * determinate if any address within the sector
311 kfile_putc(FLASH25_WREN, fd->channel);
312 kfile_putc(FLASH25_SECTORE_ERASE,fd-> channel);
315 * Address inside the sector that we want to
318 kfile_putc(sector, fd->channel);
323 * We check serial flash memory state, and wait until ready-flag
326 flash25_waitReady(fd);
328 DB(kprintf("Erased sector [%ld] in %d ms\n", sector, ticks_to_ms(timer_clock() - start_time)));
333 * Chip erase function.
335 * Erase all sector of serial flash memory.
337 * \note This operation could take a while.
339 void flash25_chipErase(Flash25 *fd)
342 * Erase all chip could take a while,
343 * for debug we measure that time
344 * see datasheet to compare this time.
346 DB(ticks_t start_time = timer_clock());
349 * To erase serial flash memory we must first
350 * enable write with a WREN opcode command, before
351 * the CHIP_ERASE opcode.
353 flash25_sendCmd(fd, FLASH25_WREN);
354 flash25_sendCmd(fd, FLASH25_CHIP_ERASE);
357 * We check serial flash memory state, and wait until ready-flag
360 flash25_waitReady(fd);
362 DB(kprintf("Erased all memory in %ld ms\n", ticks_to_ms(timer_clock() - start_time)));
367 * Init data flash memory interface.
369 void flash25_init(Flash25 *fd, KFile *ch)
375 //Set kfile struct type as a generic kfile structure.
376 DB(fd->fd._type = KFT_FLASH25);
378 // Set up data flash programming functions.
379 fd->fd.reopen = flash25_reopen;
380 fd->fd.close = flash25_close;
381 fd->fd.read = flash25_read;
382 fd->fd.write = flash25_write;
383 fd->fd.seek = kfile_genericSeek;
386 * Init a local channel structure and flash kfile interface.
389 flash25_reopen(&fd->fd);
392 * Init data flash memory and micro pin.
394 if (!flash25_pin_init(fd))