Subversion Repositories group.electronics

Rev

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

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