BeRTOS
|
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> /* IRQ_DISABLE / IRQ_ENABLE */ 00054 #include <cpu/power.h> /* cpu_relax() */ 00055 00056 #include <drv/usb.h> 00057 #include <drv/usb_endpoint.h> 00058 00059 #include <string.h> /* memcpy() */ 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, /* 100 mA */ 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"); // Language ID: en_US 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 /* Global usb-serial descriptor that identifies the usb-serial device */ 00168 static UsbDevice usb_serial = { 00169 .device = &usb_serial_device_descriptor, 00170 .config = usb_serial_config, 00171 .strings = usb_serial_strings, 00172 }; 00173 00174 /* Low-level usb-serial device initialization */ 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 /* Silent compiler warnings if _DEBUG is not enabled */ 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 /* Silent compiler warnings if _DEBUG is not enabled */ 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 /* Silent compiler warnings if _DEBUG is not enabled */ 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 /* TODO: only a single usb-serial unit is supported for now */ 00266 ASSERT(unit == 0); 00267 00268 /* Initialize usb-serial driver */ 00269 if (usb_serial_hw_init() < 0) 00270 return -1; 00271 /* Clear error flags */ 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 /* TODO: properly implement error handling. */ 00305 fds->fd.error = usb_serial_error; 00306 fds->fd.clearerr = usb_serial_clearerr; 00307 00308 return usb_serial_open(fds, unit); 00309 }