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

📄 mass_bulktrance.c

📁 usb host在ARM7上的实现
💻 C
字号:
#include "HostStack.h"

uint8 BulkGetCSWStatus(transfer_instance *Bulk_tr_In_Ptr,  uint8 *CBW_BuffPtr);
void BulkCBWSet(	uint8 *CBW_BuffPtr,
					uint32 DataTransferLength,
					uint8 CBWFlags, 
					uint8 bCBW_LUN,
					uint8 CBWCBLength,
					uint8 *RBC_BuffPtr);
uint8 BulkCommand_handle(	MassStorageClass *MSC_ptr,
								uint8		*CBW_BuffPtr,
								uint8		*Data_BuffPtr,
								uint8		Tr_Direction,
								uint16		*transfer_size);



//******************************************************************************************
// 函数名称:MassStorageReset
// 输入参数:DevicePtr,设备描述信息结构指针
// 输出参数:TRUE,正常完成
// 		   FALSE,出错
// 功能描述:大容量设备复位请求。
//******************************************************************************************
unsigned char MassStorageReset(device_instance * DevicePtr)
{
	unsigned char None 		=0;
	USB_Device_Request		req;		// 设备请求结构
	unsigned short			err;

	req.bmRequestType		= 0x21;				// 大容量容中的,获取最大单元号
	req.bRequest			= 0xff;
	req.wValue				= 0;
	req.wIndex				= 0;
	req.wLength			= 0;
	err = control_transfer( &req, DevicePtr, &None );		// 发送控制传输
	return 	(err ? FALSE : TRUE);
}

//******************************************************************************************
// 函数名称:GetMaxLUN
// 输入参数:DevicePtr,设备描述信息结构指针
// 输出参数:返回最大逻辑单元数,返回值为0表示只有1个逻辑单元存在。
//		   出错返回去0xff.
// 功能描述:获取设备的逻辑单元总数请求。
//******************************************************************************************
unsigned char GetMaxLUN(device_instance * DevicePtr)
{
	unsigned char MaxLUN	 =0;
	USB_Device_Request	req;						// 设备请求结构
	req.bmRequestType	= 0xa1;					// 大容量容中的,获取最大单元号
	req.bRequest			= 0xfe;
	req.wValue			= 0;
	req.wIndex			= 0;
	req.wLength			= 1;
	if ( control_transfer( &req, DevicePtr, &MaxLUN ) )		// 发送控制传输
		return 	( 0xff );
	return 	(MaxLUN);
}

//*****************************************************************************************
// 函数名称:ResetRecovery
// 输入参数:dvi_ptr,设备描述信息数据结构
// 输出参数:TRUE,正常返回,
//				    FALSE,出错返回。
// 功能描述:复位恢复处理。
//*****************************************************************************************
uint8 ResetRecovery(device_instance * dvi_ptr)
{
	endpoint_info *epi_ptr;
	if(FALSE == MassStorageReset(dvi_ptr))			// 大容量设备复位
		return FALSE;
	epi_ptr = find_endport_type(dvi_ptr, Ep_TransferType_Bulk, Ep_Direction_IN_ENDPOINT, 1);
	if(FALSE == ClearEndpointSTALL( dvi_ptr,  epi_ptr))	// 清批量输出停止状态
		return FALSE;
	epi_ptr = find_endport_type(dvi_ptr, Ep_TransferType_Bulk, Ep_Direction_OUT_ENDPOINT, 1);		
	if(FALSE == ClearEndpointSTALL( dvi_ptr,  epi_ptr))	// 清批量输入停止状态
		return FALSE;
	return TRUE;
}




//*****************************************************************************************
// 函数名称:BulkOnlyTransport
// 输入参数:tr_with_rbc_ptr,设备描述信息数据结构
// 输出参数:COMMAND_PASSED,命令完成
//				    COMMAND_FAILED,命令失败
//				    PHASE_ERROR,相位出错
//   				    PERSISTENT_FAILURE,严重出错
// 功能描述:复位恢复处理。
//*****************************************************************************************
uint8 BulkOnlyComHandle(TR_With_RBC *tr_with_rbc_ptr)
{
	uint8		CSWStatus;

		/* CBW设置 */
	BulkCBWSet(	tr_with_rbc_ptr->MSC->CBW_BuffPtr,
				tr_with_rbc_ptr->DataTransferLength,
				tr_with_rbc_ptr->TrDirection,
				tr_with_rbc_ptr->LUN,
				tr_with_rbc_ptr->CBLength,
				tr_with_rbc_ptr->MSC->RBC_BuffPtr
				);
	/* CBW处理 */
	CSWStatus = BulkCommand_handle( tr_with_rbc_ptr->MSC,
									  tr_with_rbc_ptr->MSC->CBW_BuffPtr, 
									  tr_with_rbc_ptr->Data_BuffPtr, 
									  tr_with_rbc_ptr->TrDirection, 
									  &tr_with_rbc_ptr->DataTransferLength);

	if( CSWStatus == FALSE )/* 设备发生了不可纠正的错误 */
		return PERSISTENT_FAILURE;

	/* 接收CSW */
	CSWStatus = BulkGetCSWStatus(	tr_with_rbc_ptr->MSC->tr_bulk_in_ptr, 
									tr_with_rbc_ptr->MSC->CBW_BuffPtr);

	/* 返回命令执行状态 */
	if(CSWStatus == COMMAND_PASSED)
		return COMMAND_PASSED;

	if((CSWStatus == 0xff)||(CSWStatus == PHASE_ERROR))
	{	/*执行复位恢复*/
		if( FALSE == ResetRecovery(tr_with_rbc_ptr->MSC->dvi_ptr))
			return PERSISTENT_FAILURE;			/* 复位恢复不能正常完成 */ 
		
		return PHASE_ERROR;
	}

	if(CSWStatus == COMMAND_FAILED)
		return COMMAND_FAILED;
		
	return PERSISTENT_FAILURE;
}


//******************************************************************************************
// 函数名称:BulkCommand_handle
// 输入参数:Bulk_tr_In_Ptr,批量输入传输描述符
//				    Bulk_tr_Out_Ptr,批量输出传输描述符
//				    CBW_BuffPtr,命令包缓冲区指针
//				    Data_BuffPtr,数据缓冲区指针
//				    Tr_Direction,数据传输方向,输入、输出、无数据
//				    transfer_size,传输的数据长度。
// 输出参数:TRUE,正常完成
//				    FALSE,出错
// 功能描述:单批量协议命令处理。
//******************************************************************************************
uint8 BulkCommand_handle(	MassStorageClass *MSC_ptr,
								uint8		*CBW_BuffPtr,
								uint8		*Data_BuffPtr,
								uint8		Tr_Direction,
								uint16		*transfer_size)
{
	uint8			Completion_Code;
	uint16			CBW_size;
	device_instance 	*dvi_ptr;
	endpoint_info 		*epi_ptr;

	/* 命令包输出 */
	CBW_size = 31;				/* 包长度固定为31字节 */
	Completion_Code = bulk_transaction( DirectionPID_OUT, CBW_BuffPtr, &CBW_size, MSC_ptr->tr_bulk_out_ptr);
	if(Completion_Code)
		return FALSE;			// 没有定义的错误
	if(Tr_Direction == IN_DATA)
		Completion_Code = bulk_transaction(DirectionPID_IN,Data_BuffPtr, transfer_size, MSC_ptr->tr_bulk_in_ptr);
	if(Tr_Direction ==OUT_DATA)
		Completion_Code = bulk_transaction(DirectionPID_OUT,Data_BuffPtr, transfer_size, MSC_ptr->tr_bulk_out_ptr);
	if(Completion_Code)
	{
		if(Completion_Code == 0x04)		// 如果端点停止
		{
			if(Tr_Direction == IN_DATA)	// 清批量输入端点STALL
			{
				epi_ptr = MSC_ptr->tr_bulk_in_ptr->epi_ptr;			// 端点描述信息数据结构指针
				dvi_ptr = MSC_ptr->dvi_ptr;	// 设备描述信息数据结构指针
				return ClearEndpointSTALL( dvi_ptr, epi_ptr);
			}

			if(Tr_Direction ==OUT_DATA)	// 清批量输出端点STALL
			{
				epi_ptr = MSC_ptr->tr_bulk_out_ptr->epi_ptr;			// 端点描述信息数据结构指针
				dvi_ptr = MSC_ptr->dvi_ptr;	// 设备描述信息数据结构指针
				return ClearEndpointSTALL( dvi_ptr, epi_ptr);
			}
		}
		if(Completion_Code == 0x09)
			return TRUE;
		return FALSE;			// 没有定义的错误
	}
	return TRUE;					// 没有定义的错误
}

//************************************************************************************
// 函数名称:BulkGetCSWStatus
// 输入参数:Bulk_tr_In_Ptr,批量输入传输描述符
//				    CBW_BuffPtr,命令块包缓冲区指针
// 输出参数:正常返回命令状态:0、1、2
//				    出错返回0xff;
// 功能描述:获取命令状态包
//************************************************************************************
uint8 BulkGetCSWStatus(transfer_instance *Bulk_tr_In_Ptr,  uint8 *CBW_BuffPtr)
{
	#define CSW_LENGTH		13
	COMMAND_STATUS_WRAPPER	CSWB;
	uint8	CSWStatus;
	uint16	transfer_size = CSW_LENGTH;
	uint32	dCSWDataResidue;
	uint32	dCBW_DataXferLen;
	COMMAND_BLOCK_WRAPPER *CBW_ptr;

	CBW_ptr = (COMMAND_BLOCK_WRAPPER *) CBW_BuffPtr;
	CSWStatus = bulk_transaction(DirectionPID_IN, (uint8 *)&CSWB, 
							     &transfer_size,  Bulk_tr_In_Ptr);
	
	if(CSWStatus==NULL)
	{
		/* 检验CSW是否有效 */
		if(transfer_size == CSW_LENGTH)
			if((CSWB.dCSW_Signature_0==0x55)&&
				(CSWB.dCSW_Signature_1==0x53)&&
				(CSWB.dCSW_Signature_2==0x42)&&
				(CSWB.dCSW_Signature_3==0x53)&&
				(CSWB.dCSW_Tag == CBW_ptr->dCBW_Tag))
			{	/* 检验CSW是否有意义 */
				if(CSWB.bCSW_Status==PHASE_ERROR)
					return (PHASE_ERROR);
				if(CSWB.bCSW_Status < PHASE_ERROR)
				{
					dCSWDataResidue = CSWB.dCSW_DataResidue_0+
									   CSWB.dCSW_DataResidue_1*0x100+
									   CSWB.dCSW_DataResidue_2*0x10000+
									   CSWB.dCSW_DataResidue_3*0x1000000;
					dCBW_DataXferLen =  CBW_ptr->dCBW_DataXferLen_0+
									     CBW_ptr->dCBW_DataXferLen_1*0x100+
									     CBW_ptr->dCBW_DataXferLen_2*0x10000+
									     CBW_ptr->dCBW_DataXferLen_3*0x1000000;
					if(dCSWDataResidue <= dCBW_DataXferLen)
						return CSWB.bCSW_Status;
				}	
				
			}
	}
	return (0xff);
}
	
//************************************************************************************
// 函数名称:BulkCBWSet
// 输入参数:CBW_BuffPtr,命令包缓冲区指针
//				    DataTransferLength,数据传输的字节数
//				    CBWFlags,传输的方向,0为主机到设备、非0设备到主机。
//				    CBWCBLength,命令有效长度
//				    RBC_BuffPtr,命令缓冲区指针
// 输出参数:无
// 功能描述:大容量单批量传输CBW设置
//************************************************************************************
void BulkCBWSet(	uint8 *CBW_BuffPtr,
					uint32 DataTransferLength,
					uint8 CBWFlags, 
					uint8 bCBW_LUN,
					uint8 CBWCBLength,
					uint8 *RBC_BuffPtr)
{
	COMMAND_BLOCK_WRAPPER *CBW_ptr;
	uint8 *RBC_in_CBW_ptr;
	CBW_ptr = (COMMAND_BLOCK_WRAPPER *) CBW_BuffPtr;
	/* 固定特征码在初始化时已设置并一直保持 */
	CBW_ptr->dCBW_Tag ++;
	CBW_ptr->dCBW_DataXferLen_0 = (uint8)DataTransferLength;
	CBW_ptr->dCBW_DataXferLen_1 = (uint8)(DataTransferLength/0x100);
	CBW_ptr->dCBW_DataXferLen_2 = (uint8)(DataTransferLength/0x10000);
	CBW_ptr->dCBW_DataXferLen_3 = (uint8)(DataTransferLength/0x1000000);
	CBW_ptr->bCBW_Flag = (CBWFlags == OUT_DATA)? 0x00 :0x80 ;
	CBW_ptr->bCBW_LUN = bCBW_LUN;
	CBW_ptr->bCBW_CDBLength = CBWCBLength;

	RBC_in_CBW_ptr = &CBW_ptr->bCBW_CDBLength +1;
	memset(RBC_in_CBW_ptr,0,16);
	memcpy( RBC_in_CBW_ptr , RBC_BuffPtr, CBWCBLength );
}




⌨️ 快捷键说明

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