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

📄 dataflash.c

📁 这个是基于ARM7的相关驱动代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*******************************************************************************
*                    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 + -