⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nand.c

📁 windows mobile 6.13 dnldr下载源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  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 + -