📄 nand.c
字号:
/*******************************************************************************
* Copyright: Copyright (c) 2007. Hisilicon Technologies, CO., LTD.
* Version: V300R001B02
* Filename: nand.c
* Description: FMD驱动NANDC子模块功能实现文件
* History:
1.Created by chenbiyao on 2007/04/09
*******************************************************************************/
#include "nand.h"
/*FLASH中断事件*/
HANDLE g_hFlashEvent = (HANDLE)100;
volatile NANDC_REG *g_pstNandcReg = NULL;
BYTE* g_pcDataBuf = NULL;
/*中断状态值*/
DWORD g_dwIntStatus = 0;
/*长数据的位宽*/
DWORD g_dwNandLongAddr = 0;
FLASH_CHIP_STRU g_stFlashChipInfo;
/*******************************************************************************
Function: NF_WRITE_CMD
Description: 本接口用于向指定PORT口写命令字
Input: 1、PORT地址
2、命令字
Output: none
Return: none
History:
1. Created by chenbiyao on 2006/04/09
2. .....
*******************************************************************************/
#define NF_WRITE_CMD(portAddr,cmd); (portAddr)=(cmd);
/*******************************************************************************
Function: NF_GetMutex
Description: 本接口用于获得信号量操作
Input: 句柄
Output: none
Return: FMD_SUCCESS:操作成功;
其他:操作不成功;
History:
1. Created by chenbiyao on 2006/04/09
2. .....
*******************************************************************************/
static DWORD NF_GetMutex(HANDLE hHandle)
{
UINT32 dwTick;
dwTick = GetSysTimer();
while(0 == (g_pstNandcReg->NANDC_INTSTATUS & g_pstNandcReg->NANDC_INTEN))
{
if(GetPassedMicSec(dwTick) > 2 ms)
{
break;
}
}
g_dwIntStatus = g_pstNandcReg->NANDC_INTSTATUS;
/*清除相应的中断位;*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_INTCLR,g_dwIntStatus);
return FMD_SUCCESS;
}
/*******************************************************************************
Function: NF_ReleaseMutex
Description: 本接口用于释放信号量操作
Input: 信号量句柄
Output: none
Return: none
History:
1. Created by chenbiyao on 2006/04/09
2. .....
*******************************************************************************/
static VOID NF_ReleaseMutex(HANDLE hMutex)
{
}
/*******************************************************************************
Function: NF_CreateMutex
Description: 本接口用于创建信号量
Input: none
Output: 信号量句柄
Return: none
History:
1. Created by chenbiyao on 2006/04/09
2. .....
*******************************************************************************/
static VOID NF_CreateMutex(PHANDLE pHandle)
{
*pHandle = (HANDLE)1;/*区别两个HANDLE*/
}
/*******************************************************************************
Function: NF_Init
Description: 本接口用于初始化NANDC控制寄存器,创建FLASH操作信号量和FLASH事件,启动中断处理任务
Input: none
Output: none
Return: FMD_SUCCESS:操作成功;
其他:操作不成功;
History:
1. Created by chenbiyao on 2006/04/09
2. .....
*******************************************************************************/
DWORD NF_Init(DWORD *pdwFlashID)
{
DWORD ret = 0;
/*对寄存器基地址与数据缓冲区首地址进行地址映射*/
if(NULL == g_pcDataBuf)
{
#ifdef RUN_IN_WINDOWS_MOBILE
g_pcDataBuf = (PBYTE)OALPAtoVA(g_stFlashChipInfo.dwNandcBaseAddr, FALSE);
if(NULL == g_pcDataBuf)
{
return NF_MEMMAP_ERROR;
}
#else
g_pcDataBuf = (PBYTE)g_stFlashChipInfo.dwNandcBaseAddr;
#endif
g_pstNandcReg = (PNANDC_REG)((DWORD)g_pcDataBuf + NANDC_REG_ADDR);
}
/*初始化等待控制寄存器*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_WSC, NANDC_WSC_CONFIG);
/*初始化器件配置寄存器(BYTE_PER_PAGE_2K|IO_WIDTH_8_BIT);*/
#ifndef HARDWARE_READY
{
NF_WRITE_CMD(g_pstNandcReg->NANDC_DEVICECFG, BYTE_PER_PAGE_2K|IO_WIDTH_8_BIT);
}
#endif
/*去使能flashlock*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_LOCKEN, 0xFFFFFFFC);
/*调用NF_ReadID读取FLASH的ID号;*/
ret = NF_ReadID(pdwFlashID);
if(FMD_SUCCESS != ret)
{
return ret;
}
if(K5E2G1GACM == *pdwFlashID)
{
g_stFlashChipInfo.TotalBlockNumbers = (DWORD)BLOCKS_NUM_2048;
g_stFlashChipInfo.dwAddrShift = 0;
g_stFlashChipInfo.dwStatusBits = 1;
}
else if(MT29F2G16ABD == *pdwFlashID)
{
g_stFlashChipInfo.TotalBlockNumbers = (DWORD)BLOCKS_NUM_2048;
g_stFlashChipInfo.dwAddrShift = 1;
g_stFlashChipInfo.dwStatusBits = 2;
NF_WRITE_CMD(g_pstNandcReg->NANDC_DEVICECFG, BYTE_PER_PAGE_2K|IO_WIDTH_16_BIT);
}
else
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR NANDFMD] can not support this flash ID = 0x%x.\r\n"), *pdwFlashID));
return NF_NOT_SUPP_ERROR;
}
if(g_stFlashChipInfo.TotalBlockNumbers*g_stFlashChipInfo.BlockSize < FLASHSIZE_2GBIT)
{
g_dwNandLongAddr = NF_ADDR_4BITS;
}
else
{
g_dwNandLongAddr = NF_ADDR_5BITS;
}
OALMSG(ZONE_FMD_OPS, (TEXT("[Info NANDFMD] FLASH ID = 0x%x.\r\n"), *pdwFlashID));
return FMD_SUCCESS;
}
/*******************************************************************************
Function: NF_Init
Description: 本接口用于释放NANDC控制器工作所需的资源
Input: none
Output: none
Return: none
History:
1. Created by chenbiyao on 2006/04/09
2. .....
*******************************************************************************/
VOID NF_Deinit(VOID)
{
/*unmap地址*/
//MmUnmapIoSpace(g_pcDataBuf, NF_DATA_BUFFER_LENGTH);//??
g_pcDataBuf = NULL;
g_pstNandcReg = NULL;
}
/*******************************************************************************
Function: NF_ReadID
Description: 本接口用于读取NAND FLASH的ID信息
Input: none
Output: ID号;
Return: FMD_SUCCESS:操作成功;
其他:操作不成功;
History:
1. Created by chenbiyao on 2006/04/09
2. .....
*******************************************************************************/
DWORD NF_ReadID(PDWORD pIDBuf)
{
DWORD ret = 0;
WORD cStatus = 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|NF_ADD_CYC_1BIT);
/*配置数据读写数目寄存器(5个字节);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_DATANUM, NF_ID_LENGTH);
/*配置中断使能寄存器(读中断);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_INTEN, READ_DONE_INT_BIT);
NF_WRITE_CMD(g_pstNandcReg->NANDC_ADDRL, 0);
NF_WRITE_CMD(g_pstNandcReg->NANDC_ADDRH, 0);
/*向命令寄存器写入读取ID信息命令(NF_CMD_IDREAD);*/
NF_WRITE_CMD(g_pstNandcReg->NANDC_CMD, NF_CMD_IDREAD);
/*调用NF_GetMutex获取FLASH事件(FLASH_EVENT);*/
NF_GetMutex(g_hFlashEvent);
if(0 == (g_dwIntStatus & NF_READ_DONE)) /*判断中断标志位*/
{
/*调用NF_ReleaseMutex释放FLASH访问信号量(FLASH_CHIP_MUTEX);*/
OALMSG(ZONE_FMD_ERR ,(TEXT("[NANDFMD:NF_ReadID]NF_ReadID Error!g_dwIntStatus = 0x%x\n"), g_dwIntStatus));
return NF_READ_INT_MISS;
}
/*从数据映射区读取ID号输出;*/
memcpy(pIDBuf, (PVOID)(g_pcDataBuf+1), (NF_ID_LENGTH-1));
/*调用NF_ReadStatus读取状态;*/
ret = NF_ReadStatus(&cStatus);
if(FMD_SUCCESS != ret)
{
/*调用NF_ReleaseMutex释放FLASH访问信号量(FLASH_CHIP_MUTEX);*/
return ret;
}
/*调用NF_ReleaseMutex释放FLASH访问信号量(FLASH_CHIP_MUTEX);*/
return FMD_SUCCESS;
}
/*******************************************************************************
Function: NF_PageRead
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -