A fully-Android-compatible two joysticks USB driver for LPC1768. The joysticks have 1 hat, 6 buttons, and there are 1P, 2P buttons.

Dependencies:   mbed

Fork of app-board-Joystick by Chris Styles

Revision:
2:84ea6e2fb4b6
Parent:
1:76c47d2ba442
Child:
3:f1a8ec4659f8
--- a/usbhid.cpp	Fri Dec 16 18:17:42 2016 +0000
+++ b/usbhid.cpp	Sat Dec 17 13:13:59 2016 +0000
@@ -4,9 +4,11 @@
 
 /* Modified by yours truly */
 
+#include "config.h"
 #include "mbed.h"
 #include "usbhid.h"
 
+#ifdef CONFIG_TWO_REPORTS
 /* Report for 2 arcade joysticks */
 static uint8_t report_descriptor_joystick[] =
 {
@@ -89,6 +91,57 @@
 
 0xc0, // END_COLLECTION -- application
 };
+#endif
+
+#ifdef CONFIG_2ND_PAD_AS_BUTTONS
+static uint8_t report_descriptor_joystick[] =
+{
+0x05, 0x01, // USAGE_PAGE (Generic Desktop)
+0x09, 0x05, // USAGE (Gamepad)
+0xa1, 0x01, // COLLECTION (Application)
+
+0xa1, 0x00, // COLLECTION (Physical)
+0x15, 0x00, //   LOGICAL_MINIMUM (0)
+0x25, 0x01, //   LOGICAL_MAXIMUM (1)
+0x35, 0x00, //   PHYSICAL_MINIMUM (0)
+0x45, 0x01, //   PHYSICAL_MAXIMUM (1)
+0x75, 0x01, //   REPORT_SIZE (1)
+0x95, 0x12, //   REPORT_COUNT (18)
+0x05, 0x09, //   USAGE_PAGE (Button)
+0x19, 0x01, //   USAGE_MINIMUM (Button 1)
+0x29, 0x12, //   USAGE_MAXIMUM (Button 18)
+0x81, 0x02, //   INPUT (Data,Var,Abs)
+// does not work, why????????
+0x95, 0x06, //   REPORT_COUNT (6)
+0x81, 0x01, //   INPUT (Cnst,Ary,Abs)
+0x05, 0x01, //   USAGE_PAGE (Generic Desktop)
+0x25, 0x07, //   LOGICAL_MAXIMUM (7)
+0x46, 0x3b, 0x01, //   PHYSICAL_MAXIMUM (315)
+0x75, 0x04, //   REPORT_SIZE (4)
+0x95, 0x01, //   REPORT_COUNT (1)
+0x65, 0x14, //   UNIT (Eng Rot:Angular Pos)
+0x09, 0x39, //   USAGE (Hat switch)
+0x81, 0x42, //   INPUT (Data,Var,Abs,Null)
+0x65, 0x00, //   UNIT (None)
+0x95, 0x01, //   REPORT_COUNT (1)
+0x81, 0x01, //   INPUT (Cnst,Ary,Abs)
+0x26, 0xff, 0x00, //   LOGICAL_MAXIMUM (255)
+0x46, 0xff, 0x00, //   PHYSICAL_MAXIMUM (255)
+
+/* For some reason, this is necessary (though we never put it in the report). */
+0x09, 0x30, //   USAGE (X)
+0x09, 0x31, //   USAGE (Y)
+0x75, 0x04, //   REPORT_SIZE (4)
+0x95, 0x02, //   REPORT_COUNT (2)
+0x81, 0x02, //   INPUT (Data,Var,Abs)
+
+0xc0, // END_COLLECTION -- physical
+
+0xc0, // END_COLLECTION -- application
+};
+
+#endif
+
 
 /* Endpoint packet sizes */
 #define MAX_PACKET_SIZE_EP1 64
@@ -266,7 +319,34 @@
     }
 }
 
-bool USBJoystick::update(unsigned char gamepad_id, unsigned char stick, unsigned char buttons)
+/*#define JOYSTICK_UP    (1<<0)
+#define JOYSTICK_DOWN  (1<<1)
+#define JOYSTICK_LEFT  (1<<2)
+#define JOYSTICK_RIGHT (1<<3)
+
+const uint8_t hat_map[8] =
+{
+    0xf, // 0: neutral 
+    0,   // 1: up
+    4,   // 2: down
+    0xf, // 3: n/a (up + down)
+    6,   // 4: left
+    7,   // 5: left + up
+    4,   // 6: left + down
+    6,   // 7: left (+ up + down)
+    2,   // 8: right
+    1,   // 9: right + up
+    3,   //10: right + down
+    2,   //11: right (+ up + down)
+    0xf, //12: n/a (left + right)
+    0,   //13: up (+ left + right)
+    4,   //14: down (+ left + right)
+    0    //15: n/a
+};
+*/
+
+
+bool USBJoystick::update(uint8_t gamepad_id, uint8_t stick, uint32_t buttons)
 {
     unsigned char hatswitch;
     if (stick & JOYSTICK_UP)
@@ -294,10 +374,20 @@
         hatswitch = 0xf;
 
     /* Prepare report */
+#ifdef CONFIG_TWO_REPORTS
     unsigned char report[3];
     report[0] = gamepad_id;
     report[1] = buttons;
     report[2] = hatswitch;
+#endif    
+    
+#ifdef CONFIG_2ND_PAD_AS_BUTTONS
+    unsigned char report[4];
+    report[0] = buttons & 0xff;
+    report[1] = (buttons >> 8) & 0xff;
+    report[2] = (buttons >> 16) & 0x03;
+    report[3] = hatswitch;
+#endif
 
     /* Block if not configured */
     while(!configured) ;
@@ -305,7 +395,13 @@
     /* Send report */
     complete = false;
     disableEvents();
+#ifdef CONFIG_TWO_REPORTS
     endpointWrite(EP1IN, report, 3);
+#endif
+#ifdef CONFIG_2ND_PAD_AS_BUTTONS
+    endpointWrite(EP1IN, report, 4);
+#endif
+
     enableEvents();
 
     /* Wait for completion */