Windows CE GPIO/LED驱动

本以为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);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值