⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xllp_camera.c

📁 PXA270硬件测试源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    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 + -