usb.c

来自「SAMSUNG S3C6410 CPU BSP for winmobile6」· C语言 代码 · 共 1,937 行 · 第 1/5 页

C
1,937
字号
// Input : NONE
// Output : NONE
// Version :
void OTGDEV_HandleEvent_EP0(void)
{
	UINT32 DeviceRequestLength;
	UINT16 i;
	UINT32 ReadBuf[64]={0x0000, };
	UINT16 setaddress;
	UINT32 uRemoteWakeUp=0;

	if (oOtgDev.m_uEp0State == EP0_STATE_INIT)
	{

		for(i=0;i<2;i++)
		{
			//ReadBuf[i] = Inp32(EP0_FIFO);
			ReadBuf[i] = Input32(EP0_FIFO);
		}

		oOtgDev.m_oDeviceRequest.bmRequestType=ReadBuf[0];
		oOtgDev.m_oDeviceRequest.bRequest=ReadBuf[0]>>8;
		oOtgDev.m_oDeviceRequest.wValue_L=ReadBuf[0]>>16;
		oOtgDev.m_oDeviceRequest.wValue_H=ReadBuf[0]>>24;
		oOtgDev.m_oDeviceRequest.wIndex_L=ReadBuf[1];
		oOtgDev.m_oDeviceRequest.wIndex_H=ReadBuf[1]>>8;
		oOtgDev.m_oDeviceRequest.wLength_L=ReadBuf[1]>>16;
		oOtgDev.m_oDeviceRequest.wLength_H=ReadBuf[1]>>24;

//		OTGDEV_PrintEp0Pkt((UINT8 *)&oOtgDev.m_oDeviceRequest, 8);

		switch (oOtgDev.m_oDeviceRequest.bRequest)
		{
			case STANDARD_SET_ADDRESS:
				setaddress = (oOtgDev.m_oDeviceRequest.wValue_L); // Set Address Update bit
				Outp32(DCFG, 1<<18|setaddress<<4|oOtgDev.m_eSpeed<<0);
				DBGUSB(("Func_ADDR_Setaddr : %d \n", setaddress));
				oOtgDev.m_uEp0State = EP0_STATE_INIT;
				break;

			case STANDARD_SET_DESCRIPTOR:
				DBGUSB(("\n MCU >> Set Descriptor \n"));
				break;

			case STANDARD_SET_CONFIGURATION:
				DBGUSB(("\n MCU >> Set Configuration \n"));
				g_usConfig = oOtgDev.m_oDeviceRequest.wValue_L; // Configuration value in configuration descriptor
				oOtgDev.m_uIsUsbOtgSetConfiguration = 1;
				break;

			case STANDARD_GET_CONFIGURATION:
				OTGDEV_SetInEpXferSize(EP_TYPE_CONTROL, 1, 2);
				Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(3<<0));	//ep0 enable, clear nak, next ep0, 8byte
				Outp32(EP0_FIFO, g_usConfig);
				oOtgDev.m_uEp0State = EP0_STATE_INIT;
				break;

			case STANDARD_GET_DESCRIPTOR:
				switch (oOtgDev.m_oDeviceRequest.wValue_H)
				{
					case DEVICE_DESCRIPTOR:
						DBGUSB(("\n MCU >> Get Device Descriptor \n"));
						oOtgDev.m_uEp0State = EP0_STATE_GD_DEV_0;
						break;

					case CONFIGURATION_DESCRIPTOR:
						DBGUSB(("\n MCU >> Get Configuration Descriptor \n"));

						DeviceRequestLength = (UINT32)((oOtgDev.m_oDeviceRequest.wLength_H << 8) |
							oOtgDev.m_oDeviceRequest.wLength_L);

						if (DeviceRequestLength > CONFIG_DESC_SIZE){
						// === GET_DESCRIPTOR:CONFIGURATION+INTERFACE+ENDPOINT0+ENDPOINT1 ===
						// Windows98 gets these 4 descriptors all together by issuing only a request.
						// Windows2000 gets each descriptor seperately.
						// oOtgDev.m_uEpZeroTransferLength = CONFIG_DESC_TOTAL_SIZE;
							oOtgDev.m_uEp0State = EP0_STATE_GD_CFG_0;
						}
						else
							oOtgDev.m_uEp0State = EP0_STATE_GD_CFG_ONLY_0; // for win2k
						break;

					case STRING_DESCRIPTOR :
						switch(oOtgDev.m_oDeviceRequest.wValue_L)
						{
							case 0:
								oOtgDev.m_uEp0State = EP0_STATE_GD_STR_I0;
								break;
							case 1:
								oOtgDev.m_uEp0State = EP0_STATE_GD_STR_I1;
								break;
							case 2:
								oOtgDev.m_uEp0State = EP0_STATE_GD_STR_I2;
								break;
							default:
									break;
						}
						break;
					case ENDPOINT_DESCRIPTOR:
						switch(oOtgDev.m_oDeviceRequest.wValue_L&0xf)
						{
						case 0:
							oOtgDev.m_uEp0State=EP0_STATE_GD_EP0_ONLY_0;
							break;
						case 1:
							oOtgDev.m_uEp0State=EP0_STATE_GD_EP1_ONLY_0;
							break;
						default:
							break;
						}
						break;

					case DEVICE_QUALIFIER:
						DBGUSB(("\n MCU >> Get Device Qualifier Descriptor \n"));
						oOtgDev.m_uEp0State = EP0_STATE_GD_DEV_QUALIFIER;
						break;
				}
				break;

			case STANDARD_CLEAR_FEATURE:
				DBGUSB(("\n MCU >> Clear Feature \n"));
				switch (oOtgDev.m_oDeviceRequest.bmRequestType)
				{
					case DEVICE_RECIPIENT:
						if (oOtgDev.m_oDeviceRequest.wValue_L == 1)
							uRemoteWakeUp = false;
						break;

					case ENDPOINT_RECIPIENT:
						if (oOtgDev.m_oDeviceRequest.wValue_L == 0)
						{
							if ((oOtgDev.m_oDeviceRequest.wIndex_L & 0x7f) == 0x00)
								oStatusGet.Endpoint0= 0;

							if ((oOtgDev.m_oDeviceRequest.wIndex_L & 0x8f) == 0x01) // IN  Endpoint 1
								oStatusGet.Endpoint1= 0;

							if ((oOtgDev.m_oDeviceRequest.wIndex_L & 0x8f) == 0x02) // OUT Endpoint 3
								oStatusGet.Endpoint2= 0;
						}
						break;

					default:
						break;
				}
				oOtgDev.m_uEp0State = EP0_STATE_INIT;
				break;

			case STANDARD_SET_FEATURE:
				DBGUSB(("\n MCU >> Set Feature \n"));
				switch (oOtgDev.m_oDeviceRequest.bmRequestType)
				{
					case DEVICE_RECIPIENT:
						if (oOtgDev.m_oDeviceRequest.wValue_L == 1)
							uRemoteWakeUp = true;
							break;

					case ENDPOINT_RECIPIENT:
						if (oOtgDev.m_oDeviceRequest.wValue_L == 0)
						{
							if ((oOtgDev.m_oDeviceRequest.wIndex_L & 0x7f) == 0x00)
								oStatusGet.Endpoint0= 1;

							if ((oOtgDev.m_oDeviceRequest.wIndex_L & 0x8f) == 0x01)
								oStatusGet.Endpoint1= 1;

							if ((oOtgDev.m_oDeviceRequest.wIndex_L & 0x8f) == 0x02)
								oStatusGet.Endpoint2= 1;
						}
						break;

					default:
						break;
				}
				oOtgDev.m_uEp0State = EP0_STATE_INIT;
				break;

			case STANDARD_GET_STATUS:
				switch(oOtgDev.m_oDeviceRequest.bmRequestType)
				{
					case  (0x80):
						oStatusGet.Device=((UINT8)uRemoteWakeUp<<1)|0x1;		// SelfPowered
						oOtgDev.m_uEp0State = EP0_STATE_GET_STATUS0;
						break;

					case  (0x81):
						oStatusGet.Interface=0;
						oOtgDev.m_uEp0State = EP0_STATE_GET_STATUS1;
						break;

					case  (0x82):
						if ((oOtgDev.m_oDeviceRequest.wIndex_L & 0x7f) == 0x00)
							oOtgDev.m_uEp0State = EP0_STATE_GET_STATUS2;

						if ((oOtgDev.m_oDeviceRequest.wIndex_L & 0x8f) == 0x01)
							oOtgDev.m_uEp0State = EP0_STATE_GET_STATUS3;

						if ((oOtgDev.m_oDeviceRequest.wIndex_L & 0x8f) == 0x02)
							oOtgDev.m_uEp0State = EP0_STATE_GET_STATUS4;
						break;

					default:
						break;
				}
				break;

			case STANDARD_GET_INTERFACE:
				oOtgDev.m_uEp0State = EP0_STATE_INTERFACE_GET;
				break;

			case STANDARD_SET_INTERFACE:
				oInterfaceGet.AlternateSetting= oOtgDev.m_oDeviceRequest.wValue_L;
				oOtgDev.m_uEp0State = EP0_STATE_INIT;
				break;

			case STANDARD_SYNCH_FRAME:
				oOtgDev.m_uEp0State = EP0_STATE_INIT;
				break;

			default:
				break;
		}
	}
	OTGDEV_SetInEpXferSize(EP_TYPE_CONTROL, 1, oOtgDev.m_uControlEPMaxPktSize);
	Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(0<<0));	//ep0 enable, clear nak, next ep0, 64byte
}

//////////
// Function Name : OTGDEV_TransferEp0
// Function Desctiption : This function is called during data phase of control transfer.
// Input : NONE
// Output : NONE
// Version :
void OTGDEV_TransferEp0(void)
{

	DBGUSB(("TransferEp0 , oOtgDev.m_uEp0State == %d\n", oOtgDev.m_uEp0State));

	switch (oOtgDev.m_uEp0State)
	{
		case EP0_STATE_INIT:
			OTGDEV_SetInEpXferSize(EP_TYPE_CONTROL, 1, 0);
			Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(3<<0));	//ep0 enable, clear nak, next ep0, 8byte
			break;

		// === GET_DESCRIPTOR:DEVICE ===
		case EP0_STATE_GD_DEV_0:
			if (oOtgDev.m_eSpeed == USB_HIGH)
			{
				OTGDEV_SetInEpXferSize(EP_TYPE_CONTROL, 1, 18);
				Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(0<<0));	//ep0 enable, clear nak, next ep0, max 64byte
				OTGDEV_WrPktEp0((UINT8 *)&oOtgDev.m_oDesc.oDescDevice+0, 18); // EP0_PKT_SIZE
				oOtgDev.m_uEp0State = EP0_STATE_INIT;
				DBGUSB(("EndpointZeroTransfer(EP0_STATE_GD_DEV)\n"));
			}
			else
			{
				OTGDEV_SetInEpXferSize(EP_TYPE_CONTROL, 1, 18);
				Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(3<<0));	//ep0 enable, clear nak, next ep0, max 8byte
				OTGDEV_WrPktEp0((UINT8 *)&oOtgDev.m_oDesc.oDescDevice+0, 8); // EP0_PKT_SIZE
				oOtgDev.m_uEp0State = EP0_STATE_GD_DEV_1;
				DBGUSB(("EndpointZeroTransfer(FS:EP0_STATE_GD_DEV_0)\n"));
			}
			break;

		case EP0_STATE_GD_DEV_1:
			Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(3<<0));	//ep0 enable, clear nak, next ep0, 8byte
			OTGDEV_WrPktEp0((UINT8 *)&oOtgDev.m_oDesc.oDescDevice+8, 8); // EP0_PKT_SIZE
			oOtgDev.m_uEp0State = EP0_STATE_GD_DEV_2;
			DBGUSB(("EndpointZeroTransfer(EP0_STATE_GD_DEV_1)\n"));
			break;

		case EP0_STATE_GD_DEV_2:
			Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(3<<0));	//ep0 enable, clear nak, next ep0, 8byte
			OTGDEV_WrPktEp0((UINT8 *)&oOtgDev.m_oDesc.oDescDevice+16, 2); // EP0_PKT_SIZE
			oOtgDev.m_uEp0State = EP0_STATE_INIT;
			DBGUSB(("EndpointZeroTransfer(EP0_STATE_GD_DEV_2)\n"));
			break;

		// === GET_DESCRIPTOR:CONFIGURATION+INTERFACE+ENDPOINT0+ENDPOINT1 ===
		// Windows98 gets these 4 descriptors all together by issuing only a request.
		// Windows2000 gets each descriptor seperately.
		// === GET_DESCRIPTOR:CONFIGURATION ONLY for WIN2K===

		case EP0_STATE_GD_CFG_0:
			if (oOtgDev.m_eSpeed == USB_HIGH)
			{
				OTGDEV_SetInEpXferSize(EP_TYPE_CONTROL, 1, 32);
				Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(0<<0));	//ep0 enable, clear nak, next ep0, max 64byte
				OTGDEV_WrPktEp0((UINT8 *)&oOtgDev.m_oDesc.oDescConfig+0, 32); // EP0_PKT_SIZE
				oOtgDev.m_uEp0State = EP0_STATE_INIT;
				DBGUSB(("EndpointZeroTransfer(EP0_STATE_GD_CFG)\n"));
			}
			else
			{
				OTGDEV_SetInEpXferSize(EP_TYPE_CONTROL, 1, 32);
				Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(3<<0));	//ep0 enable, clear nak, next ep0, 8byte
				OTGDEV_WrPktEp0((UINT8 *)&oOtgDev.m_oDesc.oDescConfig+0, 8); // EP0_PKT_SIZE
				oOtgDev.m_uEp0State = EP0_STATE_GD_CFG_1;
				DBGUSB(("EndpointZeroTransfer(EP0_STATE_GD_CFG_0)\n"));
			}
			break;

		case EP0_STATE_GD_CFG_1:
			Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(3<<0));	//ep0 enable, clear nak, next ep0, 8byte
			OTGDEV_WrPktEp0((UINT8 *)&oOtgDev.m_oDesc.oDescConfig+8, 8); // EP0_PKT_SIZE	OTGDEV_WrPktEp0((UINT8 *)&descConf+8, 1); OTGDEV_WrPktEp0((UINT8 *)&descIf+0, 7);
			oOtgDev.m_uEp0State = EP0_STATE_GD_CFG_2;
			break;

		case EP0_STATE_GD_CFG_2:
			Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(3<<0));	//ep0 enable, clear nak, next ep0, 8byte
			OTGDEV_WrPktEp0((UINT8 *)&oOtgDev.m_oDesc.oDescConfig+16, 8); // EP0_PKT_SIZE	OTGDEV_WrPktEp0((UINT8 *)&descIf+7, 2); OTGDEV_WrPktEp0((UINT8 *)&descEndpt0+0, 6);
			oOtgDev.m_uEp0State = EP0_STATE_GD_CFG_3;
			break;

		case EP0_STATE_GD_CFG_3:
			Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(3<<0));	//ep0 enable, clear nak, next ep0, 8byte
			OTGDEV_WrPktEp0((UINT8 *)&oOtgDev.m_oDesc.oDescConfig+24, 8); // EP0_PKT_SIZE	OTGDEV_WrPktEp0((UINT8 *)&descEndpt0+6, 1); OTGDEV_WrPktEp0((UINT8 *)&descEndpt1+0, 7);
			oOtgDev.m_uEp0State = EP0_STATE_GD_CFG_4;
			break;

		case EP0_STATE_GD_CFG_4:
			oOtgDev.m_uEp0State = EP0_STATE_INIT;
			break;

		// === GET_DESCRIPTOR:CONFIGURATION ONLY===
		case EP0_STATE_GD_CFG_ONLY_0:
			if (oOtgDev.m_eSpeed == USB_HIGH)
			{
				DBGUSB(("[DBG : EP0_STATE_GD_CFG_ONLY]\n"));
				OTGDEV_SetInEpXferSize(EP_TYPE_CONTROL, 1, 9);
				Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(0<<0));	//ep0 enable, clear nak, next ep0, max 64byte
				OTGDEV_WrPktEp0((UINT8 *)&oOtgDev.m_oDesc.oDescConfig+0, 9); // EP0_PKT_SIZE
				oOtgDev.m_uEp0State = EP0_STATE_INIT;
			}
			else
			{
				DBGUSB(("[DBG : EP0_STATE_GD_CFG_ONLY_0]\n"));
				OTGDEV_SetInEpXferSize(EP_TYPE_CONTROL, 1, 9);
				Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(3<<0));	//ep0 enable, clear nak, next ep0, 8byte
				OTGDEV_WrPktEp0((UINT8 *)&oOtgDev.m_oDesc.oDescConfig+0, 8); // EP0_PKT_SIZE
				oOtgDev.m_uEp0State = EP0_STATE_GD_CFG_ONLY_1;
			}
			break;

		case EP0_STATE_GD_CFG_ONLY_1:
			DBGUSB(("[DBG : EP0_STATE_GD_CFG_ONLY_1]\n"));
			Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(3<<0));	//ep0 enable, clear nak, next ep0, 8byte
			OTGDEV_WrPktEp0((UINT8 *)&oOtgDev.m_oDesc.oDescConfig+8, 1); // EP0_PKT_SIZE
			oOtgDev.m_uEp0State = EP0_STATE_INIT;
			break;

		// === GET_DESCRIPTOR:INTERFACE ONLY===

		case EP0_STATE_GD_IF_ONLY_0:
			if (oOtgDev.m_eSpeed == USB_HIGH)
			{
				OTGDEV_SetInEpXferSize(EP_TYPE_CONTROL, 1, 9);
				Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(0<<0));	//ep0 enable, clear nak, next ep0, max 64byte
				OTGDEV_WrPktEp0((UINT8 *)&oOtgDev.m_oDesc.oDescInterface+0, 9);	// INTERFACE_DESC_SIZE
				oOtgDev.m_uEp0State = EP0_STATE_INIT;
			}
			else
			{
				OTGDEV_SetInEpXferSize(EP_TYPE_CONTROL, 1, 9);
				Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(3<<0));	//ep0 enable, clear nak, next ep0, 8byte
				OTGDEV_WrPktEp0((UINT8 *)&oOtgDev.m_oDesc.oDescInterface+0, 8);	// INTERFACE_DESC_SIZE
				oOtgDev.m_uEp0State = EP0_STATE_GD_IF_ONLY_1;
			}
			break;

		case EP0_STATE_GD_IF_ONLY_1:
			Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(3<<0));	//ep0 enable, clear nak, next ep0, 8byte
			OTGDEV_WrPktEp0((UINT8 *)&oOtgDev.m_oDesc.oDescInterface+8, 1);
			oOtgDev.m_uEp0State = EP0_STATE_INIT;
			break;


		// === GET_DESCRIPTOR:ENDPOINT 1 ONLY===
		case EP0_STATE_GD_EP0_ONLY_0:
			OTGDEV_SetInEpXferSize(EP_TYPE_CONTROL, 1, ENDPOINT_DESC_SIZE);
			Outp32(DIEPCTL0, (1u<<31)|(1<<26)|(BULK_IN_EP<<11)|(3<<0));	//ep0 enable, clear nak, next ep0, 8byte
			OTGDEV_WrPktEp0((UINT8 *)&oOtgDev.m_oDesc.oDescEndpt1+0, ENDPOINT_DESC_SIZE);
			oOtgDev.m_uEp0State = EP0_STATE_INIT;
			break;

		// === GET_DESCRIPTOR:ENDPOINT 2 ONLY===
		case EP0_STATE_GD_EP1_ONLY_0:

⌨️ 快捷键说明

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