00001
00041 #include "usb_hid.h"
00042 #include "usbmouse.h"
00043
00044 #include "cfg/cfg_usbmouse.h"
00045
00046 #define LOG_LEVEL USB_MOUSE_LOG_LEVEL
00047 #define LOG_FORMAT USB_MOUSE_LOG_FORMAT
00048
00049 #include <cfg/log.h>
00050 #include <cfg/debug.h>
00051 #include <cfg/macros.h>
00052 #include <cfg/compiler.h>
00053 #include <cfg/module.h>
00054
00055 #include <cpu/power.h>
00056
00057 #include <drv/usb.h>
00058 #include <drv/usb_endpoint.h>
00059
00060
00061
00062
00063
00064 #define USB_HID_VENDOR_ID USB_MOUSE_VENDOR_ID
00065 #define USB_HID_PRODUCT_ID USB_MOUSE_PRODUCT_ID
00066
00067 #define USB_HID_INTERFACES 1
00068 #define USB_HID_ENDPOINTS 1
00069
00070 #define USB_STRING_MANUFACTURER 1
00071 #define USB_STRING_PRODUCT 2
00072
00073 #define USB_HID_REPORT_EP (USB_DIR_IN | USB_MOUSE_EP_REPORT)
00074
00075 static UsbDeviceDesc usb_hid_device_descriptor =
00076 {
00077 .bLength = sizeof(usb_hid_device_descriptor),
00078 .bDescriptorType = USB_DT_DEVICE,
00079 .bcdUSB = 0x100,
00080 .bDeviceClass = 0,
00081 .bDeviceSubClass = 0,
00082 .bDeviceProtocol = 0,
00083 .idVendor = USB_HID_VENDOR_ID,
00084 .idProduct = USB_HID_PRODUCT_ID,
00085 .bcdDevice = 0,
00086 .iManufacturer = USB_STRING_MANUFACTURER,
00087 .iProduct = USB_STRING_PRODUCT,
00088 .iSerialNumber = 0,
00089 .bNumConfigurations = 1,
00090 };
00091
00092 static const UsbConfigDesc usb_hid_config_descriptor =
00093 {
00094 .bLength = sizeof(usb_hid_config_descriptor),
00095 .bDescriptorType = USB_DT_CONFIG,
00096 .bNumInterfaces = USB_HID_INTERFACES,
00097 .bConfigurationValue = 1,
00098 .iConfiguration = 0,
00099 .bmAttributes = USB_CONFIG_ATT_ONE,
00100 .bMaxPower = 50,
00101 };
00102
00103 static const UsbInterfaceDesc usb_hid_interface_descriptor =
00104 {
00105 .bLength = sizeof(usb_hid_interface_descriptor),
00106 .bDescriptorType = USB_DT_INTERFACE,
00107 .bInterfaceNumber = 0,
00108 .bAlternateSetting = 0,
00109 .bNumEndpoints = USB_HID_ENDPOINTS,
00110 .bInterfaceClass = USB_CLASS_HID,
00111 .bInterfaceSubClass = USB_INTERFACE_SUBCLASS_BOOT,
00112 .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE,
00113 .iInterface = 0,
00114 };
00115
00116 static const uint8_t hid_report_descriptor[] =
00117 {
00118 0x05, 0x01,
00119 0x09, 0x02,
00120 0xA1, 0x01,
00121 0x09, 0x01,
00122 0xA1, 0x00,
00123 0x05, 0x09,
00124 0x19, 0x01,
00125 0x29, 0x03,
00126 0x15, 0x00,
00127 0x25, 0x01,
00128 0x95, 0x03,
00129 0x75, 0x01,
00130 0x81, 0x02,
00131 0x95, 0x01,
00132 0x75, 0x05,
00133 0x81, 0x01,
00134 0x05, 0x01,
00135 0x09, 0x30,
00136 0x09, 0x31,
00137 0x09, 0x38,
00138 0x15, 0x81,
00139 0x25, 0x7F,
00140 0x75, 0x08,
00141 0x95, 0x02,
00142 0x81, 0x06,
00143 0xC0,
00144 0xC0
00145 };
00146
00147 static const usb_HidDesc usb_hid_descriptor =
00148 {
00149 .bLength = sizeof(usb_hid_descriptor),
00150 .bDescriptorType = HID_DT_HID,
00151 .bcdHID = usb_cpu_to_le16((uint16_t)0x0110),
00152 .bCountryCode = 0,
00153 .bNumDescriptors = 1,
00154 .bDescriptorHidType = HID_DT_REPORT,
00155 .wDescriptorLength =
00156 usb_cpu_to_le16((uint16_t)sizeof(hid_report_descriptor)),
00157 };
00158
00159 static const UsbEndpointDesc usb_hid_ep_descriptor =
00160 {
00161 .bLength = sizeof(usb_hid_ep_descriptor),
00162 .bDescriptorType = USB_DT_ENDPOINT,
00163 .bEndpointAddress = USB_HID_REPORT_EP,
00164 .bmAttributes = USB_ENDPOINT_XFER_INT,
00165 .wMaxPacketSize = usb_cpu_to_le16((uint16_t)4),
00166 .bInterval = 10,
00167 };
00168
00169 static const UsbDescHeader *usb_hid_config[] =
00170 {
00171 (const UsbDescHeader *)&usb_hid_config_descriptor,
00172 (const UsbDescHeader *)&usb_hid_interface_descriptor,
00173 (const UsbDescHeader *)&usb_hid_descriptor,
00174 (const UsbDescHeader *)&usb_hid_ep_descriptor,
00175 NULL,
00176 };
00177
00178 static const DEFINE_USB_STRING(language_str, "\x09\x04");
00179 static const DEFINE_USB_STRING(manufacturer_str,
00180 USB_STRING("B", "e", "R", "T", "O", "S"));
00181 static const DEFINE_USB_STRING(product_str,
00182 USB_STRING("U", "S", "B", " ", "M", "o", "u", "s", "e"));
00183
00184 static const UsbStringDesc *usb_hid_strings[] =
00185 {
00186 (const UsbStringDesc *)&language_str,
00187 (const UsbStringDesc *)&manufacturer_str,
00188 (const UsbStringDesc *)&product_str,
00189 NULL,
00190 };
00191
00192 typedef struct mouse_report
00193 {
00194 uint8_t buttons;
00195 int8_t x;
00196 int8_t y;
00197 } PACKED mouse_report_t;
00198
00199 static mouse_report_t report;
00200
00201 static bool hid_mouse_configured;
00202
00203 static void usb_hid_event_cb(UsbCtrlRequest *ctrl)
00204 {
00205 uint16_t value = usb_le16_to_cpu(ctrl->wValue);
00206 uint16_t index = usb_le16_to_cpu(ctrl->wIndex);
00207 uint16_t length = usb_le16_to_cpu(ctrl->wLength);
00208 uint8_t type = ctrl->mRequestType;
00209 uint8_t request = ctrl->bRequest;
00210
00211 LOG_INFO("%s: s 0x%02x 0x%02x 0x%04x 0x%04x 0x%04x\n",
00212 __func__, type, request, value, index, length);
00213 switch (ctrl->bRequest)
00214 {
00215 case USB_REQ_GET_DESCRIPTOR:
00216 switch (value >> 8)
00217 {
00218 case HID_DT_HID:
00219 LOG_INFO("%s: HID_DT_HID\n", __func__);
00220 usb_endpointWrite(USB_DIR_IN | 0,
00221 &usb_hid_descriptor,
00222 sizeof(usb_hid_descriptor));
00223 break;
00224 case HID_DT_REPORT:
00225 LOG_INFO("%s: HID_DT_REPORT\n", __func__);
00226 usb_endpointWrite(USB_DIR_IN | 0,
00227 &hid_report_descriptor,
00228 sizeof(hid_report_descriptor));
00229 hid_mouse_configured = true;
00230 break;
00231 }
00232 break;
00233 case HID_REQ_GET_REPORT:
00234 LOG_INFO("%s: HID_REQ_GET_REPORT\n", __func__);
00235 break;
00236 case HID_REQ_SET_REPORT:
00237 LOG_INFO("%s: HID_REQ_SET_REPORT\n", __func__);
00238 break;
00239 case HID_REQ_GET_IDLE:
00240 LOG_INFO("%s: HID_REQ_GET_IDLE\n", __func__);
00241 break;
00242 case HID_REQ_SET_IDLE:
00243 LOG_INFO("%s: HID_REQ_SET_IDLE\n", __func__);
00244 usb_endpointWrite(USB_DIR_IN | 0, NULL, 0);
00245 break;
00246 case HID_REQ_GET_PROTOCOL:
00247 LOG_INFO("%s: HID_REQ_GET_PROTOCOL\n", __func__);
00248 break;
00249 case HID_REQ_SET_PROTOCOL:
00250 LOG_INFO("%s: HID_REQ_SET_PROTOCOL\n", __func__);
00251 break;
00252 default:
00253 LOG_ERR("%s: unknown request: 0x%02x\n",
00254 __func__, ctrl->bRequest);
00255 break;
00256 }
00257 }
00258
00259
00260 static UsbDevice usb_mouse = {
00261 .device = &usb_hid_device_descriptor,
00262 .config = usb_hid_config,
00263 .strings = usb_hid_strings,
00264 .event_cb = usb_hid_event_cb,
00265 };
00266
00267
00268 static int usb_mouse_hw_init(void)
00269 {
00270 if (usb_deviceRegister(&usb_mouse) < 0)
00271 return -1;
00272 LOG_INFO("usb-hid: registered new USB mouse device\n");
00273 return 0;
00274 }
00275
00276
00277 void usbmouse_sendEvent(int8_t x, int8_t y, int8_t buttons)
00278 {
00279 report.x = x;
00280 report.y = y;
00281 report.buttons = buttons;
00282 usb_endpointWrite(USB_HID_REPORT_EP, &report, sizeof(report));
00283 }
00284
00285
00286
00287
00288
00289
00290 int usbmouse_init(UNUSED_ARG(int, unit))
00291 {
00292 #if CONFIG_KERN
00293 MOD_CHECK(proc);
00294 #endif
00295 usb_mouse_hw_init();
00296 while (!hid_mouse_configured)
00297 cpu_relax();
00298 return 0;
00299 }