#define F_CPU 12000000L #include #include #include #include #include "usbdrv/usbdrv.h" 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. */ void debug(int i) { if (i >= 63) i=63; PORTB = ~i; } USB_PUBLIC uchar usbFunctionSetup(uchar data[8]) { usbRequest_t* rq = (usbRequest_t*) data; 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; } int main (void) { char rand=123; DDRC=0x00; PORTC=0x00; DDRB=0xFF; wdt_enable(WDTO_1S); usbInit(); usbDeviceDisconnect(); for (int i=0;i<100;i++) { PORTB=~i; wdt_reset(); _delay_ms(5); } usbDeviceConnect(); 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 }