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