210WinCE6.0NandFlash移植小进展

我这菜鸟水平折腾了3个月,今天终于看得懂一点点东西

NandFlsh使用的是三星的K9K8G08U0A

首先是\wince600\platform\smdkv210\src\common\nandflash\fmd\Cfnand.h下的小分析

以下结构体用于存储NandFalsh的信息

typedef struct
{
UINT8 ucMID;// Manufacturer ID厂家ID
UINT8 ucDID;// Device ID设备ID
UINT8 ucType;// SLC / MLC类型,分SLC和MLC,在百度百科可以搜到2者大致的差别

UINT16 usNumberOfBlocks; // Number of blocksBlock的数量,芯片手册第九页可以查到是8192
UINT16 usPagesPerBlock; // Number of pages per blockPage的数量
UINT16 usBytesPerPage; // Number of bytes per page
UINT16 usMainBytesPerPage; // Main area size per page主区的页大小
UINT16 usSpareBytesPerPage; // Spare area size per page扩展区的页大小

//三个时序 要特别理解还是谈不上
DWORD dwTACLS;
DWORD dwTWRPH0;
DWORD dwTWRPH1;
} NAND_FLASH_SPEC;




static NAND_FLASH_SPEC g_supportedNAND[] = 
{
/* 8Gbit DDP NAND Flash */
{0xEC, 0xD3, SLC_NAND, 8192, 64, 2112, 2048, 64, 7, 7, 7},// Samsung 2Gbit SLC - K9K8G08U0A
//这是添加Nand支持列表 其元素的顺序是按上面的结构体填写
/* 4Gbit DDP NAND Flash */
{0xEC, 0xDC, SLC_NAND, 4096, 64, 2112, 2048, 64, 7, 7, 7},// Samsung 2Gbit SLC - K9F4G08U0A
{0xEC, 0xDA, SLC_NAND, 2048, 64, 2112, 2048, 64, 7, 7, 7},// Samsung 2Gbit SLC - K9F2G08U0A
{0xEC, 0xF1, SLC_NAND, 1024, 64, 2112, 2048, 64, 7, 7, 7},// Samsung 1Gbit SLC - K91FG08U0C
{0x00, 0x00, SLC_NAND, 0, 0, 0, 0, 0}//必须有这个,初始化的时候进行循环检测,此处0标识结束
};


某些大神中的文章,大概理解到Nand和普通WinCE的驱动有点区别,不是普遍的PDD和MMD

而是FAL和FMD两层

FAL是抽象层,FMD就是实际对硬件进行操作的

不过我手头的BSP怎么都找不到FAL

只有很明显的\wince600\platform\smdkv210\src\common\nandflash\fmd\fmd.cpp下的

FMD_XXX函数,而且多数被FMD_LB_XXX函数调用

我的水平只能理解FMD_LB_XXX比FMD_XXX高一层


在初始化之前是注册这三个东西

static volatile NAND_REG *v_pNFCONregs = (NAND_REG *)NAND_BASE;
static volatile NAND_ECC_REG *v_pECCregs = (NAND_ECC_REG *)ECC_BASE;
NAND_FLASH_SPEC *g_pNANDSpec = NULL;


首先看的是函数

PVOID FMD_Init(LPCTSTR lpActiveReg, PPCI_REG_INFO pRegIn, PPCI_REG_INFO pRegOut)

其操作先后是

1.初始化注册

if (pRegIn && pRegIn->MemBase.Num && pRegIn->MemBase.Reg[0])
   v_pNFCONregs = (NAND_REG *)(pRegIn->MemBase.Reg[0]);
else
   v_pNFCONregs = (NAND_REG *)NAND_BASE;


2.ECC的注册 ECC是校检用的 据我所知有硬件校检和软件校检之分,这里看来这么简单的样子我才不是软件校检...

v_pECCregs = (NAND_ECC_REG *)ECC_BASE;

3.接着设置时序

v_pNFCONregs->NFCONF = (NAND_TACLS << 12) | (NAND_TWRPH0 << 8) | (NAND_TWRPH1 << 4);
v_pNFCONregs->NFCONT = (0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(0x3<<1)|(1<<0);
v_pNFCONregs->NFSTAT = (1<<4);


4.读ID,检测

// 读Nand的MID(厂家ID)和DID(设备ID)
rdid = ReadFlashID();


//分离
nMID = (UINT8)(rdid >> 8);
nDID = (UINT8)(rdid & 0xff);

for (nCnt = 0; g_supportedNAND[nCnt].ucMID != 0; nCnt++)
{
if (nDID == g_supportedNAND[nCnt].ucDID && nMID == g_supportedNAND[nCnt].ucMID )
//查看支持列表中有没有与nand读到对应的(cfnand.h)
{
g_pNANDSpec = &(g_supportedNAND[nCnt]);
break;
}
}

if(g_pNANDSpec == NULL)//没有支持的
{
FMDERR(TRUE, (TEXT("Failed to find a supported NAND flash memory.\r\n")));
FMDERR(FMD_INFO, (TEXT("Manufacturer code         : 0x%2X\r\n"), nMID));
FMDERR(FMD_INFO, (TEXT("Device code               : 0x%2X\r\n"), nDID));


// error return
v_pNFCONregs = NULL;
goto CleanUp;
}



5.设置

dwTotalNumberOfPages = g_pNANDSpec->usNumberOfBlocks * g_pNANDSpec->usPagesPerBlock;

dwTACLS = g_pNANDSpec->dwTACLS;
dwTWRPH0 = g_pNANDSpec->dwTWRPH0;
dwTWRPH1 = g_pNANDSpec->dwTWRPH1;
// -- SLC or MLC
// -- FMD driver supports SLC NAND flash memory only.
if(g_pNANDSpec->ucType == SLC_NAND)
{
if(g_pNANDSpec->usMainBytesPerPage == 2048)
{
if(dwTotalNumberOfPages > (1 << 16))
{
// SLC, Large block, 5 address cycle
v_pNFCONregs->NFCONF = (dwTACLS  <<  12) | (dwTWRPH0 <<  8) | (dwTWRPH1 <<  4)
| ECC_1BIT | SLC_NAND | LARGE_BLOCK | EXT_ADDR;
NEED_EXT_ADDR = TRUE;
}
else
{
// SLC, Large block, 4 address cycle
v_pNFCONregs->NFCONF = (dwTACLS  <<  12) | (dwTWRPH0 <<  8) | (dwTWRPH1 <<  4)
| ECC_1BIT | SLC_NAND | LARGE_BLOCK;
NEED_EXT_ADDR = FALSE;
}
}
else if(g_pNANDSpec->usMainBytesPerPage == 512)
{
// Small block NAND
FMDERR(TRUE, (TEXT("FMD doesn't support the small block NAND flash memory.\r\n")));


v_pNFCONregs = NULL;
goto CleanUp;
}
else
{
// page size > 2KB
FMDERR(TRUE, (TEXT("FMD doesn't support the NAND flash memory whose page size is larger than 2KB\r\n")));

v_pNFCONregs = NULL;
goto CleanUp;
}
}
else
{
// MLC NAND flash memory
FMDERR(TRUE, (TEXT("FMD doesn't support the MLC NAND flash memory.\r\n")));


v_pNFCONregs = NULL;
goto CleanUp;
}



某次调试中发现,依旧还是提示失败,不支持的NandFlash

顺藤摸瓜的找到

    switch(cMID)
    {
    case 0xEC:
    {
    switch(cDID)
    {
    case 0xDA://Samsung 2Gbit SLC - K9F2G08U0A  在这里添加对应的DID
case 0xDC://Samsung 2Gbit SLC - K9F4G08U0A
case 0xD3://Samsung 2Gbit SLC - K9K8G08U0A
    {
    g_bLargeBlock = TRUE;
    NEED_EXT_ADDR = TRUE;
    break;
    }


    case 0xF1://Samsung 1Gbit SLC - K91FG08U0C
    {
    g_bLargeBlock = TRUE;
    NEED_EXT_ADDR = FALSE;
    break;
    }


    default:
    // Not supported NAND
while(1);
    break;
    }


break;     
    }


我的文章基本上都是看到哪写到哪,看了什么写什么...思路混乱,谨慎阅读

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值