diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 119 |
1 files changed, 72 insertions, 47 deletions
@@ -6,11 +6,56 @@ #include <avr/interrupt.h> #include "usbdrv/usbdrv.h" -static uchar replyBuf[18]= "Hello, World!"; +PROGMEM const char usbHidReportDescriptor[52] = { /* USB report descriptor, size must match usbconfig.h */ + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x02, // USAGE (Mouse) + 0xa1, 0x01, // COLLECTION (Application) + 0x09, 0x01, // USAGE (Pointer) + 0xA1, 0x00, // COLLECTION (Physical) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM + 0x29, 0x03, // USAGE_MAXIMUM + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x95, 0x03, // REPORT_COUNT (3) + 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) + 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) + 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; +} report_t; + + +report_t reportBuffer; + /* device is detected, however unreliably. dunno why. */ -static uchar dataReceived, dataLength; void debug(int i) { @@ -22,47 +67,23 @@ USB_PUBLIC uchar usbFunctionSetup(uchar data[8]) { usbRequest_t* rq = (usbRequest_t*) data; - switch(rq->bRequest) - { - case 0: PORTB |= 1; break; - case 1: PORTB &= ~1; break; - - case 2: usbMsgPtr = replyBuf; return sizeof(replyBuf); // pc reads - case 3: // alter byte - PORTB = ~(rq->wIndex.word & 0xFF); - if ((rq->wIndex.word >= 0) && (rq->wIndex.word < sizeof(replyBuf))) - { - replyBuf[rq->wIndex.word] = rq->wValue.word; - } - break; - case 4: // pc writes - dataLength = rq->wLength.word; - debug(dataLength); - dataReceived = 0; - - return USB_NO_MSG; - - } + if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS && + (rq->bRequest == USBRQ_HID_GET_REPORT)) + { + debug(32); + // wValue: ReportType (highbyte), ReportID (lowbyte) + usbMsgPtr = (void *)&reportBuffer; // we only have this one + return sizeof(reportBuffer); + } return 0; } -USB_PUBLIC uchar usbFunctionWrite(uchar* data, uchar len) -{ - PORTB&=~32; - for (uchar i = 0; dataReceived < dataLength && i < len; i++, dataReceived++) - { - if (0 <= dataReceived && dataReceived < sizeof(replyBuf)) - replyBuf[dataReceived] = data[i]; - } - - return (dataReceived >= dataLength); -} - - int main (void) { + char rand=123; + DDRC=0x00; PORTC=0x00; @@ -70,16 +91,6 @@ int main (void) wdt_enable(WDTO_1S); -/* - for (int i=0;i<20;i++) - { - PORTB|=1; - _delay_ms(50); - PORTB&=~1; - _delay_ms(50); - wdt_reset(); - } */ - usbInit(); usbDeviceDisconnect(); @@ -94,11 +105,25 @@ int main (void) PORTB=~42; sei(); - +debug(4); while(1) { 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 = (rand&0xf)-8; + reportBuffer.dy = ((rand&0xf0)>>4)-8; + + usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer)); + + debug(2); + } } return 0; // never reached |