summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNélio Laranjeiro2010-01-12 23:51:26 +0100
committerNélio Laranjeiro2010-01-12 23:51:26 +0100
commit32ed04c7e1435b8019974ac0671a6896e2786f31 (patch)
treed3e9300a81c32838a938d4b6ec827611f8871b46
parent0f278970130103b1df4a2b308359943520f10987 (diff)
digital/avr/modules/flash: flash sst driver
Modify flash source code to initialise the SPI interface and detect the flash type using JDEC. Once the JDEC is read the flash driver initialise functions pointers to pilot the flash memory. The final objective is to have several flash support.
-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. */