/* Name: main.c * Project: hid-mouse, a very simple HID example * Author: Christian Starkjohann * Creation Date: 2008-04-07 * Tabsize: 4 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) * This Revision: $Id: main.c 692 2008-11-07 15:07:40Z cs $ */ /* This example should run on most AVRs with only little changes. No special hardware resources except INT0 are used. You may have to change usbconfig.h for different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or at least be connected to INT0 as well. We use VID/PID 0x046D/0xC00E which is taken from a Logitech mouse. Don't publish any hardware using these IDs! This is for demonstration only! */ #include #include #include /* for sei() */ #include /* for _delay_ms() */ #include /* required by usbdrv.h */ #include "usbdrv.h" #include "oddebug.h" /* This is also an example for using debug macros */ /* Keyboard usage values, see usb.org's HID-usage-tables document, chapter * 10 Keyboard/Keypad Page for more codes. */ #define MOD_CONTROL_LEFT (1<<0) #define MOD_SHIFT_LEFT (1<<1) #define MOD_ALT_LEFT (1<<2) #define MOD_GUI_LEFT (1<<3) #define MOD_CONTROL_RIGHT (1<<4) #define MOD_SHIFT_RIGHT (1<<5) #define MOD_ALT_RIGHT (1<<6) #define MOD_GUI_RIGHT (1<<7) #define KEY_A 4 #define KEY_B 5 #define KEY_C 6 #define KEY_D 7 #define KEY_E 8 #define KEY_F 9 #define KEY_G 10 #define KEY_H 11 #define KEY_I 12 #define KEY_J 13 #define KEY_K 14 #define KEY_L 15 #define KEY_M 16 #define KEY_N 17 #define KEY_O 18 #define KEY_P 19 #define KEY_Q 20 #define KEY_R 21 #define KEY_S 22 #define KEY_T 23 #define KEY_U 24 #define KEY_V 25 #define KEY_W 26 #define KEY_X 27 #define KEY_Y 28 #define KEY_Z 29 #define KEY_1 30 #define KEY_2 31 #define KEY_3 32 #define KEY_4 33 #define KEY_5 34 #define KEY_6 35 #define KEY_7 36 #define KEY_8 37 #define KEY_9 38 #define KEY_0 39 #define KEY_F1 58 #define KEY_F2 59 #define KEY_F3 60 #define KEY_F4 61 #define KEY_F5 62 #define KEY_F6 63 #define KEY_F7 64 #define KEY_F8 65 #define KEY_F9 66 #define KEY_F10 67 #define KEY_F11 68 #define KEY_F12 69 #define KEY_RETURN 40 #define KEY_UP 82 #define KEY_DOWN 81 #define KEY_LEFT 80 #define KEY_RIGHT 79 /* ------------------------------------------------------------------------- */ /* ----------------------------- USB interface ----------------------------- */ /* ------------------------------------------------------------------------- */ PROGMEM char usbHidReportDescriptor[63] = { 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x06, // USAGE (Keyboard) 0xa1, 0x01, // COLLECTION (Application) 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x08, // REPORT_COUNT (8) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x08, // REPORT_SIZE (8) 0x81, 0x03, // INPUT (Cnst,Var,Abs) 0x95, 0x05, // REPORT_COUNT (5) 0x75, 0x01, // REPORT_SIZE (1) 0x05, 0x08, // USAGE_PAGE (LEDs) 0x19, 0x01, // USAGE_MINIMUM (Num Lock) 0x29, 0x05, // USAGE_MAXIMUM (Kana) 0x91, 0x02, // OUTPUT (Data,Var,Abs) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x03, // REPORT_SIZE (3) 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) 0x95, 0x06, // REPORT_COUNT (6) 0x75, 0x08, // REPORT_SIZE (8) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x65, // LOGICAL_MAXIMUM (101) 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) 0x81, 0x00, // INPUT (Data,Ary,Abs) 0xc0 // END_COLLECTION }; typedef struct{ uchar buttonMask; uchar reserved; uchar buttons[6]; }report_t; static report_t reportBuffer; static uchar idleRate; /* repeat rate for keyboards, never used for mice */ /* The following function advances sin/cos by a fixed angle * and stores the difference to the previous coordinates in the report * descriptor. * The algorithm is the simulation of a second order differential equation. */ static void sendButton(void) { int result=0; reportBuffer.buttonMask=0; reportBuffer.reserved=0; uchar freeKey=2; reportBuffer.buttons[0]=0; reportBuffer.buttons[1]=0; reportBuffer.buttons[2]=0; reportBuffer.buttons[3]=0; reportBuffer.buttons[4]=0; reportBuffer.buttons[5]=0; // ADMUX=_BV(REFS0)|_BV(ADLAR)|_BV(MUX2)|_BV(MUX1)|_BV(MUX0); // ADCSRA|=(1<160) // reportBuffer.buttons[0]=KEY_A; // else if (result<120) // reportBuffer.buttons[0]=KEY_D; // result=0; // ADMUX=_BV(REFS0)|_BV(ADLAR)|_BV(MUX2)|_BV(MUX1); // ADCSRA|=(1<150) // reportBuffer.buttons[1]=KEY_W; // else if (result<90) // reportBuffer.buttons[1]=KEY_X; if ((~PINB&(1<bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */ DBG1(0x50, &rq->bRequest, 1); /* debug output: print our request */ if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */ /* we only have one report type, so don't look at wValue */ usbMsgPtr = (void *)&reportBuffer; return sizeof(reportBuffer); }else if(rq->bRequest == USBRQ_HID_GET_IDLE){ usbMsgPtr = &idleRate; return 1; }else if(rq->bRequest == USBRQ_HID_SET_IDLE){ idleRate = rq->wValue.bytes[1]; } }else{ /* no vendor specific requests implemented */ } return 0; /* default for not implemented requests: return no data back to host */ } void adcInit(){ DDRC=0; DDRB=0; PORTC=0xff; PORTB=0xff; //PORTB=(1< 250 ms */ wdt_reset(); _delay_ms(1); } usbDeviceConnect(); sei(); DBG1(0x01, 0, 0); /* debug output: main loop starts */ for(;;){ /* main event loop */ DBG1(0x02, 0, 0); /* debug output: main loop iterates */ wdt_reset(); usbPoll(); if(usbInterruptIsReady()){ /* called after every poll of the interrupt endpoint */ sendButton(); DBG1(0x03, 0, 0); /* debug output: interrupt report prepared */ usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer)); } } return 0; } /* ------------------------------------------------------------------------- */