210WinCE6.0NandFlash移植小进展
我这菜鸟水平折腾了3个月,今天终于看得懂一点点东西 NandFlsh使用的是三星的K9K8G08U0A 首先是wince600platformsmdkv210srccommonnandflashfmdCfnand.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,7,7},// Samsung 2Gbit SLC - K9K8G08U0A //这是添加Nand支持列表 其元素的顺序是按上面的结构体填写 /* 4Gbit DDP NAND Flash */ {0xEC,0xDC,4096,// Samsung 2Gbit SLC - K9F4G08U0A {0xEC,0xDA,// Samsung 2Gbit SLC - K9F2G08U0A {0xEC,0xF1,1024,// Samsung 1Gbit SLC - K91FG08U0C {0x00,0x00,0}//必须有这个,初始化的时候进行循环检测,此处0标识结束 }; 某些大神中的文章,大概理解到Nand和普通WinCE的驱动有点区别,不是普遍的PDD和MMD 而是FAL和FMD两层 FAL是抽象层,FMD就是实际对硬件进行操作的 不过我手头的BSP怎么都找不到FAL 只有很明显的wince600platformsmdkv210srccommonnandflashfmdfmd.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.rn"))); FMDERR(FMD_INFO,(TEXT("Manufacturer code : 0x%2Xrn"),nMID)); FMDERR(FMD_INFO,(TEXT("Device code : 0x%2Xrn"),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,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.rn"))); 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 2KBrn"))); v_pNFCONregs = NULL; goto CleanUp; } } else { // MLC NAND flash memory FMDERR(TRUE,(TEXT("FMD doesn't support the MLC NAND flash memory.rn"))); 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; } 我的文章基本上都是看到哪写到哪,看了什么写什么...思路混乱,谨慎阅读 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |