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

📄 emc.c

📁 philips arm7 lpc2103的常用功能的库函数第二部分
💻 C
字号:
/***********************************************Copyright (c)*********************************************
**                                Guangzou ZLG-MCU Development Co.,LTD.
**                                     
**                                       http://www.zlgmcu.com
**
**--------------File Info---------------------------------------------------------------------------------
** File name:			    Emc.c
** Last modified Date:      2007-10-15
** Last Version:		    1.0
** Descriptions:		    Emc函数实现,采用设备描述符来操作
**
**--------------------------------------------------------------------------------------------------------
** Created by:			    wengshujie
** Created date:		    2007-10-15
** Version:				    1.0
** Descriptions:		    无
**
**--------------------------------------------------------------------------------------------------------
** Modified by:			    
** Modified Date:		    
** Version:				    
** Descriptions:		    
**
*********************************************************************************************************/
#include "Config.h"
#include "EmcPrivate.h"
#include "Emc.h"
                                                                      /* 该文件是用来让该驱动更容易移值 */
/*********************************************************************************************************
   定义操作EMC器件的结构体
*********************************************************************************************************/
static __EMC_INFO  __GEmcInfoDate;

/*********************************************************************************************************
   定义一个数组存储四组外部扩张存储器的控制寄存器基址
*********************************************************************************************************/
const uint32    __GuiEmcBaseAddrTab[__EMC_MAX_NUM] = {EMC0_BASE_ADDR, EMC1_BASE_ADDR,
                                                      EMC2_BASE_ADDR, EMC3_BASE_ADDR};
                                                       
/*********************************************************************************************************
** Function name:			__emcInit
** Descriptions:			EMC配置
** Input parameters:		uiId:       EMC的BANK号,如uiId=0,为BANK0
**							puiParaData: 数组首地址
**										 BusWidth:       总线宽度     8、16、32
**										 Rdlong:         读等待周期   0 ~ 31
**										 Wrlong:         写等待周期	  0 ~ 31
**										 Idcy:           读写切换周期 0 ~ 15 	
** Output parameters:       NONE
** Returned value:          操作成功:   OPERATE_SUCCESS
**                          操作失败:   OPERATE_FAIL
*********************************************************************************************************/
#define BUSCFG_WORD	(~((0x03 << 28) | (0x1F << 11) | (0x1F << 5)))      /*  BCFG寄存器设置位清0         */
                                                                        /*  (bit29~28\bit15~11\bit9~5)  */
#define BW8     0x00000000
#define BW16_32     0x10000400;    

static void __emcInit (uint32 uiId, uint32 *puiParaData)       
{
    volatile uint32 *puiAddrBase;
	volatile uint32  uiOffBase;
	         uint32  uiBw;
	
	__GEmcInfoDate.puiAddrBase = (uint32*)__GuiEmcBaseAddrTab[uiId];    /*  初始化GPIO结构体参数        */
	__GEmcInfoDate.uiOffBase   = 0;
	
	puiAddrBase = __GEmcInfoDate.puiAddrBase;                           /*  获取结构体参数              */
	uiOffBase   = __GEmcInfoDate.uiOffBase;
                                                                        /*  参数过滤                    */
    if ((puiParaData[BusWidth] != 8) && (puiParaData[BusWidth] != 16) && (puiParaData[BusWidth] != 32)) {
        puiParaData[BusWidth] = 8;
    }
    if (puiParaData[Rdlong] > 31) {
        puiParaData[Rdlong] = 31;
    }
    if (puiParaData[Wrlong] > 31) {
        puiParaData[Wrlong] = 31;
    }
 	if (puiParaData[Idcy] > 15) {
 	    puiParaData[Idcy] = 15;
 	}
	if (puiParaData[BusWidth] == 8) {
        uiBw = BW8;                                                     /*  8位                          */
    }
 	else {
        uiBw = BW16_32;					                                /*  16位或32位                   */
    }

 	puiAddrBase[__B_EMC_BCFG << uiOffBase] &= BUSCFG_WORD;
	puiAddrBase[__B_EMC_BCFG << uiOffBase] |= (uiBw |
	                                          (puiParaData[Wrlong] << 11) |
	                                          (puiParaData[Rdlong] << 5) |
	                                           puiParaData[Idcy]);
}
                                               
/*********************************************************************************************************
** Function name:			emcInit
** Descriptions:			EMC配置
** Input parameters:		uiId:       EMC的BANK号,如uiId=0,为BANK0
**							pcArg:      配置参数字符窜指针
**										BusWidth:       总线宽度     8、16、32
**										Rdlong:         读等待周期   0 ~ 31
**										Wrlong:         写等待周期	 0 ~ 31
**										Idcy:           读写切换周期 0 ~ 15 														
**							pRsv:       预留参数
** Output parameters:       NONE
** Returned value:          操作成功:   OPERATE_SUCCESS
**                          操作失败:   OPERATE_FAIL
** Example:                 char cEmcArt[]="BusWidth=8 Rdlong=15 Wrlong=15 Idcy=10";
**                          emcInit( BANK0, cEmcArt, NULL ); 
*********************************************************************************************************/
#define MAX_EMC_STR_NUM   4                                             /*  字符串中包含4个参数         */

extern int32 emcInit (uint32 uiId, 
                      char *pcArg, 
                      void *pRsv)
{
    uint32 uiParaData[MAX_EMC_STR_NUM] = {0};                           /*  定义一个数组存放字符串的参数*/
    
    if ((uiId < __EMC_MAX_NUM) && (strlen(pcArg) < 80)) {
        
        ImpCmd(Tab_EMC, pcArg, uiParaData);                             /*  从字符串中提取参数          */
        
        __emcInit( uiId, uiParaData );
        
        return OPERATE_SUCCESS;
    }
    else {
        return OPERATE_FAIL;
    }
}

/*********************************************************************************************************
** Function name:			emcWrite
** Descriptions:			EMC写操作
** Input parameters:		uiId:       EMC的BANK号,如uiId=0,为BANK0
**							uiBw:       数据总线宽度
**							uiAddr:     偏移地址0x80000000 ~ 0x83FFFFFF
**                                      BANK0:  0x80000000 ~ 0x80FFFFFF
**                                      BANK1:  0x81000000 ~ 0x81FFFFFF
**                                      BANK2:  0x82000000 ~ 0x82FFFFFF
**                                      BANK3:  0x83000000 ~ 0x83FFFFFF
**							uiNum:      写的数据个数			      														
**							puiData:    输入数组首地址
** Output parameters:       NONE
** Returned value:          操作成功:   OPERATE_SUCCESS
**                          操作失败:   OPERATE_FAIL
**                          超出地址范围:EXBUSADRROVER
** Example:                 uint32 uiWriteData[10]={0};
**                          emcWrite( BANK0, 16, 0x80000000, 10, uiWriteData );
*********************************************************************************************************/
#define EXBUSADRROVER -2

extern int32 emcWrite (uint32 uiId,
                       uint32 uiBw,
                       uint32 uiAddr,
                       uint32 uiNum,
                       uint32 *puiData)
{
	volatile uint8  *pucAddr8;
	volatile uint16 *pusAddr16;
	volatile uint32 *puiAddr32;
	
	         uint32 uiStartAddr; 
	         uint32 uiEndAddr;
	         
	         uint32 uiCount;
	         
	if (uiId > 3) {
	    return(OPERATE_FAIL);
	}
	if (uiBw != 8);
		else if (uiBw != 16);
			 else if (uiBw != 32) {
			    return OPERATE_FAIL;
			 }
			 
    uiStartAddr = 0x80000000 + (uiId * 0x01000000);                     /*  计算可以操作的地址范围      */
    uiEndAddr = 0x80FFFFFF + (uiId * 0x01000000); 
    
	switch(uiBw)
	{
	case 8:
	    pucAddr8 = (volatile uint8 *)uiAddr;		
		for (uiCount = 0; uiCount < uiNum; uiCount++) {
		    if (*pucAddr8 >= uiEndAddr) {
			    return EXBUSADRROVER;		                            /*  地址越界                    */
			}
			*pucAddr8 = (uint8)(puiData[uiCount] & 0xff);				/*  写入数据                    */
			 pucAddr8++;
		}
		break;
	case 16:
		pusAddr16 = (volatile uint16 *)uiAddr;		
		for (uiCount = 0; uiCount < uiNum; uiCount++) {
		    if (*pusAddr16 >= uiEndAddr) {
			    return EXBUSADRROVER;		
		    }
			*pusAddr16 = (uint16)(puiData[uiCount] & 0xffff);										
			 pusAddr16++;
			}
		break;
	case 32:
		puiAddr32 =(volatile uint32 *)uiAddr;	
		for (uiCount = 0; uiCount < uiNum; uiCount++) {
		    if (*puiAddr32 >= uiEndAddr) {
			    return EXBUSADRROVER;		
			}
			*puiAddr32 = puiData[uiCount];								
			 puiAddr32++;
		}
		break;
	default:
		return OPERATE_FAIL;			
	}
	return OPERATE_SUCCESS;   
}
                       
/*********************************************************************************************************
** Function name:			emcRead
** Descriptions:			EMC读操作
** Input parameters:		uiId:       EMC的BANK号,如uiId=0,为BANK0
**							uiBw:       数据总线宽度
**							uiAddr:     偏移地址0x80000000 ~ 0x83FFFFFF
**                                      BANK0:  0x80000000 ~ 0x80FFFFFF
**                                      BANK1:  0x81000000 ~ 0x81FFFFFF
**                                      BANK2:  0x82000000 ~ 0x82FFFFFF
**                                      BANK3:  0x83000000 ~ 0x83FFFFFF
**							uiNum:      读的数据个数			      														
**							puiData:    读数据的存放首地址
** Output parameters:       NONE
** Returned value:          操作成功:   OPERATE_SUCCESS
**                          操作失败:   OPERATE_FAIL
** Example:                 uint32 uiReadData[10]={0};
**                          emcRead( BANK0, 16, 0x80000000, 10, uiReadData );
*********************************************************************************************************/
extern int32 emcRead (uint32 uiId,
                      uint32 uiBw,
                      uint32 uiAddr,
                      uint32 uiNum,
                      uint32 *puiData)
{
	volatile uint8  *pucAddr8;
	volatile uint16 *pusAddr16;
	volatile uint32 *puiAddr32;
	
	         uint32 uiStartAddr; 
	         uint32 uiEndAddr;
	         
	         uint32 uiCount;
	         
	if (uiId > 3) {
	    return(OPERATE_FAIL);
	}
	if (uiBw != 8);
		else if (uiBw != 16);
			 else if (uiBw != 32) {
			    return OPERATE_FAIL;
			 }
			 
    uiStartAddr = 0x80000000 + (uiId * 0x01000000);                     /*  计算可以操作的地址范围      */
    uiEndAddr = 0x80FFFFFF + (uiId * 0x01000000); 
    
	switch(uiBw)
	{
	case 8:
	    pucAddr8 = (volatile uint8 *)uiAddr;		
		for (uiCount = 0; uiCount < uiNum; uiCount++) {
		    if (*pucAddr8 >= uiEndAddr) {
			    return EXBUSADRROVER;		                            /*  地址越界                    */
			}				
			puiData[uiCount] = *pucAddr8;                               /*  读入数据                    */
			pucAddr8++;
		}
		break;
	case 16:
		pusAddr16 = (volatile uint16 *)uiAddr;		
		for (uiCount= 0; uiCount < uiNum; uiCount++) {
		    if (*pusAddr16 >= uiEndAddr) {
			    return EXBUSADRROVER;		
		    }
			puiData[uiCount] = *pusAddr16;                              /*  读入数据                    */
			pusAddr16++;
			}
		break;
	case 32:
		puiAddr32 =(volatile uint32 *)uiAddr;	
		for (uiCount = 0; uiCount < uiNum; uiCount++) {
		    if (*puiAddr32 >= uiEndAddr) {
			    return EXBUSADRROVER;		
			}
			puiData[uiCount] = *puiAddr32;                              /*  读入数据                    */
			puiAddr32++;
		}
		break;
	default:
		return OPERATE_FAIL;			
	}
	return OPERATE_SUCCESS; 
}

/*********************************************************************************************************
   END FILE
*********************************************************************************************************/

⌨️ 快捷键说明

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