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

📄 k9f2808.c

📁 基于ARM7的直流电机的驱动,还有FLASH驱动,LCD驱动等
💻 C
字号:
/*
 *	DESC:	K9F2808 NAND FLASH test program.
 *
 *	AUTHOR:	余康华
 *
 *	DATE:	2005-11-8 22:44
 *
 *	Copyright (C) 2005 Hui Yuan Electronic Corp. Ltd.
 *
 *	Historys
 *	2005-11-8 22:45  ..............	LCD 测试完成!
 *	2005-11-10 11:39 .............. 内存分配测试完成!
 *
 *
 *	/WP	 --- 3.3V
 *	ALE  --- ADDR2
 *	CLE  --- ADDR1
 *	/CE  --- GPC9
 *	RDY/B--- GPC8
 */
#include <string.h>
#include <stdio.h>
#include "Defs.h"
#include "44b0x.h"

//   读操作:任意大小
//   写操作:扇区大小(512字节)
// 擦除操作:快大小(16k字节)
#define	BSZ				0x4000//16K
#define	BMSK				0x3FFF
#define	NC				10


// 实践证明对于快速CPU访问NAND FLASH,用下面的函数实现比宏定义实现要更可靠。
//
/*
#define	NfReadData()		*(volatile UCHAR *)0x02000000
#define	NfWriteCmd(cmd)		*(volatile UCHAR *)0x02000002= cmd
#define	NfWriteAddr(addr)	*(volatile UCHAR *)0x02000004= addr
#define	NfWriteData(dat)	*(volatile UCHAR *)0x02000000= dat
#define	NfChipEnable()		rPDATC &= ~0x200;
#define	NfChipDisable()		rPDATC |= 0x200
*/

// 数据读入
static UCHAR
NfReadData(void) {
	return *(volatile UCHAR *)NAND_DAT;
}

// 写入数据
static void
NfWriteData(UCHAR dat) {
	*(volatile UCHAR *)NAND_DAT = dat;
}

// 写入地址字段
static void
NfWriteAddr(UCHAR adr) {
	*(volatile UCHAR *)NAND_ALE = adr;
}

// 命令写入
static void
NfWriteCmd(UCHAR cmd) {
	*(volatile UCHAR *)NAND_CLE = cmd;
}

// 芯片使能
static void
NfChipEnable(void) {
	rPDATC &= ~0x200;
}

// 芯片片选无效
static void
NfChipDisable(void) {
	rPDATC |= 0x200;
}

#if 1
#define	PSW	int psw;
#define DISABLE	psw = interrupts_disable()
#define ENABLE	interrupts_enable(psw)
#else
#define PSW
#define DISABLE
#define ENABLE
#endif


void	udelay(UINT us);

//
// 等待FLASH就绪
//
static void
NfWait(void) {
	
	while(1) {
		if(rPDATC & 0x100)
			break;
	}
}

//
// 读FLASH操作状态
//

static UCHAR
NfReadStatus(void) {
	UCHAR	st;
	
	while(1) {
		NfWriteCmd(0x70);
		st = NfReadData();
		if(st & 0x40)
			break;
	}
	return st;
}

//
// 读出芯片ID标识
//
static ULONG
NfReadId(void) {
	ULONG	t;
	PSW;
	
	DISABLE;
	
	NfChipEnable();
	NfWriteCmd(0x90);
	NfWriteAddr(0);
	NfWait();

	t = NfReadData() << 8;
	t |= NfReadData();
	NfChipDisable();
	
	ENABLE;

	return t;
}

/*
//
//	Get bad block info
//
//	OK!

static UCHAR
NfAnyBadBlock(ULONG offst) {
	UCHAR	t;
	UCHAR	cc;
	PSW;
	
	DISABLE;
	
	cc = rSYSCFG;
	rSYSCFG = 1 << 3;

	NfChipEnable();
	NfWriteCmd(0x50);	// point to area C
	NfWriteAddr(5);
	NfWriteAddr(offst >> 9);
	NfWriteAddr(offst >> 17);
	
	NfWait();
	t = NfReadData();
	NfWriteCmd(0x0);	// point to area A
	NfChipDisable();
	
	rSYSCFG = cc;
	
	ENABLE;
	return t;
}
*/

//
// 擦除若干块(每块32扇区)
//
// offst: 块首地址
// nr: 块数

ULONG
__NfErase(ULONG offst, ULONG nr) {
	ULONG	st;
	PSW;
	
	st = 0;
	
	//DbgOut("Erase Page %u...\n", offst);
	
	DISABLE;
	
	NfChipEnable();
	while(nr-- != 0) {
		// 擦除扇区.
		NfWriteCmd(0x60);
		NfWriteAddr(offst >> 9);	// Block Addr.: A9 ~ A23//row address page address,页地址实现了块跨越
		NfWriteAddr(offst >> 17);	// Only A14 - A23 is vaild//具体到快积存器
		NfWriteCmd(0xd0);
		
		st |= NfReadStatus();
		offst += BSZ;//16K
	}
	NfChipDisable();
	
	ENABLE;
	
	return st;
}

//
// 读出若干扇区
//
// pgaddr: 扇区号。首地址
// buf: 数据存储位置
// nr: 扇区数
//

//COLUMN ADDRESS   
//ROW  ADDRESS
//达到对区的定位,具体化某扇区,起始单元

//ROW  ADDRESS PAGE ADDRESS 
//   512
//达到对块的定位

static void
__NfRead(ULONG pgaddr, UCHAR *buf, ULONG nr) {
	ULONG	i;
	PSW;

	while(nr-- != 0) {
		
		DISABLE;
		
		// 读入A区
		NfChipEnable();
		NfWriteCmd(0x0);
		NfWriteAddr(0);//COLUMN ADDRESS
		NfWriteAddr(pgaddr);
		NfWriteAddr(pgaddr >> 8);//ROW  ADDRESS
		//I/O 0`7 三次写入。
		NfWait();
		
		for(i = 0; i < 256; i++)
			*buf++ = NfReadData();
		
		// 读入B区
		NfWriteCmd(0x01);
		NfWriteAddr(0);
		NfWriteAddr(pgaddr);
		NfWriteAddr(pgaddr >> 8);
		
		NfWait();
		
		for(; i < 512; i++)
			*buf++ = NfReadData();
		NfChipDisable();
		
		ENABLE;
		
		pgaddr++;
	}
}

//
// 读FLASH
//
// offst: FLASH位置
// buf: 数据指针
// sz: 待读入数据长度
void
NfRead(ULONG offst, void *buf, ULONG sz) {
	ULONG	bsz;
	static UCHAR	tbuf[512];

	while(sz != 0) {
		// 扇区对齐
		__NfRead(offst >> 9, tbuf, 1);
		bsz = 512;
		if(offst & 511)//不满511
			bsz -= offst & 511;//操作的大小为OFFSET大小
		if(bsz > sz)
			bsz = sz;//不能 大于SZ
		memcpy(buf, tbuf + (offst & 511), bsz);
		offst += bsz;
		buf = (char *)buf + bsz;
		sz -= bsz;
	}
}

//
// 写入若干扇区
//
// pgaddr: 块首地址
// buf: 数据存储位置
// nr: 块数

void
__NfWrite(ULONG pgaddr, void *buf, ULONG nr) {
	ULONG	i;
	UCHAR	*bp = (UCHAR *)buf;
	UCHAR	cc;
	PSW;

	CHECK_PTR(buf);

	NfChipEnable();
	while(nr-- != 0) {
		
		DISABLE;
		
		// 关闭CACHE
		cc = rSYSCFG;
		rSYSCFG = 1 << 3;

		// 写入整个扇区
		NfWriteCmd(0x80);		// Prg0
		NfWriteAddr(0);
		NfWriteAddr(pgaddr);
		NfWriteAddr(pgaddr >> 8);
		for(i = 0; i < 512; i++)
			NfWriteData(bp[i]);

		NfWriteCmd(0x10);		// Prg1
		
		rSYSCFG = cc;
		
		ENABLE;
		
		NfWait();
		pgaddr++;
		bp += 512;
	}
	NfChipDisable();
}


//
//	复位FLASH, 检查FLASH标识。
//

//
//	NAND FLASH 不用文件系统了!!!!
//

void
NfInit(void) {
	ULONG	t;
	
	NfWriteCmd(0xFF);

	t = NfReadId();
	
	DBG1("NAND FLASH: 0x%X\n", t);
	
	if(t != 0xEC73) {
		internal_fatal("NAND FLASH 型号错误!");
	}
}

// EOF

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -