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

📄 usbh_hcds_vhub.c

📁 epson usb2.0 控制芯片 S1R72V05 固件程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
//
//				  Initialize the virtual route hub
//
// argument 	: None
//
// return		: None
===============================================================================================*/
void USBH_HCDS_VHUBInit( void )
{
	memset(&VHUBStatus, 0, sizeof(VHUBStatus));
}

/*=============================================================================================
// Function_Name: USBH_HCDS_VHUBRegisterCBR
//
// description	: Register for notification target of port status changing
//
//				  Register the callback function of notification used when the port status of the virtual route hub changed
//
// argument 	: pfnCallback				(in)Pointer of callback function
//
// return		: None
===============================================================================================*/
void USBH_HCDS_VHUBRegisterCBR( CALLBACK_PROC pfnCallback )
{
	unsigned long vhubStatus;


	VHUBStatus.pfnCallback = pfnCallback;

	vhubStatus = 0;
	if( VHUBStatus.sHubStatus.changeStatus != 0  ){
		/* Do notification if there is already a hub status change when registering */

		vhubStatus = USBH_HCDS_VHUB_HUB_STATUS;
	}
	if( VHUBStatus.sPortStatus.changeStatus != 0 ){
		/* Do notification if there is already a port status change when registering */

		vhubStatus |= USBH_HCDS_VHUB_PORT_STATUS;
	}

	USBH_HCDS_ExecCallback(VHUBStatus.pfnCallback, vhubStatus, 0, NULL);
}

/*=============================================================================================
// Function_Name: USBH_HCDS_VHUBRequest
//
// description	: USB request process for the virtual route hub address
//
//				  Process the USB request for the virtual route hub address
//
// argument 	: None
//
// return		: STATUS_SUCCESS			Processing completed successfully
//				  STATUS_INVALID_PARAMETER	Parameter error

===============================================================================================*/
long USBH_HCDS_VHUBRequest( USBH_HCD_URB *psUrb )
{
	DEVICE_REQUEST	*psDeviceRequest;
	unsigned short reqDataLength;
	long retValue;


	psUrb->actualLength = 0;

	psDeviceRequest = (DEVICE_REQUEST *)psUrb->pSetupPacket;

	reqDataLength =  MAKEWORD(psDeviceRequest->wLengthL, psDeviceRequest->wLengthH);
	if( reqDataLength > psUrb->transBufLength ){
		/* The data buffer is not enough for the data size required by the request */

		return STATUS_INVALID_PARAMETER;
	}

	VHUBStatus.psUrb = psUrb;
	switch( psDeviceRequest->bmRequestType & BMREQ_TYPE_MASK ){
		case TYPE_STANDARD:
			retValue = StandardRequest(psDeviceRequest);
			break;
		case TYPE_CLASS:
			retValue = ClassRequest(psDeviceRequest);
			break;
		default:
			retValue = STATUS_INVALID_PARAMETER;
	}
	if( retValue != STATUS_SUCCESS ){
		/* For request error */

		psUrb->status = USBH_HCD_URBSTS_PIPE;
	} else {
		/* When request terminated normally */

		psUrb->status = USBH_HCD_URBSTS_SUCCESS;
	}

	return STATUS_SUCCESS;
}

/*=============================================================================================
// Function_Name: NotifyPortStateChanged
//
// description	: Notification of Port state changing
//
//				  Notify the changing of the port state of the virtual route hub
//
// argument 	: 				(in)Pointer of callback function
//
// return		: None
===============================================================================================*/
//Inline long NotifyPortStateChanged( unsigned long portState, unsigned long portSpeed, void *pParam )
long NotifyPortStateChanged( unsigned long portState, unsigned long portSpeed, void *pParam )
{
	unsigned long vhubStatus;


	switch( portState ){
		case USBH_HCDS_PORT_ST_DISCONNECTED:
			/* When device is unplugged */

			/* Clear the Port Connection of port status */
			/* Clear the Port Enable of port status */
			/* Clear the Port High Speed, Port Low Speed of port status */
			/* Set the change of Port Connection in the port change status */
			VHUBStatus.sPortStatus.status &= ~(PORTSTS_PORT_CONNECTION | PORTSTS_PORT_ENABLE
												 | PORTSTS_PORT_HIGH_SPEED | PORTSTS_PORT_LOW_SPEED);
			VHUBStatus.sPortStatus.changeStatus |= PORTSTS_C_PORT_CONNECTION;

			/* Clear the Port Suspend of port status */
			VHUBStatus.sPortStatus.status &= ~PORTSTS_PORT_SUSPEND;
			break;
		case USBH_HCDS_PORT_ST_DISABLED:
			/* when device is connected, or when port error occurred/when ClearPortFeatuer(PORT_ENABLE) */

			if( (VHUBStatus.sPortStatus.status & PORTSTS_PORT_ENABLE) == 0 ){
				/* Device is connected */

				/* Set the port Connection of port status */
				/* Set the change of Port Connection in the port change status */
				VHUBStatus.sPortStatus.status |= PORTSTS_PORT_CONNECTION;
				VHUBStatus.sPortStatus.changeStatus |= PORTSTS_C_PORT_CONNECTION;
			} else {
				/* When port error occurred/when ClearPortFeatuer(PORT_ENABLE) */

				/* Clear the Port Enable of port status */
				/* Clear the Port High Speed, Port Low Speed of port status */
				/* Set the change of Port Enable in the port change status */
				VHUBStatus.sPortStatus.status &= ~(PORTSTS_PORT_ENABLE | PORTSTS_PORT_HIGH_SPEED | PORTSTS_PORT_LOW_SPEED);
				VHUBStatus.sPortStatus.changeStatus |= PORTSTS_C_PORT_ENABLE;
			}
			break;
		case USBH_HCDS_PORT_ST_ENABLED:
			/* When USB reset is completed, or USB resume is completed */

			if( (VHUBStatus.sPortStatus.status & PORTSTS_PORT_SUSPEND) == 0 ){
				/* The port is out of suspending */

				/* Clear the Port Reset of port change status */
				VHUBStatus.sPortStatus.status &= ~PORTSTS_PORT_RESET;

				/* Set the Port Enable of port status */
				VHUBStatus.sPortStatus.status |= PORTSTS_PORT_ENABLE;

				/* Set the Port Low Speed/Port High Speed of port status */
				switch( portSpeed ){
					case USBH_HCDS_PORT_SPEED_MODE_HIGH:

						/* Clear PORT_LOW_SPEED, set PORT_HIGH_SPEED */
						VHUBStatus.sPortStatus.status &= ~PORTSTS_PORT_LOW_SPEED;
						VHUBStatus.sPortStatus.status |= PORTSTS_PORT_HIGH_SPEED;
						break;
					case USBH_HCDS_PORT_SPEED_MODE_FULL:

						/* Clear PORT_LOW_SPEED, clear PORT_HIGH_SPEED */
						VHUBStatus.sPortStatus.status &= ~PORTSTS_PORT_LOW_SPEED;
						VHUBStatus.sPortStatus.status &= ~PORTSTS_PORT_HIGH_SPEED;
						break;
					case USBH_HCDS_PORT_SPEED_MODE_LOW:

						/* Set PORT_LOW_SPEED, clear PORT_HIGH_SPEED */
						VHUBStatus.sPortStatus.status |= PORTSTS_PORT_LOW_SPEED;
						VHUBStatus.sPortStatus.status &= ~PORTSTS_PORT_HIGH_SPEED;
						break;
				}

				/* Set the change of Port Reset in the port change status */
				VHUBStatus.sPortStatus.changeStatus |= PORTSTS_C_PORT_RESET;
			} else {
				/* When the port is under suspending */

				/* Clear the Port Suspend of port status */
				/* Set the change of Port Suspend in the port change status */
				VHUBStatus.sPortStatus.status &= ~PORTSTS_PORT_SUSPEND;
				VHUBStatus.sPortStatus.changeStatus |= PORTSTS_C_PORT_SUSPEND;
			}
			break;
		case USBH_HCDS_PORT_ST_SUSPENDED:
			/* Transferring to Suspend is completed */

			/* Set the Port SUSPEND of port status */
			VHUBStatus.sPortStatus.status |= PORTSTS_PORT_SUSPEND;

			break;
		case USBH_HCDS_PORT_ST_VBUS_OVER_CURRENT:
			/* Overcurrent occurred in VBUS */

			/* Clear all the port status and port change status */
			VHUBStatus.sPortStatus.status = 0;
			VHUBStatus.sPortStatus.changeStatus = 0;

			/* Set the Hub Over-Current of hub status */
			/* Set the change of Hub Over-Current in the hub change status */
			VHUBStatus.sHubStatus.status |= HUBSTS_HUB_OVER_CURRENT;
			VHUBStatus.sHubStatus.changeStatus |= HUBSTS_C_HUB_OVER_CURRENT;
			break;

		case USBH_HCDS_PORT_ST_VBUS_OVER_CURRENT_CLR:
			/* VBUS recovery from the overcurrent */

			/* Clear the Hub Over-Current of hub status */
			/* Set the change of Hub Over-Current in the hub change status */
			VHUBStatus.sHubStatus.status &= ~HUBSTS_HUB_OVER_CURRENT;
			VHUBStatus.sHubStatus.changeStatus |= HUBSTS_C_HUB_OVER_CURRENT;
			break;
	}


	vhubStatus = 0;
	if( VHUBStatus.sHubStatus.changeStatus != 0  ){
		/* Do notification if there is already a hub status change when registering */

		vhubStatus = USBH_HCDS_VHUB_HUB_STATUS;
	}
	if( VHUBStatus.sPortStatus.changeStatus != 0 ){
		/* Do notification if there is already a port status change when registering */

		vhubStatus |= USBH_HCDS_VHUB_PORT_STATUS;
	}

	USBH_HCDS_ExecCallback(VHUBStatus.pfnCallback, vhubStatus, 0, NULL);

	return STATUS_SUCCESS;
}

/*=============================================================================================
// Function_Name: StandardRequest
//
// description	: Process for standard request
//
//				  Analyze the passed request data, and process an appropriate standard request
//
// argument 	: *psDeviceRequest			(in)Pointer to request data
//
// return		: STATUS_SUCCESS			Processing completed successfully
===============================================================================================*/
Inline long StandardRequest( DEVICE_REQUEST *psDeviceRequest )
{
	long retValue;


	switch( psDeviceRequest->bRequest ){
		case SREQ_GET_STATUS:
			retValue = GetStatus(psDeviceRequest);
			break;
		case SREQ_CLEAR_FEATURE:
			retValue = ClearFeature(psDeviceRequest);
			break;
		case SREQ_SET_FEATURE:
			retValue = SetFeature(psDeviceRequest);
			break;
		case SREQ_SET_ADDRESS:
			retValue = SetAddress(psDeviceRequest);
			break;
		case SREQ_GET_DESCRIPTOR:
			retValue = GetDescriptor(psDeviceRequest);
			break;
		case SREQ_GET_CONFIGURATION:
			retValue = GetConfiguration(psDeviceRequest);
			break;
		case SREQ_SET_CONFIGURATION:
			retValue = SetConfiguration(psDeviceRequest);
			break;
		case SREQ_GET_INTERFACE:
			retValue = GetInterface(psDeviceRequest);
			break;
		case SREQ_SET_INTERFACE:
			retValue = SetInterface(psDeviceRequest);
			break;
		default:
			retValue = STATUS_INVALID_PARAMETER;
	}

	return retValue;
}

/*======================================================================
// Function_Name: GetStatus
//
// description	: Get Status request
//
//				  Process for Get Status request
//
// argument 	: *psDeviceRequest			Pointer of device request
//
// return		: STATUS_SUCCESS			Success
//				  STATUS_INVALID_PARAMETER		Error
//				  STATUS_INVALID_PARAMETER	Parameter error
========================================================================*/
Inline long GetStatus( DEVICE_REQUEST *psDeviceRequest )
{
	USBH_HCD_URB *psUrb;
	unsigned char *pBufAdrs;


	psUrb = VHUBStatus.psUrb;
	pBufAdrs = (unsigned char *)psUrb->pTransBuf;
	if( VHUBStatus.bmFlags.usbState == DEFAULT_STATE ){

		return STATUS_INVALID_PARAMETER;
	}

	if( (psDeviceRequest->bmRequestType & BMREQ_DIR_MASK) != DIR_DEVICE_TO_HOST ){
		/* Direction of transfer is different */

		return STATUS_INVALID_PARAMETER;
	}

	if( psDeviceRequest->wValueH || psDeviceRequest->wValueL ){
		/* wValue != 0 */

		return STATUS_INVALID_PARAMETER;
	}

	if( psDeviceRequest->wLengthH || psDeviceRequest->wLengthL != GET_STATUS_DATA_LENGTH ){
		/* wLength != GET_STATUS_DATA_LENGTH */

		return STATUS_INVALID_PARAMETER;
	}

	switch( psDeviceRequest->bmRequestType & BMREQ_RECIPIENT_MASK ){
		case RECIPIENT_DEVICE:

			if( psDeviceRequest->wIndexH || psDeviceRequest->wIndexL ){
				/* wIndex != 0*/

				return STATUS_INVALID_PARAMETER;
			}

			/*===========================/
			Set the replying data/
			/===========================*/
			pBufAdrs[0] = (VHUBStatus.bmFlags.remoteWakeup << 1)
								+ ((StdConfigDesc[OFFSET_BMATTRIBUTES] & ATTRIB_SELF_POWERED) >> 6);
			pBufAdrs[1] = 0x00;
			break;
		case RECIPIENT_INTERFACE:
			if( VHUBStatus.bmFlags.usbState == ADDRESSED_STATE ){

				return STATUS_INVALID_PARAMETER;
			}

			if( psDeviceRequest->wIndexH ){
				/* wIndex != 0*/

				return STATUS_INVALID_PARAMETER;
			}

			/*===========================================/
			Check whether specified Interface Number is effective/
			/===========================================*/
			if( psDeviceRequest->wIndexL != 0 ){
				/* Invalid Interface Number */

				return STATUS_INVALID_PARAMETER;
			}

			/*===========================/
			Set the replying data	  /
			/===========================*/
			pBufAdrs[0] = 0x00;
			pBufAdrs[1] = 0x00;
			break;
		case RECIPIENT_ENDPOINT:
			if( psDeviceRequest->wIndexH ){
				/* wIndex.h != 0 */

				return STATUS_INVALID_PARAMETER;
			}
			if(VHUBStatus.bmFlags.usbState == ADDRESSED_STATE && psDeviceRequest->wIndexL != 0x00){

				return STATUS_INVALID_PARAMETER;
			}


			if( psDeviceRequest->wIndexL != 0 && psDeviceRequest->wIndexL != INT_EP_ADDRESS ){
				/* There are neither Endpoint 0 nor Interrupt IN Endpoint */

				return STATUS_INVALID_PARAMETER;
			}

			/*===========================/
			Set the replying data	  /
			/===========================*/
			if( psDeviceRequest->wIndexL != 0x00 ){
				/* For Interrupt IN Endpoint */

				pBufAdrs[0] = (unsigned char)VHUBStatus.bmFlags.epHalt;
			} else {
				/* For Endpoint 0 */

				pBufAdrs[0] = 0x00;
			}
			pBufAdrs[1] = 0x00;

			break;
		default:
			return STATUS_INVALID_PARAMETER;
	}

	psUrb->actualLength = GET_STATUS_DATA_LENGTH;

⌨️ 快捷键说明

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