📄 ppclass.cpp
字号:
} while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IPU_FS_PROC_FLOW,
oldVal, newVal) != oldVal);
break;
case eIPU_ADC:
m_bADCDirect = TRUE;
// Compute bitmask and shifted bit value for IPU_FS_PROC_FLOW register
iMask = CSP_BITFMASK(IPU_IPU_FS_PROC_FLOW_PP_DEST_SEL);
iBitval = CSP_BITFVAL(IPU_IPU_FS_PROC_FLOW_PP_DEST_SEL,
IPU_IPU_FS_PROC_FLOW_PP_DEST_SEL_ADC_DIRECT);
// If display type is a smart display, we configure
// frame synchronization to write data to ADC
// Direct Viewfinding Channel
do
{
oldVal = INREG32(&P_IPU_REGS->IPU_FS_PROC_FLOW);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IPU_FS_PROC_FLOW,
oldVal, newVal) != oldVal);
break;
default:
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Error. Display type is neither SDC or ADC!\r\n"),
__WFUNCTION__));
return FALSE;
}
}
else
{
m_bADCDirect = FALSE;
// Compute bitmask and shifted bit value for IPU_FS_PROC_FLOW register
iMask = CSP_BITFMASK(IPU_IPU_FS_PROC_FLOW_PP_DEST_SEL);
iBitval = CSP_BITFVAL(IPU_IPU_FS_PROC_FLOW_PP_DEST_SEL,
IPU_IPU_FS_PROC_FLOW_PP_DEST_SEL_ARM);
// Direct display mode is disabled, so the destination
// should be system memory.
do
{
oldVal = INREG32(&P_IPU_REGS->IPU_FS_PROC_FLOW);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IPU_FS_PROC_FLOW,
oldVal, newVal) != oldVal);
}
channelParams.iBAM = 0;
// Pixel Burst rate always 16 unless we are using a rotation channel
// channelParams.iPixelBurstCode = IDMAC_PIXEL_BURST_CODE_16;
channelParams.iPixelBurstCode = IDMAC_PIXEL_BURST_CODE_8;
// Set viewfinding channel parameters
PpIDMACChannelConfig(PP_IC_TO_MEM_DMA_CHANNEL, &channelParams);
if (m_bFlipRot)
{
// Rotation/Flipping datapath
// First, allocate rotation buffers, if they have not been allocated,
// or if the size needs to be modified.
/*
if (!m_bRotBuffersAllocated || (m_iLastAllocatedBufferSize != iOutputBufSize))
{
pRotBufferManager->DeleteBuffers();
PpAllocateRotBuffers(PP_NUM_ROT_BUFFERS, iOutputBufSize);
}
*/
pRotBufferManager->PrintBufferInfo();
// Burst length is 8 for rotation channels
channelParams.iPixelBurstCode = IDMAC_PIXEL_BURST_CODE_8;
channelParams.iBAM = (pConfigData->flipRot.verticalFlip ? 1 : 0) |
(pConfigData->flipRot.horizontalFlip ? 1 : 0) << 1 |
(pConfigData->flipRot.rotate90 ? 1 : 0) << 2;
// Set viewfinding channel parameters (Mem->IC for rotation)
PpIDMACChannelConfig(PP_MEM_TO_IC_ROT_DMA_CHANNEL, &channelParams);
// If we are rotating, we must Reverse the width, height, and
// line stride again, back to the original output width, height,
// and stride. This way, the requested output size is
// always achieved correctly.
if (pConfigData->flipRot.rotate90)
{
tempWidth = channelParams.iWidth;
channelParams.iWidth = channelParams.iHeight;
channelParams.iHeight = tempWidth;
channelParams.iLineStride = iOutputStride;
}
channelParams.iBAM = 0;
// Set viewfinding channel parameters (IC->Mem after rotation)
PpIDMACChannelConfig(PP_IC_TO_MEM_ROT_DMA_CHANNEL, &channelParams);
}
else
{
// Delete PP buffers for rotation.
// If buffers have not yet been created, this will simply return.
/*
if (!pRotBufferManager->DeleteBuffers())
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s : Failed to delete buffers!\r\n"), __WFUNCTION__));
return FALSE;
}
*/
m_bRotBuffersAllocated = FALSE;
}
_outputDone:
PP_FUNCTION_EXIT();
return result;
}
//-----------------------------------------------------------------------------
//
// Function: PpStartChannel
//
// This function starts the postprocessing channel.
//
// Parameters:
// None.
//
// Returns:
// TRUE if success
// FALSE if failure
//
//-----------------------------------------------------------------------------
BOOL PpClass::PpStartChannel()
{
UINT32 oldVal, newVal, iMask, iBitval;
PP_FUNCTION_ENTRY();
// PP must have been configured at least once
// in order to start the channel
if (!m_bConfigured)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Error. Cannot start post-processing channel without first configuring\r\n"),
__WFUNCTION__));
return FALSE;
}
if (m_bRunning)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Viewfinding channel already running.\r\n"), __WFUNCTION__));
return TRUE;
}
m_bRestartBufferLoop = TRUE;
m_bRestartISRLoop = TRUE;
m_bRunning = TRUE;
m_iCurrentBuf = 0;
// Reset EOF event, in case stale EOF events were triggered,
// which would cause Pin to believe a frame was ready.
ResetEvent(m_hEOFEvent);
if (m_bFlipRot)
{
m_bRotRestartBufferLoop = TRUE;
// Protect access to IPU_INT_CTRL_1, IPU_CHA_DB_MODE_SEL,
// IDMAC_CHA_EN, and IC_CONF registers.
// Compute bitmask and shifted bit value for IPU_INT_CTRL_1 register
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMAIC_12)
| CSP_BITFMASK(IPU_DMA_CHA_DMAIC_2);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMAIC_12, IPU_ENABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAIC_2, IPU_ENABLE);
// Enable IPU interrupts for channel 12 (IC->Mem after rotation).
// This is the final channel in the chain, so we want this channel
// to trigger an interrupt that the camera IST will handle.
// Also Enable IPU interrupts for channel 2 (IC->Mem after PP).
// This will allow us to inform the waiting thread that
// we need a new buffer.
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);
// Compute bitmask and shifted bit value for DB mode sel register.
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMAIC_5)
| CSP_BITFMASK(IPU_DMA_CHA_DMAIC_2)
| CSP_BITFMASK(IPU_DMA_CHA_DMAIC_13)
| CSP_BITFMASK(IPU_DMA_CHA_DMAIC_12);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMAIC_5, IPU_DUB_BUF)
| CSP_BITFVAL(IPU_DMA_CHA_DMAIC_2, IPU_DUB_BUF)
| CSP_BITFVAL(IPU_DMA_CHA_DMAIC_13, IPU_DUB_BUF)
| CSP_BITFVAL(IPU_DMA_CHA_DMAIC_12, IPU_DUB_BUF);
// Set double-buffering for all channels used
do
{
oldVal = INREG32(&P_IPU_REGS->IPU_CHA_DB_MODE_SEL);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IPU_CHA_DB_MODE_SEL,
oldVal, newVal) != oldVal);
// Set current buffer bits, so that we will start on buffer 0.
SETREG32(&P_IPU_REGS->IPU_CHA_CUR_BUF,
CSP_BITFVAL(IPU_DMA_CHA_DMAIC_5, IPU_IPU_CHA_CUR_BUF_CLEAR)
| CSP_BITFVAL(IPU_DMA_CHA_DMAIC_2, IPU_IPU_CHA_CUR_BUF_CLEAR)
| CSP_BITFVAL(IPU_DMA_CHA_DMAIC_13, IPU_IPU_CHA_CUR_BUF_CLEAR)
| CSP_BITFVAL(IPU_DMA_CHA_DMAIC_12, IPU_IPU_CHA_CUR_BUF_CLEAR));
// Compute bitmask and shifted bit value for IDMAC enable register.
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMAIC_5)
| CSP_BITFMASK(IPU_DMA_CHA_DMAIC_2)
| CSP_BITFMASK(IPU_DMA_CHA_DMAIC_13)
| CSP_BITFMASK(IPU_DMA_CHA_DMAIC_12);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMAIC_5, IPU_ENABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAIC_2, IPU_ENABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAIC_13, IPU_ENABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAIC_12, IPU_ENABLE);
// Set the bits to enable the IDMAC channels.
do
{
oldVal = INREG32(&P_IPU_REGS->IDMAC_CHA_EN);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IDMAC_CHA_EN,
oldVal, newVal) != oldVal);
// Compute bitmask and shifted bit value for IC_CONF register.
iMask = CSP_BITFMASK(IPU_IC_CONF_PP_EN)
| CSP_BITFMASK(IPU_IC_CONF_PP_ROT_EN);
iBitval = CSP_BITFVAL(IPU_IC_CONF_PP_EN, IPU_IC_CONF_PP_EN_ENABLE)
| CSP_BITFVAL(IPU_IC_CONF_PP_ROT_EN, IPU_IC_CONF_PP_ROT_EN_ENABLE);
// Enable postprocessing path in IC and
// enable postprocessing for rotation path in IC.
do
{
oldVal = INREG32(&P_IPU_REGS->IC_CONF);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IC_CONF,
oldVal, newVal) != oldVal);
// If direct display mode is enabled, enable display.
if (m_bVfDirectDisplay)
{
// Enable Viewfinding in the display driver
if (ExtEscape(m_hDisplay, VF_ENABLE, 0, NULL, 0, NULL) <= 0)
{
DEBUGMSG(ZONE_ERROR, (TEXT("%s: Failed enabling display for viewfinding.\r\n"), __WFUNCTION__));
return FALSE;
}
m_bVfDisplayActive = TRUE;
}
// Set up and start buffer 0, and
// set variable m_bVfRequestSecondBuffer to ensure
// that buffer 1 is requested subsequently.
// Set next-to-fill buffer to buffer 0
m_iBufferToFill = 0;
// Fill buffer 1 after buffer 0 filled for Chan 2
m_bRequestSecondBuffer = TRUE;
// Request buffer for IDMAC Channel 1 (IC->Mem for viewfinding)
// and for Channel 11 (Mem-IC for rotation for viewfinding).
// This will attempt to set up buffer 0.
SetEvent(m_hRequestBuffer);
// Set next-to-fill buffer to buffer 0
m_iRotBufferToFill = 0;
}
else
{
// Protect access to IPU_INT_CTRL_1, IPU_CHA_DB_MODE_SEL,
// IDMAC_CHA_EN, and IC_CONF registers.
// Compute bitmask and shifted bit value for IPU_INT_CTRL_1 register
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMAIC_2);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMAIC_2, IPU_ENABLE);
// enable IPU interrupts for channel 2 (IC->Mem)
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);
// Compute bitmask and shifted bit value for DB mode sel register.
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMAIC_5)
| CSP_BITFMASK(IPU_DMA_CHA_DMAIC_2);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMAIC_5, IPU_DUB_BUF)
| CSP_BITFVAL(IPU_DMA_CHA_DMAIC_2, IPU_DUB_BUF);
// Set double-buffering for all channels used
do
{
oldVal = INREG32(&P_IPU_REGS->IPU_CHA_DB_MODE_SEL);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IPU_CHA_DB_MODE_SEL,
oldVal, newVal) != oldVal);
// Set current buffer bits, so that we will start on buffer 0.
SETREG32(&P_IPU_REGS->IPU_CHA_CUR_BUF,
CSP_BITFVAL(IPU_DMA_CHA_DMAIC_5, IPU_IPU_CHA_CUR_BUF_CLEAR)
| CSP_BITFVAL(IPU_DMA_CHA_DMAIC_2, IPU_IPU_CHA_CUR_BUF_CLEAR));
// Compute bitmask and shifted bit value for IDMAC enable register.
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMAIC_5)
| CSP_BITFMASK(IPU_DMA_CHA_DMAIC_2);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMAIC_5, IPU_ENABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAIC_2, IPU_ENABLE);
// Set the bits to enable the IDMAC channels.
do
{
oldVal = INREG32(&P_IPU_REGS->IDMAC_CHA_EN);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IDMAC_CHA_EN,
oldVal, newVal) != oldVal);
// Compute bitmask and shifted bit value for IC_CONF register.
iMask = CSP_BITFMASK(IPU_IC_CONF_PP_EN);
iBitval = CSP_BITFVAL(IPU_IC_CONF_PP_EN, IPU_IC_CONF_PP_EN_ENABLE);
// enable post-processing path in IC
do
{
oldVal = INREG32(&P_IPU_REGS->IC_CONF);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IC_CONF,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -