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

📄 vp_capture.c

📁 DM642的VP口驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
                      	Ptr cbArg)				//Point to GIO_Obj
{
    Int 	chanid;
    Int 	retVal = IOM_COMPLETED;    
   	CapChan_Handle 	hCapChan;
    CapVP_Handle 	hCapVP = (CapVP_Handle)devp;
	CapChan_Params 	*paramCapChan = (CapChan_Params *)chanParams;
    
	//通道模式检测
    if(mode != IOM_INPUT){
    	return(IOM_EBADARGS);
    }
    
    //通道名检测
    if(*name ++ != '/'){
        return(IOM_EBADARGS);
    }else{
    	chanid = *name ++ - 'A';
	}
	
    //检查该视频端口驱动是否绑定
    if(!(hCapVP->status & VP_STATUS_OPENED)){
    	return(IOM_EBADARGS);
    }

    //检查视频通道号是否合法
    if(chanid == 0){
    	if(hCapVP->status & VP_STATUS_CHAOPENED){
    		return(IOM_EINUSE);
    	}else{
    		if(hCapVP->supCMode & (((Uns) 1) << paramCapChan->capMode)){
    			hCapVP->status |= VP_STATUS_CHAOPENED;
    		}else{
    			return(IOM_EBADARGS);
    		}
    	}
    }else{
    	if(hCapVP->status & VP_STATUS_CHBOPENED){
    		return(IOM_EINUSE);
    	}else{
    		if(hCapVP->supCMode & (((Uns) 1) << paramCapChan->capMode)){
    			hCapVP->status |= VP_STATUS_CHAOPENED;
    		}else{
    			return(IOM_EBADARGS);
    		}
    	}
    }
    hCapChan = &hCapVP->capChan[chanid];

    //配置通道设备及其管理器.
    QUE_new(&hCapChan->iomPktQue);
    hCapChan->cbFxn = cbFxn;
    hCapChan->cbArg = (Arg)cbArg;
    
    hCapChan->vSnapStarted = FALSE;

	//配置通道寄存器.
	if(paramCapChan != INV){
		if(IOM_COMPLETED != (retVal = CapChan_chanConfig(hCapChan, paramCapChan))){
		    if(0 == hCapChan->chanid){
    			hCapVP->status &= (~VP_STATUS_CHAOPENED);
    		}else{
    			hCapVP->status &= (~VP_STATUS_CHBOPENED);
    		}
			return(retVal);
		}
	}

    //分配视频数据缓冲区.
	if(IOM_COMPLETED != (retVal = CapChan_memAlloc(hCapChan, paramCapChan))){
		goto DelAllocatedForChan;
	}
	
	//分配EDMA通道及相关资源.
	if(IOM_COMPLETED != (retVal = CapChan_edmaAllocConfig(hCapChan, paramCapChan))){
		goto DelAllocatedForChan;
	}

    //打开并配置外部设备.
    if(hCapChan->edcFxns != INV){
		if((EDC_Handle)EDC_FAILED == (hCapChan->hEDC = hCapChan->edcFxns->open(name, (Arg)INV))){
			retVal = IOM_EALLOC;
			goto DelAllocatedForChan;
		}
    }
    	
	//设置返回值.
	*chanp = hCapChan;
    return(retVal);  
    
    //异常处理.
	DelAllocatedForChan:
    mdDeleteChan(hCapChan);
    *chanp = NULL;
    return(retVal);  
}

/*
 *  =================== mdDeleteChan ============================
 *  create a capture channel
 */
static Int mdDeleteChan(Ptr chanp)
{
	Uns	*baseAddr;
   	CapChan_Handle	hCapChan = (CapChan_Handle)chanp;
    CapVP_Handle 	hCapVP   = (CapVP_Handle)hCapChan->hCapVP;
    
    //复位该通道;
    baseAddr = (Uns	*)hCapChan->baseAddr;
    baseAddr[_VP_VCACTL_OFFSETA] = VP_VCACTL_DEFAULT | (VP_VCACTL_RSTCH_RESET << _VP_VCACTL_RSTCH_SHIFT);
    
    //释放MEM资源.
    CapChan_memFree(hCapChan);

    //释放EDMA资源.    
    CapChan_edmaFree(hCapChan);
    
    //清除状态位.
    if(0 == hCapChan->chanid){
    	hCapVP->status &= (~VP_STATUS_CHAOPENED);
    }else{
    	hCapVP->status &= (~VP_STATUS_CHBOPENED);
    }
    
    return(IOM_COMPLETED);
}

/*
 *  =================== mdSubmitChan ============================
 *  submit a IOM_Packet to capture channel
 */                        
static Int mdSubmitChan(Ptr chanp, IOM_Packet *packet)
{
    Int 	i, retVal;    
   	Uns	 	*baseAddr;
   	Char	**ycbrBuf;
   	CapChan_Handle	hCapChan = (CapChan_Handle)chanp;
	CapChan_VideoBufElem *hVideoBuf;
	
	//用户缓冲区.
	baseAddr = (Uns *)hCapChan->baseAddr;
	ycbrBuf  = (Char **)packet->addr;

	//命令解析处理.b
   	switch(packet->cmd){
		case CAPVP_CMD_GET:
			if(!QUE_empty(&hCapChan->vFullBufQue)){
				hVideoBuf = QUE_get(&hCapChan->vFullBufQue);
				QUE_put(&hCapChan->vEmptingBufQue, hVideoBuf);
				for(i=0; i<VP_YCBR_CHAN_CNT; i++){
					*(ycbrBuf + i) = hVideoBuf->ycrbBuf.ycbr[i];
				}

				retVal = IOM_COMPLETED;
			}else{
				QUE_put(&hCapChan->iomPktQue, packet);
				
				if(hCapChan->edmaConfigFlg){
					if(VP_CAP_SINGLE == hCapChan->vConCap){
						if(!hCapChan->vSnapStarted){
							baseAddr[_VP_VCACTL_OFFSETA] &= ~_VP_VCACTL_BLKCAP_MASK;
							baseAddr[_VP_VCACTL_OFFSETA] |=  _VP_VCACTL_VCEN_MASK;
							hCapChan->vSnapStarted = TRUE;						
						}else{
							baseAddr[_VP_VCACTL_OFFSETA] |= _VP_VCACTL_BLKCAP_MASK;
							baseAddr[_VP_VCASTAT_OFFSETA] = VP_VCASTAT_RMK(VP_VCASTAT_FRMC_CLEAR, VP_VCASTAT_F2C_CLEAR, VP_VCASTAT_F1C_CLEAR);
							baseAddr[_VP_VCACTL_OFFSETA] &= ~_VP_VCACTL_BLKCAP_MASK;
						}
						hCapChan->edmaConfigFlg = FALSE;
					}
				}else if((!QUE_empty(&hCapChan->vEmptyBufQue)) && ((baseAddr[_VP_VCASTAT_OFFSETA]) & (_VP_VCASTAT_FRMC_MASK | _VP_VCASTAT_F2C_MASK |_VP_VCASTAT_F1C_MASK))){
					hVideoBuf = (CapChan_VideoBufElem *)QUE_get(&hCapChan->vEmptyBufQue);

					QUE_put(&hCapChan->vFillingBufQue, hVideoBuf);
					
			   		hCapChan->edmaCfg[0].dst = (Uint32)hVideoBuf->ycrbBuf.ycbr[0];
			   		hCapChan->edmaCfg[1].dst = (Uint32)hVideoBuf->ycrbBuf.ycbr[1];
			   		hCapChan->edmaCfg[2].dst = (Uint32)hVideoBuf->ycrbBuf.ycbr[2];
				   	
				   	EDMA_config(hCapChan->hEdma[0], &hCapChan->edmaCfg[0]);	
				   	EDMA_config(hCapChan->hEdma[1], &hCapChan->edmaCfg[1]);
				   	EDMA_config(hCapChan->hEdma[2], &hCapChan->edmaCfg[2]);

				   	EDMA_link(hCapChan->hEdma[0], EDMA_hNull);
				   	EDMA_link(hCapChan->hEdma[1], EDMA_hNull);
				   	EDMA_link(hCapChan->hEdma[2], EDMA_hNull);
					
					hCapChan->edmaConfigFlg = TRUE;
					
					if(VP_CAP_SINGLE == hCapChan->vConCap){
						baseAddr[_VP_VCACTL_OFFSETA] |= _VP_VCACTL_BLKCAP_MASK;
						baseAddr[_VP_VCASTAT_OFFSETA] = VP_VCASTAT_RMK(VP_VCASTAT_FRMC_CLEAR, VP_VCASTAT_F2C_CLEAR, VP_VCASTAT_F1C_CLEAR);
						baseAddr[_VP_VCACTL_OFFSETA] &= ~_VP_VCACTL_BLKCAP_MASK;
						
						hCapChan->edmaConfigFlg = FALSE;
					}
				}

				retVal = IOM_PENDING;
			}
			break;
			
		case CAPVP_CMD_PUT:
			if(!QUE_empty(&hCapChan->vEmptingBufQue)){
				hVideoBuf = QUE_get(&hCapChan->vEmptingBufQue);
				for(i=0; i<VP_YCBR_CHAN_CNT; i++){
					hVideoBuf->bufSt[i] = VP_VBUF_IS_EMPTY;
				}
				QUE_put(&hCapChan->vEmptyBufQue, hVideoBuf);
				retVal = IOM_COMPLETED;
			}else{
				retVal = IOM_EBADARGS;
			}
			break;
			
		case CAPVP_CMD_EXCHANGE:
			if(!QUE_empty(&hCapChan->vEmptingBufQue)){
				hVideoBuf = QUE_get(&hCapChan->vEmptingBufQue);
				for(i=0; i<VP_YCBR_CHAN_CNT; i++){
					hVideoBuf->bufSt[i] = VP_VBUF_IS_EMPTY;
				}
				QUE_put(&hCapChan->vEmptyBufQue, hVideoBuf);
				
				if(!QUE_empty(&hCapChan->vFullBufQue)){
					hVideoBuf = QUE_get(&hCapChan->vFullBufQue);
					QUE_put(&hCapChan->vEmptingBufQue, hVideoBuf);
					
					for(i=0; i<VP_YCBR_CHAN_CNT; i++){
						*(ycbrBuf + i) = hVideoBuf->ycrbBuf.ycbr[i];
					}
					
					retVal = IOM_COMPLETED;						
				}else{
					QUE_put(&hCapChan->iomPktQue, packet);
	
					if(hCapChan->edmaConfigFlg){
						if(VP_CAP_SINGLE == hCapChan->vConCap){
							baseAddr[_VP_VCACTL_OFFSETA] |= _VP_VCACTL_BLKCAP_MASK;
							baseAddr[_VP_VCASTAT_OFFSETA] = VP_VCASTAT_RMK(VP_VCASTAT_FRMC_CLEAR, VP_VCASTAT_F2C_CLEAR, VP_VCASTAT_F1C_CLEAR);
							baseAddr[_VP_VCACTL_OFFSETA] &= ~_VP_VCACTL_BLKCAP_MASK;
							
							hCapChan->edmaConfigFlg = FALSE;
						}
					}else if((!QUE_empty(&hCapChan->vEmptyBufQue)) && ((baseAddr[_VP_VCASTAT_OFFSETA]) & (_VP_VCASTAT_FRMC_MASK | _VP_VCASTAT_F2C_MASK |_VP_VCASTAT_F1C_MASK))){
   						hVideoBuf = (CapChan_VideoBufElem *)QUE_get(&hCapChan->vEmptyBufQue);

						QUE_put(&hCapChan->vFillingBufQue, hVideoBuf);
						
				   		hCapChan->edmaCfg[0].dst = (Uint32)hVideoBuf->ycrbBuf.ycbr[0];
				   		hCapChan->edmaCfg[1].dst = (Uint32)hVideoBuf->ycrbBuf.ycbr[1];
				   		hCapChan->edmaCfg[2].dst = (Uint32)hVideoBuf->ycrbBuf.ycbr[2];
					   	
					   	EDMA_config(hCapChan->hEdma[0], &hCapChan->edmaCfg[0]);	
					   	EDMA_config(hCapChan->hEdma[1], &hCapChan->edmaCfg[1]);
					   	EDMA_config(hCapChan->hEdma[2], &hCapChan->edmaCfg[2]);

					   	EDMA_link(hCapChan->hEdma[0], EDMA_hNull);
					   	EDMA_link(hCapChan->hEdma[1], EDMA_hNull);
					   	EDMA_link(hCapChan->hEdma[2], EDMA_hNull);
					   	
						hCapChan->edmaConfigFlg = TRUE;
						
						if(VP_CAP_SINGLE == hCapChan->vConCap){
							baseAddr[_VP_VCACTL_OFFSETA] |= _VP_VCACTL_BLKCAP_MASK;
							baseAddr[_VP_VCASTAT_OFFSETA] = VP_VCASTAT_RMK(VP_VCASTAT_FRMC_CLEAR, VP_VCASTAT_F2C_CLEAR, VP_VCASTAT_F1C_CLEAR);
							baseAddr[_VP_VCACTL_OFFSETA] &= ~_VP_VCACTL_BLKCAP_MASK;
							
							hCapChan->edmaConfigFlg = FALSE;
						}

					}					

					retVal = IOM_PENDING;
				}
			}else{
				retVal = IOM_EBADARGS;
			}

			break;

		default:
			retVal = IOM_ENOTIMPL;
			break;
	}

    return(retVal);
}

/*
 *  =================== mdControlChan ============================
 */
static Int mdControlChan(Ptr chanp, Uns cmd, Ptr args)
{
	Int	retVal;
	Uns *baseAddr;
   	CapChan_Handle	hCapChan = (CapChan_Handle)chanp;
   	
	baseAddr = (Uns *)hCapChan->baseAddr;
	
	switch(cmd){
   		case CAPVP_CMD_STARTCAP:
   			if(VP_CAP_CONTINUOUS == hCapChan->vConCap){
   				baseAddr[_VP_VCACTL_OFFSETA] &= ~_VP_VCACTL_BLKCAP_MASK;
   				baseAddr[_VP_VCACTL_OFFSETA] |=  _VP_VCACTL_VCEN_MASK;
   				retVal = IOM_COMPLETED;
   			}else{
   				retVal = IOM_EBADARGS;
   			}
   			break;
   		
   		case CAPVP_CMD_STOPCAP:
   			if(VP_CAP_CONTINUOUS == hCapChan->vConCap){
		   			baseAddr[_VP_VCACTL_OFFSETA] &= ~_VP_VCACTL_VCEN_MASK;
   				baseAddr[_VP_VCACTL_OFFSETA] |=  _VP_VCACTL_BLKCAP_MASK;
   				retVal = IOM_COMPLETED;
   			}else{
   				retVal = IOM_EBADARGS;
   			}
   			break;
   			
   		default:
			if(INV != hCapChan->edcFxns){
				retVal = hCapChan->edcFxns->ctrl(hCapChan->hEDC, cmd - CAPVP_CMD_EDC_BASE, (Arg)args);
			}else{
				retVal = IOM_ENOTIMPL;
			}
   	}
   	
    return(retVal);
}



⌨️ 快捷键说明

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