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

📄 cim.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
字号:
/* * ucosii/jz4730/drv/cim.c * * Camera Interface Module (CIM) driver for JzSOC * This driver is independent of the camera sensor * * Copyright (C) 2005  JunZheng semiconductor * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "includes.h" //ucosii#include "jz4740.h"#include "camera.h" // Select one of the sensors#undef dprintf#define dprintf(x...)int printf(char *format, ...);/* If use cachable descriptor, enable this *///#define USE_CACHE 1/* * CIM configuration. */typedef struct{	u32 cfg;	u32 ctrl;	u32 mclk;} cim_config_t;struct cim_config {	int mclk;/* Master clock output to the sensor */	int vsp; /* VSYNC Polarity:0-rising edge is active,1-falling edge is active */	int hsp; /* HSYNC Polarity:0-rising edge is active,1-falling edge is active */	int pcp; /* PCLK Polarity:0-rising edge sampling,1-falling edge sampling */	int dsm; /* Data Sampling Mode:0-CCIR656 Progressive Mode, 1-CCIR656 Interlace Mode,2-Gated Clock Mode,3-Non-Gated Clock Mode */	int pack; /* Data Packing Mode: suppose received data sequence were 0x11 0x22 0x33 0x44, then packing mode will rearrange the sequence in the RXFIFO:		     0: 0x11 0x22 0x33 0x44		     1: 0x22 0x33 0x44 0x11		     2: 0x33 0x44 0x11 0x22		     3: 0x44 0x11 0x22 0x33		     4: 0x44 0x33 0x22 0x11		     5: 0x33 0x22 0x11 0x44		     6: 0x22 0x11 0x44 0x33		     7: 0x11 0x44 0x33 0x22		  */	int inv_dat;    /* Inverse Input Data Enable */	int frc;        /* Frame Rate Control:0-15 */	int trig;   /* RXFIFO Trigger 0:4 | 1:8 | 2:12 | 3:16 | 4:20 | 5:24 | 6:28 | 7:32 */};/* Actual image size, must less than max values */static int img_width, img_height, img_bpp;/* * CIM DMA descriptor */struct cim_desc {	u32 nextdesc;   /* Physical address of next desc */	u32 framebuf;   /* Physical address of frame buffer */	u32 frameid;    /* Frame ID */ 	u32 dmacmd;     /* DMA command */};/* * CIM device structure */struct cim_device {	unsigned char *framebuf;	unsigned int frame_size;        OS_EVENT *WaitSem;        OS_EVENT *JpegWaitSem;	struct cim_desc *frame_desc __attribute__ ((aligned (16)));};// globalstatic struct cim_device *cim_dev;static struct cim_desc cim_frame_desc[CIM_BUF_NUM] __attribute__ ((aligned (16)));static struct cim_desc cim_jpeg_desc __attribute__ ((aligned (16)));static struct cim_desc cim_test_jpeg_desc __attribute__ ((aligned (16)));#ifndef USE_CACHEstatic struct cim_desc *cim_uncached_frame_desc;#endif/* Buffer ID for buffer mutex handling */static int cim_id_init = 1;static int init_post = 0;static int cim_tran_buf_id;	/*cim dma current transfer buffer ID*/static int data_ready_buf_id;	/*data ready for yuv convert buffer ID*/static int last_data_buf_id;	/*last buf of yuv convert, if equal to data_ready_buf_id, wait eof intr*/static int data_buf_reading_flag, jpeg_reading_flag;static int img_width, img_height, img_bpp;static unsigned char *frm_buf;	/*current trans buffer pointer*/static unsigned char *jpeg_buf; /* buf for jpeg data *///#define CameraSize (4096 + (IMG_WIDTH * IMG_HEIGHT * IMG_BPP / 8 + 4095) / 4096 *4096 * CIM_BUF_NUM)#define CameraSize (4096 + (img_width * img_height * img_bpp / 8 + 4095) / 4096 *4096 * CIM_BUF_NUM)typedef void (* ALLOCMEMFUNC)( void *, int);static ALLOCMEMFUNC allocmemfunc=NULL, allocjpgmemfunc = NULL;void   SetAllocMemfunc(ALLOCMEMFUNC func){     allocmemfunc=func;}void   SetAllocJpgMemfunc(ALLOCMEMFUNC func){    allocjpgmemfunc = func;}/*========================================== * Sensor Configure CIM depend on Sensor *==========================================*/static struct cim_config cim_cfg = {#if CAMERATYPE == 1  /*OV2640*/	24000000, 1, 0, 0, 2, 4, 0, 0, 1,#endif#if CAMERATYPE == 2  /*OV3640*///	24000000, 1, 0, 0, 2, 4, 0, 0, 1,	24000000, 1, 0, 0, 2, 4, 0, 0, 0,#endif};/*============================= * CIM init routines *=============================*/static void camera_gpio_init(void) {	__gpio_as_cim();	__gpio_as_i2c();}/*=================================================== * Config CIM Modules depends on Sensor arguments *===================================================*/static void cim_config(cim_config_t *c){	REG_CIM_CFG = c->cfg;	REG_CIM_CTRL = c->ctrl;	/* Set the master clock output */	__cim_set_master_clk(__cpm_get_hclk(), c->mclk);	// Enable sof, eof and stop interrupts//	__cim_enable_sof_intr();	__cim_enable_eof_intr();//	__cim_enable_stop_intr();	__cim_enable_rxfifo_overflow_intr();}/* * Split YUV to three buf */void split_yuv422(unsigned char * yuv_buf,unsigned char * y_buf,unsigned char * u_buf,unsigned char * v_buf){	int i = 0, j;	for (j = 0;j < cim_dev->frame_size; i+=4, j+=4){		 y_buf[i/2]   = yuv_buf[j+0];		 y_buf[i/2+1] = yuv_buf[j+2];		 u_buf[i/4]   = yuv_buf[j+1];		 v_buf[i/4]   = yuv_buf[j+3];	}	__dcache_writeback_all(); }static unsigned char * cim_start_dma(void){	frm_buf = (u8 *)VIRT(cim_frame_desc[data_ready_buf_id].framebuf);	return frm_buf;}void framebuf_handled(void) {	data_buf_reading_flag = 0;	//last_data_buf_id = data_ready_buf_id;}/*=================================================== *Start cim and dma to transfer data from sensor *===================================================*/void cim_start(void){	if (cim_id_init == 1) {		cim_tran_buf_id = 0;		last_data_buf_id = data_ready_buf_id = 0;		data_buf_reading_flag = 0;		cim_id_init = 0;	}	__cim_disable();	__cim_set_da(PHYS((unsigned int)(&cim_frame_desc[cim_tran_buf_id])));//	__cim_set_da(PHYS(cim_dev->frame_desc));	__cim_clear_state();	// clear state register	__cim_reset_rxfifo();	// resetting rxfifo	__cim_unreset_rxfifo();	__cim_enable_dma();	// enable dma	__cim_enable();}void cim_stop(void){	__cim_disable();	__cim_clear_state();}/*============================================ * Framebuffer allocation and destroy *============================================*/static void cim_fb_destroy(void){	if (cim_dev->framebuf) {	  cim_dev->framebuf = NULL;	}}/*======================================= *Alloc JPEG buf y-buf, u-buf, v-buf *=======================================*/static unsigned char * get_jpeg_buf(void) {//	static unsigned char jpeg_heap[JPEG_BUF_SIZE + 0x10];	static unsigned char *jpeg_heap;        if(allocjpgmemfunc)            allocjpgmemfunc(&jpeg_heap, JPEG_BUF_SIZE + 0x10);	printf("_____________jpeg_heap____________ = 0x%08x\n", (unsigned int)jpeg_heap);	return jpeg_heap;}/*======================= * Set cim desc list *=======================*/static struct cim_desc *get_desc_list(u8 *cim_heap){	int i, num, page_nums = 0;	unsigned char *p_buf;	struct cim_desc *desc_list_head __attribute__ ((aligned (16)));	struct cim_desc *desc_list_tail __attribute__ ((aligned (16)));	struct cim_desc *p_desc __attribute__ ((aligned (16)));	int frm_id = 0;#ifndef USE_CACHE	struct cim_desc *cim_uncached_jpeg_desc, *cim_uncached_test_jpeg_desc;	cim_uncached_frame_desc = (struct cim_desc *)CIM_UNCACHED(cim_frame_desc);	cim_uncached_jpeg_desc =  (struct cim_desc *)CIM_UNCACHED(&cim_jpeg_desc);	cim_uncached_test_jpeg_desc =  (struct cim_desc *)CIM_UNCACHED(&cim_test_jpeg_desc);#endif	desc_list_head = desc_list_tail = NULL;	/* Prepare CIM_BUF_NUM-1 link descriptors for getting sensor data */	for (i = 0; i < CIM_BUF_NUM; i++) {#ifdef USE_CACHE		p_desc = &cim_frame_desc[i];#else /* uncached */		p_desc = &cim_uncached_frame_desc[i];#endif		p_buf = (u8 *)((u32)cim_dev->framebuf + cim_dev->frame_size  * i);		if (desc_list_head == NULL)			desc_list_head = p_desc;		else			desc_list_tail->nextdesc = PHYS(p_desc);			desc_list_tail = p_desc;		desc_list_tail->framebuf = PHYS(p_buf);		desc_list_tail->frameid = frm_id;		desc_list_tail->dmacmd = (cim_dev->frame_size >> 2) | CIM_CMD_EOFINT;		frm_id++;	}	desc_list_tail->nextdesc = PHYS(desc_list_head);#ifdef USE_CACHE /* cachable */	dma_cache_wback_inv(cim_frame_desc, sizeof(struct cim_desc) * CIM_BUF_NUM);	cim_test_jpeg_desc->framebuf = PHYS(jpeg_buf);	cim_test_jpeg_desc->nextdesc = PHYS(NULL);	cim_test_jpeg_desc->frameid = 0xf;	cim_test_jpeg_desc->dmacmd = (4 >> 2) | CIM_CMD_EOFINT | CIM_CMD_STOP;	dma_cache_wback_inv(&cim_test_jpeg_desc, sizeof(struct cim_desc));	cim_jpeg_desc.framebuf = PHYS(jpeg_buf);	cim_jpeg_desc.nextdesc = PHYS(NULL);	cim_jpeg_desc.frameid = 0xf;	cim_jpeg_desc.dmacmd = (JPEG_BUF_SIZE >> 2) | CIM_CMD_EOFINT | CIM_CMD_STOP;	dma_cache_wback_inv(&cim_jpeg_desc, sizeof(struct cim_desc));#else /* uncached */	cim_uncached_test_jpeg_desc->framebuf = PHYS(jpeg_buf);	cim_uncached_test_jpeg_desc->nextdesc = PHYS(NULL);	cim_uncached_test_jpeg_desc->frameid = 0xf;	cim_uncached_test_jpeg_desc->dmacmd = (4 >> 2) | CIM_CMD_EOFINT | CIM_CMD_STOP;	cim_uncached_jpeg_desc->framebuf = PHYS(jpeg_buf);	cim_uncached_jpeg_desc->nextdesc = PHYS(NULL);	cim_uncached_jpeg_desc->frameid = 0xf;	cim_uncached_jpeg_desc->dmacmd = (JPEG_BUF_SIZE >> 2) | CIM_CMD_EOFINT | CIM_CMD_STOP;#endif#if 0	for (i = 0; i < CIM_BUF_NUM; i++) {		printf("cim_frame_desc[%d] addr      \t= 0x%08x\n", i, (unsigned int)(&cim_frame_desc[i]));		printf("cim_frame_desc[%d].framebuf \t= 0x%08x\n",i, (unsigned int)cim_frame_desc[i].framebuf);		printf("cim_frame_desc[%d].frameid \t= 0x%08x\n",i, (unsigned int)cim_frame_desc[i].frameid);		printf("cim_frame_desc[%d].dmacmd \t= 0x%08x\n",i, (unsigned int)cim_frame_desc[i].dmacmd);		printf("cim_frame_desc[%d].nextdesc \t= 0x%08x\n",i, (unsigned int)cim_frame_desc[i].nextdesc);	}#endif	return desc_list_head;}/*================================================ * Alloc framebuf for get camera data through DMA *================================================*/static int cim_fb_alloc(void){//	static u8 cim_heap[4096 + (IMG_WIDTH * IMG_HEIGHT * IMG_BPP / 8 + 4095) / 4096 *4096 * CIM_BUF_NUM]  __attribute__ ((aligned(4096)));	static u8  *cim_heap;        if(allocmemfunc)            allocmemfunc(&cim_heap, CameraSize);	cim_dev->frame_size = img_width * img_height * (img_bpp/8);//	cim_dev->framebuf = (u8 *)(((u32)cim_heap & ~0xfff) + 0x1000);	cim_dev->framebuf = (u8 *)((u32)cim_heap & ~0x3);	if ( !(cim_dev->framebuf) ) {		return -1;	}	jpeg_buf = get_jpeg_buf();	cim_dev->frame_desc = get_desc_list(cim_heap);	return 0;}/*========================= * File operations *=========================*/unsigned char * cim_read(void){  return cim_start_dma();}/* * Snapshot functions  */unsigned char * cim_snapshot(int mode){	int i;        u8 err;	cim_stop();	jpeg_reading_flag = 1;	output_jpeg(0);	for(i = 0; i < 2; i++) {		__cim_disable();		__cim_set_da(PHYS((unsigned int)(&cim_test_jpeg_desc)));		__cim_clear_state();	// clear state register		__cim_reset_rxfifo();	// resetting rxfifo		__cim_unreset_rxfifo();		__cim_enable_dma();	// enable dma		__cim_enable();		OSSemPend(cim_dev->JpegWaitSem, 0, &err);	}	for(i = 0; i < 1; i++) {		__cim_disable();		__cim_set_da(PHYS((unsigned int)(&cim_jpeg_desc)));		__cim_clear_state();	// clear state register		__cim_reset_rxfifo();	// resetting rxfifo		__cim_unreset_rxfifo();		__cim_enable_dma();	// enable dma		__cim_enable();        //printf(" 5 ======================== cim_snapshot \n");		OSSemPend(cim_dev->JpegWaitSem, 0, &err);	}        //printf(" 6 ======================== cim_snapshot \n");	__cim_disable();        //printf(" 7 ======================== cim_snapshot \n");	return jpeg_buf;}void cim_snapshot_finish(void) {	jpeg_reading_flag = 0;	output_yuv();	cim_start();}void cim_close(void){        cim_stop();  //  	free_irq(IRQ_CIM);	cim_fb_destroy();}/*========================= * Interrupt handler *=========================*/static void cim_irq_handler(int irq, void *dev_id){	u32 state = REG_CIM_STATE, curr_frmid = REG_CIM_FID;	if (state & CIM_STATE_DMA_EOF) {		if (jpeg_reading_flag != 1) {				data_ready_buf_id = cim_tran_buf_id;				cim_tran_buf_id = curr_frmid;		}		else {			printf("JPEG EOF interrupt\n");			OSSemPost(cim_dev->JpegWaitSem);		}	}	if (state & CIM_STATE_RXF_OF) {		printf("OverFlow interrupt...\n");		printf("REG_CIM_STATE = 0x%08x\n", state);		__cim_disable();		__cim_reset_rxfifo();	// resetting rxfifo		__cim_unreset_rxfifo();		__cim_enable_dma();	// enable dma		__cim_enable();	}	/* clear status flags*/	REG_CIM_STATE = 0;}/*=========================================================== * Get image parameters from app, Call it before cim_init() *===========================================================*//*============================ * Module init *============================*///int cim_init(void)int cim_init(img_param_t *img){        static struct cim_device *dev;	int ret;	cim_config_t c;	static struct cim_device dev0;	camera_gpio_init();	/* set image parameter*/	img_width  = img->in_width;	img_height = img->in_height;	img_bpp    = img->in_bpp;	/* config cim */	c.mclk = cim_cfg.mclk;	c.cfg = (cim_cfg.vsp << 14) | (cim_cfg.hsp << 13) | (cim_cfg.pcp << 12) | (cim_cfg.dsm << 0) | (cim_cfg.pack << 4) | (cim_cfg.inv_dat << 15);	c.ctrl = (cim_cfg.frc << 16) | (cim_cfg.trig << 4);	cim_config(&c);	/* cim image parameter isn't set newly */	/* allocate device */        dev = &dev0;	/* record device */	cim_dev = dev;	/* allocate a frame buffer */	if (cim_fb_alloc() < 0) {		return -1;	}	dev->WaitSem = OSSemCreate(0);	dev->JpegWaitSem = OSSemCreate(0);	if ((ret = request_irq(IRQ_CIM, cim_irq_handler, dev)) == -1) {		cim_fb_destroy();		printf("CIM could not get IRQ");		return ret;	}	printf("JzSOC Camera Interface(CIM) driver init OK\n");	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -