📄 nand.c
字号:
Description: 本接口用于读取指定一页中指定长度内容到缓冲区
Input: 1、读取数据地址
2、数据缓冲区指针
3、读取数据长度
Output: 读取的数据
Return: FMD_SUCCESS:操作成功;
其他:操作不成功;
History:
1. Created by chenbiyao on 2006/04/09
2. .....
*******************************************************************************/
DWORD NF_PageRead(DWORD startAddr, PBYTE pDataBuff, DWORD dwLength)
{
DWORD dwAddrL = 0;
DWORD dwAddrH = 0;
/*参数判断(此处没有对列地址进行判断)*/
if((startAddr >= (g_stFlashChipInfo.TotalBlockNumbers*g_stFlashChipInfo.SectorsPerBlock*NF_SECTOR_ADDR_SHIFT))||
(NULL == pDataBuff)||((((startAddr&0xFFF)>>g_stFlashChipInfo.dwAddrShift) + dwLength) > (g_stFlashChipInfo.SectorSize + g_stFlashChipInfo.SpareSize))||
(dwLength < 1))
{
return NF_PARAMETER_ERROR;
}
/*使能ECC Check和ECC Correct,禁止LSD的ECC Check,工作于NORMAL模式*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_BUFCFG, NORMAL_MODE|ECC_DATA_CHECK_ENABLE|ECC_LSN_CHECK_DISABLE|ECC_CORRECT_ENABLE);
/*清除所有中断位;*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_INTCLR,0xFFFFFFFF);
/*根据输入块地址写地址寄存器(超过两G的器件需要使用高位地址寄存器)*/
dwAddrL = ((startAddr&0xFFF)>>g_stFlashChipInfo.dwAddrShift) + ((startAddr&0xFFFF000)<<LOW_ADDR_SHIFT_BITS);
dwAddrH = (startAddr&0xF0000000)>>HIGH_ADDR_SHIFT_BITS;
NF_WRITE_CMD(g_pstNandcReg->NANDC_ADDRL, dwAddrL);
NF_WRITE_CMD(g_pstNandcReg->NANDC_ADDRH, dwAddrH);
/*向命令配置寄存器写入当前命令格式(命令+地址+命令);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_CMDCFG, g_dwNandLongAddr|NF_TWO_CMD|NF_STATE_RUN|NF_READ_MODE);
/*根据读取数据长度配置数据读写数目寄存器;*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_DATANUM, dwLength);
/*配置中断使能寄存器(读中断、ECC Check、ECCCORRECT);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_INTEN, READ_DONE_INT_BIT|DATA_ECC_2BIT_ERROR_INT_BIT);
/*向命令寄存器写入页读取命令(NF_CMD_READPAGE);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_CMD, NF_CMD_READPAGE);
/*调用NF_GetMutex获取FLASH事件(FLASH_EVENT);*/
NF_GetMutex(g_hFlashEvent);
/*出现ECC纠正错误,该块是个坏块*/
if(0 != (g_dwIntStatus & DATA_ECC_2BIT_ERROR_INT_BIT)) /*判断中断标志位*/
{
return NF_ECC_CORRECT_ERROR;
}
else if(0 != (g_dwIntStatus & LSN_ECC_2BIT_ERROR_INT_BIT)) /*判断中断标志位*/
{
return NF_LSN_ECC_CORRECT_ERROR;
}
/*不是读完成中断,报错*/
else if(0 == (g_dwIntStatus & READ_DONE_INT_BIT)) /*判断中断标志位*/
{
OALMSG(ZONE_FMD_ERR ,(TEXT("[NANDFMD:NF_PageRead]NF_PageRead Error!g_dwIntStatus = 0x%x\n"), g_dwIntStatus));
return NF_READ_INT_MISS;
}
/*从数据映射区中读取指定长度的数据;*/
memcpy(pDataBuff, (PVOID)g_pcDataBuf, dwLength);
return FMD_SUCCESS;
}
/*******************************************************************************
Function: NF_PageProgram
Description: 本接口用于把数据写入指定的FLASH地址
Input: 1、写入的地址
2、待写入的数据缓冲区指针
3、待写入的数据长度
Output: none
Return: FMD_SUCCESS:操作成功;
其他:操作不成功;
History:
1. Created by chenbiyao on 2006/04/09
2. .....
*******************************************************************************/
DWORD NF_PageProgram(DWORD startAddr,CONST BYTE * pDataBuff, DWORD dwLength)
{
DWORD ret = 0;
WORD cStatus = 0;
DWORD dwAddrL = 0;
DWORD dwAddrH = 0;
/*参数判断不合法*/
if((startAddr >= (g_stFlashChipInfo.TotalBlockNumbers*g_stFlashChipInfo.SectorsPerBlock*NF_SECTOR_ADDR_SHIFT))||
(NULL == pDataBuff)||((((startAddr&0xFFF)>>g_stFlashChipInfo.dwAddrShift) + dwLength) > (g_stFlashChipInfo.SectorSize + g_stFlashChipInfo.SpareSize))||
(dwLength < 1))
{
return NF_PARAMETER_ERROR;
}
/*使能ECC Check和ECC Correct,禁止LSD的ECC Check,工作于NORMAL模式*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_BUFCFG, NORMAL_MODE|ECC_DATA_CHECK_ENABLE|ECC_LSN_CHECK_DISABLE|ECC_CORRECT_ENABLE);
/*清除所有中断位;*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_INTCLR,0xFFFFFFFF);
/*根据输入块地址写地址寄存器(超过两G的器件需要使用高位地址寄存器)*/
dwAddrL = ((startAddr&0xFFF)>>g_stFlashChipInfo.dwAddrShift) + ((startAddr&0xFFFF000)<<LOW_ADDR_SHIFT_BITS);
dwAddrH = (startAddr&0xF0000000)>>HIGH_ADDR_SHIFT_BITS;
NF_WRITE_CMD(g_pstNandcReg->NANDC_ADDRL, dwAddrL);
NF_WRITE_CMD(g_pstNandcReg->NANDC_ADDRH, dwAddrH);
/*把要写入的数据写到数据缓冲区;*/
memcpy((PVOID)g_pcDataBuf, pDataBuff, dwLength);
/*根据写入数据长度配置数据读写数目寄存器;*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_DATANUM, dwLength);
/*配置中断使能寄存器(写中断);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_INTEN, WRITE_DONE_INT_BIT);
/*向命令配置寄存器写入当前命令格式(命令+地址);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_CMDCFG, g_dwNandLongAddr|NF_SINGLE_CMD|NF_STATE_RUN|NF_WRITE_MODE);
/*向命令寄存器写入页编程开始命令(NF_CMD_PAGEPROG_FIRST);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_CMD, NF_CMD_PAGEPROG_FIRST);
/*调用NF_GetMutex获取FLASH事件(FLASH_EVENT);*/
NF_GetMutex(g_hFlashEvent);
if(0 == (g_dwIntStatus & WRITE_DONE_INT_BIT)) /*判断中断标志位*/
{
OALMSG(ZONE_FMD_ERR ,(TEXT("[NANDFMD:NF_PageProgram]NF_PageProgram Error!g_dwIntStatus = 0x%x\n"), g_dwIntStatus));
return NF_WRITE_INT_MISS;
}
/*配置中断使能寄存器(写中断);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_INTEN, CMD_SEND_INT_BIT);
/*向命令配置寄存器写入当前命令格式(命令);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_CMDCFG, NF_SINGLE_CMD|NF_STATE_STOP|NF_WRITE_MODE);
/*向命令寄存器写入页编程结束命令(NF_CMD_PAGEPROG_SECOND);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_CMD, NF_CMD_PAGEPROG_SECOND);
/*调用NF_GetMutex获取FLASH事件(FLASH_EVENT);*/
NF_GetMutex(g_hFlashEvent);
if(0 == (g_dwIntStatus & CMD_SEND_INT_BIT)) /*判断中断标志位*/
{
OALMSG(ZONE_FMD_ERR ,(TEXT("[NANDFMD:NF_PageProgram]NF_PageProgram Error!g_dwIntStatus = 0x%x\n"), g_dwIntStatus));
return NF_WRITE_INT_MISS;
}
/*调用NF_ReadStatus读取状态;*/
ret = NF_ReadStatus(&cStatus);
if (FMD_SUCCESS == ret)/*NF_ReadStatus读取成功*/
{
if(0 == (cStatus & NF_PROGRAM_SUCCESS))
{
ret = FMD_SUCCESS;
}
else
{
ret = NF_PAGEPROGRAM_ERROR;
}
}
return ret;
}
/*******************************************************************************
Function: NF_BlockErase
Description: 本接口用于擦除指定块的内容
Input: 待擦除块地址
Output: none
Return: FMD_SUCCESS:操作成功;
其他:操作不成功;
History:
1. Created by chenbiyao on 2006/04/09
2. .....
*******************************************************************************/
DWORD NF_BlockErase(BLOCK_ID blockID)
{
DWORD ret = 0;
WORD cStatus = 0;
/*参数判断不合法*/
if(blockID >= g_stFlashChipInfo.TotalBlockNumbers)
{
return NF_PARAMETER_ERROR;
}
/*根据输入块地址写地址寄存器*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_ADDRL, blockID*g_stFlashChipInfo.SectorsPerBlock);
/*配置中断使能寄存器(CMD_SEND_INT_BIT);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_INTEN, CMD_SEND_INT_BIT);
/*向命令配置寄存器写入当前命令格式(命令+地址+命令);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_CMDCFG, NF_STATE_STOP|NF_ADD_CYC_3BIT|NF_TWO_CMD);
/*向命令寄存器写入块擦除命令(NF_CMD_BLOCKERASE);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_CMD, NF_CMD_BLOCKERASE);
/*调用NF_GetMutex获取FLASH事件(FLASH_EVENT);*/
NF_GetMutex(g_hFlashEvent);
do
{
/*调用NF_ReadStatus读取状态;*/
ret = NF_ReadStatus(&cStatus);
if(FMD_SUCCESS != ret)
{
return ret;
}
}
while(0 == (cStatus & NF_STATUS_READY));
if(0 == (cStatus & NF_ERASE_SUCCESS))
{
ret = FMD_SUCCESS;
}
else
{
ret = NF_BLOCKERASE_ERROR;
}
return ret;
}
/*******************************************************************************
Function: NF_ReadStatus
Description: 本接口用于读取操作状态
Input: 待擦除块地址
Output: 状态
Return: FMD_SUCCESS:操作成功;
其他:操作不成功;
History:
1. Created by chenbiyao on 2006/04/09
2. .....
*******************************************************************************/
DWORD NF_ReadStatus(PWORD pStatus)
{
BYTE status = 0;
/*禁止ECC Check和ECC Correct,禁止LSD的ECC Check,工作于NORMAL模式*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_BUFCFG, NORMAL_MODE|ECC_DATA_CHECK_DISABLE|ECC_LSN_CHECK_DISABLE|ECC_CORRECT_DISABLE);
/*清除所有中断位;*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_INTCLR,0xFFFFFFFF);
/*向命令配置寄存器写入当前命令格式(单命令);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_CMDCFG, NF_SINGLE_CMD|NF_STATE_RUN|NF_READ_MODE);
/*配置数据读写数目寄存器为1;*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_DATANUM, g_stFlashChipInfo.dwStatusBits);
/*配置中断使能寄存器(读中断);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_INTEN, READ_DONE_INT_BIT);
/*向命令寄存器写入读取状态命令(NF_CMD_STATUSREAD);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_CMD, NF_CMD_STATUSREAD);
/*调用NF_GetMutex获取FLASH事件(FLASH_EVENT);*/
NF_GetMutex(g_hFlashEvent);
if(0 == (g_dwIntStatus & READ_DONE_INT_BIT)) /*判断中断标志位*/
{
OALMSG(ZONE_FMD_ERR ,(TEXT("[NANDFMD:NF_ReadStatus]NF_ReadStatus Error!g_dwIntStatus = 0x%x\n"), g_dwIntStatus));
return NF_READ_INT_MISS;
}
/*从缓冲区中输出状态值;*/
if(1 != g_stFlashChipInfo.dwStatusBits)
{
memcpy(pStatus, (PVOID)g_pcDataBuf, g_stFlashChipInfo.dwStatusBits);
}
else
{
memcpy(&status, (PVOID)g_pcDataBuf, g_stFlashChipInfo.dwStatusBits);
*pStatus = status;
}
return FMD_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -