From 62949cf58f69ccd67fb38bb1aedcfe6a667265c1 Mon Sep 17 00:00:00 2001 From: Nélio Laranjeiro Date: Wed, 17 Jun 2009 23:47:12 +0200 Subject: *digital/avr/modules/flash: * Coded a flash simulation for host. --- digital/avr/modules/flash/Makefile.module | 2 +- digital/avr/modules/flash/flash.avr.c | 43 ------- digital/avr/modules/flash/flash.c | 66 +++++++++++ digital/avr/modules/flash/flash.h | 3 + digital/avr/modules/flash/flash.host.c | 175 +++++++++++++++++++++++++--- digital/avr/modules/flash/test/test-flash.c | 11 +- 6 files changed, 235 insertions(+), 65 deletions(-) create mode 100644 digital/avr/modules/flash/flash.c (limited to 'digital/avr/modules/flash') diff --git a/digital/avr/modules/flash/Makefile.module b/digital/avr/modules/flash/Makefile.module index 988bbbc7..1cb45350 100644 --- a/digital/avr/modules/flash/Makefile.module +++ b/digital/avr/modules/flash/Makefile.module @@ -1 +1 @@ -flash_SOURCES=flash.avr.c flash.host.c +flash_SOURCES=flash.avr.c flash.host.c flash.c diff --git a/digital/avr/modules/flash/flash.avr.c b/digital/avr/modules/flash/flash.avr.c index c44e1863..ef445918 100644 --- a/digital/avr/modules/flash/flash.avr.c +++ b/digital/avr/modules/flash/flash.avr.c @@ -27,9 +27,6 @@ #include "modules/spi/spi.h" #include "modules/utils/utils.h" -#define FLASH_LOG_PAGE_SIZE 0x80000 -#define FLASH_LOG_BUFFER_SIZE 16 - /** Flash access. * The flash contains an address of 21 bits in a range from 0x0-0x1fffff. * This function shall access the memory directly by the SPI. @@ -215,43 +212,3 @@ flash_write_array (uint32_t addr, uint8_t *data, uint32_t length) flash_write (addr + i, data[i]); } } - -int8_t -flash_log (uint8_t size, uint8_t *args) -{ - uint8_t buf[FLASH_LOG_BUFFER_SIZE+1]; - int8_t error = 0x0; - uint32_t addr = 0; - - if (size >= 4) - addr = (((uint32_t) args[1]) << 16) - | (((uint32_t) args[2]) << 8) | args[3]; - - switch (args[0]) - { - case FLASH_CMD_INIT: - error = !flash_init (); - proto_send1b ('s', error ? 0 : 1); - break; - case FLASH_CMD_READ: - if ((size == 5) - && (args[4] <= sizeof(buf))) - { - flash_read_array (addr, buf, args[4]); - proto_send ('r', args[4], buf); - error = 0; - } - else if (size == 4) - { - proto_send1b ('r', flash_read (addr)); - error = 0; - } - else - error = 2; - break; - default: - return 3; - } - - return error; -} diff --git a/digital/avr/modules/flash/flash.c b/digital/avr/modules/flash/flash.c new file mode 100644 index 00000000..b8f9143c --- /dev/null +++ b/digital/avr/modules/flash/flash.c @@ -0,0 +1,66 @@ +/* flash.c */ +/* avr.flash - AVR Flash SPI use. {{{ + * + * Copyright (C) 2009 Nélio Laranjeiro + * + * APBTeam: + * Web: http://apbteam.org/ + * Email: team AT apbteam DOT org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * }}} */ +#include "flash.h" +#include "modules/proto/proto.h" + +int8_t +flash_log (uint8_t size, uint8_t *args) +{ + uint8_t buf[FLASH_LOG_BUFFER_SIZE+1]; + int8_t error = 0x0; + uint32_t addr = 0; + + if (size >= 4) + addr = (((uint32_t) args[1]) << 16) + | (((uint32_t) args[2]) << 8) | args[3]; + + switch (args[0]) + { + case FLASH_CMD_INIT: + error = !flash_init (); + proto_send1b ('s', error ? 0 : 1); + break; + case FLASH_CMD_READ: + if ((size == 5) + && (args[4] <= sizeof(buf))) + { + flash_read_array (addr, buf, args[4]); + proto_send ('r', args[4], buf); + error = 0; + } + else if (size == 4) + { + proto_send1b ('r', flash_read (addr)); + error = 0; + } + else + error = 2; + break; + default: + return 3; + } + + return error; +} diff --git a/digital/avr/modules/flash/flash.h b/digital/avr/modules/flash/flash.h index d1fec1f0..ff4713db 100644 --- a/digital/avr/modules/flash/flash.h +++ b/digital/avr/modules/flash/flash.h @@ -50,6 +50,9 @@ #define FLASH_TBP_US 10 +#define FLASH_LOG_PAGE_SIZE 0x80000 +#define FLASH_LOG_BUFFER_SIZE 16 + enum { FLASH_CMD_INIT, diff --git a/digital/avr/modules/flash/flash.host.c b/digital/avr/modules/flash/flash.host.c index 7b1a9255..1d984f32 100644 --- a/digital/avr/modules/flash/flash.host.c +++ b/digital/avr/modules/flash/flash.host.c @@ -23,48 +23,191 @@ * * }}} */ #include "flash.h" +#include +#include +#include +#include +#include +#include -void -flash_address (uint32_t addr){} +struct flash_t +{ + /** Status of the flash memory. */ + uint8_t status; + /** File to store, read the data. */ + int file; +}; +static struct flash_t flash_global; + +static void +flash_deactivate (void) +{ + flash_global.status = 0; + + if (flash_global.file) + close (flash_global.file); +} void -flash_erase (uint8_t cmd, uint32_t start_addr){} +flash_send_command (uint8_t cmd) {} void -flash_send_command (uint8_t cmd){} +flash_erase (uint8_t cmd, uint32_t start_addr) +{ + if (flash_global.status) + { + uint32_t length; + switch (cmd) + { + case FLASH_ERASE_4K: + length = 4096; + break; + case FLASH_ERASE_32K: + length = 32768; + break; + case FLASH_ERASE_64K: + length = 65535; + break; + case FLASH_ERASE_FULL: + length = FLASH_SIZE; + break; + default: + length = 0; + } + + if (length) + { + uint8_t data = 0xFF; + int res; + + /* Set the stream to the correct position. */ + lseek (flash_global.file, start_addr, SEEK_SET); + for (res = 1; (res != -1) && length; length --) + res = write (flash_global.file, &data, sizeof (uint8_t)); + + if ((res < 0) && length) + { + flash_deactivate (); + } + } + } +} uint8_t flash_read_status (void) { - return 0; + return 0x0; } -/** Initialise the flash memory. - * \return true if the flash is present, false otherwise. - */ uint8_t flash_init (void) { - return 0; + memset (&flash_global, 0, sizeof (struct flash_t)); + + flash_global.file = open ("flash.apb", O_CREAT | O_RDWR, S_IREAD | + S_IWRITE); + if (flash_global.file > 0) + { + struct stat fstats; + fstat (flash_global.file, &fstats); + + if (fstats.st_size == FLASH_SIZE) + { + /* Set the stream to the beginning of the file. */ + lseek (flash_global.file, 0, SEEK_SET); + flash_global.status = 1; + } + else + { + flash_global.status = 1; + flash_erase (FLASH_ERASE_FULL, 0); + fstat (flash_global.file, &fstats); + if (fstats.st_size != FLASH_SIZE) + flash_deactivate (); + } + } + else + flash_deactivate (); + + return flash_global.status; } void -flash_write (uint32_t addr, uint8_t data) {} +flash_write (uint32_t addr, uint8_t data) +{ + if (flash_global.status) + { + uint8_t res; + + /* Set the stream to the position of address. */ + lseek (flash_global.file, addr, SEEK_SET); + res = write (flash_global.file, &data, sizeof (uint8_t)); + + if (res == 0) + flash_deactivate (); + } +} uint8_t -flash_read (uint32_t addr) { return 0xff; } +flash_read (uint32_t addr) +{ + if (flash_global.status) + { + uint8_t res; + uint8_t data; + + /* Set the stream to the position of address. */ + lseek (flash_global.file, addr, SEEK_SET); + res = read (flash_global.file, &data, sizeof (uint8_t)); + + if (res == 0) + flash_global.status = 0; + + return data; + } + + return 0xff; +} void flash_read_array (uint32_t addr, uint8_t *buffer, uint32_t length) { + if (flash_global.status) + { + uint32_t nb; + int8_t res; + /* Set the stream to the position required. */ + res = lseek (flash_global.file, addr, SEEK_SET); + if (res == -1) + { + flash_deactivate(); + return; + } + + nb = read (flash_global.file, buffer, length); + + if (nb != length) + flash_deactivate(); + } } void flash_write_array (uint32_t addr, uint8_t *data, uint32_t length) -{} - -int8_t -flash_log (uint8_t size, uint8_t *args) { - return 1; + if (flash_global.status) + { + uint8_t res; + + if (sizeof (data) >= length) + { + /* Set the stream to the position required. */ + lseek (flash_global.file, addr, SEEK_SET); + res = write (flash_global.file, data, length); + + if (res != length) + flash_deactivate(); + } + else + flash_deactivate(); + } } diff --git a/digital/avr/modules/flash/test/test-flash.c b/digital/avr/modules/flash/test/test-flash.c index 461096c3..bbfcfd6a 100644 --- a/digital/avr/modules/flash/test/test-flash.c +++ b/digital/avr/modules/flash/test/test-flash.c @@ -35,7 +35,8 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) { /* May be unused. */ uint32_t addr = v8_to_v32 (0, args[0], args[1], args[2]); - uint8_t buf[16]; + uint8_t buf[FLASH_LOG_BUFFER_SIZE+1]; + uint8_t status; #define c(cmd, size) (cmd << 8 | size) switch (c (cmd, size)) { @@ -86,6 +87,10 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) * - 1b: byte. */ flash_write (addr, args[3]); break; + case c ('i', 0): + status = flash_init (); + proto_send1b ('f', status); + break; default: if (cmd == 'w' && size > 4) { @@ -109,12 +114,8 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) int main (void) { - uint8_t status; uart0_init (); proto_send0 ('z'); - proto_send0 ('c'); - status = flash_init (); - proto_send1b ('f', status); while (1) proto_accept (uart0_getc ()); -- cgit v1.2.3