📄 sdc.c
字号:
// Re-enable foreground
ForegroundWindowEnable();
// Restore last active buffer to foreground
phyAddr.QuadPart = g_SDCFGBuf_Saved;
ForegroundWindowSetSrcBuffer(&phyAddr);
}
//------------------------------------------------------------------------------
//
// Function: ForegroundWindowSetOffset
//
// This function sets up the window offset for the foreground plane.
//
// Parameters:
// left
// [in] X coordinate of the foreground plane in the
// display window.
//
// top
// [in] Y coordinate of the foreground plane in the
// display window.
//
// Returns:
// None.
//------------------------------------------------------------------------------
void ForegroundWindowSetOffset(POINT *ptWinOffset)
{
// Set the top or the Y coordinate of the foreground plane
INSREG32BF(&g_pIPU->SDC_FG_POS,
IPU_SDC_FG_POS_FGYP, g_pCurrentPanel->VSTARTWIDTH + ptWinOffset->y);
// Set the left or the X coordinate of the foreground plane
INSREG32BF(&g_pIPU->SDC_FG_POS,
IPU_SDC_FG_POS_FGXP, g_pCurrentPanel->HSTARTWIDTH + ptWinOffset->x);
g_iCurrentFGXP = g_pCurrentPanel->HSTARTWIDTH + ptWinOffset->x;
}
//------------------------------------------------------------------------------
//
// Function: ForegroundWindowEnable
//
// This function enables the foreground window.
//
// Parameters:
// None.
//
// Returns:
// None.
//------------------------------------------------------------------------------
void ForegroundWindowEnable(void)
{
UINT32 oldVal, newVal, iMask, iBitval;
// If FG_EN = 1, bail out
if (EXTREG32BF(&g_pIPU->SDC_COM_CONF, IPU_SDC_COM_CONF_FG_EN) == IPU_ENABLE)
{
return;
}
// Set to double buffer mode
// Compute bitmask and shifted bit value for DB mode sel register
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMASDC_1);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMASDC_1, IPU_DUB_BUF);
// Use interlocked function to set DB Mode sel to 1.
do
{
oldVal = INREG32(&g_pIPU->IPU_CHA_DB_MODE_SEL);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange(&g_pIPU->IPU_CHA_DB_MODE_SEL,
oldVal, newVal) != oldVal);
SETREG32(&g_pIPU->IPU_CHA_CUR_BUF,
CSP_BITFVAL(IPU_DMA_CHA_DMASDC_1, IPU_IPU_CHA_CUR_BUF_CLEAR));
// Enable DMA VF Channel 1
// Compute bitmask and shifted bit value for IDMAC enable reg.
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMASDC_1);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMASDC_1, IPU_ENABLE);
// Use interlocked function to Enable DMA VF Channel 1.
do
{
oldVal = INREG32(&g_pIPU->IDMAC_CHA_EN);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange(&g_pIPU->IDMAC_CHA_EN,
oldVal, newVal) != oldVal);
// Enable VF foreground
// Compute bitmask and shifted bit value for IDMAC enable reg.
iMask = CSP_BITFMASK(IPU_SDC_COM_CONF_FG_EN);
iBitval = CSP_BITFVAL(IPU_SDC_COM_CONF_FG_EN, IPU_ENABLE);
// Use interlocked function to set FG_EN = 1 (Foreground is enabled)
do
{
oldVal = INREG32(&g_pIPU->SDC_COM_CONF);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange(&g_pIPU->SDC_COM_CONF,
oldVal, newVal) != oldVal);
return;
}
//------------------------------------------------------------------------------
//
// Function: ForegroundWindowDisable
//
// This function disables the foreground window.
//
// Parameters:
// None.
//
// Returns:
// TRUE if success; FALSE if failure.
//------------------------------------------------------------------------------
BOOL ForegroundWindowDisable(void)
{
UINT32 oldVal, newVal, iMask, iBitval;
// Set FG_EN = 0 (Foreground disable)
INSREG32BF(&g_pIPU->SDC_COM_CONF,
IPU_SDC_COM_CONF_FG_EN, IPU_DISABLE);
// Wait for the SDC Foreground DMA interrupt.
// Timeout after 25ms...with a 60Hz refresh, we should receive
// an interrupt after 18-20ms.
DisplayPlaneWaitForVSync(DisplayPlane_1, 25);
// Now, we can disable IDMAC channel.
// Set up chaining register
INSREG32BF(&g_pIPU->IPU_FS_DISP_FLOW,
IPU_IPU_FS_DISP_FLOW_SDC1_SRC_SEL, 0);
// Compute bitmask and shifted bit value for idmac register
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMASDC_1);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMASDC_1, IPU_DISABLE);
// Use interlocked function to Disable DMA SDC Channel 1.
do
{
oldVal = INREG32(&g_pIPU->IDMAC_CHA_EN);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange(&g_pIPU->IDMAC_CHA_EN,
oldVal, newVal) != oldVal);
// Return double-buffer mode to 0 so that we will restart correctly
// upon next init.
// Compute bitmask and shifted bit value for idmac register
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMASDC_1);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMASDC_1, IPU_SIG_BUF);
// Use interlocked function to set DB mode to 0.
do
{
oldVal = INREG32(&g_pIPU->IPU_CHA_DB_MODE_SEL);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange(&g_pIPU->IPU_CHA_DB_MODE_SEL,
oldVal, newVal) != oldVal);
// Set next buffer to the BUF_0 for when FG is next started.
g_iSDCFGNextBuffer = 0;
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: DisplayPlaneIsBusy
//
// This function queries whether or not the specified display
// plane is currently busy displaying data.
//
// Parameters:
// dispPlane
// [in] Specifies whether to query for the background
// (DisplayPlane_0) or foreground plane (DisplayPlane_1).
//
// Returns:
// TRUE if specified plane is busy; FALSE if not busy.
//------------------------------------------------------------------------------
BOOL DisplayPlaneIsBusy(DisplayPlane dispPlane)
{
BOOL retval = FALSE;
if (dispPlane == DisplayPlane_0)
{
// Poll Background Channel DMA channel busy bit. If bit is set,
// background window is busy.
if (EXTREG32BF(&g_pIPU->IDMAC_CHA_BUSY, IPU_DMA_CHA_DMASDC_0))
{
retval = TRUE;
}
}
else if (dispPlane == DisplayPlane_1)
{
// Poll Background Channel DMA channel busy bit. If bit is set,
// background window is busy.
if (EXTREG32BF(&g_pIPU->IDMAC_CHA_BUSY, IPU_DMA_CHA_DMASDC_1))
{
retval = TRUE;
}
}
else
{
DEBUGMSG(SDC_ERROR,
(TEXT("%s(): Invalid display plane specified.\r\n"), __WFUNCTION__));
}
return retval;
}
//------------------------------------------------------------------------------
//
// Function: DisplayPlaneWaitForNotBusy
//
// This function waits for the specified display
// plane to complete processing the current frame. If
// the plane is not busy, this function returns immediately.
//
// Parameters:
// dispPlane
// [in] Specifies whether to query for the background
// (DisplayPlane_0) or foreground plane (DisplayPlane_1).
//
// Returns:
// None.
//------------------------------------------------------------------------------
void DisplayPlaneWaitForNotBusy(DisplayPlane dispPlane)
{
DisplayPlaneWaitForVSync(dispPlane, 1000 * (1/50));
}
void VSyncInterruptEnable()
{
UINT32 oldCtrl, newCtrl, ctrlMask, ctrlBitval;
// Enable and wait for an EOF interrupt
// Compute bitmask and shifted bit value for ctrl register
ctrlMask = CSP_BITFMASK(IPU_DMA_CHA_DMASDC_0);
ctrlBitval = CSP_BITFVAL(IPU_DMA_CHA_DMASDC_0, IPU_ENABLE);
// Use interlocked function to update control registers
do
{
oldCtrl = INREG32(&g_pIPU->IPU_INT_CTRL_1);
newCtrl = (oldCtrl & (~ctrlMask)) | ctrlBitval;
} while (InterlockedTestExchange(&g_pIPU->IPU_INT_CTRL_1,
oldCtrl, newCtrl) != oldCtrl);
}
void VSyncInterruptClear()
{
// Clear status bit (write-1-to-clear) to prepare for interrupt.
OUTREG32(&g_pIPU->IPU_INT_STAT_1,
CSP_BITFVAL(IPU_DMA_CHA_DMASDC_0, 1));
}
void WaitForVSyncInterrupt()
{
WaitForSingleObject(g_hSDCBGIntrEvent, INFINITE);
}
//------------------------------------------------------------------------------
//
// Function: DisplayPlaneWaitForVSync
//
// This function waits for the specified display
// plane to complete processing the current frame
// and enter the Vertical Blanking Interval.
//
// Parameters:
// dispPlane
// [in] Specifies whether to query for the background
// (DisplayPlane_0) or foreground plane (DisplayPlane_1).
//
// timeout
// [in] Timeout period for VSync interrupt.
//
// Returns:
// None.
//------------------------------------------------------------------------------
void DisplayPlaneWaitForVSync(DisplayPlane dispPlane, UINT32 timeout)
{
UINT32 oldCtrl, newCtrl, ctrlMask, ctrlBitval;
if (dispPlane == DisplayPlane_0)
{
// Clear status bit (write-1-to-clear) to prepare
// for interrupt.
OUTREG32(&g_pIPU->IPU_INT_STAT_1,
CSP_BITFVAL(IPU_DMA_CHA_DMASDC_0, 1));
// Enable and wait for an EOF interrupt
// Compute bitmask and shifted bit value for ctrl register
ctrlMask = CSP_BITFMASK(IPU_DMA_CHA_DMASDC_0);
ctrlBitval = CSP_BITFVAL(IPU_DMA_CHA_DMASDC_0, IPU_ENABLE);
// Use interlocked function to update control registers
do
{
oldCtrl = INREG32(&g_pIPU->IPU_INT_CTRL_1);
newCtrl = (oldCtrl & (~ctrlMask)) | ctrlBitval;
} while (InterlockedTestExchange(&g_pIPU->IPU_INT_CTRL_1,
oldCtrl, newCtrl) != oldCtrl);
if (WaitForSingleObject(g_hSDCBGIntrEvent, timeout) == WAIT_TIMEOUT)
{
DEBUGMSG(SDC_ERROR,
(TEXT("%s(): Waiting for SDC BG EOF interrupt time out!\r\n"), __WFUNCTION__));
}
// We have received our interrupt, so we can clear the
// status bit (write-1-to-clear).
OUTREG32(&g_pIPU->IPU_INT_STAT_1,
CSP_BITFVAL(IPU_DMA_CHA_DMASDC_0, 1));
return;
}
else if (dispPlane == DisplayPlane_1)
{
// Clear status bit (write-1-to-clear) to prepare
// for interrupt.
OUTREG32(&g_pIPU->IPU_INT_STAT_1,
CSP_BITFVAL(IPU_DMA_CHA_DMASDC_0, 1))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -