#include "windows.h"
#include "BSP.h"
#include <ceddk.h>
#pragma comment(lib,"ceddk.lib")
//#define MYDRVDLL_API __declspec(dllexport)
//#define DEBUGOUT(pInfo) RETAILMSG(1,(TEXT(pInfo)));
#define DPR_PHYBASEADDR 0x10000000 // DPRAM的起始物理地址
#define DPR_PHYSEMBASEADDR ( DPR_PHYBASEADDR + (1 << 13) ) // DPRAM的Semaphore片选地址
#define DPR_SIZE 8192 // DPRAM的SRAM容量
#define SEM_SIZE 8 // SEM的个数
#define DPRAM_THREAD_PRIORITY 200 // EINT14的IST线程优先级
typedef struct
{
BYTE *pRAM_begin, *pRAM; // DPRAM的SRAM起始虚拟地址指针,当前虚拟地址指针
BYTE *pSEM_begin; // DPRAM的SEM起始地址指针
BOOL NewDataOtherSide; // DPRAM是否有对方发来的数据
DWORD sysIntr; // EINT14的系统逻辑中断号
HANDLE hEvent; // EINT14的IST等待事件的句柄
HANDLE hThread; // EINT14的IST线程的句柄
BOOL Valid; // 指示本结构是否有效
}_DPRAM_;
static _DPRAM_ DPRAM;
static volatile S3C2440A_IOPORT_REG *v_pIOPregs; // Pointer to device control registers
static volatile S3C2440A_MEMCTRL_REG *v_pMEMregs; // Pointer to device Memory registers
DWORD IST_CNT = 0;
DWORD DPR_Init(DWORD dwContext);
BOOL DPR_Deinit(DWORD hDeviceConext);
DWORD DPR_Open(DWORD hDeviceContext,DWORD AccessCode,DWORD ShareMode);
BOOL DPR_Close(DWORD hOpenContext);
void DPR_PowerUp(DWORD hDeviceContext);
void DPR_PowerDown(DWORD hDeviceContext);
BOOL DPR_IOControl(DWORD hOpenContext,DWORD swCode,PBYTE pBufIn,DWORD dwLenIn,PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut);
DWORD DPR_Seek(DWORD hOpenContext,long Amount,DWORD Type);
DWORD DPR_Read(DWORD hOpenContext,LPVOID pBuffer,DWORD Count);
DWORD DPR_Write(DWORD hOpenContext,LPVOID pSourceBytes,DWORD NumberOfBytes);
static BOOL RequestSemaphore(BYTE SemaphoreNumber);
static BOOL ReleaseSemaphore(BYTE SemaphoreNumber);
static DWORD EINT14_IST(LPVOID Context);
BOOL
DllEntry(
HINSTANCE hinstDll, /*@parm Instance pointer. */
DWORD dwReason, /*@parm Reason routine is called. */
LPVOID lpReserved /*@parm system parameter. */
)
{
if ( dwReason == DLL_PROCESS_ATTACH ) {
DEBUGREGISTER(hinstDll);
// DEBUGMSG (ZONE_INIT, (TEXT("DPR: Process Attach\r\n")));
}
if ( dwReason == DLL_PROCESS_DETACH ) {
// DEBUGMSG (ZONE_INIT, (TEXT("DPR: Process Detach\r\n")));
}
return(TRUE);
}
/*******************************************************************
功能:驱动程序初始化
返回:TRUE/FALSE
*******************************************************************/
DWORD DPR_Init(DWORD dwContext)
{
PHYSICAL_ADDRESS phyaddr;
UINT32 Irq;
DWORD dwErr = ERROR_SUCCESS;
RETAILMSG(1,(TEXT("DPR: Init\r\n")));
memset(&DPRAM, 0, sizeof(_DPRAM_));
// 把DPRAM物理地址映射到pDPRAM所指的虚拟地址
phyaddr.LowPart = DPR_PHYBASEADDR;
phyaddr.HighPart = 0;
DPRAM.pRAM_begin = (BYTE *)MmMapIoSpace(phyaddr, DPR_SIZE, FALSE);
DPRAM.pRAM = DPRAM.pRAM_begin;
if( DPRAM.pRAM_begin == NULL )
goto _DPRinit_error;
// 把Semaphore物理地址映射到pSEM_begin所指的虚拟地址
phyaddr.LowPart = DPR_PHYSEMBASEADDR;
phyaddr.HighPart = 0;
DPRAM.pSEM_begin = (BYTE *)MmMapIoSpace(phyaddr, SEM_SIZE, FALSE);
if( DPRAM.pSEM_begin == NULL )
goto _DPRinit_error;
// 修改nGCS2片选区域总线位宽为8位
v_pMEMregs = (volatile S3C2440A_MEMCTRL_REG *)VirtualAlloc(0, sizeof(S3C2440A_MEMCTRL_REG), MEM_RESERVE, PAGE_NOACCESS);
if( v_pMEMregs == NULL )
goto _DPRinit_error;
if( !VirtualCopy((PVOID)v_pMEMregs, (PVOID)(S3C2440A_BASE_REG_PA_MEMCTRL >> 8), sizeof(S3C2440A_MEMCTRL_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE) )
goto _DPRinit_error;
v_pMEMregs->BWSCON &= ~(0X03 << 8);
v_pMEMregs->BWSCON |= (0X01 << 10);
v_pMEMregs->BANKCON2 = 0xffff;
VirtualFree((PVOID) v_pMEMregs, 0, MEM_RELEASE);
v_pMEMregs = NULL;
// 把GPIO寄存器的物理地址映射到虚拟地址
v_pIOPregs = (volatile S3C2440A_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2440A_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
if( v_pIOPregs == NULL )
goto _DPRinit_error;
if( !VirtualCopy((PVOID)v_pIOPregs, (PVOID)(S3C2440A_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2440A_IOPORT_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE) )
goto _DPRinit_error;
// 配置GPG7(EINT15)
v_pIOPregs->GPGCON &= ~(0x01 << 15); // 把GPG7设置为OUTPUT方向
v_pIOPregs->GPGCON |= (0x01 << 14);
v_pIOPregs->GPGDAT |= (0x01 << 7); // GPG7上电默认输出高电平
v_pIOPregs->GPGUP &= ~(0x01 << 7); // GPG7带上拉电阻
// 配置GPF3(EINT3)
v_pIOPregs->GPFCON &= ~(0x01 << 7); // 把GPG7设置为OUTPUT方向
v_pIOPregs->GPFCON |= (0x01 << 3);
v_pIOPregs->GPFDAT |= (0x01 << 3); // GPG7上电默认输出高电平
v_pIOPregs->GPGUP &= ~(0x01 << 3); // GPG7带上拉电阻
// 配置GPG6(EINT14)
v_pIOPregs->GPGCON &= ~ (0x01 << 13); // 把GPG6设置为EINT
v_pIOPregs->GPGCON |= (0x01 << 12);
v_pIOPregs->GPGDAT |= (0x01 << 6); // GPG6上电默认输出高电平
v_pIOPregs->GPGUP &= ~(0x01 << 6); // GPG6带上拉电阻
// 初始化EINT14
v_pIOPregs->EXTINT1 |= (0x01 << 27); // Filter Enable
v_pIOPregs->EXTINT1 &= ~(0x07 << 24); // Falling edge triggered
v_pIOPregs->EXTINT1 |= (0x01 << 25);
v_pIOPregs->EINTPEND |= (0x01 << 14); // Clear External interrupt pending register
//v_pIOPregs->EINTMASK &= ~(0x01 << 14); // enable interrupt
// 创建连接到EINT14的IST的事件
if( (DPRAM.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL )
goto _DPRinit_error;
// 申请EINT14的系统逻辑中断号
Irq = IRQ_EINT14;
if( !KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq, sizeof(UINT32), &DPRAM.sysIntr, sizeof(UINT32), NULL) )
goto _DPRinit_error;
// 连接逻辑中断号与事件
InterruptDisable(DPRAM.sysIntr);
if( !InterruptInitialize(DPRAM.sysIntr, DPRAM.hEvent, NULL, 0) )
goto _DPRinit_error;
InterruptDone(DPRAM.sysIntr);
// 创建IST线程
if( (DPRAM.hThread = CreateThread(NULL, 0, &EINT14_IST, NULL, 0, NULL)) == NULL )
goto _DPRinit_error;
if( !CeSetThreadPriority(DPRAM.hThread, DPRAM_THREAD_PRIORITY) )
goto _DPRinit_error;
ReleaseSemaphore(0);
DPRAM.Valid = TRUE;
return TRUE;
_DPRinit_error:
DPR_Deinit(NULL);
return FALSE;
}
/*******************************************************************
功能:撤销驱动程序
返回:TRUE/FALSE
*******************************************************************/
BOOL DPR_Deinit(DWORD hDeviceConext)
{
RETAILMSG(1,(TEXT("DPR: Deinit\r\n")));
DPRAM.Valid = FALSE;
// 禁止EXINT14中断,释放系统逻辑中断号
if( DPRAM.sysIntr != SYSINTR_UNDEFINED )
{
InterruptDisable(DPRAM.sysIntr);
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &DPRAM.sysIntr, sizeof(UINT32), NULL ,0 ,NULL);
DPRAM.sysIntr = SYSINTR_UNDEFINED;
}
// 关闭EXINT14的IST中断事件,关闭EXINT14的IST线程
if( DPRAM.hEvent != NULL )
{
CloseHandle(DPRAM.hEvent);
DPRAM.hEvent = NULL;
}
if( DPRAM.hThread != NULL )
{
CloseHandle(DPRAM.hThread);
DPRAM.hThread = NULL;
}
// 释放虚拟内存
if( DPRAM.pRAM_begin != NULL )
{
MmUnmapIoSpace((PVOID)(DPRAM.pRAM_begin), DPR_SIZE); // 解除物理地址到虚拟地址的映射
DPRAM.pRAM_begin = NULL;
DPRAM.pRAM = NULL;
}
if( DPRAM.pSEM_begin != NULL )
{
MmUnmapIoSpace((PVOID)(DPRAM.pSEM_begin), SEM_SIZE); // 解除物理地址到虚拟地址的映射
DPRAM.pSEM_begin = NULL;
}
if( v_pMEMregs != NULL ) // 解除物理地址到虚拟地址的映射
{
VirtualFree((PVOID) v_pMEMregs, 0, MEM_RELEASE);
v_pMEMregs = NULL;
}
if( v_pIOPregs != NULL ) // 解除物理地址到虚拟地址的映射
{
VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE);
v_pIOPregs = NULL;
}
return TRUE;
}
/*******************************************************************
功能:打开设备
返回:TRUE/FALSE
*******************************************************************/
DWORD DPR_Open(DWORD hDeviceContext,DWORD AccessCode,DWORD ShareMode)
{
RETAILMSG(1,(TEXT("DPR: Open\r\n")
评论0