00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include "../virthid.h"
00036 #include <errno.h>
00037 #include <usb/debug.h>
00038 #include <usb/hid/hid.h>
00039 #include <usb/hid/usages/core.h>
00040
00041 #include "../report.h"
00042
00043 uint8_t report_descriptor[] = {
00044 STD_USAGE_PAGE(USB_HIDUT_PAGE_GENERIC_DESKTOP),
00045 USAGE1(USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD),
00046 START_COLLECTION(COLLECTION_APPLICATION),
00047 STD_USAGE_PAGE(USB_HIDUT_PAGE_KEYBOARD),
00048 USAGE_MINIMUM1(224),
00049 USAGE_MAXIMUM1(231),
00050 LOGICAL_MINIMUM1(0),
00051 LOGICAL_MAXIMUM1(1),
00052 REPORT_SIZE1(1),
00053 REPORT_COUNT1(8),
00054
00055 INPUT(IOF_DATA | IOF_VARIABLE | IOF_ABSOLUTE),
00056 REPORT_COUNT1(1),
00057 REPORT_SIZE1(8),
00058
00059 INPUT(IOF_CONSTANT),
00060 REPORT_COUNT1(5),
00061 REPORT_SIZE1(1),
00062 STD_USAGE_PAGE(USB_HIDUT_PAGE_LED),
00063 USAGE_MINIMUM1(1),
00064 USAGE_MAXIMUM1(5),
00065
00066 OUTPUT(IOF_DATA | IOF_VARIABLE | IOF_ABSOLUTE),
00067 REPORT_COUNT1(1),
00068 REPORT_SIZE1(3),
00069
00070 OUTPUT(IOF_CONSTANT),
00071 REPORT_COUNT1(6),
00072 REPORT_SIZE1(8),
00073 LOGICAL_MINIMUM1(0),
00074 LOGICAL_MAXIMUM1(101),
00075 STD_USAGE_PAGE(USB_HIDUT_PAGE_KEYBOARD),
00076 USAGE_MINIMUM1(0),
00077 USAGE_MAXIMUM1(101),
00078
00079 INPUT(IOF_DATA | IOF_ARRAY),
00080 END_COLLECTION()
00081 };
00082
00083 #define INPUT_SIZE 8
00084
00085 static uint8_t in_data[] = {
00086 0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00087 0, 0, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00,
00088 0, 0, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00,
00089 0, 0, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00,
00090 1 << 2, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00091 1 << 2, 0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
00092 1 << 2, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00093 0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00094 };
00095 static size_t in_data_count = sizeof(in_data)/INPUT_SIZE;
00096
00097 static size_t in_data_position = 0;
00098
00099 static int on_data_in(vuhid_interface_t *iface,
00100 void *buffer, size_t buffer_size, size_t *act_buffer_size)
00101 {
00102 static size_t last_pos = (size_t) -1;
00103 size_t pos = in_data_position;
00104 if (pos >= in_data_count) {
00105 return EBADCHECKSUM;
00106 }
00107
00108 if (last_pos == pos) {
00109 return ENAK;
00110 }
00111
00112 if (buffer_size > INPUT_SIZE) {
00113 buffer_size = INPUT_SIZE;
00114 }
00115
00116 if (act_buffer_size != NULL) {
00117 *act_buffer_size = buffer_size;
00118 }
00119
00120 memcpy(buffer, in_data + pos * INPUT_SIZE, buffer_size);
00121 last_pos = pos;
00122
00123 return EOK;
00124 }
00125
00126 static int on_data_out(vuhid_interface_t *iface,
00127 void *buffer, size_t buffer_size)
00128 {
00129 if (buffer_size == 0) {
00130 return EEMPTY;
00131 }
00132 uint8_t leds = ((uint8_t *) buffer)[0];
00133 #define _GET_LED(index, signature) \
00134 (((leds) & (1 << index)) ? (signature) : '-')
00135 usb_log_info("%s: LEDs = %c%c%c%c%c\n",
00136 iface->name,
00137 _GET_LED(0, '0'), _GET_LED(1, 'A'), _GET_LED(2, 's'),
00138 _GET_LED(3, 'c'), _GET_LED(4, 'k'));
00139 #undef _GET_LED
00140 return EOK;
00141 }
00142
00143
00144 static void live(vuhid_interface_t *iface)
00145 {
00146 async_usleep(1000 * 1000 * 5);
00147 usb_log_debug("Boot keyboard comes to life...\n");
00148 while (in_data_position < in_data_count) {
00149 async_usleep(1000 * 500);
00150 in_data_position++;
00151 }
00152 usb_log_debug("Boot keyboard died.\n");
00153 }
00154
00155
00156 vuhid_interface_t vuhid_interface_bootkbd = {
00157 .id = "boot",
00158 .name = "boot keyboard",
00159 .usb_subclass = USB_HID_SUBCLASS_BOOT,
00160 .usb_protocol = USB_HID_PROTOCOL_KEYBOARD,
00161
00162 .report_descriptor = report_descriptor,
00163 .report_descriptor_size = sizeof(report_descriptor),
00164
00165 .in_data_size = INPUT_SIZE,
00166 .on_data_in = on_data_in,
00167
00168 .out_data_size = 1,
00169 .on_data_out = on_data_out,
00170
00171 .live = live,
00172
00173 .vuhid_data = NULL
00174 };
00175