📄 fmd.cpp
字号:
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 2006 Jade Technologies
Module Name: FMD.CPP
Abstract: FLASH Media Driver Interface Samsung K9K8G08 NAND Flash Chip
on Z228 development board.
Notes: Currently, *only* the CE 3.0 (and earlier) power management logic
is implemented (i.e. the PowerUp() and PowerDown() APIs).
Environment: As noted, this media driver works on behalf of the FAL to directly
access the underlying FLASH hardware. Consquently, this module
needs to be linked with FAL.LIB to produce the device driver
named FLASHDRV.DLL.
Author: Yan,Zheng
Change Log: 2007.02.05 Add WP
-----------------------------------------------------------------------------*/
#include <windows.h>
#include <ceddk.h>
#include <fmd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "cfnand.h"
//#include "args.h"
//#include "image_cfg.h"
//#include "nanflashfun.h"
#include "..\..\..\inc\platform.h"
NAND_CHIP_INFO *pChipInfo;
NAND_CHIP_INFO *pChipInfo2;
int isCE2 = 0;
#define EdbgOutputDebugString printf
//yz_add_070629
//you only have to modify here if GPIO changed !!!
static int GpioBaseAddr[] = { PHYS_GPIO0_BASE , PHYS_GPIO1_BASE , PHYS_GPIO2_BASE , PHYS_GPIO3_BASE , PHYS_GPIO4_BASE ,
PHYS_GPIO5_BASE , PHYS_GPIO6_BASE , PHYS_GPIO7_BASE , PHYS_GPIO8_BASE };
#define CS_GP_num 2
#define CS_GP_pin 1
#define RB_GP_num 4
#define RB_GP_pin 0
#define WP_GP_num 4
#define WP_GP_pin 3
//end
unsigned int BaseAddr = 0xcc000000;
unsigned int RegBaseAddr = 0x0; // R/B
unsigned int RegBaseAddr2 = 0x0; // CS1
//unsigned int RegBaseAddr3 = 0x20026000; // CS2
//unsigned int NandBaseAddr = 0x2000f000;
unsigned int NandWpAddr = 0x0;
#define IDLETIME 200
typedef unsigned long ULONG;
//void nandflash_test2(void);
void nand_wp(BOOL flag);
void WriteReg( unsigned int offset , unsigned int val )
{
*(volatile unsigned char*)(BaseAddr + offset ) = val ;
}
void WriteReg32( unsigned int offset , unsigned int val )
{
*(volatile unsigned int*)(BaseAddr + offset ) = val ;
}
unsigned char ReadReg( unsigned int offset )
{
return *(volatile unsigned char*)(BaseAddr + offset );
}
unsigned int ReadReg32( unsigned int offset )
{
return *(volatile unsigned int*)(BaseAddr + offset );
}
void WriteGPioCE( unsigned int offset , unsigned int val )
{
*(volatile unsigned int*)(RegBaseAddr2 + offset ) = val;
//RETAILMSG(1, (TEXT("WriteGPioCE:: offset = 0x%x, val = 0x%x\r\n"), offset, val));
}
unsigned int ReadGPioRB( unsigned int val)
{
return (*(volatile unsigned int*)(RegBaseAddr + (val<<2) ) & val);
}
/************************************************************
******************* Physical Driver Layer *******************
************************************************************/
UINT32 nand_getid(void)
{
UINT32 id1,id2,id3,id4;
//BOOL bLastMode = SetKMode(TRUE);
//RETAILMSG(1, (TEXT("nand_getid()\r\n")));
NF_CE_L();
//RETAILMSG(1, (TEXT("NF_CE_L()\r\n")));
//NF_CLEAR_RB();
NF_CMD(CMD_READ_ID);
//RETAILMSG(1, (TEXT("NF_CMD\r\n")));
NF_ADDR(CMD_READ);
//RETAILMSG(1, (TEXT("NF_ADDR\r\n")));
/*
for(index = 0; index < 100; index++)
{
id1 = NF_DATA_R();
if(id1 == 0xEC)
break;
}
*/
id1 = NF_DATA_R();
//RETAILMSG(1, (TEXT("NF_DATA_R\r\n")));
id2 = NF_DATA_R();
id3 = NF_DATA_R();
id4 = NF_DATA_R();
NF_CE_H();
//RETAILMSG(1, (TEXT("NF_CE_H()\r\n")));
//SetKMode(bLastMode);
return ((id1<<8) | id2);
}
UINT32 nand_getid2(void)
{
UINT32 id1,id2,id3,id4;
//BOOL bLastMode = SetKMode(TRUE);
//RETAILMSG(1, (TEXT("nand_getid()\r\n")));
NF_CE_L_2();
//RETAILMSG(1, (TEXT("NF_CE_L()\r\n")));
//NF_CLEAR_RB();
NF_CMD(CMD_READ_ID);
//RETAILMSG(1, (TEXT("NF_CMD\r\n")));
NF_ADDR(CMD_READ);
//RETAILMSG(1, (TEXT("NF_ADDR\r\n")));
/*
for(index = 0; index < 100; index++)
{
id1 = NF_DATA_R();
if(id1 == 0xEC)
break;
}
*/
id1 = NF_DATA_R();
//RETAILMSG(1, (TEXT("NF_DATA_R\r\n")));
id2 = NF_DATA_R();
id3 = NF_DATA_R();
id4 = NF_DATA_R();
NF_CE_H_2();
//RETAILMSG(1, (TEXT("NF_CE_H()\r\n")));
//SetKMode(bLastMode);
return ((id1<<8) | id2);
}
void nand_wait(void)
{
volatile int count=20;
while(count-- && (ReadGPioRB(1<<RB_GP_pin)) );
#if 0
volatile int count = 10;
while(count--);
#endif
}
int nand_erase(UINT32 blkpage)
{
int iRet;
#ifdef S512
blkpage = blkpage / 4;
#endif
nand_wp(FALSE);
NF_CE_L();
switch(pChipInfo->rowaddrcycle)
{
case 2:
{
NF_CMD(CMD_ERASE);
NF_ADDR(blkpage&0xFF);
NF_ADDR((blkpage>>8)&0xFF);
NF_CMD(CMD_ERASE2);
}
break;
case 3:
{
NF_CMD(CMD_ERASE);
NF_ADDR(blkpage&0xFF);
NF_ADDR((blkpage>> 8)&0xFF);
NF_ADDR((blkpage>>16)&0xFF);
NF_CMD(CMD_ERASE2);
}
break;
}
nand_wait();
NF_DETECT_RB();
NF_CMD(CMD_STATUS);
if(NF_DATA_R() & 0x01)
iRet = -1;
else
iRet = 0;
NF_CE_H();
nand_wp(TRUE);
return iRet;
}
int nand_readpage(UINT32 blkpage,UINT8 *pagebuf)
{
UINT32 index,mode;
#ifdef S512
//int NewSpareAddr = 2048 + 16*(blkpage%4);
int NewDataAddr = 512*(blkpage%4);
int NewSectorAddr = blkpage/4;
#endif
if((pagebuf == NULL) || (pChipInfo == NULL))
return -1;
mode = (pChipInfo->coladdrcycle&0xF) | ((pChipInfo->rowaddrcycle&0xF)<<4);
NF_CE_L();
switch(mode)
{
case 0x21:
{
NF_CMD(CMD_READ);
NF_ADDR(0x0);
NF_ADDR(blkpage&0xFF);
NF_ADDR((blkpage>>8)&0xFF);
}
break;
case 0x22:
{
NF_CMD(CMD_READ);
NF_ADDR(0x00);
NF_ADDR(0x00);
NF_ADDR(blkpage&0xFF);
NF_ADDR((blkpage>>8)&0xFF);
}
break;
case 0x31:
{
NF_CMD(CMD_READ);
NF_ADDR(0x00);
NF_ADDR(blkpage&0xFF);
NF_ADDR((blkpage>>8)&0xFF);
NF_ADDR((blkpage>>16)&0xFF);
}
break;
case 0x32:
{
#ifdef S512
NF_CMD(CMD_READ);
NF_ADDR((NewDataAddr)&0xff);
NF_ADDR(((NewDataAddr)>>8)&0xff);
NF_ADDR((NewSectorAddr) & 0xff);
NF_ADDR((NewSectorAddr >> 8) & 0xff);
NF_ADDR((NewSectorAddr >> 16) & 0xff);
#else
NF_CMD(CMD_READ);
NF_ADDR(0x00);
NF_ADDR(0x00);
NF_ADDR(blkpage&0xFF);
NF_ADDR((blkpage>>8)&0xFF);
NF_ADDR((blkpage>>16)&0xFF);
#endif
}
break;
}
if(pChipInfo->sectorperpage == 4)
NF_CMD(CMD_READ3);
nand_wait();
NF_DETECT_RB();
for(index = 0; index < pChipInfo->pagesize; index++)
pagebuf[index] = (BYTE)NF_DATA_R();
NF_CE_H();
return 0;
}
int nand_writepage(UINT32 blkpage,UINT8 *pagebuf)
{
int iRet;
UINT32 index, mode;
#ifdef S512
//int NewSpareAddr = 2048 + 16*(blkpage%4);
int NewDataAddr = 512*(blkpage%4);
int NewSectorAddr = blkpage/4;
#endif
if((pagebuf == NULL) || (pChipInfo == NULL))
return -1;
mode = (pChipInfo->coladdrcycle&0xF) | ((pChipInfo->rowaddrcycle&0xF)<<4);
nand_wp(FALSE);
NF_CE_L();
switch(mode)
{
case 0x21:
{
NF_CMD(CMD_READ);
NF_CMD(CMD_WRITE);
NF_ADDR(0x00);
NF_ADDR(blkpage&0xFF);
NF_ADDR((blkpage>>8)&0xFF);
}
break;
case 0x22:
{
NF_CMD(CMD_READ);
NF_CMD(CMD_WRITE);
NF_ADDR(0x00);
NF_ADDR(0x00);
NF_ADDR(blkpage&0xFF);
NF_ADDR((blkpage>>8)&0xFF);
}
break;
case 0x31:
{
NF_CMD(CMD_READ);
NF_CMD(CMD_WRITE);
NF_ADDR(0x00);
NF_ADDR(blkpage&0xFF);
NF_ADDR((blkpage>>8)&0xFF);
NF_ADDR((blkpage>>16)&0xFF);
}
break;
case 0x32:
{
#ifdef S512
NF_CMD(CMD_READ);
NF_CMD(CMD_WRITE);
NF_ADDR((NewDataAddr)&0xff);
NF_ADDR(((NewDataAddr)>>8)&0xff);
NF_ADDR((NewSectorAddr) & 0xff);
NF_ADDR((NewSectorAddr >> 8) & 0xff);
NF_ADDR((NewSectorAddr >> 16) & 0xff);
#else
NF_CMD(CMD_READ);
NF_CMD(CMD_WRITE);
NF_ADDR(0x00);
NF_ADDR(0x00);
NF_ADDR(blkpage&0xFF);
NF_ADDR((blkpage>>8)&0xFF);
NF_ADDR((blkpage>>16)&0xFF);
#endif
}
break;
}
for(index = 0; index < pChipInfo->pagesize ; index++)
NF_DATA_W(pagebuf[index]);
NF_CMD(CMD_WRITE2);
nand_wait();
NF_DETECT_RB();
NF_CMD(CMD_STATUS);
if(NF_DATA_R() & 0x01)
iRet = -1;
else
iRet = 0;
NF_CE_H();
nand_wp(TRUE);
return iRet;
}
int nand_readoob(UINT32 blkpage,UINT32 offset,UINT8 *oobbuf,UINT32 readlen)
{
UINT8 readcmd,coladdr1,coladdr2;
UINT32 index,mode;
#ifdef S512
int NewSpareAddr = 2048 + 16*(blkpage%4);
blkpage = blkpage / 4;
#endif
if((oobbuf == NULL) || (pChipInfo == NULL))
return -1;
if(pChipInfo->sectorperpage == 4)
{
readcmd = CMD_READ;
#ifdef S512
coladdr1 = (NewSpareAddr + offset)&0xFF;
coladdr2 = ((NewSpareAddr + offset)>>8)&0xFF;
#else
coladdr1 = (pChipInfo->pagesize + offset)&0xFF;
coladdr2 = ((pChipInfo->pagesize + offset)>>8)&0xFF;
#endif
}
else
{
readcmd = CMD_READ2;
coladdr1 = offset&0xFF;
coladdr2 = (offset>>8)&0xFF;
}
mode = (pChipInfo->coladdrcycle&0xF) | ((pChipInfo->rowaddrcycle&0xF)<<4);
NF_CE_L();
switch(mode)
{
case 0x21:
{
NF_CMD(readcmd);
NF_ADDR(coladdr1);
NF_ADDR(blkpage&0xFF);
NF_ADDR((blkpage>>8)&0xFF);
}
break;
case 0x22:
{
NF_CMD(readcmd);
NF_ADDR(coladdr1);
NF_ADDR(coladdr2);
NF_ADDR(blkpage&0xFF);
NF_ADDR((blkpage>>8)&0xFF);
}
break;
case 0x31:
{
NF_CMD(readcmd);
NF_ADDR(coladdr1);
NF_ADDR(blkpage&0xFF);
NF_ADDR((blkpage>>8)&0xFF);
NF_ADDR((blkpage>>16)&0xFF);
}
break;
case 0x32:
{
//NF_CMD(readcmd);
NF_CMD(readcmd); //yz_add
NF_ADDR(coladdr1);
NF_ADDR(coladdr2);
NF_ADDR(blkpage&0xFF);
NF_ADDR((blkpage>>8)&0xFF);
NF_ADDR((blkpage>>16)&0xFF);
}
break;
}
if(pChipInfo->sectorperpage == 4)
NF_CMD(CMD_READ3);
nand_wait();
NF_DETECT_RB();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -