Skip to content

Commit 6dc5404

Browse files
committed
1 parent 379df90 commit 6dc5404

File tree

2 files changed

+367
-3
lines changed

2 files changed

+367
-3
lines changed

hardware/arduino/avr/cores/arduino/HID.cpp

Lines changed: 285 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
31
/* Copyright (c) 2011, Peter Barrett
42
**
53
** Permission to use, copy, modify, and/or distribute this software for
@@ -23,10 +21,12 @@
2321

2422
//#define RAWHID_ENABLED
2523

26-
// Singletons for mouse and keyboard
24+
// Singletons for mouse, keyboard and joystick
2725

2826
Mouse_ Mouse;
2927
Keyboard_ Keyboard;
28+
Joystick_ Joystick;
29+
Remote_ Remote;
3030

3131
//================================================================================
3232
//================================================================================
@@ -124,6 +124,136 @@ const u8 _hidReportDescriptor[] = {
124124
0x91, 0x02, // Output (array)
125125
0xC0 // end collection
126126
#endif
127+
// *** Here is where the RAW_HID has been converted to a Joystick device
128+
// *** Inspired by helmpcb.com/electronics/usb-joystick
129+
// *** Check out www.usb.org/developers/hidpage/ for more than you'll ever need to know about USB HID
130+
// *** HID descriptor created using the HID descriptor tool from www.usb.org/developers/hidpage/dt2_4.zip (win32)
131+
132+
// 32 buttons (and a throttle - just in case the game doesn't recognise a joystick with no analog axis)
133+
134+
0x05, 0x01,// USAGE_PAGE (Generic Desktop)
135+
0x09, 0x04,// USAGE (Joystick)
136+
0xa1, 0x01,// COLLECTION (Application)
137+
0x85, 0x03,// REPORT_ID (3) (This is important when HID_SendReport() is called)
138+
139+
//Buttons:
140+
0x05, 0x09,// USAGE_PAGE (Button)
141+
0x19, 0x01,// USAGE_MINIMUM (Button 1)
142+
0x29, 0x20,// USAGE_MAXIMUM (Button 32)
143+
0x15, 0x00,// LOGICAL_MINIMUM (0)
144+
0x25, 0x01,// LOGICAL_MAXIMUM (1)
145+
0x75, 0x01,// REPORT_SIZE (1)
146+
0x95, 0x20,// REPORT_COUNT (32)
147+
0x55, 0x00,// UNIT_EXPONENT (0)
148+
0x65, 0x00,// UNIT (None)
149+
0x81, 0x02,// INPUT (Data,Var,Abs)
150+
151+
// 8 bit Throttle and Steering
152+
0x05, 0x02,// USAGE_PAGE (Simulation Controls)
153+
154+
0x15, 0x00,// LOGICAL_MINIMUM (0)
155+
0x26, 0xff, 0x00,// LOGICAL_MAXIMUM (255)
156+
0xA1, 0x00,// COLLECTION (Physical)
157+
0x09, 0xBB,// USAGE (Throttle)
158+
0x09, 0xBA,// USAGE (Steering)
159+
0x75, 0x08,// REPORT_SIZE (8)
160+
0x95, 0x02,// REPORT_COUNT (2)
161+
0x81, 0x02,// INPUT (Data,Var,Abs)
162+
163+
0xc0,// END_COLLECTION
164+
// Two Hat switches
165+
166+
0x05, 0x01,// USAGE_PAGE (Generic Desktop)
167+
168+
0x09, 0x39,// USAGE (Hat switch)
169+
0x15, 0x00,// LOGICAL_MINIMUM (0)
170+
0x25, 0x07,// LOGICAL_MAXIMUM (7)
171+
0x35, 0x00,// PHYSICAL_MINIMUM (0)
172+
0x46, 0x3B, 0x01,// PHYSICAL_MAXIMUM (315)
173+
0x65, 0x14,// UNIT (Eng Rot:Angular Pos)
174+
0x75, 0x04,// REPORT_SIZE (4)
175+
0x95, 0x01,// REPORT_COUNT (1)
176+
0x81, 0x02,// INPUT (Data,Var,Abs)
177+
178+
0x09, 0x39,// USAGE (Hat switch)
179+
0x15, 0x00,// LOGICAL_MINIMUM (0)
180+
0x25, 0x07,// LOGICAL_MAXIMUM (7)
181+
0x35, 0x00,// PHYSICAL_MINIMUM (0)
182+
0x46, 0x3B, 0x01,// PHYSICAL_MAXIMUM (315)
183+
0x65, 0x14,// UNIT (Eng Rot:Angular Pos)
184+
0x75, 0x04,// REPORT_SIZE (4)
185+
0x95, 0x01,// REPORT_COUNT (1)
186+
0x81, 0x02,// INPUT (Data,Var,Abs)
187+
188+
0x15, 0x00,// LOGICAL_MINIMUM (0)
189+
0x26, 0xff, 0x00,// LOGICAL_MAXIMUM (255)
190+
0x75, 0x08,// REPORT_SIZE (8)
191+
192+
0x09, 0x01,// USAGE (Pointer)
193+
0xA1, 0x00,// COLLECTION (Physical)
194+
0x09, 0x30,// USAGE (x)
195+
0x09, 0x31,// USAGE (y)
196+
0x09, 0x32,// USAGE (z)
197+
0x09, 0x33,// USAGE (rx)
198+
0x09, 0x34,// USAGE (ry)
199+
0x09, 0x35,// USAGE (rz)
200+
0x95, 0x06,// REPORT_COUNT (2)
201+
0x81, 0x02,// INPUT (Data,Var,Abs)
202+
0xc0,// END_COLLECTION
203+
204+
0xc0// END_COLLECTION
205+
206+
//-----------------------------------------------------------------------------
207+
208+
/* Cross-platform support for controls found on IR Remotes */
209+
210+
0x05, 0x0c, //Usage Page (Consumer Devices)
211+
0x09, 0x01, //Usage (Consumer Control)
212+
0xa1, 0x01, //Collection (Application)
213+
0x85, 0x04, //REPORT_ID (4)
214+
0x15, 0x00, //Logical Minimum (0)
215+
0x25, 0x01, //Logical Maximum (1)
216+
0x09, 0xe9, //Usage (Volume Up)
217+
0x09, 0xea, //Usage (Volume Down)
218+
0x75, 0x01, //Report Size (1)
219+
0x95, 0x02, //Report Count (2)
220+
0x81, 0x06, //Input (Data, Variable, Relative)
221+
222+
0x09, 0xe2, //Usage (Mute)
223+
0x95, 0x01, //Report Count (1)
224+
0x81, 0x06, //Input (Data, Variable, Relative)
225+
226+
0x09, 0xb0, //Usage (Play)
227+
0x95, 0x01, //Report Count (1)
228+
0x81, 0x06, //Input (Data, Variable, Relative)
229+
230+
0x09, 0xb1, //Usage (Pause)
231+
0x95, 0x01, //Report Count (1)
232+
0x81, 0x06, //Input (Data, Variable, Relative)
233+
234+
0x09, 0xb7, //Usage (Stop)
235+
0x95, 0x01, //Report Count (1)
236+
0x81, 0x06, //Input (Data, Variable, Relative)
237+
238+
0x09, 0xb5, //Usage (Next)
239+
0x95, 0x01, //Report Count (1)
240+
0x81, 0x06, //Input (Data, Variable, Relative)
241+
242+
0x09, 0xb6, //Usage (Previous)
243+
0x95, 0x01, //Report Count (1)
244+
0x81, 0x06, //Input (Data, Variable, Relative)
245+
246+
0x09, 0xb3, //Usage (Fast Forward)
247+
0x95, 0x01, //Report Count (1)
248+
0x81, 0x06, //Input (Data, Variable, Relative)
249+
250+
0x09, 0xb4, //Usage (Rewind)
251+
0x95, 0x01, //Report Count (1)
252+
0x81, 0x06, //Input (Data, Variable, Relative)
253+
254+
0x95, 0x06, //Report Count (6) Number of bits remaining in byte
255+
0x81, 0x07, //Input (Constant, Variable, Relative)
256+
0xc0 //End Collection
127257
};
128258

129259
extern const HIDDescriptor _hidInterface PROGMEM;
@@ -195,6 +325,54 @@ bool WEAK HID_Setup(Setup& setup)
195325
return false;
196326
}
197327

328+
//================================================================================
329+
//================================================================================
330+
//Joystick
331+
// Usage: Joystick.move(inputs go here)
332+
//
333+
// The report data format must match the one defined in the descriptor exactly
334+
// or it either won't work, or the pc will make a mess of unpacking the data
335+
//
336+
337+
Joystick_::Joystick_()
338+
{
339+
}
340+
341+
342+
#define joyBytes 13 // should be equivalent to sizeof(JoyState_t)
343+
344+
void Joystick_::setState(JoyState_t *joySt)
345+
{
346+
uint8_t data[joyBytes];
347+
uint32_t buttonTmp;
348+
buttonTmp = joySt->buttons;
349+
350+
data[0] = buttonTmp & 0xFF;// Break 32 bit button-state out into 4 bytes, to send over USB
351+
buttonTmp >>= 8;
352+
data[1] = buttonTmp & 0xFF;
353+
buttonTmp >>= 8;
354+
data[2] = buttonTmp & 0xFF;
355+
buttonTmp >>= 8;
356+
data[3] = buttonTmp & 0xFF;
357+
358+
data[4] = joySt->throttle;// Throttle
359+
data[5] = joySt->rudder;// Steering
360+
361+
data[6] = (joySt->hatSw2 << 4) | joySt->hatSw1;// Pack hat-switch states into a single byte
362+
363+
data[7] = joySt->xAxis;// X axis
364+
data[8] = joySt->yAxis;// Y axis
365+
data[9] = joySt->zAxis;// Z axis
366+
data[10] = joySt->xRotAxis;// rX axis
367+
data[11] = joySt->yRotAxis;// rY axis
368+
data[12] = joySt->zRotAxis;// rZ axis
369+
370+
//HID_SendReport(Report number, array of values in same order as HID descriptor, length)
371+
HID_SendReport(3, data, joyBytes);
372+
// The joystick is specified as using report 3 in the descriptor. That's where the "3" comes from
373+
}
374+
375+
198376
//================================================================================
199377
//================================================================================
200378
// Mouse
@@ -513,6 +691,110 @@ size_t Keyboard_::write(uint8_t c)
513691
return p; // just return the result of press() since release() almost always returns 1
514692
}
515693

694+
//================================================================================
695+
//================================================================================
696+
//Remote
697+
698+
Remote_::Remote_(void)
699+
{
700+
}
701+
702+
void Remote_::begin(void)
703+
{
704+
}
705+
706+
void Remote_::end(void)
707+
{
708+
}
709+
710+
void Remote_::increase(void)
711+
{
712+
u8 m[2];
713+
m[0] = VOLUME_UP;
714+
m[1] = 0;
715+
HID_SendReport(4,m,2);
716+
}
717+
718+
void Remote_::decrease(void)
719+
{
720+
u8 m[2];
721+
m[0] = VOLUME_DOWN;
722+
m[1] = 0;
723+
HID_SendReport(4,m,2);
724+
}
725+
726+
void Remote_::mute(void)
727+
{
728+
u8 m[2];
729+
m[0] = VOLUME_MUTE;
730+
m[1] = 0;
731+
HID_SendReport(4,m,2);
732+
}
733+
734+
void Remote_::play(void)
735+
{
736+
u8 m[2];
737+
m[0] = REMOTE_PLAY;
738+
m[1] = 0;
739+
HID_SendReport(4,m,2);
740+
}
741+
742+
void Remote_::pause(void)
743+
{
744+
u8 m[2];
745+
m[0] = REMOTE_PAUSE;
746+
m[1] = 0;
747+
HID_SendReport(4,m,2);
748+
}
749+
750+
void Remote_::stop(void)
751+
{
752+
u8 m[2];
753+
m[0] = REMOTE_STOP;
754+
m[1] = 0;
755+
HID_SendReport(4,m,2);
756+
}
757+
758+
void Remote_::next(void)
759+
{
760+
u8 m[2];
761+
m[0] = REMOTE_NEXT;
762+
m[1] = 0;
763+
HID_SendReport(4,m,2);
764+
}
765+
766+
void Remote_::previous(void)
767+
{
768+
u8 m[2];
769+
m[0] = REMOTE_PREVIOUS;
770+
m[1] = 0;
771+
HID_SendReport(4,m,2);
772+
}
773+
774+
void Remote_::forward(void)
775+
{
776+
u8 m[2];
777+
m[0] = 0;
778+
m[1] = REMOTE_FAST_FORWARD >> 8;
779+
HID_SendReport(4,m,2);
780+
}
781+
782+
void Remote_::rewind(void)
783+
{
784+
u8 m[2];
785+
m[0] = 0;
786+
m[1] = REMOTE_REWIND >> 8;
787+
HID_SendReport(4,m,2);
788+
}
789+
790+
void Remote_::clear(void)
791+
{
792+
u8 m[2];
793+
m[0] = 0;
794+
m[1] = 0;
795+
HID_SendReport(4,m,2);
796+
}
797+
516798
#endif
517799

518800
#endif /* if defined(USBCON) */

0 commit comments

Comments
 (0)