📄 usbtty.c
字号:
/* * (C) Copyright 2003 * Gerry Hamel, geh@ti.com, Texas Instruments * * 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"#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 0#define TTYERR(fmt,args...) serial_printf("ERROR![%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args)#else#define TTYERR(fmt,args...) do{}while(0)#endif/* * 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[NUM_INTERFACES];static struct usb_alternate_instance alternate_instance[NUM_INTERFACES];static struct usb_endpoint_instance endpoint_instance[NUM_ENDPOINTS+1]; /* one extra for control endpoint *//* * Static allocation of urbs */#define RECV_ENDPOINT 1#define TX_ENDPOINT 2/* * Global flag */int usbtty_configured_flag = 0;/* * Serial number */static char serial_number[16];/* * Descriptors */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 wstrInterface[2 + 2*(sizeof(CONFIG_USBD_INTERFACE_STR)-1)];static struct usb_string_descriptor *usbtty_string_table[] = { (struct usb_string_descriptor*)wstrLang, (struct usb_string_descriptor*)wstrManufacturer, (struct usb_string_descriptor*)wstrProduct, (struct usb_string_descriptor*)wstrSerial, (struct usb_string_descriptor*)wstrConfiguration, (struct usb_string_descriptor*)wstrInterface};extern struct usb_string_descriptor **usb_strings; /* defined and used by omap1510_ep0.c */static struct usb_device_descriptor device_descriptor = { bLength: sizeof(struct usb_device_descriptor), bDescriptorType: USB_DT_DEVICE, bcdUSB: USB_BCD_VERSION, bDeviceClass: USBTTY_DEVICE_CLASS, bDeviceSubClass: USBTTY_DEVICE_SUBCLASS, bDeviceProtocol: USBTTY_DEVICE_PROTOCOL, bMaxPacketSize0: EP0_MAX_PACKET_SIZE, idVendor: CONFIG_USBD_VENDORID, idProduct: CONFIG_USBD_PRODUCTID, bcdDevice: USBTTY_BCD_DEVICE, iManufacturer: STR_MANUFACTURER, iProduct: STR_PRODUCT, iSerialNumber: STR_SERIAL, bNumConfigurations: NUM_CONFIGS };static struct usb_configuration_descriptor config_descriptors[NUM_CONFIGS] = { { bLength: sizeof(struct usb_configuration_descriptor), bDescriptorType: USB_DT_CONFIG, wTotalLength: (sizeof(struct usb_configuration_descriptor)*NUM_CONFIGS) + (sizeof(struct usb_interface_descriptor)*NUM_INTERFACES) + (sizeof(struct usb_endpoint_descriptor)*NUM_ENDPOINTS), bNumInterfaces: NUM_INTERFACES, bConfigurationValue: 1, iConfiguration: STR_CONFIG, bmAttributes: BMATTRIBUTE_SELF_POWERED | BMATTRIBUTE_RESERVED, bMaxPower: USBTTY_MAXPOWER },};static struct usb_interface_descriptor interface_descriptors[NUM_INTERFACES] = { { bLength: sizeof(struct usb_interface_descriptor), bDescriptorType: USB_DT_INTERFACE, bInterfaceNumber: 0, bAlternateSetting: 0, bNumEndpoints: NUM_ENDPOINTS, bInterfaceClass: USBTTY_INTERFACE_CLASS, bInterfaceSubClass: USBTTY_INTERFACE_SUBCLASS, bInterfaceProtocol: USBTTY_INTERFACE_PROTOCOL, iInterface: STR_INTERFACE },};static struct usb_endpoint_descriptor ep_descriptors[NUM_ENDPOINTS] = { { bLength: sizeof(struct usb_endpoint_descriptor), bDescriptorType: USB_DT_ENDPOINT, bEndpointAddress: CONFIG_USBD_SERIAL_OUT_ENDPOINT | USB_DIR_OUT, bmAttributes: USB_ENDPOINT_XFER_BULK, wMaxPacketSize: CONFIG_USBD_SERIAL_OUT_PKTSIZE, bInterval: 0 }, { bLength: sizeof(struct usb_endpoint_descriptor), bDescriptorType: USB_DT_ENDPOINT, bEndpointAddress: CONFIG_USBD_SERIAL_IN_ENDPOINT | USB_DIR_IN, bmAttributes: USB_ENDPOINT_XFER_BULK, wMaxPacketSize: CONFIG_USBD_SERIAL_IN_PKTSIZE, bInterval: 0 }, { bLength: sizeof(struct usb_endpoint_descriptor), bDescriptorType: USB_DT_ENDPOINT, bEndpointAddress: CONFIG_USBD_SERIAL_INT_ENDPOINT | USB_DIR_IN, bmAttributes: USB_ENDPOINT_XFER_INT, wMaxPacketSize: CONFIG_USBD_SERIAL_INT_PKTSIZE, bInterval: 0 },};static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS] = { &(ep_descriptors[0]), &(ep_descriptors[1]), &(ep_descriptors[2]),};/* 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++) wide[i] = (u16) str[i];}/* * Prototypes */static void usbtty_init_strings (void);static void usbtty_init_instances (void);static void usbtty_init_endpoints (void);static void usbtty_event_handler (struct usb_device_instance *device, usb_device_event_t event, int data);static int usbtty_configured (void);static int write_buffer (circbuf_t * buf);static int fill_buffer (circbuf_t * buf);void usbtty_poll (void);static void pretend_interrupts (void);/* * Test whether a character is in the RX buffer */int usbtty_tstc (void){ 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; while (usbtty_input.size <= 0) { usbtty_poll (); } buf_pop (&usbtty_input, &c, 1); 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. */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) { space = maxlen - usbtty_output.size; /* Empty buffer here, if needed, to ensure space... */ if (space <= 0) { write_buffer (&usbtty_output); space = maxlen - usbtty_output.size; if (space <= 0) { space = len; /* allow old data to be overwritten. */ } } 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; } } /* Poll at end to handle new data... */ usbtty_poll ();}/* * Initialize the usb client port. * */int drv_usbtty_init (void){ int rc; char * sn; int snlen; if (!(sn = getenv("serial#"))) { sn = "000000000000"; } snlen = strlen(sn); if (snlen > sizeof(serial_number) - 1) { printf ("Warning: serial number %s is too long (%d > %d)\n", sn, snlen, sizeof(serial_number) - 1); snlen = sizeof(serial_number) - 1; } memcpy (serial_number, sn, snlen); serial_number[snlen] = '\0'; /* prepare buffers... */ buf_init (&usbtty_input, USBTTY_BUFFER_SIZE); buf_init (&usbtty_output, USBTTY_BUFFER_SIZE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -