wince -- 2410-gpio的驱动
在WINCE下能够直接访问的都是虚拟地址,不能直接访问GPIO端口,因此我们首先需要将GPIO口的物理地址映射到虚拟地址上来。
分别使用VirtualAlloc和VirtualCopy这两个函数来完成映射!
这两个函数的原型:
LPVOID VirtualAlloc( LPVOID lpAddress, DWORD dwSize,
DWORD flAllocationType, DWORD flProtect );
BOOL VirtualCopy( LPVOID lpvDest, LPVOID lpvSrc, DWORD cbSize, DWORD fdwProtect );
如果这两个函数执行成功,哪么VirtualAlloc将返回一个指针,使用这个指针我们就可以直接访问GPIO,通过读写相关地址寄存器,来控制GPIO端口!
v_pIOPregs = (volatile IOPreg *)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
if (v_pIOPregs == NULL){
RetValue = FALSE;
}
else {
if (!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(IOP_BASE), sizeof(IOPreg), PAGE_READWRITE | PAGE_NOCACHE)) {
RetValue = FALSE;
}
}
if (!RetValue){
//PIO_InitializeAddresses - Failed !!
if (v_pIOPregs){
VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE);
}
v_pIOPregs = NULL;
}
//else RETAILMSG (1, (TEXT("::: PBT_InitializeAddresses - Success\r\n") ));
return(RetValue);
v_pIOPregs是一个IOPreg结构,在s2410.h中定义,
//
// Registers : I/O port
#define IOP_BASE 0xB1600000 // 0x56000000
typedef struct {
unsigned int rGPACON; // 00
unsigned int rGPADAT;
unsigned int rPAD1[2];
unsigned int rGPBCON; // 10
unsigned int rGPBDAT;
unsigned int rGPBUP;
unsigned int rPAD2;
unsigned int rGPCCON; // 20
unsigned int rGPCDAT;
unsigned int rGPCUP;
unsigned int rPAD3;
unsigned int rGPDCON; // 30
unsigned int rGPDDAT;
unsigned int rGPDUP;
unsigned int rPAD4;
unsigned int rGPECON; // 40
unsigned int rGPEDAT;
unsigned int rGPEUP;
unsigned int rPAD5;
unsigned int rGPFCON; // 50
unsigned int rGPFDAT;
unsigned int rGPFUP;
unsigned int rPAD6;
unsigned int rGPGCON; // 60
unsigned int rGPGDAT;
unsigned int rGPGUP;
unsigned int rPAD7;
unsigned int rGPHCON; // 70
unsigned int rGPHDAT;
unsigned int rGPHUP;
unsigned int rPAD8;
unsigned int rMISCCR; // 80
unsigned int rDCKCON;
unsigned int rEXTINT0;
unsigned int rEXTINT1;
unsigned int rEXTINT2; // 90
unsigned int rEINTFLT0;
unsigned int rEINTFLT1;
unsigned int rEINTFLT2;
unsigned int rEINTFLT3; // A0
unsigned int rEINTMASK;
unsigned int rEINTPEND;
unsigned int rGSTATUS0;
unsigned int rGSTATUS1; // B0
}IOPreg;
分别使用VirtualAlloc和VirtualCopy这两个函数来完成映射!
这两个函数的原型:
LPVOID VirtualAlloc( LPVOID lpAddress, DWORD dwSize,
DWORD flAllocationType, DWORD flProtect );
BOOL VirtualCopy( LPVOID lpvDest, LPVOID lpvSrc, DWORD cbSize, DWORD fdwProtect );
如果这两个函数执行成功,哪么VirtualAlloc将返回一个指针,使用这个指针我们就可以直接访问GPIO,通过读写相关地址寄存器,来控制GPIO端口!
v_pIOPregs = (volatile IOPreg *)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
if (v_pIOPregs == NULL){
RetValue = FALSE;
}
else {
if (!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(IOP_BASE), sizeof(IOPreg), PAGE_READWRITE | PAGE_NOCACHE)) {
RetValue = FALSE;
}
}
if (!RetValue){
//PIO_InitializeAddresses - Failed !!
if (v_pIOPregs){
VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE);
}
v_pIOPregs = NULL;
}
//else RETAILMSG (1, (TEXT("::: PBT_InitializeAddresses - Success\r\n") ));
return(RetValue);
v_pIOPregs是一个IOPreg结构,在s2410.h中定义,
//
// Registers : I/O port
#define IOP_BASE 0xB1600000 // 0x56000000
typedef struct {
unsigned int rGPACON; // 00
unsigned int rGPADAT;
unsigned int rPAD1[2];
unsigned int rGPBCON; // 10
unsigned int rGPBDAT;
unsigned int rGPBUP;
unsigned int rPAD2;
unsigned int rGPCCON; // 20
unsigned int rGPCDAT;
unsigned int rGPCUP;
unsigned int rPAD3;
unsigned int rGPDCON; // 30
unsigned int rGPDDAT;
unsigned int rGPDUP;
unsigned int rPAD4;
unsigned int rGPECON; // 40
unsigned int rGPEDAT;
unsigned int rGPEUP;
unsigned int rPAD5;
unsigned int rGPFCON; // 50
unsigned int rGPFDAT;
unsigned int rGPFUP;
unsigned int rPAD6;
unsigned int rGPGCON; // 60
unsigned int rGPGDAT;
unsigned int rGPGUP;
unsigned int rPAD7;
unsigned int rGPHCON; // 70
unsigned int rGPHDAT;
unsigned int rGPHUP;
unsigned int rPAD8;
unsigned int rMISCCR; // 80
unsigned int rDCKCON;
unsigned int rEXTINT0;
unsigned int rEXTINT1;
unsigned int rEXTINT2; // 90
unsigned int rEINTFLT0;
unsigned int rEINTFLT1;
unsigned int rEINTFLT2;
unsigned int rEINTFLT3; // A0
unsigned int rEINTMASK;
unsigned int rEINTPEND;
unsigned int rGSTATUS0;
unsigned int rGSTATUS1; // B0
}IOPreg;