Subversion Repositories group.electronics

Rev

Rev 7 | Rev 18 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
7 pfowler 1
#include <avr/io.h>
2
#include <avr/pgmspace.h>
3
#include <avr/interrupt.h>
4
 
5
#define F_CPU 12000000
6
#include <util/delay.h>
7
#include <avr/wdt.h>
8
#include <avr/eeprom.h>
9
#include <usbdrv.h>
10
 
11
#include <stdlib.h>
12
#include <string.h>
13
 
14
#include "config.h"
15
#include "hiddesc.h"
16
 
16 pfowler 17
#define	DEPRESS_TIME	1
18
 
19
void doInt(void);
20
 
21
volatile uint8_t pcIntCurr = 0;
22
volatile uint8_t pcIntLast = 0;
23
volatile uint8_t pcIntMask = 0;
24
 
25
volatile uint8_t timer0_ovf = 0;
26
 
27
uint8_t time_rot = 0;
28
 
7 pfowler 29
struct{
30
  union {
31
    uint8_t data;
32
    struct {
33
      uint8_t X:2;
34
      uint8_t Y:2;
35
      uint8_t B:1;
36
      uint8_t A:1;
16 pfowler 37
      uint8_t rot1:1;
38
      uint8_t rot2:1;
7 pfowler 39
    };
40
  };
16 pfowler 41
} report;
7 pfowler 42
 
43
usbMsgLen_t usbFunctionSetup(uchar data[8]) {
44
  usbRequest_t *rq = (void *)data;
45
 
46
    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) {
47
        if(rq->bRequest == USBRQ_HID_GET_REPORT) {  
16 pfowler 48
            return sizeof(report);
7 pfowler 49
        } else if(rq->bRequest == USBRQ_HID_GET_IDLE) {
50
            return 1;
51
        } 
52
    }
53
 
54
  return 0;
55
}
56
 
57
void hadUsbReset(void) {
58
}
59
 
60
int main(void) {
61
 
62
  ACSR |= (1<<ACD); // Disable analog comparator
16 pfowler 63
 
64
  // DDR : 1 = Output, 0 = Input
65
  // PORT: 1 = Pullup for Input, otherwise set output
66
  // PIN : Read input pin
67
  DDRB		= 0B00011111;
68
  PORTB 	= 0B00011111;
69
 
70
  DDRD		= 0B00110000;
71
  PORTD		= 0B00110000;
72
 
73
  // Setup timer0
74
  TIMSK = (1<<TOIE0);			// Eable timer overflow for Timer0
75
  TCNT0 = 0x00;				// Set Timer0 to 0
76
  TCCR0B = (1<< CS02) | (1<<CS00);	// /1024 prescaler
77
 
7 pfowler 78
  usbDeviceDisconnect();  /* enforce re-enumeration, do this while interrupts are disabled! */
79
  _delay_ms(500);
80
  usbDeviceConnect();
81
 
82
  wdt_enable(WDTO_1S);
83
  usbInit();
84
  sei();
85
 
86
 
87
  for(;;) {
88
    wdt_reset();
89
    usbPoll();
90
 
16 pfowler 91
	if (pcIntMask);
92
		doInt();
7 pfowler 93
 
16 pfowler 94
	if (!time_rot) {
95
		report.rot1 = 0;
96
		report.rot2 = 0;
97
	}	
98
 
7 pfowler 99
    if(usbInterruptIsReady()){
16 pfowler 100
      report.data = 0x05; // Center pad, little endian
7 pfowler 101
 
102
	if (bit_is_clear(PINB, PB0)) 
16 pfowler 103
		report.X++;
7 pfowler 104
	if (bit_is_clear(PINB, PB1))
16 pfowler 105
		report.Y--;
7 pfowler 106
	if (bit_is_clear(PINB, PB2))
16 pfowler 107
		report.X--;
7 pfowler 108
	if (bit_is_clear(PINB, PB3))
16 pfowler 109
		report.Y++;
7 pfowler 110
 
111
	if (bit_is_clear(PIND, PD4))
16 pfowler 112
		report.A = 1;
7 pfowler 113
	if (bit_is_clear(PIND, PD5))
16 pfowler 114
		report.B = 1;
7 pfowler 115
 
116
      /* called after every poll of the interrupt endpoint */
16 pfowler 117
      usbSetInterrupt(&report, sizeof(report));
7 pfowler 118
    }
16 pfowler 119
  }
120
}
7 pfowler 121
 
16 pfowler 122
void doInt() {
123
  if (rbi(pcIntCurr, PCINT2) == 0 && rbi(pcIntCurr, PCINT3) == 0 && rbi(pcIntMask, PCINT2) ) {
124
	time_rot = 5;
125
	report.rot1 = 1;
126
	report.rot2 = 0;
127
  } else if (rbi(pcIntCurr, PCINT3) == 0 && rbi(pcIntCurr, PCINT2) == 0 && rbi(pcIntMask, PCINT3) ) {
128
	time_rot = 5;
129
	report.rot1 = 0;
130
	report.rot2 = 1;
7 pfowler 131
  }
132
 
16 pfowler 133
  pcIntMask = 0;
7 pfowler 134
}
16 pfowler 135
 
136
ISR(TIMER0_OVF_vect) {
137
	timer0_ovf++;
138
 
139
	if (time_rot) {
140
		time_rot--;
141
	}
142
}
143
 
144
ISR(PCINT_vect)
145
{
146
  pcIntCurr = PINB;
147
  pcIntMask = pcIntCurr ^ pcIntLast;
148
  pcIntLast = pcIntCurr;
149
}
150