📄 pxa27x_camera.c
字号:
{
XLLP_STATUS_T status;
EnterCriticalSection(&CameraMutex);
bDoStillCapture = FALSE;
bDoVideoCapture = TRUE;
XllpLock(I2C);
// Configure the capture format. Set the width, height, mode, and the physical addresses of the
// start of the descriptor chain.
g_HwContext.XllpCAMERA.capture_width = g_HwContext.XllpCAMERA.Video_capture_width;
g_HwContext.XllpCAMERA.capture_height = g_HwContext.XllpCAMERA.Video_capture_height;
g_HwContext.XllpCAMERA.capture_mode = XLLP_CAMERA_MODE_RECORD;
g_HwContext.XllpCAMERA.sensor_flip_mode = XLLP_CAMERA_VIDEO_FLIP_VERTICAL|
XLLP_CAMERA_VIDEO_FLIP_HORIZONTAL;
g_HwContext.XllpDMA.fifo0_descriptors_physical = VideoCaptureDescriptorPhysicalStartAddress_CH0;
g_HwContext.XllpDMA.fifo1_descriptors_physical = VideoCaptureDescriptorPhysicalStartAddress_CH1;
g_HwContext.XllpDMA.fifo2_descriptors_physical = VideoCaptureDescriptorPhysicalStartAddress_CH2;
// set capture format
status = PrvCameraSetCaptureFormat(&g_HwContext);
if (status)
{
RETAILMSG(1,(TEXT("Camera init failure inside CameraSetCaptureFormat().\r\n")));
}
XllpCameraSetInterruptMask(&g_HwContext.XllpCAMERA,
XLLP_CI_CICR0_FOM |
XLLP_CI_CICR0_EOFM |
XLLP_CI_CICR0_SOFM |
XLLP_CI_CICR0_CDM |
XLLP_CI_CICR0_QDM |
XLLP_CI_CICR0_PERRM |
XLLP_CI_CICR0_EOLM |
XLLP_CI_CICR0_FEM);
PrvStartCapture(&g_HwContext, 0, 0);
XllpUnlock(I2C);
LeaveCriticalSection(&CameraMutex);
}
void CameraStopVideoCapture()
{
EnterCriticalSection(&CameraMutex);
bDoVideoCapture = FALSE;
XllpLock(I2C);
// stop capture
g_HwContext.XllpCAMERA.camera_functions->stop_capture(&g_HwContext.XllpCAMERA);
// stop dma
PrvStopDMATransfer(&g_HwContext);
XllpUnlock(I2C);
LeaveCriticalSection(&CameraMutex);
}
void CameraCaptureStillImage()
{
XLLP_STATUS_T status;
EnterCriticalSection(&CameraMutex);
XllpLock(I2C);
// stop capture
g_HwContext.XllpCAMERA.camera_functions->stop_capture(&g_HwContext.XllpCAMERA);
// stop dma
PrvStopDMATransfer(&g_HwContext);
discardframes = 0;
// Configure the capture format. Set the width, height, mode, and the physical addresses of the
// start of the descriptor chain.
g_HwContext.XllpCAMERA.capture_width = g_HwContext.XllpCAMERA.Still_capture_width;
g_HwContext.XllpCAMERA.capture_height = g_HwContext.XllpCAMERA.Still_capture_height;
g_HwContext.XllpCAMERA.capture_mode = XLLP_CAMERA_MODE_STILL;
g_HwContext.XllpCAMERA.sensor_flip_mode = XLLP_CAMERA_VIDEO_FLIP_HORIZONTAL |
XLLP_CAMERA_STILL_FLIP_HORIZONTAL;
g_HwContext.XllpDMA.fifo0_descriptors_physical = StillCaptureDescriptorPhysicalStartAddress_CH0;
g_HwContext.XllpDMA.fifo1_descriptors_physical = StillCaptureDescriptorPhysicalStartAddress_CH1;
g_HwContext.XllpDMA.fifo2_descriptors_physical = StillCaptureDescriptorPhysicalStartAddress_CH2;
// Reset the buffer chain. The application must now resubmit all capture buffers.
bFirstVideoCaptureBufferSubmitted = FALSE;
VirtAddr_Last_Pn_CH0 = 0x0;
// set capture format
status = PrvCameraSetCaptureFormat(&g_HwContext);
if (status)
{
RETAILMSG(1,(TEXT("Camera init failure inside CameraSetCaptureFormat().\r\n")));
// return 1;
}
XllpCameraSetInterruptMask(&g_HwContext.XllpCAMERA,
XLLP_CI_CICR0_FOM |
XLLP_CI_CICR0_EOFM |
XLLP_CI_CICR0_SOFM |
XLLP_CI_CICR0_CDM |
XLLP_CI_CICR0_QDM |
XLLP_CI_CICR0_PERRM |
XLLP_CI_CICR0_EOLM |
XLLP_CI_CICR0_FEM);
bDoStillCapture = TRUE;
bDoVideoCapture = FALSE;
// Enable the still image capture sequence.
// Calling this routine once results in capture sequence that sometimes fails to interrupt
// on the end of frame.
// Calling this routine twice works around this problem - but it needs to be looked into
// to root cause the failure.
// PrvStartCapture(&g_HwContext, 0, 1);
PrvStartCapture(&g_HwContext, 0, 1);
XllpUnlock(I2C);
LeaveCriticalSection(&CameraMutex);
}
// Shut down this session of the camera driver and free all of the relevent resources allocated within.
int CameraShutdown(void)
{
XllpLock(I2C);
XllpCameraDeInit(&g_HwContext.XllpCAMERA);
// Signal the ISR thread to shutdown
SetEvent(hShutDown);
XllpUnlock(I2C);
return TRUE;
}
// A helper function that is called to configure the parameters that are later used
// to configure the capture format.
int CameraChangeCaptureFormat(void)
{
// TBD: call some real function
return TRUE;
}
// Provides a physical address for a given user mode virtual address.
BOOL getPhyAddress (DWORD * pdwVirtual, DWORD * pdwPhysical)
{
BOOL bReturnVal = TRUE;
DWORD dwPageSize = UserKInfo[KINX_PAGESIZE];
DWORD dwPageTableEntry;
DWORD dwPageTablePart;
DWORD dwOffsetInPage;
/* query the page tables */
if (LockPages (pdwVirtual, sizeof (DWORD), &dwPageTableEntry, LOCKFLAG_QUERY_ONLY) != TRUE)
{
bReturnVal = FALSE;
goto cleanAndReturn;
}
/* shift left to make into a real address */
dwPageTablePart = dwPageTableEntry << UserKInfo[KINX_PFN_SHIFT];
/* figure out the offset in the page */
dwOffsetInPage = ((DWORD) pdwVirtual) & (~UserKInfo[KINX_PFN_MASK]);
/* combine the page table part and offset to create the address */
*pdwPhysical = dwPageTablePart | dwOffsetInPage;
cleanAndReturn:
return (bReturnVal);
}
void CameraUnprepareBuffer(P_CAMERA_DMA_BUFFER_INFO pCamDmaBuf, int ucBufferType)
{
DESCRIPTOR_INFO_T *pDescriptorInfo;
pDescriptorInfo = NULL;
bDoStillCapture = FALSE;
bDoVideoCapture = FALSE;
if (pCamDmaBuf)
{
if (pCamDmaBuf->BufferID >=0 && pCamDmaBuf->BufferID < MAX_CAMERA_DMA_BUFFERS)
{
pDescriptorInfo = MasterBufferList[pCamDmaBuf->BufferID];
}
}
if (pDescriptorInfo)
{
free(pDescriptorInfo->pDescriptorBufferPhyAddress);
free(pDescriptorInfo->pDescriptorBufferVirtAddress);
free(pDescriptorInfo->pBufferPhyAddress);
free(pDescriptorInfo);
MasterBufferList[pCamDmaBuf->BufferID]= NULL;
}
if (NumBuffers > 0)
{
NumBuffers--;
}
// We are going to unprepare all Video or still buffers
// So we should initialize all related variables also
if (ucBufferType == VIDEO_CAPTURE_BUFFER)
{
VirtAddr_Last_Pn_CH0 = 0x0;
VirtAddr_Last_Pn_CH1 = 0x0;
VirtAddr_Last_Pn_CH2 = 0x0;
// Address of the last real descriptor
VirtAddr_Last_n_CH0 = 0x0;
VirtAddr_Last_n_CH1 = 0x0;
VirtAddr_Last_n_CH2 = 0x0;
// Physical address of the start of the video capture descriptor chain
VideoCaptureDescriptorPhysicalStartAddress_CH0 = 0x0;
VideoCaptureDescriptorPhysicalStartAddress_CH1 = 0x0;
VideoCaptureDescriptorPhysicalStartAddress_CH2 = 0x0;
// Set to true when the first video capture buffer has been submitted.
bFirstVideoCaptureBufferSubmitted = FALSE;
}
else
{
// Physical address of the start of the still capture descriptor chain
StillCaptureDescriptorPhysicalStartAddress_CH0 = 0x0;
StillCaptureDescriptorPhysicalStartAddress_CH1 = 0x0;
StillCaptureDescriptorPhysicalStartAddress_CH2 = 0x0;
// Set to true when the first stll image buffer has been submitted
bFirstStillBufferSubmitted = FALSE;
}
if (NumBuffers == 0)
{
if (VirtAddr_Phantom_Buffer_Base_Address)
{
free((void *)VirtAddr_Phantom_Buffer_Base_Address);
}
// Virtual address of the phantom buffer
VirtAddr_Phantom_Buffer = 0x0;
VirtAddr_Phantom_Buffer_Base_Address = 0x0;
// Physical address of the phantom buffer
PhysAddr_Phantom_Buffer = 0x0;
}
return;
}
//
// Submit a buffer to be filled by the camera DMA.
// A buffer is submitted by chaining the last buffer to this new buffer.
//
// Requires a valid FrameID, which is obtained from a successful call to PrepareBuffer().
//
void CameraSubmitBuffer(P_CAMERA_DMA_BUFFER_INFO pBufInfo, int BufferType)
{
DESCRIPTOR_INFO_T *pDescriptorInfo;
XLLP_DMAC_DESCRIPTOR_T *pXPn_CH0;
XLLP_DMAC_DESCRIPTOR_T *pXPn_CH1;
XLLP_DMAC_DESCRIPTOR_T *pXPn_CH2;
XLLP_DMAC_DESCRIPTOR_T *pXn_CH0;
XLLP_DMAC_DESCRIPTOR_T *pXn_CH1;
XLLP_DMAC_DESCRIPTOR_T *pXn_CH2;
XLLP_DMAC_DESCRIPTOR_T *pLast_Pn_CH0;
XLLP_DMAC_DESCRIPTOR_T *pLast_Pn_CH1;
XLLP_DMAC_DESCRIPTOR_T *pLast_Pn_CH2;
XLLP_DMAC_DESCRIPTOR_T *pLast_n_CH0;
XLLP_DMAC_DESCRIPTOR_T *pLast_n_CH1;
XLLP_DMAC_DESCRIPTOR_T *pLast_n_CH2;
BOOL isYUV_PLANAR;
pDescriptorInfo = NULL;
if (pBufInfo)
{
if (pBufInfo->BufferID >=0 && pBufInfo->BufferID < MAX_CAMERA_DMA_BUFFERS)
{
pDescriptorInfo = MasterBufferList[pBufInfo->BufferID];
}
}
if (pDescriptorInfo)
{
isYUV_PLANAR = (3 == pDescriptorInfo->dwPlanesNumber ? TRUE : FALSE);
// If this is the first buffer being submitted, then we want to store the physical address of the descriptor chain
// so that when we start DMA's later on, we start with _this_ buffer. All buffers submitted after this first buffer
// are chained behind this one. Therefore, this buffer is the logical choice to start with.
if (BufferType == VIDEO_CAPTURE_BUFFER)
{
if (bFirstVideoCaptureBufferSubmitted == FALSE)
{
VideoCaptureDescriptorPhysicalStartAddress_CH0 = pDescriptorInfo->pPhysAddr_X1_CH0;
VideoCaptureDescriptorPhysicalStartAddress_CH1 = pDescriptorInfo->pPhysAddr_X1_CH1;
VideoCaptureDescriptorPhysicalStartAddress_CH2 = pDescriptorInfo->pPhysAddr_X1_CH2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -