Skip to content

Commit ddae105

Browse files
committed
[HID] port to stable PluggableUSB API
1 parent b454120 commit ddae105

File tree

2 files changed

+164
-157
lines changed

2 files changed

+164
-157
lines changed

hardware/arduino/sam/libraries/HID/HID.cpp

+87-109
Original file line numberDiff line numberDiff line change
@@ -13,156 +13,134 @@
1313
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
1414
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
1515
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
16-
** SOFTWARE.
16+
** SOFTWARE.
1717
*/
1818

19-
#include "USB/PluggableUSB.h"
2019
#include "HID.h"
2120

22-
HID_ HID;
21+
#if defined(USBCON)
2322

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_PAGE 0xFFC0
35-
#define RAWHID_USAGE 0x0C00
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+
}
5228

53-
int HID_GetInterface(uint8_t* interfaceNum)
29+
int HID_::getInterface(uint8_t* interfaceCount)
5430
{
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)
6136
};
62-
return USBD_SendControl(0,&_hidInterface,sizeof(_hidInterface));
37+
return USBD_SendControl(0, &hidInterface, sizeof(hidInterface));
6338
}
6439

65-
int HID_GetDescriptor(int8_t t)
40+
int HID_::getDescriptor(USBSetup& setup)
6641
{
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;
7756
}
57+
return total;
7858
}
7959

80-
void HID_::AppendDescriptor(HIDDescriptorListNode *node)
60+
void HID_::AppendDescriptor(HIDSubDescriptor *node)
8161
{
82-
if (modules_count == 0) {
62+
if (!rootNode) {
8363
rootNode = node;
8464
} else {
85-
HIDDescriptorListNode *current = rootNode;
86-
while(current->next != NULL) {
65+
HIDSubDescriptor *current = rootNode;
66+
while (current->next) {
8767
current = current->next;
8868
}
8969
current->next = node;
9070
}
91-
modules_count++;
92-
sizeof_hidReportDescriptor += node->length;
71+
descriptorSize += node->length;
9372
}
9473

9574
void HID_::SendReport(uint8_t id, const void* data, int len)
9675
{
9776
uint8_t p[64];
98-
const uint8_t *d = reinterpret_cast<const uint8_t *>(data);
99-
10077
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);
10480
}
10581

106-
bool HID_Setup(USBSetup& setup, uint8_t i)
82+
bool HID_::setup(USBSetup& setup)
10783
{
108-
if (HID_INTERFACE != i) {
84+
if (pluggedInterface != setup.wIndex) {
10985
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;
125113
}
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)
128119
{
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);
140127
}
141-
return false;
142128
}
129+
130+
return false;
143131
}
144132

145-
HID_::HID_(void)
133+
HID_::HID_(void) : PluggableUSBModule(1, 1, epType),
134+
rootNode(NULL), descriptorSize(0),
135+
protocol(1), idle(1)
146136
{
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);
163139
}
164140

165141
int HID_::begin(void)
166142
{
167143
return 0;
168144
}
145+
146+
#endif /* if defined(USBCON) */

0 commit comments

Comments
 (0)