📄 xllp_camera.c
字号:
status = PrvStartCapture( camera_context, block_id, 1 );
return status;
}
// capture motion video and copy it to the ring buffer
XLLP_STATUS_T XllpCameraStartVideoCapture( P_XLLP_Camera_Context_T camera_context, unsigned int block_id )
{
XLLP_STATUS_T status;
// init buffer status & capture
camera_context->block_header = camera_context->block_tail = block_id;
camera_context->capture_status = XLLP_CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS;
status = PrvStartCapture( camera_context, block_id, 0 );
return status;
}
// disable motion video image capture
void XllpCameraStopVideoCapture( P_XLLP_Camera_Context_T camera_context )
{
XLLP_STATUS_T status;
// stop capture
status = camera_context->camera_functions->stop_capture(camera_context);
// stop dma
PrvStopDMATransfer(camera_context);
// update the flag
if ( !(camera_context->capture_status & XLLP_CAMERA_STATUS_RING_BUFFER_FULL) )
camera_context->capture_status &= ~XLLP_CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS;
return;
}
/***********************************************************************
*
* Flow Control APIs
*
***********************************************************************/
// continue capture image to next available buffer
void XllpCameraContinueTransfer( P_XLLP_Camera_Context_T camera_context )
{
// don't think we need this either. JR
// continue transfer on next block
PrvStartDMATransfer( camera_context, camera_context->block_tail );
}
// Return 1: there is available buffer, 0: buffer is full
int XllpCameraNextBufferAvailable( P_XLLP_Camera_Context_T camera_context )
{
camera_context->block_header = (camera_context->block_header + 1) % camera_context->block_number;
if (((camera_context->block_header + 1) % camera_context->block_number) != camera_context->block_tail)
{
return 1;
}
camera_context->capture_status |= XLLP_CAMERA_STATUS_RING_BUFFER_FULL;
return 0;
}
// Application supplies the FrameBufferID to the driver to tell it that the application has completed processing of the given frame buffer, and that buffer is now available for re-use.
void XllpCameraReleaseFrameBuffer( P_XLLP_Camera_Context_T camera_context, unsigned int frame_buffer_id )
{
camera_context->block_tail = (camera_context->block_tail + 1) % camera_context->block_number;
// restart video capture only if video capture is in progress and space is available for image capture
if( (camera_context->capture_status & XLLP_CAMERA_STATUS_RING_BUFFER_FULL ) &&
(camera_context->capture_status & XLLP_CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS))
{
if (((camera_context->block_header + 2) % camera_context->block_number) != camera_context->block_tail)
{
camera_context->capture_status &= ~XLLP_CAMERA_STATUS_RING_BUFFER_FULL;
PrvStartCapture( camera_context, camera_context->block_tail, 0 );
}
}
}
// Returns the FrameBufferID for the first filled frame
// Note: -1 represents buffer empty
int XllpCameraGetFirstFrameBufferID( P_XLLP_Camera_Context_T camera_context )
{
// not sure if this routine makes any sense.. JR
// check whether buffer is empty
if ( (camera_context->block_header == camera_context->block_tail) &&
!(camera_context->capture_status & XLLP_CAMERA_STATUS_RING_BUFFER_FULL) )
return -1;
// return the block header
return camera_context->block_header;
}
// Returns the FrameBufferID for the last filled frame, this would be used if we were polling for image completion data, or we wanted to make sure there were no frames waiting for us to process.
// Note: -1 represents buffer empty
int XllpCameraGetLastFrameBufferID( P_XLLP_Camera_Context_T camera_context )
{
// this doesn't make sense any more...JR
int ret;
// check whether buffer is empty
if ( (camera_context->block_header == camera_context->block_tail) &&
!(camera_context->capture_status & XLLP_CAMERA_STATUS_RING_BUFFER_FULL) )
return -1;
// return the block before the block_tail
ret = ( camera_context->block_tail + camera_context->block_number -1 ) % camera_context->block_number;
return ret;
}
/***********************************************************************
*
* Buffer Info APIs
*
***********************************************************************/
// Return: the number of frame buffers allocated for use.
unsigned int XllpCameraGetNumFrameBuffers( P_XLLP_Camera_Context_T camera_context )
{
return camera_context->block_number;
}
// FrameBufferID is a number between 0 and N-1, where N is the total number of frame buffers in use. Returns the address of
// the given frame buffer. The application will call this once for each frame buffer at application initialization only.
void* XllpCameraGetFrameBufferAddress( P_XLLP_Camera_Context_T camera_context, unsigned int frame_buffer_id )
{
return (void*)((unsigned)camera_context->buffer_virtual + camera_context->block_size * frame_buffer_id);
}
// Return the block id
int XllpCameraGetFrameBufferID( P_XLLP_Camera_Context_T camera_context, void* address )
{
if ( ((unsigned)address >= (unsigned)camera_context->buffer_virtual) &&
((unsigned)address <= (unsigned)camera_context->buffer_virtual + camera_context->buf_size ))
return ((unsigned)address - (unsigned)camera_context->buffer_virtual) / camera_context->block_size;
return -1;
}
/***********************************************************************
*
* Frame rate APIs
*
***********************************************************************/
// Set desired frame rate
void XllpCameraSetCaptureFrameRate( P_XLLP_Camera_Context_T camera_context )
{
XllpCISetFrameRate(camera_context->ci_reg_base, camera_context->frame_rate);
return;
}
// return current setting
void XllpCameraGetCaptureFrameRate( P_XLLP_Camera_Context_T camera_context )
{
camera_context->frame_rate = XllpCIGetFrameRate(camera_context->ci_reg_base);
return;
}
/***********************************************************************
*
* Interrupt APIs
*
***********************************************************************/
// set interrupt mask
void XllpCameraSetInterruptMask( P_XLLP_Camera_Context_T camera_context, unsigned int mask )
{
XLLP_DMAC_DESCRIPTOR_T *end_des_virtual;
int dma_interrupt_on;
unsigned int i;
// set CI interrupt
XllpCISetInterruptMask( camera_context->ci_reg_base, mask & XLLP_CI_CICR0_INTERRUPT_MASK );
// set dma end interrupt
if ( mask & XLLP_CAMERA_INTMASK_END_OF_DMA )
dma_interrupt_on = 1;
else
dma_interrupt_on = 0;
// set fifo0 dma chains' flag
end_des_virtual = (XLLP_DMAC_DESCRIPTOR_T*)camera_context->fifo0_descriptors_virtual + camera_context->fifo0_num_descriptors - 1;
for(i=0; i<camera_context->block_number; i++) {
if (dma_interrupt_on)
end_des_virtual->DCMD |= XLLP_DMAC_DCMD_END_IRQ_EN;
else
end_des_virtual->DCMD &= ~XLLP_DMAC_DCMD_END_IRQ_EN;
end_des_virtual += camera_context->fifo0_num_descriptors;
}
// Don't need to enable the interrupt for the other two channels, because we will always have the interrupt from the first channel.
/*
// set fifo1 dma chains' flag
if (camera_context->fifo1_descriptors_virtual) {
end_des_virtual = (XLLP_DMAC_DESCRIPTOR_T*)camera_context->fifo1_descriptors_virtual + camera_context->fifo1_num_descriptors - 1;
for(i=0; i<camera_context->block_number; i++) {
if (dma_interrupt_on)
end_des_virtual->DCMD |= XLLP_DMAC_DCMD_END_IRQ_EN;
else
end_des_virtual->DCMD &= ~XLLP_DMAC_DCMD_END_IRQ_EN;
end_des_virtual += camera_context->fifo1_num_descriptors;
}
}
// set fifo2 dma chains' flag
if (camera_context->fifo2_descriptors_virtual) {
end_des_virtual = (XLLP_DMAC_DESCRIPTOR_T*)camera_context->fifo2_descriptors_virtual + camera_context->fifo2_num_descriptors - 1;
for(i=0; i<camera_context->block_number; i++) {
if (dma_interrupt_on)
end_des_virtual->DCMD |= XLLP_DMAC_DCMD_END_IRQ_EN;
else
end_des_virtual->DCMD &= ~XLLP_DMAC_DCMD_END_IRQ_EN;
end_des_virtual += camera_context->fifo2_num_descriptors;
}
}
*/
}
// get interrupt mask
unsigned int XllpCameraGetInterruptMask( P_XLLP_Camera_Context_T camera_context )
{
XLLP_DMAC_DESCRIPTOR_T *end_des_virtual;
unsigned int ret;
// get CI mask
ret = XllpCIGetInterruptMask( camera_context->ci_reg_base );
// get dma end mask
end_des_virtual = (XLLP_DMAC_DESCRIPTOR_T*)camera_context->fifo0_descriptors_virtual + camera_context->fifo0_num_descriptors - 1;
if (end_des_virtual->DCMD & XLLP_DMAC_DCMD_END_IRQ_EN)
ret |= XLLP_CAMERA_INTMASK_END_OF_DMA;
return ret;
}
// clear interrupt status
void XllpCameraClearInterruptStatus( P_XLLP_Camera_Context_T camera_context, unsigned int status )
{
XllpCIClearInterruptStatus( camera_context->ci_reg_base, (status & 0xFFFF) );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -