📄 flashlib.c
字号:
/* flashLib.c - Flash library */
/*
* am29LV320DB flash driver
* by Curt McDowell, 08-06-99, Broadcom Corp.
*/
/*
modification of TPOS
2c,06may03,lyx change flashDev[1] to 3M fit to COMP_BUF_SIZE in flashFsLib.h
2b,04apr04,lyx deleted swap from flash_dev_t
2a,27mar03,lyx support am29LV320DB driver for new board
*/
/* Copyright 1998-2000 Wind River Systems, Inc. */
/* NOMANUAL */
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "vxWorks.h"
#include "taskLib.h"
#include "config.h"
#include "flashLib.h"
#include "ads860.h"
int flashLibDebug = 0;
int flashLibInited = 0;
#define PRINTF if (flashLibDebug) printf
#if FALSE
#define PRIVATE static
#else
#define PRIVATE
#endif
#ifndef IO_SYNC
#define IO_SYNC __asm__(" sync") /* Macro for all i/o operations to use */
#endif
#ifndef EIEIO_SYNC
#define EIEIO_SYNC __asm__("eieio; sync")
#endif
#define eieio() __asm__("eieio": : : "memory");
#ifndef
#define KILL_TIME_FUNC ((iz * iz) / (iz + iz)) / ((iy + iz) / (iy * iz))
#endif
/*for DEBUG modify 2004.11.20 yangdy*/
#if 0 /*ark d10: 2 chips AM29LV320DB ,total 8M bytes*/
/***********************************************************************
*
* Virtual Flash Devices on Mousse board
*
* These must be kept in sync with the definitions in flashLib.h.
*
***********************************************************************/
PRIVATE flash_dev_t flashDev[] = {
/* Bank 0 sector SA0~SA7 (8 * 8kb =64 kB) not used */
{ FLASH_BANK, FLASH_START, 8, 13, FLASH_VENDOR_ID, FLASH_DEVICE_ID },
/* Bank 0 sector SA8~SA55(48 * 64 kB = 3Mkb ) VXWORKS IMAGE */
{ FLASH_BANK, FLASH_START + 0x10000, 48, 16, FLASH_VENDOR_ID, FLASH_DEVICE_ID},
/* Bank 0 sector SA56~SA63 (8 * 64 kB = 512kb ) DOS FILESYSTEM */
{ FLASH_BANK, FLASH_START + 0x310000 , 8, 16,FLASH_VENDOR_ID, FLASH_DEVICE_ID},
/* Bank 0 sector SA64~SA70 (7 * 64 kB =448Kb ) not used*/
{ FLASH_BANK, FLASH_START + 0x390000, 7, 16,FLASH_VENDOR_ID, FLASH_DEVICE_ID},
/* Bank 1 sector SA0~SA7 (8 * 8kb =64 kB) not used */
{ FLASH_BANK1, FLASH_START_2, 8, 13, FLASH_VENDOR_ID, FLASH_DEVICE_ID },
/* Bank 1 sector SA8~SA55 (48 * 64 kB = 3Mkb ) VXWORKS IMAGE */
{ FLASH_BANK1, FLASH_START_2 + 0x10000, 48, 16, FLASH_VENDOR_ID, FLASH_DEVICE_ID},
/* Bank 1 sector SA56~SA63 (8 * 64 kB = 512kb ) DOS FILESYSTEM */
{ FLASH_BANK1, FLASH_START_2 + 0x310000 , 8, 16,FLASH_VENDOR_ID, FLASH_DEVICE_ID},
/* Bank 1 sector SA64~SA70 (7 * 64 kB =448Kb ) not used*/
{ FLASH_BANK1, FLASH_START_2 + 0x390000, 7, 16,FLASH_VENDOR_ID, FLASH_DEVICE_ID},
};
#endif
/*ark d20: 2 chips AM29LV640MH/L ,total 16M bytes*/
#if 0
PRIVATE flash_dev_t flashDev[] = {
/* Bank 0 sector SA0 (1 * 64kb =64 kB) not used */
{ FLASH_BANK, FLASH_START, 1, 16, FLASH_VENDOR_ID, FLASH_DEVICE_ID },
/* Bank 0 sector SA1~SA96 (96 * 64 kB = 6Mkb ) VXWORKS IMAGE */
{ FLASH_BANK, FLASH_START + 0x10000, 96, 16, FLASH_VENDOR_ID, FLASH_DEVICE_ID},
/* Bank 0 sector SA97~SA120 (24 * 64 kB = 1.5Mkb ) DOS FILESYSTEM */
{ FLASH_BANK, FLASH_START + 0x610000 , 24, 16,FLASH_VENDOR_ID, FLASH_DEVICE_ID},
/* Bank 0 sector SA121~SA127 (7 * 64 kB =448Kb ) not used*/
{ FLASH_BANK, FLASH_START + 0x790000, 7, 16,FLASH_VENDOR_ID, FLASH_DEVICE_ID},
/* Bank 1 sector SA0 (1 * 64kb =64 kB) not used */
{ FLASH_BANK1, FLASH_START_2, 1, 16, FLASH_VENDOR_ID, FLASH_DEVICE_ID },
/* Bank 1 sector SA1~SA96 (96 * 64 kB = 6Mkb ) VXWORKS IMAGE */
{ FLASH_BANK1, FLASH_START_2 + 0x10000, 96, 16, FLASH_VENDOR_ID, FLASH_DEVICE_ID},
/* Bank 1 sector SA97~SA120 (24 * 64 kB = 1.5Mkb ) DOS FILESYSTEM */
{ FLASH_BANK1, FLASH_START_2 + 0x610000 , 24, 16,FLASH_VENDOR_ID, FLASH_DEVICE_ID},
/* Bank 1 sector SA121~SA127 (7 * 64 kB =448Kb ) not used*/
{ FLASH_BANK1, FLASH_START_2 + 0x790000, 7, 16,FLASH_VENDOR_ID, FLASH_DEVICE_ID},
#else
PRIVATE flash_dev_t flashDev[] = {
/* Bank 0 sector SA0 (1 * 64kb =64 kB) not used */
{ FLASH_BANK, FLASH_START, 1, 16, FLASH_VENDOR_ID, FLASH_DEVICE_ID },
/* Bank 0 sector SA1~SA103 (103 * 64 kB = 6Mkb+448kb ) VXWORKS IMAGE */
{ FLASH_BANK, FLASH_START + 0x10000, 103, 16, FLASH_VENDOR_ID, FLASH_DEVICE_ID},
/* Bank 0 sector SA104~SA127 (24 * 64 kB = 1.5Mkb ) DOS FILESYSTEM */
{ FLASH_BANK, FLASH_START + 0x680000 , 24, 16,FLASH_VENDOR_ID, FLASH_DEVICE_ID},
{ FLASH_BANK1, FLASH_START_2, 1, 16, FLASH_VENDOR_ID, FLASH_DEVICE_ID },
/* Bank 1 sector SA1~SA96 (96 * 64 kB = 6Mkb ) VXWORKS IMAGE */
{ FLASH_BANK1, FLASH_START_2 + 0x10000, 96, 16, FLASH_VENDOR_ID, FLASH_DEVICE_ID},
/* Bank 1 sector SA97~SA127 (24 * 64 kB = 1.5Mkb+448kb ) DOS FILESYSTEM */
{ FLASH_BANK1, FLASH_START_2 + 0x610000 , 31, 16,FLASH_VENDOR_ID, FLASH_DEVICE_ID},
#endif
};
int flashDevCount = (sizeof (flashDev) / sizeof (flashDev[0]));
#define DEV(no) (&flashDev[no])
#define DEV_NO(dev) ((dev) - flashDev)
/* 对BOOTROM部分的定义 */
#define BOOT_FLASH_VENDOR_ID 0x01
#define BOOT_FLASH_DEVICE_ID 0x04
PRIVATE flash_dev_t flashBootDev[] = {
{0, ROM_BASE_ADRS, 8, 16, BOOT_FLASH_VENDOR_ID, BOOT_FLASH_DEVICE_ID}
};
#define FLASH_BOOTDEV_COUNT (sizeof (flashBootDev) / sizeof (flashBootDev[0]))
/*
* The convention is:
*
* "addr" is always the PROM raw address, which is the address of an
* 8-bit quantity for flash 0 and 16-bit quantity for flash 1.
*
* "pos" is always a logical byte position from the PROM beginning.
*/
#define FLASH_ADDR(dev, addr) \
((UINT8 *) ((dev)->base + addr))
#define FLASH_WRITE(dev, addr, value) \
(*FLASH_ADDR(dev, addr) = (value))
#define FLASH_READ(dev, addr) \
( *FLASH_ADDR(dev, addr))
PRIVATE int flashCheck(flash_dev_t *dev)
{
if (! flashLibInited) {
printf("flashCheck: flashLib not initialized\n");
return ERROR;
}
if (dev < &flashDev[0] || dev >= &flashDev[flashDevCount]) {
printf("flashCheck: Bad dev parameter\n");
return ERROR;
}
if (! dev->found) {
printf("flashCheck: Device %d not available\n", DEV_NO(dev));
return ERROR;
}
return OK;
}
PRIVATE void flashReset(flash_dev_t *dev)
{
PRINTF("flashReset: dev=%d\n", DEV_NO(dev));
FLASH_WRITE(dev, 0xaaa, 0xaa);
FLASH_WRITE(dev, 0x555, 0x55);
FLASH_WRITE(dev, 0xaaa, 0xf0);
taskDelay(1);
PRINTF("flashReset: done\n");
}
PRIVATE void flashBootReset(flash_dev_t *dev)
{
PRINTF("flashReset: dev=%d\n", DEV_NO(dev));
FLASH_WRITE(dev, 0x555, 0xAA);
FLASH_WRITE(dev, 0x2AA, 0x55);
FLASH_WRITE(dev, 0xAAA, 0xF0);
taskDelay(1);
PRINTF("flashReset: done\n");
}
void myDelayLoop ( int cycles )
{
UINT32 ix = 0;
UINT32 iy = 1;
UINT32 iz = 2;
while (--cycles)
{
iy = KILL_TIME_FUNC; /* consume time */
ix++; /* increment the counter */
}
}
PRIVATE int flashProbe(flash_dev_t *dev)
{
unsigned int rv, deviceID, vendorID;
unsigned char tmp0,tmp1,tmp2;
int i=0 ,j =0,ix = 0,iy = 0;
UINT times = 1;
unsigned int dontcare;
flashLibDebug=1;
PRINTF("flashProbe: dev=%d\n", DEV_NO(dev));
FLASH_WRITE(dev, 0, 0xf0);
myDelayLoop(times);
eieio();
FLASH_WRITE(dev, 0xaaa, 0xaa);
FLASH_WRITE(dev, 0x555, 0x55);
FLASH_WRITE(dev, 0xaaa, 0x90);
vendorID = FLASH_READ(dev, 0);
tmp0 = FLASH_READ(dev, 0x02);
tmp1 = FLASH_READ(dev, 0x1c);
tmp2 = FLASH_READ(dev, 0x1e);
FLASH_WRITE(dev, 0, 0xf0);
eieio();
PRINTF("flashProbe: vendor=0x%x deviceID=0x%x 0x%x 0x%x \n", vendorID, tmp0,tmp1,tmp2);
deviceID = (tmp0 <<16)|(tmp1<<8)|(tmp2);
PRINTF("flashProbe: vendor=0x%x device=0x%x\n", vendorID, deviceID);
/*
if (vendorID == dev->vendorID && deviceID == dev->deviceID)
rv = OK;
else
rv = ERROR;
*//*deleted by lyx*/
rv=OK;
flashLibDebug=0;
return rv;
}
PRIVATE int flashBootProbe(flash_dev_t *dev)
{
unsigned int rv, deviceID, vendorID;
flashLibDebug=1;
PRINTF("flashProbe: dev=%d\n", DEV_NO(dev));
FLASH_WRITE(dev, 0, 0xf0);
FLASH_WRITE(dev, 0x555, 0xAA);
FLASH_WRITE(dev, 0x2AA, 0x55);
FLASH_WRITE(dev, 0x555, 0x90);
taskDelay(1);
vendorID = FLASH_READ(dev, 0x00);
deviceID = FLASH_READ(dev, 0x01);
FLASH_WRITE(dev, 0, 0xf0);
PRINTF("flashProbe: vendor=0x%x device=0x%x\n", vendorID, deviceID);
/*
if (vendorID == dev->vendorID && deviceID == dev->deviceID)
rv = OK;
else
rv = ERROR;
*//*deleted by lyx*/
rv=OK;
PRINTF("flashProbe: rv=%d\n", rv);
flashLibDebug=0;
return rv;
}
PRIVATE int flashWait(flash_dev_t *dev, int addr, int expect, int erase)
{
int rv = ERROR;
int i, data;
int polls;
rv = OK;
#if FALSE
PRINTF("flashWait: dev=%d addr=0x%x expect=0x%x erase=%d\n",
DEV_NO(dev), addr, expect, erase);
#endif
if (erase)
polls = FLASH_ERASE_SECTOR_TIMEOUT; /* Ticks */
else
polls = FLASH_PROGRAM_POLLS; /* Loops */
for (i = 0; i < polls; i++) {
if (erase)
taskDelay(1);
data = FLASH_READ(dev, addr);
if (((data ^ expect) & 0x80) == 0) {
rv = OK;
goto done;
}
if (data & 0x20) {
/*
* If the 0x20 bit has come on, it could actually be because
* the operation succeeded, so check the done bit again.
*/
data = FLASH_READ(dev, addr);
if (((data ^ expect) & 0x80) == 0) {
rv = OK;
goto done;
}
/*YOUNG printf("flashWait: Program error (dev: %d, addr: 0x%x)\n",
DEV_NO(dev), addr);
flashReset(dev);
goto done;*/
}
}
printf("flashWait: Timeout %s (dev: %d, addr: 0x%x)\n",
erase ? "erasing sector" : "programming byte",
DEV_NO(dev), addr);
printf("Address 0x%x, Expect 0x%x, Real 0x%x\n", addr, expect, data);
/*YOUNG */
flashReset(dev);
done:
#if FALSE
PRINTF("flashWait: rv=%d\n", rv);
#endif
return rv;
}
/***********************************************************************
*
* Public Flash Routines
*
***********************************************************************/
STATUS flashLibInit(void)
{
int i;
PRINTF("flashLibInit: devices=%d\n", flashDevCount);
for (i = 0; i < flashDevCount; i++) {
flash_dev_t *dev = &flashDev[i];
/*
* For bank 1, probe both without and with byte swappage,
* so that this module works on both old and new Mousse boards.
*/
flashReset(dev);
if (flashProbe(dev) != ERROR)
dev->found = 1;
/*
else if (dev->bank == FLASH_BANK) {
dev->swap = 1;
flashReset(dev);
if (flashProbe(dev) != ERROR)
dev->found = 1;
else
dev->swap = 0;
}*/ /*deleted 04apr03,lyx*/
}
flashLibInited = 1;
PRINTF("flashLibInit: done\n");
return OK;
}
STATUS flashEraseSector(flash_dev_t *dev, int sector)
{
int pos, addr;
PRINTF("flashErasesector: dev=%d sector=%d\n", DEV_NO(dev), sector);
if (flashCheck(dev) == ERROR)
return ERROR;
if (sector < 0 || sector >= dev->sectors) {
printf("flashEraseSector: Sector out of range (dev: %d, sector: %d)\n",
DEV_NO(dev), sector);
return ERROR;
}
pos = FLASH_SECTOR_POS(dev, sector);
addr = pos ;
FLASH_WRITE(dev, 0xaaa, 0xaa);
FLASH_WRITE(dev, 0x555, 0x55);
FLASH_WRITE(dev, 0xaaa, 0x80);
FLASH_WRITE(dev, 0xaaa, 0xaa);
FLASH_WRITE(dev, 0x555, 0x55);
FLASH_WRITE(dev, addr, 0x30);
return flashWait(dev, addr, 0xff, 1);
}
STATUS flashBootEraseSector(flash_dev_t *dev, int sector)
{
int pos, addr;
PRINTF("flashErasesector: dev=%d sector=%d\n", DEV_NO(dev), sector);
if (flashCheck(dev) == ERROR)
return ERROR;
if (sector < 0 || sector >= dev->sectors) {
printf("flashEraseSector: Sector out of range (dev: %d, sector: %d)\n",
DEV_NO(dev), sector);
return ERROR;
}
pos = FLASH_SECTOR_POS(dev, sector);
addr = pos ;
FLASH_WRITE(dev, 0x555, 0xAA);
FLASH_WRITE(dev, 0x2AA, 0x55);
FLASH_WRITE(dev, 0x555, 0x80);
FLASH_WRITE(dev, 0x555, 0xAA);
FLASH_WRITE(dev, 0x2AA, 0x55);
FLASH_WRITE(dev, addr, 0x30);
return flashWait(dev, addr, 0xff, 1);
}
/*
* Note: it takes about as long to flash all sectors together with Chip
* Erase as it does to flash them one at a time (about 30 seconds for 2
* MB). Also since we want to be able to treat subsets of sectors as if
* they were complete devices, we don't use Chip Erase.
*/
STATUS flashErase(flash_dev_t *dev)
{
int sector;
PRINTF("flashErase: dev=%d sectors=%d\n", DEV_NO(dev), dev->sectors);
if (flashCheck(dev) == ERROR)
return ERROR;
for (sector = 0; sector < dev->sectors; sector++)
if (flashEraseSector(dev, sector) == ERROR)
return ERROR;
return OK;
}
STATUS flashBootErase(flash_dev_t *dev)
{
int sector;
PRINTF("flashErase: dev=%d sectors=%d\n", DEV_NO(dev), dev->sectors);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -