summaryrefslogtreecommitdiff
path: root/digital/avr/modules/flash/flash_sst.avr.c
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 /digital/avr/modules/flash/flash_sst.avr.c
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.
Diffstat (limited to 'digital/avr/modules/flash/flash_sst.avr.c')
-rw-r--r--digital/avr/modules/flash/flash_sst.avr.c201
1 files changed, 201 insertions, 0 deletions
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]);
+ }
+}