diff options
author | Florian Jung <flo@windfisch.org> | 2014-04-05 19:29:18 +0200 |
---|---|---|
committer | Florian Jung <flo@windfisch.org> | 2014-04-05 19:29:18 +0200 |
commit | fc0bea2bd940e5fecea3b52e9fe31cec1b412ced (patch) | |
tree | f84416713bee57fcb407554fe1ff69c37b8d5028 | |
parent | 61369296fb7907360f9113555cd05f3f572119bf (diff) |
be a USB gamepad :)
-rw-r--r-- | main.c | 107 | ||||
-rw-r--r-- | usbdrv/usbconfig.h | 2 |
2 files changed, 55 insertions, 54 deletions
@@ -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 |