Subversion Repositories group.electronics

Rev

Rev 93 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
79 pfowler 1
#include <avr/io.h>
2
#include <avr/wdt.h>
3
#include <avr/interrupt.h>
4
#include <avr/pgmspace.h>
5
#include <util/delay.h>
6
 
7
#include "usbdrv.h"
8
#include "config.h"
9
 
10
#ifndef NULL
11
#define NULL    ((void *)0)
12
#endif
13
 
112 pfowler 14
#define USB_GET_STATE  100
15
#define USB_LEDS_SET  101
88 pfowler 16
 
79 pfowler 17
/* ------------------------------------------------------------------------- */
18
 
84 pfowler 19
uint8_t getKey(void);
86 pfowler 20
void doButtons(uint8_t);
85 pfowler 21
inline void setLeds(uint8_t);
84 pfowler 22
 
79 pfowler 23
struct {
86 pfowler 24
	int16_t axis[2];
25
	uint8_t buttons;
79 pfowler 26
} reportBuffer;
27
 
28
 
29
volatile struct {
84 pfowler 30
	uint8_t buttons;
31
	uint8_t waitup;
79 pfowler 32
	uint8_t timer;
84 pfowler 33
} debounce;
79 pfowler 34
 
92 pfowler 35
volatile struct {
36
	uint8_t data;
37
	union {
38
		uint8_t led_method:1;
39
		uint8_t other:1;
40
		uint8_t reserved:6;
41
	};
42
} config;
43
 
112 pfowler 44
static uchar usbReplyBuf[16];
45
 
46
volatile uint8_t currLeds = 0;
47
volatile uint8_t currKeys = 0;
79 pfowler 48
volatile uint8_t tmr0_ovf = 0;
49
volatile uint32_t systime = 0;
50
 
51
/* ------------------------------------------------------------------------- */
52
 
86 pfowler 53
void hadUsbReset(void) {
85 pfowler 54
}
55
 
56
 
79 pfowler 57
uchar	usbFunctionSetup(uchar data[8])
58
{
59
    usbRequest_t    *rq = (void *)data;
60
 
88 pfowler 61
        switch (rq->bRequest ) {
112 pfowler 62
		case USB_GET_STATE:
63
			usbReplyBuf[0] = currLeds;
64
			usbReplyBuf[1] = currKeys;
65
			usbMsgPtr = usbReplyBuf;
66
			return sizeof(usbReplyBuf);
67
		case USB_LEDS_SET:
68
			currLeds = rq->wValue.bytes[0];
89 pfowler 69
			return 0;
112 pfowler 70
 
79 pfowler 71
        }
72
 
73
	return 0;
74
}
75
 
76
int main(void) {
77
 
86 pfowler 78
	DIDR0 = 0x00;
79
 
80 pfowler 80
  /*
81
  DDR : 1 = Output, 0 = Input
82
  PORT: 1 = Pullup for Input, otherwise set output
83
  PIN : Read input pin
84
  */
85
 
86
  /*
85 pfowler 87
        PB0     - Output                - LED 3
88
        PB1     - Output                - LED 4
89
        PB2     - Output                - LED 5
90
        PB3     - Output                - LED 6
91
        PB4     - Output                - LED 7
92
        PB5     - 
93
        PB6     - 
94
        PB7     - 
80 pfowler 95
  */
85 pfowler 96
  DDRB          = 0B00011111;
80 pfowler 97
  PORTB         = 0B00000000;
85 pfowler 98
 
80 pfowler 99
  /*
85 pfowler 100
        PC0     - Output		- ButtonPad Gnd0
101
        PC1     - Output		- ButtonPad Gnd1
102
        PC2     - Input, Pullup		- ButtonPad 0
103
        PC3     - Input, Pullup		- ButtonPad 1
104
        PC4     - Input, Pullup		- ButtonPad 2
105
        PC5     - Input, Pullup		- ButtonPad 3
80 pfowler 106
  */
86 pfowler 107
  DDRC          = 0B00000011;
108
  PORTC         = 0B00111111;
80 pfowler 109
 
85 pfowler 110
  /*
111
        PD0     - 
112
        PD1     - 
113
        PD2     - 
114
        PD3     - 
115
        PD4     - 
116
        PD5     - Output		- LED 0
117
        PD6     - Output		- LED 1
118
        PD7     - Output		- LED 2
119
  */
120
  DDRD          = 0B11100000;
121
  PORTD         = 0B00000000;
122
 
86 pfowler 123
	setLeds(0xff);
80 pfowler 124
 
79 pfowler 125
    usbDeviceDisconnect();
86 pfowler 126
    _delay_ms(500);
79 pfowler 127
    usbDeviceConnect();
128
 
129
 
85 pfowler 130
    TIMSK0 = (1<<TOIE0);                    // Enable timer overflow
79 pfowler 131
    TCNT0 = 0x00;                           // Set Timer0 initial value to 0
85 pfowler 132
    TCCR0B = (1<< CS00) ;                   // /1 prescaler
79 pfowler 133
 
86 pfowler 134
    wdt_enable(WDTO_1S);
79 pfowler 135
    usbInit();
136
    sei();
137
 
92 pfowler 138
	config.led_method = 1;
112 pfowler 139
	setLeds(currLeds);
80 pfowler 140
 
92 pfowler 141
 
86 pfowler 142
    for(;;){
79 pfowler 143
        wdt_reset();
144
        usbPoll();
145
 
112 pfowler 146
	currKeys = getKey();
92 pfowler 147
 
148
	if (config.led_method != rbi(PORTB, 5)) {
93 pfowler 149
		// Reset the leds when switcing	to buttons
112 pfowler 150
		if (config.led_method == 0) currLeds = 1;
92 pfowler 151
		config.led_method = rbi(PORTB, 5);
152
	}
153
 
112 pfowler 154
	if (config.led_method == 1) {
155
		uint8_t pressed = getKey();
92 pfowler 156
		doButtons(pressed);
112 pfowler 157
	}
92 pfowler 158
 
112 pfowler 159
	setLeds(currLeds);
80 pfowler 160
 
84 pfowler 161
 
79 pfowler 162
    }
86 pfowler 163
 
79 pfowler 164
    return 0;
165
}
166
 
85 pfowler 167
inline void setLeds(uint8_t leds) {
86 pfowler 168
	PORTB &= 0xE0;
85 pfowler 169
        PORTB |= (0x1F & (leds >> 3));
86 pfowler 170
	PORTD &= 0x1F;
85 pfowler 171
        PORTD |= (0xE0 & (leds << 5));
172
}
173
 
86 pfowler 174
void doButtons(uint8_t pressed) {
79 pfowler 175
 
84 pfowler 176
        // Deboucing
177
        // When i key first goes down, wait 5 ms, check it again to see if its still down
178
        if (pressed && debounce.buttons == 0 && debounce.timer == 0) {
179
                debounce.buttons = pressed;
180
                debounce.timer = 5;
79 pfowler 181
        }
182
 
84 pfowler 183
        // The key has come up
184
        if (pressed != debounce.buttons) {
185
                debounce.buttons = 0;
186
                debounce.timer = 0;
187
                debounce.waitup = 0;
188
        }
79 pfowler 189
 
84 pfowler 190
        // Debounce timer is up, process our button
191
        if (debounce.buttons && debounce.timer == 0 && debounce.waitup != 1) {
192
                uint8_t i = 0;
193
                for (i=0; i<=7; i++) {
194
                        // Button pressed and the led is currently on
112 pfowler 195
                        if ( rbi(debounce.buttons, i) == 1 && rbi(currLeds, i) == 1 ) {
196
                                if ( i == 0 && rbi(currLeds, 1) != 1)  //Dont turn off com1 if no comm2
84 pfowler 197
                                        break;
79 pfowler 198
 
112 pfowler 199
                                if ( i == 1 && rbi(currLeds, 0) != 1)  //Dont turn off com2 if no comm1
84 pfowler 200
                                        break;
201
 
112 pfowler 202
                                cbi(currLeds, i);
84 pfowler 203
                        // Button is pressed and led is currently off
112 pfowler 204
                         } else if ( rbi(debounce.buttons, i) == 1 && rbi(currLeds, i) == 0 ) {
205
                                if ( i == 0 && rbi(currLeds, 1) == 1)  //Turn on comm2, turn off comm1
206
                                        cbi(currLeds,1);
84 pfowler 207
 
112 pfowler 208
                                if ( i == 1 && rbi(currLeds, 0) == 1)  //Turn on comm1, turn off comm2
209
                                        cbi(currLeds,0);
84 pfowler 210
 
112 pfowler 211
                                sbi(currLeds, i);
84 pfowler 212
                        }
213
                }
214
                debounce.waitup = 1;
215
        }
79 pfowler 216
}
217
 
85 pfowler 218
// Gnd = PC0, PC1
219
// Btn = PC2, PC3, PC4, PC5
84 pfowler 220
uint8_t getKey() {
221
        uint8_t key = 0;
222
 
86 pfowler 223
        cbi(PORTC, 1);
84 pfowler 224
        _delay_us(10);        // Wait for the port change
85 pfowler 225
        if (rbi(PINC, 2) == 0) key = 1;
226
        if (rbi(PINC, 3) == 0) key = 2;
227
        if (rbi(PINC, 4) == 0) key = 4;
228
        if (rbi(PINC, 5) == 0) key = 8;
86 pfowler 229
        sbi(PORTC, 1);
84 pfowler 230
 
86 pfowler 231
        cbi(PORTC, 0);
84 pfowler 232
        _delay_us(10);
85 pfowler 233
        if (rbi(PINC, 2) == 0) key = 16;
234
        if (rbi(PINC, 3) == 0) key = 32;
235
        if (rbi(PINC, 4) == 0) key = 64;
236
        if (rbi(PINC, 5) == 0) key = 128;
86 pfowler 237
        sbi(PORTC, 0);
84 pfowler 238
 
239
        return key;
79 pfowler 240
}
241
 
84 pfowler 242
 
79 pfowler 243
ISR(TIMER0_OVF_vect) {
244
        tmr0_ovf++;
84 pfowler 245
 
87 pfowler 246
	// Clk/1 TCCR0B = (1<< CS00);
247
	//20.0Mhz, 1ms = 78ovf
248
	//16.5Mhz, 1ms = 64ovf
85 pfowler 249
	//12.0Mhz, 1ms = 46ovf
84 pfowler 250
 
87 pfowler 251
        if (tmr0_ovf>=78) {
79 pfowler 252
                systime++;
253
                tmr0_ovf = 0;
84 pfowler 254
 
255
		if (debounce.timer != 0)
256
			debounce.timer--;
92 pfowler 257
 
79 pfowler 258
        }
259
}