您的位置:首页 > 其它

Windows CE GPIO/LED驱动

2009-08-19 00:14 330 查看
本以为GPIO驱动很简单,结果查资料整了一周,还是没搞明白。主要是实验箱(HHARM9 EDU)上驱动LED是利用CPLD,自己不知道CPLD,加上不明白CPLD与2410的连接,所有程序没搞明白。不过修改实验箱配套bsp的代码,总算修改通过了。
主要是VirtualAlloc的问题,在PB4.2的bsp版本中代码为
v_pIOPregs = (volatile IOPreg *)VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE, PAGE_NOACCESS);
而且竟然把在s2410.h中的地址给修改了
#define IOP_BASE 0xB1600000 // 0x56000000
把固定的 0x56000000修改为0xB1600000了
我在网上搜到资料说
1:0xB1600000是虚拟地址,是经过MMU映射过的地址,访问这个地址就是访问0x56000000地址。
2:这个值是用这个公式推出来的:虚拟地址=物理>>4位 + 0xac000000,算了一下,UART,SIP等其它口的基地址都符合这个公式,在s2410.h中有他的宏定义: " #define DMA_BUFFER_BASE 0xAC000000 "
我自己的系统式PB5.0的,于是我就按照这种方法修改了PB5.0的基址,结果定制的系统运行不起来了,害得我又重装了PB,后来才发现时因为我修改了IO基址的原因
现在知道了在PB5.0中VirtualAlloc的用法是
if(!VirtualCopy((PVOID)v_pIOPregs,(PVOID)(S3C2410X_BASE_REG_PA_IOPORT>> 8),sizeof(S3C2410X_IOPORT_REG),
PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)){
ERRORMSG(1,(TEXT("For pIOPregs: VirtualCopy failed!/r/n")));
return (FALSE);
}
要有PAGE_PHYSICAL 在PB帮助文档上说,要是使用了PAGE_PHYSICAL ,就要S3C2410X_BASE_REG_PA_IOPORT>> 8。
于是GPIO驱动修给通过了,我只是把原来的bsp4.2变成了PB5.0环境中的。
虽然LED亮了,可是还是没明白该驱动如何点亮LED。因为实验箱用了CPLD点亮LED。不过想来,GIOP驱动其实是完成
取得相关寄存器的虚拟地址、设置某个引脚为输出引脚、设置某个引脚为输入引脚、设置某个引脚输出高电平、设置某个引脚输出底电平等功能。所有GPIO就先告一段落了


驱动代码:
#include <windows.h>
#include <types.h>
#include <tchar.h>
#include <cardserv.h>
#include <cardapi.h>
#include <tuple.h>
#include <devload.h>
#include <diskio.h>
/******************************************************************************
*End of Modification Done by Maneesh Gupta
*****************************************************************************/
//#include <nkintr.h>
//#include <oalintr.h>
#include <Winbase.h>
#include <s3c2410x.h>
#include "led.h"

#define IO_LED_WRITE 99
DWORD mIoAddr = NULL;
DWORD LedAddr[6];
//volatile IOPreg *v_pIOPregs;
volatile S3C2410X_IOPORT_REG *v_pIOPregs;

void ReadRegDWORD(LPCWSTR szKeyName,LPCWSTR szValueName,LPDWORD pdwValue){
HKEY hKeybd;
DWORD ValType;
DWORD ValLen;
DWORD status;

status=RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
szKeyName,
0,
0,
&hKeybd);
if(status){
*pdwValue=0;
return;
}
ValLen=sizeof(DWORD);
status=RegQueryValueEx(
hKeybd,
szValueName,
NULL,
&ValType,
(PUCHAR)pdwValue,
&ValLen
);
if(status!=ERROR_SUCCESS){
*pdwValue=0;
}
RegCloseKey(hKeybd);

}

BOOL WINAPI
DllEntry(HINSTANCE DllInstance, INT Reason, LPVOID Reserved)
{
return TRUE;
}

DWORD
LED_Init(
DWORD dwContext
)
{
DWORD dwValue;
int count;
DWORD status;
RETAILMSG(0,(TEXT("LED_Init/r/n")));

if(NULL == mIoAddr){
ReadRegDWORD(TEXT("Drivers//BuiltIn//LED"), _T("IoAddr"), &dwValue);
if(0==dwValue){
RETAILMSG(1,(TEXT("no EnableWake regValue/r/n")));
dwValue=0x10000000;
}
mIoAddr =(unsigned int)VirtualAlloc(0,0x10,MEM_RESERVE,PAGE_NOACCESS);
RETAILMSG(1, (TEXT("iopBase=%x/r/n"),(unsigned int)mIoAddr));
if(!VirtualCopy((LPVOID)mIoAddr,(LPVOID)((dwValue)>>8),0x10,PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL))
RETAILMSG(1, (TEXT("VIRTUAL COPY failed/r/n")));
else
RETAILMSG(1, (TEXT("VIRTUAL COPY succeed/r/n")));

for(count=0;count<6;count++)
LedAddr[count]=(mIoAddr+count);
}
if(v_pIOPregs == NULL) {
v_pIOPregs = (volatile S3C2410X_IOPORT_REG*)VirtualAlloc(0,sizeof(S3C2410X_IOPORT_REG),MEM_RESERVE, PAGE_NOACCESS);

if(v_pIOPregs == NULL) {
RETAILMSG(1,(TEXT("For IOPreg: VirtualAlloc failed!/r/n")));
return (FALSE);
}
else {
if(!VirtualCopy((PVOID)v_pIOPregs,(PVOID)(S3C2410X_BASE_REG_PA_IOPORT>> 8),sizeof(S3C2410X_IOPORT_REG),
PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)){
ERRORMSG(1,(TEXT("For pIOPregs: VirtualCopy failed!/r/n")));
return (FALSE);
}
}
}

return mIoAddr;
}

BOOL LED_Close(DWORD Handle)
{
RETAILMSG(1,(TEXT("LED_Close/r/n")));
v_pIOPregs->GPACON &= (~0x2000);
v_pIOPregs->GPADAT |= 0x2000;
return TRUE;
} // LED_Close

BOOL
LED_Deinit(
DWORD dwContext // pointer to the per disk structure
)
{
RETAILMSG(0,(TEXT("LED_Deinit/r/n")));
return TRUE;
} // LED_Deinit

//
// Returns handle value for the open instance.
//
DWORD
LED_Open(
DWORD dwDLED,
DWORD dwAccess,
DWORD dwShareMode
)
{
RETAILMSG(1,(TEXT("LED_Open/r/n")));
v_pIOPregs->GPACON |= 0x2000; //select function of GPA20 :nFRE(NAND Flash Read Enable (Output))
v_pIOPregs->GPADAT &= (~0x2000);
return 1;//(DWORD)(&LedAddr[0]);
} // LED_Open
BOOL
LED_IOControl(
DWORD Handle,
DWORD dwIoControlCode,
PBYTE pInBuf,
DWORD nInBufSize,
PBYTE pOutBuf,
DWORD nOutBufSize,
PDWORD pBytesReturned
)
{
RETAILMSG(1,(TEXT("LED_IOControl/r/n")));
if(IO_LED_WRITE==dwIoControlCode){
int count;
RETAILMSG(1,(TEXT("dwIoControlCode = 99/r/n")));
for(count=0;count<6;count++)
*(volatile unsigned char*)LedAddr[count]=pInBuf[count];
}

return TRUE;
} // LED_IOControl
其他函数为空
驱动测试代码
void CLedTestDlg::OnOpen()
{
// TODO: Add your control notification handler code here
LPDWORD lpBytesReturned;

hLedPort=CreateFile(TEXT("LED1:"),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
if(hLedPort==INVALID_HANDLE_VALUE){
RETAILMSG(1,(TEXT("open error error=%d/r/n"),GetLastError()));
return ;
}

DeviceIoControl(hLedPort,IO_LED_WRITE,(LPVOID)ledBuf,6,NULL,NULL,lpBytesReturned,NULL);
}

void CLedTestDlg::OnClose()
{
// TODO: Add your control notification handler code here
CloseHandle(hLedPort);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: