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

📄 usb_lib.c

📁 HID-Ukey底层源码实现(st72651芯片) windows上层驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
				Non_Standard_Request;
			}
		}
		else if (sUSB_vSetup.USBwValue1 == 0x03					// String Descriptor
				&& sUSB_vSetup.USBwIndex == 0x0409				// US english only
				&& sUSB_vSetup.USBwValue0 < UI.Num_Strings) {	// Valid index
			vUSB_DataToSend = StringDescriptor[sUSB_vSetup.USBwValue0].Descriptor;
			vUSB_length = StringDescriptor[sUSB_vSetup.USBwValue0].Size;
		}

		if (vUSB_DataToSend == NULL)
			goto Req_Error;

		if (vUSB_length > sUSB_vSetup.USBwLength)
			vUSB_length = sUSB_vSetup.USBwLength;
		return;

	case GET_STATUS:
		if (DADDR == 0)				// On default state, to stall the request
			goto Req_Error;

		if (sUSB_vSetup.Flag != (TWO_wLength | NON0_wLength0))	// (wValue | wIndex) != 0 || wLength != 2
			goto Req_Error;

		// Request of Get Device Status
		_vUSB_Report[0] = vUSB_Current_Feature & 0x03;	// Remote wakeup and self power feature
		_vUSB_Report[1] = 0;
		vUSB_length = 2;
		vUSB_DataToSend = _vUSB_Report;
		return;

	default:
		goto Req_Error;
	}
}	// Device->Host, Standard, Device-Recipient

/*****************************************************************************
ROUTINE NAME : RequestType_0x01
DESCRIPTION  : Standard process for request of (H->D, Standard, Interface)
*****************************************************************************/
void RequestType_0x01(void)		// Host->Device, Standard, Interface-Recipient
{
//	_vUSB_StateMachine = WAIT_STATUS_IN;		// Expect Status IN stage follow the Setup Stage

	if (DADDR == 0 || vUSB_Configuration == 0)	// Not on configured state
		goto Req_Error;
	if (sUSB_vSetup.Flag & NON0_wLength)
		goto Req_Error;							// wLength != 0

	if (sUSB_vSetup.USBbRequest == CLEAR_FEATURE) {
		USER(USER_Clear_Feature_Int);
		return;
	}
	else if (sUSB_vSetup.USBbRequest == SET_FEATURE) {
		USER(USER_Set_Feature_Int);
		return;
	}
	else if (sUSB_vSetup.USBbRequest == SET_INTERFACE) {
		if (sUSB_vSetup.Flag & (NON0_wIndex1 | NON0_wValue1))
			goto Req_Error;						// (wIndex1 | wValue1) != 0

		USER(USER_Set_Interface);	// if (USER_Set_Interface == REQ_SUCCESS) return;
		asm {									// Check the return status of USER_Set_Interface
			CP		A, #REQ_SUCCESS
			JRNE	bad_setting
			RET
	bad_setting:
		}
	}

Req_Error:
	Non_Standard_Request;
}	// End of "Host->Device, Standard, Interface-Recipient"

/*****************************************************************************
ROUTINE NAME : RequestType_0x81
DESCRIPTION  : Standard process for request of (D->H, Standard, Interface)
*****************************************************************************/
void RequestType_0x81(void)		// Device->Host, Standard, Interface-Recipient
{
//	_vUSB_StateMachine = IN_DATA;	// Expect Data IN stage follow the Setup Stage

	if (DADDR == 0 || vUSB_Configuration == 0)	// Not on configured state
		goto Req_Error;
	if (sUSB_vSetup.Flag & (NON0_wValue | NON0_wIndex1))
		goto Req_Error;						// (wValue | wIndex1) != 0

	if (sUSB_vSetup.USBbRequest == GET_STATUS) {
		if (!(sUSB_vSetup.Flag & TWO_wLength))
			goto Req_Error;					// wLength != 2

		// Check range of the interface number
		if (sUSB_vSetup.USBwIndex0 >= UI.Num_Interface)
			goto Req_Error;

		_vUSB_Report[0] = 0;				// Send a 0 Word according to spec.
		_vUSB_Report[1] = 0;				// Send a 0 Word according to spec.
		vUSB_length = 2;
		vUSB_DataToSend = _vUSB_Report;
		return;
	}
	else if (sUSB_vSetup.USBbRequest == GET_INTERFACE) {
		if (!(sUSB_vSetup.Flag & ONE_wLength))
			goto Req_Error;					// wLength != 1

		USER(USER_Get_Interface);
		asm LD	_vUSB_Report[0], A;			// _vUSB_Report[0] = USER_Get_Interface();
		vUSB_length = 1;
		vUSB_DataToSend = _vUSB_Report;
		return;
	}

Req_Error:
	Non_Standard_Request;
}	// End of "Device->Host, Standard, Interface-Recipient"

/*****************************************************************************
ROUTINE NAME : RequestType_0x02
DESCRIPTION  : Standard process for request of (H->D, Standard, Endpoint)
*****************************************************************************/
void RequestType_0x02(void)		// Host->Device, Standard, Endpoint-Recipient
{
	if (DADDR == 0 || vUSB_Configuration == 0)	// Not on configured state
		goto Req_Error;

	if ((sUSB_vSetup.Flag & (NON0_wValue | NON0_wLength | NON0_wIndex)) != NON0_wIndex0)
		goto Req_Error;						// (wValue | wIndex1 | wLength) != 0 || wIndex0 == 0

	if (sUSB_vSetup.USBbRequest == CLEAR_FEATURE) {
		_USB_Clr_Feature_EP();
		USER(USER_Clear_Feature_EP);
		return;
	}
	else if (sUSB_vSetup.USBbRequest == SET_FEATURE) {
		_USB_Set_Feature_EP();
		USER(USER_Set_Feature_EP);
		return;
	}

Req_Error:
	Non_Standard_Request;
}	// End of "Host->Device, Standard, Endpoint-Recipient"

/*****************************************************************************
ROUTINE NAME : RequestType_0x82
DESCRIPTION  : Standard process for request of (D->H, Standard, Endpoint)
*****************************************************************************/
void RequestType_0x82(void)		// Device->Host, Standard, Endpoint-Recipient
{
	char EP_State;

//	_vUSB_StateMachine = IN_DATA;	// Expect Data IN stage follow the Setup Stage

	if (sUSB_vSetup.USBbRequest != GET_STATUS)
		goto Req_Error;

	if (DADDR == 0)
		goto Req_Error;						// Error on default state
	
	if ((sUSB_vSetup.Flag & (NON0_wValue | TWO_wLength)) != TWO_wLength)
		goto Req_Error;						// wValue != 0 || wLength != 2

	if (vUSB_Configuration == 0 && (sUSB_vSetup.USBwIndex & ~0x80))
		goto Req_Error;						// Error on address state if it is not EP0

	EP_State = _USB_GetEPStatus(sUSB_vSetup.USBwIndex0);
	if (EP_State == EP_DISABLE || EP_State == REQ_UNSUPPORT)
Req_Error:
		Non_Standard_Request;

	_vUSB_Report[0] = (EP_State == EP_STALL);
	_vUSB_Report[1] = 0;

	vUSB_length = 2;          
	vUSB_DataToSend = _vUSB_Report;
}	// End of "Device->Host, Standard, Endpoint-Recipient"

/*****************************************************************************
ROUTINE NAME : _USB_CopydataIN
DESCRIPTION  : Copy data to endpoint transmit buffer
			Adjust the pointer and counter
*****************************************************************************/
void _USB_CopydataIN(void)
{
	unsigned char TransferLength;

	if (vUSB_length >= MAX_PACKET_SIZE) {
		if (vUSB_length == MAX_PACKET_SIZE)
			_vUSB_StateMachine = ONE_MORE_IN;
		TransferLength = MAX_PACKET_SIZE;
	}
	else
		TransferLength = vUSB_length;

	CNT0TXR = TransferLength;
	vUSB_length -= TransferLength;
	if (vUSB_DataToSend) {		// Data from the library
		asm {
			LD		X, TransferLength
			DEC		X
	_Copy_Byte:
			LD		A, ([vUSB_DataToSend.w],X)
			LD		(EP0_IN,X), A
			DEC		X
			JRPL	_Copy_Byte
		}
		vUSB_DataToSend += TransferLength;
	}
	else {					// Data from user space
		asm	LD	A, TransferLength;
		USER(USER_CopydataIN);
	}
	vUSB_offset += CNT0TXR;
}


/*****************************************************************************
ROUTINE NAME : _USB_CopydataOUT
DESCRIPTION  : Copy data from endpoint receive buffer to user space
			Adjust the pointer and counter
			Return error if the received data length is too long
*****************************************************************************/
char _USB_CopydataOUT(void)
{
	if (_vUSB_Data_OUT_Len > vUSB_length)
		return REQ_ERROR;

	asm LD	A, _vUSB_Data_OUT_Len;
	USER(USER_CopydataOUT);

	vUSB_offset += _vUSB_Data_OUT_Len;
	vUSB_length -= _vUSB_Data_OUT_Len;
	if (vUSB_length == 0)
		_vUSB_StateMachine = ONE_MORE_OUT;

	return (REQ_SUCCESS);
}
 
/*****************************************************************************
ROUTINE NAME : Init_USB
DESCRIPTION  : Initialize the USB Macrocell
*****************************************************************************/
void Init_USB(void)
{
	_vUSB_StateMachine = 0;
	vUSB_Current_Feature = 0;
	vUSB_Configuration = 0;

	_EP_RxTx_Flag = 0;		// Clear flag for non-control EPs

#ifdef	USB_POLLING_MODEL
	// In polling model, set USB as highest interrupt level 3
	// All the other interrupt source are set as level 1
//	ITSPR0 = 0x5D;
#else
	// In interrupt model, set USB as highest interrupt level 2
	// All the other interrupt source are set as level 1
	ITSPR0 = 0x51;
#endif
	ITSPR0 = 0x15;		// DTC interrupt is in level 2@jin0823

	ITSPR1 = 0x57;		// USB interrupt is in level 3
//	ITSPR2 = 0x55;
	ITSPR2 = 0x5f;			// PC interrupt & timer interrupt is level 3 @jin0823
	ITSPR3 = 0xF5;

	USBCTLR = 0x00;			// No-force USB reset and Power on 3.3V regulator
	USBISTR = 0;			// Clear pending flags
	USBIMR = IMR_RESET;		// Enable USB reset interrupt only
}

/*****************************************************************************
ROUTINE NAME : USB_Reset
DESCRIPTION  : Called when USB cell is reset
*****************************************************************************/
void USB_Reset(void)
{
	Init_USB();
	DADDR = 0x00;				// Enable this device at USB address zero
	CNT0RXR = MAX_PACKET_SIZE;	// Receive data on endpoint 0
	CNT0TXR = 0;
	EP0R = 0x01;				// TX disable, RX Stall (only SETUP token will be ACKed)

	USBIMR = UI.Interrupt_Mask;
	USERIT(USER_Reset);

}

/*****************************************************************************/
// EP_RXR_Adr has the address of all EP?RXR register.
// The value is 0x00 if the EP?RXR is not exist.
#pragma CONST_SEG	USB_CONST
const unsigned char *const near EP_RXR_Adr[6] = {
	&EP0R,
#ifdef	MCU_ST7265
	&EP1RXR,
#else
	0x00,
#endif
	&EP2RXR,
	0x00,
	0x00,
	0x00
};

// EP_TXR_Adr has the address of all EP?TXR register.
// The value is 0x00 if the EP?TXR is not exist.
const unsigned char *const near EP_TXR_Adr[6] = {
	0x00,
	&EP1TXR,
	&EP2TXR,
#ifdef	MCU_ST7265
	0x00,
	0x00,
	0x00
#else
	&EP3TXR,
	&EP4TXR,
	&EP5TXR
#endif
};

/*****************************************************************************
ROUTINE NAME : _USB_GetEPStatus
INPUT/OUTPUT :
	Endpoint: The endpoint number which the status is going to return
			  Rx status is returned if bit7 = 0
			  Tx status is returned if bit7 = 1
DESCRIPTION  : Used to get the current Status of Endpoint
*****************************************************************************/
#pragma NO_ENTRY
char _USB_GetEPStatus(char Endpoint)
{
	asm {
		TNZ		A
		JRMI	Tx_Status
//		JRNE	Non_rEP0
//		LD		A, EP0R
//		JRT		EP_Status
//Non_rEP0:
		CP		A, #5
		JRUGT	No_EPs
		LD		X, A
		LD		X, (EP_RXR_Adr,X)
		JREQ	No_EPs
gEP_Status:
		LD		A, (X)
EP_Status:
		AND		A, #0x03
		RET

Tx_Status:
		AND		A, #0x7F
		JRNE	Non_tEP0
		LD		A, EP0R
		SWAP	A
		JRT		EP_Status
Non_tEP0:
		CP		A, #5
		JRUGT	No_EPs
		LD		X, A
		LD		X, (EP_TXR_Adr,X)
		JRNE	gEP_Status
No_EPs:
	}
	return REQ_UNSUPPORT;
}

/*****************************************************************************
ROUTINE NAME : _USB_Clr_Feature_EP
DESCRIPTION  : Clear STALL condition of the specified EP if it is not DISABLED
			The specified EP is given in sUSB_vSetup.USBwIndex0
*****************************************************************************/
void _USB_Clr_Feature_EP(void)
{
	asm {
		LD		A, sUSB_vSetup.USBwIndex0
		AND		A, #0x7F
		CP		A, #6
		JRUGE	EP_Error
		LD		X, A
		LD		A, sUSB_vSetup.USBwIndex0
		JRMI	Clear_Feature_Tx
		LD		X, (EP_RXR_Adr, X)
		JRT		Set_Feature
EP_Error:
		JP		RequestError
Clear_Feature_Tx:
		LD		X, (EP_TXR_Adr, X)
Set_Feature:
		JREQ	EP_Error				// Error: if the EP is not exist
		LD		A, (X)
		AND		A, #0x03
		JREQ	EP_Error				// Error: if the EP is EP_DISABLE
		CP		A, #EP_STALL
		JRNE	End_Clear				// Return if the EP is not in STALL
		LD		A, (X)
		AND		A, #0xF8
		OR		A, #EP_NAK				// Change the endpoint state to NAK
		LD		(X), A
End_Clear:
	}
}

/*****************************************************************************
ROUTINE NAME : USB_Set_Feature_EP
INPUT/OUTPUT : None
DESCRIPTION  : Set STALL condition of the specified EP if it is not DISABLED
			The specified EP is given in sUSB_vSetup.USBwIndex0
*****************************************************************************/
void _USB_Set_Feature_EP(void)
{
	asm {
		LD		A, sUSB_vSetup.USBwIndex0
		AND		A, #0x7F
		CP		A, #6
		JRUGE	EP_Error
		LD		X, A
		LD		A, sUSB_vSetup.USBwIndex0
		JRMI	Set_Feature_Tx
		LD		X, (EP_RXR_Adr, X)
		JRT		Set_Feature
EP_Error:
		JP		RequestError
Set_Feature_Tx:
		LD		X, (EP_TXR_Adr, X)
Set_Feature:
		JREQ	EP_Error				// Error: if the EP is not exist
		LD		A, (X)
		BCP		A, #0x03
		JREQ	EP_Error				// Error: if the EP is EP_DISABLE
		AND		A, #0xFC
		OR		A, #EP_STALL
		LD		(X), A
	}
}

/*****************************************************************************
ROUTINE NAME : USB_Remote_Wakeup
INPUT/OUTPUT : return SUCCESS if device is in suspend state, ERROR instead
DESCRIPTION  : Send a resume signal within 3ms for 8MHz CPU clock, 6ms for 4MHz
				12ms for 2MHz. At least the resume signal must be longer 
				than 1ms and lower than 15ms
*****************************************************************************/
char USB_Remote_Wakeup(void)
{
	unsigned int loop;

	if ((USBCTLR & 0x02) && (vUSB_Current_Feature & 0x02)) {	// SUSPEND MODE and RWU enabled
		USBCTLR &= ~0x02;	// Exit from SUSPEND mode
		USBCTLR |= 0x08; 	// Force RESUME signal

		// CPU frequency = 8MHz => Resume signal active for 3ms
		// CPU frequency = 4MHz => Resume signal active for 6ms
		// CPU frequency = 2MHz => Resume signal active for 12ms
		for (loop = 3 * 340; loop; loop--)	// loop to keep the Resume signal for at least 3ms 
			asm nop;
			
		USBCTLR &= ~0x08; // stop RESUME signal

		return 	REQ_SUCCESS;
	}
	else
		return	REQ_ERROR;
};


/**************** (c) 2000  STMicroelectronics *******************************/

⌨️ 快捷键说明

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