summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c119
1 files changed, 72 insertions, 47 deletions
diff --git a/main.c b/main.c
index a3d1b28..9f287a5 100644
--- a/main.c
+++ b/main.c
@@ -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