hid-arcade/firmware/main.c.old

344 lines
10 KiB
C
Executable File

/* 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 <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h> /* for sei() */
#include <util/delay.h> /* for _delay_ms() */
#include <avr/pgmspace.h> /* 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<<ADSC);
// while((ADCSRA&(1<<ADSC)));
//result+=ADCH;
/* ADCSRA|=(1<<ADSC);
while((ADCSRA&(1<<ADSC)));
result+=ADCH;
ADCSRA|=(1<<ADSC);
while((ADCSRA&(1<<ADSC)));
result+=ADCH;
result=result/3;*/
// if (result>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<<ADSC);
// while((ADCSRA&(1<<ADSC)));
// result+=ADCH;
/* ADCSRA|=(1<<ADSC);
while((ADCSRA&(1<<ADSC)));
result+=ADCH;
ADCSRA|=(1<<ADSC);
while((ADCSRA&(1<<ADSC)));
result+=ADCH;
result=result/3;*/
// if (result>150)
// reportBuffer.buttons[1]=KEY_W;
// else if (result<90)
// reportBuffer.buttons[1]=KEY_X;
if ((~PINB&(1<<PB0)))
reportBuffer.buttons[0]=KEY_W;
else if ((~PINB&(1<<PB1)))
reportBuffer.buttons[0]=KEY_S;
if ((~PINB&(1<<PB2)))
reportBuffer.buttons[1]=KEY_A;
else if ((~PINB&(1<<PB3)))
reportBuffer.buttons[1]=KEY_D;
reportBuffer.buttons[2]=0;
reportBuffer.buttons[3]=0;
reportBuffer.buttons[4]=0;
reportBuffer.buttons[5]=0;
if ((~PINC&(1<<PC0))&&freeKey<=5){
reportBuffer.buttons[freeKey]=KEY_F;
freeKey++;
}
if ((~PINC&(1<<PC1))&&freeKey<=5){
reportBuffer.buttons[freeKey]=KEY_G;
freeKey++;
}
if ((~PINC&(1<<PC2))&&freeKey<=5){
reportBuffer.buttons[freeKey]=KEY_H;
freeKey++;
}
if ((~PINC&(1<<PC3))&&freeKey<=5){
reportBuffer.buttons[freeKey]=KEY_Y;
freeKey++;
}
if ((~PINC&(1<<PC4))&&freeKey<=5){
reportBuffer.buttons[freeKey]=KEY_R;
freeKey++;
}
if ((~PINC&(1<<PC5))&&freeKey<=5){
reportBuffer.buttons[freeKey]=KEY_T;
freeKey++;
}
// if ((~PINB&(1<<PB1))&&freeKey<=5){
// reportBuffer.buttons[freeKey]=KEY_V;
// freeKey++;
// }
// if ((~PINB&(1<<PB2))&&freeKey<=5){
// reportBuffer.buttons[freeKey]=KEY_B;
// freeKey++;
// }
}
/* ------------------------------------------------------------------------- */
usbMsgLen_t usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
/* The following requests are never used. But since they are required by
* the specification, we implement them in this example.
*/
if((rq->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<<PB1)|(1<<PB2);
//ADMUX=(1<<REFS0);
//ADCSRA=(1<<ADEN)|(1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2);
}
/* ------------------------------------------------------------------------- */
int main(void)
{
uchar i;
wdt_enable(WDTO_1S);
/* Even if you don't use the watchdog, turn it off here. On newer devices,
* the status of the watchdog (on/off, period) is PRESERVED OVER RESET!
*/
DBG1(0x00, 0, 0); /* debug output: main starts */
/* RESET status: all port bits are inputs without pull-up.
* That's the way we need D+ and D-. Therefore we don't need any
* additional hardware initialization.
*/
adcInit();
odDebugInit();
usbInit();
usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
i = 0;
while(--i){ /* fake USB disconnect for > 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;
}
/* ------------------------------------------------------------------------- */