📄 dataflash.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 + -