00001
00039 #include "usbser.h"
00040
00041 #include "cfg/cfg_usbser.h"
00042
00043 #define LOG_LEVEL USB_SERIAL_LOG_LEVEL
00044 #define LOG_FORMAT USB_SERIAL_LOG_FORMAT
00045
00046 #include <cfg/log.h>
00047 #include <cfg/debug.h>
00048 #include <cfg/macros.h>
00049
00050 #include <cfg/compiler.h>
00051 #include <cfg/module.h>
00052
00053 #include <cpu/irq.h>
00054 #include <cpu/power.h>
00055
00056 #include <drv/usb.h>
00057 #include <drv/usb_endpoint.h>
00058
00059 #include <string.h>
00060
00061
00062 #define USB_SERIAL_INTERFACES 1
00063 #define USB_SERIAL_ENDPOINTS 3
00064
00065 #define USB_STRING_MANUFACTURER 1
00066 #define USB_STRING_PRODUCT 2
00067 #define USB_STRING_SERIAL 3
00068
00069 static UsbDeviceDesc usb_serial_device_descriptor =
00070 {
00071 .bLength = sizeof(usb_serial_device_descriptor),
00072 .bDescriptorType = USB_DT_DEVICE,
00073 .bcdUSB = 0x110,
00074 .bDeviceClass = USB_CLASS_COMM,
00075 .bDeviceSubClass = 0,
00076 .bDeviceProtocol = 0,
00077 .idVendor = USB_SERIAL_VENDOR_ID,
00078 .idProduct = USB_SERIAL_PRODUCT_ID,
00079 .bcdDevice = 0,
00080 .iManufacturer = USB_STRING_MANUFACTURER,
00081 .iProduct = USB_STRING_PRODUCT,
00082 .iSerialNumber = USB_STRING_SERIAL,
00083 .bNumConfigurations = 1,
00084 };
00085
00086 static const UsbConfigDesc usb_serial_config_descriptor =
00087 {
00088 .bLength = sizeof(usb_serial_config_descriptor),
00089 .bDescriptorType = USB_DT_CONFIG,
00090 .bNumInterfaces = USB_SERIAL_INTERFACES,
00091 .bConfigurationValue = 1,
00092 .iConfiguration = 0,
00093 .bmAttributes = USB_CONFIG_ATT_ONE,
00094 .bMaxPower = 50,
00095 };
00096
00097 static const UsbInterfaceDesc usb_serial_interface_descriptor =
00098 {
00099 .bLength = sizeof(usb_serial_interface_descriptor),
00100 .bDescriptorType = USB_DT_INTERFACE,
00101 .bInterfaceNumber = 0,
00102 .bAlternateSetting = 0,
00103 .bNumEndpoints = USB_SERIAL_ENDPOINTS,
00104 .bInterfaceClass = 0xff,
00105 .bInterfaceSubClass = 0,
00106 .bInterfaceProtocol = 0,
00107 .iInterface = 0,
00108 };
00109
00110 static const UsbEndpointDesc usb_serial_ep_report_descriptor =
00111 {
00112 .bLength = sizeof(usb_serial_ep_report_descriptor),
00113 .bDescriptorType = USB_DT_ENDPOINT,
00114 .bEndpointAddress = USB_DIR_IN | USB_SERIAL_EP_REPORT,
00115 .bmAttributes = USB_ENDPOINT_XFER_INT,
00116 .wMaxPacketSize = usb_cpu_to_le16((uint16_t)8),
00117 .bInterval = 1,
00118 };
00119
00120 static const UsbEndpointDesc usb_serial_ep_in_descriptor =
00121 {
00122 .bLength = sizeof(usb_serial_ep_in_descriptor),
00123 .bDescriptorType = USB_DT_ENDPOINT,
00124 .bEndpointAddress = USB_DIR_IN | USB_SERIAL_EP_IN,
00125 .bmAttributes = USB_ENDPOINT_XFER_BULK,
00126 .wMaxPacketSize = usb_cpu_to_le16((uint16_t)64),
00127 .bInterval = 0,
00128 };
00129
00130 static const UsbEndpointDesc usb_serial_ep_out_descriptor =
00131 {
00132 .bLength = sizeof(usb_serial_ep_in_descriptor),
00133 .bDescriptorType = USB_DT_ENDPOINT,
00134 .bEndpointAddress = USB_DIR_OUT | USB_SERIAL_EP_OUT,
00135 .bmAttributes = USB_ENDPOINT_XFER_BULK,
00136 .wMaxPacketSize = usb_cpu_to_le16((uint16_t)64),
00137 .bInterval = 0,
00138 };
00139
00140 static const UsbDescHeader *usb_serial_config[] =
00141 {
00142 (const UsbDescHeader *)&usb_serial_config_descriptor,
00143 (const UsbDescHeader *)&usb_serial_interface_descriptor,
00144 (const UsbDescHeader *)&usb_serial_ep_report_descriptor,
00145 (const UsbDescHeader *)&usb_serial_ep_in_descriptor,
00146 (const UsbDescHeader *)&usb_serial_ep_out_descriptor,
00147 NULL,
00148 };
00149
00150 static const DEFINE_USB_STRING(language_str, "\x09\x04");
00151 static const DEFINE_USB_STRING(manufacturer_str,
00152 USB_STRING("B", "e", "R", "T", "O", "S"));
00153 static const DEFINE_USB_STRING(product_str,
00154 USB_STRING("U", "S", "B", "-", "s", "e", "r", "i", "a", "l"));
00155 static const DEFINE_USB_STRING(serial_str,
00156 USB_STRING("0", "0", "1"));
00157
00158 static const UsbStringDesc *usb_serial_strings[] =
00159 {
00160 (const UsbStringDesc *)&language_str,
00161 (const UsbStringDesc *)&manufacturer_str,
00162 (const UsbStringDesc *)&product_str,
00163 (const UsbStringDesc *)&serial_str,
00164 NULL,
00165 };
00166
00167
00168 static UsbDevice usb_serial = {
00169 .device = &usb_serial_device_descriptor,
00170 .config = usb_serial_config,
00171 .strings = usb_serial_strings,
00172 };
00173
00174
00175 static int usb_serial_hw_init(void)
00176 {
00177 #if CONFIG_KERN
00178 MOD_CHECK(proc);
00179 #endif
00180 if (usb_deviceRegister(&usb_serial) < 0)
00181 return -1;
00182 LOG_INFO("usb-serial: registered new USB interface driver\n");
00183 return 0;
00184 }
00185
00191 static size_t usb_serial_write(struct KFile *fd,
00192 const void *buf, size_t size)
00193 {
00194 DB(USBSerial *fds = USB_SERIAL_CAST(fd));
00195
00196
00197 (void)fd;
00198 ASSERT(fds->is_open);
00199 return usb_endpointWrite(usb_serial_ep_in_descriptor.bEndpointAddress,
00200 buf, size);
00201 }
00202
00208 static size_t usb_serial_read(struct KFile *fd, void *buf, size_t size)
00209 {
00210 DB(USBSerial *fds = USB_SERIAL_CAST(fd));
00211
00212
00213 (void)fd;
00214 ASSERT(fds->is_open);
00215 return usb_endpointRead(usb_serial_ep_out_descriptor.bEndpointAddress,
00216 buf, size);
00217 }
00218
00224 static int usb_serial_error(struct KFile *fd)
00225 {
00226 USBSerial *fds = USB_SERIAL_CAST(fd);
00227 return fds->status;
00228 }
00229
00235 static void usb_serial_clearerr(struct KFile *fd)
00236 {
00237 USBSerial *fds = USB_SERIAL_CAST(fd);
00238 fds->status = 0;
00239 }
00240
00244 static int usb_serial_close(struct KFile *fd)
00245 {
00246 DB(USBSerial *fds = USB_SERIAL_CAST(fd));
00247
00248
00249 (void)fd;
00250 ASSERT(fds->is_open);
00251 DB(fds->is_open = false);
00252 return 0;
00253 }
00254
00261 static int usb_serial_open(struct USBSerial *fds, int unit)
00262 {
00263 unit = unit;
00264 ASSERT(!fds->is_open);
00265
00266 ASSERT(unit == 0);
00267
00268
00269 if (usb_serial_hw_init() < 0)
00270 return -1;
00271
00272 fds->status = 0;
00273 DB(fds->is_open = true);
00274
00275 return 0;
00276 }
00277
00281 static struct KFile *usb_serial_reopen(struct KFile *fd)
00282 {
00283 USBSerial *fds = USB_SERIAL_CAST(fd);
00284
00285 usb_serial_close(fd);
00286 usb_serial_open(fds, fds->unit);
00287 return 0;
00288 }
00289
00295 int usbser_init(struct USBSerial *fds, int unit)
00296 {
00297 memset(fds, 0, sizeof(*fds));
00298
00299 DB(fds->fd._type = KFT_USB_SERIAL);
00300 fds->fd.reopen = usb_serial_reopen;
00301 fds->fd.close = usb_serial_close;
00302 fds->fd.read = usb_serial_read;
00303 fds->fd.write = usb_serial_write;
00304
00305 fds->fd.error = usb_serial_error;
00306 fds->fd.clearerr = usb_serial_clearerr;
00307
00308 return usb_serial_open(fds, unit);
00309 }