Subversion Repositories group.electronics

Rev

Rev 99 | Rev 101 | 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
 
99 pfowler 25
#define BUTTONS	 	1
39 pfowler 26
#define ON		1
27
#define OFF		0
28
 
100 pfowler 29
 
30
uint8_t getKey(void);
31
void updateLcd();
32
 
97 pfowler 33
// * = 0x25, #=0x20
34
// F9 = 0x42, F12 = 0x45
35
uint8_t keyMap[] = { 	0x1E, 0x1F, 0x20,
36
						0x21, 0x22, 0x23,
37
						0x24, 0x25, 0x26,
38
						0x42, 0x27, 0x45 };
100 pfowler 39
 
98 pfowler 40
uint8_t lcdRectangle[] = {   
41
	0B00011111,
42
	0B00010001,
43
	0B00010001,
44
	0B00010001,
45
	0B00010001,
46
	0B00010001,
47
	0B00010001,
48
	0B00011111 };
97 pfowler 49
 
50
 
100 pfowler 51
uint8_t oldpotVal = 0;
52
volatile uint8_t lcdtimer = 0;
53
uint8_t keySelect = 1;
54
 
98 pfowler 55
volatile struct {
56
	uint8_t detected;
57
	uint8_t timer;
99 pfowler 58
	uint8_t waitup;
98 pfowler 59
} buttons[BUTTONS];
97 pfowler 60
 
98 pfowler 61
int main(void)
62
{
63
 
64
	setup();
65
 
66
    while(1)
67
    {
100 pfowler 68
		wdt_reset();
98 pfowler 69
        loop(); 
70
    }
39 pfowler 71
}
72
 
98 pfowler 73
void setup() {
97 pfowler 74
	/*
75
		DDR : 1 = Output, 0 = Input
76
		PORT: 1 = Pullup for Input, otherwise set output
77
		PIN : Read input pin
78
	*/
33 pfowler 79
 
97 pfowler 80
	/*
81
		PB0	- Output 		- Keypad 2
82
		PB1	- Output 		- Keypad 7
83
		PB2	- Output 		- Keypad 6
84
		PB3	- Output 		- Keypad 4
85
		PB4	- Input, Pullup		- Function select
86
		PB5	- Input, Pullup		- Function select
87
	*/
88
	DDRB		= 0B00001111;
89
	PORTB 	= 0B00111111;
33 pfowler 90
 
97 pfowler 91
	/*
92
		PD0	- Input, Pullup, PCINT16	- Rotary 1a
93
		PD1	- Input, Pullup, PCINT17	- Rotary 1b
33 pfowler 94
 
95
 
97 pfowler 96
		PD4	- Output		- Keypad select status led
97
		PD5	- Input, Pullup		- Keypad 3
98
		PD6	- Input, Pullup		- Keypad 1
99
		PD7	- Input, Pullup		- Keypad 5
100
	*/
101
	DDRD		= 0B00010000;
102
	PORTD		= 0B11110011;
33 pfowler 103
 
97 pfowler 104
	PCMSK2 |= (( 1 << PCINT16 ) | ( 1 << PCINT17 )); //enable encoder pins interrupt sources
98 pfowler 105
	PCICR |= ( 1 << PCIE2 ); //enable pin change interrupts
106
 
107
	analogInit();
108
	sysclockInit();
109
 
110
	reportKeyboard.report_id = 1;
111
	reportJoystick.report_id = 2;	
112
 
97 pfowler 113
	usbDeviceDisconnect();  /* enforce re-enumeration, do this while interrupts are disabled! */
114
	_delay_ms(500);
115
	usbDeviceConnect();
33 pfowler 116
 
99 pfowler 117
	sei();
97 pfowler 118
	wdt_enable(WDTO_1S);
119
	usbInit();
63 pfowler 120
 
40 pfowler 121
	i2c_master();
63 pfowler 122
	lcd_init();
98 pfowler 123
	lcd_createChar(0x00, lcdRectangle);
40 pfowler 124
 
63 pfowler 125
	char strTime[] = {'T', 'i', 'm', 'e', ':', 0x00};
97 pfowler 126
	lcd_setCursor(0, 1);
98 pfowler 127
	lcd_print(strTime);
99 pfowler 128
 
129
	buttons[0].detected = 0;
130
	buttons[0].timer = 0;
131
	buttons[0].waitup = 0;
132
 
133
	cbi(PORTD, 4);
98 pfowler 134
 
135
}
33 pfowler 136
 
98 pfowler 137
void loop() {
99 pfowler 138
 
100 pfowler 139
   	usbPoll();
140
 
141
	if (lcdtimer==0) {
142
		lcdtimer = 100;
143
		updateLcd();
144
	}
145
 
146
 
98 pfowler 147
	if(usbInterruptIsReady()){
148
	    reportJoystick.data1[0] = (-128 + analogRead(0));
149
	    reportJoystick.data1[1] = (-128 + analogRead(1));
150
	    reportJoystick.data2 = 0x0000;				// Clear all the buttons
33 pfowler 151
 
98 pfowler 152
	    reportKeyboard.modifier = 0x00;
153
	    reportKeyboard.keycode = 0x00;
39 pfowler 154
 
98 pfowler 155
	    uint8_t key = getKey();
156
	    if (rbi(keySelect, 0)) {
157
		    // Keypad is joystick
158
		    if (key > 0)
159
				reportJoystick.data2 |= (1 << (--key));
160
		    } else {
161
		    // Keypad is keyboard
162
		    if (key > 0) {
163
			    //if (key==10 || key==12) // Left shift, for *, #
164
			    //	reportKeyboard.modifier |= (1<<1);
165
			    reportKeyboard.keycode = keyMap[--key];
166
		    }
167
	    }
168
	    usbSendHidReport((uchar*)&reportKeyboard, sizeof(reportKeyboard));
169
	    usbSendHidReport((uchar*)&reportJoystick, sizeof(reportJoystick));
100 pfowler 170
    }	
33 pfowler 171
}
172
 
173
uint8_t getKey() {
174
	uint8_t col, row = 0;
175
	uint8_t key = 0;
176
	uint8_t n = 1;
177
 
178
	for (row=0; row<=3; row++) {
179
		cbi(PORTB, row);
180
		_delay_us(10);				// Wait for the port to change
181
 
182
		for (col=5; col<=7; col++) {
183
			if (rbi(PIND, col) == 0)
98 pfowler 184
			key = n;
33 pfowler 185
			n++;
98 pfowler 186
		}
33 pfowler 187
 
188
		sbi(PORTB, row);
189
	}
190
	return key;
191
}
192
 
100 pfowler 193
void updateLcd() {
194
	usbPoll();
195
 
196
 
197
	char syschar[10];
198
	ultoa(systime, syschar, 10);
199
	lcd_overprint_right(syschar, 10, 5, 1);
200
 
201
	uint8_t potVal = map_8(analogRead(0), 0, 255, 0, 100);
202
	if (potVal != oldpotVal) {
203
		lcd_percent_graph(potVal, 0, 0);
204
		oldpotVal = potVal;
205
 
206
		char pot[3];
207
		utoa(potVal, pot, 10);
208
		lcd_overprint_right(pot, 3, 11, 0);
209
 
210
		// Set percentage
211
		lcd_setCursor(15, 0);
212
		lcd_char(0x25);
213
	}
214
 
215
	lcdtimer = 100;
216
}
217
 
97 pfowler 218
void millis_tick() {
219
	if (buttons[0].detected && buttons[0].timer)
220
		buttons[0].timer--;
98 pfowler 221
 
97 pfowler 222
}
223
 
33 pfowler 224
ISR(TIMER0_OVF_vect) {
63 pfowler 225
	tmr0_ovf++;
99 pfowler 226
	if (tmr0_ovf >= sys_ovf_tick) {
63 pfowler 227
		systime++;
228
		tmr0_ovf = 0;
99 pfowler 229
		//millis_tick();	// Not working, taking too long to call?
230
 
231
		if (buttons[0].detected && buttons[0].timer)
232
			buttons[0].timer--;
100 pfowler 233
 
234
		if (lcdtimer)
235
			lcdtimer--;
63 pfowler 236
	}
33 pfowler 237
}
98 pfowler 238
void usbSendHidReport(uchar * data, uchar len) {
239
	while(1)
240
	{
241
		usbPoll();
242
		if (usbInterruptIsReady())
243
		{
244
			usbSetInterrupt(data, len);
245
			break;
246
		}
247
	}
33 pfowler 248
}
249
 
98 pfowler 250
usbMsgLen_t usbFunctionSetup(uchar data[8]) {
251
	usbRequest_t *rq = (void *)data;
33 pfowler 252
 
98 pfowler 253
	if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) {
254
		switch (rq->bRequest) {
255
			case USBRQ_HID_GET_REPORT:
100 pfowler 256
				if (rq->wValue.bytes[0] == 1)
257
					return sizeof(reportKeyboard);
258
				else if (rq->wValue.bytes[0] == 2)
259
					return sizeof(reportJoystick);
260
				else
261
					return 0;
98 pfowler 262
			case USBRQ_HID_GET_IDLE:
100 pfowler 263
				usbMsgPtr = &idleRate;
98 pfowler 264
			return 1;
265
 
266
 
267
 
268
			default:
269
			return 0;
270
		}
271
	}
272
	return 0;
62 pfowler 273
}
274
 
98 pfowler 275
void hadUsbReset(void) {
99 pfowler 276
}