19,500
社区成员
发帖
与我相关
我的任务
分享
#include <bsp.h>
#include "ADCQueuedDrv.h"
#include <windows.h>
#include <commctrl.h>
#include <s3c6410.h>
// virtual addresses
static volatile S3C6410_PWM_REG *g_pPWMRegs = NULL;
static volatile S3C6410_VIC_REG *g_pVIC0Reg = NULL;
static HANDLE g_hTimerEvent = NULL;
static DWORD g_dwTimerSysIntr = 0;
static HANDLE g_hISTThread = NULL;
static int g_nInterruptCount = 0;
static DWORD WINAPI TimerIST(PVOID lpParams);
//
// DllMain
//
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//
//
//
static void TimerInitialize()
{
OutputDebugString(_T("TimerInitialize"));
// virtual addresses mapping
PHYSICAL_ADDRESS physicalAddr;
physicalAddr.QuadPart = S3C6410_BASE_REG_PA_PWM;
g_pPWMRegs = (volatile S3C6410_PWM_REG*)MmMapIoSpace(physicalAddr, sizeof(S3C6410_PWM_REG), FALSE);
ASSERTMSG(_T("Failed to mapping PWM physical address."), g_pPWMRegs);
physicalAddr.QuadPart = S3C6410_BASE_REG_PA_VIC0;
g_pVIC0Reg = (volatile S3C6410_VIC_REG*)MmMapIoSpace(physicalAddr, sizeof(S3C6410_VIC_REG), FALSE);
ASSERTMSG(_T("Failed to mapping VIC physical address."), g_pVIC0Reg);
// g_pVIC0Reg->VICINTENABLE |= 1 << 23;
// prescaler = 1, divider = 1/4 : resolution = 8.25 Mhz (8250000)
// PCLK = 66Mhz: interval = 66000000 / 8 / 1000 = 8250
// PCLK / 8 / 1000 = 8250, 8250000 / 8250 = 1Khz
g_pPWMRegs->TCFG0 &= ~(0xff << 0);
g_pPWMRegs->TCFG0 |= (0x01 << 0);
g_pPWMRegs->TCFG1 &= ~(0x0f << 0);
g_pPWMRegs->TCFG1 |= (0x02 << 0);
g_pPWMRegs->TCNTB0 = (S3C6410_PCLK) / 8 / 1000;
g_pPWMRegs->TCMPB0 = g_pPWMRegs->TCNTB0 >> 1; // duty cycle: 50%
g_pPWMRegs->TCON &= ~(0xff << 8); // clear control bits.
g_pPWMRegs->TCON |= ((0x02 | 0x08) << 0);
UINT32 i = 100;
while(i--); // delay
g_pPWMRegs->TCON &= ~(0x02 << 8); // clear manual update bit
//create the timer event
g_hTimerEvent = CreateEvent(NULL, FALSE, FALSE, _T("TE6410_AQD_TIMER"));
ASSERTMSG(_T("Event TE6410_AQD_TIMER creation failed."), g_hTimerEvent);
// obtain sysintr values from the OAL for the timer interrupt.
DWORD dwTimerSysIRQ = IRQ_TIMER0;
BOOL bRetVal = KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwTimerSysIRQ, sizeof(DWORD), &g_dwTimerSysIntr, sizeof(DWORD), NULL);
ASSERTMSG(_T("Failed to request the timer sysintr"), bRetVal);
// initialize the interrupt.
bRetVal = InterruptInitialize(g_dwTimerSysIntr, g_hTimerEvent, NULL, 0);
ASSERTMSG(_T("Unable to initialize timer interrupt."), bRetVal);
// create the IST
g_hISTThread = CreateThread(NULL, 0, TimerIST, NULL, 0, NULL);
ASSERTMSG(_T("Unable to create timer IST."), g_hISTThread);
InterruptDone(g_dwTimerSysIntr);
// CeSetThreadPriority(g_hISTThread, 98); // 21-98
}
//
//
//
static void TimerDeinitialize()
{
OutputDebugString(_T("TimerDeinitialize"));
InterruptDisable(g_dwTimerSysIntr);
CloseHandle(g_hISTThread);
CloseHandle(g_hTimerEvent);
// virtual addresses unmapping
VirtualFree((PVOID)g_pPWMRegs, 0, MEM_RELEASE);
VirtualFree((PVOID)g_pVIC0Reg, 0, MEM_RELEASE);
}
//
//
//
static DWORD WINAPI TimerIST(PVOID lpParams)
{
OutputDebugString(_T("TimerIST"));
for (;;)
{
DWORD dwStatus = WaitForSingleObject(g_hTimerEvent, INFINITE);
// TODO: our jobs
g_nInterruptCount ++;
InterruptDone(g_dwTimerSysIntr);
}
return 1;
}
//
//
//
static void TimerStart()
{
g_pPWMRegs->TCON |= (0x01 << 0);
}
//
//
//
static void TimerStop()
{
g_pPWMRegs->TCON &= ~(0x01 << 0);
}
/**
*
*/
DWORD AQD_Init(LPCTSTR pContext, LPCVOID lpvBusContext)
{
OutputDebugString(L"AQD - AQD Init\n");
TimerInitialize();
return 1;
}
/**
*
*/
BOOL AQD_Deinit(DWORD hDeviceContext)
{
OutputDebugString(L"AQD - AQD Deinit\n");
TimerDeinitialize();
return TRUE;
}
/**
*
*/
DWORD AQD_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode)
{
return 1;
}
/**
*
*/
BOOL AQD_Close(DWORD hOpenContext)
{
OutputDebugString(L"AQD - AQD Close\n");
TimerStop();
return TRUE;
}
/**
*
*/
DWORD AQD_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)
{
if (Count < 4)
return 0;
*(DWORD*)pBuffer = g_nInterruptCount;
return 4;
}
/**
*
*/
DWORD AQD_Write(DWORD hOpenContext, LPCVOID pBuffer, DWORD Count)
{
return 1;
}
/**
*
*/
VOID AQD_PowerUp(DWORD hDeviceContext)
{
}
/**
*
*/
VOID AQD_PowerDown(DWORD hDeviceContext)
{
}
/**
*
*/
DWORD AQD_Seek(DWORD hOpenContext, long Amount, DWORD Type)
{
return 0;
}
/**
*
*/
BOOL AQD_IOControl(DWORD Handle,
DWORD dwIoControlCode,
PBYTE pInBuf,
DWORD nInBufSize,
PBYTE pOutBuf,
DWORD nOutBufSize,
PDWORD pBytesReturned)
{
switch (dwIoControlCode)
{
case IOCTL_AQD_START:
TimerStart();
break;
case IOCTL_AQD_STOP:
TimerStop();
break;
default:
break;
}
return TRUE;
}