Subversion Repositories group.electronics

Rev

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

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