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

📄 usbtty.c

📁 U-boot源码 ARM7启动代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * (C) Copyright 2003 * Gerry Hamel, geh@ti.com, Texas Instruments * * (C) Copyright 2006 * Bryan O'Donoghue, bodonoghue@codehermit.ie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307	 USA * */#include <common.h>#ifdef CONFIG_USB_TTY#include <circbuf.h>#include <devices.h>#include "usbtty.h"#include "usb_cdc_acm.h"#include "usbdescriptors.h"#include <config.h>		/* If defined, override Linux identifiers with			   	 * vendor specific ones */#if 0#define TTYDBG(fmt,args...)\	serial_printf("[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args)#else#define TTYDBG(fmt,args...) do{}while(0)#endif#if 1#define TTYERR(fmt,args...)\	serial_printf("ERROR![%s] %s %d: "fmt, __FILE__,__FUNCTION__,\	__LINE__,##args)#else#define TTYERR(fmt,args...) do{}while(0)#endif/* * Defines */#define NUM_CONFIGS    1#define MAX_INTERFACES 2#define NUM_ENDPOINTS  3#define ACM_TX_ENDPOINT 3#define ACM_RX_ENDPOINT 2#define GSERIAL_TX_ENDPOINT 2#define GSERIAL_RX_ENDPOINT 1#define NUM_ACM_INTERFACES 2#define NUM_GSERIAL_INTERFACES 1#define CONFIG_USBD_DATA_INTERFACE_STR "Bulk Data Interface"#define CONFIG_USBD_CTRL_INTERFACE_STR "Control Interface"/* * Buffers to hold input and output data */#define USBTTY_BUFFER_SIZE 256static circbuf_t usbtty_input;static circbuf_t usbtty_output;/* * Instance variables */static device_t usbttydev;static struct usb_device_instance device_instance[1];static struct usb_bus_instance bus_instance[1];static struct usb_configuration_instance config_instance[NUM_CONFIGS];static struct usb_interface_instance interface_instance[MAX_INTERFACES];static struct usb_alternate_instance alternate_instance[MAX_INTERFACES];/* one extra for control endpoint */static struct usb_endpoint_instance endpoint_instance[NUM_ENDPOINTS+1];/* * Global flag */int usbtty_configured_flag = 0;/* * Serial number */static char serial_number[16];/* * Descriptors, Strings, Local variables. *//* defined and used by usbdcore_ep0.c */extern struct usb_string_descriptor **usb_strings;/* Indicies, References */static unsigned short rx_endpoint = 0;static unsigned short tx_endpoint = 0;static unsigned short interface_count = 0;static struct usb_string_descriptor *usbtty_string_table[STR_COUNT];/* USB Descriptor Strings */static u8 wstrLang[4] = {4,USB_DT_STRING,0x9,0x4};static u8 wstrManufacturer[2 + 2*(sizeof(CONFIG_USBD_MANUFACTURER)-1)];static u8 wstrProduct[2 + 2*(sizeof(CONFIG_USBD_PRODUCT_NAME)-1)];static u8 wstrSerial[2 + 2*(sizeof(serial_number) - 1)];static u8 wstrConfiguration[2 + 2*(sizeof(CONFIG_USBD_CONFIGURATION_STR)-1)];static u8 wstrDataInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)];static u8 wstrCtrlInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)];/* Standard USB Data Structures */static struct usb_interface_descriptor interface_descriptors[MAX_INTERFACES];static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS];static struct usb_configuration_descriptor	*configuration_descriptor = 0;static struct usb_device_descriptor device_descriptor = {	.bLength = sizeof(struct usb_device_descriptor),	.bDescriptorType =	USB_DT_DEVICE,	.bcdUSB = 		cpu_to_le16(USB_BCD_VERSION),	.bDeviceSubClass =	0x00,	.bDeviceProtocol =	0x00,	.bMaxPacketSize0 =	EP0_MAX_PACKET_SIZE,	.idVendor =		cpu_to_le16(CONFIG_USBD_VENDORID),	.bcdDevice =		cpu_to_le16(USBTTY_BCD_DEVICE),	.iManufacturer =	STR_MANUFACTURER,	.iProduct =		STR_PRODUCT,	.iSerialNumber =	STR_SERIAL,	.bNumConfigurations =	NUM_CONFIGS};/* * Static CDC ACM specific descriptors */struct acm_config_desc {	struct usb_configuration_descriptor configuration_desc;	/* Master Interface */	struct usb_interface_descriptor interface_desc;	struct usb_class_header_function_descriptor usb_class_header;	struct usb_class_call_management_descriptor usb_class_call_mgt;	struct usb_class_abstract_control_descriptor usb_class_acm;	struct usb_class_union_function_descriptor usb_class_union;	struct usb_endpoint_descriptor notification_endpoint;	/* Slave Interface */	struct usb_interface_descriptor data_class_interface;	struct usb_endpoint_descriptor		data_endpoints[NUM_ENDPOINTS-1] __attribute__((packed));} __attribute__((packed));static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = {	{		.configuration_desc ={			.bLength =				sizeof(struct usb_configuration_descriptor),    			.bDescriptorType = USB_DT_CONFIG,			.wTotalLength =				cpu_to_le16(sizeof(struct acm_config_desc)),	    		.bNumInterfaces = NUM_ACM_INTERFACES,    			.bConfigurationValue = 1,			.iConfiguration = STR_CONFIG,			.bmAttributes =				BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,			.bMaxPower = USBTTY_MAXPOWER		},		/* Interface 1 */		.interface_desc = {			.bLength  = sizeof(struct usb_interface_descriptor),			.bDescriptorType = USB_DT_INTERFACE,			.bInterfaceNumber = 0,			.bAlternateSetting = 0,			.bNumEndpoints = 0x01,			.bInterfaceClass =				COMMUNICATIONS_INTERFACE_CLASS_CONTROL,			.bInterfaceSubClass = COMMUNICATIONS_ACM_SUBCLASS,			.bInterfaceProtocol = COMMUNICATIONS_V25TER_PROTOCOL,			.iInterface = STR_CTRL_INTERFACE,		},		.usb_class_header = {			.bFunctionLength	=				sizeof(struct usb_class_header_function_descriptor),			.bDescriptorType	= CS_INTERFACE,			.bDescriptorSubtype	= USB_ST_HEADER,			.bcdCDC	= cpu_to_le16(110),		},		.usb_class_call_mgt = {			.bFunctionLength	=				sizeof(struct usb_class_call_management_descriptor),			.bDescriptorType	= CS_INTERFACE,			.bDescriptorSubtype	= USB_ST_CMF,			.bmCapabilities		= 0x00,			.bDataInterface		= 0x01,		},		.usb_class_acm = {			.bFunctionLength	=				sizeof(struct usb_class_abstract_control_descriptor),			.bDescriptorType	= CS_INTERFACE,			.bDescriptorSubtype	= USB_ST_ACMF,			.bmCapabilities		= 0x00,		},		.usb_class_union = {			.bFunctionLength	=				sizeof(struct usb_class_union_function_descriptor),			.bDescriptorType	= CS_INTERFACE,			.bDescriptorSubtype	= USB_ST_UF,			.bMasterInterface	= 0x00,			.bSlaveInterface0	= 0x01,		},		.notification_endpoint = {			.bLength =				sizeof(struct usb_endpoint_descriptor),			.bDescriptorType	= USB_DT_ENDPOINT,			.bEndpointAddress	= 0x01 | USB_DIR_IN,			.bmAttributes		= USB_ENDPOINT_XFER_INT,			.wMaxPacketSize				= cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),			.bInterval		= 0xFF,		},		/* Interface 2 */		.data_class_interface = {			.bLength		=				sizeof(struct usb_interface_descriptor),			.bDescriptorType	= USB_DT_INTERFACE,			.bInterfaceNumber	= 0x01,			.bAlternateSetting	= 0x00,			.bNumEndpoints		= 0x02,			.bInterfaceClass	=				COMMUNICATIONS_INTERFACE_CLASS_DATA,			.bInterfaceSubClass	= DATA_INTERFACE_SUBCLASS_NONE,			.bInterfaceProtocol	= DATA_INTERFACE_PROTOCOL_NONE,			.iInterface		= STR_DATA_INTERFACE,		},		.data_endpoints = {			{				.bLength		=					sizeof(struct usb_endpoint_descriptor),				.bDescriptorType	= USB_DT_ENDPOINT,				.bEndpointAddress	= 0x02 | USB_DIR_OUT,				.bmAttributes		=					USB_ENDPOINT_XFER_BULK,				.wMaxPacketSize		=					cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),				.bInterval		= 0xFF,			},			{				.bLength		=					sizeof(struct usb_endpoint_descriptor),				.bDescriptorType	= USB_DT_ENDPOINT,				.bEndpointAddress	= 0x03 | USB_DIR_IN,				.bmAttributes		=					USB_ENDPOINT_XFER_BULK,				.wMaxPacketSize		=					cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),				.bInterval		= 0xFF,			},		},	},};static struct rs232_emu rs232_desc={		.dter 		=  	115200,	   	.stop_bits	=	0x00,	   	.parity		=	0x00,		.data_bits	=	0x08};/* * Static Generic Serial specific data */struct gserial_config_desc {	struct usb_configuration_descriptor configuration_desc;	struct usb_interface_descriptor		interface_desc[NUM_GSERIAL_INTERFACES] __attribute__((packed));	struct usb_endpoint_descriptor		data_endpoints[NUM_ENDPOINTS] __attribute__((packed));} __attribute__((packed));static struct gserial_config_descgserial_configuration_descriptors[NUM_CONFIGS] ={	{		.configuration_desc ={			.bLength = sizeof(struct usb_configuration_descriptor),			.bDescriptorType = USB_DT_CONFIG,			.wTotalLength =				cpu_to_le16(sizeof(struct gserial_config_desc)),			.bNumInterfaces = NUM_GSERIAL_INTERFACES,			.bConfigurationValue = 1,			.iConfiguration = STR_CONFIG,			.bmAttributes =				BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,			.bMaxPower = USBTTY_MAXPOWER		},		.interface_desc = {			{				.bLength  =					sizeof(struct usb_interface_descriptor),				.bDescriptorType = USB_DT_INTERFACE,				.bInterfaceNumber = 0,				.bAlternateSetting = 0,				.bNumEndpoints = NUM_ENDPOINTS,				.bInterfaceClass =					COMMUNICATIONS_INTERFACE_CLASS_VENDOR,				.bInterfaceSubClass =					COMMUNICATIONS_NO_SUBCLASS,				.bInterfaceProtocol =					COMMUNICATIONS_NO_PROTOCOL,				.iInterface = STR_DATA_INTERFACE			},  		},		.data_endpoints  = {			{				.bLength =					sizeof(struct usb_endpoint_descriptor),				.bDescriptorType =	USB_DT_ENDPOINT,				.bEndpointAddress =	0x01 | USB_DIR_OUT,				.bmAttributes =		USB_ENDPOINT_XFER_BULK,				.wMaxPacketSize =					cpu_to_le16(CONFIG_USBD_SERIAL_OUT_PKTSIZE),				.bInterval=		0xFF,			},			{				.bLength =					sizeof(struct usb_endpoint_descriptor),				.bDescriptorType =	USB_DT_ENDPOINT,				.bEndpointAddress =	0x02 | USB_DIR_IN,				.bmAttributes =		USB_ENDPOINT_XFER_BULK,				.wMaxPacketSize =					cpu_to_le16(CONFIG_USBD_SERIAL_IN_PKTSIZE),				.bInterval = 		0xFF,			},			{				.bLength =					sizeof(struct usb_endpoint_descriptor),				.bDescriptorType =	USB_DT_ENDPOINT,				.bEndpointAddress =	0x03 | USB_DIR_IN,				.bmAttributes =		USB_ENDPOINT_XFER_INT,    				.wMaxPacketSize =					cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),				.bInterval =		0xFF,			},		},	},};/* * Static Function Prototypes */static void usbtty_init_strings (void);static void usbtty_init_instances (void);static void usbtty_init_endpoints (void);static void usbtty_init_terminal_type(short type);static void usbtty_event_handler (struct usb_device_instance *device,				usb_device_event_t event, int data);static int usbtty_cdc_setup(struct usb_device_request *request,				struct urb *urb);static int usbtty_configured (void);static int write_buffer (circbuf_t * buf);static int fill_buffer (circbuf_t * buf);void usbtty_poll (void);/* utility function for converting char* to wide string used by USB */static void str2wide (char *str, u16 * wide){	int i;	for (i = 0; i < strlen (str) && str[i]; i++){		#if defined(__LITTLE_ENDIAN)			wide[i] = (u16) str[i];		#elif defined(__BIG_ENDIAN)			wide[i] = ((u16)(str[i])<<8);		#else			#error "__LITTLE_ENDIAN or __BIG_ENDIAN undefined"		#endif	}}/* * Test whether a character is in the RX buffer */int usbtty_tstc (void){	struct usb_endpoint_instance *endpoint =		&endpoint_instance[rx_endpoint];	/* If no input data exists, allow more RX to be accepted */	if(usbtty_input.size <= 0){		udc_unset_nak(endpoint->endpoint_address&0x03);	}	usbtty_poll ();	return (usbtty_input.size > 0);}/* * Read a single byte from the usb client port. Returns 1 on success, 0 * otherwise. When the function is succesfull, the character read is * written into its argument c. */int usbtty_getc (void){	char c;	struct usb_endpoint_instance *endpoint =		&endpoint_instance[rx_endpoint];	while (usbtty_input.size <= 0) {		udc_unset_nak(endpoint->endpoint_address&0x03);		usbtty_poll ();	}	buf_pop (&usbtty_input, &c, 1);	udc_set_nak(endpoint->endpoint_address&0x03);	return c;}/* * Output a single byte to the usb client port. */void usbtty_putc (const char c){	buf_push (&usbtty_output, &c, 1);	/* If \n, also do \r */	if (c == '\n')		buf_push (&usbtty_output, "\r", 1);	/* Poll at end to handle new data... */	if ((usbtty_output.size + 2) >= usbtty_output.totalsize) {		usbtty_poll ();	}}/* usbtty_puts() helper function for finding the next '\n' in a string */static int next_nl_pos (const char *s){	int i;	for (i = 0; s[i] != '\0'; i++) {		if (s[i] == '\n')			return i;	}	return i;}/* * Output a string to the usb client port - implementing flow control */static void __usbtty_puts (const char *str, int len){	int maxlen = usbtty_output.totalsize;	int space, n;	/* break str into chunks < buffer size, if needed */	while (len > 0) {		usbtty_poll ();		space = maxlen - usbtty_output.size;		/* Empty buffer here, if needed, to ensure space... */		if (space) {			write_buffer (&usbtty_output);			n = MIN (space, MIN (len, maxlen));			buf_push (&usbtty_output, str, n);			str += n;			len -= n;		}	}}void usbtty_puts (const char *str){	int n;	int len = strlen (str);	/* add '\r' for each '\n' */	while (len > 0) {		n = next_nl_pos (str);		if (str[n] == '\n') {			__usbtty_puts (str, n + 1);			__usbtty_puts ("\r", 1);			str += (n + 1);			len -= (n + 1);		} else {			/* No \n found.	 All done. */			__usbtty_puts (str, n);			break;

⌨️ 快捷键说明

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