summaryrefslogtreecommitdiff
path: root/digital
diff options
context:
space:
mode:
authorNélio Laranjeiro2009-06-17 23:47:12 +0200
committerNélio Laranjeiro2009-06-17 23:47:12 +0200
commit62949cf58f69ccd67fb38bb1aedcfe6a667265c1 (patch)
treece7196f692197c557ec47909683a48ba8f23ab3b /digital
parent39c427bfce5dfc2dc7037e3f4a80dca78c10db47 (diff)
*digital/avr/modules/flash:
* Coded a flash simulation for host.
Diffstat (limited to 'digital')
-rw-r--r--digital/avr/modules/flash/Makefile.module2
-rw-r--r--digital/avr/modules/flash/flash.avr.c43
-rw-r--r--digital/avr/modules/flash/flash.c66
-rw-r--r--digital/avr/modules/flash/flash.h3
-rw-r--r--digital/avr/modules/flash/flash.host.c175
-rw-r--r--digital/avr/modules/flash/test/test-flash.c11
6 files changed, 235 insertions, 65 deletions
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 <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
-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 ());