Subversion Repositories group.electronics

Rev

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

Rev Author Line No. Line
98 pfowler 1
/*
2
 * atcpad.c
3
 *
4
 * Created: 7/06/2013 10:15:34 PM
5
 *  Author: pfowler
6
 */ 
7
 
8
 
33 pfowler 9
#include <avr/io.h>
10
#include <avr/pgmspace.h>
11
#include <avr/interrupt.h>
12
 
13
#include <util/delay.h>
14
#include <avr/wdt.h>
100 pfowler 15
#include <stdlib.h>
16
#include <string.h>
17
 
98 pfowler 18
#include "usbdrv.h"
19
#include "atcpad.h"
20
#include "avrutil.h"
63 pfowler 21
#include "lcd.h"
40 pfowler 22
#include "wire.h"
33 pfowler 23
#include "hiddesc.h"
24
 
101 pfowler 25
#define BUTTONS	 		1
26
#define ROTARYS			1
39 pfowler 27
 
101 pfowler 28
#define LCD_UPDATE		11
29
#define	ROTARY_UPDATE	5
100 pfowler 30
 
101 pfowler 31
 
100 pfowler 32
uint8_t getKey(void);
33
void updateLcd();
101 pfowler 34
void checkRotarys();
35
void checkButtons(void);
100 pfowler 36
 
101 pfowler 37
 
97 pfowler 38
// * = 0x25, #=0x20
39
// F9 = 0x42, F12 = 0x45
40
uint8_t keyMap[] = { 	0x1E, 0x1F, 0x20,
41
						0x21, 0x22, 0x23,
42
						0x24, 0x25, 0x26,
43
						0x42, 0x27, 0x45 };
100 pfowler 44
 
98 pfowler 45
uint8_t lcdRectangle[] = {   
46
	0B00011111,
47
	0B00010001,
48
	0B00010001,
49
	0B00010001,
50
	0B00010001,
51
	0B00010001,
52
	0B00010001,
53
	0B00011111 };
97 pfowler 54
 
55
 
100 pfowler 56
uint8_t oldpotVal = 0;
57
uint8_t keySelect = 1;
58
 
101 pfowler 59
// Start these of at different times, so they
60
//  don't kick of it the same loop run
61
volatile uint8_t lcdTimer = 8;
62
volatile uint8_t rotaryTimer = 5;
63
 
98 pfowler 64
volatile struct {
65
	uint8_t detected;
66
	uint8_t timer;
99 pfowler 67
	uint8_t waitup;
98 pfowler 68
} buttons[BUTTONS];
97 pfowler 69
 
101 pfowler 70
volatile struct {
71
 
72
	union {
73
		uint8_t data;
74
		struct {
75
			uint8_t stat:4;
76
			uint8_t sent:4;
77
		};
78
	};
79
} rotary[ROTARYS];
80
 
98 pfowler 81
int main(void)
82
{
83
 
84
	setup();
85
 
86
    while(1)
87
    {
100 pfowler 88
		wdt_reset();
98 pfowler 89
        loop(); 
90
    }
39 pfowler 91
}
92
 
98 pfowler 93
void setup() {
97 pfowler 94
	/*
95
		DDR : 1 = Output, 0 = Input
96
		PORT: 1 = Pullup for Input, otherwise set output
97
		PIN : Read input pin
98
	*/
33 pfowler 99
 
97 pfowler 100
	/*
101
		PB0	- Output 		- Keypad 2
102
		PB1	- Output 		- Keypad 7
103
		PB2	- Output 		- Keypad 6
104
		PB3	- Output 		- Keypad 4
105
		PB4	- Input, Pullup		- Function select
106
		PB5	- Input, Pullup		- Function select
107
	*/
101 pfowler 108
	DDRB	= 0B00001111;
97 pfowler 109
	PORTB 	= 0B00111111;
33 pfowler 110
 
97 pfowler 111
	/*
112
		PD0	- Input, Pullup, PCINT16	- Rotary 1a
113
		PD1	- Input, Pullup, PCINT17	- Rotary 1b
33 pfowler 114
 
115
 
97 pfowler 116
		PD4	- Output		- Keypad select status led
117
		PD5	- Input, Pullup		- Keypad 3
118
		PD6	- Input, Pullup		- Keypad 1
119
		PD7	- Input, Pullup		- Keypad 5
120
	*/
101 pfowler 121
	DDRD	= 0B00010000;
122
	PORTD	= 0B11110011;
33 pfowler 123
 
97 pfowler 124
	PCMSK2 |= (( 1 << PCINT16 ) | ( 1 << PCINT17 )); //enable encoder pins interrupt sources
98 pfowler 125
	PCICR |= ( 1 << PCIE2 ); //enable pin change interrupts
126
 
127
	analogInit();
128
	sysclockInit();
129
 
130
	reportKeyboard.report_id = 1;
131
	reportJoystick.report_id = 2;	
132
 
97 pfowler 133
	usbDeviceDisconnect();  /* enforce re-enumeration, do this while interrupts are disabled! */
134
	_delay_ms(500);
135
	usbDeviceConnect();
33 pfowler 136
 
99 pfowler 137
	sei();
97 pfowler 138
	wdt_enable(WDTO_1S);
139
	usbInit();
63 pfowler 140
 
40 pfowler 141
	i2c_master();
63 pfowler 142
	lcd_init();
98 pfowler 143
	lcd_createChar(0x00, lcdRectangle);
40 pfowler 144
 
63 pfowler 145
	char strTime[] = {'T', 'i', 'm', 'e', ':', 0x00};
97 pfowler 146
	lcd_setCursor(0, 1);
98 pfowler 147
	lcd_print(strTime);
99 pfowler 148
 
149
	buttons[0].detected = 0;
150
	buttons[0].timer = 0;
151
	buttons[0].waitup = 0;
152
 
153
	cbi(PORTD, 4);
98 pfowler 154
 
155
}
33 pfowler 156
 
98 pfowler 157
void loop() {
99 pfowler 158
 
100 pfowler 159
   	usbPoll();
160
 
101 pfowler 161
	if (lcdTimer==0) {
100 pfowler 162
		updateLcd();
101 pfowler 163
		lcdTimer = LCD_UPDATE;
100 pfowler 164
	}
101 pfowler 165
 
166
 
167
	if (rotaryTimer==0) {
168
		checkRotarys();
169
		rotaryTimer = ROTARY_UPDATE;
170
	}
171
 
172
	checkButtons();
100 pfowler 173
 
174
 
98 pfowler 175
	if(usbInterruptIsReady()){
176
	    usbSendHidReport((uchar*)&reportKeyboard, sizeof(reportKeyboard));
177
	    usbSendHidReport((uchar*)&reportJoystick, sizeof(reportJoystick));
100 pfowler 178
    }	
33 pfowler 179
}
180
 
181
uint8_t getKey() {
182
	uint8_t col, row = 0;
183
	uint8_t key = 0;
184
	uint8_t n = 1;
185
 
186
	for (row=0; row<=3; row++) {
187
		cbi(PORTB, row);
188
		_delay_us(10);				// Wait for the port to change
189
 
190
		for (col=5; col<=7; col++) {
191
			if (rbi(PIND, col) == 0)
98 pfowler 192
			key = n;
33 pfowler 193
			n++;
98 pfowler 194
		}
33 pfowler 195
 
196
		sbi(PORTB, row);
197
	}
198
	return key;
199
}
200
 
101 pfowler 201
void checkRotarys() {
202
	uint8_t rot = 0;
203
	for (rot=0; rot<=(ROTARYS - 1); rot++) {
204
		if (rotary[rot].stat == 0x01 && rotary[rot].sent == 0) {
205
			rotary[rot].sent = 1;
206
			switch (rot) {
207
				case(0):        reportJoystick.rot1a = 1; break;
208
				case(1):        reportJoystick.rot2a = 1; break;
209
			}
210
		} else if (rotary[rot].stat == 0x02 && rotary[rot].sent == 0) {
211
			rotary[rot].sent = 1;
212
			switch (rot) {
213
				case(0):      reportJoystick.rot1b = 1; break;
214
				case(1):      reportJoystick.rot2b = 1; break;
215
			}
216
		} else {
217
			rotary[rot].sent = 0;
218
		}
219
		rotary[rot].stat = 0;
220
 
221
		if (rbi(PINB, PB4))
222
			rotary[rot].sent = 0;
223
	}
224
}
225
 
226
void checkButtons() {
227
 
228
	reportJoystick.data1[0] = (-128 + analogRead(0));
229
	reportJoystick.data1[1] = (-128 + analogRead(1));
230
	reportJoystick.data2 = 0x0000;				// Clear all the buttons
231
 
232
	reportKeyboard.modifier = 0x00;
233
	reportKeyboard.keycode = 0x00;
234
 
235
	uint8_t key = getKey();
236
	if (rbi(keySelect, 0)) {
237
		// Keypad is joystick
238
		if (key > 0)
239
			reportJoystick.data2 |= (1 << (--key));
240
		} else {
241
		// Keypad is keyboard
242
		if (key > 0) {
243
			//if (key==10 || key==12) // Left shift, for *, #
244
			//	reportKeyboard.modifier |= (1<<1);
245
			reportKeyboard.keycode = keyMap[--key];
246
		}
247
	}
248
 
249
	// Only one button for now
250
	if (rbi(PINB, 5) == 0 && buttons[0].detected == 0 && buttons[0].timer == 0) {
251
		buttons[0].detected = 1;
252
		buttons[0].timer = 5;
253
 
254
	}
255
 
256
	if (rbi(PINB, 5) == 1 && buttons[0].waitup == 1) {
257
		buttons[0].detected = 0;
258
		buttons[0].timer = 0;
259
		buttons[0].waitup = 0;
260
	}
261
 
262
	if (buttons[0].detected == 1 && buttons[0].timer == 0 && buttons[0].waitup == 0 ) {
263
 
264
		xbi(keySelect, 0);
265
 
266
		if (keySelect == 0)
267
			sbi(PORTD, PD4);
268
		else
269
			cbi(PORTD, PD4);	
270
 
271
		buttons[0].waitup = 1;
272
	}
273
}
274
 
100 pfowler 275
void updateLcd() {
276
	usbPoll();
277
 
278
 
279
	char syschar[10];
280
	ultoa(systime, syschar, 10);
281
	lcd_overprint_right(syschar, 10, 5, 1);
282
 
283
	uint8_t potVal = map_8(analogRead(0), 0, 255, 0, 100);
284
	if (potVal != oldpotVal) {
285
		lcd_percent_graph(potVal, 0, 0);
286
		oldpotVal = potVal;
287
 
288
		char pot[3];
289
		utoa(potVal, pot, 10);
290
		lcd_overprint_right(pot, 3, 11, 0);
291
 
292
		// Set percentage
293
		lcd_setCursor(15, 0);
294
		lcd_char(0x25);
295
	}
296
}
297
 
97 pfowler 298
void millis_tick() {
98 pfowler 299
 
97 pfowler 300
}
301
 
33 pfowler 302
ISR(TIMER0_OVF_vect) {
63 pfowler 303
	tmr0_ovf++;
99 pfowler 304
	if (tmr0_ovf >= sys_ovf_tick) {
63 pfowler 305
		systime++;
306
		tmr0_ovf = 0;
99 pfowler 307
		//millis_tick();	// Not working, taking too long to call?
308
 
101 pfowler 309
		if (buttons[0].timer)
99 pfowler 310
			buttons[0].timer--;
100 pfowler 311
 
101 pfowler 312
		if (lcdTimer)
313
			lcdTimer--;
314
 
315
		if (rotaryTimer)
316
			rotaryTimer--;
317
 
63 pfowler 318
	}
33 pfowler 319
}
98 pfowler 320
void usbSendHidReport(uchar * data, uchar len) {
321
	while(1)
322
	{
323
		usbPoll();
324
		if (usbInterruptIsReady())
325
		{
326
			usbSetInterrupt(data, len);
327
			break;
328
		}
329
	}
33 pfowler 330
}
331
 
98 pfowler 332
usbMsgLen_t usbFunctionSetup(uchar data[8]) {
333
	usbRequest_t *rq = (void *)data;
33 pfowler 334
 
98 pfowler 335
	if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) {
336
		switch (rq->bRequest) {
337
			case USBRQ_HID_GET_REPORT:
100 pfowler 338
				if (rq->wValue.bytes[0] == 1)
339
					return sizeof(reportKeyboard);
340
				else if (rq->wValue.bytes[0] == 2)
341
					return sizeof(reportJoystick);
342
				else
343
					return 0;
98 pfowler 344
			case USBRQ_HID_GET_IDLE:
100 pfowler 345
				usbMsgPtr = &idleRate;
101 pfowler 346
				return 1;
98 pfowler 347
 
348
 
349
 
350
			default:
101 pfowler 351
				return 0;
98 pfowler 352
		}
353
	}
354
	return 0;
62 pfowler 355
}
356
 
98 pfowler 357
void hadUsbReset(void) {
99 pfowler 358
}