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

📄 tr_scheduler.c

📁 ARM读写U盘驱动软件包源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
			if ( ph.ActualBytes )		
			{				
			   if ( i == BULK_TRANSFER)
					tr_inst_ptr->readout_position	= NULL;
				if ( tr_inst_ptr->direction == IN )
					memcpy( tr_inst_ptr->data_ptr_start, ptd_start + PTD_HEADER_LENGTH, ph.ActualBytes );

				tr_inst_ptr->data_ptr_start	+= ph.ActualBytes;	
				tr_inst_ptr->transferred_size	+= ph.ActualBytes;	
			}

			tr_inst_ptr->readout_position	= NULL;
	//
			tr_inst_ptr->fatal_error		 = (tr_inst_ptr->fatal_error << 1) | (( (!ph.CompletionCode) || (ph.CompletionCode & 0x8) ) ? 0 : 1);
			tr_inst_ptr->completion_code	 = ph.CompletionCode;



			if ( !((!ph.CompletionCode) || (ph.CompletionCode & 0x8)) )  /* 2005-2-24 updata */
			{
				(tr_inst_ptr->epi_ptr)->toggle = !ph.Toggle;
			}
			else
			{	

				if ( (i == INTERRUPT_TRANSFER) && (ph.DirectionPID == IN) && !ph.Active && !ph.ActualBytes )
					ph.Toggle	= !ph.Toggle;
				else
					(tr_inst_ptr->epi_ptr)->toggle = ph.Toggle;
			}
	
			if ( ((!ph.Active)&&(!(tr_inst_ptr->data_ptr_start < tr_inst_ptr->data_ptr_end))) 	
					
				|| (tr_inst_ptr->fatal_error		== 0x7) 				
				|| (tr_inst_ptr->completion_code == CompletionCode_DataUnderrun)				
				|| (tr_inst_ptr->completion_code == CompletionCode_Stall))					
			{
				tr_inst_ptr->data_ptr_start = NULL;						
				(*(tr_inst_ptr->callback))( tr_inst_ptr );				
			}
		}
	}
}



void atl_schedule( unsigned char *bp, unsigned short length, unsigned short *atl_buffer_access_length )
{
	transfer_instance_ptr	tr_inst_ptr;
	PTD_header_param		ph;
	unsigned char			*ptd_start;
	unsigned char			*ptd_end;
	unsigned char			*last_ptd_start;
	unsigned short			required_transfer_size;
	unsigned short			transfer_size;
	unsigned short			transfer_size_limit;
	unsigned short			size_may_be_written;
	unsigned short			packet_size;

	int						i;
							
	ptd_start						= bp;			
	ptd_end						= bp + length;		
	last_ptd_start				  	= ptd_start;		

for(i=0;i<NUMBER_OF_TRANSFER_TYPES;i++)
	for(tr_inst_ptr = g_tr_list_ptr[i]; 
		tr_inst_ptr!=NULL; 
		tr_inst_ptr = tr_inst_ptr->tr_list_for_tr.Blink)
	{
			if(tr_inst_ptr->lock == DELETE)		
			{
				tr_inst_ptr->lock = UNLOCK;
				remove_tr_list(&g_tr_list_ptr[i],tr_inst_ptr);	 
				remove_tr_from_ep(tr_inst_ptr);
				continue;	
			}
			
     	   		if ( tr_inst_ptr->data_ptr_start == NULL )					
				continue;

	   		if ( tr_inst_ptr->readout_position != NULL )		
				continue;
	                                                                                                                                                                                                                                                                                                                                                                                                                        			
	   		if ( tr_inst_ptr->direction == HOLD )						
				continue;
			
			if ( i == INTERRUPT_TRANSFER )							
			{
				if ( g_sof_counter < (tr_inst_ptr->poll_timing_timer) )		
					continue;
				else
					tr_inst_ptr->poll_timing_timer = g_sof_counter + tr_inst_ptr->schedule_rate;
			}
 
	
			size_may_be_written	= ptd_end - ptd_start;						
			packet_size			= (tr_inst_ptr->epi_ptr)->max_packet_size;		
		
			transfer_size_limit		= (size_may_be_written < MAX_DATA_SIZE_IN_A_FRAME) ? 	((size_may_be_written / packet_size) * packet_size) : MAX_DATA_SIZE_IN_A_FRAME;
			
			required_transfer_size	= (unsigned short)((unsigned long)(tr_inst_ptr->data_ptr_end) - (unsigned long)(tr_inst_ptr->data_ptr_start));					
			transfer_size			= (required_transfer_size < transfer_size_limit) ? required_transfer_size : transfer_size_limit;									
			
			if ( required_transfer_size && !transfer_size )				
				continue;


			if ( !((ptd_start + PTD_HEADER_LENGTH +  transfer_size) < ptd_end) )	
				continue;

			tr_inst_ptr->readout_position	= ptd_start;	
			last_ptd_start	 				= ptd_start;	


			ph.ActualBytes		= 0;
			ph.CompletionCode	= 0;
			ph.Active			= 1;
			ph.Toggle			= (tr_inst_ptr->epi_ptr)->toggle;
			ph.MaxPacketSize	= packet_size;
			ph.EndpointNumber	= (tr_inst_ptr->epi_ptr)->ep_num;
			ph.Last			= 0;
			ph.Speed			= (tr_inst_ptr->epi_ptr)->speed;
			ph.TotalBytes		= transfer_size;
			ph.DirectionPID	= tr_inst_ptr->direction;
			ph.Format		= 0x03&(tr_inst_ptr->epi_ptr)->tr_type;
			ph.FunctionAddress	= (tr_inst_ptr->epi_ptr)->dev_addr;
		  if ( i == BULK_TRANSFER)
					ph.FunctionAddress	= (tr_inst_ptr->epi_ptr)->dev_addr;

			#define	A_BIT_FOR_INTERRUPT_TR	0x2
			
			ph.test	= (i == INTERRUPT_TRANSFER) ? A_BIT_FOR_INTERRUPT_TR : 0x0;
			
			set_PTD_header( ptd_start, &ph );			
			
			if ( tr_inst_ptr->direction != IN )				
				memcpy( ptd_start + PTD_HEADER_LENGTH, tr_inst_ptr->data_ptr_start, transfer_size );


			
			ptd_start	= ptd_start + PTD_HEADER_LENGTH + transfer_size;
			ptd_start	= mem_align( ptd_start );	// 
			
			
	}

	set_LAST_PTD_flag( last_ptd_start );
	
	*atl_buffer_access_length = ptd_start  - bp;	

}





unsigned char atl_buffer_state( unsigned short pattern )
{
	return ( read_register16( Com16_HcBufferStatus ) & pattern );
}



void PTD_image_create( PTD_header_param *php, unsigned char *data, unsigned char *atl_buffer )
{

	int		i;

	set_PTD_header( atl_buffer, php );	
	
	atl_buffer		+= 8;			
	
	for ( i = 0; i < php->TotalBytes; i++ )	
		*atl_buffer++	= *data++;
}



void set_PTD_header( unsigned char *ph, PTD_header_param *php )
{
	*(ph + 0)	= php->ActualBytes & 0x0FF;
	
	*(ph + 1)	= (php->CompletionCode << 4)
					| (php->Active << 3) 		
					| (php->Toggle << 2) 
					| (php->ActualBytes >> 8);
	
	*(ph + 2)	= php->MaxPacketSize & 0xFF;
	
	*(ph + 3)	= (php->EndpointNumber << 4)
					| (php->Last << 3) 		
					| (php->Speed << 2) 
					| (php->MaxPacketSize >> 8);
					
	*(ph + 4)	= php->TotalBytes & 0xFF;

	*(ph + 5)	= (php->DirectionPID << 2)
					| (php->TotalBytes >> 8);
	
	*(ph + 6)	= 	  (php->Format << 7)
					| (php->FunctionAddress & 0x7F);
	
	*(ph + 5)  |= (php->test << 4);
}

void set_LAST_PTD_flag( unsigned char *p )
{
	*(p + 3)	= *(p + 3)	| (0x01 << 3);
}


void get_PTD_header( PTD_header_param *php, unsigned char *ph )
{
	php->ActualBytes		=  *(ph + 0) | ((*(ph + 1) & 0x3) << 8);
	php->CompletionCode		=  *(ph + 1) >> 4;
	php->Active				= (*(ph + 1) >> 3) & 0x01;
	php->Toggle				= (*(ph + 1) >> 2) & 0x01;
	php->MaxPacketSize		=  *(ph + 2) | ((*(ph + 3) & 0x3) << 8);
	php->EndpointNumber		=  *(ph + 3) >> 4;
	php->Last				= (*(ph + 3) >> 3) & 0x01;
	php->Speed				= (*(ph + 3) >> 2) & 0x01;
	php->TotalBytes			=  *(ph + 4) | ((*(ph + 5) & 0x3) << 8);
	php->DirectionPID		= (*(ph + 5) >> 2) & 0x03;
	php->Format				=  *(ph + 6) >> 7;
	php->FunctionAddress	=  *(ph + 6) & 0x7F;
}



unsigned char is_fatal_error( transfer_instance *tr_inst_ptr )
{
	unsigned char	completion_code;

	completion_code = tr_inst_ptr->completion_code;

	if ( !completion_code )
		return ( FALSE );
		
	else if ( completion_code & 0x8 )
		return ( FALSE );

	else
		return ( TRUE );
}



void	insert_tr_to_ep_list(transfer_instance **to_this_list, transfer_instance *list	)
{
	disable();

	if(list->epi_ptr->ep_num==0x2)
		to_this_list = to_this_list;

	
	if(*to_this_list!=NULL)
		list->tr_list_for_ep.Flink = (*to_this_list)->tr_list_for_ep.Flink;
	else
		list->tr_list_for_ep.Flink = list;
	list->tr_list_for_ep.Blink = *to_this_list;
	if(*to_this_list!=NULL)
		(*to_this_list)->tr_list_for_ep.Flink = list;
	*to_this_list =  list;

	enable();
}


void	remove_tr_list(transfer_instance **from_this_list, transfer_instance *list	)
{
	transfer_instance * last_tr_inst_ptr;
	transfer_instance * next_tr_inst_ptr;


	if(((*from_this_list)->tr_list_for_tr.Flink==list)&&(*from_this_list)==list)
		(*from_this_list) = NULL ;
	else
		if((*from_this_list)->tr_list_for_tr.Flink==list)
		{
			(*from_this_list)->tr_list_for_tr.Flink =   list->tr_list_for_tr.Flink;
			last_tr_inst_ptr = list->tr_list_for_tr.Flink;	
			last_tr_inst_ptr->tr_list_for_tr.Blink= NULL;
		}
		else	
			if((*from_this_list)==list)	
			{
				next_tr_inst_ptr = list->tr_list_for_tr.Blink;
				next_tr_inst_ptr->tr_list_for_tr.Flink = list->tr_list_for_tr.Flink;
				*from_this_list = next_tr_inst_ptr;
			}
			else
			{
				last_tr_inst_ptr = list->tr_list_for_tr.Flink;
				next_tr_inst_ptr = list->tr_list_for_tr.Blink;
				last_tr_inst_ptr->tr_list_for_tr.Blink = next_tr_inst_ptr;
				next_tr_inst_ptr->tr_list_for_tr.Flink = last_tr_inst_ptr;
			}
	list->tr_list_for_tr.Flink = NULL;
	list->tr_list_for_tr.Blink = NULL;
	
}

 
void	remove_tr_from_ep(transfer_instance *list	)
{

	transfer_instance **from_this_list;
	transfer_instance * last_tr_inst_ptr;
	transfer_instance * next_tr_inst_ptr;


	if(NULL==list->epi_ptr->tr_instance_ptr)				// UPDATA 2005-3-16
		return;
	from_this_list = &list->epi_ptr->tr_instance_ptr;

	if(((*from_this_list)->tr_list_for_ep.Flink==list)&&(*from_this_list)==list)
		(*from_this_list) = NULL ;
	else
		if((*from_this_list)->tr_list_for_ep.Flink==list)
		{
			(*from_this_list)->tr_list_for_ep.Flink =   list->tr_list_for_ep.Flink;
			last_tr_inst_ptr = list->tr_list_for_ep.Flink;	
			last_tr_inst_ptr->tr_list_for_ep.Blink= NULL;
		}
		else	
			if((*from_this_list)==list)	
			{
				next_tr_inst_ptr = list->tr_list_for_ep.Blink;
				next_tr_inst_ptr->tr_list_for_ep.Flink = list->tr_list_for_ep.Flink;
				*from_this_list = next_tr_inst_ptr;
			}
			else
			{
				last_tr_inst_ptr = list->tr_list_for_ep.Flink;
				next_tr_inst_ptr = list->tr_list_for_ep.Blink;
				last_tr_inst_ptr->tr_list_for_ep.Blink = next_tr_inst_ptr;
				next_tr_inst_ptr->tr_list_for_ep.Flink = last_tr_inst_ptr;
			}
	list->tr_list_for_ep.Flink = NULL;
	list->tr_list_for_ep.Blink = NULL;
}









⌨️ 快捷键说明

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