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

📄 drv_usb_ctl.c

📁 sparc硬件平台上的usb驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
			sizeof (USB_STRING_LANG_ID_DESCRIPTOR);		//              code_transmit((D_UINT8 *)&(usb_descr.LangIDDescr), ControlData.DeviceRequest.wLength);	    }	  // 主机要求获取接口描述符      }    else if (bDescriptor == USB_INTERFACE_DESCRIPTOR_TYPE)      {	  if (ControlData.DeviceRequest.wLength >	      sizeof (USB_INTERFACE_DESCRIPTOR))	      ControlData.DeviceRequest.wLength =		  sizeof (USB_INTERFACE_DESCRIPTOR);	  //      code_transmit((D_UINT8 *)&(usb_descr.InterfaceDescr), ControlData.DeviceRequest.wLength);	  //}else if (bDescriptor == USB_ENDPOINT_DESCRIPTOR_TYPE) {	  //      code_transmit((D_UINT8 *)&DeviceDescr, sizeof(USB_DEVICE_DESCRIPTOR));      }    else	stall_ep0 ();		//没有该请求,返回STALL    USB_SetEndpointReady (0, 1);}/**************************************** ** 函数名称: void set_descriptor(void) ** 功能描述: 设置描述符 *****************************************/voidset_descriptor (void){    USB_SetEndpointReady (0, 1);}/**************************************** ** 函数名称: void get_configuration(void) ** 功能描述: 获取配置 *****************************************/voidget_configuration (void){    D_UINT8 c = bEPPflags.bits.configuration;	//取出配置值    single_transmit (&c, 1);	//发送配置值    USB_SetEndpointReady (0, 1);}/**************************************** ** 函数名称: void set_configuration(void) ** 功能描述: 设置配置 *****************************************/// 如果设备没有收到此命令,会使用其默认的配置1voidset_configuration (void){	frm_printf("set_configuration");    if (ControlData.DeviceRequest.wValue == 0)      {				//配置值不对,设备进入未配置状态	  DISABLE ();	  bEPPflags.bits.configuration = 0;	//标记未配置	  ENABLE ();	  init_unconfig ();	//进入地址状态,禁止0除外的所有端点      }    else if (ControlData.DeviceRequest.wValue == 1)      {				//配置设备	  init_unconfig ();	//进入地址状态,禁止0除外的所有端点	  init_config ();	//配置处理,允许端点收发	  DISABLE ();	  bEPPflags.bits.configuration = 1;	//标志已配置	  ENABLE ();      }    else	stall_ep0 ();		//没有该请求,返回STALL    USB_SetEndpointReady (0, 1);}/**************************************** ** 函数名称: void get_interface(void) ** 功能描述: 获取接口信息 *****************************************/voidget_interface (void){    D_UINT8 txdat = 0;		//本设备只有一个接口    single_transmit (&txdat, 1);	//发送一个字节    USB_SetEndpointReady (0, 1);}/**************************************** ** 函数名称: void set_interface(void) ** 功能描述: 设置接口信息 *****************************************/voidset_interface (void){    USB_SetEndpointReady (0, 1);} voidsynch_frame (void){    D_UINT8 frame_number[2];    frame_number[0] = 0x33;    frame_number[1] = 0x3;    code_transmit (frame_number, 2);    USB_SetEndpointReady (0, 1);} voidget_max_lun (void){    D_UINT8 c;    c = 0;    code_transmit (&c, 1);}/************************************************************* ** 函数名称: void control_handler(void) ** 功能描述: 控制传输(执行控制命令 -- 13中控制命令) **************************************************************/voidcontrol_handler (void){    D_UINT8 type, req;    type = ControlData.DeviceRequest.bmRequestType & USB_REQUEST_TYPE_MASK;    //读取请求代码    req = ControlData.DeviceRequest.bRequest & USB_REQUEST_MASK;printf("req=%d\n",req);    if (type == USB_STANDARD_REQUEST)	(*StandardDeviceRequest[req]) ();	//标准请求处理    //else if (type == USB_VENDOR_REQUEST)           //厂商请求    //      (*VendorDeviceRequest[req])();    else if (type == USB_CLASS_REQUEST)	(*ClassDeviceRequest[req]) ();	//类请求,如大容量类    else	stall_ep0 ();		//无效请求,返回STALL                             }// 读取主机发来的命令, 并根据命令执行相应动作voidep0_setupdone (void){    D_UINT8 req[sizeof (DEVICE_REQUEST)];    ControlData.wLength = 0;	//传输字节总数清0    ControlData.wCount = 0;	//传输字节计数器清0    // 读取主机发来的命令及其参数,并保存到req中  /*  if (USB_ReadEndpoint (0, sizeof (ControlData.DeviceRequest), req)	!= sizeof (DEVICE_REQUEST))      {	  //从端点0读8个字节失败	  USB_SetEndpointStall (0, 1);	//停止控制端点0	  //USB_SetEndpointStall(1, 1);                    //停止控制端点1	  bEPPflags.bits.control_state = USB_IDLE;	//设置为等待状态	  return;      }*/	/******* 以下语句通信中的解决大小端问题,使该函数与编译器无关 ****/    // 将读取的命令及其参数赋值到ControlData中	memcpy(req,rx_data,8);	free(rx_data);	int i;	for(i=0;i<8;i++)		printf("%d\n",req[i]);    ControlData.DeviceRequest.bmRequestType = req[0];    ControlData.DeviceRequest.bRequest = req[1];    ControlData.DeviceRequest.wValue = (req[3] << 8) | req[2];    ControlData.DeviceRequest.wIndex = (req[5] << 8) | req[4];    ControlData.DeviceRequest.wLength = (req[7] << 8) | req[6];	/********  接收建立包成功 **********/    //USB_AcknowledgeEndpoint(0);    //对控制端点0进行建立包应答    //USB_AcknowledgeEndpoint(1);    //对控制端点1进行建立包应答    ControlData.wLength = ControlData.DeviceRequest.wLength;	//取出要传输数据的总字节数    // 查看紧跟该命令之后的数据的传输方向    // 如果数据的传输方向是: 设备至主机(直接执行命令,并将主机需要的数据写入FIFO中)    if (ControlData.DeviceRequest.	bmRequestType & (D_UINT8) USB_ENDPOINT_DIRECTION_MASK)    {		printf("ep0 in\n");	    //如果控制传输是控制读取	    //bEPPflags.bits.setup_packet = 1;                             	    //通知control_handler()处理Setup包	  	bEPPflags.bits.control_state = USB_TRANSMIT;	//设置为发送状态	    control_handler ();	//调用请求处理子程序    }    // 如果数据的传输方向是: 主机至设备    else    {						//控制传输是控制写入	  // 如果该命令没有后续数据	  printf("ep0 out\n");	    if (ControlData.DeviceRequest.wLength == 0)	    {			// bEPPflags.bits.setup_packet = 1;                       		 	//通知control_handler()处理Setup包                                			bEPPflags.bits.control_state = USB_IDLE;	//设置为等待状态			// SET_ADDRESS命令需要等到IN包到来时才能执行,这里只是标识有该命令需要执行			if (ControlData.DeviceRequest.bRequest == USB_REQUEST_SET_ADDRESS)		    {		    	bEPPflags.bits.command = CMD_SET_ADDRESS;		    	USB_SetEndpointReady (0, 1);		    }			else		    	control_handler ();	//调用命令处理子程序	    }	    else	    {		// 数据长度出错		if (ControlData.DeviceRequest.wLength > MAX_CONTROLDATA_SIZE)		{			bEPPflags.bits.control_state = USB_IDLE;	//设置为等待状态 		    USB_SetEndpointStall (0, 1);	//停止控制端点0		}		// udc准备接收数据		else		  {		      bEPPflags.bits.control_state = USB_RECEIVE;	//设置为接收状态		      USB_SetEndpointReady (0, 1);		  }	    }			// set command with data      }				// else set command    USB_SetEndpointReady(0,1);}/*************************************** ** 函数名称: void ep0_rxdone(void) ** 功能描述: 通过端点索引 0 接收数据 ** 输	 入: 无 ** 输	 出: 无 ***************************************/// EP0收到OUT包后的处理函数;接收HOST发来的数据// 如果EP0收到的是命令有后续的数据输出,则调用该函数,负责接收后续的输出数据voidep0_outdone (void){    D_INT16 i;	/*****  下面为控制写入的数据阶段  ***************/    if (bEPPflags.bits.control_state == USB_RECEIVE)    {				//如果为接收状态	  //从端点0接收数据(收到的数据作何处理? )		i = USB_ReadEndpoint (0, MAX_CONTROLDATA_SIZE,				ControlData.dataBuffer + ControlData.wCount);	  	ControlData.wCount += i;	//统计已接收的字节数	  	//数据接收完毕	  	if (i != MAX_CONTROLDATA_SIZE	      || ControlData.wCount >= ControlData.wLength)	  	{			//bEPPflags.bits.setup_packet = 1;                       			//通知control_handler()处理Setup包                                  			bEPPflags.bits.control_state = USB_IDLE;	//设置为等待状态			control_handler();                          //调用请求处理子程序		    return;	    }      }    else		bEPPflags.bits.control_state = USB_IDLE;	//设置等待状态    USB_SetEndpointReady (0, 1);}/*************************************** ** 函数名称: void ep0_txdone(void) ** 功能描述: 通过端点索引 0 发送数据 ** 输	 入: 无 ** 输	 出: 无 ***************************************/// EP0收到IN包,UDC发送数据到HOSTvoidep0_indone (void){    D_INT16 i = ControlData.wLength - ControlData.wCount;	//计算未发送的字节数    //USB_ReadLastTransactionStatus(1);                             //清除中断寄存器标志位    // SET_ADDRESS命令将在数据阶段得到执行(无可发送数据)    if (bEPPflags.bits.control_state != USB_TRANSMIT)    {				//非发送状态                                                                                               	  //single_transmit(0, 0);        	  	if (bEPPflags.bits.command == CMD_SET_ADDRESS)	    {			bEPPflags.bits.command = CMD_IDLE;			control_handler ();	    }	  	else	      	USB_SetEndpointReady (0, 1);	  	return;		//返回    }    if (i >= EP0_PACKET_SIZE)    {				//未发送字节数大于16,发送16个字节	  	USB_WriteEndpoint (0, EP0_PACKET_SIZE,			     ControlData.pData + ControlData.wCount);	  	ControlData.wCount += EP0_PACKET_SIZE;	  	bEPPflags.bits.control_state = USB_TRANSMIT;    }    else if (i != 0)    {				//发送所有未发送的字节	  	USB_WriteEndpoint (0, i, ControlData.pData + ControlData.wCount);	 	ControlData.wCount += i;	  	bEPPflags.bits.control_state = USB_IDLE;	//置状态为等待状态    }    else if (i == 0)    {	  	USB_WriteEndpoint (0, 0, 0);	//发送完毕,发0个字节	  	bEPPflags.bits.control_state = USB_IDLE;    }}

⌨️ 快捷键说明

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