|
13 | 13 | ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, |
14 | 14 | ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, |
15 | 15 | ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS |
16 | | -** SOFTWARE. |
| 16 | +** SOFTWARE. |
17 | 17 | */ |
18 | 18 |
|
19 | | -#include "USB/PluggableUSB.h" |
20 | 19 | #include "HID.h" |
21 | 20 |
|
22 | | -HID_ HID; |
| 21 | +#if defined(USBCON) |
23 | 22 |
|
24 | | -static uint8_t HID_ENDPOINT_INT; |
25 | | - |
26 | | -//================================================================================ |
27 | | -//================================================================================ |
28 | | - |
29 | | -//HID report descriptor |
30 | | - |
31 | | -#define LSB(_x) ((_x) & 0xFF) |
32 | | -#define MSB(_x) ((_x) >> 8) |
33 | | - |
34 | | -#define RAWHID_USAGE_PAGE0xFFC0 |
35 | | -#define RAWHID_USAGE0x0C00 |
36 | | -#define RAWHID_TX_SIZE 64 |
37 | | -#define RAWHID_RX_SIZE 64 |
38 | | - |
39 | | -static uint8_t HID_INTERFACE; |
40 | | - |
41 | | -HIDDescriptor _hidInterface; |
42 | | - |
43 | | -static HIDDescriptorListNode* rootNode = NULL; |
44 | | -static uint8_t sizeof_hidReportDescriptor = 0; |
45 | | -static uint8_t modules_count = 0; |
46 | | -//================================================================================ |
47 | | -//================================================================================ |
48 | | -//Driver |
49 | | - |
50 | | -uint8_t _hid_protocol = 1; |
51 | | -uint8_t _hid_idle = 1; |
| 23 | +HID_& HID() |
| 24 | +{ |
| 25 | +static HID_ obj; |
| 26 | +return obj; |
| 27 | +} |
52 | 28 |
|
53 | | -int HID_GetInterface(uint8_t* interfaceNum) |
| 29 | +int HID_::getInterface(uint8_t* interfaceCount) |
54 | 30 | { |
55 | | -interfaceNum[0] += 1;// uses 1 |
56 | | -_hidInterface = |
57 | | -{ |
58 | | -D_INTERFACE(HID_INTERFACE,1,3,0,0), |
59 | | -D_HIDREPORT(sizeof_hidReportDescriptor), |
60 | | -D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01) |
| 31 | +*interfaceCount += 1; // uses 1 |
| 32 | +HIDDescriptor hidInterface = { |
| 33 | +D_INTERFACE(pluggedInterface, 1, USB_DEVICE_CLASS_HUMAN_INTERFACE, HID_SUBCLASS_NONE, HID_PROTOCOL_NONE), |
| 34 | +D_HIDREPORT(descriptorSize), |
| 35 | +D_ENDPOINT(USB_ENDPOINT_IN(pluggedEndpoint), USB_ENDPOINT_TYPE_INTERRUPT, 0x40, 0x01) |
61 | 36 | }; |
62 | | -return USBD_SendControl(0,&_hidInterface,sizeof(_hidInterface)); |
| 37 | +return USBD_SendControl(0, &hidInterface, sizeof(hidInterface)); |
63 | 38 | } |
64 | 39 |
|
65 | | -int HID_GetDescriptor(int8_t t) |
| 40 | +int HID_::getDescriptor(USBSetup& setup) |
66 | 41 | { |
67 | | -if (HID_REPORT_DESCRIPTOR_TYPE == t) { |
68 | | -HIDDescriptorListNode* current = rootNode; |
69 | | -int total = 0; |
70 | | -while(current != NULL) { |
71 | | -total += USBD_SendControl(0,current->data,current->length); |
72 | | -current = current->next; |
73 | | -} |
74 | | -return total; |
75 | | -} else { |
76 | | -return 0; |
| 42 | +// Check if this is a HID Class Descriptor request |
| 43 | +if (setup.bmRequestType != REQUEST_DEVICETOHOST_STANDARD_INTERFACE) { return 0; } |
| 44 | +if (setup.wValueH != HID_REPORT_DESCRIPTOR_TYPE) { return 0; } |
| 45 | + |
| 46 | +// In a HID Class Descriptor wIndex cointains the interface number |
| 47 | +if (setup.wIndex != pluggedInterface) { return 0; } |
| 48 | + |
| 49 | +int total = 0; |
| 50 | +HIDSubDescriptor* node; |
| 51 | +for (node = rootNode; node; node = node->next) { |
| 52 | +int res = USBD_SendControl(0, node->data, node->length); |
| 53 | +if (res == -1) |
| 54 | +return -1; |
| 55 | +total += res; |
77 | 56 | } |
| 57 | +return total; |
78 | 58 | } |
79 | 59 |
|
80 | | -void HID_::AppendDescriptor(HIDDescriptorListNode *node) |
| 60 | +void HID_::AppendDescriptor(HIDSubDescriptor *node) |
81 | 61 | { |
82 | | -if (modules_count == 0) { |
| 62 | +if (!rootNode) { |
83 | 63 | rootNode = node; |
84 | 64 | } else { |
85 | | -HIDDescriptorListNode *current = rootNode; |
86 | | -while(current->next != NULL) { |
| 65 | +HIDSubDescriptor *current = rootNode; |
| 66 | +while (current->next) { |
87 | 67 | current = current->next; |
88 | 68 | } |
89 | 69 | current->next = node; |
90 | 70 | } |
91 | | -modules_count++; |
92 | | -sizeof_hidReportDescriptor += node->length; |
| 71 | +descriptorSize += node->length; |
93 | 72 | } |
94 | 73 |
|
95 | 74 | void HID_::SendReport(uint8_t id, const void* data, int len) |
96 | 75 | { |
97 | 76 | uint8_t p[64]; |
98 | | -const uint8_t *d = reinterpret_cast<const uint8_t *>(data); |
99 | | - |
100 | 77 | p[0] = id; |
101 | | -for (uint32_t i=0; i<len; i++) |
102 | | -p[i+1] = d[i]; |
103 | | -USBD_Send(HID_TX, p, len+1); |
| 78 | +memcpy(&p[1], data, len); |
| 79 | +USBD_Send(pluggedEndpoint, p, len+1); |
104 | 80 | } |
105 | 81 |
|
106 | | -bool HID_Setup(USBSetup& setup, uint8_t i) |
| 82 | +bool HID_::setup(USBSetup& setup) |
107 | 83 | { |
108 | | -if (HID_INTERFACE != i) { |
| 84 | +if (pluggedInterface != setup.wIndex) { |
109 | 85 | return false; |
110 | | -} else { |
111 | | -uint8_t r = setup.bRequest; |
112 | | -uint8_t requestType = setup.bmRequestType; |
113 | | -if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) |
114 | | -{ |
115 | | -if (HID_GET_REPORT == r) |
116 | | -{ |
117 | | -//HID_GetReport(); |
118 | | -return true; |
119 | | -} |
120 | | -if (HID_GET_PROTOCOL == r) |
121 | | -{ |
122 | | -//Send8(_hid_protocol); // TODO |
123 | | -return true; |
124 | | -} |
| 86 | +} |
| 87 | + |
| 88 | +uint8_t request = setup.bRequest; |
| 89 | +uint8_t requestType = setup.bmRequestType; |
| 90 | + |
| 91 | +if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE) |
| 92 | +{ |
| 93 | +if (request == HID_GET_REPORT) { |
| 94 | +// TODO: HID_GetReport(); |
| 95 | +return true; |
| 96 | +} |
| 97 | +if (request == HID_GET_PROTOCOL) { |
| 98 | +// TODO: Send8(protocol); |
| 99 | +return true; |
| 100 | +} |
| 101 | +if (request == HID_GET_IDLE) { |
| 102 | +// TODO: Send8(idle); |
| 103 | +} |
| 104 | +} |
| 105 | + |
| 106 | +if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE) |
| 107 | +{ |
| 108 | +if (request == HID_SET_PROTOCOL) { |
| 109 | +// The USB Host tells us if we are in boot or report mode. |
| 110 | +// This only works with a real boot compatible device. |
| 111 | +protocol = setup.wValueL; |
| 112 | +return true; |
125 | 113 | } |
126 | | - |
127 | | -if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType) |
| 114 | +if (request == HID_SET_IDLE) { |
| 115 | +idle = setup.wValueL; |
| 116 | +return true; |
| 117 | +} |
| 118 | +if (request == HID_SET_REPORT) |
128 | 119 | { |
129 | | -if (HID_SET_PROTOCOL == r) |
130 | | -{ |
131 | | -_hid_protocol = setup.wValueL; |
132 | | -return true; |
133 | | -} |
134 | | - |
135 | | -if (HID_SET_IDLE == r) |
136 | | -{ |
137 | | -_hid_idle = setup.wValueL; |
138 | | -return true; |
139 | | -} |
| 120 | +//uint8_t reportID = setup.wValueL; |
| 121 | +//uint16_t length = setup.wLength; |
| 122 | +//uint8_t data[length]; |
| 123 | +// Make sure to not read more data than USB_EP_SIZE. |
| 124 | +// You can read multiple times through a loop. |
| 125 | +// The first byte (may!) contain the reportID on a multreport. |
| 126 | +//USB_RecvControl(data, length); |
140 | 127 | } |
141 | | -return false; |
142 | 128 | } |
| 129 | + |
| 130 | +return false; |
143 | 131 | } |
144 | 132 |
|
145 | | -HID_::HID_(void) |
| 133 | +HID_::HID_(void) : PluggableUSBModule(1, 1, epType), |
| 134 | + rootNode(NULL), descriptorSize(0), |
| 135 | + protocol(1), idle(1) |
146 | 136 | { |
147 | | -static uint32_t endpointType[1]; |
148 | | - |
149 | | -endpointType[0] = EP_TYPE_INTERRUPT_IN; |
150 | | - |
151 | | -static PUSBCallbacks cb = { |
152 | | -.setup = &HID_Setup, |
153 | | -.getInterface = &HID_GetInterface, |
154 | | -.getDescriptor = &HID_GetDescriptor, |
155 | | -.numEndpoints = 1, |
156 | | -.numInterfaces = 1, |
157 | | -.endpointType = endpointType, |
158 | | -}; |
159 | | - |
160 | | -static PUSBListNode node(&cb); |
161 | | - |
162 | | -HID_ENDPOINT_INT = PUSB_AddFunction(&node, &HID_INTERFACE); |
| 137 | +epType[0] = EP_TYPE_INTERRUPT_IN; |
| 138 | +PluggableUSB().plug(this); |
163 | 139 | } |
164 | 140 |
|
165 | 141 | int HID_::begin(void) |
166 | 142 | { |
167 | 143 | return 0; |
168 | 144 | } |
| 145 | + |
| 146 | +#endif /* if defined(USBCON) */ |
0 commit comments