📄 flash.c
字号:
/* * (C) Copyright 2003 * Martin Winistoerfer, martinwinistoerfer@gmx.ch. * * See file CREDITS for list of people who contributed to this * project. * * 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 *//* * File: flash.c * * Discription: This Driver is for 28F320J3A, 28F640J3A and * 28F128J3A Intel flashs working in 16 Bit mode. * They are single bank flashs. * * Most of this code is taken from existing u-boot * source code. *//*几片FLASH*/#define CFG_MAX_FLASH_BANKS 1/*每个FLASH有多少块*/#define CFG_MAX_FLASH_SECT 256#define FLASH_BASE0_PRELIM FLASH_BASE_ADRS/*#define DEBUG /**/#define INTEL_ID_28F320J3A 0x00160016 /* 32M = 128K x 32 */#define INTEL_ID_28F640J3A 0x00170017 /* 64M = 128K x 64 */#define INTEL_ID_28F128J3A 0x00180018 /* 128M = 128K x 128 */#define INTEL_ID_28F256J3A 0x001D001D /* 256M = 128K x 256 */#define FLASH_ID_28F320J3A 0x00C0 /* INTEL 28F320J3A ( 32M = 128K x 32) */#define FLASH_ID_28F640J3A 0x00C2 /* INTEL 28F640J3A ( 64M = 128K x 64) */#define FLASH_ID_28F128J3A 0x00C4 /* INTEL 28F128J3A (128M = 128K x 128) */#define FLASH_ID_28F256J3A 0x00C6 /* INTEL 28F256J3A (256M = 128K x 256) */#define FLASH_ID_UNKNOWN 0xFFFF /* unknown flash type *//*----------------------------------------------------------------------- * Device IDs */#define AMD_MANUFACT 0x00010001 /* AMD manuf. ID in D23..D16, D7..D0 */#define FUJ_MANUFACT 0x00040004 /* FUJITSU manuf. ID in D23..D16, D7..D0 */#define ATM_MANUFACT 0x001F001F /* ATMEL */#define STM_MANUFACT 0x00200020 /* STM (Thomson) manuf. ID in D23.. -"- */#define SST_MANUFACT 0x00BF00BF /* SST manuf. ID in D23..D16, D7..D0 */#define MT_MANUFACT 0x00890089 /* MT manuf. ID in D23..D16, D7..D0 */#define INTEL_MANUFACT 0x00890089 /* INTEL manuf. ID in D23..D16, D7..D0 */#define INTEL_ALT_MANU 0x00B000B0 /* alternate INTEL namufacturer ID */#define MX_MANUFACT 0x00C200C2 /* MXIC manuf. ID in D23..D16, D7..D0 */#define TOSH_MANUFACT 0x00980098 /* TOSHIBA manuf. ID in D23..D16, D7..D0 */#define MT2_MANUFACT 0x002C002C /* alternate MICRON manufacturer ID*/#define EXCEL_MANUFACT 0x004A004A /* Excel Semiconductor *//* manufacturer offsets */#define FLASH_MAN_AMD 0x00000000 /* AMD */#define FLASH_MAN_FUJ 0x00010000 /* Fujitsu */#define FLASH_MAN_BM 0x00020000 /* Bright Microelectronics */#define FLASH_MAN_MX 0x00030000 /* MXIC */#define FLASH_MAN_STM 0x00040000#define FLASH_MAN_TOSH 0x00050000 /* Toshiba */#define FLASH_MAN_EXCEL 0x00060000 /* Excel Semiconductor */#define FLASH_MAN_SST 0x00100000#define FLASH_MAN_INTEL 0x00300000#define FLASH_MAN_MT 0x00400000#define FLASH_MAN_SHARP 0x00500000#define FLASH_MAN_ATM 0x00600000#define FLASH_TYPEMASK 0x0000FFFF /* extract FLASH type information */#define FLASH_VENDMASK 0xFFFF0000 /* extract FLASH vendor information *//*----------------------------------------------------------------------- * FLASH Info: contains chip specific data, per FLASH bank */typedef struct { unsigned long size; /* total bank size in bytes */ unsigned short sector_count; /* number of erase units */ unsigned long flash_id; /* combined device & manufacturer code */ unsigned long start[CFG_MAX_FLASH_SECT]; /* physical sector start addresses */ unsigned char protect[CFG_MAX_FLASH_SECT]; /* sector protection status */} flash_info_t;#define FLASH_ID_MASK 0xFFFF#define FLASH_BLOCK_SIZE 0x00020000#define FLASH_CMD_READ_ID 0x0090#define FLASH_CMD_RESET 0x00ff#define FLASH_CMD_BLOCK_ERASE 0x0020#define FLASH_CMD_ERASE_CONFIRM 0x00D0#define FLASH_CMD_CLEAR_STATUS 0x0050#define FLASH_CMD_SUSPEND_ERASE 0x00B0#define FLASH_CMD_WRITE 0x0040#define FLASH_CMD_PROTECT 0x0060#define FLASH_CMD_PROTECT_SET 0x0001#define FLASH_CMD_PROTECT_CLEAR 0x00D0#define FLASH_STATUS_DONE 0x0080flash_info_t flash_info[CFG_MAX_FLASH_BANKS];/*--------------------------------------------------------------------** CPU 时钟周期: 50 Mhz 860 -- 20ns, 200 Mhz 8260 -- 5ns*---------------------------------------------------------------------*/#define CLOCK_860 20 #define CLOCK_8260 5#define CLOCK_ARM7 3#define CPU_CLOCK CLOCK_8260/* * Local function prototypes */static unsigned long flash_get_size (volatile unsigned short *addr, flash_info_t *info);static int write_short (flash_info_t *info, unsigned long dest, unsigned short data);static void flash_get_offsets (unsigned long base, flash_info_t *info);/*===============================================* * 辅助: helper function for time delay* *===============================================*/void DelayTime( unsigned long Tns ){ unsigned long i; for (i=0; i<Tns/CPU_CLOCK; i++);}/* 1000 纳秒: 写FALSH 时延*/#define DELAY_TIME 20/* program/erase operation inner algorithm be in progress or have been completed *//* 最大轮询时间: 将近118 秒*/#define POLL_TIME 10000int disable_interrupts(void){ return 0;}void enable_interrupts(void){}/* * Initialize flash */unsigned long flash_init_flag =0;unsigned long flash_init (void){ unsigned long size_b0; int i; flash_init_flag=0xacce; /* Init: no FLASHes known */ for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { flash_info[i].flash_id = FLASH_ID_UNKNOWN; } /* Static FLASH Bank configuration here - FIXME XXX */ size_b0 = flash_get_size((volatile unsigned short *)FLASH_BASE0_PRELIM, &flash_info[0]); if (flash_info[0].flash_id == FLASH_ID_UNKNOWN) { printf ("## Unknown FLASH on Bank 0: ID 0x%lx, Size = 0x%08lx = %ld MB\n", flash_info[0].flash_id, size_b0, size_b0<<20); } flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]); flash_info[0].size = size_b0; return size_b0;}/* * Compute start adress of each sector (block) */static void flash_get_offsets (unsigned long base, flash_info_t *info){ int i; if (info->flash_id == FLASH_ID_UNKNOWN) { return; } switch (info->flash_id & FLASH_VENDMASK) { case FLASH_MAN_INTEL: for (i = 0; i < info->sector_count; i++) { info->start[i] = base + i * FLASH_BLOCK_SIZE; } return; default: printf ("Don't know sector offsets for flash type 0x%lx\n", info->flash_id); return; }}/* * Print flash information */void flash_print_info (flash_info_t *info){ int i; if (info->flash_id == FLASH_ID_UNKNOWN) { printf ("missing or unknown FLASH type\n"); return; } switch (info->flash_id & FLASH_VENDMASK) { case FLASH_MAN_AMD: printf ("AMD "); break; case FLASH_MAN_FUJ: printf ("Fujitsu "); break; case FLASH_MAN_SST: printf ("SST "); break; case FLASH_MAN_STM: printf ("STM "); break; case FLASH_MAN_INTEL: printf ("Intel "); break; case FLASH_MAN_MT: printf ("MT "); break; default: printf ("Unknown Vendor "); break; } switch (info->flash_id & FLASH_TYPEMASK) { case FLASH_ID_28F320J3A: printf ("28F320J3A (32Mbit) 16-Bit\n"); break; case FLASH_ID_28F640J3A: printf ("28F640J3A (64Mbit) 16-Bit\n"); break; case FLASH_ID_28F128J3A: printf ("28F128J3A (128Mbit) 16-Bit\n"); break; default: printf ("Unknown Chip Type\n"); break; } if (info->size >= (1 << 20)) { i = 20; } else { i = 10; } printf (" Size: %ld %cB in %d Sectors\n", info->size >> i, (i == 20) ? 'M' : 'k', info->sector_count); printf (" Sector Start Addresses:"); for (i=0; i<info->sector_count; ++i) { if ((i % 5) == 0) printf ("\n "); printf (" %08lX%s", info->start[i], info->protect[i] ? " (RO)" : " " ); } printf ("\n"); return;}/* * Get size of flash in bytes. * The following code cannot be run from FLASH! */static unsigned long flash_get_size (volatile unsigned short *addr, flash_info_t *info){ volatile unsigned short value; /* Read Manufacturer ID */ addr[0] = FLASH_CMD_READ_ID; value = addr[0]; switch (value) { case (AMD_MANUFACT & FLASH_ID_MASK): info->flash_id = FLASH_MAN_AMD; break; case (FUJ_MANUFACT & FLASH_ID_MASK): info->flash_id = FLASH_MAN_FUJ; break; case (SST_MANUFACT & FLASH_ID_MASK): info->flash_id = FLASH_MAN_SST; break; case (STM_MANUFACT & FLASH_ID_MASK): info->flash_id = FLASH_MAN_STM; break; case (INTEL_MANUFACT & FLASH_ID_MASK): info->flash_id = FLASH_MAN_INTEL; break; default: info->flash_id = FLASH_ID_UNKNOWN; info->sector_count = 0; info->size = 0; addr[0] = FLASH_CMD_RESET; /* restore read mode */ return (0); /* no or unknown flash */ } value = addr[1]; /* device ID */ switch (value) { case (INTEL_ID_28F320J3A & FLASH_ID_MASK): info->flash_id += FLASH_ID_28F320J3A; info->sector_count = 32; info->size = 0x00400000; break; /* => 32 MBit */ case (INTEL_ID_28F640J3A & FLASH_ID_MASK): info->flash_id += FLASH_ID_28F640J3A; info->sector_count = 64; info->size = 0x00800000; break; /* => 64 MBit */ case (INTEL_ID_28F128J3A & FLASH_ID_MASK): info->flash_id += FLASH_ID_28F128J3A; info->sector_count = 128; info->size = 0x01000000;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -