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

📄 usbch9.c

📁 PDIUSBD12的嵌入式软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*   usbch9.c
*
*   USB device communications - "Standard Request" layer,
*   conforming to the USB 2.0 specification, Chapter 9.
*
*   Adapted from Philips PDIUSBD12 firmware library.
*   MJB Nov 2005
*/

#include "gendef.h"
#include "usbdef.h"
#include "usbhal.h"
#include "usbci.h"
#include "usb200.h"
#include "usbch9.h"


#define  NUM_ENDPOINTS  2   /* Number of endpoints (In + Out) required by the device */

/*
*   Device descriptors need to be customised to suit the application.
*
*   Endpoints defined for the device interface, excluding control endpoints (EP0 in/out):
*   For CDC (Communications Device Class) devices:
*      Bulk IN (EP2 in) + Bulk OUT (EP2 out) = 2 endpoints (mandatory).
*   For USBTMC (Test and Measurment Class) devices:
*      Bulk IN (EP2 in) + Bulk OUT (EP2 out) = 2 endpoints (mandatory).
*   Interrupt IN (EP1 in) += 1 endpoint (required if device has "interrupt" capability).
*/

const USB_DEVICE_DESCRIPTOR DeviceDescr =
{
	sizeof(USB_DEVICE_DESCRIPTOR),          /* bLength ( =18 =0x12) */
	USB_DEVICE_DESCRIPTOR_TYPE,             /* descriptor type */
	SWAP(0x0200),                           /* bcdUSB = 02.00 */
	0x00,                                   /* device class    (see Interface Desc.) */
	0x00,                                   /* device subclass ( .. .. .. ) */
	0x00,                                   /* device protocol ( .. .. .. ) */
	EP0_MAX_PACKET_SIZE,                    /* max packet size for EP0 (16) */
	SWAP(0xABCD),                           /* vendor code (allocated by USB-IF) */
	SWAP(0x1234),                           /* product code, BCD */
	SWAP(0x0100),                           /* device release number, BCD */
	MANUFACTURER_STR_ID,                    /* manufacturer string idx (0 if none) */
	PRODUCT_NAME_STR_ID,                    /* product string idx (0 if none) */
	SERIAL_NUM_STR_ID,                      /* serial number string idx (0 if none) */
	1                                       /* number of configurations */
};


#if ( NUM_ENDPOINTS == 3 )
#define  PACKED_USB_CONFIG_DESCR_LEN  39
#else
#define  PACKED_USB_CONFIG_DESCR_LEN  32
#endif

/*
*   The Configuration Descriptor must be bytewise packed (no alignment or stuff bytes).
*   Interface class and subclass codes are defined according to the device usage.
*   (Refer to relevant USB Class Specification for allocated codes.)
*/
const PACKED_USB_CONFIG_DESCR  PackedConfigDescr =
{
	9,                                      /* bLength */
	USB_CONFIGURATION_DESCRIPTOR_TYPE,      /* descriptor type */
	SWAP( PACKED_USB_CONFIG_DESCR_LEN ),    /* length of packed config descr. (16b) */
	0x01,                                   /* number of interfaces */
	0x01,                                   /* configuration value */
	0x00,                                   /* configuration string index (none) */
	0xC0,                                   /* attributes (self-powered, no remote wakeup) */
	0x01,                                   /* max power */

	9,                                      /* bLength */
	USB_INTERFACE_DESCRIPTOR_TYPE,          /* descriptor type */
	0x00,                                   /* interface number */
	0x00,                                   /* alternate setting */
	NUM_ENDPOINTS,                          /* number of endpoints (excl. EP0) */
	0xFE,                                   /* interface class (USBTMC=0xFE) */
	0x03,                                   /* interface subclass (USB488=0x03) */
	0x01,                                   /* interface protocol */
	0x00,                                   /* interface string index (none) */

	7,                                      /* bLength */
	USB_ENDPOINT_DESCRIPTOR_TYPE,           /* descriptor type */
	0x82,                                   /* Endpoint dir'n (IN) & addr */
	USB_ENDPOINT_TYPE_BULK,                 /* Endpoint type */
	LO_BYTE( EP2_MAX_PACKET_SIZE ),         /* Maximum pkt size (64) */
	HI_BYTE( EP2_MAX_PACKET_SIZE ),
	10,                                     /* Interval - usually ignored for bulk */

	7,                                      /* bLength */
	USB_ENDPOINT_DESCRIPTOR_TYPE,           /* descriptor type */
	0x02,                                   /* Endpoint dir'n (OUT) & addr */
	USB_ENDPOINT_TYPE_BULK,                 /* Endpoint type */
	LO_BYTE( EP2_MAX_PACKET_SIZE ),         /* Maximum pkt size (64) */
	HI_BYTE( EP2_MAX_PACKET_SIZE ),
	10,                                     /* Interval - usually ignored for bulk */

	7,                                      /* bLength */
	USB_ENDPOINT_DESCRIPTOR_TYPE,           /* descriptor type */
	0x81,                                   /* Endpoint dir'n (IN) & addr */
	USB_ENDPOINT_TYPE_INTERRUPT,            /* Endpoint type */
	LO_BYTE( EP1_MAX_PACKET_SIZE ),         /* Maximum pkt size (4) */
	HI_BYTE( EP1_MAX_PACKET_SIZE ),
	10                                      /* Polling interval (unit=frame=1mS) */
};


/**************
*   String Descriptors...
*   NB:  !! Ensure that bString[ ] sizes are defined correctly (in usbch9.h) !!
*   The Language String Descriptor is mandatory for USB2.0 compliance;
*   all the others are optional. (Put string index = 0 to disable string descriptor.)
*   The Unicode strings are NOT NUL-terminated.
*/
const struct USB_STRING_DESCR_LANG stringDescLang =
		{
		sizeof(stringDescLang),
		USB_STRING_DESCRIPTOR_TYPE,
		SWAP( UNICODE_ENGLISH )
		};


const struct USB_STRING_DESCR_MANU stringDescManu =
		{
		sizeof(stringDescManu),
		USB_STRING_DESCRIPTOR_TYPE,
		{  /***  Unicode string -- manufacturer name ***/  }
		};


const struct USB_STRING_DESCR_PROD stringDescProd =
		{
		sizeof(stringDescProd),
		USB_STRING_DESCRIPTOR_TYPE,
		{  /***  Unicode string -- product name ***/  }
		};


const struct USB_STRING_DESCR_SNUM stringDescSNum =
		{
		sizeof(stringDescSNum),
		USB_STRING_DESCRIPTOR_TYPE,
		{  /***  Unicode string -- serial number ***/  }
		};


/************************************************************************** */
/*  USB2.0 protocol standard device requests - function table               */
/************************************************************************** */

const pfnvoid StandardDeviceRequest[] =
		{
		get_status,                /*  0  */
		clear_feature,             /*  1  */
		req_undefined,             /*  2  reserved in USB2.0 */
		set_feature,               /*  3  */
		req_undefined,             /*  4  reserved in USB2.0 */
		set_address,               /*  5  */
		get_descriptor,            /*  6  */
		req_undefined,             /*  7  set_descriptor -- not supported */
		get_configuration,         /*  8  */
		set_configuration,         /*  9  */
		get_interface,             /* 10  */
		set_interface,             /* 11  */
		req_undefined,             /* 12  synch_frame -- not supported */
		};


void get_status(void)
{
	uchar endp, txdat[2];
	uchar bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT_MASK;
	uchar c;

	if ( bRecipient == USB_RECIPIENT_DEVICE )
	{
		if ( USBflags.bits.remote_wakeup ) txdat[0] = 3;
		else txdat[0] = 1;
		txdat[1]=0;
		single_transmit( txdat, 2 );
	}
	else if ( bRecipient == USB_RECIPIENT_INTERFACE )
	{
		txdat[0]=0;
		txdat[1]=0;
		single_transmit( txdat, 2 );
	}
	else if ( bRecipient == USB_RECIPIENT_ENDPOINT )
	{
		endp = (uchar)(ControlData.DeviceRequest.wIndex & MAX_EP_MASK);
		if ( ControlData.DeviceRequest.wIndex & USB_ENDPOINT_DIRECTION_MASK )
			c = D12_SelectEndpoint( endp*2 + 1 );
		else
			c = D12_SelectEndpoint( endp*2 );
		if ( c & D12_STALL ) txdat[0] = 1;
		else txdat[0] = 0;
		txdat[1] = 0;
		single_transmit( txdat, 2 );
	}
	else stall_ep0();
}


void  clear_feature( void )
{
	uchar endpointIndex;
	uchar bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT_MASK;

	if ( bRecipient == USB_RECIPIENT_DEVICE )
	{
		if ( ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP )
		{
			DISABLE_USB_IRQ;
			USBflags.bits.remote_wakeup = FALSE;     /* Disable Remote Wake-up */
			RESTORE_USB_IRQ;
			single_transmit( 0, 0 );                 /* Ack */
		}
		else if ( ControlData.DeviceRequest.wValue == USB_FEATURE_TEST_MODE )
		{
			/* The TEST_MODE feature cannot be cleared by the CLEAR_FEATURE request... */
			single_transmit( 0, 0 );                /* ... (Ref: USB 2.0 spec. $9.4.1) */
		}
	}
	else if ( bRecipient == USB_RECIPIENT_ENDPOINT
			&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_HALT )
	{
		endpointIndex = 2 * (uchar)(ControlData.DeviceRequest.wIndex & MAX_EP_MASK);
		if ( ControlData.DeviceRequest.wIndex & USB_ENDPOINT_DIRECTION_MASK )
			endpointIndex++;   /* Direction is IN (to host) */

		D12_SetEndpointStatus( endpointIndex, 0 );  /* Clear specified endpoint */
		debug_signal( BIT_10 );

		/*** Perform here any specific Device Class requirements ***/

		single_transmit( 0, 0 );                 /* Ack */
	}
	else
	{
		stall_ep0();
	}
}


void set_feature(void)
{
	uchar endpointIndex;
	uchar bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT_MASK;

	if ( bRecipient == USB_RECIPIENT_DEVICE )
	{
		if ( ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP)
		{
			DISABLE_USB_IRQ;
			USBflags.bits.remote_wakeup = TRUE;       /* Enable Remote Wake-up */
			RESTORE_USB_IRQ;
			single_transmit(0, 0);
		}
		else if ( ControlData.DeviceRequest.wValue == USB_FEATURE_TEST_MODE )
		{
			DISABLE_USB_IRQ;
			USBflags.bits.test_mode = TRUE;        /* Enable TEST_MODE feature */
			RESTORE_USB_IRQ;
			single_transmit( 0, 0 );
		}
	}
	else if ( bRecipient == USB_RECIPIENT_ENDPOINT
			&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_HALT)
	{
		endpointIndex = 2 * (uchar)(ControlData.DeviceRequest.wIndex & MAX_EP_MASK);
		if ( ControlData.DeviceRequest.wIndex & USB_ENDPOINT_DIRECTION_MASK )
			endpointIndex++;   /* Direction is IN (to host) */

		D12_SetEndpointStatus( endpointIndex, 1 );   /* Stall (halt) specified endpoint */
		single_transmit( 0, 0 );      /* Ack */
	}
	else
	{
		stall_ep0();
	}
}


void set_address(void)
{
	uchar bAddr;

	bAddr = (LO_BYTE(ControlData.DeviceRequest.wValue)) & DEVICE_ADDRESS_MASK;
	D12_SetAddressEnable( bAddr, 1 );
	single_transmit( 0, 0 );               /* Ack */
}


void get_descriptor(void)
{
	uchar  bDescriptorType = HI_BYTE(ControlData.DeviceRequest.wValue);
	uchar  bDescriptorIndex = LO_BYTE( ControlData.DeviceRequest.wValue );
	ushort wIndex = ControlData.DeviceRequest.wIndex;   /* Lang_ID or zero */
	ushort wLength = ControlData.DeviceRequest.wLength;
	ushort ReplyLen;

	if ( bDescriptorType == USB_DEVICE_DESCRIPTOR_TYPE )
	{
		ReplyLen = LESSER_OF( sizeof(USB_DEVICE_DESCRIPTOR), wLength );
		control_transmit( (const uchar *) &DeviceDescr, ReplyLen );
	}
	else if ( bDescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE )
	{
		ReplyLen = LESSER_OF( PACKED_USB_CONFIG_DESCR_LEN, wLength );
		control_transmit( (const uchar *) &PackedConfigDescr, ReplyLen );
	}
	else if ( bDescriptorType == USB_STRING_DESCRIPTOR_TYPE )
	{
		switch( bDescriptorIndex )
		{
		case UNICODE_LANGUAGE_STR_ID:       /* primary language code */
			ReplyLen = LESSER_OF( sizeof(stringDescLang), wLength );
			control_transmit( (const uchar *) &stringDescLang, ReplyLen );
			break;

		case MANUFACTURER_STR_ID:           /* manufacturer string */
			ReplyLen = LESSER_OF( sizeof(stringDescManu), wLength );
			control_transmit( (const uchar *) &stringDescManu, ReplyLen );
			break;

		case PRODUCT_NAME_STR_ID:           /* product name string */

⌨️ 快捷键说明

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