📄 nf_drv.c
字号:
/*C**************************************************************************
* NAME: nf_drv.c
*----------------------------------------------------------------------------
* Copyright (c)
*----------------------------------------------------------------------------
* RELEASE:
* REVISION:
*----------------------------------------------------------------------------
* PURPOSE:
* This file contains the NF driver definitions
*****************************************************************************/
#include "typedef.h"
#include "16c554.h"
#include "nf_drv.h"
#include <intrins.h>
#define SIZEBYTE_PERLINE 20 /*bit size per bus line*/
#define SIZEPAGE_PERLINE 4096
#define SIZEBLOCK_PERLINE 6
extern Uchar volatile xdata D12_Y0;//原来的xCONTROLBYTE8K
extern idata Uchar D17CS;//D12_Y0的寄存器,原来的xConByte8KValue
extern Uchar volatile xdata D12_Y3;//原来的xFLASHCS
extern Uchar volatile xdata D12_Y2;//原来的xCONTROLBYTE82
unsigned long volatile xdata xCurErasedBlock;//Uint32 xdata xCurErasedBlock;
volatile Byte xEraseStatus;//Byte xdata xEraseStatus;
volatile bit halfpage;
#if (NF_CAPACITY_AUTO_DETECT == TRUE) /* If autodetect capacity nand flash is active */
Byte nf_zone_max; //xdata Byte nf_zone_max; /* nf_zone_max definition */
Byte nf_device_type;//xdata Byte nf_device_type; /* nf_device_type definition */
bdata bit nf_4_cycle_address; /* nf_4_cycle_address definition */
#endif
/*_____ M A C R O S ________________________________________________________*/
#ifndef NF_CAPACITY_AUTO_DETECT
#error NF_CAPACITY_AUTO_DETECT must be defined in board.h
#endif
void Test_nf_send_command(Byte command)
{
D17CS &= 0xdf;
D12_Y0 = D17CS;//ALE=0;
D17CS |= 0x10;
D12_Y0 = D17CS;//CLE=1;
D12_Y3 = command;
D17CS &= 0xcf;
D12_Y0 = D17CS;//ALE=0=CLE
}
void Test_nf_send_address(Byte address)
{
D17CS |= 0x20;
D12_Y0 = D17CS;//ALE=1
D12_Y3 = address;
D17CS &= 0xcf;
D12_Y0 = D17CS;//ALE=0=CLE
}
void Test_nf_write_open_B_area(Uint32 nRow, Byte nCol)
{
Test_nf_send_command(NF_READ_B_AREA_CMD);
Test_nf_send_command(NF_SEQUENTIAL_DATA_INPUT_CMD);
Test_nf_send_address(nCol);
Test_nf_send_address(((Byte*)&nRow)[3]);
Test_nf_send_address(((Byte*)&nRow)[2]);
}
void Test_nf_write_open_A_area(Uint32 nRow, Byte nCol)
{
Test_nf_send_command(NF_READ_A_AREA_CMD);
Test_nf_send_command(NF_SEQUENTIAL_DATA_INPUT_CMD);
Test_nf_send_address(nCol);
Test_nf_send_address(((Byte*)&nRow)[3]);
Test_nf_send_address(((Byte*)&nRow)[2]);
}
void Test_nf_write_open_C_area(Uint32 nRow, Byte nCol)
{
Test_nf_send_command(NF_READ_C_AREA_CMD);
Test_nf_send_command(NF_SEQUENTIAL_DATA_INPUT_CMD);
Test_nf_send_address(nCol);
Test_nf_send_address(((Byte*)&nRow)[3]);
Test_nf_send_address(((Byte*)&nRow)[2]);
}
void Test_nf_read_open_A_area(Uint32 nRow, Byte nCol)
{
Test_nf_send_command(NF_READ_A_AREA_CMD);
Test_nf_send_address(nCol);
Test_nf_send_address(((Byte*)&nRow)[3]);
Test_nf_send_address(((Byte*)&nRow)[2]);
Nf_wait_busy();
}
void Test_nf_read_open_B_area(Uint32 nRow, Byte nCol)
{
Test_nf_send_command(NF_READ_B_AREA_CMD);
Test_nf_send_address(nCol);
Test_nf_send_address(((Byte*)&nRow)[3]);
Test_nf_send_address(((Byte*)&nRow)[2]);
Nf_wait_busy();
}
void Test_nf_read_open_C_area(Uint32 nRow, Byte nCol)
{
Test_nf_send_command(NF_READ_C_AREA_CMD);
Test_nf_send_address(nCol);
Test_nf_send_address(((Byte*)&nRow)[3]);
Test_nf_send_address(((Byte*)&nRow)[2]);
Nf_wait_busy();
}
#define Test_nf_rd_byte(buf) ((buf) = D12_Y3)
#define Test_nf_wr_byte(buf) (D12_Y3 = (buf))
void nf_wp_on()
{
D17CS &= 0xbf;
D12_Y0 = D17CS;
}
void nf_wp_off()
{
D17CS |= 0x40;
D12_Y0 = D17CS;
}
/*******************************************
nlinenum: 值从0开始
*********************************************/
bit nf_check_linevalid(Uint8 nlinenum/*in*/)
{
Byte value1, value2;
Uint32 nAddr;
nAddr = nlinenum*SIZEPAGE_PERLINE;
Nf_wait_busy();
Test_nf_read_open_A_area(nAddr, 0x00);
Nf_wait_busy();
Test_nf_rd_byte(value1);
Test_nf_rd_byte(value2);
if ((0x55 == value1) && (0xaa == value2))
return OK;
else
return KO;
}
/*F**************************************************************************
* NAME: nf_check_status
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* NF status
*----------------------------------------------------------------------------
* PURPOSE:
* Check the status of the device after a program or an erase operation
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
* ram/xram:
* cycle:
* stack:
* code:
*****************************************************************************/
bit nf_check_status (void)
{
Uint8 status;
Nf_wait_busy();
Test_nf_send_command(NF_READ_STATUS_CMD);
Test_nf_rd_byte(status);
if (0x00 == (status & 0x01))
{
return OK;
}
else
{
return KO;
}
}
/*F**************************************************************************
* NAME: nf_block_erase
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* OK : erase done
* KO : erase not done
*----------------------------------------------------------------------------
* PURPOSE: Erase a block on Nand Flash Media
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* This function use the global variable Uint32 address
*----------------------------------------------------------------------------
* REQUIREMENTS:
* ram/xram:
* cycle:
* stack:
* code:
*****************************************************************************/
bit nf_block_erase (Uint32 pos)
{
Nf_wait_busy();
Test_nf_send_command(NF_READ_A_AREA_CMD);
Test_nf_send_command(NF_BLOCK_ERASE_CMD);
Test_nf_send_address(((Byte*)&pos)[2]);//[3]);
Test_nf_send_address(((Byte*)&pos)[1]);//[2]);
Test_nf_send_command(NF_BLOCK_ERASE_CONFIRM_CMD);
nf_check_status();
return OK;
}
/*F**************************************************************************
* NAME: nf_write_onepage
*----------------------------------------------------------------------------
* PARAMS:
* pos: the page number ,the start num is 0;//the start row address
* pbuf: the content to write, whose size is 512 bytes
* return:
* OK : write done
* KO : write not done
*----------------------------------------------------------------------------
* PURPOSE: write one on Nand Flash Media. It is only permitted to write 512 Bytes
* when writting on flash(our assume).
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* This function use the global variable Uint32 address
*----------------------------------------------------------------------------
* REQUIREMENTS:
* ram/xram:
* cycle:
* stack:
* code:
*****************************************************************************/
/*bit nf_write_onepage(Uint32 pos, Byte* pBuf)
{
Uint8 status = 0;
data Uint16 nTmp;
nTmp = pos >> 5;
if ((FALSE == xEraseStatus) || (xCurErasedBlock != nTmp))
{
nf_block_erase(pos<<8);
nf_check_status();
xEraseStatus = TRUE;
xCurErasedBlock = nTmp;
}
Nf_wait_busy();
Test_nf_write_open_A_area(pos, 0);
for (nTmp=0; nTmp<512; nTmp++)
Nf_wr_byte(pBuf[nTmp]);
Nf_wait_busy();
Test_nf_send_command(NF_PAGE_PROGRAM_CMD);
Nf_wait_busy();
return OK;
}*/
/************************************
*pos:值为页地址,而非实际地址!!!!!
************************************/
bit nf_write_onepage2(Uint32 pos, Byte* pBuf1, Byte* pBuf2, Byte* pBuf3, Byte* pBuf4)
{
/*first check to see whether to erase block*/
Uint8 status = 0;
data Uint32 nTmp;
data Uint8 tmpCount;
nTmp = pos >> 5;/*row address*/
if ((FALSE == xEraseStatus) || (xCurErasedBlock != nTmp))
{
nf_block_erase(pos<<8);
/*debug: test R/B*/
nf_check_status();
xEraseStatus = TRUE;
xCurErasedBlock = nTmp;
}
/*write routine*/
Nf_wait_busy();
Test_nf_write_open_A_area(pos, 0);
for (tmpCount=0; tmpCount<128; tmpCount++)
D12_Y3 = pBuf1[tmpCount];
for (tmpCount=0; tmpCount<128; tmpCount++)
D12_Y3 = pBuf2[tmpCount];
for (tmpCount=0; tmpCount<128; tmpCount++)
D12_Y3 = pBuf3[tmpCount];
for (tmpCount=0; tmpCount<128; tmpCount++)
D12_Y3 = pBuf4[tmpCount];
//需要等待
// delay();//不需要等待,06.04.11日测试的结果
Nf_wait_busy();
Test_nf_send_command(NF_PAGE_PROGRAM_CMD);
Nf_wait_busy();
return OK;
}
/********************************************
*写任意长度到flash中,这里要求一次不能跨越两页
*一旦跨越两页,由外部处理函数处理
*pos:为需要写的实际地址,包括行地址和列地址
*********************************************/
bit nf_write_onebuf(Uint32 pos, Byte* pBuf, Uint16 nLen)
{
/*first check to see whether to erase block*/
Uint8 status = 0;
// data Uint32 nTmp;
data Uint16 tmpCount;
// Uint8 c;
// Nf_CS_ON();
// nTmp = pos >> (5+9);/*row address*/
if((pos&0x00003fff)==0)
{
nf_block_erase(pos>>1);//nTmp<<(5+8));
nf_check_status();
}
/*
if ((FALSE == xEraseStatus) || (xCurErasedBlock != nTmp))
{
nf_block_erase(pos>>1);//nTmp<<(5+8));
c=(unsigned char)(pos>>9);
siob_send(&c,1);
c=(unsigned char)(pos>>17);
siob_send(&c,1);
nf_check_status();
xEraseStatus = TRUE;
xCurErasedBlock = nTmp;
}
*/
/*write routine*/
Nf_wait_busy();
if (0 == (pos & 0x00000100))
{
Test_nf_write_open_A_area(pos>>9, (Byte)pos);
}
else
{
Test_nf_write_open_B_area(pos>>9, (Byte)pos);
}
for (tmpCount=0; tmpCount<nLen; tmpCount++)
D12_Y3 = pBuf[tmpCount];
Nf_wait_busy();
Test_nf_send_command(NF_PAGE_PROGRAM_CMD);
Nf_wait_busy();
return OK;
}
/********************************************
*调用该函数前,需要由调用者自己调用擦除函数
*写任意长度到flash中,这里要求一次不能跨越两页
*一旦跨越两页,由外部处理函数处理
*pos:为需要写的实际地址,包括行地址和列地址
*********************************************/
bit nf_write_onebuf_withouterase(Uint32 pos, Byte* pBuf, Uint8 nLen)
{
/*first check to see whether to erase block*/
Uint8 status = 0;
data Uint8 tmpCount;
Nf_wait_busy();
if (0 == (pos & 0x00000100))
{
Test_nf_write_open_A_area(pos>>9, (Byte)pos);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -