summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2014-04-05 19:29:18 +0200
committerFlorian Jung <flo@windfisch.org>2014-04-05 19:29:18 +0200
commitfc0bea2bd940e5fecea3b52e9fe31cec1b412ced (patch)
treef84416713bee57fcb407554fe1ff69c37b8d5028
parent61369296fb7907360f9113555cd05f3f572119bf (diff)
be a USB gamepad :)
-rw-r--r--main.c107
-rw-r--r--usbdrv/usbconfig.h2
2 files changed, 55 insertions, 54 deletions
diff --git a/main.c b/main.c
index db2654d..4afe361 100644
--- a/main.c
+++ b/main.c
@@ -51,48 +51,44 @@
static char buffer[300]; // contains the exploded gamecube bits, i.e. each bit sent/received occupies one byte here.
-PROGMEM const char usbHidReportDescriptor[52] = { /* USB report descriptor, size must match usbconfig.h */
+PROGMEM const char usbHidReportDescriptor[50] = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x02, // USAGE (Mouse)
- 0xa1, 0x01, // COLLECTION (Application)
- 0x09, 0x01, // USAGE (Pointer)
+ 0x09, 0x05, // USAGE (Game Pad)
+ 0xA1, 0x01, // COLLECTION (Application)
0xA1, 0x00, // COLLECTION (Physical)
0x05, 0x09, // USAGE_PAGE (Button)
- 0x19, 0x01, // USAGE_MINIMUM
- 0x29, 0x03, // USAGE_MAXIMUM
+ 0x19, 0x01, // USAGE_MINIMUM (Button 1)
+ 0x29, 0x10, // USAGE_MAXIMUM (Button 16)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
- 0x95, 0x03, // REPORT_COUNT (3)
+ 0x95, 0x10, // REPORT_COUNT (16)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
- 0x95, 0x01, // REPORT_COUNT (1)
- 0x75, 0x05, // REPORT_SIZE (5)
- 0x81, 0x03, // INPUT (Const,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
- 0x09, 0x38, // USAGE (Wheel)
+ 0x09, 0x32, // USAGE (Z)
+ 0x09, 0x33, // USAGE (Rx)
+ 0x09, 0x34, // USAGE (Ry)
+ 0x09, 0x35, // USAGE (Rz)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7F, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
- 0x95, 0x03, // REPORT_COUNT (3)
- 0x81, 0x06, // INPUT (Data,Var,Rel)
+ 0x95, 0x06, // REPORT_COUNT (6)
+ 0x81, 0x02, // INPUT (Data,Var,Abs)
0xC0, // END_COLLECTION
- 0xC0, // END COLLECTION
+ 0xC0 // END_COLLECTION
};
-/* This is the same report descriptor as seen in a Logitech mouse. The data
- * described by this descriptor consists of 4 bytes:
- * . . . . . B2 B1 B0 .... one byte with mouse button states
- * X7 X6 X5 X4 X3 X2 X1 X0 .... 8 bit signed relative coordinate x
- * Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 .... 8 bit signed relative coordinate y
- * W7 W6 W5 W4 W3 W2 W1 W0 .... 8 bit signed relative coordinate wheel
- */
-typedef struct{
- uchar buttonMask;
- char dx;
- char dy;
- char dWheel;
+typedef struct {
+ uchar btn1;
+ uchar btn2;
+ char x;
+ char y;
+ char cx;
+ char cy;
+ uchar ltrig;
+ uchar rtrig;
} report_t;
@@ -286,6 +282,19 @@ int send_recv_gc(char* bytes, int len)
// a value of >=128 means "0", <127 means "1" bit.
}
+/* reads eight exploded bits from bufptr, and makes a 8bit-char from them.
+ * Bit ordering is MSB first. A bit is considered as 1, if bufptr[i] & 0x80 is
+ * *not* set, and vice versa. */
+char decode_byte(char* bufptr)
+{
+ char result=0;
+ for (int i=0;i<8;i++)
+ result|= ( (bufptr[7-i]&0x80)?0:(1<<i) );
+
+ return result;
+}
+
+
int main (void)
{
char rand=123;
@@ -336,14 +345,10 @@ debug(4);
wdt_reset();
usbPoll();
- if(usbInterruptIsReady()) { // if the interrupt is ready, feed data
- // pseudo-random sequence generator, thanks to Dan Frederiksen @AVRfreaks
- // http://en.wikipedia.org/wiki/Linear_congruential_generator
- rand=(rand*109+89)%251;
-
- // move to a random direction
- reportBuffer.dx = gc_x;
- reportBuffer.dy = -gc_y;
+ if(usbInterruptIsReady())
+ {
+ reportBuffer.x = gc_x;
+ reportBuffer.y = -gc_y;
usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer));
@@ -388,29 +393,25 @@ debug(4);
n_received=send_recv_gc(foo, 3);
if (n_received == 64)
{
+
+ gc_y=decode_byte(buffer+24);
+ gc_x=decode_byte(buffer+16);
+
+ reportBuffer.cx=decode_byte(buffer+32);
+ reportBuffer.cy=decode_byte(buffer+40);
- gc_y=0;
- for (int i=0;i<8;i++)
- gc_y|= ( (buffer[23+8-i]&0x80)?0:(1<<i) );
-
- gc_x=0;
- for (int i=0;i<8;i++)
- gc_x|= ( (buffer[23-i]&0x80)?0:(1<<i) );
-
- //gc_x^=0x80;
- //gc_y^=0x80;
-
- gc_x = ((signed char)(((unsigned char) gc_x) - 128)) /8;
- gc_y = ((signed char)(((unsigned char) gc_y) - 128)) /8;
+ reportBuffer.ltrig=decode_byte(buffer+48);
+ reportBuffer.rtrig=decode_byte(buffer+56);
- char tmp=0;
- for (int i=1;i<8;i++)
- tmp|= ( (buffer[i]&0x80)?0:(1<<i) );
+ reportBuffer.btn1=decode_byte(buffer+0);
+ reportBuffer.btn2=decode_byte(buffer+8);
-// if ( (temp & 0xFF) > tmp2 )
-// tmp|=1;
+ ltrig=decode_byte(buffer+48);
+ rtrig=decode_byte(buffer+56);
+
+ gc_x = ((signed char)(((unsigned char) gc_x) - 128));
+ gc_y = ((signed char)(((unsigned char) gc_y) - 128));
- //PORTB=~gc_x;
}
else
{
diff --git a/usbdrv/usbconfig.h b/usbdrv/usbconfig.h
index 7bb2a17..a5a0c0a 100644
--- a/usbdrv/usbconfig.h
+++ b/usbdrv/usbconfig.h
@@ -279,7 +279,7 @@ section at the end of this file).
* HID class is 3, no subclass and protocol required (but may be useful!)
* CDC class is 2, use subclass 2 and protocol 1 for ACM
*/
-#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 52
+#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 50
/* Define this to the length of the HID report descriptor, if you implement
* an HID device. Otherwise don't define it or define it to 0.
* If you use this define, you must add a PROGMEM character array named