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

📄 tr_scheduler.c

📁 ARM读写U盘驱动软件包源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzou ZLG-MCU Development Co.,LTD.
**                                     graduate school
**                                 http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name: tr_scheduler.c
** Last modified Date: 2005-04-22
** Last Version: V1.0 
** Description: 
**
**------------------------------------------------------------------------------------------------------
** Created By: Lishan Zhou
** Created date: 2005-04-22
** Version: V1.0 
** Description:
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
********************************************************************************************************/

/****************************************************************************/
/*	includes																*/
/****************************************************************************/
#include "HostStack.h"

#ifndef	MAX_TRANSFER_LIST
#define MAX_TRANSFER_LIST			60		
#endif
/****************************************************************************/
/*	constants																*/
/****************************************************************************/
#define	PTD_HEADER_LENGTH			8
#define	NUMBER_OF_TRANSFER_TYPES	3		
#define	ATL_STATUS__FULL			0x04
#define	ATL_STATUS__DONE			0x20
#define	mem_align( x )				((unsigned char *)((((unsigned long)(x)) + 3) & ~0x3))

/****************************************************************************/
/*	global vars																*/
/****************************************************************************/
unsigned short	 	g_atl_access_length = 0;
transfer_instance	g_transfer_list[ MAX_TRANSFER_LIST ];					
unsigned char		g_static_atl_buffer[ InitVal_HcATLBufferLength + 3 ];	
unsigned char		*g_atl_buffer;											
transfer_instance	*g_tr_list_ptr[3] = {NULL,NULL,NULL} ;					
transfer_instance	*g_insert_tr_list_ptr[3] = {NULL,NULL,NULL} ;			

/****************************************************************************/
/*	function prototypes														*/
/****************************************************************************/
unsigned char	atl_buffer_state( unsigned short pattern );
void			atl_read_buffer( unsigned char *bp, unsigned short length );
void			atl_write_buffer( unsigned char *bp, unsigned short length );
void			atl_buffer_parse( unsigned char *bp );
void			atl_schedule( unsigned char *g_atl_buffer, unsigned short length, unsigned short *ap );
void			PTD_image_create( PTD_header_param *php, unsigned char *data, unsigned char *atl_buffer );
void			set_PTD_header( unsigned char *ph, PTD_header_param *php );
void			set_LAST_PTD_flag( unsigned char *p );
void			get_PTD_header( PTD_header_param *php, unsigned char *ph );
void			remove_tr_list(transfer_instance **from_this_list, transfer_instance *list	);
void			insert_tr_to_ep_list(transfer_instance **to_this_list, transfer_instance *list	);
void			remove_tr_from_ep(transfer_instance *list);

/****************************************************************************/
/*	function definitions													*/
/****************************************************************************/
void atl_initialize( void )
{
	int					i;

	for(i=0;  i < MAX_TRANSFER_LIST ; i++)
	{
		(g_transfer_list[i]).lock				= UNLOCK;		
		(g_transfer_list[ i ]).readout_position	= NULL;
		(g_transfer_list[ i ]).data_ptr_start	= NULL;
	}

	g_tr_list_ptr[0] = NULL ;
	g_tr_list_ptr[1] = NULL ;
	g_tr_list_ptr[2] = NULL ;
	g_insert_tr_list_ptr[0] = NULL ;	
	g_insert_tr_list_ptr[1] = NULL ;
	g_insert_tr_list_ptr[2] = NULL ;
	g_atl_buffer	= mem_align( g_static_atl_buffer );	
	
	install_ATLInt_service_routine( 0, atl_ATL_transfer_mixer );	
	install_SOF_service_routine(    1, atl_ATL_transfer_mixer );	
}


unsigned char g_is_add = 0;

void insert_transfer_descriptor(transfer_instance *tr_instance_ptr , 
								unsigned char  transfer_type)
{
	transfer_instance **tr_instance_type_ptr;

	disable();
	g_is_add =0;
	switch(transfer_type & 0x03)
	{
		case 3:
			tr_instance_type_ptr = &g_insert_tr_list_ptr[INTERRUPT_TRANSFER];
			break;
		case	 0:	
			tr_instance_type_ptr = &g_insert_tr_list_ptr[CONTROL_TRANSFER];
			break;
		case	 2:							
			tr_instance_type_ptr = &g_insert_tr_list_ptr[BULK_TRANSFER];
			break;
	}

	tr_instance_ptr->tr_list_for_tr.Flink = NULL;		
	tr_instance_ptr->tr_list_for_tr.Blink = NULL;	
	
	if ( *tr_instance_type_ptr == NULL)			
	{
		*tr_instance_type_ptr = tr_instance_ptr;
		(*tr_instance_type_ptr)->tr_list_for_tr.Flink = tr_instance_ptr;
		(*tr_instance_type_ptr)->tr_list_for_tr.Blink = NULL;
	}
	else
	{
		(*tr_instance_type_ptr)->tr_list_for_tr.Flink->tr_list_for_tr.Blink = tr_instance_ptr;
		tr_instance_ptr->tr_list_for_tr.Flink = (*tr_instance_type_ptr)->tr_list_for_tr.Flink;	
		tr_instance_ptr->tr_list_for_tr.Blink = NULL;						
		(*tr_instance_type_ptr)->tr_list_for_tr.Flink = tr_instance_ptr;			
	}
	g_is_add = 1;
	enable();
	
}


transfer_instance *atl_open_transfer_instance( endpoint_info * epi_ptr)
{
	int		j;
	unsigned char transfer_type = epi_ptr->transfer_type & 0x03;
	OS_EVENT	*os_event_ptr;

 disable();
	if(epi_ptr->ep_num==ENDPOINT_BE_FREE)
	{
		enable();
		return ATL_ENDPOINT_ERR;
	}
	for ( j = 0; j < MAX_TRANSFER_LIST; j++ )
	{
		if ( (g_transfer_list[ j ]).lock == UNLOCK )
		{
			 (g_transfer_list[ j ]).lock= LOCK;		
			os_event_ptr = OSMboxCreate(NULL);	
			if(os_event_ptr)
				(g_transfer_list[ j ]).os_event_ptr = os_event_ptr;					
			else
			{
				(g_transfer_list[ j ]).lock	= UNLOCK;		
				enable();
				return  NO_OPEN_ATL_TRANSFER ;
			}
			(g_transfer_list[ j ]).epi_ptr 	= epi_ptr;		
			(g_transfer_list[ j ]).endpoint_create_id = epi_ptr->endpoint_create_id;

			insert_transfer_descriptor(&(g_transfer_list[ j ]), transfer_type);
			insert_tr_to_ep_list(&epi_ptr->tr_instance_ptr, &(g_transfer_list[ j ]));
			enable();
			return  &(g_transfer_list[ j ]) ;
		}
	}
	enable();
	return  NO_OPEN_ATL_TRANSFER ;
}


void atl_close_transfer_instance( transfer_instance *tr_instance_ptr  )
{
 	unsigned char err;
	if(tr_instance_ptr->lock == UNLOCK)
		return;
	if(tr_instance_ptr->lock == DELETE)
		return;

	tr_instance_ptr->data_ptr_start	= NULL;
	tr_instance_ptr->lock			= DELETE;


	// UPDATA 2005-06-17	
	OSMboxDel( tr_instance_ptr->os_event_ptr, 		
			    OS_DEL_NO_PEND , &err  );

	if(err == OS_ERR_TASK_WAITING)
	{
			tr_instance_ptr->completion_code = OS_EVENT_DELETE;			
		OSMboxPost( tr_instance_ptr->os_event_ptr, 
				      &tr_instance_ptr->completion_code);	
		return;
	}

	tr_instance_ptr->os_event_ptr = NULL;

}



 unsigned char atl_set_transfer( transfer_instance *tr_inst_ptr,		 
					  unsigned char *buffer_ptr, 			
					  unsigned short length, 				
					   unsigned char direction, 				
					   void (*callback)( transfer_instance  *tr_inst_ptr ) )	
{
  	unsigned char schedule_rate;

	if( tr_inst_ptr->lock != LOCK)				
		return FALSE ;
	if( tr_inst_ptr->epi_ptr == NULL)				
		return FALSE ;
	if( tr_inst_ptr->epi_ptr->ep_num == ENDPOINT_BE_FREE)
		return FALSE ;
	if( tr_inst_ptr->endpoint_create_id !=			
	     tr_inst_ptr->epi_ptr->endpoint_create_id)
		return FALSE;

	schedule_rate = tr_inst_ptr->epi_ptr->endpoint_descriptor.bInterval;
	
	tr_inst_ptr->data_ptr_base		= buffer_ptr;	  	
	tr_inst_ptr->data_ptr_end		= buffer_ptr + length;	
	tr_inst_ptr->direction			= direction;			
	tr_inst_ptr->callback			= callback;			
	tr_inst_ptr->readout_position	= NULL;			
	tr_inst_ptr->transferred_size	= 0;				
	tr_inst_ptr->fatal_error			= 0;   			
	tr_inst_ptr->completion_code	= 0;				
	tr_inst_ptr->schedule_rate		= schedule_rate;		
	tr_inst_ptr->poll_timing_timer	= g_sof_counter + tr_inst_ptr->schedule_rate;
	tr_inst_ptr->data_ptr_start		= tr_inst_ptr->data_ptr_base;		

	return TRUE;
}


void re_enable_interrupt_transfer( transfer_instance *tr_inst_ptr )
{
	
	tr_inst_ptr->data_ptr_start		= tr_inst_ptr->data_ptr_base;
}



void atl_ATL_transfer_mixer( void )
{
	unsigned short	atl_stat;
	unsigned short	atl_full;
	unsigned short	atl_done;

	unsigned short	i;

	transfer_instance *tr_instance_ptr;
	
	atl_stat	= atl_buffer_state( ATL_STATUS__DONE | ATL_STATUS__FULL );	
	atl_full	= atl_stat & ATL_STATUS__FULL;							
	atl_done	= atl_stat & ATL_STATUS__DONE;							

	if ( atl_full && !atl_done )									
		return;												

	if ( atl_done && g_atl_access_length )						
	{
		atl_read_buffer( g_atl_buffer, g_atl_access_length );	
		atl_buffer_parse( g_atl_buffer );
	}

	g_atl_access_length		= 0;	


	if(g_is_add)
		for( i=0; i< NUMBER_OF_TRANSFER_TYPES;i++)
		{	
			g_is_add = 0;
			if(g_insert_tr_list_ptr[i] == NULL)
				continue;

			if(g_tr_list_ptr[i]==NULL)
			{	
				g_tr_list_ptr[i] =  g_insert_tr_list_ptr[i];
				g_insert_tr_list_ptr[i]=NULL;
				continue;
			}
			else
			{
				tr_instance_ptr = g_tr_list_ptr[i]->tr_list_for_tr.Flink;	

				g_tr_list_ptr[i]->tr_list_for_tr.Flink = g_insert_tr_list_ptr[i]->tr_list_for_tr.Flink;
				tr_instance_ptr->tr_list_for_tr.Blink = g_insert_tr_list_ptr[i];
				g_insert_tr_list_ptr[i]->tr_list_for_tr.Flink = tr_instance_ptr;	
				g_insert_tr_list_ptr[i] = NULL;
			}
		}
	
	atl_schedule( g_atl_buffer, InitVal_HcATLBufferLength, &g_atl_access_length);	

	if ( g_atl_access_length )
		atl_write_buffer( g_atl_buffer, g_atl_access_length );		
}



void atl_read_buffer( unsigned char *bp, unsigned short length )
{
	write_register16( Com16_HcTransferCounter, length );
	read_register_burst_char( Com16_HcATLBufferPort, bp, length );
}


void atl_write_buffer( unsigned char *bp, unsigned short length )
{
	write_register16( Com16_HcTransferCounter, length );
	write_register_burst_char( Com16_HcATLBufferPort, bp, length );
}


#ifdef	TRANSFER_STATUS_MONITOR
#include	<conio.h>
#endif


void atl_buffer_parse( unsigned char *ptd_start )
{
	transfer_instance	*tr_inst_ptr;
	PTD_header_param	ph;
	int					i;

	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->data_ptr_start == NULL )
				continue;												
	   		if ( tr_inst_ptr->readout_position == NULL )
				continue;												
			ptd_start	= tr_inst_ptr->readout_position;
			
			get_PTD_header( &ph, ptd_start );	

			   if ( i == BULK_TRANSFER)
					tr_inst_ptr->readout_position	= NULL;									
	

⌨️ 快捷键说明

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