Subversion Repositories group.electronics

Rev

Rev 86 | Rev 88 | Go to most recent revision | 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
 
14
/* ------------------------------------------------------------------------- */
15
 
84 pfowler 16
uint8_t getKey(void);
86 pfowler 17
void doButtons(uint8_t);
85 pfowler 18
inline void setLeds(uint8_t);
84 pfowler 19
 
79 pfowler 20
struct {
86 pfowler 21
	int16_t axis[2];
22
	uint8_t buttons;
79 pfowler 23
} reportBuffer;
24
 
25
 
26
volatile struct {
84 pfowler 27
	uint8_t buttons;
28
	uint8_t waitup;
79 pfowler 29
	uint8_t timer;
84 pfowler 30
} debounce;
79 pfowler 31
 
86 pfowler 32
uint8_t currleds = 1;
79 pfowler 33
static uchar    idleRate;           /* in 4 ms units */
34
volatile uint8_t tmr0_ovf = 0;
35
volatile uint32_t systime = 0;
36
 
37
/* ------------------------------------------------------------------------- */
38
 
39
const PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { /* USB report descriptor */
40
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
41
    0x09, 0x05,                    // USAGE (Game Pad)
42
    0xa1, 0x01,                    // COLLECTION (Application)
43
    0x09, 0x01,                    //   USAGE (Pointer)
44
    0xa1, 0x00,                    //   COLLECTION (Physical)
45
    0x09, 0x30,                    //     USAGE (X)
46
    0x09, 0x31,                    //     USAGE (Y)
47
    0x16, 0x00, 0x80,		   //	  Log Min -32768
48
    0x26, 0xff, 0x7f,		   //	  Log max 32768
49
    0x75, 0x10,                    //     REPORT_SIZE (16)
50
    0x95, 0x02,                    //     REPORT_COUNT (2)
51
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
52
 
53
    0x05, 0x09,                    //     USAGE_PAGE (Button)
54
    0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
84 pfowler 55
    0x29, 0x08,                    //     USAGE_MAXIMUM (Button 8)
79 pfowler 56
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
57
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
58
    0x75, 0x01,                    //     REPORT_SIZE (1)
59
    0x95, 0x08,                    //     REPORT_COUNT (2)
60
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
61
 
62
    0xc0,                          //   END_COLLECTION
63
    0xc0                           // END_COLLECTION
64
};
65
 
86 pfowler 66
void hadUsbReset(void) {
85 pfowler 67
}
68
 
69
 
79 pfowler 70
uchar	usbFunctionSetup(uchar data[8])
71
{
72
    usbRequest_t    *rq = (void *)data;
73
 
74
    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ 
75
        if(rq->bRequest == USBRQ_HID_GET_REPORT){ 
76
            return sizeof(reportBuffer);
77
        }else if(rq->bRequest == USBRQ_HID_GET_IDLE){
86 pfowler 78
            //usbMsgPtr = &idleRate;
79 pfowler 79
            return 1;
80
        }else if(rq->bRequest == USBRQ_HID_SET_IDLE){
81
            idleRate = rq->wValue.bytes[1];
82
        }
83
    }else{
84
 
85
    }
86
	return 0;
87
}
88
 
89
 
90
void usbSendHidReport(uchar * data, uchar len) {
91
	usbSetInterrupt(data, len);
92
}
93
 
86 pfowler 94
/*
95
void usbSendHidReport(uchar * data, uchar len) {
96
        while(1)
97
        {
98
                usbPoll();
99
                if (usbInterruptIsReady())
100
                {
101
                        usbSetInterrupt(data, len);
102
                        break;
103
                }
104
        }
105
}
106
*/
79 pfowler 107
 
86 pfowler 108
 
79 pfowler 109
int main(void) {
110
 
86 pfowler 111
	DIDR0 = 0x00;
112
 
80 pfowler 113
  /*
114
  DDR : 1 = Output, 0 = Input
115
  PORT: 1 = Pullup for Input, otherwise set output
116
  PIN : Read input pin
117
  */
118
 
119
  /*
85 pfowler 120
        PB0     - Output                - LED 3
121
        PB1     - Output                - LED 4
122
        PB2     - Output                - LED 5
123
        PB3     - Output                - LED 6
124
        PB4     - Output                - LED 7
125
        PB5     - 
126
        PB6     - 
127
        PB7     - 
80 pfowler 128
  */
85 pfowler 129
  DDRB          = 0B00011111;
80 pfowler 130
  PORTB         = 0B00000000;
85 pfowler 131
 
80 pfowler 132
  /*
85 pfowler 133
        PC0     - Output		- ButtonPad Gnd0
134
        PC1     - Output		- ButtonPad Gnd1
135
        PC2     - Input, Pullup		- ButtonPad 0
136
        PC3     - Input, Pullup		- ButtonPad 1
137
        PC4     - Input, Pullup		- ButtonPad 2
138
        PC5     - Input, Pullup		- ButtonPad 3
80 pfowler 139
  */
86 pfowler 140
  DDRC          = 0B00000011;
141
  PORTC         = 0B00111111;
80 pfowler 142
 
85 pfowler 143
  /*
144
        PD0     - 
145
        PD1     - 
146
        PD2     - 
147
        PD3     - 
148
        PD4     - 
149
        PD5     - Output		- LED 0
150
        PD6     - Output		- LED 1
151
        PD7     - Output		- LED 2
152
  */
153
  DDRD          = 0B11100000;
154
  PORTD         = 0B00000000;
155
 
86 pfowler 156
	setLeds(0xff);
80 pfowler 157
 
79 pfowler 158
    usbDeviceDisconnect();
86 pfowler 159
    _delay_ms(500);
79 pfowler 160
    usbDeviceConnect();
161
 
162
 
85 pfowler 163
    TIMSK0 = (1<<TOIE0);                    // Enable timer overflow
79 pfowler 164
    TCNT0 = 0x00;                           // Set Timer0 initial value to 0
85 pfowler 165
    TCCR0B = (1<< CS00) ;                   // /1 prescaler
79 pfowler 166
 
86 pfowler 167
    wdt_enable(WDTO_1S);
79 pfowler 168
    usbInit();
169
    sei();
170
 
86 pfowler 171
    reportBuffer.axis[0] = 0xfffd;
172
    reportBuffer.axis[1] = 0xfffd;
173
    reportBuffer.buttons = 0x00;
79 pfowler 174
 
86 pfowler 175
	setLeds(currleds);
80 pfowler 176
 
86 pfowler 177
    for(;;){
79 pfowler 178
        wdt_reset();
179
        usbPoll();
180
 
86 pfowler 181
	uint8_t pressed = getKey();
182
	doButtons(pressed);	
80 pfowler 183
 
79 pfowler 184
        if(usbInterruptIsReady()){ 
86 pfowler 185
                reportBuffer.buttons = pressed;
79 pfowler 186
		usbSendHidReport(&reportBuffer, sizeof(reportBuffer));
187
        }
84 pfowler 188
 
79 pfowler 189
    }
86 pfowler 190
 
79 pfowler 191
    return 0;
192
}
193
 
85 pfowler 194
inline void setLeds(uint8_t leds) {
86 pfowler 195
	PORTB &= 0xE0;
85 pfowler 196
        PORTB |= (0x1F & (leds >> 3));
86 pfowler 197
	PORTD &= 0x1F;
85 pfowler 198
        PORTD |= (0xE0 & (leds << 5));
199
}
200
 
86 pfowler 201
void doButtons(uint8_t pressed) {
79 pfowler 202
 
84 pfowler 203
        // Deboucing
204
        // When i key first goes down, wait 5 ms, check it again to see if its still down
205
        if (pressed && debounce.buttons == 0 && debounce.timer == 0) {
206
                debounce.buttons = pressed;
207
                debounce.timer = 5;
79 pfowler 208
        }
209
 
84 pfowler 210
        // The key has come up
211
        if (pressed != debounce.buttons) {
212
                debounce.buttons = 0;
213
                debounce.timer = 0;
214
                debounce.waitup = 0;
215
        }
79 pfowler 216
 
84 pfowler 217
        // Debounce timer is up, process our button
218
        if (debounce.buttons && debounce.timer == 0 && debounce.waitup != 1) {
219
                uint8_t i = 0;
220
                for (i=0; i<=7; i++) {
221
                        // Button pressed and the led is currently on
222
                        if ( rbi(debounce.buttons, i) == 1 && rbi(currleds, i) == 1 ) {
86 pfowler 223
                                if ( i == 0 && rbi(currleds, 1) != 1)  //Dont turn off com1 if no comm2
84 pfowler 224
                                        break;
79 pfowler 225
 
86 pfowler 226
                                if ( i == 1 && rbi(currleds, 0) != 1)  //Dont turn off com2 if no comm1
84 pfowler 227
                                        break;
228
 
229
                                cbi(currleds, i);
230
                        // Button is pressed and led is currently off
231
                         } else if ( rbi(debounce.buttons, i) == 1 && rbi(currleds, i) == 0 ) {
86 pfowler 232
                                if ( i == 0 && rbi(currleds, 1) == 1)  //Turn on comm2, turn off comm1
233
                                        cbi(currleds,1);
84 pfowler 234
 
86 pfowler 235
                                if ( i == 1 && rbi(currleds, 0) == 1)  //Turn on comm1, turn off comm2
236
                                        cbi(currleds,0);
84 pfowler 237
 
238
                                sbi(currleds, i);
239
                        }
240
                }
85 pfowler 241
                setLeds(currleds);
84 pfowler 242
                debounce.waitup = 1;
243
        }
79 pfowler 244
}
245
 
85 pfowler 246
// Gnd = PC0, PC1
247
// Btn = PC2, PC3, PC4, PC5
84 pfowler 248
uint8_t getKey() {
249
        uint8_t key = 0;
250
 
86 pfowler 251
        cbi(PORTC, 1);
84 pfowler 252
        _delay_us(10);        // Wait for the port change
85 pfowler 253
        if (rbi(PINC, 2) == 0) key = 1;
254
        if (rbi(PINC, 3) == 0) key = 2;
255
        if (rbi(PINC, 4) == 0) key = 4;
256
        if (rbi(PINC, 5) == 0) key = 8;
86 pfowler 257
        sbi(PORTC, 1);
84 pfowler 258
 
86 pfowler 259
        cbi(PORTC, 0);
84 pfowler 260
        _delay_us(10);
85 pfowler 261
        if (rbi(PINC, 2) == 0) key = 16;
262
        if (rbi(PINC, 3) == 0) key = 32;
263
        if (rbi(PINC, 4) == 0) key = 64;
264
        if (rbi(PINC, 5) == 0) key = 128;
86 pfowler 265
        sbi(PORTC, 0);
84 pfowler 266
 
267
        return key;
79 pfowler 268
}
269
 
84 pfowler 270
 
79 pfowler 271
ISR(TIMER0_OVF_vect) {
272
        tmr0_ovf++;
84 pfowler 273
 
87 pfowler 274
	// Clk/1 TCCR0B = (1<< CS00);
275
	//20.0Mhz, 1ms = 78ovf
276
	//16.5Mhz, 1ms = 64ovf
85 pfowler 277
	//12.0Mhz, 1ms = 46ovf
84 pfowler 278
 
87 pfowler 279
        if (tmr0_ovf>=78) {
79 pfowler 280
                systime++;
281
                tmr0_ovf = 0;
84 pfowler 282
 
283
		if (debounce.timer != 0)
284
			debounce.timer--;
79 pfowler 285
        }
286
}