三星 nand flash 读写问题

小陆zi 2012-08-09 05:15:46
hi 大家好:

我最近在看flash的驱动。环境就是在uboot下。
我的问题是这样:
现象:
nand write 时候column address 始终保持0,但是page的address 在自加。
函数:
do_nand -> nand_do_write_ops -> nand_write_page -> s3c_nand_write_page_8bit
在nand_write_page中调用chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
我把page打印出来page是从 0 1 2 3 ...... 511
那么我的理解是写flash的操作是以page为单位的。page 自加 完成偏移。

我看了网上的一篇文章,对于K9K8G08 flash的操作时候定义的寻址方式有出入。
A0 - A11 是col的地址,2K 个 Byte + 64 Byte的寻址。
A12 - A17 是page在block中的偏移量。应为有64个page组成一个block。
A18 - A30 是block的index。K9K8G08的片内一共有8192个block。


但是我自己写了一个测试函数去读flash的中的内容的时候发现 读出来的数据和写入的数据不符合。
我自己写的flash的read函数就是想要:
从第一个block中第一个page中读出前256Bytes (0 block 0 page offset 0 col)

函数这样写:
cmdfunc(mtd, NAND_CMD_READ0, 0, 0);
device_ready();
nand_read();
printf("content %X\n",buf);

打印出来的数据和uboot内容不一样。这是为什么啊?

谢谢
希望大侠 多指点!
...全文
391 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
xgbing 2012-08-09
  • 打赏
  • 举报
回复
/*--------------------------------------------------------------------------
* Function:
* ReadFlashMainArea
*
* Parameters:
* chunkInNAND - chunk number.
* outBuffer - output buffer.
* outEccResult - ecc result.
*
* Returns value:
* If successed, return bTRUE, else bFALSE;
*
* Description:
* Read main area data in flash.
*
*--------------------------------------------------------------------------*/
static int ReadFlashMainArea(int chunkInNAND, TUINT8 *outBuffer, yaffs_ECCResult *outEccResult)
{
int ret = YAFFS_OK;

DEBUG_ASSERT(chunkInNAND >= 0 && chunkInNAND < BLOCK_NUM_PER_DEVICE * PAGE_NUM_PER_BLOCK);
DEBUG_ASSERT(outBuffer != NULL);
DEBUG_ASSERT(outEccResult != NULL);

/* Enable the chip */
//NandEnableCE();


/* Write specific command, Read from start */
WRITE_NAND_COMMAND(CMD_READ_1);

/* Push sector address */
//uSectorAddr >>= pNandInfo->uOffset;

TUINT32 col, row;
col = 0;
row = chunkInNAND;
WRITE_NAND_ADDRESS(col & 0xFF);
WRITE_NAND_ADDRESS((col >> 8) & 0xFF);
WRITE_NAND_ADDRESS((row >> 0) & 0xFF);
WRITE_NAND_ADDRESS((row >> 8) & 0xFF);
WRITE_NAND_ADDRESS((row >> 16) & 0xFF);

WRITE_NAND_COMMAND(CMD_READ_2);



NAND_WAIT_READY();
NAND_WAIT_READY();

/* Read loop */
TINT i;
for(i=0; i < DATA_SIZE; i++)
{
*outBuffer = READ_NAND_DATA();
outBuffer++;
}

/* Read ecc */
WRITE_NAND_COMMAND(CMD_RAND_READ1);
WRITE_NAND_ADDRESS(ECCC_BASE_IN_SPARE & 0xFF);
WRITE_NAND_ADDRESS((ECCC_BASE_IN_SPARE >> 8) & 0xFF);
WRITE_NAND_COMMAND(CMD_RAND_READ2);

NAND_WAIT_READY();
NAND_WAIT_READY();

//Read 4 cycles.
READ_NAND_DATA();
READ_NAND_DATA();
READ_NAND_DATA();
READ_NAND_DATA();

/* judge ecc */
*outEccResult = CorrectECC(outBuffer);

/* Disable the chip */
//NandDisableCE();

return ret;
}
xgbing 2012-08-09
  • 打赏
  • 举报
回复
/*--------------------------------------------------------------------------
* Function:
* WriteFlashMainArea
*
* Parameters:
* chunkInNand - chunk number.
* inBuffer - main area data buffer.
*
* Returns value:
* If success, return bTRUE, else bFALSE.
*
* Description:
* Write data into nand flash main area.
*
*--------------------------------------------------------------------------*/
static int WriteFlashMainArea(int chunkInNAND, const TUINT8 *inBuffer)
{
int ret = YAFFS_OK;

DEBUG_ASSERT(chunkInNAND >= 0 && chunkInNAND < BLOCK_NUM_PER_DEVICE * PAGE_NUM_PER_BLOCK);
DEBUG_ASSERT(inBuffer != NULL);
/* Enable the chip */
//NandEnableCE();

/* Write specific command, Read from start */
WRITE_NAND_COMMAND(CMD_WRITE_1);

/* Push sector address */
//uSectorAddr >>= pNandInfo->uOffset;

WRITE_NAND_ADDRESS(0);
WRITE_NAND_ADDRESS(0);
WRITE_NAND_ADDRESS((chunkInNAND >> 0) & 0xFF);
WRITE_NAND_ADDRESS((chunkInNAND >> 8) & 0xFF);
WRITE_NAND_ADDRESS((chunkInNAND >> 16) & 0xFF);



/* Write loop */
TINT i;
for(i=0; i < DATA_SIZE; i++)
{
WRITE_NAND_DATA(*inBuffer);
inBuffer++;
}

//Write ECC
WRITE_NAND_COMMAND(CMD_RAND_WRITE);

WRITE_NAND_ADDRESS(ECCC_BASE_IN_SPARE & 0xFF);
WRITE_NAND_ADDRESS((ECCC_BASE_IN_SPARE >> 8) & 0xFF);

TUINT16 data_ECC_PR,data_ECC_NPR;
data_ECC_PR = (TUINT16)pAt91s_ecc->ECC_PR;
data_ECC_NPR = (TUINT16)pAt91s_ecc->ECC_NPR;

WRITE_NAND_DATA(data_ECC_PR & 0xFF);
WRITE_NAND_DATA((data_ECC_PR >> 8) & 0xFF);
WRITE_NAND_DATA(data_ECC_NPR & 0xFF);
WRITE_NAND_DATA((data_ECC_NPR >> 8) & 0xFF);

WRITE_NAND_COMMAND(CMD_WRITE_2);


/* Wait for flash to be ready (can't pool on status, read upper WARNING) */
NAND_WAIT_READY();
NAND_WAIT_READY(); /* Need to be done twice, READY detected too early the first time? */

if(StatusRegIsSet(0))
{
ret = YAFFS_FAIL;
}


/* Disable the chip */
//NandDisableCE();

return ret;
}
xgbing 2012-08-09
  • 打赏
  • 举报
回复
int K9K8G08U0A_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)
{
TBOOL bRet = bTRUE;
TUINT rowAdr;

CheckInit(dev);

if(blockNumber < 0 || blockNumber >= BLOCK_NUM_PER_DEVICE)
{
//T(YAFFS_TRACE_ALWAYS,("Attempt to erase non-existant block %d\n",blockNumber));
return (YAFFS_FAIL);
}

rowAdr = blockNumber << 6;


//NandEnableCE();
WRITE_NAND_COMMAND(CMD_ERASE_1);

WRITE_NAND_ADDRESS((rowAdr >> 0) & 0xFF);
WRITE_NAND_ADDRESS((rowAdr >> 8) & 0xFF);
WRITE_NAND_ADDRESS((rowAdr >> 16) & 0xFF);

WRITE_NAND_COMMAND(CMD_ERASE_2);

NAND_WAIT_READY();
NAND_WAIT_READY();

if (StatusRegIsSet(0))
{
bRet = bFALSE;
}
else
{
bRet = bTRUE;
}

//NandDisableCE();


return (bRet);
}
小陆zi 2012-08-09
  • 打赏
  • 举报
回复
你好 感谢你的回复
是这款 flash。如果可以加我的QQ1813613757 非常感谢!
xgbing 2012-08-09
  • 打赏
  • 举报
回复
uboot中的FLASH驱动是一个通用的驱动,对大多数FLASH都有效,所以代码复杂一些
xgbing 2012-08-09
  • 打赏
  • 举报
回复
是K9K8G08U0A吗?

/* Write specific command, Read from start */
WRITE_NAND_COMMAND(CMD_WRITE_1);

/* Push sector address */
//uSectorAddr >>= pNandInfo->uOffset;

WRITE_NAND_ADDRESS(0);
WRITE_NAND_ADDRESS(0);
WRITE_NAND_ADDRESS((chunkInNAND >> 0) & 0xFF);
WRITE_NAND_ADDRESS((chunkInNAND >> 8) & 0xFF);
WRITE_NAND_ADDRESS((chunkInNAND >> 16) & 0xFF);

//下面是把页数据写入
...
小陆zi 2012-08-09
  • 打赏
  • 举报
回复
顺便 补充一句:
A0 - A11 是col的地址,2K 个 Byte + 64 Byte的寻址。
A12 - A17 是page在block中的偏移量。应为有64个page组成一个block。
A18 - A30 是block的index。K9K8G08的片内一共有8192个block。
这样的寻址方式 在理解上是正确的吗?

谢谢

21,595

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧