📄 gptpdd.cpp
字号:
//-----------------------------------------------------------------------------
//
// Copyright (C) 2004, Motorola Inc. All Rights Reserved
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004-2006, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//-----------------------------------------------------------------------------
//
// File: gptpdd.c
//
// Implementation of General Purpose Timer Driver
//
//-----------------------------------------------------------------------------
#include <windows.h>
#include <nkintr.h>
#include <ceddk.h>
#include "csp.h"
#include "gpt.h"
#include "gpt_priv.h"
//-----------------------------------------------------------------------------
// External Functions
extern UINT32 BSPGptGetClockSource();
extern UINT32 BSPGptGetPERCLK1();
extern UINT32 BSPGptGet32kHzRefFreq();
extern BOOL BSPGptSetClockGatingMode(DWORD, BOOL);
//-----------------------------------------------------------------------------
// External Variables
//-----------------------------------------------------------------------------
// Defines
#define GPT_PRESCALER_VAL 0 // No prescaling
#define THREAD_PRIORITY 250
//-----------------------------------------------------------------------------
//
// Function: GptInitialize
//
// This function will call the PMU function to enable the timer source
// clock and create the timer irq event and create the IST thread.
//
// Parameters:
// dwIOBase
// [in] Physical IOBase address of the GPT device
//
// dwIOLen
// [in] Physical IOLen of the GPT device
//
// dwIRQ
// [in] Physical IRQ number of the GPT device
//
// Returns:
// TRUE - If success
//
// FALSE - If failure
//
//-----------------------------------------------------------------------------
BOOL gptClass::GptInitialize(DWORD dwIOBase, DWORD dwIOLen, DWORD dwIRQ)
{
PHYSICAL_ADDRESS phyAddr;
DWORD gptIrq = dwIRQ;
GPT_FUNCTION_ENTRY();
phyAddr.QuadPart = dwIOBase;
m_pGPT = (PCSP_GPT_REGS) MmMapIoSpace(phyAddr, sizeof(CSP_GPT_REGS), FALSE);
// check if Map Virtual Address failed
if (m_pGPT == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: MmMapIoSpace failed!\r\n"), __WFUNCTION__));
return FALSE;
}
m_dwIOBase = dwIOBase;
DEBUGMSG(ZONE_INFO, (TEXT("%s: CreateEvent\r\n"), __WFUNCTION__));
m_hGptIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (m_hGptIntrEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
// Translate IRQ to SYSINTR
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &gptIrq, sizeof(gptIrq),
&m_gptIntr, sizeof(m_gptIntr), NULL))
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Request SYSINTR failed\r\n"), __WFUNCTION__));
goto Error;
}
if(!InterruptInitialize(m_gptIntr, m_hGptIntrEvent, NULL, 0))
{
CloseHandle(m_hGptIntrEvent);
m_hGptIntrEvent = NULL;
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Interrupt initialization failed! \r\n"), __WFUNCTION__));
goto Error;
}
// Initialize critical section for GPT
InitializeCriticalSection(&m_GptCS);
if (!(m_hTimerThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)GptIntrThread, this, 0, NULL)))
{
DEBUGMSG(ZONE_ERROR,(TEXT("%s: CreateThread failed!\r\n"), __WFUNCTION__));
return 0;
}
else
{
DEBUGMSG(ZONE_INFO, (TEXT("%s: create timer thread success\r\n"), __WFUNCTION__));
// Set our interrupt thread's priority
CeSetThreadPriority(m_hTimerThread, THREAD_PRIORITY);
}
// Set initial state for GPT registers
GptRegInit();
GptStatus();
GPT_FUNCTION_EXIT();
return TRUE;
Error:
GptRelease();
return FALSE;
}
//------------------------------------------------------------------------------
//
// Function: GptRelease
//
// This function will release all resources and terminate the IST thread.
//
// Parameters:
// None
//
// Returns:
// None
//
//------------------------------------------------------------------------------
void gptClass::GptRelease()
{
GPT_FUNCTION_ENTRY();
GptStopTimer();
GptDisableTimerInterrupt();
// Also set the clock gating mode to minimize power consumption when the
// GPT is no longer being used.
BSPGptSetClockGatingMode(m_dwIOBase, FALSE);
// Release SYSINTR
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &m_gptIntr, sizeof(DWORD), NULL, 0, NULL);
m_gptIntr = SYSINTR_UNDEFINED;
// deregister the system interrupt
if (m_gptIntr != SYSINTR_UNDEFINED)
{
InterruptDisable(m_gptIntr);
m_gptIntr = SYSINTR_UNDEFINED;
}
if (m_hGptIntrEvent)
{
CloseHandle(m_hGptIntrEvent);
m_hGptIntrEvent = NULL;
}
if (m_hTimerEvent)
{
CloseHandle(m_hTimerEvent);
m_hTimerEvent = NULL;
}
if (m_hTimerThread)
{
CloseHandle(m_hTimerThread);
m_hTimerThread = NULL;
}
// Delete GPT critical section
DeleteCriticalSection(&m_GptCS);
GPT_FUNCTION_EXIT();
return;
}
//------------------------------------------------------------------------------
//
// Function: GptTimerCreateEvent
//
// This function is used to create a GPT timer event handle
// triggered in the GPT ISR.
//
// Parameters:
// None
//
// Returns:
// TRUE if success
// FALSE if handle creation fails or if event
// hasn't already been created by caller
//
//------------------------------------------------------------------------------
BOOL gptClass::GptTimerCreateEvent(LPTSTR eventString)
{
GPT_FUNCTION_ENTRY();
m_hTimerEvent = CreateEvent(NULL, FALSE, FALSE, eventString);
if ((m_hTimerEvent == NULL) || (GetLastError() != ERROR_ALREADY_EXISTS))
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed or event does not already exist\r\n"), __WFUNCTION__));
return FALSE;
}
m_TimerEventString = eventString;
GPT_FUNCTION_EXIT();
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: GptTimerReleaseEvent
//
// This function is used to close the handle to the
// GPT timer event.
//
// Parameters:
// None
//
// Returns:
// TRUE if success
// FALSE if string name does not match
//
//------------------------------------------------------------------------------
BOOL gptClass::GptTimerReleaseEvent(LPTSTR eventString)
{
GPT_FUNCTION_ENTRY();
if (strcmp((const char *) m_TimerEventString, (const char *) eventString) != 0)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Cannot close GPT timer event handle: Wrong event string name.\r\n"), __WFUNCTION__));
return FALSE;
}
CloseHandle(m_hTimerEvent);
GPT_FUNCTION_EXIT();
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: GptStartTimer
//
// This function is used to start the timer. It will set the enable
// bit in the GPT control register. This function should be called to
// enable the timer after configuring the timer.
//
// Parameters:
// None
//
// Returns:
// TRUE if success. FALSE if timer has not been set.
//
//------------------------------------------------------------------------------
BOOL gptClass::GptStartTimer(void)
{
GPT_FUNCTION_ENTRY();
EnterCriticalSection(&m_GptCS);
if (INREG32(&m_pGPT->TCMP) == 0xFFFFFFFF)
{
DEBUGMSG (ZONE_ERROR, (TEXT("%s: Timer period has not been set. Cannot start timer.\r\n"), __WFUNCTION__));
LeaveCriticalSection(&m_GptCS);
return FALSE;
}
INSREG32BF(&m_pGPT->TCTL, GPT_TCTL_TEN, GPT_TCTL_TEN_ENABLE);
INSREG32BF(&m_pGPT->TCTL, GPT_TCTL_COMPEN, GPT_TCTL_COMPEN_ENABLE);
LeaveCriticalSection(&m_GptCS);
GPT_FUNCTION_EXIT();
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: GptStopTimer
//
// This function is used to stop the timer. It will
// clear the enable bit in the GPT control register.
// After this, the counter will reset to 0x00000000.
//
// Parameters:
// None
//
// Returns:
// None
//
//------------------------------------------------------------------------------
void gptClass::GptStopTimer(void)
{
GPT_FUNCTION_ENTRY();
EnterCriticalSection(&m_GptCS);
INSREG32BF(&m_pGPT->TCTL, GPT_TCTL_TEN, GPT_TCTL_TEN_DISABLE);
INSREG32BF(&m_pGPT->TCTL, GPT_TCTL_COMPEN, GPT_TCTL_COMPEN_DISABLE);
LeaveCriticalSection(&m_GptCS);
GPT_FUNCTION_EXIT();
}
//------------------------------------------------------------------------------
//
// Function: GptEnableTimerInterrupt
//
// This function is used to enable the timer interrupt.
//
// Parameters:
// None
//
// Returns:
// None
//
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -