summaryrefslogtreecommitdiff
path: root/digital
diff options
context:
space:
mode:
Diffstat (limited to 'digital')
-rw-r--r--digital/avr/modules/flash/Makefile.module3
-rw-r--r--digital/avr/modules/flash/flash.avr.c139
-rw-r--r--digital/avr/modules/flash/flash.c172
-rw-r--r--digital/avr/modules/flash/flash.h93
-rw-r--r--digital/avr/modules/flash/flash.host.c189
-rw-r--r--digital/avr/modules/flash/flash_sst.avr.c201
-rw-r--r--digital/avr/modules/flash/flash_sst.c37
-rw-r--r--digital/avr/modules/flash/flash_sst.h136
-rw-r--r--digital/avr/modules/flash/flash_sst.host.c104
-rw-r--r--digital/avr/modules/flash/test/test-flash.c6
10 files changed, 706 insertions, 374 deletions
diff --git a/digital/avr/modules/flash/Makefile.module b/digital/avr/modules/flash/Makefile.module
index e9ec103c..07eed434 100644
--- a/digital/avr/modules/flash/Makefile.module
+++ b/digital/avr/modules/flash/Makefile.module
@@ -1 +1,2 @@
-flash_SOURCES=flash.avr.c flash.host.c flash.c flash_io.host.c
+flash_SOURCES=flash.avr.c flash.host.c flash.c flash_io.host.c \
+ flash_sst.avr.c flash_sst.host.c flash_sst.c
diff --git a/digital/avr/modules/flash/flash.avr.c b/digital/avr/modules/flash/flash.avr.c
index bd053524..bcc81fa6 100644
--- a/digital/avr/modules/flash/flash.avr.c
+++ b/digital/avr/modules/flash/flash.avr.c
@@ -23,14 +23,14 @@
*
* }}} */
#include "flash.h"
-#include "modules/proto/proto.h"
+#include "flash_sst.h"
#include "modules/spi/spi.h"
-#include "modules/utils/utils.h"
uint8_t
flash_init (void)
{
uint8_t rsp[3];
+ uint8_t res;
AC_FLASH_PORT |= _BV(AC_FLASH_BIT_SS);
AC_FLASH_DDR |= _BV(AC_FLASH_BIT_SS);
@@ -40,138 +40,21 @@ flash_init (void)
SPI_FOSC_DIV16);
FLASH_CS_ENABLE;
- spi_send (FLASH_READ_ID);
+ spi_send (FLASH_SST_CMD_READ_ID);
rsp[0] = spi_recv ();
rsp[1] = spi_recv ();
rsp[2] = spi_recv ();
FLASH_CS_DISABLE;
- if (rsp[0] != 0xBF)
- return 0;
-
- if (flash_status_aai())
+ switch (rsp[0])
{
- flash_send_command (FLASH_WEDI);
+ case FLASH_SST_MANUFACTURER_ID:
+ flash_sst_init ();
+ flash_init_sst ();
+ res = 1;
+ break;
+ default:
+ res = 0;
}
-
- /* Enables the flash to be writable. */
- flash_send_command (FLASH_WREN);
-
- FLASH_CS_ENABLE;
- spi_send (FLASH_WRSR);
- spi_send (0);
- FLASH_CS_DISABLE;
-
- return 1;
-}
-
-void
-flash_address (uint32_t addr)
-{
- /* The address must be sent */
- spi_send ((addr >> 16) & 0x1f);
- spi_send (addr >> 8);
- spi_send (addr);
-}
-
-void
-flash_erase (uint8_t cmd, uint32_t start_addr)
-{
- flash_send_command (FLASH_WREN);
-
- FLASH_CS_ENABLE;
- /* send the command. */
- spi_send (cmd);
-
- /* verify if the cmd is the full erase. */
- if (cmd != FLASH_ERASE_FULL)
- {
- /* Send the start address */
- flash_address (start_addr);
- }
- FLASH_CS_DISABLE;
-
- while (flash_is_busy());
-}
-
-void
-flash_send_command (flash_cmd_t cmd)
-{
- FLASH_CS_ENABLE;
- spi_send (cmd);
- FLASH_CS_DISABLE;
-}
-
-uint8_t
-flash_read_status (void)
-{
- uint8_t res;
-
- FLASH_CS_ENABLE;
- spi_send (FLASH_RDSR);
- res = spi_recv();
- FLASH_CS_DISABLE;
-
return res;
}
-
-void
-flash_write (uint32_t addr, uint8_t data)
-{
- while (flash_is_busy ());
- flash_send_command (FLASH_WREN);
-
- FLASH_CS_ENABLE;
- /* Write instruction. */
- spi_send (FLASH_WRITE);
- flash_address (addr);
- spi_send (data);
- FLASH_CS_DISABLE;
-
- /* Wait for the flash until it is busy */
- while (flash_is_busy());
-}
-
-uint8_t
-flash_read (uint32_t addr)
-{
- uint8_t data;
-
- while (flash_is_busy ());
- FLASH_CS_ENABLE;
- /* Send the read instruction. */
- spi_send (FLASH_READ);
- flash_address (addr);
- data = spi_recv ();
- FLASH_CS_DISABLE;
- while (flash_is_busy ());
- return data;
-}
-
-void
-flash_read_array (uint32_t addr, uint8_t *buffer, uint32_t length)
-{
- uint8_t i;
-
- while (flash_is_busy ());
- FLASH_CS_ENABLE;
- spi_send (FLASH_READ);
- flash_address (addr);
- for (i = 0; i < length; i++)
- {
- buffer[i] = spi_recv ();
- }
- FLASH_CS_DISABLE;
- while (flash_is_busy ());
-}
-
-void
-flash_write_array (uint32_t addr, uint8_t *data, uint32_t length)
-{
- uint32_t i;
-
- for (i = 0; i < length; i++)
- {
- flash_write (addr + i, data[i]);
- }
-}
diff --git a/digital/avr/modules/flash/flash.c b/digital/avr/modules/flash/flash.c
index e75df80c..bd84b4e4 100644
--- a/digital/avr/modules/flash/flash.c
+++ b/digital/avr/modules/flash/flash.c
@@ -23,8 +23,153 @@
*
* }}} */
#include "flash.h"
+#include "flash_sst.h"
+#include "flash_at.h"
#include "modules/proto/proto.h"
+/** Erase the memory.
+ * \param erase_type the erase type..
+ * \param start_addr the start address.
+ */
+typedef void
+(*flash_erase_t) (flash_erase_cmd_t cmd, uint32_t start_addr);
+
+/* Send a flash command to the flash memory (only a command).
+ * \param cmd the command to send.
+ */
+typedef void
+(*flash_send_command_t) (flash_cmd_t cmd);
+
+/** Read the busy bit in the Software Status Register of the flash memory.
+ * \return the status register.
+ */
+typedef uint8_t
+(*flash_read_status_t) (void);
+
+/** Read the busy bit in the Software Status Register of the flash memory.
+ * \return the busy bit state.
+ */
+typedef uint8_t
+(*flash_is_busy_t) (void);
+
+/** Write in the flash byte provided in parameter.
+ * \param data the buffer to store the data.
+ */
+typedef void
+(*flash_write_t) (uint32_t addr, uint8_t data);
+
+/** Read the data at the address provided.
+ * \param addr the address of the data to read.
+ * \return the data read.
+ */
+typedef uint8_t
+(*flash_read_t) (uint32_t addr);
+
+/** Read a data from the flash memory from the address provided and for a
+ * length of the number of bytes provided.
+ * \param address at which the data should be read.
+ * \param buffer the buffer to fill with the read data.
+ * \param length the length of the data to read.
+ */
+typedef void
+(*flash_read_array_t) (uint32_t addr, uint8_t *buffer, uint32_t length);
+
+/** Write in the flash byte provided in parameter.
+ * \param addr the address to store the data.
+ * \param data the array to store.
+ * \param length the array length
+ */
+typedef void
+(*flash_write_array_t) (uint32_t addr, uint8_t *data, uint32_t length);
+
+/** Get the flash size.
+ * \return the flash size.
+ */
+typedef uint32_t
+(*flash_size_t) (void);
+
+/** Get the flash block size.
+ * \return the flash block size.
+ */
+typedef uint32_t
+(*flash_block_size_t) (void);
+
+struct flash_t
+{
+ /** Erase function. */
+ flash_erase_t erase_func;
+ /** Send command function. */
+ flash_send_command_t send_cmd_func;
+ /** Read status function. */
+ flash_read_status_t read_status_func;
+ /** Is busy function. */
+ flash_is_busy_t is_busy_func;
+ /** Write function. */
+ flash_write_t write_func;
+ /** Read function. */
+ flash_read_t read_func;
+ /** Read array function. */
+ flash_read_array_t read_array_func;
+ /** Write array function. */
+ flash_write_array_t write_array_func;
+ /** Flash size function. */
+ flash_size_t flash_size_func;
+ /** Flash block size function. */
+ flash_block_size_t flash_block_size_func;
+};
+typedef struct flash_t flash_t;
+
+/** Static variable. */
+static flash_t flash;
+
+void
+flash_erase (flash_erase_cmd_t cmd, uint32_t start_addr)
+{
+ flash.erase_func (cmd, start_addr);
+}
+
+void
+flash_send_command (flash_cmd_t cmd)
+{
+ flash.send_cmd_func (cmd);
+}
+
+uint8_t
+flash_read_status (void)
+{
+ return flash.read_status_func ();
+}
+
+uint8_t
+flash_is_busy (void)
+{
+ return flash.is_busy_func ();
+}
+
+void
+flash_write (uint32_t addr, uint8_t data)
+{
+ flash.write_func (addr, data);
+}
+
+uint8_t
+flash_read (uint32_t addr)
+{
+ return flash.read_func (addr);
+}
+
+void
+flash_read_array (uint32_t addr, uint8_t *buffer, uint32_t length)
+{
+ flash.read_array_func (addr, buffer, length);
+}
+
+void
+flash_write_array (uint32_t addr, uint8_t *data, uint32_t length)
+{
+ flash.write_array_func (addr, data, length);
+}
+
int8_t
flash_log (uint8_t size, uint8_t *args)
{
@@ -75,3 +220,30 @@ flash_log (uint8_t size, uint8_t *args)
return error;
}
+
+uint32_t
+flash_size (void)
+{
+ return flash.flash_size_func ();
+}
+
+uint32_t
+flash_block_size (void)
+{
+ return flash.flash_block_size_func ();
+}
+
+void
+flash_init_sst (void)
+{
+ flash.erase_func = flash_sst_erase;
+ flash.send_cmd_func = flash_sst_send_command;
+ flash.read_status_func = flash_sst_read_status;
+ flash.is_busy_func = flash_sst_is_busy;
+ flash.write_func = flash_sst_write;
+ flash.read_func = flash_sst_read;
+ flash.read_array_func = flash_sst_read_array;
+ flash.write_array_func = flash_sst_write_array;
+ flash.flash_size_func = flash_sst_size;
+ flash.flash_block_size_func = flash_sst_block_size;
+}
diff --git a/digital/avr/modules/flash/flash.h b/digital/avr/modules/flash/flash.h
index 806b97ad..0ac87596 100644
--- a/digital/avr/modules/flash/flash.h
+++ b/digital/avr/modules/flash/flash.h
@@ -27,29 +27,6 @@
#include "common.h"
#include "io.h"
-#define FLASH_SIZE 0x200000
-#define FLASH_ADDRESS_HIGH (FLASH_SIZE - 1)
-#define FLASH_ADDRESS_ERROR 0xFFFFFF
-#define FLASH_ADDRESS_INC(val) \
- ((val) + 1) & FLASH_ADDRESS_HIGH
-
-#define FLASH_ERASE_FULL 0x60
-#define FLASH_ERASE_4K 0x20
-#define FLASH_ERASE_32K 0x52
-#define FLASH_ERASE_64K 0xD8
-
-#define FLASH_READ_ID 0x9F
-#define FLASH_READ 0x03
-#define FLASH_WRITE 0x2
-#define FLASH_WRSR 0x1
-#define FLASH_RDSR 0x5
-#define FLASH_WREN 0x6
-#define FLASH_WEDI 0x4
-#define FLASH_EWSR 0x50
-#define FLASH_AAI 0xAD
-
-#define FLASH_TBP_US 10
-
#define FLASH_LOG_PAGE_SIZE 0x80000
#define FLASH_LOG_BUFFER_SIZE 16
@@ -62,67 +39,56 @@
AC_FLASH_PORT |= _BV(AC_FLASH_BIT_SS);
enum flash_cmd_t
-enum
{
FLASH_CMD_INIT,
- FLASH_CMD_READ,
- FLASH_CMD_WRITE,
FLASH_CMD_READ_BYTE,
FLASH_CMD_WRITE_BYTE,
+ FLASH_CMD_READ,
+ FLASH_CMD_WRITE,
FLASH_CMD_NB
};
typedef enum flash_cmd_t flash_cmd_t;
-/** 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.
- * \param addr the address to provide to the flash memory.
+enum flash_erase_cmd_t
+{
+ FLASH_ERASE_PAGE,
+ FLASH_ERASE_SECTOR,
+ FLASH_ERASE_BLOCK,
+ FLASH_ERASE_FULL,
+ FLASH_ERASE_NB
+};
+typedef enum flash_erase_cmd_t flash_erase_cmd_t;
+
+/** Initialise the flash memory.
+ * \return true if the flash is present, false otherwise.
*/
-void
-flash_address (uint32_t addr);
+uint8_t
+flash_init (void);
/** Erase the memory.
* \param erase_type the erase type..
* \param start_addr the start address.
*/
void
-flash_erase (uint8_t cmd, uint32_t start_addr);
+flash_erase (flash_erase_cmd_t cmd, uint32_t start_addr);
/* Send a flash command to the flash memory (only a command).
* \param cmd the command to send.
*/
void
-flash_send_command (uint8_t cmd);
+flash_send_command (flash_cmd_t cmd);
-/** Poll the busy bit in the Software Status Register of the flash memory.
+/** Read the busy bit in the Software Status Register of the flash memory.
* \return the status register.
*/
uint8_t
flash_read_status (void);
-/** Poll the busy bit in the Software Status Register of the flash memory.
+/** Read the busy bit in the Software Status Register of the flash memory.
* \return the busy bit state.
*/
-extern inline uint8_t
-flash_is_busy (void)
-{
- return flash_read_status () & 0x1;
-}
-
-/** Return the AAI status flag of the register.
- * \return the AAI status.
- */
-extern inline uint8_t
-flash_status_aai (void)
-{
- return flash_read_status () >> 6;
-}
-
-/** Initialise the flash memory.
- * \return true if the flash is present, false otherwise.
- */
uint8_t
-flash_init (void);
+flash_is_busy (void);
/** Write in the flash byte provided in parameter.
* \param data the buffer to store the data.
@@ -165,4 +131,21 @@ flash_write_array (uint32_t addr, uint8_t *data, uint32_t length);
int8_t
flash_log (uint8_t size, uint8_t *args);
+/** Get the flash size.
+ * \return the flash size.
+ */
+uint32_t
+flash_size (void);
+
+/** Get the flash block size.
+ * \return the flash block size.
+ */
+uint32_t
+flash_block_size (void);
+
+/** Initialise all the function pointer for SST flash memory.
+ */
+void
+flash_init_sst (void);
+
#endif /* flash_h */
diff --git a/digital/avr/modules/flash/flash.host.c b/digital/avr/modules/flash/flash.host.c
index 9b0666bf..7ecee246 100644
--- a/digital/avr/modules/flash/flash.host.c
+++ b/digital/avr/modules/flash/flash.host.c
@@ -23,193 +23,12 @@
*
* }}} */
#include "flash.h"
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-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_send_command (uint8_t cmd) {}
-
-void
-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 0x0;
-}
+#include "flash_sst.h"
uint8_t
flash_init (void)
{
- 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)
-{
- 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)
-{
- 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_deactivate ();
-
- return data;
- }
-
- return 0xff;
-}
-
-void
-flash_read_array (uint32_t addr, uint8_t *buffer, uint32_t length)
-{
- if (flash_global.status)
- {
- uint8_t res;
- uint8_t deactivate = 1;
-
- /* Set the stream to the position of address. */
- res = lseek (flash_global.file, addr, SEEK_SET);
- if (res == addr)
- {
- res = read (flash_global.file, buffer, length);
- printf ("read: %d\n", res);
-
- if (res == length)
- deactivate = 0x0;
- }
-
- if (deactivate == 0x1)
- flash_deactivate ();
- }
-}
-
-void
-flash_write_array (uint32_t addr, uint8_t *data, uint32_t length)
-{
- 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();
- }
+ flash_sst_init ();
+ flash_init_sst ();
+ return 1;
}
diff --git a/digital/avr/modules/flash/flash_sst.avr.c b/digital/avr/modules/flash/flash_sst.avr.c
new file mode 100644
index 00000000..5f0a63ec
--- /dev/null
+++ b/digital/avr/modules/flash/flash_sst.avr.c
@@ -0,0 +1,201 @@
+/* flash_sst.avr.c */
+/* avr.flash - AVR Flash SPI use. {{{
+ *
+ * Copyright (C) 2009 Nelio 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_sst.h"
+#include "modules/proto/proto.h"
+#include "modules/spi/spi.h"
+#include "modules/utils/utils.h"
+
+/** Return the AAI status flag of the register.
+ * \return the AAI status.
+ */
+extern inline uint8_t
+flash_sst_status_aai (void)
+{
+ return flash_sst_read_status () >> 6;
+}
+
+void
+flash_sst_init (void)
+{
+ if (flash_sst_status_aai())
+ flash_sst_send_command (FLASH_SST_CMD_WEDI);
+ /* Enables the flash to be writable. */
+ flash_sst_send_command (FLASH_SST_CMD_WREN);
+ FLASH_CS_ENABLE;
+ spi_send (FLASH_SST_CMD_WRSR);
+ spi_send (0);
+ FLASH_CS_DISABLE;
+}
+
+/** 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.
+ * \param addr the address to provide to the flash memory.
+ */
+static inline void
+flash_sst_address (uint32_t addr)
+{
+ if (FLASH_SST_ADDR_IS_VALID (addr))
+ {
+ /* The address must be sent */
+ spi_send ((addr >> 16) & 0x1f);
+ spi_send (addr >> 8);
+ spi_send (addr);
+ }
+}
+
+void
+flash_sst_erase (flash_erase_cmd_t cmd, uint32_t start_addr)
+{
+ uint8_t sst_cmd;
+ switch (cmd)
+ {
+ case FLASH_ERASE_PAGE:
+ sst_cmd = FLASH_SST_ERASE_4K;
+ break;
+ case FLASH_ERASE_SECTOR:
+ sst_cmd = FLASH_SST_ERASE_32K;
+ break;
+ case FLASH_ERASE_BLOCK:
+ sst_cmd = FLASH_SST_ERASE_64K;
+ break;
+ default:
+ return;
+ }
+ flash_sst_send_command (FLASH_SST_CMD_WREN);
+ FLASH_CS_ENABLE;
+ /* send the command. */
+ spi_send (cmd);
+ /* verify if the cmd is the full erase. */
+ if (sst_cmd != FLASH_SST_ERASE_FULL)
+ /* Send the start address */
+ flash_sst_address (start_addr);
+ FLASH_CS_DISABLE;
+ while (flash_sst_is_busy());
+}
+
+void
+flash_sst_send_command (flash_cmd_t cmd)
+{
+ uint8_t sst_cmd;
+ switch (cmd)
+ {
+ case FLASH_CMD_READ_BYTE:
+ case FLASH_CMD_READ:
+ sst_cmd = FLASH_SST_CMD_READ;
+ break;
+ case FLASH_CMD_WRITE_BYTE:
+ case FLASH_CMD_WRITE:
+ sst_cmd = FLASH_SST_CMD_WRITE;
+ break;
+ default:
+ return;
+ }
+ FLASH_CS_ENABLE;
+ spi_send (cmd);
+ FLASH_CS_DISABLE;
+}
+
+uint8_t
+flash_sst_read_status (void)
+{
+ uint8_t res;
+ FLASH_CS_ENABLE;
+ spi_send (FLASH_SST_CMD_RDSR);
+ res = spi_recv();
+ FLASH_CS_DISABLE;
+ return res;
+}
+
+uint8_t
+flash_sst_is_busy (void)
+{
+ return flash_sst_read_status () & 0x1;
+}
+
+void
+flash_sst_write (uint32_t addr, uint8_t data)
+{
+ if (FLASH_SST_ADDR_IS_VALID (addr))
+ {
+ while (flash_sst_is_busy ());
+ flash_sst_send_command (FLASH_SST_CMD_WREN);
+ FLASH_CS_ENABLE;
+ /* Write instruction. */
+ spi_send (FLASH_SST_CMD_WRITE);
+ flash_sst_address (addr);
+ spi_send (data);
+ FLASH_CS_DISABLE;
+ /* Wait for the flash until it is busy */
+ while (flash_sst_is_busy());
+ }
+}
+
+uint8_t
+flash_sst_read (uint32_t addr)
+{
+ if (FLASH_SST_ADDR_IS_VALID (addr))
+ {
+ uint8_t data;
+ while (flash_sst_is_busy ());
+ FLASH_CS_ENABLE;
+ /* Send the read instruction. */
+ spi_send (FLASH_SST_CMD_READ);
+ flash_sst_address (addr);
+ data = spi_recv ();
+ FLASH_CS_DISABLE;
+ while (flash_sst_is_busy ());
+ return data;
+ }
+ return 0xFF;
+}
+
+void
+flash_sst_read_array (uint32_t addr, uint8_t *buffer, uint32_t length)
+{
+ if (FLASH_SST_ADDR_IS_VALID (addr))
+ {
+ uint8_t i;
+ while (flash_sst_is_busy ());
+ FLASH_CS_ENABLE;
+ spi_send (FLASH_SST_CMD_READ);
+ flash_sst_address (addr);
+ for (i = 0; i < length; i++)
+ buffer[i] = spi_recv ();
+ FLASH_CS_DISABLE;
+ while (flash_sst_is_busy ());
+ }
+}
+
+void
+flash_sst_write_array (uint32_t addr, uint8_t *data, uint32_t length)
+{
+ if (FLASH_SST_ADDR_IS_VALID (addr))
+ {
+ uint32_t i;
+ for (i = 0; i < length; i++)
+ flash_sst_write (addr + i, data[i]);
+ }
+}
diff --git a/digital/avr/modules/flash/flash_sst.c b/digital/avr/modules/flash/flash_sst.c
new file mode 100644
index 00000000..aac0867f
--- /dev/null
+++ b/digital/avr/modules/flash/flash_sst.c
@@ -0,0 +1,37 @@
+/* flash_sst.c */
+/* avr.flash - AVR Flash SPI use. {{{
+ *
+ * Copyright (C) 2009 Nelio 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_sst.h"
+
+uint32_t
+flash_sst_size (void)
+{
+ return FLASH_SST_SIZE;
+}
+
+uint32_t
+flash_sst_block_size (void)
+{
+ return FLASH_SST_BLOCK_SIZE;
+}
diff --git a/digital/avr/modules/flash/flash_sst.h b/digital/avr/modules/flash/flash_sst.h
new file mode 100644
index 00000000..36ff0fca
--- /dev/null
+++ b/digital/avr/modules/flash/flash_sst.h
@@ -0,0 +1,136 @@
+#ifndef flash_sst_h
+#define flash_sst_h
+/* flash_sst.h */
+/* avr.flash - AVR Flash SPI use. {{{
+ *
+ * Copyright (C) 2009 Nelio 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 "common.h"
+#include "flash.h"
+#define FLASH_SST_SIZE 0x200000
+#define FLASH_SST_BLOCK_SIZE 0x10000
+#define FLASH_SST_ADDRESS_HIGH (FLASH_SST_SIZE - 1)
+
+#define FLASH_SST_ADDR_IS_VALID(addr) \
+ ((addr) < FLASH_SST_SIZE)
+
+#define FLASH_SST_TBP_US 10
+#define FLASH_SST_MANUFACTURER_ID 0xBF
+
+enum flash_sst_erase_t
+{
+ FLASH_SST_ERASE_FULL = 0x60,
+ FLASH_SST_ERASE_4K = 0x20,
+ FLASH_SST_ERASE_32K = 0x52,
+ FLASH_SST_ERASE_64K = 0xD8,
+ FLASH_SST_ERASE_NB
+};
+typedef enum flash_sst_erase_t flash_sst_erase_t;
+
+enum flash_sst_cmd_t
+{
+ FLASH_SST_CMD_READ_ID = 0x9F,
+ FLASH_SST_CMD_READ = 0x03,
+ FLASH_SST_CMD_WRITE = 0x2,
+ FLASH_SST_CMD_WRSR = 0x1,
+ FLASH_SST_CMD_RDSR = 0x5,
+ FLASH_SST_CMD_WREN = 0x6,
+ FLASH_SST_CMD_WEDI = 0x4,
+ FLASH_SST_CMD_EWSR = 0x50,
+ FLASH_SST_CMD_AAI = 0xAD,
+ FLASH_SST_CMD_NB
+};
+typedef enum flash_sst_cmd_t flash_sst_cmd_t;
+
+/** Initialise the flash memory.
+ */
+void
+flash_sst_init (void);
+
+/** Erase the memory.
+ * \param erase_type the erase type..
+ * \param start_addr the start address.
+ */
+void
+flash_sst_erase (flash_erase_cmd_t cmd, uint32_t start_addr);
+
+/* Send a flash command to the flash memory (only a command).
+ * \param cmd the command to send.
+ */
+void
+flash_sst_send_command (flash_cmd_t cmd);
+
+/** Read the busy bit in the Software Status Register of the flash memory.
+ * \return the status register.
+ */
+uint8_t
+flash_sst_read_status (void);
+
+/** Read the busy bit in the Software Status Register of the flash memory.
+ * \return the busy bit state.
+ */
+uint8_t
+flash_sst_is_busy (void);
+
+/** Write in the flash byte provided in parameter.
+ * \param data the buffer to store the data.
+ */
+void
+flash_sst_write (uint32_t addr, uint8_t data);
+
+/** Read the data at the address provided.
+ * \param addr the address of the data to read.
+ * \return the data read.
+ */
+uint8_t
+flash_sst_read (uint32_t addr);
+
+/** Read a data from the flash memory from the address provided and for a
+ * length of the number of bytes provided.
+ * \param address at which the data should be read.
+ * \param buffer the buffer to fill with the read data.
+ * \param length the length of the data to read.
+ */
+void
+flash_sst_read_array (uint32_t addr, uint8_t *buffer, uint32_t length);
+
+/** Write in the flash byte provided in parameter.
+ * \param addr the address to store the data.
+ * \param data the array to store.
+ * \param length the array length
+ */
+void
+flash_sst_write_array (uint32_t addr, uint8_t *data, uint32_t length);
+
+/** Get the flash size.
+ * \return the flash size.
+ */
+uint32_t
+flash_sst_size (void);
+
+/** Get the flash block size.
+ * \return the flash block size.
+ */
+uint32_t
+flash_sst_block_size (void);
+
+#endif /* flash_sst_h */
diff --git a/digital/avr/modules/flash/flash_sst.host.c b/digital/avr/modules/flash/flash_sst.host.c
new file mode 100644
index 00000000..86bdc1e3
--- /dev/null
+++ b/digital/avr/modules/flash/flash_sst.host.c
@@ -0,0 +1,104 @@
+/* flash_sst.host.c */
+/* avr.flash - AVR Flash SPI use. {{{
+ *
+ * Copyright (C) 2009 Nelio 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_sst.h"
+#include "flash_io.host.h"
+
+void
+flash_sst_init (void)
+{
+ flash_io_init (FLASH_SST_SIZE);
+}
+
+void
+flash_sst_erase (flash_erase_cmd_t cmd, uint32_t start_addr)
+{
+ if (FLASH_SST_ADDR_IS_VALID (start_addr))
+ {
+ uint32_t length;
+ switch (cmd)
+ {
+ case FLASH_ERASE_PAGE:
+ length = 4096;
+ break;
+ case FLASH_ERASE_SECTOR:
+ length = 32565;
+ break;
+ case FLASH_ERASE_BLOCK:
+ length = 65536;
+ break;
+ case FLASH_ERASE_FULL:
+ length = FLASH_SST_SIZE;
+ default:
+ return;
+ }
+ flash_io_erase (start_addr, length);
+ }
+}
+
+void
+flash_sst_send_command (flash_cmd_t cmd)
+{ }
+
+uint8_t
+flash_sst_read_status (void)
+{
+ return 0;
+}
+
+uint8_t
+flash_sst_is_busy (void)
+{
+ /* Not busy. */
+ return 0;
+}
+
+void
+flash_sst_write (uint32_t addr, uint8_t data)
+{
+ if (FLASH_SST_ADDR_IS_VALID (addr))
+ flash_io_write (addr, data);
+}
+
+uint8_t
+flash_sst_read (uint32_t addr)
+{
+ if (FLASH_SST_ADDR_IS_VALID (addr))
+ return flash_io_read (addr);
+ return 0xff;
+}
+
+void
+flash_sst_read_array (uint32_t addr, uint8_t *buffer, uint32_t length)
+{
+ if (FLASH_SST_ADDR_IS_VALID (addr))
+ flash_io_read_array (addr, buffer, length);
+}
+
+void
+flash_sst_write_array (uint32_t addr, uint8_t *data, uint32_t length)
+{
+ if (FLASH_SST_ADDR_IS_VALID (addr))
+ flash_io_write_array (addr, data, length);
+}
diff --git a/digital/avr/modules/flash/test/test-flash.c b/digital/avr/modules/flash/test/test-flash.c
index 99b12df2..92fb69f7 100644
--- a/digital/avr/modules/flash/test/test-flash.c
+++ b/digital/avr/modules/flash/test/test-flash.c
@@ -51,16 +51,12 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args)
case c ('e', 3):
/* Erase 4k:
* - 3b: address. */
- flash_erase (FLASH_ERASE_4K, addr);
+ flash_erase (FLASH_ERASE_PAGE, addr);
break;
case c ('s', 0):
/* print flash status */
proto_send1b ('s', flash_read_status());
break;
- case c ('w', 0):
- /* Send the write enable flash command. */
- flash_send_command (FLASH_WREN);
- break;
case c ('r', 3):
/* Read one byte:
* - 3b: address. */