📄 dataflash.c
字号:
/*
*******************************************************************************
* Copyright (c) 2005, Comba Telecom System
* All Rights Reserved
*
* Purpose : dataFlash operation file
* File Name : dataFlash.c
* Chip type : LPC22XX(ARM7TDMI)
* IDE : ADS1.2
* Revision history :
01a,2005/08/16,Lu jiangmin -- Creation(written)
01a,2006/04, Max -- Modification by search "Max"
* Description :
*******************************************************************************
*/
#define _DEFINE_VAR_DF //全局变量定义
//#define _AT45DB081B
//#define _AT45DB321D
#include "config.h"
#include "dataflash.h"
/*
*******************************************************************************
* 函数功能: FPGA代码单字节编程
* 说 明:
* 1. 采用buffer x write与buffer x to main memory page program with
build-in erase组合命令:
首先向BUFFER1快速写入数据,如果BUFFER1写满,则向主FLASH编程,此后向
BUFFER2快速写入数据,如果BUFFER2写满,则向主FLASH编程,此后向BUFFER1快速
写入数据,循环反复.下载结束后向主FLASH编程可能未满的BUFFERx数据!
上述"方法"得以实现的原因:
主FLASH擦除和编程是自定时的(20mS),同时允许操作器件中的SRAM缓冲,
系统应用决定了BUFFER2写满的时候,BUFFER1向主FLASH的编程已经完成了!
上述"系统应用"只要满足:
SPI位速率>=5MHz(由fpclk和SPI初始化决定),SPI发送字节数<=15.
*******************************************************************************
*/
static INT8U bufferSEL = DF_OP_B2W;
static union {
INT8U byte[2];
INT16U word;
} pageAddr;
void df_writeDF_hex (INT16U PageBegin, INT8U data, INT32U addr)
{
INT8U spiBuffer[10], i;
union {
INT8U byte[2];
INT16U word;
} bufferAddr;
INT16U temp;
pageAddr.word = addr/DF_PAGE_SIZE + PageBegin ;
bufferAddr.word = addr % DF_PAGE_SIZE; //表示BUFFER内部地址:[0,DF_PAGE_SIZE-1]
if (!bufferAddr.word) //BUFFER切换:BUFFER1->BUFFER2或BUFFER2->BUFFER1
{
if (bufferSEL == DF_OP_B1W)
{
bufferSEL = DF_OP_B2W;
}
else if (bufferSEL == DF_OP_B2W)
{
bufferSEL = DF_OP_B1W;
}
}
// buffer x write命令
spiBuffer[0] = bufferSEL;
spiBuffer[1] = 0;
spiBuffer[2] = bufferAddr.byte[HIGH_ORDER];
spiBuffer[3] = bufferAddr.byte[LOW_ORDER];
spiBuffer[4] = data;
IO0CLR |= 0x00000001 << DF_FLASH_CS;
for (i = 0; i < 5; i++)
{
S0PDR = spiBuffer[i];
while (!(S0PSR & 0x80));
}
IO0SET |= 0x00000001 << DF_FLASH_CS;
// buffer x to main memory page program with build-in erase命令
if (bufferAddr.word == (DF_PAGE_SIZE - 1)) //当前BUFFER写满,需要向FLASH编程
{
if (bufferSEL == DF_OP_B1W)
{
spiBuffer[0] = DF_OP_B1MMP_E;
}
else if (bufferSEL == DF_OP_B2W)
{
spiBuffer[0] = DF_OP_B2MMP_E;
}
#ifdef _AT45DB081B //Max 20060425
pageAddr.word <<= 1;
#else
pageAddr.word <<= 2;
#endif
spiBuffer[1] = pageAddr.byte[HIGH_ORDER];
spiBuffer[2] = pageAddr.byte[LOW_ORDER];
spiBuffer[3] = 0;
IO0CLR |= 0x00000001 << DF_FLASH_CS;
for (i = 0; i < 4; i++)
{
S0PDR = spiBuffer[i];
while (!(S0PSR & 0x80));
}
IO0SET |= 0x00000001 << DF_FLASH_CS;
pageAddr.word = temp;
}
}
/*
*******************************************************************************
* 函数功能: 完成数据由BUFFER 至MAIN MEMORY的写入
* 说 明:
*******************************************************************************
*/
void df_writeDF_buf2mm (void)
{
INT8U spiBuffer[10], i;
if (bufferSEL == DF_OP_B1W)
{
spiBuffer[0] = DF_OP_B1MMP_E;
}
else if (bufferSEL == DF_OP_B2W)
{
spiBuffer[0] = DF_OP_B2MMP_E;
}
#ifdef _AT45DB081B //Max 20060425
pageAddr.word <<= 1;
#else
pageAddr.word <<= 2;
#endif
spiBuffer[1] = pageAddr.byte[HIGH_ORDER];
spiBuffer[2] = pageAddr.byte[LOW_ORDER];
spiBuffer[3] = 0;
IO0CLR |= 0x00000001 << DF_FLASH_CS;
for (i = 0; i < 4; i++)
{
S0PDR = spiBuffer[i];
while (!(S0PSR & 0x80));
}
IO0SET |= 0x00000001 << DF_FLASH_CS;
}
/*
*******************************************************************************
* 函数功能: FPGA代码单字节读取
* 说 明:
* 1. 输入:
addr--FPGA代码字节相对地址.
输出:
FPGA代码字节.
* 2. 基本方法:
a)计算绝对页地址,需要判断读取那个区的代码;
b)等待FLASH有效,发送"main memory page to buffer x transfer"命令把相
应页的内容拷贝到BUFFER中;
c)等待FLASH有效,发送"buffer x read"命令读取BUFFER中的相应字节.
* 3. 注意:
*******************************************************************************
*/
INT8U df_readDF_hex (INT32U addr, INT8U fpgaCS)
{
INT8U spiBuffer[10], i;
INT16U page_addr;
union {
INT8U byte[2];
INT16U word;
} temp;
//计算绝对页地址
if (fpgaCS == DF_M_CODE0) //准备向CODE 0区下载新软件,则取CODE 1区代码
{
page_addr = DF_ADDR_HEXCODE2_S + (INT16U)(addr / DF_PAGE_SIZE);
}
else if (fpgaCS == DF_M_CODE1) //准备向CODE 1区下载新软件,则取CODE 0区代码
{
page_addr = DF_ADDR_HEXCODE1_S + (INT16U)(addr / DF_PAGE_SIZE);
}
// 等待DataFlash有效
while (!(IO0PIN & (0x00000001 << 24)));
//读取Flash Page到Buffer
df_mmpToBuffer (page_addr);
// 等待DataFlash有效
while (!(IO0PIN & (0x00000001 << 24)));
//读取BUFFER中的相应字节
if (bufferSEL == DF_OP_B1W) //FPGA下载准备使用buffer1,则使用buffer2
{
spiBuffer[0] = DF_OP_B2R;
}
else if (bufferSEL == DF_OP_B2W)
{
spiBuffer[0] = DF_OP_B1R;
}
spiBuffer[1] = 0;
temp.word = (INT16U)(addr % DF_PAGE_SIZE);
spiBuffer[2] = temp.byte[HIGH_ORDER]; //for AT45DB081/AT45DB161B is all ok -Max
spiBuffer[3] = temp.byte[LOW_ORDER];
spiBuffer[4] = 0; //Additional Dummy
spiBuffer[5] = 0; //need this dummy?-datasheet not illuminate -Max
IO0CLR |= 0x00000001 << DF_FLASH_CS;
for (i = 0; i < 6; i++)
{
S0PDR = spiBuffer[i];
while (!(S0PSR & 0x80));
}
i = S0PDR;
IO0SET |= 0x00000001 << DF_FLASH_CS;
return (i);
}
/*
*******************************************************************************
* 函数功能: FPGA代码单字节读取
* 说 明:
* 1. 输入:
returnData--返回代码的指针;
page_addr--需要读取代码的页地址.
输出:
无.
* 2. 基本方法:
a)等待FLASH有效,发送"main memory page to buffer x transfer"命令把相
应页的内容拷贝到BUFFER中;
b)等待FLASH有效,发送"buffer x read"命令读取BUFFER中的相应字节.
* 3. 注意:
*******************************************************************************
*/
void df_readDF_hex_page (INT8U *returnData, INT16U page_addr, INT8U fpgaCS)
{
INT8U spiBuffer[10];
INT16U i;
// 等待DataFlash有效
while (!(IO0PIN & (0x00000001 << 24)));
// 读取Flash Page到Buffer
df_mmpToBuffer (page_addr);
// 等待DataFlash有效
while (!(IO0PIN & (0x00000001 << 24)));
// b)读整页
if (bufferSEL == DF_OP_B1W) //FPGA下载准备使用buffer1,则使用buffer2
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -