📄 pfclass.cpp
字号:
writeDMAChannelParam(ch, 0, 1, 1<<14); //Variable data set to 0. NSB set 63-32
writeDMAChannelParam(ch, 0, 2, 0); //Variable data set to 0. 95-64
writeDMAChannelParam(ch, 0, 3, ((pChannelParams->iWidth-1) << 12) |
((pChannelParams->iHeight-1) << 24)); // 127-96
writeDMAChannelParam(ch, 0, 4, ((pChannelParams->iHeight-1) >> 8)); // 160-128
// Notice we do not write row 1, words 0 or 1, as these
// words control the DMA channel buffers. This data
// is written when PfStartChannel is called.
writeDMAChannelParam(ch, 1, 2,
((pChannelParams->iBitsPerPixelCode) |
((pChannelParams->iLineStride - 1)<<3) |
(pChannelParams->iFormatCode<<17) |
(pChannelParams->iPixelBurstCode<<25))); // 95-64
writeDMAChannelParam(ch, 1, 3, 2); // SAT code of 0x10 = 32 bit memory access
// Cede control of IPU_IMA registers by writing 0 to IPU_IMA_ADDR
OUTREG32(&P_IPU_REGS->IPU_IMA_ADDR, 0);
PF_FUNCTION_EXIT();
return;
}
//-----------------------------------------------------------------------------
//
// Function: PfEnable
//
// Enable the Image Converter and the IDMAC channels we will need.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
void PfClass::PfEnable(void)
{
UINT32 oldVal, newVal, iMask, iBitval;
PF_FUNCTION_ENTRY();
// Protect access to IPU_CONF register.
// Set the bit to enable the PF.
// Compute bitmask and shifted bit value for IPU_CONF register
iMask = CSP_BITFMASK(IPU_IPU_CONF_PF_EN);
iBitval = CSP_BITFVAL(IPU_IPU_CONF_PF_EN, IPU_IPU_CONF_PF_EN_ENABLE);
// Use interlocked function to enable the PF.
do
{
oldVal = INREG32(&P_IPU_REGS->IPU_CONF);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IPU_CONF,
oldVal, newVal) != oldVal);
dumpIpuRegisters(P_IPU_REGS);
PF_FUNCTION_EXIT();
}
//-----------------------------------------------------------------------------
//
// Function: PfDisable
//
// Disable the Post-filtering unit.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
void PfClass::PfDisable(void)
{
UINT32 oldVal, newVal, iMask, iBitval;
PF_FUNCTION_ENTRY();
// Protect access to IPU_CONF register.
// Set the bit to disable the PF.
// Compute bitmask and shifted bit value for IPU_CONF register
iMask = CSP_BITFMASK(IPU_IPU_CONF_PF_EN);
iBitval = CSP_BITFVAL(IPU_IPU_CONF_PF_EN, IPU_IPU_CONF_PF_EN_DISABLE);
// Use interlocked function to disable PF.
do
{
oldVal = INREG32(&P_IPU_REGS->IPU_CONF);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IPU_CONF,
oldVal, newVal) != oldVal);
PF_FUNCTION_EXIT();
}
//------------------------------------------------------------------------------
//
// Function: PfClearInterruptStatus
//
// This function is used to clear the PF interrupt status and signal to the
// kernel that interrupt processing is completed.
//
// Parameters:
// clearBitmask
// [in] Mask of bits in status register to clear
//
// Returns:
// None
//
//------------------------------------------------------------------------------
void PfClass::PfClearInterruptStatus(DWORD clearBitmask)
{
PF_FUNCTION_ENTRY();
// Clear Interrupt Status Bits
OUTREG32(&P_IPU_REGS->IPU_INT_STAT_1, clearBitmask);
PF_FUNCTION_EXIT();
}
//------------------------------------------------------------------------------
//
// Function: PfIntrThread
//
// This function is the IST thread.
//
// Parameters:
// None
//
// Returns:
// None
//
//---------------------------------------------------------------------
void PfClass::PfIntrThread(LPVOID lpParameter)
{
PfClass *pPf = (PfClass *)lpParameter;
PF_FUNCTION_ENTRY();
pPf->PfISRLoop(INFINITE);
PF_FUNCTION_EXIT();
}
//------------------------------------------------------------------------------
//
// Function: PfISRLoop
//
// This function is the interrupt handler for the Post-filterer.
// It waits for the End-Of-Frame (EOF) interrupt, and signals
// the EOF event registered by the user of the post-filterer.
//
// Parameters:
// timeout
// [in] Timeout value while waiting for EOF interrupt.
//
// Returns:
// None
//
//---------------------------------------------------------------------
void PfClass::PfISRLoop(UINT32 timeout)
{
DWORD statReg1, chanMask;
DWORD dwIntrCnt = 0;
UINT32 oldVal, newVal, iMask, iBitval;
PF_FUNCTION_ENTRY();
// loop here
while(TRUE)
{
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: In the loop\r\n"), __WFUNCTION__));
if (WaitForSingleObject(m_hPfIntrEvent, timeout) == WAIT_OBJECT_0)
{
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: Interrupt received\r\n"), __WFUNCTION__));
statReg1 = INREG32(&P_IPU_REGS->IPU_INT_STAT_1);
//dumpInterruptRegisters(P_IPU_REGS);
if (statReg1 & 0xE0000000) // check PF channel status bits only
{
// EOF for Post-processor
DEBUGMSG (ZONE_DEVICE, (TEXT("%s:*** Post-filtering End of frame interrupt ***\r\n"), __WFUNCTION__));
if (!m_bRunning)
{
// Don't do anything else. We do not want to re-enable
// the buffer ready bits since we are stopping.
dwIntrCnt = 0;
}
else
{
// Determine which channels have completed
// Check Y Output Channel
chanMask = 0x20000000;
if ((statReg1 & chanMask) & chanMask)
{
// Y output channel completed
dwIntrCnt++;
PfClearInterruptStatus(chanMask);
}
// Check U Output Channel
chanMask = 0x40000000;
if ((statReg1 & chanMask) & chanMask)
{
// U output channel completed
dwIntrCnt++;
PfClearInterruptStatus(chanMask);
}
// Check V Output Channel
chanMask = 0x80000000;
if ((statReg1 & chanMask) & chanMask)
{
// V output channel completed
dwIntrCnt++;
PfClearInterruptStatus(chanMask);
}
// PF operation is only done if we have received
// 3 interrupts (Y, U, and V output channels)
if (dwIntrCnt > 2)
{
// Clear all PF-related Status bits
chanMask = 0xE0000000;
PfClearInterruptStatus(chanMask);
if (!PfStopChannel())
{
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: Could not properly stop PF channel!\r\n"), __WFUNCTION__));
}
// Trigger PF EOF event
SetEvent(m_hEOFEvent);
dwIntrCnt = 0;
}
else
{
// Re-enable interrupt control bits so
// that we can continue to receive PF interrupts.
// Protect access to IPU_INT_CTRL_1 register.
// Compute bitmask and shifted bit value for IPU_INT_CTRL_1 register
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMAPF_5)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_6)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_7);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMAPF_5, IPU_ENABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_6, IPU_ENABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_7, IPU_ENABLE);
// enable IPU interrupts for channels 29, 30, 31 (PF Y, U, and V Output)
do
{
oldVal = INREG32(&P_IPU_REGS->IPU_INT_CTRL_1);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IPU_INT_CTRL_1,
oldVal, newVal) != oldVal);
}
}
}
if (INREG32(&P_IPU_REGS->IPU_INT_STAT_5) & 0xFFFF)
{
// TODO: Properly Handle Error Cases
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: Error Interrupt received!\r\n"), __WFUNCTION__));
if (INREG32(&P_IPU_REGS->IPU_INT_STAT_5) & 0x3800)
{
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: Frame Lost.\r\n"), __WFUNCTION__));
// Clear frame drop interrupt registers
OUTREG32(&P_IPU_REGS->IPU_INT_STAT_5, 0x3800);
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: Cleared INT_STAT_5: %x\r\n"),
__WFUNCTION__, INREG32(&P_IPU_REGS->IPU_INT_STAT_5)));
}
else
{
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: Other error.\r\n"), __WFUNCTION__));
}
}
}
else
{
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: Time out\r\n"), __WFUNCTION__));
}
}
PF_FUNCTION_EXIT();
return;
}
//------------------------------------------------------------------------------
//
// Function: dumpChannelParams
//
//
//
// Parameters:
// None
//
// Returns:
// None
//
//---------------------------------------------------------------------
static void dumpChannelParams(pPfIDMACChannelParams pChannelParams)
{
DEBUGMSG (ZONE_DEVICE, (TEXT("Width = %x\r\n"), pChannelParams->iWidth));
DEBUGMSG (ZONE_DEVICE, (TEXT("Height = %x\r\n"), pChannelParams->iHeight));
DEBUGMSG (ZONE_DEVICE, (TEXT("BPP Code = %x\r\n"), pChannelParams->iBitsPerPixelCode));
DEBUGMSG (ZONE_DEVICE, (TEXT("Line Stride = %x\r\n"), pChannelParams->iLineStride));
DEBUGMSG (ZONE_DEVICE, (TEXT("Format Code = %x\r\n"), pChannelParams->iFormatCode));
DEBUGMSG (ZONE_DEVICE, (TEXT("Pixel Burst = %x\r\n"), pChannelParams->iPixelBurstCode));
return;
}
//------------------------------------------------------------------------------
//
// Function: dumpInterruptRegisters
//
//
//
// Parameters:
// None
//
// Returns:
// None
//
//---------------------------------------------------------------------
static void dumpInterruptRegisters(PCSP_IPU_REGS pIPU)
{
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_1: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_1)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_2: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_2)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_3: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_3)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_4: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_4)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_5: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_5)));
return;
}
//------------------------------------------------------------------------------
//
// Function: dumpIpuRegisters
//
//
//
// Parameters:
// None
//
// Returns:
// None
//
//---------------------------------------------------------------------
static void dumpIpuRegisters(PCSP_IPU_REGS pIPU)
{
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_CONF: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_CONF)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_CHA_BUF0_RDY: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_CHA_BUF0_RDY)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_CHA_BUF1_RDY: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_CHA_BUF1_RDY)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_CHA_DB_MODE_SEL: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_CHA_DB_MODE_SEL)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_CHA_CUR_BUF: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_CHA_CUR_BUF)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_FS_PROC_FLOW: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_FS_PROC_FLOW)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_FS_DISP_FLOW: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_FS_DISP_FLOW)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_TASK_STAT: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_TASK_STAT)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_CTRL_1: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_CTRL_1)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_1: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_1)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_2: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_2)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_3: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_3)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IPU_INT_STAT_5: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IPU_INT_STAT_5)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: PF_CONF: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->PF_CONF)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: SDC_COM_CONF: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->SDC_COM_CONF)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: SDC_FG_POS: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->SDC_FG_POS)));
DEBUGMSG (ZONE_DEVICE, (TEXT("%s: IDMAC_CHA_BUSY: %x\r\n"), __WFUNCTION__, INREG32(&pIPU->IDMAC_CHA_BUSY)));
}
static void ReadVfDMA(PCSP_IPU_REGS pIPU)
{
int i;
UINT32 data;
// Software-controlled access to IMA registers
// IMA registers may only be accessed if IMA_ADDR is
// set to 0.
while (1)
{
if (INREG32(&pIPU->IPU_IMA_ADDR) == 0)
{
// Try to set IPU_IMA registers.
if (InterlockedTestExchange((LPLONG)&pIPU->IPU_IMA_ADDR, 0, 1) == 0)
{
// Successfully set IMA_ADDR.
break;
}
}
// IPU_IMA controlled by another process.
// Surrender CPU and then try again.
Sleep(0);
}
OUTREG32(&pIPU->IPU_IMA_ADDR,
CSP_BITFVAL( IPU_IPU_IMA_ADDR_MEM_NU, IPU_IMA_ADDR_MEM_NU_CPM) |
CSP_BITFVAL( IPU_IPU_IMA_ADDR_ROW_NU, 2)|
CSP_BITFVAL( IPU_IPU_IMA_ADDR_WORD_NU, 0));
for (i = 0; i < 132; i += 32)
{
data = INREG32(&pIPU->IPU_IMA_DATA);
DEBUGMSG(ZONE_ERROR,
(TEXT("%s(): Word0, bits %d - %d: %x\r\n"), __WFUNCTION__, i, i+32, data));
}
OUTREG32(&pIPU->IPU_IMA_ADDR,
CSP_BITFVAL( IPU_IPU_IMA_ADDR_MEM_NU, IPU_IMA_ADDR_MEM_NU_CPM) |
CSP_BITFVAL( IPU_IPU_IMA_ADDR_ROW_NU, 3)|
CSP_BITFVAL( IPU_IPU_IMA_ADDR_WORD_NU, 0));
for (i = 0; i < 132; i += 32)
{
data = INREG32(&pIPU->IPU_IMA_DATA);
DEBUGMSG(ZONE_ERROR,
(TEXT("%s(): Word1, bits %d - %d: %x\r\n"), __WFUNCTION__, i, i+32, data));
}
// Cede control of IPU_IMA registers by writing 0 to IPU_IMA_ADDR
OUTREG32(&pIPU->IPU_IMA_ADDR, 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -