⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdk7a404_strataflash.c

📁 sharp flash blob 的烧写代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************
 * $Workfile:   sdk7a404_strataflash.c  $
 * $Revision:   1.0  $
 * $Author:   WellsK  $
 * $Date:   Sep 04 2003 15:51:48  $
 *
 * Project: Basic SDK7A400/SDK7A404 StrataFlash driver
 *
 * Description:
 *     This file contains functions used to program 2 StrataFlash
 *     devices configured in x16 mode (with a 32-bit width) on the
 *     SDK7A400 and SDK7A404 EVBs.
 *
 * Notes:
 *     This driver does not attempt to detect and work with every
 *     configuration of StrataFlash connected in a system. It is
 *     targeted to support 2 devices in x16 mode only as configured on
 *     the SDK7A400 and SDK7A404 EVBs.
 *
 * Revision History:
 * $Log:   //smaicnt2/pvcs/VM/sharpmcu/archives/sharpmcu/software/csps/lh7a404/bsps/sdk7a404/source/sdk7a404_strataflash.c-arc  $
 * 
 *    Rev 1.0   Sep 04 2003 15:51:48   WellsK
 * Initial revision.
 * 
 *
 ***********************************************************************
 * SHARP MICROELECTRONICS OF THE AMERICAS MAKES NO REPRESENTATION
 * OR WARRANTIES WITH RESPECT TO THE PERFORMANCE OF THIS SOFTWARE,
 * AND SPECIFICALLY DISCLAIMS ANY RESPONSIBILITY FOR ANY DAMAGES, 
 * SPECIAL OR CONSEQUENTIAL, CONNECTED WITH THE USE OF THIS SOFTWARE.
 *
 * SHARP MICROELECTRONICS OF THE AMERICAS PROVIDES THIS SOFTWARE SOLELY 
 * FOR THE PURPOSE OF SOFTWARE DEVELOPMENT INCORPORATING THE USE OF A 
 * SHARP MICROCONTROLLER OR SYSTEM-ON-CHIP PRODUCT. USE OF THIS SOURCE
 * FILE IMPLIES ACCEPTANCE OF THESE CONDITIONS.
 *
 * COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
 *     CAMAS, WA
 **********************************************************************/

#include "sdk7a404_strataflash.h"

/***********************************************************************
 * Private types and data
 **********************************************************************/

/* Maximum number of block regions supported */
#define MAX_CFI_REGIONS 8

/* Maximum number of blocks supported */
#define MAX_CFI_BLOCKS 128

/* Structure used to hold device geometry */
typedef struct
{
    UNS_32 baseaddr;    /* Device base address */
    UNS_32 devsize;     /* Device size, 2^n bytes * 2 devices */
    UNS_32 wb_size;     /* Write buffer size in 32-bit words */
    UNS_32 erblocks;    /* Number of erase block regions in device */
    /* Number of blocks in erase region */
    UNS_16 blks[MAX_CFI_REGIONS];
    /* Size of each block in erase region */
    UNS_32 bsize[MAX_CFI_REGIONS];
    UNS_32 blocks;      /* Number of blocks in the device */
    /* List of block pointers */
    UNS_32 blk_addr[MAX_CFI_BLOCKS];
    /* List of block sizes */
    UNS_32 blk_size[MAX_CFI_BLOCKS];
} CFI_DEV_GEOM_T;

/* CFI device geometry data */
CFI_DEV_GEOM_T cfi_dg;
#if 1  
/* CFI standard defines (32-bit) */
#define CFI32_TAG_Q 0x00510051      /* First tag string =  '_Q_Q' */
#define CFI32_TAG_R 0x00520052      /* Second tag string = '_R_R' */
#define CFI32_TAG_Y 0x00590059      /* Third tag string =  '_Y_Y' */

/* CFI query command (32-bit) */
#define CFI32_QUERY_COMMAND 0x00980098

/* CFI exit programming mode command */
#define CFI32_EXITPROG_COMMAND 0xFFFFFFFF

/* CFI read status command */
#define CFI32_READ_STATUS 0x00700070

/* CFI clear status command */
#define CFI32_CLEAR_STATUS_COMMAND 0x0050050

/* CFI set block command */
#define CFI32_SET_BLOCK_COMMAND 0x00600060

/* CFI block confirm clear (lock) command */
#define CFI32_CONFIRM_CLEAR_BLOCK_COMMAND 0x00D000D0

/* CFI block confirm buffer write command */
#define CFI32_CONFIRM_BUFWRITE_COMMAND 0x00D000D0

/* CFI block confirm command */
#define CFI32_CONFIRM_SET_BLOCK_COMMAND 0x00010001

/* CFI block erase command */
#define CFI32_BLOCKERASE_COMMAND 0x00200020

/* CFI byte (word) write command */
#define CFI32_BYTEWRITE_COMMAND 0x00400040

/* CFI write exit command */
#define CFI32_WRITE_EXIT_COMMAND 0x00FF00FF

/* CFI block write command */
#define CFI32_BLOCK_WRITE_COMMAND 0x00E800E008

#else
/* CFI standard defines (32-bit) */
#define CFI32_TAG_Q 0x0051      /* First tag string =  '_Q_Q' */
#define CFI32_TAG_R 0x0052      /* Second tag string = '_R_R' */
#define CFI32_TAG_Y 0x0059      /* Third tag string =  '_Y_Y' */

/* CFI query command (32-bit) */
#define CFI32_QUERY_COMMAND 0x0098

/* CFI exit programming mode command */
#define CFI32_EXITPROG_COMMAND 0xFFFF

/* CFI read status command */
#define CFI32_READ_STATUS 0x0070

/* CFI clear status command */
#define CFI32_CLEAR_STATUS_COMMAND 0x0050

/* CFI set block command */
#define CFI32_SET_BLOCK_COMMAND 0x0060

/* CFI block confirm clear (lock) command */
#define CFI32_CONFIRM_CLEAR_BLOCK_COMMAND 0x00D0

/* CFI block confirm buffer write command */
#define CFI32_CONFIRM_BUFWRITE_COMMAND 0x00D0

/* CFI block confirm command */
#define CFI32_CONFIRM_SET_BLOCK_COMMAND 0x0001

/* CFI block erase command */
#define CFI32_BLOCKERASE_COMMAND 0x0020

/* CFI byte (word) write command */
#define CFI32_BYTEWRITE_COMMAND 0x0040

/* CFI write exit command */
#define CFI32_WRITE_EXIT_COMMAND 0x00FF

/* CFI block write command */
#define CFI32_BLOCK_WRITE_COMMAND 0x00E8
#endif 
/* CFI tag (QRY) register offset (32-bit) */
#define CFI32_TAG_OFFSET 0x00000010

/* CFI device geometry device size offset */
#define CFI32_DEVSIZE_OFFSET 0x00000027

/* CFI write buffer size offset */
#define CFI32_WBSIZE_OFFSET 0x0000002A

/* CFI erase block regions number offset */
#define CFI_ERBLK_OFFSET 0x0000002C

/* CFI erase block regions information offset */
#define CFI_REINFO_OFFSET 0x0000002D


/***********************************************************************
 * Private functions
 **********************************************************************/

/***********************************************************************
 *
 * Function: flash_write
 *
 * Purpose: Write a value to FLASH
 *
 * Processing:
 *     See function.
 *
 * Parameters: 
 *     addr: Address to write to
 *     data: Data to write to FLASH
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void flash_write(volatile UNS_32 *addr, UNS_32 data)
{
    *addr = data;
}

/***********************************************************************
 *
 * Function: flash_read
 *
 * Purpose: Read a value from FLASH
 *
 * Processing:
 *     See function.
 *
 * Parameters: 
 *     addr: Address to read
 *
 * Outputs: None
 *
 * Returns: Data read from the address
 *
 * Notes:
 *     A dummy read of another chip select is needed on consecutive
 *     reads to force the FLASH chip select to deassert. Be careful
 *     when calling this function consecutively.
 *
 **********************************************************************/
UNS_32 flash_read(volatile UNS_32 *addr)
{
    return *addr;
}

/***********************************************************************
 *
 * Function: power
 *
 * Purpose: Compute val to the power of pow.
 *
 * Processing:
 *     See function.
 *
 * Parameters: 
 *     val: Base value
 *     pow: Power value for val
 *
 * Outputs: None
 *
 * Returns: The computer power value of val.
 *
 * Notes: None
 *
 **********************************************************************/
UNS_32 power(UNS_32 val,
             UNS_32 pow)
{
    UNS_32 ret = 1;

    while (pow > 0)
    {
        ret = ret * val;
        pow--;
    }

    return ret;
}

/***********************************************************************
 *
 * Function: cfi_config_check
 *
 * Purpose:
 *    Check the configuration of a StrataFlash interface for the
 *    LPD SDK7A400 EVB.
 *
 * Processing:
 *     See function.
 *
 * Parameters: 
 *     addr: Base address of StrataFlash device(s)
 *
 * Outputs: None
 *
 * Returns: 0 if the FLASH device was detected, otherwise (-1)
 *
 * Notes:
 *     This sequence only works for 2x16 devices connected on a 32-bit
 *     bus in x16 mode.
 *
 **********************************************************************/
INT_32 cfi_config_check(volatile UNS_32 *addr)
{
    UNS_32 bbase;
    INT_32 idx, ebidx, bidx, status = -1;
	INT_32 i = 0, j = 0;  ///xj add for test
	

    /* Save base address of device */
    cfi_dg.baseaddr = (UNS_32) addr;

    /* Issue CFI query command to each device */
    flash_write(addr, CFI32_QUERY_COMMAND);

    /* Verify that QRY tags are correct */
    if ((flash_read(addr + CFI32_TAG_OFFSET) == CFI32_TAG_Q) &&
        (flash_read(addr + CFI32_TAG_OFFSET + 1) == CFI32_TAG_R) &&
        (flash_read(addr + CFI32_TAG_OFFSET + 2) == CFI32_TAG_Y))
    {
        /* Valid StrataFlash part */
        /* Get device(s) size in bytes */
        cfi_dg.devsize = (flash_read(addr + CFI32_DEVSIZE_OFFSET) &
            0xFF);
        cfi_dg.devsize = 2 * power(2, cfi_dg.devsize);

        /* Get write buffer size - the FLASH device returns this size
           in bytes, but since we need to program the interface in
           32-bit increments, this number is converted to 32-bit
           words (2 devices * buffer size per dev / 4 bytes per word) */
        cfi_dg.wb_size = ((flash_read(addr + CFI32_WBSIZE_OFFSET) &
            0xFF) + ((flash_read(addr + CFI32_WBSIZE_OFFSET + 1) &
            0xFF) << 8));
        cfi_dg.wb_size = ((2 * power(2, cfi_dg.wb_size)) / 4);

        /* Get number of erase block regions */
        cfi_dg.erblocks = (flash_read(addr + CFI_ERBLK_OFFSET) & 0xFF);

        /* Get regional block information */
        for (idx = 0; idx < cfi_dg.erblocks; idx++)  ///1 erblock for 404
        {
            /* Get low and high region sizes */
		
			i = addr + CFI_REINFO_OFFSET + (idx * 4);
			
            cfi_dg.blks[idx] = (UNS_16)
                (flash_read(addr + CFI_REINFO_OFFSET + (idx * 4)) &
                0xFF);

			
			cfi_dg.blks[idx] += (UNS_16)
                ((flash_read(addr + CFI_REINFO_OFFSET + 1 + (idx * 4)) &
                0xFF) << 8);
		

		    /* Get low and high region sizes */
            cfi_dg.bsize[idx] = (UNS_16)
                (flash_read(addr + CFI_REINFO_OFFSET + 2 + (idx * 4)) &
                0xFF);
            cfi_dg.bsize[idx] += (UNS_16)
                ((flash_read(addr + CFI_REINFO_OFFSET + 3 + (idx * 4)) &
                0xFF) << 8);
        }

        /* Compute block count, addresses, and sizes */
        idx = 0;
        cfi_dg.blocks = 0;
        bbase = (UNS_32) addr;
        ebidx = 0;
        while (ebidx < cfi_dg.erblocks)
        {
            /* Compute block info for this erase region */
            bidx = 0;
            while (bidx <= cfi_dg.blks[ebidx])
            {
                /* Save address to this block and size of block */
                cfi_dg.blk_addr[cfi_dg.blocks] = bbase;
                cfi_dg.blk_size[cfi_dg.blocks] = (2 * 0x100 * cfi_dg.bsize[ebidx]);

                /* Increment address to next block w/ 2 devices */
                bbase = bbase + cfi_dg.blk_size[cfi_dg.blocks];

                /* Increment block count */
                cfi_dg.blocks++;

                /* Next block in erase region */
                bidx++;
            }

            /* Next erase region */
            ebidx++;
        }

        status = 0;
    }

    return status;
}

/***********************************************************************
 *
 * Function: cfi_read_status
 *
 * Purpose: Return the device statuses
 *
 * Processing:
 *     See function.
 *
 * Parameters:
 *     addr: Base address of StrataFlash device(s)
 *
 * Outputs: None
 *
 * Returns: The statuses of the devices
 *
 * Notes: None
 *
 **********************************************************************/
UNS_32 cfi_read_status(volatile UNS_32 *addr)
{
	flash_write(addr, CFI32_READ_STATUS);

    return flash_read(addr);
}

/***********************************************************************
 *
 * Function: cfi_clear_status
 *
 * Purpose: Clear device statuses
 *
 * Processing:
 *     See function.
 *
 * Parameters: 
 *     addr: Base address of StrataFlash device(s)
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void cfi_clear_status(volatile UNS_32 *addr)
{
    flash_write(addr, CFI32_CLEAR_STATUS_COMMAND);
}

/***********************************************************************
 *
 * Function: cfi_wait_read
 *
 * Purpose: Wait for device to become ready
 *
 * Processing:
 *     See function.
 *
 * Parameters: 
 *     addr: Base address of StrataFlash device(s)
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
int  cfi_wait_read(volatile UNS_32 *addr)
{
	int tmp;
    /* Wait until device is ready on high and low devies */
    //while ((cfi_read_status(addr) & 0x00000080) == 0);
    //while ((cfi_read_status(addr) & 0x00800000) == 0);
    while ((cfi_read_status(addr) & 0x80) == 0);
    while ((cfi_read_status(addr) & 0x00800000) == 0);
    
    return cfi_read_status(addr); 
    cfi_clear_status(addr);
}

/***********************************************************************
 * Public functions
 **********************************************************************/

/***********************************************************************
 *
 * Function: cfi_detect
 *
 * Purpose: Detect the number of CFI devices and the configuration
 *
 * Processing:
 *     See function.
 *
 * Parameters: 
 *     addr: Base address of StrataFlash device(s)
 *
 * Outputs: None
 *
 * Returns: 0 if the FLASH device was detected, otherwise (-1)
 *
 * Notes: None
 *
 **********************************************************************/
INT_32 cfi_detect(volatile UNS_32 *addr)
{
    /* Attempt to check device */
    return cfi_config_check(addr);
}

/***********************************************************************
 *
 * Function: cfi_getdevsize
 *
 * Purpose: Return the (combined) device size in bytes

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -