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

📄 usbvideo_state.c

📁 MTK平台绝密核心代码之 USB驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
			g_USBVideo.video_control.video_buffer_full = KAL_FALSE;
			g_USBVideo.video_control.send_video_msg = KAL_TRUE;
			RestoreIRQMask(savedMask);
			g_USBVideo.video_control.still_count--;
			USBVideo_Send_Msg(USBVIDEO_MSG_MED_STILL_CAPTURE_IND, commit_still_index, g_USBVideo.commit_still_compression_index);
		}
		else
		{
		#ifndef  __PRODUCTION_RELEASE__
			if((g_USBVideo.video_control.still_count>0) && (commit_still_index==0))
			{
				ASSERT(0);
			}
		#endif	
			g_USBVideo.video_control.still_count = 0;
			
			savedMask = SaveAndSetIRQMask();
			g_USBVideo.video_control.sent_video_size = 0;
			g_USBVideo.video_control.send_video_msg = KAL_TRUE;
			RestoreIRQMask(savedMask);
			/* there are two conditions that STILL_DMA_DONE without STILL_DMA_PARTIAL
			     1 : Still image is stopped by USB HISR receiving clear EP Halt feature
			     2:  Still image size is less than one video buffer size */
			g_USBVideo.state = USBVIDEO_STATE_SEND;
			USBVideo_Send_Msg(USBVIDEO_MSG_MED_START_IND, g_USBVideo.commit_video_index, g_USBVideo.video_compression_index);
		}
	}
}

/* Handler for still DMA partial done(complete of some video buffer size) from DMA HISR */
static void USBVideo_Still_DMA_Partial_Hdlr(ilm_struct *p_recv_ilm, USB_DEVICE_TYPE device_type)
{
	usbvideo_still_dma_struct *still_dma;
	kal_uint32 savedMask;

	if(g_USBVideo.state==USBVIDEO_STATE_PAUSE)
		EXT_ASSERT(0, (kal_uint32)g_USBVideo.state, 0, 0);
	
	if((g_USBVideo.state == USBVIDEO_STATE_PRE_PAUSE) || (g_USBVideo.state == USBVIDEO_STATE_STOP))
		return;

	if(g_USBVideo.video_control.still_count==0)
	{
		still_dma = (usbvideo_still_dma_struct *)p_recv_ilm->local_para_ptr;
		savedMask = SaveAndSetIRQMask();
		/* update read pointer so that video can start to capture in this buffer */
		g_USBVideo.video_control.video_buffer_read_index = still_dma->index;/* update read  pointer 1, so only can be written pointer 0*/
		g_USBVideo.video_control.video_buffer_full = KAL_FALSE;
		RestoreIRQMask(savedMask);
		if(still_dma->index==1)
		{
			g_USBVideo.state = USBVIDEO_STATE_SEND;
			USBVideo_Send_Msg(USBVIDEO_MSG_MED_START_IND, g_USBVideo.commit_video_index, g_USBVideo.video_compression_index);
		}	
	}
}

/* Handler for still capture request(PC request) from USB HISR */
static void USBVideo_Still_Capture_Hdlr(ilm_struct *p_recv_ilm, USB_DEVICE_TYPE device_type)
{
	kal_bool  bSendMsg = KAL_FALSE;
	kal_uint32 savedMask;
	kal_uint8 commit_still_index = g_USBVideo.commit_still_index;

#ifndef  __PRODUCTION_RELEASE__
	if(commit_still_index==0)
	{
		ASSERT(0);
	}
#endif	

	/* Do not assert because still capture msg is triggered by USB HISR, but pause request is triggered by media task */
	if((g_USBVideo.state==USBVIDEO_STATE_PRE_PAUSE) || (g_USBVideo.state==USBVIDEO_STATE_PAUSE)
		|| (g_USBVideo.state==USBVIDEO_STATE_STOP) || (commit_still_index==0))
		return;
			
	if(g_USBVideo.state != USBVIDEO_STATE_STILL) /* SEND or DROP */
	{
		g_USBVideo.state = USBVIDEO_STATE_STILL;
		g_USBVideo.video_control.still_count = 0;
		savedMask = SaveAndSetIRQMask();
		if(USB_DMA_Get_Run_Status(g_USBVideo.txpipe->byEP)==KAL_FALSE)
		{	
			g_USBVideo.video_control.video_buffer_read_index = 0;
			g_USBVideo.video_control.video_buffer_write_index = 0;
			g_USBVideo.video_control.video_buffer_full = KAL_FALSE;
			g_USBVideo.video_control.send_video_msg = KAL_TRUE;
			bSendMsg = KAL_TRUE;	
		}
		/* else wait DMA_DONE */
		RestoreIRQMask(savedMask);
		if(bSendMsg == KAL_TRUE)
		{
			USBVideo_Send_Msg(USBVIDEO_MSG_MED_STILL_CAPTURE_IND, commit_still_index, g_USBVideo.commit_still_compression_index);
		}
		else
		{
			/* In the mechanism that buffer can be released as video when the first part of still image is transmitted,
			     it may happens that: STILL_DMA_PARTIAL has been received so state change to SEND,
			     before the whole still image transmitted, this still capture request is received again */
			 if(g_USBVideo.video_control.dma_type == USBVIDEO_DMA_STILL)
			{
				g_USBVideo.video_control.still_count++;
			}
		}
	}
	else
	{
		g_USBVideo.video_control.still_count++;
	}
}

/* Handler for complete still buffer filling from camera HISR */
static void USBVideo_Still_Complete_Hdlr(ilm_struct *p_recv_ilm, USB_DEVICE_TYPE device_type)
{
	kal_uint32 savedMask;
	
	if(g_USBVideo.state==USBVIDEO_STATE_STOP)
		return;

	if(g_USBVideo.state!=USBVIDEO_STATE_STILL)
		EXT_ASSERT(0, (kal_uint32)g_USBVideo.state,g_USBVideo.video_control.video_buffer_read_index, 
					g_USBVideo.video_control.video_buffer_write_index);

	savedMask = SaveAndSetIRQMask();
	/* In case video complete msg is sent after still DMA partial done but before still DMA done*/
	g_USBVideo.video_control.send_video_msg = KAL_FALSE;	
	RestoreIRQMask(savedMask);
	g_USBVideo.video_control.dma_type = USBVIDEO_DMA_STILL;
	USBVideo_Send_Video();
}

/* Handler for device request still image from media task */
static void USBVideo_Dev_Still_Req_Hdlr(ilm_struct *p_recv_ilm, USB_DEVICE_TYPE device_type)
{
	kal_bool  bSendMsg;

	if(g_USBVideo.state==USBVIDEO_STATE_STOP)
	{
		/* cable may have been plug out, return error to media task*/
		USBVideo_Send_Msg(USBVIDEO_MSG_MED_DEVICE_STILL_CNF, (kal_uint32)KAL_FALSE, 0);
		return;
	}
	
	if((g_USBVideo.state == USBVIDEO_STATE_PRE_PAUSE) || (g_USBVideo.state == USBVIDEO_STATE_PAUSE))
	{
		/* return error to media task */
		USBVideo_Send_Msg(USBVIDEO_MSG_MED_DEVICE_STILL_CNF, (kal_uint32)KAL_FALSE, 0);
	}
	else if(g_USBVideo.still_probe_state == USBVIDEO_COMMIT_DONE)
	{
		/* send buttom press interrupt to host */
		g_USBVideo.vs_status_pkt.bStuausType = USBVIDEO_STATUS_TYPE_VS;
		g_USBVideo.vs_status_pkt.bOriginator = g_USBVideo.vs_interface_id;
		g_USBVideo.vs_status_pkt.bEvent = USBVIDEO_STATUS_VS_EVENT_BUTTOM_PRS;
		g_USBVideo.vs_status_pkt.bValue = USBVIDEO_STATUS_VS_VALUE_BUTTOM_PRS;
		bSendMsg = USBVideo_Send_Intr(&g_USBVideo.vs_status_pkt,sizeof(USBVideo_VS_Status_Pkt_Struct));
		/* return succuess to media task */
		USBVideo_Send_Msg(USBVIDEO_MSG_MED_DEVICE_STILL_CNF, (kal_uint32)bSendMsg, 0);
	}
	else
	{
		/* return error to media task, may because still probe is not commit */
		USBVideo_Send_Msg(USBVIDEO_MSG_MED_DEVICE_STILL_CNF, (kal_uint32)KAL_FALSE, 0);
	}
}

/* GPT timeout function for pre pause timeout */
/* It may be happened when pause request recvd but host application does not open and does not ask for video */
static void USBVideo_PrePause_Timeout(void *parameter)
{
	kal_uint32 savedMask;
	kal_bool b_sendmsg = KAL_FALSE;
	USBVIDEO_DMA_TYPE dma_type;
	
	
	GPTI_StopItem(g_USBVideo.video_control.timer_handle);
	
	/* Avoid race condition with DMA or USB HISR */
	savedMask = SaveAndSetIRQMask();

	/* GPT HISR has lower priority than DMA HISR, so there should be no GPT preempt DMA case
	     If the priority is changed, the whole part of DMA callback should disable intereupt */
	if(g_USBVideo.video_control.b_processing_dma == KAL_TRUE)
			EXT_ASSERT(0, (kal_uint32)g_USBVideo.video_control.b_processing_dma, 
						(kal_uint32)g_USBVideo.video_control.dma_type, (kal_uint32)g_USBVideo.state);

	/* stop DMA if it is on */
	if(USB_DMA_Get_Run_Status(g_USBVideo.txpipe->byEP)==KAL_TRUE)
	{
		USB_Stop_DMA_Channel(g_USBVideo.txpipe->byEP);

		#ifdef WEBCAM_TEST_DMA_DELAY
			g_USBVideo.test_enable = KAL_FALSE;
		#endif

		/* clear FIFO, if not clear it, the next packet may be false */
		USB_Clear_IN_EP_FIFO(g_USBVideo.txpipe->byEP);
		
		/* clear dma running state here*/
		USB_DMA_Set_Run_Status(g_USBVideo.txpipe->byEP, KAL_FALSE);

		g_USBVideo.video_control.sent_video_size = 0;

		/* Notify state machine to update state */
		if(g_USBVideo.video_control.dma_type == USBVIDEO_DMA_VIDEO)
		{
			b_sendmsg = KAL_TRUE;
			dma_type = USBVIDEO_DMA_VIDEO;
		}
		else if(g_USBVideo.video_control.dma_type == USBVIDEO_DMA_STILL)
		{
			b_sendmsg = KAL_TRUE;
			dma_type = USBVIDEO_DMA_STILL;
		}
		else if(g_USBVideo.video_control.dma_type == USBVIDEO_DMA_INCALL_JPEG)
		{
			/* Note that if pause and then resume, without open PC application, and then pause again, pre_pause state may happen */
			b_sendmsg = KAL_TRUE;
			dma_type = USBVIDEO_DMA_INCALL_JPEG;
		}
		else 
			ASSERT(0);
	}	

	RestoreIRQMask(savedMask);	

	if(b_sendmsg==KAL_TRUE)
	{
		g_USBVideo.video_control.dma_done_type = USBVIDEO_DMA_DONE_STOP;
		if(dma_type == USBVIDEO_DMA_VIDEO)
		{
			USBVideo_Send_Msg(USBVIDEO_MSG_USB_DMA_DONE, MOD_GPT_HISR, 0);
		}
		else if(dma_type == USBVIDEO_DMA_STILL)
		{
			USBVideo_Send_Msg(USBVIDEO_MSG_USB_STILL_DMA_DONE, MOD_GPT_HISR, 0);
		}
		else if(dma_type == USBVIDEO_DMA_INCALL_JPEG)
		{
			USBVideo_Send_Msg(USBVIDEO_MSG_USB_INCALL_DMA_DONE, MOD_GPT_HISR, 0);
		}
	}
}

/* Handler for pause request from media task */
static void USBVideo_Pause_Req_Hdlr(ilm_struct *p_recv_ilm, USB_DEVICE_TYPE device_type)
{
	usbvideo_default_JPEG_struct *video_default_jpeg_info;
	kal_bool  bSendMsg;
	kal_uint32 savedMask;
	usbvideo_default_JPEG_Info*p_default_jpeg;
	kal_uint8 video_size_num;
	const USBVideo_Video_Size_Info *p_video_size_param;
	kal_uint32 index;

	if((g_USBVideo.state==USBVIDEO_STATE_PRE_PAUSE) || (g_USBVideo.state==USBVIDEO_STATE_PAUSE))
		EXT_ASSERT(0, (kal_uint32)g_USBVideo.state, 0, 0);	
	
	if(g_USBVideo.state==USBVIDEO_STATE_STOP)
	{
		/* cable may have been plug out, return error */
		USBVideo_Send_Msg(USBVIDEO_MSG_MED_PAUSE_CNF, (kal_uint32)KAL_FALSE, 0);
		return;
	}

	video_default_jpeg_info=(usbvideo_default_JPEG_struct *)p_recv_ilm->local_para_ptr;
	g_USBVideo.default_jpeg_info = video_default_jpeg_info->jpeg_info;
	g_USBVideo.default_jpeg_num = video_default_jpeg_info->size;
     /* The in-call JPEG information is no needed in descriptor
	    Add here just for checking image size matches video size */
	p_video_size_param = g_USBVideo.camera_param->usbvideo_get_video_size_info(&video_size_num);    
	if(g_USBVideo.default_jpeg_num != video_size_num)
		EXT_ASSERT(0, g_USBVideo.default_jpeg_num, video_size_num, 0);
	for(index = 0; index < g_USBVideo.default_jpeg_num; index++)
	{
		if(g_USBVideo.default_jpeg_info[index].width != p_video_size_param[index].width)
			EXT_ASSERT(0, index, g_USBVideo.default_jpeg_info[index].width, p_video_size_param[index].width);
		if(g_USBVideo.default_jpeg_info[index].height!= p_video_size_param[index].height)
			EXT_ASSERT(0, index, g_USBVideo.default_jpeg_info[index].height, p_video_size_param[index].height);
	}
	
	bSendMsg = KAL_FALSE;
	savedMask = SaveAndSetIRQMask();
	if(USB_DMA_Get_Run_Status(g_USBVideo.txpipe->byEP)==KAL_TRUE)
	{
		g_USBVideo.state = USBVIDEO_STATE_PRE_PAUSE;
		g_USBVideo.video_control.b_stop_timer = KAL_FALSE;
		GPTI_StartItem(g_USBVideo.video_control.timer_handle, USBVIDEO_PRE_PAUSE_TIMEOUT, USBVideo_PrePause_Timeout, NULL);
	}
	else
	{
		g_USBVideo.state = USBVIDEO_STATE_PAUSE;	
		bSendMsg = KAL_TRUE;
	}
	RestoreIRQMask(savedMask);
	
	if(bSendMsg == KAL_TRUE)
	{
		USBVideo_Send_Msg(USBVIDEO_MSG_MED_PAUSE_CNF, (kal_uint32)KAL_TRUE, 0);
		//p_default_jpeg = g_USBVideo.mmi_param->usbvideo_get_incall_jpeg_info(&incall_size_num);
		p_default_jpeg = g_USBVideo.default_jpeg_info;
		savedMask = SaveAndSetIRQMask();
		g_USBVideo.video_control.still_count = 0;
		g_USBVideo.video_control.sent_video_size = 0;
		g_USBVideo.video_control.incall_jpeg_addr = p_default_jpeg[g_USBVideo.commit_video_index - 1].start_addr;
		g_USBVideo.video_control.incall_jpeg_size = p_default_jpeg[g_USBVideo.commit_video_index - 1].size;
		RestoreIRQMask(savedMask);
		g_USBVideo.video_control.dma_type = USBVIDEO_DMA_INCALL_JPEG;
		USBVideo_Send_Incall_JPEG();
	}
}

/* Handler for incall  timeout from GPT HISR*/
static void USBVideo_InCall_Timeout_Hdlr(ilm_struct *p_recv_ilm, USB_DEVICE_TYPE device_type)
{
	kal_uint32 savedMask;
	usbvideo_default_JPEG_Info*p_default_jpeg;

	/* This is executed in USB task, incase this msg is handled after resume handler (may change to send state),
	    so no state check here */
	if(g_USBVideo.state==USBVIDEO_STATE_PAUSE)

⌨️ 快捷键说明

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