📄 gptpdd.cpp
字号:
void gptClass::GptEnableTimerInterrupt(void)
{
GPT_FUNCTION_ENTRY();
EnterCriticalSection(&m_GptCS);
INSREG32BF(&m_pGPT->TCTL, GPT_TCTL_COMPEN, GPT_TCTL_COMPEN_ENABLE);
LeaveCriticalSection(&m_GptCS);
GPT_FUNCTION_EXIT();
}
//------------------------------------------------------------------------------
//
// Function: GptDisableTimerInterrupt
//
// This function is used to disable the timer interrupt.
//
// Parameters:
// None
//
// Returns:
// None
//
//------------------------------------------------------------------------------
void gptClass::GptDisableTimerInterrupt(void)
{
GPT_FUNCTION_ENTRY();
EnterCriticalSection(&m_GptCS);
INSREG32BF(&m_pGPT->TCTL, GPT_TCTL_COMPEN, GPT_TCTL_COMPEN_DISABLE);
LeaveCriticalSection(&m_GptCS);
GPT_FUNCTION_EXIT();
}
//------------------------------------------------------------------------------
//
// Function: GptSetTimerDelay
//
// This function is used to configure the timer and
// set the timer for some period delay.
//
// Parameters:
// timerMode
// [in] This parametor is used to set the timer mode.
// Set to timerModePeriodic for periodic mode, and
// timerModeFreeRunning for free running mode.
//
// period
// [in] This parameter is the period in milliseconds.
//
// Returns:
// TRUE - If success.
//
// FALSE - If the timer is not allocated.
//
//------------------------------------------------------------------------------
BOOL gptClass::GptSetTimerDelay(PGPT_TIMER_SET_PKT pSetTimerPkt)
{
UINT16 prescaler = 0;
UINT32 freq;
UINT32 div;
BOOL done;
timerMode_c timerMode = pSetTimerPkt->timerMode;
timerPeriodType_c periodType = pSetTimerPkt->periodType;
UINT32 period = pSetTimerPkt->period;
GPT_FUNCTION_ENTRY();
EnterCriticalSection(&m_GptCS);
//Stop timer to set delay
GptStopTimer();
// Write 1 to clear
m_pGPT->TSTAT = 1;
done = FALSE;
switch (periodType)
{
case MICROSEC:
// Use perclk1 clock for periods in usec
INSREG32BF(&m_pGPT->TCTL, GPT_TCTL_CLKSOURCE, GPT_TCTL_CLKSOURCE_PERCLK1);
freq = BSPGptGetPERCLK1();
for(prescaler = 0; prescaler <= CSP_BITFMASK(GPT_TPRER_PRESCALER); prescaler++)
{
if( (UINT64)((freq / (prescaler + 1) / 1000000) * period) < GPT_TCN_COUNT_MAX )
{
m_pGPT->TCMP = freq / (prescaler + 1) / 1000000 * period;
done = TRUE;
break;
}
}
if(done)
break;
// else fall thru
case MILLISEC:
// Use perclk1/4 clock for periods in msec
INSREG32BF(&m_pGPT->TCTL, GPT_TCTL_CLKSOURCE, GPT_TCTL_CLKSOURCE_PERCLK1DIV4);
freq = BSPGptGetPERCLK1() / 4;
if(periodType == MICROSEC) div = 1000000;
if(periodType == MILLISEC) div = 1000;
for(prescaler = 0; prescaler <= CSP_BITFMASK(GPT_TPRER_PRESCALER); prescaler++)
{
if( (UINT64)((freq / (prescaler + 1) / div) * period) < GPT_TCN_COUNT_MAX )
{
m_pGPT->TCMP = freq / (prescaler + 1) / div * period;
done = TRUE;
break;
}
}
if(done)
break;
// else fall thru
case SECOND:
// Use 32k ref clock for periods in seconds
INSREG32BF(&m_pGPT->TCTL, GPT_TCTL_CLKSOURCE, GPT_TCTL_CLKSOURCE_32KCLK);
freq = BSPGptGet32kHzRefFreq();
if(periodType == MICROSEC) div = 1000000;
if(periodType == MILLISEC) div = 1000;
if(periodType == SECOND) div = 1;
for(prescaler = 0; prescaler <= CSP_BITFMASK(GPT_TPRER_PRESCALER); prescaler++)
{
if( (UINT64)((freq / (prescaler + 1) / div) * period) < GPT_TCN_COUNT_MAX )
{
m_pGPT->TCMP = freq / (prescaler + 1) / div * period;
done = TRUE;
break;
}
}
if(done)
break;
else
{
DEBUGMSG(ZONE_ERROR, (TEXT("TimerClass: Unable to support requested delay!\r\n")));
return FALSE;
}
default:
DEBUGMSG(ZONE_ERROR, (TEXT("TimerClass: Invalid period type!\r\n")));
return FALSE;
}
m_pGPT->TPRER = prescaler;
if (timerMode == timerModeFreeRunning)
m_pGPT->TCTL |= CSP_BITFMASK(GPT_TCTL_FRR);
else if(timerMode == timerModePeriodic)
m_pGPT->TCTL &= ~CSP_BITFMASK(GPT_TCTL_FRR);
LeaveCriticalSection(&m_GptCS);
GptStatus();
GPT_FUNCTION_EXIT();
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: GptClearInterruptStatus
//
// This function is used to clear the GPT interrupt status and signal to the
// kernel that interrupt processing is completed.
//
// Parameters:
// None
//
// Returns:
// None
//
//------------------------------------------------------------------------------
void gptClass::GptClearInterruptStatus(void)
{
GPT_FUNCTION_ENTRY();
EnterCriticalSection(&m_GptCS);
// Clear Interrupt Status Bits
INSREG32BF(&m_pGPT->TSTAT, GPT_TSTAT_COMP, GPT_TSTAT_COMP_RESET);
LeaveCriticalSection(&m_GptCS);
// Kernel call to unmask the interrupt so that it can be signalled again
InterruptDone(m_gptIntr);
GPT_FUNCTION_EXIT();
}
//------------------------------------------------------------------------------
//
// Function: GptRegInit
//
// Set GPT registers to initial state.
//
// Parameters:
// None.
//
// Returns:
// None
//
//------------------------------------------------------------------------------
void gptClass::GptRegInit()
{
UINT32 clkSrc;
GPT_FUNCTION_ENTRY();
EnterCriticalSection(&m_GptCS);
// Must configure the clock gating mode before trying to access the GPT
// control registers. Otherwise, we will hang here when the driver is
// loaded during system boot.
BSPGptSetClockGatingMode(m_dwIOBase, TRUE);
// Disable GPT and clear all configuration bits
OUTREG32(&m_pGPT->TCTL, 0);
// Reset timer
OUTREG32(&m_pGPT->TCTL, CSP_BITFMASK(GPT_TCTL_SWR));
// Wait for the software reset to complete
while (INREG32(&m_pGPT->TCTL) & CSP_BITFMASK(GPT_TCTL_SWR));
// Get BSP-specific clock source
clkSrc = BSPGptGetClockSource();
m_pGPT->TPRER = 0;
m_pGPT->TCMP = 0xFFFFFFFF;
OUTREG32(&m_pGPT->TCTL,
CSP_BITFVAL(GPT_TCTL_TEN, GPT_TCTL_TEN_DISABLE) |
CSP_BITFVAL(GPT_TCTL_CLKSOURCE, clkSrc) |
CSP_BITFVAL(GPT_TCTL_COMPEN, GPT_TCTL_COMPEN_DISABLE) |
CSP_BITFVAL(GPT_TCTL_CAPTEN, GPT_TCTL_CAPTEN_DISABLE) |
CSP_BITFVAL(GPT_TCTL_CAP, GPT_TCTL_CAP_DISABLE) |
CSP_BITFVAL(GPT_TCTL_FRR, GPT_TCTL_FRR_FREERUN) |
CSP_BITFVAL(GPT_TCTL_OM, GPT_TCTL_OM_ACTIVELOW) |
CSP_BITFVAL(GPT_TCTL_CC, GPT_TCTL_CC_ENABLE));
LeaveCriticalSection(&m_GptCS);
GPT_FUNCTION_EXIT();
}
//------------------------------------------------------------------------------
//
// Function: GptIntrThread
//
// This function is the IST thread.
//
// Parameters:
// None
//
// Returns:
// None
//
//------------------------------------------------------------------------------
void gptClass::GptIntrThread(LPVOID lpParameter)
{
gptClass *pGpt = (gptClass *)lpParameter;
GPT_FUNCTION_ENTRY();
pGpt->GptISRLoop(INFINITE);
GPT_FUNCTION_ENTRY();
return;
}
//------------------------------------------------------------------------------
//
// Function: GptISRLoop
//
// This function is the interrupt handler for the GPT.
// It waits for the GPT interrupt event, and signals
// the timer registered by the user of this timer.
//
// Parameters:
// timeout
// [in] Timeout value while waiting for GPT timer interrupt.
//
// Returns:
// None
//
//------------------------------------------------------------------------------
void gptClass::GptISRLoop(UINT32 timeout)
{
GPT_FUNCTION_ENTRY();
// loop here
while(TRUE)
{
DEBUGMSG (ZONE_INFO, (TEXT("%s: In the loop\r\n"), __WFUNCTION__));
if (WaitForSingleObject(m_hGptIntrEvent, timeout) == WAIT_OBJECT_0)
{
DEBUGMSG (ZONE_INFO, (TEXT("%s: Interrupt received\r\n"), __WFUNCTION__));
if (m_hTimerEvent)
{
// Trigger timer event
SetEvent(m_hTimerEvent);
}
}
else
{
// Timeout as requested
DEBUGMSG (ZONE_INFO, (TEXT("%s: Time out\r\n"), __WFUNCTION__));
}
// Clear interrupt bits
GptClearInterruptStatus();
}
GPT_FUNCTION_ENTRY();
return;
}
//------------------------------------------------------------------------------
//
// Function: GptStatus
//
// This function is used to print out the GPT register status.
//
// Parameters:
// None
//
// Returns:
// None
//
//------------------------------------------------------------------------------
void gptClass::GptStatus(void)
{
DEBUGMSG (ZONE_INFO, (TEXT("ctrl: %x prescaler: %x compare: %x status: %x cnt: %x\r\n"),
INREG32(&m_pGPT->TCTL),
INREG32(&m_pGPT->TPRER),
INREG32(&m_pGPT->TCMP),
INREG32(&m_pGPT->TSTAT),
INREG32(&m_pGPT->TCN)));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -