Subversion Repositories group.electronics

Rev

Rev 26 | Rev 28 | 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);
27 pfowler 18
int getKey(void);
21 pfowler 19
 
20
volatile uint8_t pcIntCurr = 0;
21
volatile uint8_t pcIntLast = 0;
22
volatile uint8_t pcIntMask = 0;
23
 
22 pfowler 24
volatile uint8_t rot_stat = 0;
23 pfowler 25
volatile uint8_t rot_sent = 0;
21 pfowler 26
 
27
struct{
28
  union {
27 pfowler 29
    uint8_t data1[2];	// Rotaries
21 pfowler 30
    struct {
26 pfowler 31
	uint8_t rx:8;
32
	uint8_t ry:8;
27 pfowler 33
    };
34
  };
35
 
36
 
37
  union {
38
    uint16_t data2;
39
    struct {
26 pfowler 40
	uint8_t b00:1;
41
	uint8_t b01:1;
42
	uint8_t b02:1;
43
	uint8_t b03:1;
44
	uint8_t b04:1;
45
	uint8_t b05:1;
46
	uint8_t b06:1;
47
	uint8_t b07:1;
48
	uint8_t b08:1;
49
	uint8_t b09:1;
50
	uint8_t b10:1;
51
	uint8_t b11:1;
52
	uint8_t b12:1;
53
	uint8_t b13:1;
27 pfowler 54
	uint8_t rot1a:1;
55
	uint8_t rot1b:1;
21 pfowler 56
    };
57
  };
58
} report;
59
 
60
usbMsgLen_t usbFunctionSetup(uchar data[8]) {
61
  usbRequest_t *rq = (void *)data;
62
 
63
    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) {
64
        if(rq->bRequest == USBRQ_HID_GET_REPORT) {  
65
            return sizeof(report);
66
        } else if(rq->bRequest == USBRQ_HID_GET_IDLE) {
67
            return 1;
68
        } 
69
    }
70
 
71
  return 0;
72
}
73
 
74
void hadUsbReset(void) {
75
}
76
 
77
int main(void) {
78
 
79
  ACSR |= (1<<ACD); // Disable analog comparator
80
 
23 pfowler 81
  /*
82
  DDR : 1 = Output, 0 = Input
83
  PORT: 1 = Pullup for Input, otherwise set output
84
  PIN : Read input pin
85
  */
86
 
87
  /*
27 pfowler 88
	PB0	- Output 		- Keypad 5
89
	PB1	- Output 		- Keypad 6
90
	PB2	- Output 		- Keypad 7
91
	PB3	- Output 		- Keypad 8
24 pfowler 92
	PB4	- Input, Pullup		- Function select
23 pfowler 93
  */
27 pfowler 94
  DDRB		= 0B00001111;
95
  PORTB 	= 0B00011111;
21 pfowler 96
 
23 pfowler 97
  /*
24 pfowler 98
	PD0	- Input, Pullup, PCINT16	- Rotary 1a
99
	PD1	- Input, Pullup, PCINT17	- Rotary 1b
100
 
101
 
27 pfowler 102
	PD4	- Input				- Keypad 1
103
	PD5	- Input				- Keypad 2
104
	PD6	- Input				- Keypad 3
105
	PD7	- Input				- Keypad 4
23 pfowler 106
  */
27 pfowler 107
  DDRD		= 0B00000000;
108
  PORTD		= 0B11110011;
21 pfowler 109
 
24 pfowler 110
  PCMSK2 |= (( 1 << PCINT16 ) | ( 1 << PCINT17 )); //enable encoder pins interrupt sources
111
  PCICR |= ( 1 << PCIE2 ); //enable pin change interupts
21 pfowler 112
 
23 pfowler 113
  // Timers not used for the moment
114
  // Setup timer0 - Enable overflow, 8 times prescaler
115
  //TIMSK0 = (1<<TOIE0);			// Eable timer overflow for Timer0
116
  //TCNT0 = 0x00;				// Set Timer0 to 0
117
  //TCCR0B = (1<< CS01) ;			// /8 prescaler
21 pfowler 118
 
119
  usbDeviceDisconnect();  /* enforce re-enumeration, do this while interrupts are disabled! */
120
  _delay_ms(500);
121
  usbDeviceConnect();
122
 
123
  wdt_enable(WDTO_1S);
124
  usbInit();
125
  sei();
126
 
127
 
128
  for(;;) {
129
    wdt_reset();
130
    usbPoll();
131
 
132
    if(usbInterruptIsReady()){
27 pfowler 133
	report.data1[0] = 0x05;
134
	report.data1[1] = 0x05;
135
	report.data2 = 0x0000;
21 pfowler 136
 
27 pfowler 137
	int key = getKey();
138
	if (key > -1)
139
		report.data2 |= (1 << key);
21 pfowler 140
 
23 pfowler 141
	// Now work out what rotary to send, if any
142
	// Also record if we sent a positive response, 
143
	//  so we can send a '0' next time (if selected on PD4)
27 pfowler 144
 
23 pfowler 145
	if (rot_stat == 0x01 && rot_sent == 0) {
24 pfowler 146
		report.rot1a = 1;
23 pfowler 147
		rot_sent = 1;
148
	} else if (rot_stat == 0x02 && rot_sent == 0) {
24 pfowler 149
		report.rot1b = 1;
23 pfowler 150
		rot_sent = 1;
22 pfowler 151
	} else {
23 pfowler 152
		rot_sent = 0;
27 pfowler 153
	}
22 pfowler 154
 
23 pfowler 155
	// Reset our stat so ready for next turn
22 pfowler 156
	rot_stat = 0;
157
 
23 pfowler 158
	// If our function select is set, dont bother
159
	//  sending a 'o' between consequtive 1's.
24 pfowler 160
	if (rbi(PINB, PB4))
23 pfowler 161
		rot_sent = 0;
162
 
21 pfowler 163
      /* called after every poll of the interrupt endpoint */
164
      usbSetInterrupt(&report, sizeof(report));
165
    }
166
  }
167
}
168
 
27 pfowler 169
int getKey() {
24 pfowler 170
	uint8_t col, row = 0;
27 pfowler 171
	int key = -1;
24 pfowler 172
	uint8_t n = 0;
173
 
27 pfowler 174
	for (row=0; row<=3; row++) {
175
		//cbi(DDRB, row);
176
		cbi(PORTB, row);
177
		_delay_us(100);
178
		//for (col=4; col<=7; col++); {
179
			if (rbi(PIND, 4) == 0) key = n;
24 pfowler 180
			n++;
27 pfowler 181
		        if (rbi(PIND, 5) == 0) key = n;
182
			n++;
183
		        if (rbi(PIND, 6) == 0) key = n;
184
			n++;
185
		        if (rbi(PIND, 7) == 0) key = n;
186
			n++;
187
 
188
			//if (rbi(PIND, col) == 0)
189
			//	key = n;
190
		//}
191
		//sbi(DDRB, row);
192
		sbi(PORTB, row);
24 pfowler 193
	}
194
	return key;
195
}
196
 
21 pfowler 197
void doInt() {
23 pfowler 198
	// If rot_stat is not 0, we havn't sent
199
	//  our last results yet. Skip this click.
22 pfowler 200
	if (rot_stat != 0) {
201
		pcIntMask = 0;
202
		return;
203
	}
23 pfowler 204
 
205
	// Check which pin caused the interrupt. If they both
206
	//  equal 0, the pin that interrupted is the direction
24 pfowler 207
  	if (rbi(pcIntCurr, PCINT17) == 0 
208
		&& rbi(pcIntCurr, PCINT17) == 0 
209
		&& rbi(pcIntMask, PCINT16) ) {
23 pfowler 210
			rot_stat = 1;
24 pfowler 211
  	} else if (rbi(pcIntCurr, PCINT16) == 0 
212
		&& rbi(pcIntCurr, PCINT17) == 0 
213
		&& rbi(pcIntMask, PCINT17) ) {
23 pfowler 214
			rot_stat = 2;
215
  	}
216
 
217
	// Clear the mask so we know we've delth with it
218
	pcIntMask = 0;
21 pfowler 219
}
220
 
23 pfowler 221
/* Not used for the moment
21 pfowler 222
ISR(TIMER0_OVF_vect) {
223
	timer0_ovf++;
224
}
23 pfowler 225
*/
21 pfowler 226
 
24 pfowler 227
ISR(PCINT2_vect)
21 pfowler 228
{
23 pfowler 229
	// Save the state and work out which pin caused
230
	//  the interrupt to occur
24 pfowler 231
	pcIntCurr = PIND;
23 pfowler 232
	pcIntMask = pcIntCurr ^ pcIntLast;
233
	pcIntLast = pcIntCurr;
234
	doInt();
21 pfowler 235
}
236