changeset 1133:1692e174d682

New package/file(s) for flash driver for e7t
author asl
date Sun, 27 Jul 2003 09:32:21 +0000
parents 50e2b50c6ea7
children 1a21a684dbfa
files packages/devs/flash/sst/39vf400/current/ChangeLog packages/devs/flash/sst/39vf400/current/cdl/flash_sst_39vf400.cdl packages/devs/flash/sst/39vf400/current/include/flash_sst_39vf400.inl
diffstat 3 files changed, 493 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/packages/devs/flash/sst/39vf400/current/ChangeLog
@@ -0,0 +1,39 @@
+2003-07-24  Chris Garry  <cgarry@sweeneydesign.co.uk>
+
+	* include/flash_sst_39vf400.inl: 
+	* cdl/flash_sst_39vf400.cdl: New package/file(s).
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
+//
+// eCos 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 or (at your option) any later version.
+//
+// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
new file mode 100644
--- /dev/null
+++ b/packages/devs/flash/sst/39vf400/current/cdl/flash_sst_39vf400.cdl
@@ -0,0 +1,64 @@
+# ====================================================================
+#
+#      flash_sst_39vf400.cdl
+#
+#      FLASH memory - Hardware support for SST SST39vf400 device
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2002 Gary Thomas
+##
+## eCos 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 or (at your option) any later version.
+##
+## eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      Chris Garry <cgarry@sweeneydesign.co.uk>
+# Contributors:   
+# Date:           2003-04-21
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_SST_39VF400 {
+    display       "SST 39VF400 FLASH memory support"
+    description   "FLASH memory device support for SST 39VF400"
+    parent        CYGPKG_IO_FLASH
+    active_if	  CYGPKG_IO_FLASH
+    active_if     CYGINT_DEVS_FLASH_SST_39VF400_REQUIRED
+
+    implements    CYGHWR_IO_FLASH_DEVICE
+
+    include_dir   cyg/io
+}
+
+# EOF flash_sst_39vf400.cdl
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/packages/devs/flash/sst/39vf400/current/include/flash_sst_39vf400.inl
@@ -0,0 +1,390 @@
+#ifndef CYGONCE_DEVS_FLASH_SST_39VF400_INL
+#define CYGONCE_DEVS_FLASH_SST_39VF400_INL
+//==========================================================================
+//
+//      flash_sst_39vf4000.inl
+//
+//      SST SST39VF400 FLASH driver
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 Gary Thomas
+//
+// eCos 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 or (at your option) any later version.
+//
+// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Chris Garry <cgarry@sweeneydesign.co.uk>
+// Contributors:
+// Date:         2003-04-21
+// Purpose:
+// Description:  SST SST39VF400 flash driver
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/devs_flash_sst_39vf400.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_diag.h> /* HAL_DELAY_US */
+#include <cyg/infra/diag.h>   /* Required for diag_printf */
+#include CYGHWR_MEMORY_LAYOUT_H
+
+#define  _FLASH_PRIVATE_
+#include <cyg/io/flash.h>
+
+//----------------------------------------------------------------------------
+// Platform code must define the below
+// #define CYGNUM_FLASH_INTERLEAVE      : Number of interleaved devices (in parallel)
+// #define CYGNUM_FLASH_SERIES          : Number of devices in series
+// #define CYGNUM_FLASH_BASE            : Base address of the FLASH
+//
+// Note:
+// Currently the driver only supports CYGNUM_FLASH_INTERLEAVE = 1 and
+// CYGNUM_FLASH_SERIES = 1
+
+
+// Definitions for the SST 39VF400A part
+#define SST_ID                    0x00BF          /* SST Manufacturer's ID code   */
+#define SST_39VF400A              0x2780          /* SST39VF400/SST39VF400A device code */
+#define CYGNUM_FLASH_SECTOR_SIZE (0x1000)         /* Size of physical sectors */
+#define CYGNUM_FLASH_BLOCK_SIZE  (0x1000)         /* Driver 'blocks' may be a multiple of physical sectors */
+#define CYGNUM_FLASH_BLOCK_NUM   (0x80000/CYGNUM_FLASH_BLOCK_SIZE) /* Number of blocks */
+#define CYGNUM_FLASH_WIDTH       (16)             /* This part is always 16 bits wide */
+#define CYGNUM_FLASH_BLANK       (1)
+
+
+#ifndef FLASH_P2V
+# define FLASH_P2V( _a_ ) ((volatile flash_data_t *)((CYG_ADDRWORD)(_a_)))
+#endif
+#ifndef CYGHWR_FLASH_AM29XXXXX_PLF_INIT
+# define CYGHWR_FLASH_AM29XXXXX_PLF_INIT()
+#endif
+
+// Structure to hold device ID
+typedef struct
+{
+    cyg_uint16 man_id;
+    cyg_uint16 dev_id;
+} device_id_t;
+
+// FLASH registers
+volatile cyg_uint16 *flash_data_add0 = (cyg_uint16 *)(CYGNUM_FLASH_BASE);
+volatile cyg_uint16 *flash_data_add1 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x0001 << 1));
+volatile cyg_uint16 *flash_cmd_add1 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x5555 << 1));
+volatile cyg_uint16 *flash_cmd_add2 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x2AAA << 1));
+volatile cyg_uint16 *flash_cmd_add3 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x5555 << 1));
+volatile cyg_uint16 *flash_cmd_add4 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x5555 << 1));
+volatile cyg_uint16 *flash_cmd_add5 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x2AAA << 1));
+
+
+//----------------------------------------------------------------------------
+// Now that device properties are defined, include magic for defining
+// accessor type and constants.
+#include <cyg/io/flash_dev.h>
+
+//----------------------------------------------------------------------------
+// Functions that put the flash device into non-read mode must reside
+// in RAM.
+static device_id_t get_device_id(void) __attribute__ ((section (".2ram.get_device_id")));
+int  flash_erase_block(void* block, unsigned int size)
+    __attribute__ ((section (".2ram.flash_erase_block")));
+int  flash_program_buf(void* addr, void* data, int len)
+    __attribute__ ((section (".2ram.flash_program_buf")));
+
+//----------------------------------------------------------------------------
+// Get Device ID
+//
+// Reads the manufacturer and part number codes for the device
+//
+static device_id_t get_device_id(void)
+{
+    device_id_t device_id;
+    int i;
+
+    /*  Issue the Software ID command */
+    *flash_cmd_add1 = 0xAAAA;
+    *flash_cmd_add2 = 0x5555;
+    *flash_cmd_add3 = 0x9090;
+
+    /* Tida delay time, Tida = 150 ns */
+    /* Can use any function that is in ROM */
+    for (i = 0; i < 100; i++)
+    {
+        /* Do nothing */
+    }
+
+    /* Read the product ID */
+    device_id.man_id = *flash_data_add0 & 0xFF;
+    device_id.dev_id = *flash_data_add1;
+
+    /* Issue the Software ID EXIT command */
+    *flash_data_add0 = 0xF0F0;
+
+    /* Tida delay time, Tida = 150 ns */
+    /* Can use any function that is in ROM */
+    for (i = 0; i < 100; i++)
+    {
+        /* Do nothing */
+    }
+
+    return(device_id);
+}
+
+
+//----------------------------------------------------------------------------
+// Initialize driver details
+//
+int flash_hwr_init(void)
+{
+    device_id_t device_id;
+
+    /* Call the function to get the device ID */
+    device_id = get_device_id();
+
+    /* Determine whether there is a SST39VF400A installed or not */
+    if ((device_id.man_id != SST_ID) || (device_id.dev_id != SST_39VF400A))
+    {
+        return FLASH_ERR_DRV_WRONG_PART;
+    }
+
+    // Hard wired for now
+    flash_info.block_size = CYGNUM_FLASH_BLOCK_SIZE;
+    flash_info.blocks = CYGNUM_FLASH_BLOCK_NUM;
+    flash_info.start = (void *)CYGNUM_FLASH_BASE;
+    flash_info.end = (void *)(CYGNUM_FLASH_BASE + (flash_info.block_size * flash_info.blocks));
+
+    return FLASH_ERR_OK;
+}
+
+//----------------------------------------------------------------------------
+// Map a hardware status to a package error
+int flash_hwr_map_error(int e)
+{
+    return e;
+}
+
+
+//----------------------------------------------------------------------------
+// See if a range of FLASH addresses overlaps currently running code
+bool flash_code_overlaps(void *start, void *end)
+{
+    extern unsigned char _stext[], _etext[];
+
+    return ((((unsigned long)&_stext >= (unsigned long)start) &&
+             ((unsigned long)&_stext < (unsigned long)end)) ||
+            (((unsigned long)&_etext >= (unsigned long)start) &&
+             ((unsigned long)&_etext < (unsigned long)end)));
+}
+
+//----------------------------------------------------------------------------
+// Erase Block
+// This function actually uses the sector erase command instead of the block
+// erase command. this allows for the effective block size to be smaller
+// than 64K (as small as the 4K sector size)
+int flash_erase_block(void* block, unsigned int size)
+{
+
+    volatile cyg_uint16 *block_addr;
+    volatile cyg_uint16 *verify_addr;
+    int verify_failed;
+    cyg_uint32 i, timeout;
+    int j;
+    int retry;
+
+    block_addr = block;
+
+    for (j = 0; j < (size / CYGNUM_FLASH_SECTOR_SIZE); j++)
+    {
+        retry = 0;
+        while (retry < 16)
+        {
+            /* Issue the Sector-Erase command */
+            *flash_cmd_add1 = 0xAAAA;
+            *flash_cmd_add2 = 0x5555;
+            *flash_cmd_add3 = 0x8080;
+            *flash_cmd_add4 = 0xAAAA;
+            *flash_cmd_add5 = 0x5555;
+            *block_addr = 0x3030;  /* Sector Erase command */
+
+            /* Wait for the Erase operation to complete */
+            /* With a timeout to stop the board locking up with a H/W error*/
+            timeout = 0;
+            i = 0;
+            while (i < 5)
+            {
+                if (*block_addr == 0xFFFF)
+                {
+                    i++;
+                }
+                else
+                {
+                    i = 0;
+                }
+
+                if (++timeout > 0x01000000)
+                {
+                    /* Timeout - return with ERROR status */
+                    return (FLASH_ERR_DRV_TIMEOUT);
+                }
+            }
+
+            /* Verify this sector has been erased */
+            verify_addr = block_addr;
+            verify_failed = 0;
+            while ((cyg_uint32)(verify_addr) < ((cyg_uint32)block_addr + (cyg_uint32)CYGNUM_FLASH_SECTOR_SIZE))
+            {
+                if (*verify_addr != 0xFFFF)
+                {
+                    /* Error verifying segment data */
+                    retry++;
+                    verify_failed = 1;
+                    break;
+                }
+                ++verify_addr;
+            }
+
+            if (verify_failed == 0)
+            {
+                /* Sector erase verified */
+                break;
+            }
+        }
+
+        /* Increment the block address by 1 sector */
+        (cyg_uint32)block_addr += CYGNUM_FLASH_SECTOR_SIZE;
+    }
+
+    /* Verify the entire block has been set to all 0xFFFFs */
+    block_addr = block;
+    while ((cyg_uint32)(block_addr) < ((cyg_uint32)block + (cyg_uint32)size))
+    {
+        if (*block_addr != 0xFFFF)
+        {
+            /* Error verifying data */
+            return (FLASH_ERR_DRV_VERIFY);
+        }
+
+        ++block_addr;
+    }
+
+    return (FLASH_ERR_OK);
+}
+
+
+//----------------------------------------------------------------------------
+// Program Buffer
+int
+flash_program_buf(void* addr, void* data, int len)
+{
+    volatile cyg_uint16 *write_ptr;
+    volatile cyg_uint16 *data_ptr;
+    int i;
+    cyg_uint32 timeout;
+    cyg_uint16 read_data1, read_data2;
+
+    write_ptr = addr;  /* Initialise local pointers */
+    data_ptr = data;
+
+    /* Loop for writing the data */
+    while ((cyg_uint32)write_ptr < ((cyg_uint32)addr + (cyg_uint32)len))
+    {
+        /* Write word of data to FLASH */
+        /* Issue the Word-Program command */
+        *flash_cmd_add1 = 0xAAAA;
+        *flash_cmd_add2 = 0x5555;
+        *flash_cmd_add3 = 0xA0A0;
+        /* Write data word to FLASH */
+        *write_ptr = *data_ptr;
+
+        /* Wait for the operation to complete */
+        /* Wait for the Erase operation to complete */
+        /* With a timeout to stop the board locking up with a H/W error*/
+        timeout = 0;
+        i = 0;
+        while (i < 5)
+        {
+            read_data1 = *write_ptr;
+            read_data2 = *write_ptr;
+            if (read_data1 == read_data2)
+            {
+                /* Bit 6 can no longer be toggling */
+                i++;
+            }
+            else
+            {
+                i = 0;
+            }
+
+            if (++timeout > 0x01000000)
+            {
+                /* Timeout - return with ERROR status */
+                return (FLASH_ERR_DRV_TIMEOUT);
+            }
+        }
+
+        /* Increment pointers to next words */
+        ++write_ptr;
+        ++data_ptr;
+    }
+
+    /* Data write complete - verify the data */
+    write_ptr = addr;  /* Re-initialise local pointers */
+    data_ptr = data;
+
+    /* Loop for verifying the data */
+    while ((cyg_uint32)write_ptr < ((cyg_uint32)addr + (cyg_uint32)len))
+    {
+        if (*write_ptr != *data_ptr)
+        {
+            /* Error verifying data */
+            return (FLASH_ERR_DRV_VERIFY);
+        }
+
+        /* Increment pointers to next words */
+        ++write_ptr;
+        ++data_ptr;
+    }
+
+    return (FLASH_ERR_OK);
+}
+
+#endif // CYGONCE_DEVS_FLASH_SST_39VF400_INL
+
+
+
+
+
+
+