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