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

📄 dataflash.c

📁 实现ucos任务调度时保存LCD上的显示信息
💻 C
字号:
/*
********************************************************************************
*				 		C8051F340 DataFlash modular
*
*		        	  Ambition Comm Tech Ltd.Cop
*						   Jason.D.Proakis
*
* File Name		   : DataFlash.c
* File Description : C file of DataFlash modular AT45DB161D.
* Create Date	   : 04-11-2008
* Version	       : V1.00
* Modified History :
*					None
*
* All rights reserved.
*
* NOTE: This process is for device which page size is 512 bytes.
********************************************************************************
*/

/*
********************************************************************************
*							HEADER FILE INCLUDE
********************************************************************************
*/
#include <C8051F340.h>
#include "DataFlash.h"

/*
********************************************************************************
*						SPI OPERATION MACRO DEFINITION
********************************************************************************
*/
/* assert CS to begin a operation, CS setup time 5ns */
#define start_SPI()					AT45_CS = 0

/* deassert CS to end a operation, CS hold time 5ns */
#define stop_SPI()					AT45_CS = 1

/*
********************************************************************************
*						INTERNAL FUNCTION DECLARATION
********************************************************************************
*/
/* read buffer1 */
static void rd_buf1(unsigned int addr,unsigned char * buf,unsigned int len);

/* write buffer1 */
static void wr_buf1(unsigned int addr,unsigned char * buf,unsigned int len);

/* buffer1 to main memory page program with built-in erase */
static void prog_main_pg_buf1_erase(unsigned int pg_addr);

/* page erase */
static void erase_pg(unsigned int pg_addr);

/* main memory page to buffer 1 transfer */
static void get_main_pg_buf1(unsigned int pg_addr);

/* internal function, read a byte from SPI use SPI mode0 */
static unsigned char rd_byte(void);	

/* internal function, write a byte to SPI use SPI mode0 */		
static void wr_byte(unsigned char ch);

/* wait until device is ready */		
static void wait_rdy(void);

/*
********************************************************************************
*						 	  STATIC VARIABLES 	
********************************************************************************
*/
static unsigned int buf1_pg_num;
static unsigned int buf2_pg_num;
static unsigned char buf_op_flag;

/*
********************************************************************************
*						EXTERNAL INTERFACE FUNCTION 
********************************************************************************
*/
/*
********************************************************************************
* Function Name : DF_init 
* Description	: initial SPI port used by dataflash.
* Parameter		: none.
* Return		: none.
********************************************************************************
*/
void DF_init(void)
{
	P2MDOUT |= 0x70;				/* set CS,SI,SCK push-pull ouput 		*/
	P2MDOUT &= ~0x80;				/* set SO open-drain output 			*/
	P2 |= 0x80;						/* set SO input 						*/
	
	AT45_CS = 1;					/* diselect AT45DB161					*/
	AT45_SI = 1;
	AT45_SCK = 0;		
}

/*
********************************************************************************
* Function Name : DF_rd 
* Description	: Read data from dataflash.
* Parameter		: addr, unsigned long type, dataflash address begin to read.
*                   Range from 0 to 2^21 - 1.
*				  buf, unsigned char * type, header pointer to store data.
*				  len, unsigned int type, length of data want to read. 
*                   Range from 0 to 65535.
* Return		: none
********************************************************************************
*/
void DF_rd(unsigned long addr,unsigned char * buf,unsigned int len)
{
	start_SPI();
	wr_byte(OP_CODE_RD_ARRAY);
	wr_byte((unsigned char)(addr >> 16));
	wr_byte((unsigned char)(addr >> 8));
	wr_byte((unsigned char)addr);
	wr_byte(0x00);					/* 1 dummy bytes is need				*/
	
	while(len--) *buf++ = rd_byte();
	
	stop_SPI();
}

/*
********************************************************************************
* Function Name : DF_wr 
* Description	: Write data to dataflash.
* Parameter		: addr, unsigned long type, dataflash address begin to write.
*                   Range from 0 to 2^21 - 1.
*				  buf, unsigned char * type, header pointer of stored data.
*				  len, unsigned int type, length of data want to write. 
*                   Range from 0 to 65535.
* Return		: none
********************************************************************************
*/
void DF_wr(unsigned long addr,unsigned char * buf,unsigned int len)
{
	unsigned int ba,pg;
	
	ba = (unsigned int)(addr & 0x1FF);
	pg = addr >> 9;

	if(len <= (512 - ba))
	{
		if(ba) get_main_pg_buf1(pg);
		wr_buf1(ba,buf,len);
		prog_main_pg_buf1_erase(pg);
		len = 0;
	}
	else
	{
		if(ba != 0)								/* address not at page edge				*/
		{
			get_main_pg_buf1(pg);
			wr_buf1(ba,buf,512 - ba);
			prog_main_pg_buf1_erase(pg);

			pg ++;
			buf += (512 - ba);	
			len -= (512 - ba);
		}

		while(len > 511)
		{
			wr_buf1(0,buf,512);
			prog_main_pg_buf1_erase(pg);
		
			pg ++;
			buf += 512;
			len -= 512;	
		}
	
		if(len != 0) 
		{
			wr_buf1(0,buf,len);
			prog_main_pg_buf1_erase(pg);
		}
	}
}

/*
********************************************************************************
* Function Name : DF_get_stat 
* Description	: Get dataflash current status.
* Parameter		: none.
* Return		: unsigned char type, status register
*					bit7     bit6   bit5   bit4   bit3   bit2   bit1   bit0
* 				  RDY/BUSY   COMP    1      0      1      1   PROTECT PG SIZE 
********************************************************************************
*/
unsigned char DF_get_stat(void)
{
	unsigned char stat;
	start_SPI();
	wr_byte(OP_CODE_RD_STAT_REG);
	stat = rd_byte();
	stop_SPI();
	
	return stat;	
}

/*
********************************************************************************
* Function Name : DF_get_id 
* Description	: Get  manufacturer and device ID.
* Parameter		: none.
* Return		: unsigned long type, for AT45DB161D it will be 0x1F2600
********************************************************************************
*/
unsigned long DF_get_id(void)
{
	unsigned char i;
	unsigned long id = 0;

	start_SPI();
	wr_byte(OP_CODE_RD_MANU_DEV_ID);
	for(i = 0;i < 4;i ++)
	{
		id <<= 8;
		id |= rd_byte();
	}
	stop_SPI();

	return id;
}

/*
********************************************************************************
*							INTERNAL FUNCTIONS
********************************************************************************
*/
/* read buffer1 */
static void rd_buf1(unsigned int addr,unsigned char * buf,unsigned int len)
{
	start_SPI();
	wr_byte(OP_CODE_RD_BUF1);
	wr_byte(0x00);
	wr_byte((unsigned char)(addr >> 8));
	wr_byte((unsigned char)addr);
	wr_byte(0x00);					/* 1 dummy bytes is need				*/
	
	while(len--) *buf++ = rd_byte();
	
	stop_SPI();		
}

/* write buffer1 */
static void wr_buf1(unsigned int addr,unsigned char * buf,unsigned int len)
{
	start_SPI();
	wr_byte(OP_CODE_WR_BUF1);
	wr_byte(0x00);
	wr_byte((unsigned char)(addr >> 8));
	wr_byte((unsigned char)addr);
	
	while(len--) wr_byte(*buf++);
	
	stop_SPI();		
}

/* buffer1 to main memory page program with built-in erase */
static void prog_main_pg_buf1_erase(unsigned int pg_addr)
{
	
	start_SPI();
	wr_byte(OP_CODE_WR_BUF1_MAIN_ERASE);
	wr_byte((unsigned char)(pg_addr >> 7));
	wr_byte((unsigned char)(pg_addr << 1));
	wr_byte(0x00);
	stop_SPI();	
		
	wait_rdy();						/* page erase and programming time 40ms(max) */
}

/* page erase */
static void erase_pg(unsigned int pg_addr)
{
	start_SPI();
	wr_byte(OP_CODE_ERASE_PAGE);
	wr_byte((unsigned char)(pg_addr >> 7));
	wr_byte((unsigned char)(pg_addr << 7));
	wr_byte(0x00);
	stop_SPI();	

	wait_rdy();						/* page erase time 35ms(max) 				*/	
}

/* main memory page to buffer 1 transfer */
static void get_main_pg_buf1(unsigned int pg_addr)
{
	start_SPI();
	wr_byte(OP_CODE_RD_MAIN_BUF1);
	wr_byte((unsigned char)(pg_addr >> 7));
	wr_byte((unsigned char)(pg_addr << 1));
	wr_byte(0x00);
	stop_SPI();	
	
	wait_rdy();						/* transfer a page shall take place 200us(max) */
}

/* read a byte from SPI use SPI mode0 */
static unsigned char rd_byte(void)
{
	unsigned char i,dat;
	for(i  = 0;i < 8;i++)
	{
		AT45_SCK = 1;				/* SCK high time 6.8ns						*/
		dat <<= 1;
		dat |= AT45_SO;	
		AT45_SCK = 0;				/* SCK low time 6.8ns						*/
									/* output data valid 6ns					*/			
	}
	return dat;	
}

/* write a byte from SPI use SPI mode0 */
static void wr_byte(unsigned char dat)
{
	unsigned char i;
	for(i  = 0;i < 8;i++)
	{
		AT45_SI = dat & 0x80;		/* input data setup time 2ns				*/
		dat <<= 1;	
		AT45_SCK = 1;				/* SCK high time 6.8ns						*/
									/* input data hold time 3ns					*/
		AT45_SCK = 0;				/* SCK low time 6.8ns						*/			
	}	
}

/* wait until device is ready */
static void wait_rdy(void)
{
	start_SPI();
	wr_byte(OP_CODE_RD_STAT_REG);
	while(!(rd_byte() & 0x80));		/* the sequence will repeat itself			*/				
	stop_SPI();
}

⌨️ 快捷键说明

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