Skip to content

Commit e16b21c

Browse files
committed
Support for Windows and Linux
1 parent 340a112 commit e16b21c

File tree

4 files changed

+198
-100
lines changed

4 files changed

+198
-100
lines changed

src/HID/HID.cpp

Lines changed: 86 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,47 @@ int HID_::getInterface(uint8_t* interfaceCount)
3737
};
3838
return USB_SendControl(0, &hidInterface, sizeof(hidInterface));
3939
}
40+
// Send a USB descriptor string. The string is stored in PROGMEM as a
41+
// plain ASCII string but is sent out as UTF-16 with the correct 2-byte
42+
// prefix
43+
static bool USB_SendStringDescriptor(const char* string_P, u8 string_len, uint8_t flags) {
44+
45+
u8 c[2] = {(u8)(2 + string_len * 2), 3};
46+
47+
USB_SendControl(0,&c,2);
48+
49+
bool pgm = flags & TRANSFER_PGM;
50+
for(u8 i = 0; i < string_len; i++) {
51+
c[0] = pgm ? pgm_read_byte(&string_P[i]) : string_P[i];
52+
c[1] = 0;
53+
int r = USB_SendControl(0,&c,2);
54+
if(!r) {
55+
return false;
56+
}
57+
}
58+
return true;
59+
}
4060

4161
int HID_::getDescriptor(USBSetup& setup)
4262
{
63+
64+
u8 t = setup.wValueH;
65+
66+
if(USB_STRING_DESCRIPTOR_TYPE == t) {
67+
68+
// we place all strings in the 0xFF00-0xFFFE range
69+
HIDReport* rep = GetFeature(0xFF00 | setup.wValueL );
70+
if(rep) {
71+
return USB_SendStringDescriptor((char*)rep->data, strlen_P((char*)rep->data), TRANSFER_PGM);
72+
}
73+
else {
74+
return 0;
75+
}
76+
}
77+
4378
// Check if this is a HID Class Descriptor request
4479
if (setup.bmRequestType != REQUEST_DEVICETOHOST_STANDARD_INTERFACE) { return 0; }
45-
if (setup.wValueH != HID_REPORT_DESCRIPTOR_TYPE) { return 0; }
80+
if (HID_REPORT_DESCRIPTOR_TYPE != t) { return 0; }
4681

4782
// In a HID Class Descriptor wIndex cointains the interface number
4883
if (setup.wIndex != pluggedInterface) { return 0; }
@@ -65,12 +100,23 @@ int HID_::getDescriptor(USBSetup& setup)
65100

66101
uint8_t HID_::getShortName(char *name)
67102
{
103+
if(serial) {
104+
for(byte i=0; i<strlen_P(serial); i++) {
105+
name[i] = pgm_read_byte_near(serial + i);
106+
}
107+
return strlen_P(serial);
108+
}
109+
else {
110+
111+
// default serial number
112+
68113
name[0] = 'H';
69114
name[1] = 'I';
70115
name[2] = 'D';
71116
name[3] = 'A' + (descriptorSize & 0x0F);
72117
name[4] = 'A' + ((descriptorSize >> 4) & 0x0F);
73118
return 5;
119+
}
74120
}
75121

76122
void HID_::AppendDescriptor(HIDSubDescriptor *node)
@@ -87,7 +133,7 @@ void HID_::AppendDescriptor(HIDSubDescriptor *node)
87133
descriptorSize += node->length;
88134
}
89135

90-
int HID_::SetFeature(uint8_t id, const void* data, int len)
136+
int HID_::SetFeature(uint16_t id, const void* data, int len)
91137
{
92138
if(!rootReport) {
93139
rootReport = new HIDReport(id, data, len);
@@ -111,7 +157,7 @@ int HID_::SetFeature(uint8_t id, const void* data, int len)
111157
return reportCount;
112158
}
113159

114-
bool HID_::LockFeature(uint8_t id, bool lock) {
160+
bool HID_::LockFeature(uint16_t id, bool lock) {
115161
if(rootReport) {
116162
HIDReport* current;
117163
for(current = rootReport;current; current=current->next) {
@@ -125,7 +171,7 @@ bool HID_::LockFeature(uint8_t id, bool lock) {
125171
}
126172

127173

128-
int HID_::SendReport(uint8_t id, const void* data, int len)
174+
int HID_::SendReport(uint16_t id, const void* data, int len)
129175
{
130176
auto ret = USB_Send(HID_TX, &id, 1);
131177
if (ret < 0) return ret;
@@ -134,6 +180,18 @@ int HID_::SendReport(uint8_t id, const void* data, int len)
134180
return ret + ret2;
135181
}
136182

183+
HIDReport* HID_::GetFeature(uint16_t id)
184+
{
185+
HIDReport* current;
186+
int i=0;
187+
for(current=rootReport; current && i<reportCount; current=current->next, i++) {
188+
if(id == current->id) {
189+
return current;
190+
}
191+
}
192+
return (HIDReport*) NULL;
193+
}
194+
137195
bool HID_::setup(USBSetup& setup)
138196
{
139197
if (pluggedInterface != setup.wIndex) {
@@ -149,25 +207,16 @@ bool HID_::setup(USBSetup& setup)
149207

150208
if(setup.wValueH == HID_REPORT_TYPE_FEATURE)
151209
{
152-
// dbg->print(setup.wValueL);
153-
HIDReport* current;
154-
int i=0;
155-
for(current=rootReport; current && i<reportCount; current=current->next, i++) {
156-
// dbg->print(":");
157-
// dbg->print(current->id);
158-
// dbg->print(" ");
159-
// dbg->print(current->length);
160-
// dbg->print(" ");
161-
if(setup.wValueL == current->id) {
162-
if(USB_SendControl(0, &(current->id), 1)<0 ||
163-
USB_SendControl(0, current->data, current->length)<0)
164-
return false;
165-
166-
break;
167-
}
168-
// dbg->println("");
210+
211+
HIDReport* current = GetFeature(setup.wValueL);
212+
if(current){
213+
if(USB_SendControl(0, &(current->id), 1)>0 &&
214+
USB_SendControl(0, current->data, current->length)>0)
215+
return true;
169216
}
170217

218+
return false;
219+
171220
}
172221
return true;
173222
}
@@ -193,14 +242,22 @@ bool HID_::setup(USBSetup& setup)
193242
return true;
194243
}
195244
if (request == HID_SET_REPORT)
196-
{
197-
//uint8_t reportID = setup.wValueL;
198-
//uint16_t length = setup.wLength;
199-
//uint8_t data[length];
200-
// Make sure to not read more data than USB_EP_SIZE.
201-
// You can read multiple times through a loop.
202-
// The first byte (may!) contain the reportID on a multreport.
203-
//USB_RecvControl(data, length);
245+
{
246+
if(setup.wValueH == HID_REPORT_TYPE_FEATURE)
247+
{
248+
249+
HIDReport* current = GetFeature(setup.wValueL);
250+
if(!current) return false;
251+
if(setup.wLength != current->length + 1) return false;
252+
uint8_t* data = new uint8_t[setup.wLength];
253+
USB_RecvControl(data, setup.wLength);
254+
if(*data != current->id) return false;
255+
memcpy((uint8_t*)current->data, data+1, current->length);
256+
delete[] data;
257+
return true;
258+
259+
}
260+
204261
}
205262
}
206263

src/HID/HID.h

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@ typedef struct
9292
class HIDReport {
9393
public:
9494
HIDReport *next = NULL;
95-
HIDReport(uint8_t i, const void *d, uint8_t l) : id(i), data(d), length(l) {}
95+
HIDReport(uint16_t i, const void *d, uint8_t l) : id(i), data(d), length(l) {}
9696

97-
uint8_t id;
97+
uint16_t id;
9898
const void* data;
9999
uint16_t length;
100100
bool lock;
@@ -114,16 +114,22 @@ class HID_ : public PluggableUSBModule
114114
public:
115115
HID_(void);
116116
int begin(void);
117-
int SendReport(uint8_t id, const void* data, int len);
118-
int SetFeature(uint8_t id, const void* data, int len);
119-
bool LockFeature(uint8_t id, bool lock);
117+
int SendReport(uint16_t id, const void* data, int len);
118+
int SetFeature(uint16_t id, const void* data, int len);
119+
bool LockFeature(uint16_t id, bool lock);
120120

121121
void AppendDescriptor(HIDSubDescriptor* node);
122122

123-
void setSerial(Serial_& serial) {
124-
dbg = &serial;
123+
void setOutput(Serial_& out) {
124+
dbg = &out;
125125
}
126126

127+
void setSerial(const char* s) {
128+
serial = s;
129+
}
130+
131+
HIDReport* GetFeature(uint16_t id);
132+
127133
protected:
128134
// Implementation of the PluggableUSBModule
129135
int getInterface(uint8_t* interfaceCount);
@@ -146,6 +152,8 @@ class HID_ : public PluggableUSBModule
146152

147153
Serial_ *dbg;
148154

155+
const char *serial;
156+
149157
};
150158

151159
// Replacement for global singleton.

0 commit comments

Comments
 (0)