Subversion Repositories group.NITPanels

Rev

Rev 10 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 10 Rev 26
Line 8... Line 8...
8
#include "config.h"
8
#include "config.h"
9
#include "avrutil.h"
9
#include "avrutil.h"
10
#include "usbdrv.h"
10
#include "usbdrv.h"
11
#include "i2cbb.h"
11
#include "i2cbb.h"
12
 
12
 
13
#define HW_VERSION 0x01
-
 
14
#define SW_VERSION 0x01
-
 
15
 
-
 
16
#ifndef NULL
13
#ifndef NULL
17
#define NULL    ((void *)0)
14
#define NULL    ((void *)0)
18
#endif
15
#endif
19
 
16
 
-
 
17
 
20
#define DISPLAYS_ATTACHED 2
18
#define MAX_DISPLAYS 			4		// Address space for up to for displays
21
#define INPUT_REFRESH 50
19
#define INPUT_REFRESH 50
22
#define FULL_REFRESH  10
20
#define FULL_REFRESH  10
23
 
21
 
-
 
22
#define I2C_BASE_ADDR			0x26	// All display addresses start from here
-
 
23
 
24
#define I2C_GET_VERSION			0x01
24
#define I2C_GET_VERSION			0x01
25
#define I2C_SET_DEBUG			0x03
25
#define I2C_SET_DEBUG			0x03
26
#define I2C_SET_DIGITS			0x05
26
#define I2C_SET_DIGITS			0x05
27
#define I2C_SET_DECIMAL_PTS		0x08
27
#define I2C_SET_DECIMAL_PTS		0x08
28
#define I2C_RESET_ROTARY		0x09
28
#define I2C_RESET_ROTARY		0x09
29
#define I2C_GET_ROTARY_DATA 	0x0a
29
#define I2C_GET_OUTER_ROTARY 	0x0a
-
 
30
#define I2C_GET_INNER_ROTARY 	0x0b
30
#define I2C_GET_BUTTON_DATA 	0x0c
31
#define I2C_GET_BUTTON_DATA 	0x0c
-
 
32
#define I2C_GET_CONFIG_DATA 	0x0d
-
 
33
 
-
 
34
#define USB_GET_VERSION			01
-
 
35
#define USB_GET_DISPLAY_COUNT	10
-
 
36
#define USB_GET_DISPLAY_META	11
31
 
37
 
32
#define USB_GET_VERSION		01
-
 
33
#define USB_SET_LATCH			20
38
#define USB_SET_LATCH			20
34
#define USB_SET_DISPLAY1		21
39
#define USB_SET_DISPLAY_DIGIT	21
35
#define USB_SET_DISPLAY2		22
-
 
36
#define USB_SET_POINTS			23
40
#define USB_SET_POINTS			23
37
#define USB_GET_INPUT			30
41
#define USB_GET_INPUT			30
38
 
42
 
39
 
43
 
40
void usbEventResetReady(void);
44
void usbEventResetReady(void);
41
static void calibrateOscillator(void);
45
static void calibrateOscillator(void);
42
static void updateDecimals(uint8_t dis);
46
static void updateDecimals(uint8_t dis);
43
static void updateDisplay(uint8_t dis);
47
static void updateDisplay(uint8_t dis);
44
static void updateInput();
48
static void updateInput();
45
static void getDisplayVersion(uint8_t dis);
49
static uint16_t getDisplayVersion(uint8_t i2c_addr);
-
 
50
static uint8_t getDisplayConfigData(uint8_t i2c_addr);
46
 
51
 
47
struct display_type {
52
struct display_type {
48
	uint8_t address;
53
	uint8_t address;
-
 
54
	uint16_t version;	// HB = HW, LB = SW
-
 
55
	uint8_t config;		// State of the config settings
-
 
56
 
49
	uint8_t value[10];
57
	uint8_t value[10];
50
	uint16_t decpts;
58
	uint16_t decpts;
51
	uint16_t version;	// HB = HW, LB = SW
-
 
52
	// @TODO: Make refresh something to do with decpts
-
 
53
	uint8_t refresh;	// Decimal point refresh
59
	uint8_t decpts_refresh;	// Decimal point refresh
54
 
60
 
55
	int8_t rotary;		// State of the rotary encoder
61
	int8_t outer;		// State of the outer rotary encoder
-
 
62
	int8_t inner;		// State of the inner rotary encoder
56
	uint8_t buttons;	// State of the buttons
63
	uint8_t buttons;	// State of the buttons
-
 
64
 
57
} display[DISPLAYS_ATTACHED];
65
} display[MAX_DISPLAYS];
58
 
66
 
59
 
67
 
60
 
68
 
61
static uint8_t usbReplyBuf[8];
69
static uint8_t usbReplyBuf[8];
62
static uint8_t latchDisplay = 255;
70
static uint8_t latchDisplay = 255;
63
 
71
 
-
 
72
static uint8_t displays_attached = 0;
-
 
73
 
64
 
74
 
65
volatile uint8_t tmr0_ovf = 0;
75
volatile uint8_t tmr0_ovf = 0;
66
 
76
 
67
 
77
 
68
int main(void) {
78
int main(void) {
69
	// calibration value from last time
79
	// calibration value from last time
70
	uchar   calibrationValue;
80
	uchar   calibrationValue;
71
	calibrationValue = eeprom_read_byte(0);
81
	calibrationValue = eeprom_read_byte(EEPROM_USBVCALVAL);
72
	if(calibrationValue != 0xff){
82
	if(calibrationValue != 0xff){
73
		OSCCAL = calibrationValue;
83
		OSCCAL = calibrationValue;
74
	}
84
	}
75
 
85
 
76
	/*
86
	/*
77
		DDR : 1 = Output, 0 = Input
87
		DDR : 1 = Output, 0 = Input
78
		PORT: 1 = Pullup for Input, otherwise set output
88
		PORT: 1 = Pullup for Input, otherwise set output
79
		PIN : Read input pin
89
		PIN : Read input pin
80
 
90
 
81
		PB0	-
91
		PB0	-		- LED
82
		PB1	- 		- USB D- Low Speed
92
		PB1	- 		- USB D- Low Speed
83
		PB2	-		- USB D+
93
		PB2	-		- USB D+
84
		PB3	- 		- SCL i2c bb
94
		PB3	- 		- SCL i2c bb
85
		PB4	-		- SDA i2c bb
95
		PB4	-		- SDA i2c bb
86
		PB5	-
96
		PB5	-		- Reset
87
	*/
97
	*/
88
	DDRB          = 0B00000001;
98
	DDRB          = 0B00000001;
89
	PORTB         = 0B00000001;
99
	PORTB         = 0B00000001;
90
 
100
 
91
 
101
 
Line 99... Line 109...
99
 
109
 
100
    wdt_enable(WDTO_1S);
110
    wdt_enable(WDTO_1S);
101
    usbInit();
111
    usbInit();
102
    sei();
112
    sei();
103
 
113
 
104
 
-
 
105
    // Setup the display data, blank each display
-
 
106
    uint8_t i;
114
    uint8_t i;
107
    for (i=0; i<DISPLAYS_ATTACHED; i++) {
115
    for (i=0; i<MAX_DISPLAYS; i++) {
-
 
116
    	if (i2cbb_Sniff(I2C_BASE_ADDR + i))
-
 
117
    		continue;
-
 
118
 
-
 
119
    	displays_attached++;
-
 
120
 
108
    	display[i].address = 0x26 + i;
121
    	display[i].address = I2C_BASE_ADDR + i;
109
    	display[i].decpts = 0x0000;
122
		display[i].decpts = 0x0000;
110
    	display[i].refresh = 0;
123
		display[i].decpts_refresh = 0;
111
 
124
 
112
    	uint8_t j;
125
		uint8_t j;
113
    	for (j=0; j<10; j++)
126
		for (j=0; j<10; j++)
114
    		display[i].value[j] = 0x0a;
127
			display[i].value[j] = 0x01;
115
    	updateDisplay(i);
128
		updateDisplay(i);
-
 
129
 
-
 
130
		display[i].version = getDisplayVersion(display[i].address);
-
 
131
 
-
 
132
		// Only get the config if version >= 0x02xx
-
 
133
		if (display[i].version > 0x0200)
-
 
134
			display[i].config = getDisplayConfigData(display[i].address);
-
 
135
		else
-
 
136
			display[i].config = 0x00;
116
 
137
 
117
    	getDisplayVersion(i);
-
 
118
    }
138
    }
119
 
139
 
120
    for(;;){
140
    for(;;){
121
    	 wdt_reset();
141
    	 wdt_reset();
122
    	 usbPoll();
142
    	 usbPoll();
123
 
143
 
124
    	// Latch requests from the the USB host
144
    	// Latch requests from the the USB host
-
 
145
 
125
    	if (latchDisplay != 255) {
146
    	if (latchDisplay != 255) {
126
    		updateDisplay(latchDisplay);
147
    		updateDisplay(latchDisplay);
127
    		latchDisplay = 255;
148
    		latchDisplay = 255;
128
    	}
149
    	}
129
 
150
 
130
    	for (i=0; i<DISPLAYS_ATTACHED; i++) {
151
    	for (i=0; i<displays_attached; i++) {
131
    		if (display[i].refresh) {
152
    		if (display[i].decpts_refresh) {
132
    			updateDecimals(i);
153
    			updateDecimals(i);
133
				display[i].refresh = 0;
154
				display[i].decpts_refresh = 0;
134
    		}
155
    		}
135
 
156
 
136
    	}
157
    	}
137
 
158
 
138
    	// Refresh time for getting user input data
159
    	// Refresh time for getting user input data
Line 142... Line 163...
142
		}
163
		}
143
    }
164
    }
144
    return 0;
165
    return 0;
145
}
166
}
146
 
167
 
147
static void getDisplayVersion(uint8_t dis) {
168
static uint16_t getDisplayVersion(uint8_t i2c_addr) {
148
	uint8_t hw = 0x00;
169
	uint8_t hw = 0x00;
149
	uint8_t sw = 0x00;
170
	uint8_t sw = 0x00;
150
 
171
 
151
	i2cbb_Init();
172
	i2cbb_Init();
152
	i2cbb_Start();
173
	i2cbb_Start();
153
	i2cbb_Write( display[dis].address << 1 );
174
	i2cbb_Write( i2c_addr << 1 );
154
	i2cbb_Write( I2C_GET_VERSION );
175
	i2cbb_Write( I2C_GET_VERSION );
155
	i2cbb_Stop();
176
	i2cbb_Stop();
156
 
177
 
-
 
178
 
157
	i2cbb_Start();
179
	i2cbb_Start();
158
	i2cbb_Write( (display[dis].address << 1) + 1 );
180
	i2cbb_Write( (i2c_addr << 1) + 1 );
159
	hw += (int8_t)i2cbb_Read(1);
181
	hw += (int8_t)i2cbb_Read(1);
160
	sw += (int8_t)i2cbb_Read(1);
182
	sw += (int8_t)i2cbb_Read(1);
161
	i2cbb_Stop();
183
	i2cbb_Stop();
162
 
184
 
163
	display[dis].version = ((uint16_t)hw << 8) | ((uint16_t)sw);
185
	return ((uint16_t)hw << 8) | ((uint16_t)sw);
-
 
186
}
-
 
187
 
-
 
188
static uint8_t getDisplayConfigData(uint8_t i2c_addr) {
-
 
189
	uint8_t config = 0;
-
 
190
	// Request the button data
-
 
191
	i2cbb_Init();
-
 
192
	i2cbb_Start();
-
 
193
	i2cbb_Write( i2c_addr << 1 );
-
 
194
	i2cbb_Write( I2C_GET_CONFIG_DATA );
-
 
195
	i2cbb_Stop();
-
 
196
 
-
 
197
	// Receive the button data
-
 
198
	i2cbb_Start();
-
 
199
	i2cbb_Write( (i2c_addr << 1) + 1 );
-
 
200
	config = i2cbb_Read(1);
-
 
201
	i2cbb_Stop();
-
 
202
 
-
 
203
	return config;
164
}
204
}
165
 
205
 
166
// Get the user input data from each display board
206
// Get the user input data from each display board
-
 
207
// @TODO: Changes to display board are needed to reduce
-
 
208
//			the amount of i2c calls neede to retrieve all
-
 
209
//			the button data. One i2c command should be able
-
 
210
// 			to do all of this
167
static void updateInput() {
211
static void updateInput() {
168
	uint8_t i;
212
	uint8_t i;
169
	for (i = 0; i < DISPLAYS_ATTACHED; i++) {
213
	for (i = 0; i < displays_attached; i++) {
-
 
214
 
-
 
215
		// Only check the inner rotary if HW version > 2 and
-
 
216
		//  the config tells us this is a PRO model
-
 
217
		if (display[i].version >= 0x200 &&
-
 
218
				rbi(display[i].config, 0)) {
-
 
219
			// Request for the inner rotary data
-
 
220
			i2cbb_Init();
-
 
221
			i2cbb_Start();
-
 
222
			i2cbb_Write( display[i].address << 1 );
-
 
223
			i2cbb_Write( I2C_GET_INNER_ROTARY );
-
 
224
			i2cbb_Stop();
-
 
225
 
-
 
226
			// Receive inner rotary data
-
 
227
			i2cbb_Start();
-
 
228
			i2cbb_Write( (display[i].address << 1) + 1 );
-
 
229
			display[i].inner += (int8_t)i2cbb_Read(1);
-
 
230
			i2cbb_Stop();
-
 
231
		} else {
-
 
232
			display[i].inner = 0x00;
-
 
233
		}
-
 
234
 
170
		// Request for the rotary data
235
		// Request for the outer rotary data
171
		i2cbb_Init();
236
		i2cbb_Init();
172
		i2cbb_Start();
237
		i2cbb_Start();
173
		i2cbb_Write( display[i].address << 1 );
238
		i2cbb_Write( display[i].address << 1 );
174
		i2cbb_Write( I2C_GET_ROTARY_DATA );
239
		i2cbb_Write( I2C_GET_OUTER_ROTARY );
175
		i2cbb_Stop();
240
		i2cbb_Stop();
176
 
241
 
177
		// Receive rotary data
242
		// Receive outer rotary data
178
		i2cbb_Start();
243
		i2cbb_Start();
179
		i2cbb_Write( (display[i].address << 1) + 1 );
244
		i2cbb_Write( (display[i].address << 1) + 1 );
180
		display[i].rotary += (int8_t)i2cbb_Read(1);
245
		display[i].outer += (int8_t)i2cbb_Read(1);
181
		i2cbb_Stop();
246
		i2cbb_Stop();
182
 
247
 
183
		// Reset the rotary on display board
248
		// Reset the rotary on display board
184
		i2cbb_Init();
249
		i2cbb_Init();
185
		i2cbb_Start();
250
		i2cbb_Start();
Line 211... Line 276...
211
	i2cbb_Write((uint8_t)(display[dis].decpts>>8));
276
	i2cbb_Write((uint8_t)(display[dis].decpts>>8));
212
	i2cbb_Write((uint8_t)display[dis].decpts);
277
	i2cbb_Write((uint8_t)display[dis].decpts);
213
	i2cbb_Stop();
278
	i2cbb_Stop();
214
}
279
}
215
 
280
 
216
// The the display digit display buffer to the board
-
 
217
// We can select which display to update as this can
281
// We can select which display to update as this can
218
//  get slow if updates are being done all the time,
282
//  get slow if updates are being done all the time,
219
//  which might affect the user input data tasks
283
//  which might affect the user input data tasks
220
static void updateDisplay(uint8_t dis) {
284
static void updateDisplay(uint8_t dis) {
221
    // Send the display buffer to display board
285
    // Send the display buffer to display board
Line 251... Line 315...
251
    usbRequest_t    *rq = (void *)data;
315
    usbRequest_t    *rq = (void *)data;
252
 
316
 
253
	switch (rq->bRequest ) {
317
	switch (rq->bRequest ) {
254
		// Request for a display boards digits to be updated
318
		// Request for a display boards digits to be updated
255
		case USB_SET_LATCH: {
319
		case USB_SET_LATCH: {
256
			latchDisplay = rq->wValue.bytes[0];;
320
			latchDisplay = rq->wValue.bytes[0];
257
			break;
321
			break;
258
		}
322
		}
259
 
323
 
260
		case USB_SET_POINTS: {
324
		case USB_SET_POINTS: {
261
			if (display[0].decpts != rq->wValue.word) {
325
			if (display[0].decpts != rq->wValue.word) {
262
				display[0].refresh = 1;
326
				display[0].decpts_refresh = 1;
263
				display[0].decpts = rq->wValue.word;
327
				display[0].decpts = rq->wValue.word;
264
			}
328
			}
265
 
329
 
266
			if (display[1].decpts != rq->wIndex.word) {
330
			if (display[1].decpts != rq->wIndex.word) {
267
				display[1].refresh = 1;
331
				display[1].decpts_refresh = 1;
268
				display[1].decpts = rq->wIndex.word;
332
				display[1].decpts = rq->wIndex.word;
269
			}
333
			}
270
		}
334
		}
271
 
335
 
272
		// Sets the display boards digit buffer. Only on display
336
		// Sets the display boards digit buffer. Only on display
273
		//  board is updated per request. Also does decimal points
337
		//  board is updated per request. Also does decimal points
274
		case USB_SET_DISPLAY1: {
338
		case USB_SET_DISPLAY_DIGIT: {
275
			uint8_t dis = rq->wValue.bytes[1];
339
			uint8_t dis = rq->wValue.bytes[1];
276
			uint8_t dig = rq->wValue.bytes[0];
340
			uint8_t dig = rq->wValue.bytes[0];
277
			uint8_t val = rq->wIndex.bytes[0];
341
			uint8_t val = rq->wIndex.bytes[0];
278
 
342
 
279
			if ((display[dis].value[dig] & 0x0f) != val) {
343
			if ((display[dis].value[dig] & 0x0f) != val) {
Line 284... Line 348...
284
		}
348
		}
285
 
349
 
286
		// Return the user input data all at once. Its populated from
350
		// Return the user input data all at once. Its populated from
287
		//  buffered data from the updateInput() function.
351
		//  buffered data from the updateInput() function.
288
		case USB_GET_INPUT: {
352
		case USB_GET_INPUT: {
289
			uint8_t i;
-
 
290
			for (i=0; i<DISPLAYS_ATTACHED; i++) {
353
			uint8_t disnum = rq->wValue.bytes[0];
-
 
354
 
291
				usbReplyBuf[(i*2)] = display[i].buttons;
355
			usbReplyBuf[0] = display[disnum].buttons;
292
				usbReplyBuf[(i*2+1)] = display[i].rotary;
356
			usbReplyBuf[1] = display[disnum].outer;
293
				display[i].rotary = 0;
357
			usbReplyBuf[2] = display[disnum].inner;
294
			}
358
 
295
			usbMsgPtr = usbReplyBuf;
359
			usbMsgPtr = usbReplyBuf;
296
			return sizeof(usbReplyBuf);
360
			return sizeof(usbReplyBuf);
297
			break;
361
			break;
298
		}
362
		}
299
 
363
 
300
		// Return the version numbers for the controller board
364
		// Return the version numbers for the controller board
301
		//  and for all attached display boards.
365
		//  and for all attached display boards.
302
		case USB_GET_VERSION: {
366
		case USB_GET_VERSION: {
303
			usbReplyBuf[0] = HW_VERSION;
367
			usbReplyBuf[0] = HW_VERSION;
304
			usbReplyBuf[1] = SW_VERSION;
368
			usbReplyBuf[1] = SW_VERSION;
305
			uint8_t i;
369
			//uint8_t i;
306
			for (i=0; i<DISPLAYS_ATTACHED; i++) {
370
			//for (i=0; i<displays_attached; i++) {
307
				usbReplyBuf[2+(i*2)] = (uint8_t)(display[i].version >> 8);
371
			//	usbReplyBuf[2+(i*2)] = (uint8_t)(display[i].version >> 8);
308
				usbReplyBuf[2+(i*2)+1] = (uint8_t)(display[i].version && 0xff);
372
			//	usbReplyBuf[2+(i*2)+1] = (uint8_t)(display[i].version && 0xff);
-
 
373
			//}
-
 
374
			usbMsgPtr = usbReplyBuf;
-
 
375
			return sizeof(usbReplyBuf);
-
 
376
			break;
-
 
377
		}
-
 
378
 
-
 
379
		case USB_GET_DISPLAY_COUNT: {
-
 
380
			usbReplyBuf[0] = displays_attached;
-
 
381
			usbMsgPtr = usbReplyBuf;
-
 
382
			return sizeof(usbReplyBuf);
-
 
383
			break;
309
			}
384
		}
-
 
385
 
-
 
386
		case USB_GET_DISPLAY_META: {
-
 
387
			uint8_t disnum = rq->wValue.bytes[0];
-
 
388
			usbReplyBuf[0] = (uint8_t)(display[disnum].version >> 8);
-
 
389
			usbReplyBuf[1] = (uint8_t)(display[disnum].version  & 0xff);
-
 
390
			usbReplyBuf[2] = display[disnum].address;
-
 
391
			usbReplyBuf[3] = display[disnum].config;
310
			usbMsgPtr = usbReplyBuf;
392
			usbMsgPtr = usbReplyBuf;
311
			return sizeof(usbReplyBuf);
393
			return sizeof(usbReplyBuf);
312
			break;
394
			break;
313
		}
395
		}
314
 
396