www.pudn.com > S3c2410bsp.zip > sst39vf160.c
/* sst39vf160.c - SST39VF160 MTD driver */
/*
modification history
--------------------
*/
#include "intLib.h"
#include "stdio.h"
#include "tffs/flflash.h"
#include "config.h"
#define FLASH_BASE_ADRS ROM_SIZE
#define FLASH_SIZE (0x00400000-ROM_SIZE)
typedef struct {
FlashWPTR unlockAddr1;
FlashWPTR unlockAddr2;
} Vars;
static Vars mtdVars[DRIVES];
#define thisVars ((Vars *) vol.mtdVars)
#undef DEBUG_PRINT
static void FAR0* sst39vf160Map(FLFlash* pVol, CardAddress address, int length);
static FLStatus sst39vf160Erase (FLFlash vol, int firstErasableBlock, int numOfErasableBlocks);
static FLStatus sst39vf160Write (FLFlash vol, CardAddress address, const void FAR1 *buffer, int length, int modes);
static STATUS doneDetect(void * ptr, int timeCounter);
FLStatus sst39vf160Identify(FLFlash vol)
{
FlashWPTR baseFlashPtr;
#ifdef DEBUG_PRINT
#endif
flSetWindowBusWidth(vol.socket, 16); /* use 16-bits */
flSetWindowSpeed(vol.socket, 90); /* 90 nsec */
flSetWindowSize(vol.socket, FLASH_SIZE>>12);
vol.interleaving = 1;
vol.chipSize = FLASH_SIZE;
vol.noOfChips = 0x1; /* one chip */
vol.erasableBlockSize = 0x1000; /* 4k bytes */
vol.flags |= SUSPEND_FOR_WRITE;
vol.map = sst39vf160Map;
vol.erase = sst39vf160Erase;
vol.write = sst39vf160Write;
vol.mtdVars = &mtdVars[flSocketNoOf(vol.socket)];
baseFlashPtr = (FlashWPTR)vol.map (&vol, (CardAddress)0, vol.interleaving);
thisVars->unlockAddr1 = (FlashWPTR)((long)baseFlashPtr) + 0x5555;
thisVars->unlockAddr2 = (FlashWPTR)((long)baseFlashPtr) + 0x2aaa;
return flOK;
}
static void FAR0* sst39vf160Map(FLFlash* pVol, CardAddress address, int length)
{
void FAR0* pFlash = (void FAR0*) (FLASH_BASE_ADRS + address);
return(pFlash);
}
static FLStatus sst39vf160Erase (FLFlash vol, int firstErasableBlock, int numOfErasableBlocks)
{
int iBlock, i; FlashWPTR flashPtr;
unsigned int offset; int level;
if(numOfErasableBlocks <= 0) return ERROR;
for (iBlock = 0; iBlock < numOfErasableBlocks; iBlock++)
{
offset = (firstErasableBlock + iBlock) * vol.erasableBlockSize;
flashPtr = (FlashWPTR) vol.map(&vol, offset, vol.interleaving);
#ifdef DEBUG_PRINT
#endif
*thisVars->unlockAddr1 = 0xaa;
*thisVars->unlockAddr2 = 0x55;
*thisVars->unlockAddr1 = 0x80;
*thisVars->unlockAddr1 = 0xaa;
*thisVars->unlockAddr2 = 0x55;
level = intLock();
*flashPtr = 0x30;
doneDetect((void *)flashPtr, 0x2000000);
for(i=0; i= 1) {
*thisVars->unlockAddr1 = 0x0aa;
*thisVars->unlockAddr2 = 0x55;
level = intLock();
*thisVars->unlockAddr1 = 0x0a0;
*flashPtr = *gBuffer;
doneDetect((void *)flashPtr, 0x1000000);
if(*flashPtr != *gBuffer) {
*flashPtr = 0xf0;
return flWriteFault;
}
intUnlock(level);
cLength--;
flashPtr++;
gBuffer++;
}
if (tffscmp((void FAR0 *)flashTmp, buffer,length))
{
return flWriteFault;
}
return flOK;
}
static STATUS doneDetect(void * ptr, int timeCounter)
{
FlashWPTR pFlash = ptr;
INT16 buf1,buf2;
buf1 = *pFlash & 0x40;
while(1){
buf2 = *pFlash & 0x40;
if(buf1 == buf2) break;
else buf1 = buf2;
if(timeCounter-- <= 0) return ERROR;
}
return OK;
}