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

📄 atl_mix.c

📁 基于ARM的读U盘
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************/
/*	includes																*/
/****************************************************************************/
#include "HostStack.h"

#ifndef	MAX_TRANSFER_LIST
#define MAX_TRANSFER_LIST			60		// 设置传输描述符个数,最小值为1
#endif
/****************************************************************************/
/*	constants																*/
/****************************************************************************/
#define	PTD_HEADER_LENGTH			8
#define	NUMBER_OF_TRANSFER_TYPES	3		//	3 = control + interr + bulk (ATL传输类型)
#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;// 访问ATL缓冲区长度
transfer_instance	g_transfer_list[ MAX_TRANSFER_LIST ];					// 传输描述符
unsigned char		g_static_atl_buffer[ InitVal_HcATLBufferLength + 3 ];	// 加3为了确保字对齐
unsigned char		*g_atl_buffer;											// ATL RAM缓冲区指针
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													*/
/****************************************************************************/
//******************************************************************************************
//函数名称:atl_initialize
//输入参数:无
//输出参数:无
//功能描述:ATL传输列表初始化。
//******************************************************************************************
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 );	// 安装ATL传输函数
	install_SOF_service_routine(    1, atl_ATL_transfer_mixer );	// 安装ITL(同步)传输函数
}


unsigned char g_is_add = 0;
//****************************************************************************************
// 函数名称:insert_transfer_descriptor
// 输入参数:tr_instance_ptr,将插入的
//				   transfer_type,传输类型,代号与端点类型一至
// 输出参数:无
// 功能描述:插入一个传输描述符到插入链表。
//****************************************************************************************
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();
	
}

//******************************************************************************************
//函数名称:atl_get_open_index
//输入参数:epi_ptr,端点描述数据结构
//输出参数:正常返回:transfer_instance指针
//				  出错返回:ATL_ENDPOINT_ERR
//				  				NO_OPEN_ATL_TRANSFER
//功能描述:在传描述符数据结构列表中,查找空闲的传输描述符数据结构
//******************************************************************************************
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;		// 锁定该传输描述符数据结构,低7位为索引号
			os_event_ptr = OSMboxCreate(NULL);	// 创建一个消息事件
			if(os_event_ptr)
				(g_transfer_list[ j ]).os_event_ptr = os_event_ptr;					// 保存OS事件指针
			else
			{
				(g_transfer_list[ j ]).lock	= UNLOCK;		// 锁定该传输描述符数据结构,低7位为索引号
				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;// 记录端点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 ;
}

//******************************************************************************************
//函数名称:atl_free_index,
//输入参数:tr_instance_ptr,传输描述符数据结构指针
//输出参数:无
//功能描述:释放传输索引
//******************************************************************************************
void atl_close_transfer_instance( transfer_instance *tr_instance_ptr  )
{
 	unsigned char err;
	OS_MBOX_DATA Mbox_data;
	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;

	/*查询是否在任务在等待该消息*/
	OSMboxQuery(tr_instance_ptr->os_event_ptr, 
				&Mbox_data );
	if(Mbox_data.OSEventGrp)						// 有任务在等待该消息
	{
		tr_instance_ptr->completion_code = OS_EVENT_DELETE;			// 标记该传输描述符已被删除
		OSMboxPost( tr_instance_ptr->os_event_ptr, 
				      &tr_instance_ptr->completion_code);	// 向等待消息的任务发送消息
		return;
	}
	
	OSMboxDel( tr_instance_ptr->os_event_ptr, 		// 删除传输描述符使用的事件
			    OS_DEL_ALWAYS , &err  );
	tr_instance_ptr->os_event_ptr = NULL;

}


//******************************************************************************************
// 函数名称:atl_set_transfer
// 输入参数:tr_inst_ptr,传输描述符数据结构指针
//		   buffer_ptr,数据缓冲区指针
//		   length,传输数据长度
// 		   direction,传输方向
//		   callback,传输完成回调函数
// 输出参数:正常返回TRUE,出错返回FALSE。
// 功能描述:设置传输处理。
//******************************************************************************************
 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;			// 设置传输方向(SETUP、IN、OUT)
	tr_inst_ptr->callback			= callback;			// 保存回调函数结构指针
	tr_inst_ptr->readout_position	= NULL;			// 初始化为空
	tr_inst_ptr->transferred_size	= 0;				// 初始化传输数据长度为0
	tr_inst_ptr->fatal_error			= 0;   			// 初始化出错记录为0
	tr_inst_ptr->completion_code	= 0;				// 初始化完成代码为0
	tr_inst_ptr->schedule_rate		= schedule_rate;		// 设置调度时间间隔
	tr_inst_ptr->poll_timing_timer	= g_sof_counter + tr_inst_ptr->schedule_rate;
	// 设置data_ptr_start指针,当该指针成员被设置,中断中将会处理该传输
	tr_inst_ptr->data_ptr_start		= tr_inst_ptr->data_ptr_base;		//	This should be last. ISR detects the list enabled by this pointer setting.

	return TRUE;
}

//******************************************************************************************
//函数名称:re_enable_interrupt_transfer
//输入参数:tr_inst_ptr,中断传输描述信息结构指针
//输出参数:无
//功能描述:重新使能中断传输。
//******************************************************************************************
void re_enable_interrupt_transfer( transfer_instance *tr_inst_ptr )
{
	// data_ptr_start,不为空指针时,该传输将被调度
	tr_inst_ptr->data_ptr_start		= tr_inst_ptr->data_ptr_base;
}


/*	interrupt service routines  */

//***********************************************************************
//函数名称:atl_ATL_transfer_mixer
//输入参数:无
//输出参数:无
//功能描述:ATL传输处理
//***********************************************************************
void atl_ATL_transfer_mixer( void )
{
	unsigned short	atl_stat;
	unsigned short	atl_full;
	unsigned short	atl_done;

⌨️ 快捷键说明

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