Subversion Repositories svnkaklik

Rev

Go to most recent revision | Details | Last modification | View Log

Rev Author Line No. Line
151 kaklik 1
 
2
AVRcam.elf:     file format elf32-avr
3
 
4
Sections:
5
Idx Name          Size      VMA       LMA       File off  Algn
6
 
7
                  ALLOC
8
  1 .bss          00000274  00800070  00800070  00001162  2**0
9
                  ALLOC
10
  2 .data         00000010  00800060  0000109e  00001152  2**0
11
                  CONTENTS, ALLOC, LOAD, DATA
12
  3 .text         0000109e  00000000  00000000  000000b4  2**1
13
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
14
  4 .eeprom       00000000  00810000  00810000  00001162  2**0
15
                  CONTENTS
16
  5 .stab         00003f30  00000000  00000000  00001164  2**2
17
                  CONTENTS, READONLY, DEBUGGING
18
  6 .stabstr      0000181e  00000000  00000000  00005094  2**0
19
                  CONTENTS, READONLY, DEBUGGING
20
Disassembly of section .text:
21
 
22
00000000 <__vectors>:
23
       0:	63 c0       	rjmp	.+198    	; 0xc8
24
       2:	ea c7       	rjmp	.+4052   	; 0xfd8
25
       4:	ea c7       	rjmp	.+4052   	; 0xfda
26
       6:	7a c0       	rjmp	.+244    	; 0xfc
27
       8:	79 c0       	rjmp	.+242    	; 0xfc
28
       a:	78 c0       	rjmp	.+240    	; 0xfc
29
       c:	77 c0       	rjmp	.+238    	; 0xfc
30
       e:	76 c0       	rjmp	.+236    	; 0xfc
31
      10:	e5 c7       	rjmp	.+4042   	; 0xfdc
32
      12:	74 c0       	rjmp	.+232    	; 0xfc
33
      14:	73 c0       	rjmp	.+230    	; 0xfc
34
      16:	a8 c5       	rjmp	.+2896   	; 0xb68
35
      18:	71 c0       	rjmp	.+226    	; 0xfc
36
      1a:	70 c0       	rjmp	.+224    	; 0xfc
37
      1c:	6f c0       	rjmp	.+222    	; 0xfc
38
      1e:	6e c0       	rjmp	.+220    	; 0xfc
39
      20:	6d c0       	rjmp	.+218    	; 0xfc
40
      22:	13 c6       	rjmp	.+3110   	; 0xc4a
41
      24:	6b c0       	rjmp	.+214    	; 0xfc
42
 
43
00000026 <__ctors_end>:
44
      26:	2a c6       	rjmp	.+3156   	; 0xc7c
45
      28:	93 c6       	rjmp	.+3366   	; 0xd50
46
      2a:	92 c6       	rjmp	.+3364   	; 0xd50
47
      2c:	91 c6       	rjmp	.+3362   	; 0xd50
48
      2e:	90 c6       	rjmp	.+3360   	; 0xd50
49
      30:	8f c6       	rjmp	.+3358   	; 0xd50
50
      32:	8e c6       	rjmp	.+3356   	; 0xd50
51
      34:	8d c6       	rjmp	.+3354   	; 0xd50
52
      36:	22 c6       	rjmp	.+3140   	; 0xc7c
53
      38:	8b c6       	rjmp	.+3350   	; 0xd50
54
      3a:	8a c6       	rjmp	.+3348   	; 0xd50
55
      3c:	89 c6       	rjmp	.+3346   	; 0xd50
56
      3e:	88 c6       	rjmp	.+3344   	; 0xd50
57
      40:	87 c6       	rjmp	.+3342   	; 0xd50
58
      42:	86 c6       	rjmp	.+3340   	; 0xd50
59
      44:	85 c6       	rjmp	.+3338   	; 0xd50
60
      46:	2a c6       	rjmp	.+3156   	; 0xc9c
61
      48:	83 c6       	rjmp	.+3334   	; 0xd50
62
      4a:	82 c6       	rjmp	.+3332   	; 0xd50
63
      4c:	81 c6       	rjmp	.+3330   	; 0xd50
64
      4e:	80 c6       	rjmp	.+3328   	; 0xd50
65
      50:	7f c6       	rjmp	.+3326   	; 0xd50
66
      52:	7e c6       	rjmp	.+3324   	; 0xd50
67
      54:	7d c6       	rjmp	.+3322   	; 0xd50
68
      56:	25 c6       	rjmp	.+3146   	; 0xca2
69
      58:	7b c6       	rjmp	.+3318   	; 0xd50
70
      5a:	7a c6       	rjmp	.+3316   	; 0xd50
71
      5c:	79 c6       	rjmp	.+3314   	; 0xd50
72
      5e:	78 c6       	rjmp	.+3312   	; 0xd50
73
      60:	77 c6       	rjmp	.+3310   	; 0xd50
74
      62:	76 c6       	rjmp	.+3308   	; 0xd50
75
      64:	75 c6       	rjmp	.+3306   	; 0xd50
76
      66:	25 c6       	rjmp	.+3146   	; 0xcb2
77
      68:	73 c6       	rjmp	.+3302   	; 0xd50
78
      6a:	72 c6       	rjmp	.+3300   	; 0xd50
79
      6c:	71 c6       	rjmp	.+3298   	; 0xd50
80
      6e:	70 c6       	rjmp	.+3296   	; 0xd50
81
      70:	6f c6       	rjmp	.+3294   	; 0xd50
82
      72:	6e c6       	rjmp	.+3292   	; 0xd50
83
      74:	6d c6       	rjmp	.+3290   	; 0xd50
84
      76:	64 c6       	rjmp	.+3272   	; 0xd40
85
      78:	6b c6       	rjmp	.+3286   	; 0xd50
86
      7a:	6a c6       	rjmp	.+3284   	; 0xd50
87
      7c:	69 c6       	rjmp	.+3282   	; 0xd50
88
      7e:	68 c6       	rjmp	.+3280   	; 0xd50
89
      80:	67 c6       	rjmp	.+3278   	; 0xd50
90
      82:	66 c6       	rjmp	.+3276   	; 0xd50
91
      84:	65 c6       	rjmp	.+3274   	; 0xd50
92
      86:	64 c6       	rjmp	.+3272   	; 0xd50
93
      88:	63 c6       	rjmp	.+3270   	; 0xd50
94
      8a:	62 c6       	rjmp	.+3268   	; 0xd50
95
      8c:	61 c6       	rjmp	.+3266   	; 0xd50
96
      8e:	60 c6       	rjmp	.+3264   	; 0xd50
97
      90:	5f c6       	rjmp	.+3262   	; 0xd50
98
      92:	5e c6       	rjmp	.+3260   	; 0xd50
99
      94:	5d c6       	rjmp	.+3258   	; 0xd50
100
      96:	23 c6       	rjmp	.+3142   	; 0xcde
101
      98:	5b c6       	rjmp	.+3254   	; 0xd50
102
      9a:	5a c6       	rjmp	.+3252   	; 0xd50
103
      9c:	59 c6       	rjmp	.+3250   	; 0xd50
104
      9e:	58 c6       	rjmp	.+3248   	; 0xd50
105
      a0:	57 c6       	rjmp	.+3246   	; 0xd50
106
      a2:	56 c6       	rjmp	.+3244   	; 0xd50
107
      a4:	55 c6       	rjmp	.+3242   	; 0xd50
108
      a6:	fd c5       	rjmp	.+3066   	; 0xca2
109
      a8:	53 c6       	rjmp	.+3238   	; 0xd50
110
      aa:	52 c6       	rjmp	.+3236   	; 0xd50
111
      ac:	51 c6       	rjmp	.+3234   	; 0xd50
112
      ae:	50 c6       	rjmp	.+3232   	; 0xd50
113
      b0:	4f c6       	rjmp	.+3230   	; 0xd50
114
      b2:	4e c6       	rjmp	.+3228   	; 0xd50
115
      b4:	4d c6       	rjmp	.+3226   	; 0xd50
116
      b6:	1f c6       	rjmp	.+3134   	; 0xcf6
117
      b8:	4b c6       	rjmp	.+3222   	; 0xd50
118
      ba:	4a c6       	rjmp	.+3220   	; 0xd50
119
      bc:	49 c6       	rjmp	.+3218   	; 0xd50
120
      be:	48 c6       	rjmp	.+3216   	; 0xd50
121
      c0:	47 c6       	rjmp	.+3214   	; 0xd50
122
      c2:	46 c6       	rjmp	.+3212   	; 0xd50
123
      c4:	45 c6       	rjmp	.+3210   	; 0xd50
124
      c6:	36 c6       	rjmp	.+3180   	; 0xd34
125
 
126
000000c8 <__init>:
127
      c8:	11 24       	eor	r1, r1
128
      ca:	1f be       	out	0x3f, r1	; 63
129
      cc:	cf e5       	ldi	r28, 0x5F	; 95
130
      ce:	d4 e0       	ldi	r29, 0x04	; 4
131
      d0:	de bf       	out	0x3e, r29	; 62
132
      d2:	cd bf       	out	0x3d, r28	; 61
133
 
134
000000d4 <__do_copy_data>:
135
      d4:	10 e0       	ldi	r17, 0x00	; 0
136
      d6:	a0 e6       	ldi	r26, 0x60	; 96
137
      d8:	b0 e0       	ldi	r27, 0x00	; 0
138
      da:	ee e9       	ldi	r30, 0x9E	; 158
139
      dc:	f0 e1       	ldi	r31, 0x10	; 16
140
      de:	02 c0       	rjmp	.+4      	; 0xe4
141
 
142
000000e0 <.do_copy_data_loop>:
143
      e0:	05 90       	lpm	r0, Z+
144
      e2:	0d 92       	st	X+, r0
145
 
146
000000e4 <.do_copy_data_start>:
147
      e4:	a0 37       	cpi	r26, 0x70	; 112
148
      e6:	b1 07       	cpc	r27, r17
149
      e8:	d9 f7       	brne	.-10     	; 0xe0
150
 
151
000000ea <__do_clear_bss>:
152
      ea:	12 e0       	ldi	r17, 0x02	; 2
153
      ec:	a0 e7       	ldi	r26, 0x70	; 112
154
      ee:	b0 e0       	ldi	r27, 0x00	; 0
155
      f0:	01 c0       	rjmp	.+2      	; 0xf4
156
 
157
000000f2 <.do_clear_bss_loop>:
158
      f2:	1d 92       	st	X+, r1
159
 
160
000000f4 <.do_clear_bss_start>:
161
      f4:	a4 3e       	cpi	r26, 0xE4	; 228
162
      f6:	b1 07       	cpc	r27, r17
163
      f8:	e1 f7       	brne	.-8      	; 0xf2
164
      fa:	31 c0       	rjmp	.+98     	; 0x15e
165
 
166
000000fc <__bad_interrupt>:
167
      fc:	76 c7       	rjmp	.+3820   	; 0xfea
168
 
169
000000fe <CamInt_init>:
170
#endif    
171
 
172
	/* set up the mega8 ports that will be interfacing
173
	with the camera */	
174
	CAM_CONTROL_PORT_DIR |= (1<<CAM_RESET_LINE); /* cam reset is output */
175
      fe:	8f 9a       	sbi	0x11, 7	; 17
176
	CAM_CONTROL_PORT_DIR |= 0x80;   /* set just the MSB as an output */
177
     100:	8f 9a       	sbi	0x11, 7	; 17
178
	CAM_CONTROL_PORT_DIR &= 0xFB;   /* make sure bit2 is clear (input) */
179
     102:	8a 98       	cbi	0x11, 2	; 17
180
	CAM_CONTROL_PORT &= 0x7F;   /* set reset line low */
181
     104:	97 98       	cbi	0x12, 7	; 18
182
	CAM_G_BUS_DIR &= 0xF0;  /* 4-bit G bus all inputs */
183
     106:	90 ef       	ldi	r25, 0xF0	; 240
184
     108:	87 b3       	in	r24, 0x17	; 23
185
     10a:	89 23       	and	r24, r25
186
     10c:	87 bb       	out	0x17, r24	; 23
187
    CAM_G_BUS_DIR |= 0xF0;  /* disable the pull-up on PB4 and PB5 */
188
     10e:	87 b3       	in	r24, 0x17	; 23
189
     110:	89 2b       	or	r24, r25
190
     112:	87 bb       	out	0x17, r24	; 23
191
	CAM_RB_BUS_DIR &= 0xF0;  /* 4-bit RB bus all inputs */
192
     114:	84 b3       	in	r24, 0x14	; 20
193
     116:	89 23       	and	r24, r25
194
     118:	84 bb       	out	0x14, r24	; 20
195
 
196
    /* ensure that timer1 is disabled to start...eventually, when PCLK needs
197
    to feed timer1 through the external counter, it will be enabled on an
198
    "as needed" basis...*/
199
	TCCR1B &= ~( (1<<CS12)|(1<<CS11)|(1<<CS10) );
200
     11a:	8e b5       	in	r24, 0x2e	; 46
201
     11c:	88 7f       	andi	r24, 0xF8	; 248
202
     11e:	8e bd       	out	0x2e, r24	; 46
203
 
204
	/* we'll turn on the interrupt after we assign the initial TCNT value */
205
 
206
	/* set up External Interrupt1 to interrupt us on rising edges (HREF)...
207
	this is needed to indicate when the first pixel of each line is about to start, so
208
	we can synch up with it...this interrupt will be disabled once HREF goes high */
209
 
210
	MCUCR |= (1<<ISC11) | (1<<ISC10);  /* rising edge interrupt */
211
     120:	85 b7       	in	r24, 0x35	; 53
212
     122:	8c 60       	ori	r24, 0x0C	; 12
213
     124:	85 bf       	out	0x35, r24	; 53
214
	/* the interrupt will be enabled when we are ready to detect the rising edge of
215
	HREF...its now primed and ready to go */
216
 
217
	/* set up External Interrupt0 to interrupt us on rising edges (VSYNC) */
218
	MCUCR |= (1<<ISC01) | (1<<ISC00);	/* rising edge interrupt */ 
219
     126:	85 b7       	in	r24, 0x35	; 53
220
     128:	83 60       	ori	r24, 0x03	; 3
221
     12a:	85 bf       	out	0x35, r24	; 53
222
	GICR  |= (1<<INT0);    /* interrupt request enabled */
223
     12c:	8b b7       	in	r24, 0x3b	; 59
224
     12e:	80 64       	ori	r24, 0x40	; 64
225
     130:	8b bf       	out	0x3b, r24	; 59
226
 
227
	/* set up TimerO to count and be clocked from an external pulse source
228
	(HREF) on falling edges...eventually, we need to enable the interrupt
229
	for this!  FIX THIS */
230
	TCCR0 = (1<<CS02)|(1<<CS01)|(0<<CS00);
231
     132:	86 e0       	ldi	r24, 0x06	; 6
232
     134:	83 bf       	out	0x33, r24	; 51
233
 
234
	/* setting up the PCLK counter with Timer1 will be done right after
235
	we start receiving pixels in each line...we sacrifice the first pixel
236
	in each line, but we'll account for it...*/
237
 
238
	/* set up the mega8 so that its sleep mode puts it in an IDLE sleep
239
	mode, where it can wake up as fast as possible */
240
	set_sleep_mode(SLEEP_MODE_IDLE);
241
     136:	85 b7       	in	r24, 0x35	; 53
242
     138:	8f 78       	andi	r24, 0x8F	; 143
243
     13a:	85 bf       	out	0x35, r24	; 53
244
	/* umm....we need to actually enable the sleep mode...*/
245
	MCUCR |= 0x80;
246
     13c:	85 b7       	in	r24, 0x35	; 53
247
     13e:	80 68       	ori	r24, 0x80	; 128
248
     140:	85 bf       	out	0x35, r24	; 53
249
 
250
	/* initialize the memLookup table */
251
	memset(colorMap,0x00,NUM_ELEMENTS_IN_COLOR_MAP);   
252
     142:	80 e0       	ldi	r24, 0x00	; 0
253
     144:	93 e0       	ldi	r25, 0x03	; 3
254
     146:	20 e3       	ldi	r18, 0x30	; 48
255
     148:	fc 01       	movw	r30, r24
256
     14a:	11 92       	st	Z+, r1
257
     14c:	2a 95       	dec	r18
258
     14e:	e9 f7       	brne	.-6      	; 0x14a
259
 
260
	/* read the color map out of EEPROM */
261
	eeprom_read_block(colorMap, (unsigned char*)0x01,NUM_ELEMENTS_IN_COLOR_MAP);
262
     150:	40 e3       	ldi	r20, 0x30	; 48
263
     152:	50 e0       	ldi	r21, 0x00	; 0
264
     154:	61 e0       	ldi	r22, 0x01	; 1
265
     156:	70 e0       	ldi	r23, 0x00	; 0
266
     158:	7d d7       	rcall	.+3834   	; 0x1054
267
 
268
#if OUTPUT_INITIAL_COLOR_MAP    
269
    UIMgr_txBuffer("\r\n",2);
270
    for (i=0; i<NUM_ELEMENTS_IN_COLOR_MAP; i++)
271
	{
272
		memset(asciiBuffer,0x00,5);
273
		itoa(colorMap[i],asciiBuffer,10);
274
		UIMgr_txBuffer(asciiBuffer,3);
275
		UIMgr_txBuffer(" ",1);
276
		if (i==15 || i == 31)
277
		{
278
			/* break up the output */
279
			UIMgr_txBuffer("\r\n",2);
280
		}
281
	}
282
#endif    
283
 
284
#ifndef NO_CRYSTAL
285
	CamInt_resetCam();	
286
#endif    
287
}
288
     15a:	08 95       	ret
289
 
290
0000015c <CamInt_resetCam>:
291
 
292
/***********************************************************
293
	Function Name: CamInt_resetCam
294
	Function Description: This function is responsible
295
	for resetting the camera.  This is accomplished by
296
	toggling the reset line on the OV6620 for ~100 mS.
297
	Inputs:  none
298
	Outputs: none
299
    IMPORTANT NOTE: This function has effectively been removed
300
    since resetting the camera now causes the camera to not
301
    output the clock signal.  Thus, if we reset the cam, the
302
    AVR has no clock, and thus doesn't run...
303
***********************************************************/	
304
void CamInt_resetCam(void)
305
{
306
     15c:	08 95       	ret
307
 
308
0000015e <main>:
309
	Inputs:  none
310
	Outputs: int
311
***********************************************************/	
312
int main(void)
313
{
314
     15e:	cf e5       	ldi	r28, 0x5F	; 95
315
     160:	d4 e0       	ldi	r29, 0x04	; 4
316
     162:	de bf       	out	0x3e, r29	; 62
317
     164:	cd bf       	out	0x3d, r28	; 61
318
	/* initialize all of the interface modules */
319
	DebugInt_init();
320
     166:	aa d6       	rcall	.+3412   	; 0xebc
321
	UartInt_init();
322
     168:	f1 d4       	rcall	.+2530   	; 0xb4c
323
	I2CInt_init();
324
     16a:	2c d5       	rcall	.+2648   	; 0xbc4
325
	CamInt_init();
326
     16c:	c8 df       	rcall	.-112    	; 0xfe
327
 
328
	/* initialize the remaining modules that will process
329
	data...interrupts need to be on for these */
330
	ENABLE_INTS();
331
     16e:	78 94       	sei
332
	CamConfig_init(); 
333
     170:	fa d5       	rcall	.+3060   	; 0xd66
334
	UIMgr_init();
335
     172:	94 d2       	rcall	.+1320   	; 0x69c
336
	FrameMgr_init();
337
     174:	7f d0       	rcall	.+254    	; 0x274
338
 
339
	/* provide a short delay for the camera to stabilize before
340
	we let the executive start up */
341
	Utility_delay(1000);
342
     176:	88 ee       	ldi	r24, 0xE8	; 232
343
     178:	93 e0       	ldi	r25, 0x03	; 3
344
     17a:	65 d6       	rcall	.+3274   	; 0xe46
345
 
346
	/* the rest of the application will be under the
347
	control of the Executive.  */
348
	Exec_run();	
349
     17c:	03 d0       	rcall	.+6      	; 0x184
350
 
351
	/* this should never be reached */
352
	return(0);
353
}
354
     17e:	80 e0       	ldi	r24, 0x00	; 0
355
     180:	90 e0       	ldi	r25, 0x00	; 0
356
     182:	8c c7       	rjmp	.+3864   	; 0x109c
357
 
358
00000184 <Exec_run>:
359
	Inputs:  none
360
	Outputs: none
361
***********************************************************/	
362
void Exec_run(void)
363
{
364
     184:	cf 93       	push	r28
365
	unsigned char eventGenerated;
366
 
367
	while(1)
368
	{
369
		if (fastEventBitmask)
370
     186:	80 91 72 00 	lds	r24, 0x0072
371
     18a:	88 23       	and	r24, r24
372
     18c:	b9 f0       	breq	.+46     	; 0x1bc
373
		{
374
			/* an event needing fast processing has been received */
375
			/* a received line needs to be processed...this
376
			needs to be processed as quickly as possible */
377
			if (fastEventBitmask & FEV_ACQUIRE_LINE_COMPLETE)
378
     18e:	80 ff       	sbrs	r24, 0
379
     190:	09 c0       	rjmp	.+18     	; 0x1a4
380
			{
381
                DISABLE_INTS();
382
     192:	f8 94       	cli
383
				fastEventBitmask &= ~FEV_ACQUIRE_LINE_COMPLETE;	
384
     194:	80 91 72 00 	lds	r24, 0x0072
385
     198:	8e 7f       	andi	r24, 0xFE	; 254
386
     19a:	80 93 72 00 	sts	0x0072, r24
387
                ENABLE_INTS();
388
     19e:	78 94       	sei
389
				FrameMgr_processLine();				
390
     1a0:	f8 d0       	rcall	.+496    	; 0x392
391
 
392
				/* also check if serial data needs to be sent
393
				out through UIMgr */
394
				UIMgr_transmitPendingData();	
395
     1a2:	ac d2       	rcall	.+1368   	; 0x6fc
396
 
397
				/* we can't just call acquire line again here,
398
				since we don't know if we need to acquire another
399
				line or not (it depends on the FrameMgr to figure
400
				this out) */
401
			}
402
			if (fastEventBitmask & FEV_PROCESS_LINE_COMPLETE)
403
     1a4:	80 91 72 00 	lds	r24, 0x0072
404
     1a8:	81 ff       	sbrs	r24, 1
405
     1aa:	08 c0       	rjmp	.+16     	; 0x1bc
406
			{
407
                DISABLE_INTS();
408
     1ac:	f8 94       	cli
409
				fastEventBitmask &= ~FEV_PROCESS_LINE_COMPLETE;
410
     1ae:	80 91 72 00 	lds	r24, 0x0072
411
     1b2:	8d 7f       	andi	r24, 0xFD	; 253
412
     1b4:	80 93 72 00 	sts	0x0072, r24
413
                ENABLE_INTS();
414
     1b8:	78 94       	sei
415
				FrameMgr_acquireLine();
416
     1ba:	b9 d0       	rcall	.+370    	; 0x32e
417
			}
418
		}		
419
 
420
        if (IS_DATA_IN_EVENT_FIFO() == TRUE)		
421
     1bc:	90 91 70 00 	lds	r25, 0x0070
422
     1c0:	80 91 71 00 	lds	r24, 0x0071
423
     1c4:	98 17       	cp	r25, r24
424
     1c6:	f9 f2       	breq	.-66     	; 0x186
425
		{			
426
            eventGenerated = Exec_readEventFifo();
427
     1c8:	32 d0       	rcall	.+100    	; 0x22e
428
     1ca:	c8 2f       	mov	r28, r24
429
			switch(eventGenerated)
430
     1cc:	99 27       	eor	r25, r25
431
     1ce:	80 31       	cpi	r24, 0x10	; 16
432
     1d0:	91 05       	cpc	r25, r1
433
     1d2:	11 f1       	breq	.+68     	; 0x218
434
     1d4:	81 31       	cpi	r24, 0x11	; 17
435
     1d6:	91 05       	cpc	r25, r1
436
     1d8:	7c f4       	brge	.+30     	; 0x1f8
437
     1da:	82 30       	cpi	r24, 0x02	; 2
438
     1dc:	91 05       	cpc	r25, r1
439
     1de:	09 f1       	breq	.+66     	; 0x222
440
     1e0:	83 30       	cpi	r24, 0x03	; 3
441
     1e2:	91 05       	cpc	r25, r1
442
     1e4:	1c f4       	brge	.+6      	; 0x1ec
443
     1e6:	01 97       	sbiw	r24, 0x01	; 1
444
     1e8:	d1 f0       	breq	.+52     	; 0x21e
445
     1ea:	cd cf       	rjmp	.-102    	; 0x186
446
     1ec:	84 30       	cpi	r24, 0x04	; 4
447
     1ee:	91 05       	cpc	r25, r1
448
     1f0:	c1 f0       	breq	.+48     	; 0x222
449
     1f2:	08 97       	sbiw	r24, 0x08	; 8
450
     1f4:	b1 f0       	breq	.+44     	; 0x222
451
     1f6:	c7 cf       	rjmp	.-114    	; 0x186
452
     1f8:	80 38       	cpi	r24, 0x80	; 128
453
     1fa:	91 05       	cpc	r25, r1
454
     1fc:	91 f0       	breq	.+36     	; 0x222
455
     1fe:	81 38       	cpi	r24, 0x81	; 129
456
     200:	91 05       	cpc	r25, r1
457
     202:	1c f4       	brge	.+6      	; 0x20a
458
     204:	80 97       	sbiw	r24, 0x20	; 32
459
     206:	69 f0       	breq	.+26     	; 0x222
460
     208:	be cf       	rjmp	.-132    	; 0x186
461
     20a:	81 38       	cpi	r24, 0x81	; 129
462
     20c:	91 05       	cpc	r25, r1
463
     20e:	49 f0       	breq	.+18     	; 0x222
464
     210:	80 39       	cpi	r24, 0x90	; 144
465
     212:	91 05       	cpc	r25, r1
466
     214:	49 f0       	breq	.+18     	; 0x228
467
     216:	b7 cf       	rjmp	.-146    	; 0x186
468
			{
469
				case (EV_DUMP_FRAME):
470
					FrameMgr_dispatchEvent(eventGenerated);
471
					break;
472
 
473
				case (EV_ENABLE_TRACKING):
474
					FrameMgr_dispatchEvent(eventGenerated);
475
					break;
476
 
477
				case (EV_DISABLE_TRACKING):
478
					FrameMgr_dispatchEvent(eventGenerated);
479
					break;
480
 
481
				case (EV_ACQUIRE_LINE_COMPLETE):
482
					FrameMgr_dispatchEvent(eventGenerated);
483
     218:	8c 2f       	mov	r24, r28
484
     21a:	33 d0       	rcall	.+102    	; 0x282
485
					UIMgr_dispatchEvent(eventGenerated);
486
     21c:	05 c0       	rjmp	.+10     	; 0x228
487
					break;
488
 
489
				case (EV_ACQUIRE_FRAME_COMPLETE):				
490
					FrameMgr_dispatchEvent(eventGenerated);
491
					break;
492
 
493
				case (EV_PROCESS_LINE_COMPLETE):
494
					FrameMgr_dispatchEvent(eventGenerated);
495
					break;
496
 
497
				case (EV_PROCESS_FRAME_COMPLETE):
498
					FrameMgr_dispatchEvent(eventGenerated);
499
					break;
500
 
501
				case (EV_SERIAL_DATA_RECEIVED):
502
					UIMgr_dispatchEvent(eventGenerated);
503
     21e:	8c 2f       	mov	r24, r28
504
     220:	58 d2       	rcall	.+1200   	; 0x6d2
505
					FrameMgr_dispatchEvent(eventGenerated);
506
     222:	8c 2f       	mov	r24, r28
507
     224:	2e d0       	rcall	.+92     	; 0x282
508
					break;																
509
     226:	af cf       	rjmp	.-162    	; 0x186
510
 
511
				case (EV_SERIAL_DATA_PENDING_TX):
512
					UIMgr_dispatchEvent(eventGenerated);
513
     228:	8c 2f       	mov	r24, r28
514
     22a:	53 d2       	rcall	.+1190   	; 0x6d2
515
					break;
516
     22c:	ac cf       	rjmp	.-168    	; 0x186
517
 
518
0000022e <Exec_readEventFifo>:
519
 
520
				default:		
521
					break;
522
			}			
523
		}
524
 
525
        /* toggle the debug line */
526
 
527
	}
528
}
529
 
530
/***********************************************************
531
	Function Name: Exec_readEventFifo
532
	Function Description: This function is responsible for
533
	reading a single event out of the event fifo.
534
	Inputs:  none 
535
	Outputs: unsigned char-the data read
536
***********************************************************/	
537
static unsigned char Exec_readEventFifo(void)
538
{
539
	unsigned char dataByte, tmpTail;
540
 
541
	DISABLE_INTS();
542
     22e:	f8 94       	cli
543
	/* just return the current tail from the tx fifo */
544
	dataByte = Exec_eventFifo[Exec_eventFifoTail];	
545
     230:	20 91 71 00 	lds	r18, 0x0071
546
     234:	8c e6       	ldi	r24, 0x6C	; 108
547
     236:	92 e0       	ldi	r25, 0x02	; 2
548
     238:	fc 01       	movw	r30, r24
549
     23a:	e2 0f       	add	r30, r18
550
     23c:	f1 1d       	adc	r31, r1
551
     23e:	90 81       	ld	r25, Z
552
	tmpTail = (Exec_eventFifoTail+1) & (EXEC_EVENT_FIFO_MASK);
553
     240:	82 2f       	mov	r24, r18
554
     242:	8f 5f       	subi	r24, 0xFF	; 255
555
     244:	87 70       	andi	r24, 0x07	; 7
556
	Exec_eventFifoTail = tmpTail;
557
     246:	80 93 71 00 	sts	0x0071, r24
558
	ENABLE_INTS();
559
     24a:	78 94       	sei
560
 
561
	return(dataByte);
562
     24c:	89 2f       	mov	r24, r25
563
     24e:	99 27       	eor	r25, r25
564
}
565
     250:	08 95       	ret
566
 
567
00000252 <Exec_writeEventFifo>:
568
 
569
/***********************************************************
570
	Function Name: Exec_writeEventFifo
571
	Function Description: This function is responsible for
572
	writing a single event to the event fifo and
573
	updating the appropriate pointers.
574
	Inputs:  data - the byte to write to the Fifo 
575
	Outputs: none
576
***********************************************************/	
577
void Exec_writeEventFifo(unsigned char event)
578
{
579
     252:	38 2f       	mov	r19, r24
580
	unsigned char tmpHead;
581
 
582
	DISABLE_INTS();
583
     254:	f8 94       	cli
584
	Exec_eventFifo[Exec_eventFifoHead] = event;
585
     256:	20 91 70 00 	lds	r18, 0x0070
586
     25a:	8c e6       	ldi	r24, 0x6C	; 108
587
     25c:	92 e0       	ldi	r25, 0x02	; 2
588
     25e:	fc 01       	movw	r30, r24
589
     260:	e2 0f       	add	r30, r18
590
     262:	f1 1d       	adc	r31, r1
591
     264:	30 83       	st	Z, r19
592
 
593
    /* now move the head up */
594
    tmpHead = (Exec_eventFifoHead + 1) & (EXEC_EVENT_FIFO_MASK);
595
     266:	82 2f       	mov	r24, r18
596
     268:	8f 5f       	subi	r24, 0xFF	; 255
597
     26a:	87 70       	andi	r24, 0x07	; 7
598
    Exec_eventFifoHead = tmpHead;
599
     26c:	80 93 70 00 	sts	0x0070, r24
600
	ENABLE_INTS();
601
     270:	78 94       	sei
602
}
603
     272:	08 95       	ret
604
 
605
00000274 <FrameMgr_init>:
606
	Outputs: none
607
***********************************************************/	
608
void FrameMgr_init(void)
609
{
610
	memset(trackedObjectTable,0x00,sizeof(trackedObjectTable));
611
     274:	80 e4       	ldi	r24, 0x40	; 64
612
     276:	e8 e7       	ldi	r30, 0x78	; 120
613
     278:	f0 e0       	ldi	r31, 0x00	; 0
614
     27a:	11 92       	st	Z+, r1
615
     27c:	8a 95       	dec	r24
616
     27e:	e9 f7       	brne	.-6      	; 0x27a
617
}
618
     280:	08 95       	ret
619
 
620
00000282 <FrameMgr_dispatchEvent>:
621
 
622
 
623
/***********************************************************
624
	Function Name: FrameMgr_dispatchEvent
625
	Function Description: This function is responsible for
626
	taking an incoming event and performing the needed
627
	actions with it as pertains to the FrameMgr.
628
	Inputs:  event - the generated event
629
	Outputs: none
630
***********************************************************/	
631
void FrameMgr_dispatchEvent(unsigned char event)
632
{	
633
	switch(event)
634
     282:	99 27       	eor	r25, r25
635
     284:	84 30       	cpi	r24, 0x04	; 4
636
     286:	91 05       	cpc	r25, r1
637
     288:	51 f1       	breq	.+84     	; 0x2de
638
     28a:	85 30       	cpi	r24, 0x05	; 5
639
     28c:	91 05       	cpc	r25, r1
640
     28e:	34 f4       	brge	.+12     	; 0x29c
641
     290:	81 30       	cpi	r24, 0x01	; 1
642
     292:	91 05       	cpc	r25, r1
643
     294:	31 f1       	breq	.+76     	; 0x2e2
644
     296:	02 97       	sbiw	r24, 0x02	; 2
645
     298:	71 f0       	breq	.+28     	; 0x2b6
646
	{
647
		case EV_DUMP_FRAME:
648
            /* try re-initializing the camera before we start dumping */
649
 
650
			CamConfig_setCamReg(0x11,0x01);  /* reduce the frame rate for dumping*/
651
			CamConfig_sendFifoCmds();
652
			Utility_delay(1000);		/* allow the new frame rate to settle */
653
			lineCount = 0;
654
			currentState = ST_FrameMgr_DumpingFrame;
655
			//CamIntAsm_waitForNewDumpFrame(currentLineBuffer,previousLineBuffer);
656
            FrameMgr_acquireLine();
657
			break;
658
 
659
		case EV_ENABLE_TRACKING:
660
			currentState = ST_FrameMgr_TrackingFrame;					
661
			FrameMgr_acquireFrame();
662
			break;
663
 
664
		case EV_ACQUIRE_FRAME_COMPLETE:
665
			FrameMgr_processFrame();
666
			break;
667
 
668
		case EV_PROCESS_FRAME_COMPLETE:
669
			FrameMgr_acquireFrame();
670
			break;
671
 
672
		case EV_SERIAL_DATA_RECEIVED:
673
			if (currentState != ST_FrameMgr_idle)
674
			{
675
				/* we need to go back to processing line data, since
676
				serial data reception interrupted us....just trash the
677
				frame and act like the frame has been processed, which
678
				will kick off the system to wait for the next line */
679
				PUBLISH_EVENT(EV_PROCESS_FRAME_COMPLETE);
680
			}
681
			break;
682
 
683
		case EV_DISABLE_TRACKING:
684
			/* tracking needs to be turned off */
685
			currentState = ST_FrameMgr_idle;
686
			break;
687
	}
688
}
689
     29a:	08 95       	ret
690
     29c:	80 38       	cpi	r24, 0x80	; 128
691
     29e:	91 05       	cpc	r25, r1
692
     2a0:	c1 f0       	breq	.+48     	; 0x2d2
693
     2a2:	81 38       	cpi	r24, 0x81	; 129
694
     2a4:	91 05       	cpc	r25, r1
695
     2a6:	1c f4       	brge	.+6      	; 0x2ae
696
     2a8:	80 97       	sbiw	r24, 0x20	; 32
697
     2aa:	b9 f0       	breq	.+46     	; 0x2da
698
     2ac:	08 95       	ret
699
     2ae:	81 38       	cpi	r24, 0x81	; 129
700
     2b0:	91 05       	cpc	r25, r1
701
     2b2:	f1 f0       	breq	.+60     	; 0x2f0
702
     2b4:	08 95       	ret
703
     2b6:	61 e0       	ldi	r22, 0x01	; 1
704
     2b8:	81 e1       	ldi	r24, 0x11	; 17
705
     2ba:	66 d5       	rcall	.+2764   	; 0xd88
706
     2bc:	6a d5       	rcall	.+2772   	; 0xd92
707
     2be:	88 ee       	ldi	r24, 0xE8	; 232
708
     2c0:	93 e0       	ldi	r25, 0x03	; 3
709
     2c2:	c1 d5       	rcall	.+2946   	; 0xe46
710
     2c4:	10 92 73 00 	sts	0x0073, r1
711
     2c8:	82 e0       	ldi	r24, 0x02	; 2
712
     2ca:	80 93 74 00 	sts	0x0074, r24
713
     2ce:	2f d0       	rcall	.+94     	; 0x32e
714
     2d0:	08 95       	ret
715
     2d2:	81 e0       	ldi	r24, 0x01	; 1
716
     2d4:	80 93 74 00 	sts	0x0074, r24
717
     2d8:	02 c0       	rjmp	.+4      	; 0x2de
718
     2da:	18 d1       	rcall	.+560    	; 0x50c
719
     2dc:	08 95       	ret
720
     2de:	0c d0       	rcall	.+24     	; 0x2f8
721
     2e0:	08 95       	ret
722
     2e2:	80 91 74 00 	lds	r24, 0x0074
723
     2e6:	88 23       	and	r24, r24
724
     2e8:	29 f0       	breq	.+10     	; 0x2f4
725
     2ea:	84 e0       	ldi	r24, 0x04	; 4
726
     2ec:	b2 df       	rcall	.-156    	; 0x252
727
     2ee:	08 95       	ret
728
     2f0:	10 92 74 00 	sts	0x0074, r1
729
     2f4:	08 95       	ret
730
     2f6:	08 95       	ret
731
 
732
000002f8 <FrameMgr_acquireFrame>:
733
 
734
/***********************************************************
735
	Function Name: FrameMgr_acquireFrame
736
	Function Description: This function is responsible for
737
	beginning of the acquisition of a new frame of data
738
	from the camera interface. The acquisition of this line 
739
	depends on the current state of the FrameMgr.
740
	Inputs:  none
741
	Outputs: none
742
***********************************************************/	
743
void FrameMgr_acquireFrame(void)
744
{
745
	if (currentState == ST_FrameMgr_TrackingFrame)
746
     2f8:	80 91 74 00 	lds	r24, 0x0074
747
     2fc:	81 30       	cpi	r24, 0x01	; 1
748
     2fe:	a9 f4       	brne	.+42     	; 0x32a
749
	{
750
		trackedLineCount = 0;
751
     300:	10 92 77 00 	sts	0x0077, r1
752
		numPrevTrackedObjects = numCurrTrackedObjects;
753
     304:	80 91 75 00 	lds	r24, 0x0075
754
     308:	80 93 76 00 	sts	0x0076, r24
755
		numCurrTrackedObjects = 0;
756
     30c:	10 92 75 00 	sts	0x0075, r1
757
 
758
		/* clear out the tracking table, and wait for the new frame
759
		to start */
760
		memset(trackedObjectTable,0x00,sizeof(trackedObjectTable));
761
     310:	80 e4       	ldi	r24, 0x40	; 64
762
     312:	e8 e7       	ldi	r30, 0x78	; 120
763
     314:	f0 e0       	ldi	r31, 0x00	; 0
764
     316:	11 92       	st	Z+, r1
765
     318:	8a 95       	dec	r24
766
     31a:	e9 f7       	brne	.-6      	; 0x316
767
		//CamIntAsm_waitForNewTrackingFrame(currentLineBuffer,colorMap);
768
        WAIT_FOR_VSYNC_HIGH();
769
     31c:	82 9b       	sbis	0x10, 2	; 16
770
     31e:	fe cf       	rjmp	.-4      	; 0x31c
771
        CamIntAsm_acquireTrackingLine(currentLineBuffer,colorMap);
772
     320:	60 e0       	ldi	r22, 0x00	; 0
773
     322:	73 e0       	ldi	r23, 0x03	; 3
774
     324:	8c eb       	ldi	r24, 0xBC	; 188
775
     326:	91 e0       	ldi	r25, 0x01	; 1
776
     328:	f0 d5       	rcall	.+3040   	; 0xf0a
777
	}
778
}
779
     32a:	08 95       	ret
780
     32c:	08 95       	ret
781
 
782
0000032e <FrameMgr_acquireLine>:
783
 
784
/***********************************************************
785
	Function Name: FrameMgr_acquireLine
786
	Function Description: This function is responsible for
787
	acquiring a line of data from the camera interface.
788
	The acquisition of this line depends on the current
789
	state of the FrameMgr.
790
	Inputs:  none
791
	Outputs: none
792
***********************************************************/	
793
void FrameMgr_acquireLine(void)
794
{
795
	unsigned char tmpLineCount;
796
 
797
	/* clearing out the buffers takes too long...we should
798
	just overwrite the data here without a problem when
799
	we start acquiring...at no point do we check for 
800
	a 0x00 value in the current or previous lineBuffers,
801
	so it was a bit excessive :-)  */
802
 
803
	/* check which state we are in and proceed as needed */
804
	if (currentState == ST_FrameMgr_DumpingFrame)
805
     32e:	80 91 74 00 	lds	r24, 0x0074
806
     332:	82 30       	cpi	r24, 0x02	; 2
807
     334:	11 f5       	brne	.+68     	; 0x37a
808
	{
809
		tmpLineCount = lineCount*2;
810
     336:	80 91 73 00 	lds	r24, 0x0073
811
     33a:	88 0f       	add	r24, r24
812
 
813
        /* clearing out the line data in dump mode is ok, and actually
814
        is needed, since it is possible for the first dump line in
815
        a frame to come back with the last line captured of the
816
        last capture session...*/
817
        memset(currentLineBuffer,0x00,LENGTH_OF_LINE_BUFFER);
818
     33c:	90 eb       	ldi	r25, 0xB0	; 176
819
     33e:	ec eb       	ldi	r30, 0xBC	; 188
820
     340:	f1 e0       	ldi	r31, 0x01	; 1
821
     342:	11 92       	st	Z+, r1
822
     344:	9a 95       	dec	r25
823
     346:	e9 f7       	brne	.-6      	; 0x342
824
        memset(previousLineBuffer,0x00,LENGTH_OF_LINE_BUFFER);
825
     348:	90 eb       	ldi	r25, 0xB0	; 176
826
     34a:	ec e0       	ldi	r30, 0x0C	; 12
827
     34c:	f1 e0       	ldi	r31, 0x01	; 1
828
     34e:	11 92       	st	Z+, r1
829
     350:	9a 95       	dec	r25
830
     352:	e9 f7       	brne	.-6      	; 0x34e
831
		/* wait for another VSYNC so we know which frame to use 
832
		to start looking for a line to receive */
833
		WAIT_FOR_VSYNC_HIGH();  
834
     354:	82 9b       	sbis	0x10, 2	; 16
835
     356:	fe cf       	rjmp	.-4      	; 0x354
836
		WAIT_FOR_VSYNC_LOW();
837
     358:	82 99       	sbic	0x10, 2	; 16
838
     35a:	fe cf       	rjmp	.-4      	; 0x358
839
 
840
		/* look at lineCount to determine how many HREFs we should
841
		wait before we start sampling */
842
		while(tmpLineCount != 0)
843
     35c:	88 23       	and	r24, r24
844
     35e:	39 f0       	breq	.+14     	; 0x36e
845
		{
846
			WAIT_FOR_HREF_HIGH(); 
847
     360:	84 9b       	sbis	0x10, 4	; 16
848
     362:	fe cf       	rjmp	.-4      	; 0x360
849
			tmpLineCount--;
850
     364:	81 50       	subi	r24, 0x01	; 1
851
			WAIT_FOR_HREF_LOW(); 
852
     366:	84 99       	sbic	0x10, 4	; 16
853
     368:	fe cf       	rjmp	.-4      	; 0x366
854
     36a:	88 23       	and	r24, r24
855
     36c:	c9 f7       	brne	.-14     	; 0x360
856
		}
857
 
858
		/*  we should now be ready to sample our line...*/
859
		CamIntAsm_acquireDumpLine(currentLineBuffer,previousLineBuffer);
860
     36e:	6c e0       	ldi	r22, 0x0C	; 12
861
     370:	71 e0       	ldi	r23, 0x01	; 1
862
     372:	8c eb       	ldi	r24, 0xBC	; 188
863
     374:	91 e0       	ldi	r25, 0x01	; 1
864
     376:	10 d6       	rcall	.+3104   	; 0xf98
865
	}		
866
	else if (currentState == ST_FrameMgr_TrackingFrame)
867
	{
868
		WAIT_FOR_HREF_LOW();
869
		CamIntAsm_acquireTrackingLine(currentLineBuffer,colorMap);
870
	}
871
}
872
     378:	08 95       	ret
873
     37a:	80 91 74 00 	lds	r24, 0x0074
874
     37e:	81 30       	cpi	r24, 0x01	; 1
875
     380:	39 f4       	brne	.+14     	; 0x390
876
     382:	84 99       	sbic	0x10, 4	; 16
877
     384:	fe cf       	rjmp	.-4      	; 0x382
878
     386:	60 e0       	ldi	r22, 0x00	; 0
879
     388:	73 e0       	ldi	r23, 0x03	; 3
880
     38a:	8c eb       	ldi	r24, 0xBC	; 188
881
     38c:	91 e0       	ldi	r25, 0x01	; 1
882
     38e:	bd d5       	rcall	.+2938   	; 0xf0a
883
     390:	08 95       	ret
884
 
885
00000392 <FrameMgr_processLine>:
886
 
887
/***********************************************************
888
	Function Name: FrameMgr_processLine
889
	Function Description: This function is responsible for
890
	parsing the received image line and performing either
891
	connected region mapping (if in the Tracking state) or
892
	sending out the raw sampled data (if in the Dumping
893
	state).
894
	Inputs:  none
895
	Outputs: none
896
***********************************************************/	
897
void FrameMgr_processLine(void)
898
{
899
     392:	df 92       	push	r13
900
     394:	ef 92       	push	r14
901
     396:	ff 92       	push	r15
902
     398:	0f 93       	push	r16
903
     39a:	1f 93       	push	r17
904
     39c:	cf 93       	push	r28
905
     39e:	df 93       	push	r29
906
     3a0:	cd b7       	in	r28, 0x3d	; 61
907
     3a2:	de b7       	in	r29, 0x3e	; 62
908
     3a4:	21 97       	sbiw	r28, 0x01	; 1
909
     3a6:	0f b6       	in	r0, 0x3f	; 63
910
     3a8:	f8 94       	cli
911
     3aa:	de bf       	out	0x3e, r29	; 62
912
     3ac:	0f be       	out	0x3f, r0	; 63
913
     3ae:	cd bf       	out	0x3d, r28	; 61
914
	unsigned char i;
915
	volatile unsigned char dataToSend;
916
	unsigned char *pTrackedObjectData = (unsigned char *)pCurrentTrackedObjectTable;
917
     3b0:	00 91 60 00 	lds	r16, 0x0060
918
     3b4:	10 91 61 00 	lds	r17, 0x0061
919
#ifdef DEBUG_TRACKED_LINE    
920
	unsigned char *pSendData;
921
    unsigned char asciiBuffer[5];
922
    unsigned char pixelCount = 0;
923
#endif    
924
 
925
	if (currentState == ST_FrameMgr_DumpingFrame)
926
     3b8:	80 91 74 00 	lds	r24, 0x0074
927
     3bc:	82 30       	cpi	r24, 0x02	; 2
928
     3be:	09 f0       	breq	.+2      	; 0x3c2
929
     3c0:	54 c0       	rjmp	.+168    	; 0x46a
930
	{
931
		/* we want to sit in a tight loop and send the acquired data
932
		sitting in current and previous line buffers out the serial
933
		port...it is sent out the serial port immediately instead
934
		of going into the UIMgr tx fifo because we can't do anything
935
		until its sent out anyway...may as well just get it out now	*/
936
 
937
		/* currentLineBuffer is getting "g" previousLineBuffer is getting "b-r" */
938
		UartInt_txByte(0x0B);			/* send the header byte */
939
     3c2:	8b e0       	ldi	r24, 0x0B	; 11
940
     3c4:	cd d3       	rcall	.+1946   	; 0xb60
941
		UartInt_txByte(lineCount);		/* send the line count */
942
     3c6:	80 91 73 00 	lds	r24, 0x0073
943
     3ca:	ca d3       	rcall	.+1940   	; 0xb60
944
		for (i=0; i<NUM_PIXELS_IN_A_DUMP_LINE; i+=2)
945
     3cc:	dd 24       	eor	r13, r13
946
		{
947
			/* when a dump line is sampled, the upper byte can potentially
948
			have garbage in it...we don't have time to mask it off as we're
949
			sampling, so it is done here before we send it out...we also
950
			combine the samples together so we really are sending up a
951
			sample for line N as well as line N+1 */
952
			dataToSend = currentLineBuffer[i];
953
     3ce:	2d 2d       	mov	r18, r13
954
     3d0:	33 27       	eor	r19, r19
955
     3d2:	0f 2e       	mov	r0, r31
956
     3d4:	fc eb       	ldi	r31, 0xBC	; 188
957
     3d6:	ef 2e       	mov	r14, r31
958
     3d8:	f1 e0       	ldi	r31, 0x01	; 1
959
     3da:	ff 2e       	mov	r15, r31
960
     3dc:	f0 2d       	mov	r31, r0
961
     3de:	e2 0e       	add	r14, r18
962
     3e0:	f3 1e       	adc	r15, r19
963
     3e2:	f7 01       	movw	r30, r14
964
     3e4:	80 81       	ld	r24, Z
965
     3e6:	89 83       	std	Y+1, r24	; 0x01
966
			dataToSend &= 0x0F;
967
     3e8:	89 81       	ldd	r24, Y+1	; 0x01
968
     3ea:	8f 70       	andi	r24, 0x0F	; 15
969
     3ec:	89 83       	std	Y+1, r24	; 0x01
970
			dataToSend <<= 4;
971
     3ee:	89 81       	ldd	r24, Y+1	; 0x01
972
     3f0:	82 95       	swap	r24
973
     3f2:	80 7f       	andi	r24, 0xF0	; 240
974
     3f4:	89 83       	std	Y+1, r24	; 0x01
975
			dataToSend |= (previousLineBuffer[i] & 0x0F);
976
     3f6:	89 01       	movw	r16, r18
977
     3f8:	04 5f       	subi	r16, 0xF4	; 244
978
     3fa:	1e 4f       	sbci	r17, 0xFE	; 254
979
     3fc:	f8 01       	movw	r30, r16
980
     3fe:	80 81       	ld	r24, Z
981
     400:	98 2f       	mov	r25, r24
982
     402:	9f 70       	andi	r25, 0x0F	; 15
983
     404:	89 81       	ldd	r24, Y+1	; 0x01
984
     406:	89 2b       	or	r24, r25
985
     408:	89 83       	std	Y+1, r24	; 0x01
986
 
987
			/* dataToSend should be packed now */
988
			UartInt_txByte(dataToSend);
989
     40a:	89 81       	ldd	r24, Y+1	; 0x01
990
     40c:	a9 d3       	rcall	.+1874   	; 0xb60
991
 
992
			/* flip the colors around since we are doing all G on Y and BR on UV */
993
			dataToSend = previousLineBuffer[i+1];
994
     40e:	f8 01       	movw	r30, r16
995
     410:	81 81       	ldd	r24, Z+1	; 0x01
996
     412:	89 83       	std	Y+1, r24	; 0x01
997
			dataToSend &= 0x0F;
998
     414:	89 81       	ldd	r24, Y+1	; 0x01
999
     416:	8f 70       	andi	r24, 0x0F	; 15
1000
     418:	89 83       	std	Y+1, r24	; 0x01
1001
			dataToSend <<= 4;
1002
     41a:	89 81       	ldd	r24, Y+1	; 0x01
1003
     41c:	82 95       	swap	r24
1004
     41e:	80 7f       	andi	r24, 0xF0	; 240
1005
     420:	89 83       	std	Y+1, r24	; 0x01
1006
			dataToSend |= (currentLineBuffer[i+1] & 0x0F);
1007
     422:	f7 01       	movw	r30, r14
1008
     424:	81 81       	ldd	r24, Z+1	; 0x01
1009
     426:	98 2f       	mov	r25, r24
1010
     428:	9f 70       	andi	r25, 0x0F	; 15
1011
     42a:	89 81       	ldd	r24, Y+1	; 0x01
1012
     42c:	89 2b       	or	r24, r25
1013
     42e:	89 83       	std	Y+1, r24	; 0x01
1014
 
1015
			/* dataToSend should be packed now */
1016
			UartInt_txByte(dataToSend);
1017
     430:	89 81       	ldd	r24, Y+1	; 0x01
1018
     432:	96 d3       	rcall	.+1836   	; 0xb60
1019
     434:	f2 e0       	ldi	r31, 0x02	; 2
1020
     436:	df 0e       	add	r13, r31
1021
     438:	4f ea       	ldi	r20, 0xAF	; 175
1022
     43a:	4d 15       	cp	r20, r13
1023
     43c:	40 f6       	brcc	.-112    	; 0x3ce
1024
		}
1025
		UartInt_txByte(0x0F);  /* send line end */
1026
     43e:	8f e0       	ldi	r24, 0x0F	; 15
1027
     440:	8f d3       	rcall	.+1822   	; 0xb60
1028
		/* once all the data is sent, increment out line count by 2 since
1029
		we really get 2 lines worth of pixels on each pass */
1030
		/* Update...increment only by 1, but only send 72 double-lines */
1031
		lineCount++;
1032
     442:	80 91 73 00 	lds	r24, 0x0073
1033
     446:	8f 5f       	subi	r24, 0xFF	; 255
1034
     448:	80 93 73 00 	sts	0x0073, r24
1035
 
1036
		/* check to see if we have retrieved all of the needed lines */
1037
		if (lineCount >= 72)  /* half 144, since we send two lines at a time */
1038
     44c:	88 34       	cpi	r24, 0x48	; 72
1039
     44e:	08 f4       	brcc	.+2      	; 0x452
1040
     450:	4a c0       	rjmp	.+148    	; 0x4e6
1041
		{
1042
			/* we're done, so send the dump complete?...nope, just change
1043
			states and we should be fine */
1044
			lineCount = 0;
1045
     452:	10 92 73 00 	sts	0x0073, r1
1046
			currentState = ST_FrameMgr_idle;
1047
     456:	10 92 74 00 	sts	0x0074, r1
1048
 
1049
			/* disable the PCLK counting overflow interrupt */
1050
			TIMSK &= DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK;
1051
     45a:	89 b7       	in	r24, 0x39	; 57
1052
     45c:	8b 7f       	andi	r24, 0xFB	; 251
1053
     45e:	89 bf       	out	0x39, r24	; 57
1054
 
1055
			CamConfig_setCamReg(0x11,0x00);  /* reset the frame rate to normal*/
1056
     460:	60 e0       	ldi	r22, 0x00	; 0
1057
     462:	81 e1       	ldi	r24, 0x11	; 17
1058
     464:	91 d4       	rcall	.+2338   	; 0xd88
1059
			CamConfig_sendFifoCmds();
1060
     466:	95 d4       	rcall	.+2346   	; 0xd92
1061
     468:	43 c0       	rjmp	.+134    	; 0x4f0
1062
		}
1063
		else
1064
		{
1065
			/* we have more lines to acquire in this frame, so keep on truckin...*/
1066
			PUBLISH_FAST_EVENT(FEV_PROCESS_LINE_COMPLETE);
1067
		}
1068
	}
1069
	else if (currentState == ST_FrameMgr_TrackingFrame)
1070
     46a:	80 91 74 00 	lds	r24, 0x0074
1071
     46e:	81 30       	cpi	r24, 0x01	; 1
1072
     470:	09 f0       	breq	.+2      	; 0x474
1073
     472:	3e c0       	rjmp	.+124    	; 0x4f0
1074
	{
1075
#ifdef DEBUG_TRACKED_LINE	
1076
		/* send the received line over serial...this should only send
1077
		until a pixelCount == 176 */
1078
		pSendData = currentLineBuffer;
1079
		itoa(trackedLineCount,asciiBuffer,10);
1080
		UIMgr_txBuffer(asciiBuffer,3);
1081
		UIMgr_txBuffer(" ",1);
1082
		while(pixelCount < ACTUAL_NUM_PIXELS_IN_A_LINE)  
1083
		{
1084
			memset(asciiBuffer,0x00,5);
1085
			itoa(*pSendData++,asciiBuffer,10);	/* color is first byte */
1086
			UIMgr_txBuffer(asciiBuffer,3); /* 3 ascii bytes for data */
1087
			UIMgr_txBuffer(" ",1);
1088
 
1089
			pixelCount += *pSendData;	/* run-length is second byte */
1090
			memset(asciiBuffer,0x00,5);
1091
			itoa(*pSendData++,asciiBuffer,10);
1092
			UIMgr_txBuffer(asciiBuffer,3);
1093
			UIMgr_txBuffer(" ",1);
1094
		}
1095
		UIMgr_txBuffer("\n\r",2);
1096
 
1097
		trackedLineCount++;
1098
		if (trackedLineCount == 144)
1099
		{
1100
			UIMgr_txBuffer("  FC  \n\r",8);
1101
			trackedLineCount = 0;
1102
			PUBLISH_EVENT(EV_PROCESS_FRAME_COMPLETE);
1103
		}
1104
		else
1105
		{
1106
			PUBLISH_EVENT(EV_PROCESS_LINE_COMPLETE);
1107
		}	
1108
#else
1109
        /* determine if any of the RLE blocks overlap */
1110
		FrameMgr_findConnectedness();
1111
     474:	a1 d0       	rcall	.+322    	; 0x5b8
1112
 
1113
        /* we also want to remove any objects that are less than
1114
        a minimum height...we already removed portions of the 
1115
        run-length that are less than MIN_PIXEL_WIDTH in the
1116
        findConnectedness() routine...doing it here instead of 
1117
        a function to speed things up...this may end up slowing down the
1118
        frame rate slightly, and can be removed if this isn't needed */
1119
 
1120
        /* run this routine once every 8 lines */       
1121
        if ( (trackedLineCount & RUN_OBJECT_FILTER_MASK) == RUN_OBJECT_FILTER_MASK)
1122
     476:	80 91 77 00 	lds	r24, 0x0077
1123
     47a:	99 27       	eor	r25, r25
1124
     47c:	87 70       	andi	r24, 0x07	; 7
1125
     47e:	90 70       	andi	r25, 0x00	; 0
1126
     480:	07 97       	sbiw	r24, 0x07	; 7
1127
     482:	11 f5       	brne	.+68     	; 0x4c8
1128
        {
1129
            for (i=0; i<MAX_TRACKED_OBJECTS; i++)
1130
     484:	dd 24       	eor	r13, r13
1131
            {
1132
                if ( *(pTrackedObjectData + VALID_OBJECT_OFFSET) == TRUE)
1133
     486:	f8 01       	movw	r30, r16
1134
     488:	87 81       	ldd	r24, Z+7	; 0x07
1135
     48a:	81 30       	cpi	r24, 0x01	; 1
1136
     48c:	b9 f4       	brne	.+46     	; 0x4bc
1137
                {
1138
                    /* check to see if the object is already in
1139
                    our past...i.e., its last */
1140
                    if ( (*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) - 
1141
     48e:	86 81       	ldd	r24, Z+6	; 0x06
1142
     490:	28 2f       	mov	r18, r24
1143
     492:	33 27       	eor	r19, r19
1144
     494:	84 81       	ldd	r24, Z+4	; 0x04
1145
     496:	a9 01       	movw	r20, r18
1146
     498:	48 1b       	sub	r20, r24
1147
     49a:	51 09       	sbc	r21, r1
1148
     49c:	43 30       	cpi	r20, 0x03	; 3
1149
     49e:	51 05       	cpc	r21, r1
1150
     4a0:	6c f4       	brge	.+26     	; 0x4bc
1151
                          *(pTrackedObjectData + Y_UPPER_LEFT_OFFSET)) < MIN_OBJECT_TRACKING_HEIGHT)
1152
                    {
1153
                        /* the object is less than the minimum height...see if it is adjacent
1154
                        to the current line we just processed...if so, leave it here...otherwise,
1155
                        it needs to be invalidated since its too small */
1156
                        if ( trackedLineCount - *(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) > 2)
1157
     4a2:	80 91 77 00 	lds	r24, 0x0077
1158
     4a6:	99 27       	eor	r25, r25
1159
     4a8:	82 1b       	sub	r24, r18
1160
     4aa:	93 0b       	sbc	r25, r19
1161
     4ac:	03 97       	sbiw	r24, 0x03	; 3
1162
     4ae:	34 f0       	brlt	.+12     	; 0x4bc
1163
                        {
1164
                            /* invalidate the object */
1165
                            *(pTrackedObjectData + VALID_OBJECT_OFFSET) = FALSE;
1166
     4b0:	17 82       	std	Z+7, r1	; 0x07
1167
                            numCurrTrackedObjects--;
1168
     4b2:	80 91 75 00 	lds	r24, 0x0075
1169
     4b6:	81 50       	subi	r24, 0x01	; 1
1170
     4b8:	80 93 75 00 	sts	0x0075, r24
1171
                        }
1172
                    }
1173
                }
1174
                pTrackedObjectData += SIZE_OF_TRACKED_OBJECT;
1175
     4bc:	08 5f       	subi	r16, 0xF8	; 248
1176
     4be:	1f 4f       	sbci	r17, 0xFF	; 255
1177
     4c0:	d3 94       	inc	r13
1178
     4c2:	57 e0       	ldi	r21, 0x07	; 7
1179
     4c4:	5d 15       	cp	r21, r13
1180
     4c6:	f8 f6       	brcc	.-66     	; 0x486
1181
            }
1182
        }     
1183
 
1184
		trackedLineCount++;
1185
     4c8:	80 91 77 00 	lds	r24, 0x0077
1186
     4cc:	8f 5f       	subi	r24, 0xFF	; 255
1187
     4ce:	80 93 77 00 	sts	0x0077, r24
1188
		if (trackedLineCount == ACTUAL_NUM_LINES_IN_A_FRAME)
1189
     4d2:	80 39       	cpi	r24, 0x90	; 144
1190
     4d4:	41 f4       	brne	.+16     	; 0x4e6
1191
		{
1192
			/* an entire frame of tracking data has been acquired, so
1193
			publish an event letting the system know this fact */
1194
			PUBLISH_EVENT(EV_ACQUIRE_FRAME_COMPLETE);
1195
     4d6:	80 e2       	ldi	r24, 0x20	; 32
1196
     4d8:	bc de       	rcall	.-648    	; 0x252
1197
			/* disable the PCLK counting overflow interrupt */
1198
			TIMSK &= DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK;
1199
     4da:	89 b7       	in	r24, 0x39	; 57
1200
     4dc:	8b 7f       	andi	r24, 0xFB	; 251
1201
     4de:	89 bf       	out	0x39, r24	; 57
1202
			trackedLineCount = 0;
1203
     4e0:	10 92 77 00 	sts	0x0077, r1
1204
     4e4:	05 c0       	rjmp	.+10     	; 0x4f0
1205
		}
1206
		else
1207
		{
1208
			PUBLISH_FAST_EVENT(FEV_PROCESS_LINE_COMPLETE);
1209
     4e6:	80 91 72 00 	lds	r24, 0x0072
1210
     4ea:	82 60       	ori	r24, 0x02	; 2
1211
     4ec:	80 93 72 00 	sts	0x0072, r24
1212
		}
1213
#endif		
1214
	}
1215
	else
1216
	{
1217
		/* ...and here? */
1218
	}
1219
}
1220
     4f0:	21 96       	adiw	r28, 0x01	; 1
1221
     4f2:	0f b6       	in	r0, 0x3f	; 63
1222
     4f4:	f8 94       	cli
1223
     4f6:	de bf       	out	0x3e, r29	; 62
1224
     4f8:	0f be       	out	0x3f, r0	; 63
1225
     4fa:	cd bf       	out	0x3d, r28	; 61
1226
     4fc:	df 91       	pop	r29
1227
     4fe:	cf 91       	pop	r28
1228
     500:	1f 91       	pop	r17
1229
     502:	0f 91       	pop	r16
1230
     504:	ff 90       	pop	r15
1231
     506:	ef 90       	pop	r14
1232
     508:	df 90       	pop	r13
1233
     50a:	08 95       	ret
1234
 
1235
0000050c <FrameMgr_processFrame>:
1236
 
1237
/***********************************************************
1238
	Function Name: FrameMgr_processFrame
1239
	Function Description: This function is responsible for
1240
	parsing the completed frame and performing all actions
1241
	needed at this level.
1242
	Inputs:  none
1243
	Outputs: none
1244
***********************************************************/	
1245
void FrameMgr_processFrame(void)
1246
{
1247
     50c:	df 92       	push	r13
1248
     50e:	ef 92       	push	r14
1249
     510:	ff 92       	push	r15
1250
     512:	0f 93       	push	r16
1251
     514:	1f 93       	push	r17
1252
     516:	cf 93       	push	r28
1253
     518:	df 93       	push	r29
1254
	unsigned char i,k,color;
1255
#if DEBUG_FRAME_DATA    
1256
	unsigned char asciiBuffer[5];
1257
    unsigned char j;
1258
#endif    
1259
	unsigned char *pTableData = (unsigned char *)pCurrentTrackedObjectTable;
1260
	unsigned char tmpUpperLeftX,tmpUpperLeftY,tmpLowerRightX,tmpLowerRightY;
1261
 
1262
#if DEBUG_FRAME_DATA	
1263
	/* we want to send all of the currently tracked table out
1264
	the serial port for debugging */
1265
	for (i=0; i<numCurrTrackedObjects; i++)
1266
	{
1267
		UIMgr_txBuffer("----------\r\n",12);
1268
		for (j=0; j<SIZE_OF_TRACKED_OBJECT; j++)
1269
		{
1270
			memset(asciiBuffer,0x00,5);
1271
			itoa(*pTableData++,asciiBuffer,10);
1272
			UIMgr_txBuffer(asciiBuffer,3); /* 3 ascii bytes for data
1273
														+ 1 space */
1274
			UIMgr_txBuffer("\r\n",2);
1275
		}
1276
	}
1277
 
1278
	/* finally, send a new line */
1279
	UIMgr_txBuffer("\r\n",2);
1280
 
1281
	memset(asciiBuffer,0x00,5);
1282
	itoa(numCurrTrackedObjects,asciiBuffer,10);
1283
	UIMgr_txBuffer(asciiBuffer,3);
1284
	UIMgr_txBuffer(" PFC\r\n",5);
1285
 
1286
#else	
1287
	/* we only send tracking packets if there are tracked objects */	        
1288
 
1289
	if (numCurrTrackedObjects > 0)
1290
     51a:	80 91 75 00 	lds	r24, 0x0075
1291
     51e:	88 23       	and	r24, r24
1292
     520:	09 f4       	brne	.+2      	; 0x524
1293
     522:	40 c0       	rjmp	.+128    	; 0x5a4
1294
	{		
1295
		UIMgr_writeTxFifo(0x0A);					/* header byte for a tracking packet */
1296
     524:	8a e0       	ldi	r24, 0x0A	; 10
1297
     526:	01 d3       	rcall	.+1538   	; 0xb2a
1298
        /* reset the pointer */
1299
        pTableData = (unsigned char *)pCurrentTrackedObjectTable;
1300
     528:	c0 91 60 00 	lds	r28, 0x0060
1301
     52c:	d0 91 61 00 	lds	r29, 0x0061
1302
 
1303
		UIMgr_writeTxFifo(numCurrTrackedObjects);	/* num of objects tracked */
1304
     530:	80 91 75 00 	lds	r24, 0x0075
1305
     534:	fa d2       	rcall	.+1524   	; 0xb2a
1306
		for (i=0; i<MAX_TRACKED_OBJECTS; i++)
1307
     536:	dd 24       	eor	r13, r13
1308
		{
1309
            /* we only want to process objects that have their objectValid flag
1310
            set to TRUE */
1311
            if ( *(pTableData + VALID_OBJECT_OFFSET) == TRUE)
1312
     538:	8f 81       	ldd	r24, Y+7	; 0x07
1313
     53a:	81 30       	cpi	r24, 0x01	; 1
1314
     53c:	61 f5       	brne	.+88     	; 0x596
1315
            {
1316
                /* the object is valid...convert the color from bit position to value...remember, 
1317
                each bit in the "color" byte corresponds to a color */
1318
                k=0;
1319
     53e:	80 e0       	ldi	r24, 0x00	; 0
1320
                color = *(pTableData + COLOR_OFFSET);
1321
     540:	98 81       	ld	r25, Y
1322
                if (color == 128) k=0;
1323
     542:	90 38       	cpi	r25, 0x80	; 128
1324
     544:	d9 f0       	breq	.+54     	; 0x57c
1325
                else if (color == 64) k=1;
1326
     546:	90 34       	cpi	r25, 0x40	; 64
1327
     548:	11 f4       	brne	.+4      	; 0x54e
1328
     54a:	81 e0       	ldi	r24, 0x01	; 1
1329
     54c:	17 c0       	rjmp	.+46     	; 0x57c
1330
                else if (color == 32) k=2;
1331
     54e:	90 32       	cpi	r25, 0x20	; 32
1332
     550:	11 f4       	brne	.+4      	; 0x556
1333
     552:	82 e0       	ldi	r24, 0x02	; 2
1334
     554:	13 c0       	rjmp	.+38     	; 0x57c
1335
                else if (color == 16) k=3;
1336
     556:	90 31       	cpi	r25, 0x10	; 16
1337
     558:	11 f4       	brne	.+4      	; 0x55e
1338
     55a:	83 e0       	ldi	r24, 0x03	; 3
1339
     55c:	0f c0       	rjmp	.+30     	; 0x57c
1340
                else if (color == 8)  k=4;
1341
     55e:	98 30       	cpi	r25, 0x08	; 8
1342
     560:	11 f4       	brne	.+4      	; 0x566
1343
     562:	84 e0       	ldi	r24, 0x04	; 4
1344
     564:	0b c0       	rjmp	.+22     	; 0x57c
1345
                else if (color == 4)  k=5;
1346
     566:	94 30       	cpi	r25, 0x04	; 4
1347
     568:	11 f4       	brne	.+4      	; 0x56e
1348
     56a:	85 e0       	ldi	r24, 0x05	; 5
1349
     56c:	07 c0       	rjmp	.+14     	; 0x57c
1350
                else if (color == 2)  k=6;
1351
     56e:	92 30       	cpi	r25, 0x02	; 2
1352
     570:	11 f4       	brne	.+4      	; 0x576
1353
     572:	86 e0       	ldi	r24, 0x06	; 6
1354
     574:	03 c0       	rjmp	.+6      	; 0x57c
1355
                else if (color == 1)  k=7;
1356
     576:	91 30       	cpi	r25, 0x01	; 1
1357
     578:	09 f4       	brne	.+2      	; 0x57c
1358
     57a:	87 e0       	ldi	r24, 0x07	; 7
1359
 
1360
                tmpUpperLeftX = *(pTableData + X_UPPER_LEFT_OFFSET);	    /* get the upper left X */
1361
     57c:	1b 81       	ldd	r17, Y+3	; 0x03
1362
                tmpUpperLeftY = *(pTableData + Y_UPPER_LEFT_OFFSET);		/* get the upper left Y */		
1363
     57e:	0c 81       	ldd	r16, Y+4	; 0x04
1364
                tmpLowerRightX = *(pTableData + X_LOWER_RIGHT_OFFSET);		/* get the lower right X */
1365
     580:	fd 80       	ldd	r15, Y+5	; 0x05
1366
                tmpLowerRightY = *(pTableData + Y_LOWER_RIGHT_OFFSET);		/* get the lower right Y */	                
1367
     582:	ee 80       	ldd	r14, Y+6	; 0x06
1368
 
1369
                UIMgr_writeTxFifo(k);				  	/* send the color first */
1370
     584:	d2 d2       	rcall	.+1444   	; 0xb2a
1371
                UIMgr_writeTxFifo(tmpUpperLeftX);
1372
     586:	81 2f       	mov	r24, r17
1373
     588:	d0 d2       	rcall	.+1440   	; 0xb2a
1374
                UIMgr_writeTxFifo(tmpUpperLeftY);
1375
     58a:	80 2f       	mov	r24, r16
1376
     58c:	ce d2       	rcall	.+1436   	; 0xb2a
1377
                UIMgr_writeTxFifo(tmpLowerRightX);
1378
     58e:	8f 2d       	mov	r24, r15
1379
     590:	cc d2       	rcall	.+1432   	; 0xb2a
1380
                UIMgr_writeTxFifo(tmpLowerRightY);			
1381
     592:	8e 2d       	mov	r24, r14
1382
     594:	ca d2       	rcall	.+1428   	; 0xb2a
1383
            }
1384
 
1385
            /* move our pointer up to the beginning of the next object */
1386
            pTableData += SIZE_OF_TRACKED_OBJECT;
1387
     596:	28 96       	adiw	r28, 0x08	; 8
1388
     598:	d3 94       	inc	r13
1389
     59a:	87 e0       	ldi	r24, 0x07	; 7
1390
     59c:	8d 15       	cp	r24, r13
1391
     59e:	60 f6       	brcc	.-104    	; 0x538
1392
        }
1393
 
1394
		/* all done...send the end of tracking packets char */
1395
		UIMgr_writeTxFifo(0xFF);
1396
     5a0:	8f ef       	ldi	r24, 0xFF	; 255
1397
     5a2:	c3 d2       	rcall	.+1414   	; 0xb2a
1398
	}	
1399
#endif	
1400
 
1401
    /* the tracked object table will be cleared out right before we start
1402
    to wait for VSYNC to indicate a new frame...so it doesn't need to be
1403
    done now */
1404
 
1405
	/* schedule the next action to acquire a new frame */	
1406
	PUBLISH_EVENT(EV_PROCESS_FRAME_COMPLETE);
1407
     5a4:	84 e0       	ldi	r24, 0x04	; 4
1408
     5a6:	55 de       	rcall	.-854    	; 0x252
1409
}
1410
     5a8:	df 91       	pop	r29
1411
     5aa:	cf 91       	pop	r28
1412
     5ac:	1f 91       	pop	r17
1413
     5ae:	0f 91       	pop	r16
1414
     5b0:	ff 90       	pop	r15
1415
     5b2:	ef 90       	pop	r14
1416
     5b4:	df 90       	pop	r13
1417
     5b6:	08 95       	ret
1418
 
1419
000005b8 <FrameMgr_findConnectedness>:
1420
 
1421
/***********************************************************
1422
	Function Name: FrameMgr_findConnectedness
1423
	Function Description: This function is responsible for
1424
	finding the connectedness between two particular run-
1425
	length encoded lines of pixel data.  It updates the
1426
	trackingTable as needed.
1427
	Inputs:  none
1428
	Outputs: none
1429
***********************************************************/	
1430
static void FrameMgr_findConnectedness(void)
1431
{
1432
     5b8:	1f 93       	push	r17
1433
     5ba:	cf 93       	push	r28
1434
	trackedColor_t currColor;
1435
	unsigned char *pCurrLineColorInfo = currentLineBuffer;
1436
     5bc:	ac eb       	ldi	r26, 0xBC	; 188
1437
     5be:	b1 e0       	ldi	r27, 0x01	; 1
1438
	unsigned char *pTrackedObjectData;
1439
	register unsigned char currPixelRunStart=0;
1440
     5c0:	60 e0       	ldi	r22, 0x00	; 0
1441
	register unsigned char currPixelRunFinish=0; 
1442
     5c2:	c6 2f       	mov	r28, r22
1443
	register unsigned char lastLineXStart=0;
1444
	register unsigned char lastLineXFinish=0;  
1445
	register unsigned char runLength=1;
1446
     5c4:	71 e0       	ldi	r23, 0x01	; 1
1447
	unsigned char i;
1448
	bool_t colorConnected;	
1449
 
1450
	do
1451
	{
1452
		/* grab both the current color and the number of pixels
1453
		in the run...remember, pixels start at 1, not 0! */
1454
		colorConnected = FALSE;
1455
     5c6:	10 e0       	ldi	r17, 0x00	; 0
1456
		currColor = *pCurrLineColorInfo++;
1457
     5c8:	5d 91       	ld	r21, X+
1458
		currPixelRunStart += runLength;
1459
     5ca:	c7 0f       	add	r28, r23
1460
		runLength = *pCurrLineColorInfo++;
1461
     5cc:	7d 91       	ld	r23, X+
1462
		currPixelRunFinish += runLength;
1463
     5ce:	67 0f       	add	r22, r23
1464
 
1465
        /* make sure that the run-length is at least as wide as
1466
        the minimum horizontal tracking width, and we care about the color */ 
1467
 
1468
		if ( (currColor != notTracked) && (runLength > MIN_OBJECT_TRACKING_WIDTH) )
1469
     5d0:	55 23       	and	r21, r21
1470
     5d2:	09 f4       	brne	.+2      	; 0x5d6
1471
     5d4:	5d c0       	rjmp	.+186    	; 0x690
1472
     5d6:	74 30       	cpi	r23, 0x04	; 4
1473
     5d8:	08 f4       	brcc	.+2      	; 0x5dc
1474
     5da:	5a c0       	rjmp	.+180    	; 0x690
1475
		{			
1476
            /* this run contains a color we care about, so 
1477
			either it will begin a new tracked object, or it
1478
			is connected to a currently tracked object...
1479
			compare it with each object in the tracking
1480
			table...we can't just look at the numTrackedObjects because
1481
            it is entirely possible that the first couple of objects could
1482
            be invalid...
1483
 
1484
            NOTE: Instead of accessing each element in the trackedObjectTable
1485
            through the 'i' index, and then accessing the fields in each structure,
1486
            a pointer to each entry is established each time through the loop, followed
1487
            by accessing the elements through specified offsets.  GCC seems to be
1488
            able to optimize this code much better than simply accessing the elements
1489
            of each structure in the array the more normal way...*/
1490
 
1491
            pTrackedObjectData = (unsigned char *)pCurrentTrackedObjectTable;
1492
     5dc:	e0 91 60 00 	lds	r30, 0x0060
1493
     5e0:	f0 91 61 00 	lds	r31, 0x0061
1494
			for (i=0; i<MAX_TRACKED_OBJECTS; i++)
1495
     5e4:	41 2f       	mov	r20, r17
1496
			{
1497
				if ( (currColor == *(pTrackedObjectData + COLOR_OFFSET)) && 
1498
     5e6:	80 81       	ld	r24, Z
1499
     5e8:	58 17       	cp	r21, r24
1500
     5ea:	51 f5       	brne	.+84     	; 0x640
1501
     5ec:	87 81       	ldd	r24, Z+7	; 0x07
1502
     5ee:	81 30       	cpi	r24, 0x01	; 1
1503
     5f0:	39 f5       	brne	.+78     	; 0x640
1504
     5f2:	86 81       	ldd	r24, Z+6	; 0x06
1505
     5f4:	28 2f       	mov	r18, r24
1506
     5f6:	33 27       	eor	r19, r19
1507
     5f8:	80 91 77 00 	lds	r24, 0x0077
1508
     5fc:	99 27       	eor	r25, r25
1509
     5fe:	01 97       	sbiw	r24, 0x01	; 1
1510
     600:	28 17       	cp	r18, r24
1511
     602:	39 07       	cpc	r19, r25
1512
     604:	e9 f4       	brne	.+58     	; 0x640
1513
                     (*(pTrackedObjectData + VALID_OBJECT_OFFSET) == TRUE) &&
1514
                     (*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) == trackedLineCount - 1) )
1515
				{
1516
					/* found a color match and the object is valid...check to see if there is
1517
					connectedness */
1518
					lastLineXStart = *(pTrackedObjectData + LAST_LINE_X_START_OFFSET);
1519
     606:	81 81       	ldd	r24, Z+1	; 0x01
1520
					lastLineXFinish = *(pTrackedObjectData + LAST_LINE_X_FINISH_OFFSET);
1521
     608:	92 81       	ldd	r25, Z+2	; 0x02
1522
 
1523
					/* Check for the 5 following types of line connectedness:
1524
					---------------------
1525
					|                   |
1526
					---------------------
1527
					         -------------------------
1528
							 |                       |
1529
							 -------------------------  */
1530
					if ( (	(currPixelRunStart >= lastLineXStart) &&
1531
     60a:	c8 17       	cp	r28, r24
1532
     60c:	10 f0       	brcs	.+4      	; 0x612
1533
     60e:	9c 17       	cp	r25, r28
1534
     610:	40 f4       	brcc	.+16     	; 0x622
1535
     612:	68 17       	cp	r22, r24
1536
     614:	10 f0       	brcs	.+4      	; 0x61a
1537
     616:	96 17       	cp	r25, r22
1538
     618:	20 f4       	brcc	.+8      	; 0x622
1539
     61a:	8c 17       	cp	r24, r28
1540
     61c:	88 f0       	brcs	.+34     	; 0x640
1541
     61e:	69 17       	cp	r22, r25
1542
     620:	78 f0       	brcs	.+30     	; 0x640
1543
							(currPixelRunStart <= lastLineXFinish) )  ||
1544
 
1545
					/*               ---------------------
1546
					                 |                   |
1547
									 ---------------------
1548
						-------------------
1549
						|                 |
1550
						-------------------  
1551
						                   OR
1552
						     ------------------------------
1553
							 |                            |
1554
							 ------------------------------
1555
							              ---------
1556
										  |       |
1557
										  ---------  */
1558
						 (	(currPixelRunFinish >= lastLineXStart) && 
1559
							(currPixelRunFinish <= lastLineXFinish) ) ||
1560
 
1561
 
1562
					/*     -------------------------------
1563
					       |                             |
1564
						   -------------------------------
1565
						   -------------------------------
1566
						   |                             |
1567
						   -------------------------------
1568
						                  OR
1569
								     -------------
1570
									 |           |
1571
									 -------------
1572
							-------------------------------
1573
							|                             |
1574
							-------------------------------   */
1575
						 (  (currPixelRunStart <= lastLineXStart) &&
1576
							(currPixelRunFinish >= lastLineXFinish) ) )
1577
					{
1578
						/* THERE IS CONNECTEDNESS...update the lastLineXStart and lastLineXFinish
1579
						data pointed to by pTrackedObjectData */
1580
						*(pTrackedObjectData + LAST_LINE_X_START_OFFSET) = currPixelRunStart;
1581
     622:	c1 83       	std	Z+1, r28	; 0x01
1582
						*(pTrackedObjectData + LAST_LINE_X_FINISH_OFFSET) = currPixelRunFinish;
1583
     624:	62 83       	std	Z+2, r22	; 0x02
1584
 
1585
						/* check if the bounding box needs to be updated */
1586
						if (*(pTrackedObjectData + X_UPPER_LEFT_OFFSET) > currPixelRunStart)
1587
     626:	83 81       	ldd	r24, Z+3	; 0x03
1588
     628:	c8 17       	cp	r28, r24
1589
     62a:	08 f4       	brcc	.+2      	; 0x62e
1590
						{
1591
							/* need to update the bounding box for the upper left point to 
1592
							enclose this new left-most point...we never have to update the
1593
							upper left Y point, since each scan line we process moves from
1594
							top to bottom */
1595
							*(pTrackedObjectData + X_UPPER_LEFT_OFFSET) = currPixelRunStart;
1596
     62c:	c3 83       	std	Z+3, r28	; 0x03
1597
						}
1598
 
1599
						if ( *(pTrackedObjectData + X_LOWER_RIGHT_OFFSET) < currPixelRunFinish)
1600
     62e:	85 81       	ldd	r24, Z+5	; 0x05
1601
     630:	86 17       	cp	r24, r22
1602
     632:	08 f4       	brcc	.+2      	; 0x636
1603
						{
1604
							/* need to update the bounding box for the lower right X point to
1605
							enclose this new right-most point */
1606
							*(pTrackedObjectData + X_LOWER_RIGHT_OFFSET) = currPixelRunFinish;
1607
     634:	65 83       	std	Z+5, r22	; 0x05
1608
						}
1609
 
1610
						/* the lower right 'y' point always gets updated when connectedness is found */
1611
						*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) = trackedLineCount;
1612
     636:	80 91 77 00 	lds	r24, 0x0077
1613
     63a:	86 83       	std	Z+6, r24	; 0x06
1614
 
1615
						/* set a flag indicating that that color run is part of another
1616
						object and thus doesn't need to be added as a new entry into the
1617
						tracking table */
1618
						colorConnected = TRUE;
1619
     63c:	11 e0       	ldi	r17, 0x01	; 1
1620
						break;
1621
     63e:	04 c0       	rjmp	.+8      	; 0x648
1622
					}
1623
				}
1624
 
1625
                /* go to the next object */
1626
                pTrackedObjectData += SIZE_OF_TRACKED_OBJECT;
1627
     640:	38 96       	adiw	r30, 0x08	; 8
1628
     642:	4f 5f       	subi	r20, 0xFF	; 255
1629
     644:	48 30       	cpi	r20, 0x08	; 8
1630
     646:	78 f2       	brcs	.-98     	; 0x5e6
1631
			}
1632
 
1633
			if (colorConnected == FALSE)
1634
     648:	11 23       	and	r17, r17
1635
     64a:	11 f5       	brne	.+68     	; 0x690
1636
			{
1637
				/* a new entry needs to be made to the tracking table, since we have
1638
				a run-length with a color, and it isn't connected to anything...but we
1639
				can only do this if there is space left in the trackedObject table */
1640
				if (numCurrTrackedObjects < MAX_TRACKED_OBJECTS)
1641
     64c:	80 91 75 00 	lds	r24, 0x0075
1642
     650:	88 30       	cpi	r24, 0x08	; 8
1643
     652:	f0 f4       	brcc	.+60     	; 0x690
1644
				{                
1645
                    /* space is available...add the object...but first we need to find an
1646
                    invalid object in the object tracking table */
1647
                    pTrackedObjectData = (unsigned char *)pCurrentTrackedObjectTable;
1648
     654:	e0 91 60 00 	lds	r30, 0x0060
1649
     658:	f0 91 61 00 	lds	r31, 0x0061
1650
                    for (i=0; i<MAX_TRACKED_OBJECTS; i++)
1651
     65c:	41 2f       	mov	r20, r17
1652
                    {
1653
                        if ( *(pTrackedObjectData + VALID_OBJECT_OFFSET) == FALSE)  break;
1654
     65e:	87 81       	ldd	r24, Z+7	; 0x07
1655
     660:	88 23       	and	r24, r24
1656
     662:	21 f0       	breq	.+8      	; 0x66c
1657
 
1658
                        /* if we haven't broken above, then the object must have been valid...
1659
                        go ahead and move the pointer to the next object to check it */
1660
                        pTrackedObjectData += SIZE_OF_TRACKED_OBJECT;
1661
     664:	38 96       	adiw	r30, 0x08	; 8
1662
     666:	4f 5f       	subi	r20, 0xFF	; 255
1663
     668:	48 30       	cpi	r20, 0x08	; 8
1664
     66a:	c8 f3       	brcs	.-14     	; 0x65e
1665
                    }
1666
 
1667
 
1668
					/* now that we have a pointer to the tracked object to be updated, update all
1669
					the fields */
1670
					*(pTrackedObjectData + COLOR_OFFSET)                = currColor;			/* color */
1671
     66c:	50 83       	st	Z, r21
1672
					*(pTrackedObjectData + LAST_LINE_X_START_OFFSET)    = currPixelRunStart; 	/* lastLineXStart */
1673
     66e:	c1 83       	std	Z+1, r28	; 0x01
1674
					*(pTrackedObjectData + LAST_LINE_X_FINISH_OFFSET)   = currPixelRunFinish;	/* lastLineXFinish */
1675
     670:	62 83       	std	Z+2, r22	; 0x02
1676
					*(pTrackedObjectData + X_UPPER_LEFT_OFFSET)         = currPixelRunStart;	/* x_upperLeft */
1677
     672:	c3 83       	std	Z+3, r28	; 0x03
1678
					*(pTrackedObjectData + Y_UPPER_LEFT_OFFSET)         = trackedLineCount;	/* y_upperLeft */
1679
     674:	80 91 77 00 	lds	r24, 0x0077
1680
     678:	84 83       	std	Z+4, r24	; 0x04
1681
					*(pTrackedObjectData + X_LOWER_RIGHT_OFFSET)        = currPixelRunFinish;	/* x_lowerRight */
1682
     67a:	65 83       	std	Z+5, r22	; 0x05
1683
					*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET)        = trackedLineCount;	/* y_lowerRight */
1684
     67c:	80 91 77 00 	lds	r24, 0x0077
1685
     680:	86 83       	std	Z+6, r24	; 0x06
1686
                    *(pTrackedObjectData + VALID_OBJECT_OFFSET)         = TRUE;                /* objectValid flag */
1687
     682:	81 e0       	ldi	r24, 0x01	; 1
1688
     684:	87 83       	std	Z+7, r24	; 0x07
1689
 
1690
					numCurrTrackedObjects++;
1691
     686:	80 91 75 00 	lds	r24, 0x0075
1692
     68a:	8f 5f       	subi	r24, 0xFF	; 255
1693
     68c:	80 93 75 00 	sts	0x0075, r24
1694
				}
1695
			}
1696
 
1697
            /* move the pointer to the beginning of the next tracked object */
1698
            pTrackedObjectData += SIZE_OF_TRACKED_OBJECT;
1699
		}
1700
	} while(currPixelRunFinish < ACTUAL_NUM_PIXELS_IN_A_LINE);
1701
     690:	60 3b       	cpi	r22, 0xB0	; 176
1702
     692:	08 f4       	brcc	.+2      	; 0x696
1703
     694:	98 cf       	rjmp	.-208    	; 0x5c6
1704
}
1705
     696:	cf 91       	pop	r28
1706
     698:	1f 91       	pop	r17
1707
     69a:	08 95       	ret
1708
 
1709
0000069c <UIMgr_init>:
1710
	Outputs: none
1711
***********************************************************/	
1712
void UIMgr_init(void)
1713
{
1714
	memset(asciiTokenBuffer,0x00,MAX_TOKEN_LENGTH+1);
1715
     69c:	10 92 bf 00 	sts	0x00BF, r1
1716
     6a0:	10 92 c0 00 	sts	0x00C0, r1
1717
     6a4:	10 92 c1 00 	sts	0x00C1, r1
1718
     6a8:	10 92 c2 00 	sts	0x00C2, r1
1719
	memset(tokenBuffer,0x00,MAX_TOKEN_COUNT);
1720
     6ac:	80 e4       	ldi	r24, 0x40	; 64
1721
     6ae:	e3 ec       	ldi	r30, 0xC3	; 195
1722
     6b0:	f0 e0       	ldi	r31, 0x00	; 0
1723
     6b2:	11 92       	st	Z+, r1
1724
     6b4:	8a 95       	dec	r24
1725
     6b6:	e9 f7       	brne	.-6      	; 0x6b2
1726
	memset(UIMgr_txFifo,0x00,UI_MGR_TX_FIFO_SIZE);
1727
     6b8:	80 e4       	ldi	r24, 0x40	; 64
1728
     6ba:	e4 e9       	ldi	r30, 0x94	; 148
1729
     6bc:	f2 e0       	ldi	r31, 0x02	; 2
1730
     6be:	11 92       	st	Z+, r1
1731
     6c0:	8a 95       	dec	r24
1732
     6c2:	e9 f7       	brne	.-6      	; 0x6be
1733
	memset(UIMgr_rxFifo,0x00,UI_MGR_RX_FIFO_SIZE);
1734
     6c4:	80 e2       	ldi	r24, 0x20	; 32
1735
     6c6:	e4 e7       	ldi	r30, 0x74	; 116
1736
     6c8:	f2 e0       	ldi	r31, 0x02	; 2
1737
     6ca:	11 92       	st	Z+, r1
1738
     6cc:	8a 95       	dec	r24
1739
     6ce:	e9 f7       	brne	.-6      	; 0x6ca
1740
}
1741
     6d0:	08 95       	ret
1742
 
1743
000006d2 <UIMgr_dispatchEvent>:
1744
 
1745
/***********************************************************
1746
	Function Name: UIMgr_dispatchEvent
1747
	Function Description: This function is responsible for
1748
	processing events that pertain to the UIMgr.
1749
	Inputs:  event - the generated event
1750
	Outputs: none
1751
***********************************************************/	
1752
void UIMgr_dispatchEvent(unsigned char event)
1753
{
1754
	switch(event)
1755
     6d2:	99 27       	eor	r25, r25
1756
     6d4:	80 31       	cpi	r24, 0x10	; 16
1757
     6d6:	91 05       	cpc	r25, r1
1758
     6d8:	51 f0       	breq	.+20     	; 0x6ee
1759
     6da:	81 31       	cpi	r24, 0x11	; 17
1760
     6dc:	91 05       	cpc	r25, r1
1761
     6de:	1c f4       	brge	.+6      	; 0x6e6
1762
     6e0:	01 97       	sbiw	r24, 0x01	; 1
1763
     6e2:	39 f0       	breq	.+14     	; 0x6f2
1764
	{
1765
		case EV_ACQUIRE_LINE_COMPLETE:
1766
			UIMgr_transmitPendingData();
1767
			break;
1768
 
1769
		case EV_SERIAL_DATA_RECEIVED:		
1770
			UIMgr_processReceivedData();
1771
			break;
1772
 
1773
		case EV_SERIAL_DATA_PENDING_TX:
1774
			UIMgr_flushTxBuffer();
1775
			break;
1776
	}
1777
}
1778
     6e4:	08 95       	ret
1779
     6e6:	80 39       	cpi	r24, 0x90	; 144
1780
     6e8:	91 05       	cpc	r25, r1
1781
     6ea:	29 f0       	breq	.+10     	; 0x6f6
1782
     6ec:	08 95       	ret
1783
     6ee:	06 d0       	rcall	.+12     	; 0x6fc
1784
     6f0:	08 95       	ret
1785
     6f2:	0e d0       	rcall	.+28     	; 0x710
1786
     6f4:	08 95       	ret
1787
     6f6:	e6 d1       	rcall	.+972    	; 0xac4
1788
     6f8:	08 95       	ret
1789
     6fa:	08 95       	ret
1790
 
1791
000006fc <UIMgr_transmitPendingData>:
1792
/***********************************************************
1793
	Function Name: UIMgr_transmitPendingData
1794
	Function Description: This function is responsible for
1795
	transmitting a single byte of data if data is waiting
1796
	to be sent.  Otherwise, if nothing is waiting, the
1797
	function just returns.
1798
	Inputs:  none 
1799
	Outputs: none
1800
***********************************************************/
1801
void UIMgr_transmitPendingData(void)
1802
{
1803
	if (IS_DATA_IN_TX_FIFO() == TRUE)
1804
     6fc:	90 91 ba 00 	lds	r25, 0x00BA
1805
     700:	80 91 bb 00 	lds	r24, 0x00BB
1806
     704:	98 17       	cp	r25, r24
1807
     706:	11 f0       	breq	.+4      	; 0x70c
1808
	{
1809
		/* data is waiting...send a single byte */
1810
		UartInt_txByte( UIMgr_readTxFifo() );
1811
     708:	fe d1       	rcall	.+1020   	; 0xb06
1812
     70a:	2a d2       	rcall	.+1108   	; 0xb60
1813
	}
1814
}
1815
     70c:	08 95       	ret
1816
     70e:	08 95       	ret
1817
 
1818
00000710 <UIMgr_processReceivedData>:
1819
/***********************************************************
1820
	Function Name: UIMgr_processReceivedData
1821
	Function Description: This function is responsible for
1822
	parsing any serial data waiting in the rx fifo
1823
	Inputs:  none 
1824
	Outputs: none
1825
***********************************************************/
1826
void UIMgr_processReceivedData(void)
1827
{
1828
     710:	cf 93       	push	r28
1829
	unsigned char tmpData = 0;
1830
 
1831
	/* still need to add a mechanism to handle token counts 
1832
	that are excessive!!! FIX ME!!! */
1833
 
1834
	while(IS_DATA_IN_RX_FIFO() == TRUE)
1835
     712:	90 91 b8 00 	lds	r25, 0x00B8
1836
     716:	80 91 b9 00 	lds	r24, 0x00B9
1837
     71a:	98 17       	cp	r25, r24
1838
     71c:	09 f4       	brne	.+2      	; 0x720
1839
     71e:	6f c0       	rjmp	.+222    	; 0x7fe
1840
     720:	c9 e0       	ldi	r28, 0x09	; 9
1841
	{
1842
		tmpData = UIMgr_readRxFifo();
1843
     722:	df d1       	rcall	.+958    	; 0xae2
1844
     724:	38 2f       	mov	r19, r24
1845
		if (tmpData == '\r') 
1846
     726:	8d 30       	cpi	r24, 0x0D	; 13
1847
     728:	29 f5       	brne	.+74     	; 0x774
1848
		{
1849
			/* we have reached a token separator */
1850
			if (tokenCount == 0)
1851
     72a:	80 91 be 00 	lds	r24, 0x00BE
1852
     72e:	88 23       	and	r24, r24
1853
     730:	11 f4       	brne	.+4      	; 0x736
1854
			{
1855
				/* convert the command */
1856
				UIMgr_convertTokenToCmd();				
1857
     732:	2c d1       	rcall	.+600    	; 0x98c
1858
     734:	06 c0       	rjmp	.+12     	; 0x742
1859
			}
1860
			else
1861
			{
1862
				/* convert a value */
1863
				UIMgr_convertTokenToValue();
1864
     736:	02 d1       	rcall	.+516    	; 0x93c
1865
				tokenCount++;
1866
     738:	80 91 be 00 	lds	r24, 0x00BE
1867
     73c:	8f 5f       	subi	r24, 0xFF	; 255
1868
     73e:	80 93 be 00 	sts	0x00BE, r24
1869
			}
1870
			/* either way, it is time to try to process the received
1871
			token list since we have reached the end of the cmd. */
1872
			Utility_delay(100);
1873
     742:	84 e6       	ldi	r24, 0x64	; 100
1874
     744:	90 e0       	ldi	r25, 0x00	; 0
1875
     746:	7f d3       	rcall	.+1790   	; 0xe46
1876
			if (receivedCmd == invalidCmd ||
1877
     748:	80 91 62 00 	lds	r24, 0x0062
1878
     74c:	88 50       	subi	r24, 0x08	; 8
1879
     74e:	82 30       	cpi	r24, 0x02	; 2
1880
     750:	20 f4       	brcc	.+8      	; 0x75a
1881
			     receivedCmd == noCmd )
1882
			{
1883
				UIMgr_sendNck();
1884
     752:	84 d1       	rcall	.+776    	; 0xa5c
1885
				PUBLISH_EVENT(EV_SERIAL_DATA_PENDING_TX);
1886
     754:	80 e9       	ldi	r24, 0x90	; 144
1887
     756:	7d dd       	rcall	.-1286   	; 0x252
1888
     758:	04 c0       	rjmp	.+8      	; 0x762
1889
			}
1890
			else
1891
			{
1892
				UIMgr_sendAck();
1893
     75a:	77 d1       	rcall	.+750    	; 0xa4a
1894
				/* publish the serial data pending event, so it
1895
				will push the ACK out before we execute the cmd */
1896
				PUBLISH_EVENT(EV_SERIAL_DATA_PENDING_TX);
1897
     75c:	80 e9       	ldi	r24, 0x90	; 144
1898
     75e:	79 dd       	rcall	.-1294   	; 0x252
1899
				UIMgr_executeCmd();
1900
     760:	51 d0       	rcall	.+162    	; 0x804
1901
			}
1902
 
1903
			/* reset any necessary data */
1904
			tokenCount = 0;
1905
     762:	10 92 be 00 	sts	0x00BE, r1
1906
			memset(tokenBuffer,0x00,MAX_TOKEN_COUNT);
1907
     766:	80 e4       	ldi	r24, 0x40	; 64
1908
     768:	e3 ec       	ldi	r30, 0xC3	; 195
1909
     76a:	f0 e0       	ldi	r31, 0x00	; 0
1910
     76c:	11 92       	st	Z+, r1
1911
     76e:	8a 95       	dec	r24
1912
     770:	e9 f7       	brne	.-6      	; 0x76c
1913
     772:	3e c0       	rjmp	.+124    	; 0x7f0
1914
		}
1915
		else if (tmpData == ' ')  /* space char */
1916
     774:	80 32       	cpi	r24, 0x20	; 32
1917
     776:	d9 f4       	brne	.+54     	; 0x7ae
1918
		{
1919
			/* the end of a token has been reached */
1920
			if (tokenCount == 0)
1921
     778:	80 91 be 00 	lds	r24, 0x00BE
1922
     77c:	88 23       	and	r24, r24
1923
     77e:	11 f4       	brne	.+4      	; 0x784
1924
			{
1925
				UIMgr_convertTokenToCmd();
1926
     780:	05 d1       	rcall	.+522    	; 0x98c
1927
				tokenCount++;   /* check this...why is this being incremented here??? This
1928
     782:	0f c0       	rjmp	.+30     	; 0x7a2
1929
                means we have received a token, with tokenCount == 0, which means it is a
1930
                command...why is this contributing to tokenCount?
1931
                This might cause the set color map command to include too much data, since
1932
                it sets the color map based on tokenCount...CHECK*/
1933
			}
1934
			else
1935
			{
1936
				/* check to see if this token is going to push
1937
				us over the limit...if so, abort the transaction */
1938
				if (tokenCount+1 >= MAX_TOKEN_COUNT)
1939
     784:	80 91 be 00 	lds	r24, 0x00BE
1940
     788:	99 27       	eor	r25, r25
1941
     78a:	01 96       	adiw	r24, 0x01	; 1
1942
     78c:	80 34       	cpi	r24, 0x40	; 64
1943
     78e:	91 05       	cpc	r25, r1
1944
     790:	3c f0       	brlt	.+14     	; 0x7a0
1945
				{
1946
					/* we received too many tokens, and 
1947
					need to NCK this request, since its too
1948
					large...reset everything...*/
1949
					charCount=0;
1950
     792:	10 92 bc 00 	sts	0x00BC, r1
1951
					charIndex=0;
1952
     796:	10 92 bd 00 	sts	0x00BD, r1
1953
					tokenCount=0;
1954
     79a:	10 92 be 00 	sts	0x00BE, r1
1955
					receivedCmd = invalidCmd;
1956
     79e:	26 c0       	rjmp	.+76     	; 0x7ec
1957
				}
1958
				else
1959
				{
1960
					/* tokenCount is still in range...*/
1961
					UIMgr_convertTokenToValue();
1962
     7a0:	cd d0       	rcall	.+410    	; 0x93c
1963
					tokenCount++;
1964
     7a2:	80 91 be 00 	lds	r24, 0x00BE
1965
     7a6:	8f 5f       	subi	r24, 0xFF	; 255
1966
     7a8:	80 93 be 00 	sts	0x00BE, r24
1967
     7ac:	21 c0       	rjmp	.+66     	; 0x7f0
1968
				}
1969
			}
1970
		}
1971
		else if ( (tmpData >= 'A' && tmpData <= 'Z') ||
1972
     7ae:	81 54       	subi	r24, 0x41	; 65
1973
     7b0:	8a 31       	cpi	r24, 0x1A	; 26
1974
     7b2:	18 f0       	brcs	.+6      	; 0x7ba
1975
     7b4:	8f 5e       	subi	r24, 0xEF	; 239
1976
     7b6:	8a 30       	cpi	r24, 0x0A	; 10
1977
     7b8:	c8 f4       	brcc	.+50     	; 0x7ec
1978
				   (tmpData >= '0' && tmpData <= '9') )
1979
		{
1980
			/* a valid range of token was received */
1981
			asciiTokenBuffer[charIndex] = tmpData;
1982
     7ba:	20 91 bd 00 	lds	r18, 0x00BD
1983
     7be:	82 2f       	mov	r24, r18
1984
     7c0:	99 27       	eor	r25, r25
1985
     7c2:	fc 01       	movw	r30, r24
1986
     7c4:	e1 54       	subi	r30, 0x41	; 65
1987
     7c6:	ff 4f       	sbci	r31, 0xFF	; 255
1988
     7c8:	30 83       	st	Z, r19
1989
			charCount++;
1990
     7ca:	80 91 bc 00 	lds	r24, 0x00BC
1991
     7ce:	98 2f       	mov	r25, r24
1992
     7d0:	9f 5f       	subi	r25, 0xFF	; 255
1993
     7d2:	90 93 bc 00 	sts	0x00BC, r25
1994
			charIndex++;
1995
     7d6:	82 2f       	mov	r24, r18
1996
     7d8:	8f 5f       	subi	r24, 0xFF	; 255
1997
     7da:	80 93 bd 00 	sts	0x00BD, r24
1998
			if (charCount > MAX_TOKEN_LENGTH)
1999
     7de:	94 30       	cpi	r25, 0x04	; 4
2000
     7e0:	38 f0       	brcs	.+14     	; 0x7f0
2001
			{
2002
				/* we have received a token that cannot be handled...
2003
				set the received cmd to an invalid cmd, and wait
2004
				for the \r to process it */
2005
				receivedCmd = invalidCmd;
2006
     7e2:	c0 93 62 00 	sts	0x0062, r28
2007
				charIndex = 0;  /* ...so we won't overwrite memory */
2008
     7e6:	10 92 bd 00 	sts	0x00BD, r1
2009
     7ea:	02 c0       	rjmp	.+4      	; 0x7f0
2010
			}
2011
		}
2012
		else
2013
		{
2014
			/* an invalid character was received */
2015
			receivedCmd = invalidCmd;
2016
     7ec:	c0 93 62 00 	sts	0x0062, r28
2017
     7f0:	90 91 b8 00 	lds	r25, 0x00B8
2018
     7f4:	80 91 b9 00 	lds	r24, 0x00B9
2019
     7f8:	98 17       	cp	r25, r24
2020
     7fa:	09 f0       	breq	.+2      	; 0x7fe
2021
     7fc:	92 cf       	rjmp	.-220    	; 0x722
2022
		}
2023
	}  /* end while */
2024
 
2025
	asm volatile("clt"::);  /* clear out the T flag in case it wasn't
2026
     7fe:	e8 94       	clt
2027
								 cleared already */
2028
}						
2029
     800:	cf 91       	pop	r28
2030
     802:	08 95       	ret
2031
 
2032
00000804 <UIMgr_executeCmd>:
2033
 
2034
/***********************************************************
2035
	Function Name: UIMgr_executeCmd
2036
	Function Description: This function is responsible for
2037
	executing whatever cmd is stored in the receivedCmd
2038
	object.
2039
	Inputs:  none 
2040
	Outputs: none
2041
***********************************************************/
2042
static void UIMgr_executeCmd(void)
2043
{
2044
     804:	df 92       	push	r13
2045
     806:	ef 92       	push	r14
2046
     808:	ff 92       	push	r15
2047
     80a:	0f 93       	push	r16
2048
     80c:	1f 93       	push	r17
2049
     80e:	cf 93       	push	r28
2050
     810:	df 93       	push	r29
2051
	unsigned char i,eepromData, num_writes=0;
2052
     812:	ee 24       	eor	r14, r14
2053
	unsigned char *pData;
2054
    unsigned char eeprom_write_succeeded = FALSE;
2055
#if	DEBUG_COLOR_MAP	
2056
	unsigned char asciiBuffer[5];
2057
#endif
2058
 
2059
	if (receivedCmd == pingCmd) 
2060
     814:	80 91 62 00 	lds	r24, 0x0062
2061
     818:	81 30       	cpi	r24, 0x01	; 1
2062
     81a:	09 f4       	brne	.+2      	; 0x81e
2063
     81c:	87 c0       	rjmp	.+270    	; 0x92c
2064
	{
2065
	}
2066
	else if (receivedCmd == getVersionCmd)
2067
     81e:	88 23       	and	r24, r24
2068
     820:	69 f4       	brne	.+26     	; 0x83c
2069
	{
2070
		pData = AVRcamVersion;
2071
     822:	c3 e6       	ldi	r28, 0x63	; 99
2072
     824:	d0 e0       	ldi	r29, 0x00	; 0
2073
		while(*pData != 0)
2074
     826:	80 91 63 00 	lds	r24, 0x0063
2075
     82a:	88 23       	and	r24, r24
2076
     82c:	09 f4       	brne	.+2      	; 0x830
2077
     82e:	7e c0       	rjmp	.+252    	; 0x92c
2078
		{		
2079
			UIMgr_writeTxFifo(*pData++);
2080
     830:	89 91       	ld	r24, Y+
2081
     832:	7b d1       	rcall	.+758    	; 0xb2a
2082
     834:	88 81       	ld	r24, Y
2083
     836:	88 23       	and	r24, r24
2084
     838:	d9 f7       	brne	.-10     	; 0x830
2085
     83a:	78 c0       	rjmp	.+240    	; 0x92c
2086
		}
2087
	}		
2088
	else if (receivedCmd == resetCameraCmd)
2089
     83c:	80 91 62 00 	lds	r24, 0x0062
2090
     840:	87 30       	cpi	r24, 0x07	; 7
2091
     842:	11 f4       	brne	.+4      	; 0x848
2092
	{
2093
		CamInt_resetCam();
2094
     844:	8b dc       	rcall	.-1770   	; 0x15c
2095
     846:	72 c0       	rjmp	.+228    	; 0x92c
2096
	}
2097
	else if (receivedCmd == dumpFrameCmd)
2098
     848:	80 91 62 00 	lds	r24, 0x0062
2099
     84c:	83 30       	cpi	r24, 0x03	; 3
2100
     84e:	29 f4       	brne	.+10     	; 0x85a
2101
	{
2102
		/* publish the event that will indicate that
2103
		a request has come to dump a frame...this will
2104
		be received by the FrameMgr, which will begin
2105
		dumping the frame...a short delay is needed
2106
		here to keep the Java demo app happy (sometimes
2107
		it wouldn't be able to receive the serial data
2108
		as quickly as AVRcam can provide it). */
2109
		Utility_delay(100);
2110
     850:	84 e6       	ldi	r24, 0x64	; 100
2111
     852:	90 e0       	ldi	r25, 0x00	; 0
2112
     854:	f8 d2       	rcall	.+1520   	; 0xe46
2113
		PUBLISH_EVENT(EV_DUMP_FRAME);
2114
     856:	82 e0       	ldi	r24, 0x02	; 2
2115
     858:	28 c0       	rjmp	.+80     	; 0x8aa
2116
	}
2117
	else if (receivedCmd == setCameraRegsCmd)
2118
     85a:	80 91 62 00 	lds	r24, 0x0062
2119
     85e:	82 30       	cpi	r24, 0x02	; 2
2120
     860:	b1 f4       	brne	.+44     	; 0x88e
2121
	{
2122
		/* we need to gather the tokens and
2123
		build config cmds to be sent to the camera */
2124
		for (i=1; i<tokenCount; i+=2)  /* starts at 1 since first token
2125
     862:	ff 24       	eor	r15, r15
2126
     864:	f3 94       	inc	r15
2127
     866:	80 91 be 00 	lds	r24, 0x00BE
2128
     86a:	f8 16       	cp	r15, r24
2129
     86c:	70 f4       	brcc	.+28     	; 0x88a
2130
											is the CR cmd */
2131
		{
2132
			CamConfig_setCamReg(tokenBuffer[i],tokenBuffer[i+1]);
2133
     86e:	8f 2d       	mov	r24, r15
2134
     870:	99 27       	eor	r25, r25
2135
     872:	fc 01       	movw	r30, r24
2136
     874:	ed 53       	subi	r30, 0x3D	; 61
2137
     876:	ff 4f       	sbci	r31, 0xFF	; 255
2138
     878:	61 81       	ldd	r22, Z+1	; 0x01
2139
     87a:	80 81       	ld	r24, Z
2140
     87c:	85 d2       	rcall	.+1290   	; 0xd88
2141
     87e:	82 e0       	ldi	r24, 0x02	; 2
2142
     880:	f8 0e       	add	r15, r24
2143
     882:	80 91 be 00 	lds	r24, 0x00BE
2144
     886:	f8 16       	cp	r15, r24
2145
     888:	90 f3       	brcs	.-28     	; 0x86e
2146
		}
2147
		CamConfig_sendFifoCmds();
2148
     88a:	83 d2       	rcall	.+1286   	; 0xd92
2149
     88c:	4f c0       	rjmp	.+158    	; 0x92c
2150
	}
2151
	else if (receivedCmd == enableTrackingCmd)
2152
     88e:	80 91 62 00 	lds	r24, 0x0062
2153
     892:	84 30       	cpi	r24, 0x04	; 4
2154
     894:	29 f4       	brne	.+10     	; 0x8a0
2155
	{
2156
		/* publish the event...again with a short delay */
2157
		Utility_delay(100);
2158
     896:	84 e6       	ldi	r24, 0x64	; 100
2159
     898:	90 e0       	ldi	r25, 0x00	; 0
2160
     89a:	d5 d2       	rcall	.+1450   	; 0xe46
2161
		PUBLISH_EVENT(EV_ENABLE_TRACKING);
2162
     89c:	80 e8       	ldi	r24, 0x80	; 128
2163
     89e:	05 c0       	rjmp	.+10     	; 0x8aa
2164
	}
2165
	else if (receivedCmd == disableTrackingCmd)
2166
     8a0:	80 91 62 00 	lds	r24, 0x0062
2167
     8a4:	85 30       	cpi	r24, 0x05	; 5
2168
     8a6:	19 f4       	brne	.+6      	; 0x8ae
2169
	{
2170
		PUBLISH_EVENT(EV_DISABLE_TRACKING);
2171
     8a8:	81 e8       	ldi	r24, 0x81	; 129
2172
     8aa:	d3 dc       	rcall	.-1626   	; 0x252
2173
     8ac:	3f c0       	rjmp	.+126    	; 0x92c
2174
	}
2175
	else if (receivedCmd == setColorMapCmd)
2176
     8ae:	80 91 62 00 	lds	r24, 0x0062
2177
     8b2:	86 30       	cpi	r24, 0x06	; 6
2178
     8b4:	d9 f5       	brne	.+118    	; 0x92c
2179
	{
2180
		/* copy the received tokens into the color map */
2181
		for (i=0; i<tokenCount; i++)
2182
     8b6:	ff 24       	eor	r15, r15
2183
     8b8:	80 91 be 00 	lds	r24, 0x00BE
2184
     8bc:	f8 16       	cp	r15, r24
2185
     8be:	b0 f5       	brcc	.+108    	; 0x92c
2186
		{
2187
			colorMap[i] = tokenBuffer[i+1];
2188
     8c0:	8f 2d       	mov	r24, r15
2189
     8c2:	99 27       	eor	r25, r25
2190
     8c4:	8c 01       	movw	r16, r24
2191
     8c6:	00 50       	subi	r16, 0x00	; 0
2192
     8c8:	1d 4f       	sbci	r17, 0xFD	; 253
2193
     8ca:	fc 01       	movw	r30, r24
2194
     8cc:	ed 53       	subi	r30, 0x3D	; 61
2195
     8ce:	ff 4f       	sbci	r31, 0xFF	; 255
2196
     8d0:	21 81       	ldd	r18, Z+1	; 0x01
2197
     8d2:	f8 01       	movw	r30, r16
2198
     8d4:	20 83       	st	Z, r18
2199
 
2200
            /* write each colorMap byte to EEPROM, but only those
2201
            that changed...this will help reduce wear on the EEPROM */
2202
            eepromData = eeprom_read_byte( (unsigned char*)(i+1));
2203
     8d6:	01 96       	adiw	r24, 0x01	; 1
2204
     8d8:	b5 d3       	rcall	.+1898   	; 0x1044
2205
     8da:	98 2f       	mov	r25, r24
2206
            if (eepromData != colorMap[i])
2207
     8dc:	f8 01       	movw	r30, r16
2208
     8de:	80 81       	ld	r24, Z
2209
     8e0:	98 17       	cp	r25, r24
2210
     8e2:	f9 f0       	breq	.+62     	; 0x922
2211
            {
2212
                /* need to actually perform the write because the
2213
                data in eeprom is different than the current colorMap */
2214
                eeprom_write_succeeded = FALSE;
2215
     8e4:	dd 24       	eor	r13, r13
2216
                while(eeprom_write_succeeded == FALSE && num_writes < MAX_EEPROM_WRITE_ATTEMPTS)
2217
     8e6:	f2 e0       	ldi	r31, 0x02	; 2
2218
     8e8:	fe 15       	cp	r31, r14
2219
     8ea:	d0 f0       	brcs	.+52     	; 0x920
2220
     8ec:	8f 2d       	mov	r24, r15
2221
     8ee:	99 27       	eor	r25, r25
2222
     8f0:	8c 01       	movw	r16, r24
2223
     8f2:	00 50       	subi	r16, 0x00	; 0
2224
     8f4:	1d 4f       	sbci	r17, 0xFD	; 253
2225
     8f6:	ec 01       	movw	r28, r24
2226
     8f8:	21 96       	adiw	r28, 0x01	; 1
2227
                {
2228
                    eeprom_write_byte((unsigned char*)(i+1),colorMap[i]);
2229
     8fa:	f8 01       	movw	r30, r16
2230
     8fc:	60 81       	ld	r22, Z
2231
     8fe:	ce 01       	movw	r24, r28
2232
     900:	ba d3       	rcall	.+1908   	; 0x1076
2233
                    num_writes++;
2234
     902:	e3 94       	inc	r14
2235
                    eepromData = eeprom_read_byte( (unsigned char*)(i+1));
2236
     904:	ce 01       	movw	r24, r28
2237
     906:	9e d3       	rcall	.+1852   	; 0x1044
2238
     908:	98 2f       	mov	r25, r24
2239
                    if (eepromData == colorMap[i])
2240
     90a:	f8 01       	movw	r30, r16
2241
     90c:	80 81       	ld	r24, Z
2242
     90e:	98 17       	cp	r25, r24
2243
     910:	11 f4       	brne	.+4      	; 0x916
2244
                    {
2245
                        eeprom_write_succeeded = TRUE;
2246
     912:	dd 24       	eor	r13, r13
2247
     914:	d3 94       	inc	r13
2248
     916:	dd 20       	and	r13, r13
2249
     918:	19 f4       	brne	.+6      	; 0x920
2250
     91a:	f2 e0       	ldi	r31, 0x02	; 2
2251
     91c:	fe 15       	cp	r31, r14
2252
     91e:	68 f7       	brcc	.-38     	; 0x8fa
2253
                    }
2254
                }
2255
                num_writes = 0;
2256
     920:	ee 24       	eor	r14, r14
2257
     922:	f3 94       	inc	r15
2258
     924:	80 91 be 00 	lds	r24, 0x00BE
2259
     928:	f8 16       	cp	r15, r24
2260
     92a:	50 f2       	brcs	.-108    	; 0x8c0
2261
            }
2262
		}
2263
 
2264
#if	DEBUG_COLOR_MAP			
2265
            			/* for debugging...send out the entire color map */
2266
        UIMgr_txBuffer("\r\n",2);
2267
		for (i=0; i<NUM_ELEMENTS_IN_COLOR_MAP; i++)
2268
		{
2269
			memset(asciiBuffer,0x00,5);
2270
			itoa(colorMap[i],asciiBuffer,10);
2271
			UIMgr_txBuffer(asciiBuffer,3);
2272
			UIMgr_txBuffer(" ",1);
2273
			if (i==15 || i == 31)
2274
			{
2275
				/* break up the output */
2276
				UIMgr_txBuffer("\r\n",2);
2277
			}
2278
		}
2279
#endif			
2280
	}
2281
}
2282
     92c:	df 91       	pop	r29
2283
     92e:	cf 91       	pop	r28
2284
     930:	1f 91       	pop	r17
2285
     932:	0f 91       	pop	r16
2286
     934:	ff 90       	pop	r15
2287
     936:	ef 90       	pop	r14
2288
     938:	df 90       	pop	r13
2289
     93a:	08 95       	ret
2290
 
2291
0000093c <UIMgr_convertTokenToValue>:
2292
 
2293
/***********************************************************
2294
	Function Name: UIMgr_convertTokenToValue
2295
	Function Description: This function is responsible for
2296
	converting a received token to a hex value It will
2297
	access the asciiTokenBuffer directly, and store the
2298
	result in the appropriate token buffer.
2299
	Inputs:  none 
2300
	Outputs: none
2301
***********************************************************/	
2302
static void UIMgr_convertTokenToValue(void)
2303
{
2304
	unsigned int newValue;
2305
 
2306
	newValue = atoi(asciiTokenBuffer);
2307
     93c:	8f eb       	ldi	r24, 0xBF	; 191
2308
     93e:	90 e0       	ldi	r25, 0x00	; 0
2309
     940:	55 d3       	rcall	.+1706   	; 0xfec
2310
     942:	ac 01       	movw	r20, r24
2311
	if (newValue > 255)
2312
     944:	8f 3f       	cpi	r24, 0xFF	; 255
2313
     946:	91 05       	cpc	r25, r1
2314
     948:	71 f0       	breq	.+28     	; 0x966
2315
     94a:	68 f0       	brcs	.+26     	; 0x966
2316
	{
2317
		/* the value is too large */
2318
		receivedCmd = invalidCmd;
2319
     94c:	89 e0       	ldi	r24, 0x09	; 9
2320
     94e:	80 93 62 00 	sts	0x0062, r24
2321
		tokenBuffer[tokenCount] = 0xFF;  /* to indicate an error */
2322
     952:	20 91 be 00 	lds	r18, 0x00BE
2323
     956:	83 ec       	ldi	r24, 0xC3	; 195
2324
     958:	90 e0       	ldi	r25, 0x00	; 0
2325
     95a:	fc 01       	movw	r30, r24
2326
     95c:	e2 0f       	add	r30, r18
2327
     95e:	f1 1d       	adc	r31, r1
2328
     960:	8f ef       	ldi	r24, 0xFF	; 255
2329
     962:	80 83       	st	Z, r24
2330
     964:	08 c0       	rjmp	.+16     	; 0x976
2331
	}
2332
	else
2333
	{
2334
		/* copy the value into the tokenBuffer */
2335
		tokenBuffer[tokenCount] = newValue;
2336
     966:	80 91 be 00 	lds	r24, 0x00BE
2337
     96a:	23 ec       	ldi	r18, 0xC3	; 195
2338
     96c:	30 e0       	ldi	r19, 0x00	; 0
2339
     96e:	f9 01       	movw	r30, r18
2340
     970:	e8 0f       	add	r30, r24
2341
     972:	f1 1d       	adc	r31, r1
2342
     974:	40 83       	st	Z, r20
2343
	}
2344
	memset(asciiTokenBuffer,0x00,MAX_TOKEN_LENGTH);
2345
     976:	83 e0       	ldi	r24, 0x03	; 3
2346
     978:	ef eb       	ldi	r30, 0xBF	; 191
2347
     97a:	f0 e0       	ldi	r31, 0x00	; 0
2348
     97c:	11 92       	st	Z+, r1
2349
     97e:	8a 95       	dec	r24
2350
     980:	e9 f7       	brne	.-6      	; 0x97c
2351
	charIndex = 0;
2352
     982:	10 92 bd 00 	sts	0x00BD, r1
2353
	charCount = 0;
2354
     986:	10 92 bc 00 	sts	0x00BC, r1
2355
}
2356
     98a:	08 95       	ret
2357
 
2358
0000098c <UIMgr_convertTokenToCmd>:
2359
/***********************************************************
2360
	Function Name: UIMgr_convertTokenToCmd
2361
	Function Description: This function is responsible for
2362
	parsing a received 2-character command.  It will
2363
	access the asciiTokenBuffer directly.
2364
	Inputs:  none 
2365
	Outputs: none
2366
***********************************************************/	
2367
static void UIMgr_convertTokenToCmd(void)
2368
{
2369
	if ( (asciiTokenBuffer[0] == 'P') &&
2370
     98c:	80 91 bf 00 	lds	r24, 0x00BF
2371
     990:	80 35       	cpi	r24, 0x50	; 80
2372
     992:	31 f4       	brne	.+12     	; 0x9a0
2373
     994:	80 91 c0 00 	lds	r24, 0x00C0
2374
     998:	87 34       	cpi	r24, 0x47	; 71
2375
     99a:	11 f4       	brne	.+4      	; 0x9a0
2376
		 (asciiTokenBuffer[1] == 'G') )
2377
	{
2378
		/* we got a "ping" command...but we still need to see
2379
		if we are going to get the \r */
2380
		receivedCmd = pingCmd;
2381
     99c:	81 e0       	ldi	r24, 0x01	; 1
2382
     99e:	48 c0       	rjmp	.+144    	; 0xa30
2383
	}
2384
	else if ( (asciiTokenBuffer[0] == 'G') &&
2385
     9a0:	80 91 bf 00 	lds	r24, 0x00BF
2386
     9a4:	87 34       	cpi	r24, 0x47	; 71
2387
     9a6:	39 f4       	brne	.+14     	; 0x9b6
2388
     9a8:	80 91 c0 00 	lds	r24, 0x00C0
2389
     9ac:	86 35       	cpi	r24, 0x56	; 86
2390
     9ae:	19 f4       	brne	.+6      	; 0x9b6
2391
			   (asciiTokenBuffer[1] == 'V') )
2392
	{
2393
		/* we got the "get version" command */
2394
		receivedCmd = getVersionCmd;
2395
     9b0:	10 92 62 00 	sts	0x0062, r1
2396
     9b4:	3f c0       	rjmp	.+126    	; 0xa34
2397
	}
2398
	else if ( (asciiTokenBuffer[0] == 'D') &&
2399
     9b6:	80 91 bf 00 	lds	r24, 0x00BF
2400
     9ba:	84 34       	cpi	r24, 0x44	; 68
2401
     9bc:	31 f4       	brne	.+12     	; 0x9ca
2402
     9be:	80 91 c0 00 	lds	r24, 0x00C0
2403
     9c2:	86 34       	cpi	r24, 0x46	; 70
2404
     9c4:	11 f4       	brne	.+4      	; 0x9ca
2405
			   (asciiTokenBuffer[1] == 'F') )
2406
	{
2407
		/* we should go into frame dump mode */
2408
		receivedCmd = dumpFrameCmd;	
2409
     9c6:	83 e0       	ldi	r24, 0x03	; 3
2410
     9c8:	33 c0       	rjmp	.+102    	; 0xa30
2411
	}
2412
	else if ( (asciiTokenBuffer[0] == 'C') &&
2413
     9ca:	80 91 bf 00 	lds	r24, 0x00BF
2414
     9ce:	83 34       	cpi	r24, 0x43	; 67
2415
     9d0:	31 f4       	brne	.+12     	; 0x9de
2416
     9d2:	80 91 c0 00 	lds	r24, 0x00C0
2417
     9d6:	82 35       	cpi	r24, 0x52	; 82
2418
     9d8:	11 f4       	brne	.+4      	; 0x9de
2419
	           (asciiTokenBuffer[1] == 'R') )
2420
	{
2421
		/* the user wants to set registers in the OV6620 */
2422
		receivedCmd = setCameraRegsCmd;
2423
     9da:	82 e0       	ldi	r24, 0x02	; 2
2424
     9dc:	29 c0       	rjmp	.+82     	; 0xa30
2425
	}
2426
	else if ( (asciiTokenBuffer[0] == 'E') &&
2427
     9de:	80 91 bf 00 	lds	r24, 0x00BF
2428
     9e2:	85 34       	cpi	r24, 0x45	; 69
2429
     9e4:	31 f4       	brne	.+12     	; 0x9f2
2430
     9e6:	80 91 c0 00 	lds	r24, 0x00C0
2431
     9ea:	84 35       	cpi	r24, 0x54	; 84
2432
     9ec:	11 f4       	brne	.+4      	; 0x9f2
2433
			   (asciiTokenBuffer[1] == 'T') )
2434
	{
2435
		/* the user wants to enable tracking */
2436
		receivedCmd = enableTrackingCmd;
2437
     9ee:	84 e0       	ldi	r24, 0x04	; 4
2438
     9f0:	1f c0       	rjmp	.+62     	; 0xa30
2439
	}
2440
	else if ( (asciiTokenBuffer[0] == 'S') &&
2441
     9f2:	80 91 bf 00 	lds	r24, 0x00BF
2442
     9f6:	83 35       	cpi	r24, 0x53	; 83
2443
     9f8:	31 f4       	brne	.+12     	; 0xa06
2444
     9fa:	80 91 c0 00 	lds	r24, 0x00C0
2445
     9fe:	8d 34       	cpi	r24, 0x4D	; 77
2446
     a00:	11 f4       	brne	.+4      	; 0xa06
2447
			   (asciiTokenBuffer[1] == 'M') )
2448
	{
2449
		/* the user wants to set the color map */
2450
		receivedCmd = setColorMapCmd;
2451
     a02:	86 e0       	ldi	r24, 0x06	; 6
2452
     a04:	15 c0       	rjmp	.+42     	; 0xa30
2453
	}
2454
	else if ( (asciiTokenBuffer[0] == 'D') &&
2455
     a06:	80 91 bf 00 	lds	r24, 0x00BF
2456
     a0a:	84 34       	cpi	r24, 0x44	; 68
2457
     a0c:	31 f4       	brne	.+12     	; 0xa1a
2458
     a0e:	80 91 c0 00 	lds	r24, 0x00C0
2459
     a12:	84 35       	cpi	r24, 0x54	; 84
2460
     a14:	11 f4       	brne	.+4      	; 0xa1a
2461
			   (asciiTokenBuffer[1] == 'T') )
2462
	{
2463
		receivedCmd = disableTrackingCmd;
2464
     a16:	85 e0       	ldi	r24, 0x05	; 5
2465
     a18:	0b c0       	rjmp	.+22     	; 0xa30
2466
	}
2467
	else if ( (asciiTokenBuffer[0] == 'R') &&
2468
     a1a:	80 91 bf 00 	lds	r24, 0x00BF
2469
     a1e:	82 35       	cpi	r24, 0x52	; 82
2470
     a20:	31 f4       	brne	.+12     	; 0xa2e
2471
     a22:	80 91 c0 00 	lds	r24, 0x00C0
2472
     a26:	83 35       	cpi	r24, 0x53	; 83
2473
     a28:	11 f4       	brne	.+4      	; 0xa2e
2474
			   (asciiTokenBuffer[1] == 'S') )
2475
	{
2476
		receivedCmd = resetCameraCmd;
2477
     a2a:	87 e0       	ldi	r24, 0x07	; 7
2478
     a2c:	01 c0       	rjmp	.+2      	; 0xa30
2479
	}
2480
	else
2481
	{
2482
		/* don't recognize the cmd */
2483
		receivedCmd = invalidCmd;
2484
     a2e:	89 e0       	ldi	r24, 0x09	; 9
2485
     a30:	80 93 62 00 	sts	0x0062, r24
2486
	}
2487
	memset(asciiTokenBuffer,0x00,MAX_TOKEN_LENGTH);
2488
     a34:	83 e0       	ldi	r24, 0x03	; 3
2489
     a36:	ef eb       	ldi	r30, 0xBF	; 191
2490
     a38:	f0 e0       	ldi	r31, 0x00	; 0
2491
     a3a:	11 92       	st	Z+, r1
2492
     a3c:	8a 95       	dec	r24
2493
     a3e:	e9 f7       	brne	.-6      	; 0xa3a
2494
	charIndex = 0;
2495
     a40:	10 92 bd 00 	sts	0x00BD, r1
2496
	charCount = 0;
2497
     a44:	10 92 bc 00 	sts	0x00BC, r1
2498
}
2499
     a48:	08 95       	ret
2500
 
2501
00000a4a <UIMgr_sendAck>:
2502
/***********************************************************
2503
	Function Name: UIMgr_sendAck
2504
	Function Description: This function is responsible for
2505
	queuing up an ACK to be sent to the user.
2506
	Inputs:  none 
2507
	Outputs: none
2508
***********************************************************/	
2509
static void UIMgr_sendAck(void)
2510
{
2511
	UIMgr_writeTxFifo('A');
2512
     a4a:	81 e4       	ldi	r24, 0x41	; 65
2513
     a4c:	6e d0       	rcall	.+220    	; 0xb2a
2514
	UIMgr_writeTxFifo('C');
2515
     a4e:	83 e4       	ldi	r24, 0x43	; 67
2516
     a50:	6c d0       	rcall	.+216    	; 0xb2a
2517
	UIMgr_writeTxFifo('K');
2518
     a52:	8b e4       	ldi	r24, 0x4B	; 75
2519
     a54:	6a d0       	rcall	.+212    	; 0xb2a
2520
	UIMgr_writeTxFifo('\r');
2521
     a56:	8d e0       	ldi	r24, 0x0D	; 13
2522
     a58:	68 d0       	rcall	.+208    	; 0xb2a
2523
}
2524
     a5a:	08 95       	ret
2525
 
2526
00000a5c <UIMgr_sendNck>:
2527
 
2528
/***********************************************************
2529
	Function Name: UIMgr_sendNck
2530
	Function Description: This function is responsible for
2531
	queueing up an NCK to be sent to the user.
2532
	Inputs:  none 
2533
	Outputs: none
2534
***********************************************************/	
2535
static void UIMgr_sendNck(void)
2536
{
2537
		UIMgr_writeTxFifo('N');
2538
     a5c:	8e e4       	ldi	r24, 0x4E	; 78
2539
     a5e:	65 d0       	rcall	.+202    	; 0xb2a
2540
		UIMgr_writeTxFifo('C');
2541
     a60:	83 e4       	ldi	r24, 0x43	; 67
2542
     a62:	63 d0       	rcall	.+198    	; 0xb2a
2543
		UIMgr_writeTxFifo('K');
2544
     a64:	8b e4       	ldi	r24, 0x4B	; 75
2545
     a66:	61 d0       	rcall	.+194    	; 0xb2a
2546
		UIMgr_writeTxFifo('\r');
2547
     a68:	8d e0       	ldi	r24, 0x0D	; 13
2548
     a6a:	5f d0       	rcall	.+190    	; 0xb2a
2549
}
2550
     a6c:	08 95       	ret
2551
 
2552
00000a6e <UIMgr_writeBufferToTxFifo>:
2553
 
2554
 
2555
/***********************************************************
2556
	Function Name: UIMgr_writeBufferToTxFifo
2557
	Function Description: This function is responsible for
2558
	placing "length" bytes into the tx FIFO.
2559
	Inputs:  pData -  a pointer to the data to send
2560
	         length - the number of bytes to send
2561
	Outputs: none
2562
***********************************************************/	
2563
void UIMgr_writeBufferToTxFifo(unsigned char *pData, unsigned char length)
2564
{
2565
     a6e:	dc 01       	movw	r26, r24
2566
	unsigned char tmpHead;
2567
	if (length == 0)
2568
     a70:	66 23       	and	r22, r22
2569
     a72:	a9 f0       	breq	.+42     	; 0xa9e
2570
	{
2571
		return;
2572
	}
2573
 
2574
	DISABLE_INTS();
2575
     a74:	f8 94       	cli
2576
	while(length-- != 0)
2577
     a76:	61 50       	subi	r22, 0x01	; 1
2578
     a78:	6f 3f       	cpi	r22, 0xFF	; 255
2579
     a7a:	81 f0       	breq	.+32     	; 0xa9c
2580
     a7c:	24 e9       	ldi	r18, 0x94	; 148
2581
     a7e:	32 e0       	ldi	r19, 0x02	; 2
2582
	{
2583
		UIMgr_txFifo[UIMgr_txFifoHead] = *pData++;
2584
     a80:	90 91 ba 00 	lds	r25, 0x00BA
2585
     a84:	f9 01       	movw	r30, r18
2586
     a86:	e9 0f       	add	r30, r25
2587
     a88:	f1 1d       	adc	r31, r1
2588
     a8a:	8d 91       	ld	r24, X+
2589
     a8c:	80 83       	st	Z, r24
2590
 
2591
		/* now move the head up */
2592
		tmpHead = (UIMgr_txFifoHead + 1) & (UI_MGR_TX_FIFO_MASK);
2593
     a8e:	89 2f       	mov	r24, r25
2594
     a90:	8f 5f       	subi	r24, 0xFF	; 255
2595
     a92:	8f 73       	andi	r24, 0x3F	; 63
2596
		UIMgr_txFifoHead = tmpHead;
2597
     a94:	80 93 ba 00 	sts	0x00BA, r24
2598
     a98:	61 50       	subi	r22, 0x01	; 1
2599
     a9a:	90 f7       	brcc	.-28     	; 0xa80
2600
	}
2601
	ENABLE_INTS();
2602
     a9c:	78 94       	sei
2603
}
2604
     a9e:	08 95       	ret
2605
 
2606
00000aa0 <UIMgr_txBuffer>:
2607
 
2608
/***********************************************************
2609
	Function Name: UIMgr_txBuffer
2610
	Function Description: This function is responsible for
2611
	sending 'length' bytes out using the UartInterface 
2612
	module.
2613
	Inputs:  pData -  a pointer to the data to send
2614
	         length - the number of bytes to send
2615
	Outputs: none
2616
***********************************************************/	
2617
void UIMgr_txBuffer(unsigned char *pData, unsigned char length)
2618
{
2619
     aa0:	0f 93       	push	r16
2620
     aa2:	1f 93       	push	r17
2621
     aa4:	cf 93       	push	r28
2622
     aa6:	8c 01       	movw	r16, r24
2623
     aa8:	c6 2f       	mov	r28, r22
2624
	while(length-- != 0)
2625
     aaa:	c1 50       	subi	r28, 0x01	; 1
2626
     aac:	cf 3f       	cpi	r28, 0xFF	; 255
2627
     aae:	31 f0       	breq	.+12     	; 0xabc
2628
	{
2629
		UartInt_txByte(*pData++); 
2630
     ab0:	f8 01       	movw	r30, r16
2631
     ab2:	81 91       	ld	r24, Z+
2632
     ab4:	8f 01       	movw	r16, r30
2633
     ab6:	54 d0       	rcall	.+168    	; 0xb60
2634
     ab8:	c1 50       	subi	r28, 0x01	; 1
2635
     aba:	d0 f7       	brcc	.-12     	; 0xab0
2636
	}
2637
}
2638
     abc:	cf 91       	pop	r28
2639
     abe:	1f 91       	pop	r17
2640
     ac0:	0f 91       	pop	r16
2641
     ac2:	08 95       	ret
2642
 
2643
00000ac4 <UIMgr_flushTxBuffer>:
2644
 
2645
/***********************************************************
2646
	Function Name: UIMgr_flushTxBuffer
2647
	Function Description: This function is responsible for
2648
	sending all data currently in the serial tx buffer
2649
	to the user.
2650
	Inputs:  none
2651
	Outputs: none
2652
***********************************************************/	
2653
void UIMgr_flushTxBuffer(void)
2654
{
2655
	while(IS_DATA_IN_TX_FIFO() == TRUE)
2656
     ac4:	90 91 ba 00 	lds	r25, 0x00BA
2657
     ac8:	80 91 bb 00 	lds	r24, 0x00BB
2658
     acc:	98 17       	cp	r25, r24
2659
     ace:	41 f0       	breq	.+16     	; 0xae0
2660
	{
2661
		UartInt_txByte(UIMgr_readTxFifo() );
2662
     ad0:	1a d0       	rcall	.+52     	; 0xb06
2663
     ad2:	46 d0       	rcall	.+140    	; 0xb60
2664
     ad4:	90 91 ba 00 	lds	r25, 0x00BA
2665
     ad8:	80 91 bb 00 	lds	r24, 0x00BB
2666
     adc:	98 17       	cp	r25, r24
2667
     ade:	c1 f7       	brne	.-16     	; 0xad0
2668
	}
2669
}
2670
     ae0:	08 95       	ret
2671
 
2672
00000ae2 <UIMgr_readRxFifo>:
2673
 
2674
/***********************************************************
2675
	Function Name: UIMgr_readRxFifo
2676
	Function Description: This function is responsible for
2677
	reading a single byte of data from the rx fifo, and
2678
	updating the appropriate pointers.
2679
	Inputs:  none 
2680
	Outputs: unsigned char-the data read
2681
***********************************************************/	
2682
static unsigned char UIMgr_readRxFifo(void)
2683
{
2684
	unsigned char dataByte, tmpTail;
2685
 
2686
	/* just return the current tail from the rx fifo */
2687
	DISABLE_INTS();
2688
     ae2:	f8 94       	cli
2689
	dataByte = UIMgr_rxFifo[UIMgr_rxFifoTail];	
2690
     ae4:	20 91 b9 00 	lds	r18, 0x00B9
2691
     ae8:	84 e7       	ldi	r24, 0x74	; 116
2692
     aea:	92 e0       	ldi	r25, 0x02	; 2
2693
     aec:	fc 01       	movw	r30, r24
2694
     aee:	e2 0f       	add	r30, r18
2695
     af0:	f1 1d       	adc	r31, r1
2696
     af2:	90 81       	ld	r25, Z
2697
	tmpTail = (UIMgr_rxFifoTail+1) & (UI_MGR_RX_FIFO_MASK);
2698
     af4:	82 2f       	mov	r24, r18
2699
     af6:	8f 5f       	subi	r24, 0xFF	; 255
2700
     af8:	8f 71       	andi	r24, 0x1F	; 31
2701
	UIMgr_rxFifoTail = tmpTail;
2702
     afa:	80 93 b9 00 	sts	0x00B9, r24
2703
	ENABLE_INTS();
2704
     afe:	78 94       	sei
2705
 
2706
	return(dataByte);
2707
     b00:	89 2f       	mov	r24, r25
2708
     b02:	99 27       	eor	r25, r25
2709
}
2710
     b04:	08 95       	ret
2711
 
2712
00000b06 <UIMgr_readTxFifo>:
2713
 
2714
/***********************************************************
2715
	Function Name: UIMgr_readTxFifo
2716
	Function Description: This function is responsible for
2717
	reading a single byte of data from the tx fifo, and
2718
	updating the appropriate pointers.
2719
	Inputs:  none 
2720
	Outputs: unsigned char-the data read
2721
***********************************************************/	
2722
static unsigned char UIMgr_readTxFifo(void)
2723
{
2724
	unsigned char dataByte, tmpTail;
2725
 
2726
	/* just return the current tail from the tx fifo */
2727
	DISABLE_INTS();
2728
     b06:	f8 94       	cli
2729
	dataByte = UIMgr_txFifo[UIMgr_txFifoTail];	
2730
     b08:	20 91 bb 00 	lds	r18, 0x00BB
2731
     b0c:	84 e9       	ldi	r24, 0x94	; 148
2732
     b0e:	92 e0       	ldi	r25, 0x02	; 2
2733
     b10:	fc 01       	movw	r30, r24
2734
     b12:	e2 0f       	add	r30, r18
2735
     b14:	f1 1d       	adc	r31, r1
2736
     b16:	90 81       	ld	r25, Z
2737
	tmpTail = (UIMgr_txFifoTail+1) & (UI_MGR_TX_FIFO_MASK);
2738
     b18:	82 2f       	mov	r24, r18
2739
     b1a:	8f 5f       	subi	r24, 0xFF	; 255
2740
     b1c:	8f 73       	andi	r24, 0x3F	; 63
2741
	UIMgr_txFifoTail = tmpTail;
2742
     b1e:	80 93 bb 00 	sts	0x00BB, r24
2743
	ENABLE_INTS();
2744
     b22:	78 94       	sei
2745
 
2746
	return(dataByte);
2747
     b24:	89 2f       	mov	r24, r25
2748
     b26:	99 27       	eor	r25, r25
2749
}
2750
     b28:	08 95       	ret
2751
 
2752
00000b2a <UIMgr_writeTxFifo>:
2753
 
2754
/***********************************************************
2755
	Function Name: UIMgr_writeTxFifo
2756
	Function Description: This function is responsible for
2757
	writing a single byte to the TxFifo and
2758
	updating the appropriate pointers.
2759
	Inputs:  data - the byte to write to the Fifo 
2760
	Outputs: none
2761
***********************************************************/	
2762
void UIMgr_writeTxFifo(unsigned char data)
2763
{
2764
     b2a:	38 2f       	mov	r19, r24
2765
	unsigned char tmpHead;
2766
 
2767
	DISABLE_INTS();
2768
     b2c:	f8 94       	cli
2769
	UIMgr_txFifo[UIMgr_txFifoHead] = data;
2770
     b2e:	20 91 ba 00 	lds	r18, 0x00BA
2771
     b32:	84 e9       	ldi	r24, 0x94	; 148
2772
     b34:	92 e0       	ldi	r25, 0x02	; 2
2773
     b36:	fc 01       	movw	r30, r24
2774
     b38:	e2 0f       	add	r30, r18
2775
     b3a:	f1 1d       	adc	r31, r1
2776
     b3c:	30 83       	st	Z, r19
2777
 
2778
    /* now move the head up */
2779
    tmpHead = (UIMgr_txFifoHead + 1) & (UI_MGR_TX_FIFO_MASK);
2780
     b3e:	82 2f       	mov	r24, r18
2781
     b40:	8f 5f       	subi	r24, 0xFF	; 255
2782
     b42:	8f 73       	andi	r24, 0x3F	; 63
2783
    UIMgr_txFifoHead = tmpHead;
2784
     b44:	80 93 ba 00 	sts	0x00BA, r24
2785
	ENABLE_INTS();
2786
     b48:	78 94       	sei
2787
 
2788
}
2789
     b4a:	08 95       	ret
2790
 
2791
00000b4c <UartInt_init>:
2792
void UartInt_init(void)
2793
{	
2794
	/* set up the baud rate registers so the UART will operate
2795
	at 115.2 Kbps */
2796
	UBRRH = 0x00;
2797
     b4c:	10 bc       	out	0x20, r1	; 32
2798
 
2799
#ifdef NO_CRYSTAL    
2800
    UBRRL = 18;  /* 18 for double clocking at 115.2 kbps */
2801
     b4e:	82 e1       	ldi	r24, 0x12	; 18
2802
     b50:	89 b9       	out	0x09, r24	; 9
2803
#else    
2804
	UBRRL = 0x08;  /* for 16 MHz crystal at 115.2 kbps */
2805
#endif    
2806
 
2807
	/* enable the tx and rx capabilities of the UART...as well 
2808
		as the receive complete interrupt */
2809
	UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);	
2810
     b52:	88 e9       	ldi	r24, 0x98	; 152
2811
     b54:	8a b9       	out	0x0a, r24	; 10
2812
 
2813
	/* set up the control registers so the UART works at 8N1 */
2814
	UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
2815
     b56:	86 e8       	ldi	r24, 0x86	; 134
2816
     b58:	80 bd       	out	0x20, r24	; 32
2817
 
2818
#ifdef NO_CRYSTAL     
2819
    /* set the baud rate to use the double-speed */
2820
    UCSRA = (1<<U2X);
2821
     b5a:	82 e0       	ldi	r24, 0x02	; 2
2822
     b5c:	8b b9       	out	0x0b, r24	; 11
2823
#endif    
2824
 
2825
}
2826
     b5e:	08 95       	ret
2827
 
2828
00000b60 <UartInt_txByte>:
2829
 
2830
/***********************************************************
2831
	Function Name: UartInt_txByte
2832
	Function Description: This function is responsible for
2833
	transmitting a single byte on the uart.  
2834
	Inputs:  txByte - the byte to send
2835
	Outputs: none
2836
	NOTES: When the TX UDRE (data register empty) is set, there
2837
	is puposefully no interrupt...thus, to send a string of
2838
	data out, the calling routine needs to hold up the entire
2839
	application while this takes place (or just send one
2840
	byte at a time at strtegically timed intervals, like
2841
	the stats data is sent out :-)
2842
***********************************************************/
2843
void UartInt_txByte(unsigned char txByte)
2844
{
2845
	/* Wait for empty transmit buffer */
2846
	while ( !( UCSRA & (1<<UDRE)) );
2847
     b60:	5d 9b       	sbis	0x0b, 5	; 11
2848
     b62:	fe cf       	rjmp	.-4      	; 0xb60
2849
	/* Put data into buffer, sends the data */
2850
	UDR = txByte;
2851
     b64:	8c b9       	out	0x0c, r24	; 12
2852
}
2853
     b66:	08 95       	ret
2854
 
2855
00000b68 <__vector_11>:
2856
 
2857
/***********************************************************
2858
	Function Name: SIG_UART_RECV ISR
2859
	Function Description: This function is responsible for
2860
	handling the interrupt caused when a data byte is 
2861
    received by the UART.
2862
	Inputs:  none
2863
	Outputs: none
2864
	NOTES: This function was originally written in assembly,
2865
    but moved over to C when the setting of the "T" bit at
2866
    the end of the routine was no longer necessary (this
2867
    theoretically allowed the AVRcam to respond to serial
2868
    bytes in the middle of tracking or dumping a frame.
2869
    But it wasn't really needed, and understanding the C
2870
    is easier  :-)
2871
***********************************************************/
2872
SIGNAL(SIG_UART_RECV)
2873
{
2874
     b68:	1f 92       	push	r1
2875
     b6a:	0f 92       	push	r0
2876
     b6c:	0f b6       	in	r0, 0x3f	; 63
2877
     b6e:	0f 92       	push	r0
2878
     b70:	11 24       	eor	r1, r1
2879
     b72:	2f 93       	push	r18
2880
     b74:	8f 93       	push	r24
2881
     b76:	9f 93       	push	r25
2882
     b78:	ef 93       	push	r30
2883
     b7a:	ff 93       	push	r31
2884
    unsigned char tmpHead;
2885
    /* read the data byte, put it in the serial queue, and
2886
    post the event */
2887
 
2888
    UIMgr_rxFifo[UIMgr_rxFifoHead] = UDR;
2889
     b7c:	20 91 b8 00 	lds	r18, 0x00B8
2890
     b80:	84 e7       	ldi	r24, 0x74	; 116
2891
     b82:	92 e0       	ldi	r25, 0x02	; 2
2892
     b84:	fc 01       	movw	r30, r24
2893
     b86:	e2 0f       	add	r30, r18
2894
     b88:	f1 1d       	adc	r31, r1
2895
     b8a:	8c b1       	in	r24, 0x0c	; 12
2896
     b8c:	80 83       	st	Z, r24
2897
 
2898
    /* now move the head up */
2899
    tmpHead = (UIMgr_rxFifoHead + 1) & (UI_MGR_RX_FIFO_MASK);
2900
     b8e:	2f 5f       	subi	r18, 0xFF	; 255
2901
     b90:	2f 71       	andi	r18, 0x1F	; 31
2902
    UIMgr_rxFifoHead = tmpHead;
2903
     b92:	20 93 b8 00 	sts	0x00B8, r18
2904
 
2905
    /* write the serial received event to the event fifo */
2906
    Exec_eventFifo[Exec_eventFifoHead] = EV_SERIAL_DATA_RECEIVED;
2907
     b96:	20 91 70 00 	lds	r18, 0x0070
2908
     b9a:	8c e6       	ldi	r24, 0x6C	; 108
2909
     b9c:	92 e0       	ldi	r25, 0x02	; 2
2910
     b9e:	fc 01       	movw	r30, r24
2911
     ba0:	e2 0f       	add	r30, r18
2912
     ba2:	f1 1d       	adc	r31, r1
2913
     ba4:	81 e0       	ldi	r24, 0x01	; 1
2914
     ba6:	80 83       	st	Z, r24
2915
 
2916
    /* now move the head up */
2917
    tmpHead = (Exec_eventFifoHead + 1) & (EXEC_EVENT_FIFO_MASK);
2918
     ba8:	28 0f       	add	r18, r24
2919
     baa:	27 70       	andi	r18, 0x07	; 7
2920
    Exec_eventFifoHead = tmpHead;
2921
     bac:	20 93 70 00 	sts	0x0070, r18
2922
}
2923
     bb0:	ff 91       	pop	r31
2924
     bb2:	ef 91       	pop	r30
2925
     bb4:	9f 91       	pop	r25
2926
     bb6:	8f 91       	pop	r24
2927
     bb8:	2f 91       	pop	r18
2928
     bba:	0f 90       	pop	r0
2929
     bbc:	0f be       	out	0x3f, r0	; 63
2930
     bbe:	0f 90       	pop	r0
2931
     bc0:	1f 90       	pop	r1
2932
     bc2:	18 95       	reti
2933
 
2934
00000bc4 <I2CInt_init>:
2935
	Outputs: none
2936
***********************************************************/	
2937
void I2CInt_init(void)
2938
{
2939
	TWSR = 0;
2940
     bc4:	11 b8       	out	0x01, r1	; 1
2941
 
2942
	/* init the speed of the I2C interface, running at
2943
    100 Kbps */
2944
	TWBR = (FOSC / I2C_SPEED - 16)/2;
2945
     bc6:	88 e4       	ldi	r24, 0x48	; 72
2946
     bc8:	80 b9       	out	0x00, r24	; 0
2947
}
2948
     bca:	08 95       	ret
2949
 
2950
00000bcc <I2CInt_writeData>:
2951
 
2952
/***********************************************************
2953
	Function Name: I2CInt_writeData
2954
	Function Description: This function is responsible for
2955
	initiating the process of writing a sequence of bytes
2956
	an I2C slave address.  This function will try to write
2957
	the data three times before giving up.
2958
	Inputs: address: the address of the I2C slave device
2959
			data: a pointer to the data to be written 
2960
				  to the slave...for camera interfacing,
2961
				  the data follows a <register #><data>
2962
				  format
2963
			bytes: the number of bytes to write 
2964
	Outputs: none
2965
***********************************************************/
2966
void I2CInt_writeData(unsigned char address, unsigned char *data, unsigned char bytes)
2967
{
2968
     bcc:	98 2f       	mov	r25, r24
2969
	while(status & (1<<BUSY));		/* Bus is busy wait (or exit with error code) */
2970
     bce:	80 91 08 01 	lds	r24, 0x0108
2971
     bd2:	88 23       	and	r24, r24
2972
     bd4:	e4 f3       	brlt	.-8      	; 0xbce
2973
	while(TWCR & (1<<TWSTO));
2974
     bd6:	06 b6       	in	r0, 0x36	; 54
2975
     bd8:	04 fc       	sbrc	r0, 4
2976
     bda:	fd cf       	rjmp	.-6      	; 0xbd6
2977
 
2978
	/* copy the needed data and state info to our local I2C command structure */
2979
	twi_address = address;
2980
     bdc:	90 93 03 01 	sts	0x0103, r25
2981
	twi_data = data;
2982
     be0:	70 93 05 01 	sts	0x0105, r23
2983
     be4:	60 93 04 01 	sts	0x0104, r22
2984
	twi_bytes = bytes;
2985
     be8:	40 93 07 01 	sts	0x0107, r20
2986
	twi_ddr = TW_WRITE;
2987
     bec:	10 92 06 01 	sts	0x0106, r1
2988
 
2989
	retry_cnt = 0;
2990
     bf0:	10 92 09 01 	sts	0x0109, r1
2991
 
2992
	/* Generate start condition, the remainder of the transfer is interrupt driven and
2993
	   will be performed in the background */
2994
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE);
2995
     bf4:	85 ea       	ldi	r24, 0xA5	; 165
2996
     bf6:	86 bf       	out	0x36, r24	; 54
2997
 
2998
	status |= (1<<BUSY);
2999
     bf8:	80 91 08 01 	lds	r24, 0x0108
3000
     bfc:	80 68       	ori	r24, 0x80	; 128
3001
     bfe:	80 93 08 01 	sts	0x0108, r24
3002
}
3003
     c02:	08 95       	ret
3004
 
3005
00000c04 <I2CInt_readData>:
3006
 
3007
/***********************************************************
3008
	Function Name: I2CInt_readData
3009
	Function Description: This funcion is responsible for
3010
	reading the specified number of bytes from a slave
3011
	device.
3012
	Inputs:  address: the slave address to read from
3013
			 data: a pointer to where the data will be stored
3014
			 bytes: the number of bytes to read
3015
	Outputs: none
3016
***********************************************************/
3017
void I2CInt_readData(unsigned char address, unsigned char *data, unsigned char bytes)
3018
{
3019
     c04:	98 2f       	mov	r25, r24
3020
    /* Bus is busy wait (or exit with error code) */
3021
	while(status & (1<<BUSY));									
3022
     c06:	80 91 08 01 	lds	r24, 0x0108
3023
     c0a:	88 23       	and	r24, r24
3024
     c0c:	e4 f3       	brlt	.-8      	; 0xc06
3025
 
3026
	twi_address = address;
3027
     c0e:	90 93 03 01 	sts	0x0103, r25
3028
	twi_data = data;
3029
     c12:	70 93 05 01 	sts	0x0105, r23
3030
     c16:	60 93 04 01 	sts	0x0104, r22
3031
	twi_bytes = bytes;
3032
     c1a:	40 93 07 01 	sts	0x0107, r20
3033
	twi_ddr = TW_READ;
3034
     c1e:	81 e0       	ldi	r24, 0x01	; 1
3035
     c20:	80 93 06 01 	sts	0x0106, r24
3036
 
3037
	retry_cnt = 0;
3038
     c24:	10 92 09 01 	sts	0x0109, r1
3039
 
3040
	/* Generate start condition, the remainder of the transfer is interrupt driven and
3041
	   will be performed in the background */
3042
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE);
3043
     c28:	85 ea       	ldi	r24, 0xA5	; 165
3044
     c2a:	86 bf       	out	0x36, r24	; 54
3045
 
3046
	status |= (1<<BUSY);
3047
     c2c:	80 91 08 01 	lds	r24, 0x0108
3048
     c30:	80 68       	ori	r24, 0x80	; 128
3049
     c32:	80 93 08 01 	sts	0x0108, r24
3050
}
3051
     c36:	08 95       	ret
3052
 
3053
00000c38 <I2CInt_isI2cBusy>:
3054
 
3055
/***********************************************************
3056
	Function Name: I2CInt_isI2cBusy
3057
	Function Description: This funcion is responsible for
3058
	indicating if the I2C bus is currently busy to external
3059
	modules.
3060
	device.
3061
	Inputs:  none
3062
	Outputs: bool_t - indicating if bus is busy
3063
***********************************************************/
3064
bool_t I2CInt_isI2cBusy(void)
3065
{
3066
	bool_t retVal = FALSE;
3067
     c38:	90 e0       	ldi	r25, 0x00	; 0
3068
	if ( (status & (1<<BUSY)) != 0)
3069
     c3a:	80 91 08 01 	lds	r24, 0x0108
3070
     c3e:	88 23       	and	r24, r24
3071
     c40:	0c f4       	brge	.+2      	; 0xc44
3072
	{
3073
		retVal = TRUE;
3074
     c42:	91 e0       	ldi	r25, 0x01	; 1
3075
	}
3076
 
3077
	return(retVal);
3078
     c44:	89 2f       	mov	r24, r25
3079
     c46:	99 27       	eor	r25, r25
3080
}
3081
     c48:	08 95       	ret
3082
 
3083
00000c4a <__vector_17>:
3084
 
3085
/***********************************************************
3086
	Function Name: <interrupt handler for I2C>
3087
	Function Description: This function is responsible for
3088
	implementing the control logic needed to perform a
3089
	read or write operation with an I2C slave.
3090
	Inputs:  none
3091
	Outputs: none
3092
***********************************************************/
3093
SIGNAL(SIG_2WIRE_SERIAL)
3094
{
3095
     c4a:	1f 92       	push	r1
3096
     c4c:	0f 92       	push	r0
3097
     c4e:	0f b6       	in	r0, 0x3f	; 63
3098
     c50:	0f 92       	push	r0
3099
     c52:	11 24       	eor	r1, r1
3100
     c54:	8f 93       	push	r24
3101
     c56:	9f 93       	push	r25
3102
     c58:	af 93       	push	r26
3103
     c5a:	bf 93       	push	r27
3104
     c5c:	ef 93       	push	r30
3105
     c5e:	ff 93       	push	r31
3106
	unsigned char TWI_status = TWSR & TW_STATUS_MASK;   /* grab just the status bits */
3107
     c60:	81 b1       	in	r24, 0x01	; 1
3108
     c62:	88 7f       	andi	r24, 0xF8	; 248
3109
 
3110
    /* the entire I2C handler is state-based...determine
3111
    what needs to be done based on TWI_status */
3112
	switch(TWI_status) 
3113
     c64:	99 27       	eor	r25, r25
3114
     c66:	aa 27       	eor	r26, r26
3115
     c68:	bb 27       	eor	r27, r27
3116
     c6a:	fc 01       	movw	r30, r24
3117
     c6c:	38 97       	sbiw	r30, 0x08	; 8
3118
     c6e:	e1 35       	cpi	r30, 0x51	; 81
3119
     c70:	f1 05       	cpc	r31, r1
3120
     c72:	08 f0       	brcs	.+2      	; 0xc76
3121
     c74:	6d c0       	rjmp	.+218    	; 0xd50
3122
     c76:	ed 5e       	subi	r30, 0xED	; 237
3123
     c78:	ff 4f       	sbci	r31, 0xFF	; 255
3124
     c7a:	09 94       	ijmp
3125
    {
3126
        case TW_START:									/* Start condition */
3127
        case TW_REP_START:								/* Repeated start condition */
3128
            if(retry_cnt > MAX_TWI_RETRIES) 
3129
     c7c:	80 91 09 01 	lds	r24, 0x0109
3130
     c80:	83 30       	cpi	r24, 0x03	; 3
3131
     c82:	08 f0       	brcs	.+2      	; 0xc86
3132
     c84:	5d c0       	rjmp	.+186    	; 0xd40
3133
            {
3134
                /* generate stop condition if we've reached our retry limit */
3135
                TWCR |= (1<<TWINT)|(1<<TWSTO);					
3136
                status &= ~(1<<BUSY);								
3137
                return;												
3138
            }
3139
            /* indicate read or write */
3140
            TWDR = (twi_address<<1) + twi_ddr;	
3141
     c86:	80 91 03 01 	lds	r24, 0x0103
3142
     c8a:	98 2f       	mov	r25, r24
3143
     c8c:	99 0f       	add	r25, r25
3144
     c8e:	80 91 06 01 	lds	r24, 0x0106
3145
     c92:	89 0f       	add	r24, r25
3146
     c94:	83 b9       	out	0x03, r24	; 3
3147
            /* TWSTA must be cleared...also clears TWINT */
3148
            TWCR &= ~(1<<TWSTA);
3149
     c96:	86 b7       	in	r24, 0x36	; 54
3150
     c98:	8f 7d       	andi	r24, 0xDF	; 223
3151
     c9a:	4a c0       	rjmp	.+148    	; 0xd30
3152
            break;
3153
 
3154
        case TW_MT_SLA_ACK:							/* Slave acknowledged address, */
3155
            retry_cnt = 0;					
3156
     c9c:	10 92 09 01 	sts	0x0109, r1
3157
            /* tx the data, and increment the data pointer */
3158
            TWDR = *twi_data;										
3159
     ca0:	11 c0       	rjmp	.+34     	; 0xcc4
3160
            twi_data++;			
3161
 
3162
            /* clear the int to continue */
3163
            TWCR |= (1<<TWINT);						
3164
            break;
3165
 
3166
        case TW_MT_SLA_NACK:							/* Slave didn't acknowledge address, */
3167
        case TW_MR_SLA_NACK:
3168
            retry_cnt++;		
3169
     ca2:	80 91 09 01 	lds	r24, 0x0109
3170
     ca6:	8f 5f       	subi	r24, 0xFF	; 255
3171
     ca8:	80 93 09 01 	sts	0x0109, r24
3172
 
3173
            /* retry...*/
3174
            TWCR |= (1<<TWINT)|(1<<TWSTA)|(1<<TWSTO);	
3175
     cac:	86 b7       	in	r24, 0x36	; 54
3176
     cae:	80 6b       	ori	r24, 0xB0	; 176
3177
     cb0:	3f c0       	rjmp	.+126    	; 0xd30
3178
            break;
3179
 
3180
        case TW_MT_DATA_ACK:							/* Slave Acknowledged data, */
3181
            if(--twi_bytes > 0) 
3182
     cb2:	80 91 07 01 	lds	r24, 0x0107
3183
     cb6:	81 50       	subi	r24, 0x01	; 1
3184
     cb8:	80 93 07 01 	sts	0x0107, r24
3185
     cbc:	80 91 07 01 	lds	r24, 0x0107
3186
     cc0:	88 23       	and	r24, r24
3187
     cc2:	f1 f1       	breq	.+124    	; 0xd40
3188
            {						
3189
                /* more data to send, so send it */
3190
                TWDR = *twi_data;									
3191
     cc4:	e0 91 04 01 	lds	r30, 0x0104
3192
     cc8:	f0 91 05 01 	lds	r31, 0x0105
3193
     ccc:	80 81       	ld	r24, Z
3194
     cce:	83 b9       	out	0x03, r24	; 3
3195
                twi_data++;											
3196
     cd0:	cf 01       	movw	r24, r30
3197
     cd2:	01 96       	adiw	r24, 0x01	; 1
3198
     cd4:	90 93 05 01 	sts	0x0105, r25
3199
     cd8:	80 93 04 01 	sts	0x0104, r24
3200
                TWCR |= (1<<TWINT);								
3201
     cdc:	09 c0       	rjmp	.+18     	; 0xcf0
3202
            }
3203
            else 
3204
            {
3205
                /* generate the stop condition if needed */
3206
                TWCR |= (1<<TWSTO)|(1<<TWINT);					
3207
                status &= ~(1<<BUSY);								
3208
            }
3209
            break;
3210
 
3211
        case TW_MT_DATA_NACK:							/* Slave didn't acknowledge data */
3212
            /* send the stop condition */
3213
            TWCR |= (1<<TWINT)|(1<<TWSTO);						
3214
            status &= ~(1<<BUSY);									
3215
            break;
3216
 
3217
        case TW_MR_SLA_ACK:                             /* Slave acknowledged address */
3218
            if(--twi_bytes > 0) 
3219
     cde:	80 91 07 01 	lds	r24, 0x0107
3220
     ce2:	81 50       	subi	r24, 0x01	; 1
3221
     ce4:	80 93 07 01 	sts	0x0107, r24
3222
     ce8:	80 91 07 01 	lds	r24, 0x0107
3223
     cec:	88 23       	and	r24, r24
3224
     cee:	d9 f4       	brne	.+54     	; 0xd26
3225
            {
3226
                /* if there is more than one byte to read, acknowledge */
3227
                TWCR |= (1<<TWEA)|(1<<TWINT);	
3228
            }
3229
			else
3230
            {
3231
                /* no acknowledge */
3232
                TWCR |= (1<<TWINT);					
3233
     cf0:	86 b7       	in	r24, 0x36	; 54
3234
     cf2:	80 68       	ori	r24, 0x80	; 128
3235
     cf4:	1d c0       	rjmp	.+58     	; 0xd30
3236
            }
3237
            break;
3238
 
3239
        case TW_MR_DATA_ACK: 							/* Master acknowledged data */
3240
 
3241
            /* grab the received data */
3242
            *twi_data = TWDR;										
3243
     cf6:	e0 91 04 01 	lds	r30, 0x0104
3244
     cfa:	f0 91 05 01 	lds	r31, 0x0105
3245
     cfe:	83 b1       	in	r24, 0x03	; 3
3246
     d00:	80 83       	st	Z, r24
3247
            twi_data++;											
3248
     d02:	80 91 04 01 	lds	r24, 0x0104
3249
     d06:	90 91 05 01 	lds	r25, 0x0105
3250
     d0a:	01 96       	adiw	r24, 0x01	; 1
3251
     d0c:	90 93 05 01 	sts	0x0105, r25
3252
     d10:	80 93 04 01 	sts	0x0104, r24
3253
            if(--twi_bytes > 0) 
3254
     d14:	80 91 07 01 	lds	r24, 0x0107
3255
     d18:	81 50       	subi	r24, 0x01	; 1
3256
     d1a:	80 93 07 01 	sts	0x0107, r24
3257
     d1e:	80 91 07 01 	lds	r24, 0x0107
3258
     d22:	88 23       	and	r24, r24
3259
     d24:	19 f0       	breq	.+6      	; 0xd2c
3260
            {
3261
                /* get the next data byte and ack */
3262
                TWCR |= (1<<TWEA)|(1<<TWINT);	
3263
     d26:	86 b7       	in	r24, 0x36	; 54
3264
     d28:	80 6c       	ori	r24, 0xC0	; 192
3265
     d2a:	02 c0       	rjmp	.+4      	; 0xd30
3266
            }
3267
            else
3268
            {
3269
                /* clear out the enable acknowledge bit */
3270
                TWCR &= ~(1<<TWEA);							
3271
     d2c:	86 b7       	in	r24, 0x36	; 54
3272
     d2e:	8f 7b       	andi	r24, 0xBF	; 191
3273
     d30:	86 bf       	out	0x36, r24	; 54
3274
            }
3275
            break;
3276
     d32:	0e c0       	rjmp	.+28     	; 0xd50
3277
 
3278
        case TW_MR_DATA_NACK:						/* Master didn't acknowledge data -> end of read process */
3279
            /* read data, and generate the stop condition */
3280
            *twi_data = TWDR;										
3281
     d34:	e0 91 04 01 	lds	r30, 0x0104
3282
     d38:	f0 91 05 01 	lds	r31, 0x0105
3283
     d3c:	83 b1       	in	r24, 0x03	; 3
3284
     d3e:	80 83       	st	Z, r24
3285
            TWCR |= (1<<TWSTO)|(1<<TWINT); 						
3286
     d40:	86 b7       	in	r24, 0x36	; 54
3287
     d42:	80 69       	ori	r24, 0x90	; 144
3288
     d44:	86 bf       	out	0x36, r24	; 54
3289
            status &= ~(1<<BUSY);											
3290
     d46:	80 91 08 01 	lds	r24, 0x0108
3291
     d4a:	8f 77       	andi	r24, 0x7F	; 127
3292
     d4c:	80 93 08 01 	sts	0x0108, r24
3293
            break;
3294
	}
3295
}
3296
     d50:	ff 91       	pop	r31
3297
     d52:	ef 91       	pop	r30
3298
     d54:	bf 91       	pop	r27
3299
     d56:	af 91       	pop	r26
3300
     d58:	9f 91       	pop	r25
3301
     d5a:	8f 91       	pop	r24
3302
     d5c:	0f 90       	pop	r0
3303
     d5e:	0f be       	out	0x3f, r0	; 63
3304
     d60:	0f 90       	pop	r0
3305
     d62:	1f 90       	pop	r1
3306
     d64:	18 95       	reti
3307
 
3308
00000d66 <CamConfig_init>:
3309
	Outputs: none
3310
***********************************************************/	
3311
void CamConfig_init(void)
3312
{
3313
	CamConfig_setCamReg(0x14,0x20);  /* reduce frame size */
3314
     d66:	60 e2       	ldi	r22, 0x20	; 32
3315
     d68:	84 e1       	ldi	r24, 0x14	; 20
3316
     d6a:	0e d0       	rcall	.+28     	; 0xd88
3317
	CamConfig_setCamReg(0x39,0x40);  /* gate PCLK with HREF */
3318
     d6c:	60 e4       	ldi	r22, 0x40	; 64
3319
     d6e:	89 e3       	ldi	r24, 0x39	; 57
3320
     d70:	0b d0       	rcall	.+22     	; 0xd88
3321
	CamConfig_setCamReg(0x12,0x28);  /* set RGB mode, with no AWB */
3322
     d72:	68 e2       	ldi	r22, 0x28	; 40
3323
     d74:	82 e1       	ldi	r24, 0x12	; 18
3324
     d76:	08 d0       	rcall	.+16     	; 0xd88
3325
	CamConfig_setCamReg(0x28,0x05);  /* set color sequencer */
3326
     d78:	65 e0       	ldi	r22, 0x05	; 5
3327
     d7a:	88 e2       	ldi	r24, 0x28	; 40
3328
     d7c:	05 d0       	rcall	.+10     	; 0xd88
3329
    CamConfig_setCamReg(0x13,0x01);  /* un-tri-state the Y/UV lines */
3330
     d7e:	61 e0       	ldi	r22, 0x01	; 1
3331
     d80:	83 e1       	ldi	r24, 0x13	; 19
3332
     d82:	02 d0       	rcall	.+4      	; 0xd88
3333
 
3334
	/* send the first four cmds in the I2C fifo */
3335
	CamConfig_sendFifoCmds();	
3336
     d84:	06 d0       	rcall	.+12     	; 0xd92
3337
}
3338
     d86:	08 95       	ret
3339
 
3340
00000d88 <CamConfig_setCamReg>:
3341
 
3342
 
3343
/***********************************************************
3344
	Function Name: CamConfig_setCamReg
3345
	Function Description: This function is responsible for
3346
	creating an I2C cmd structure and placing it into the
3347
	cmd fifo.
3348
	Inputs:  reg - the register to modify
3349
	         val - the new value of the register
3350
	Outputs: none
3351
***********************************************************/	
3352
void CamConfig_setCamReg(unsigned char reg, unsigned char val)
3353
{
3354
	i2cCmd_t cmd;
3355
 
3356
	cmd.configReg = reg;
3357
     d88:	28 2f       	mov	r18, r24
3358
	cmd.data = val;
3359
     d8a:	36 2f       	mov	r19, r22
3360
#ifndef SIMULATION	
3361
	CamConfig_writeTxFifo(cmd);
3362
     d8c:	c9 01       	movw	r24, r18
3363
     d8e:	2f d0       	rcall	.+94     	; 0xdee
3364
#endif	
3365
}
3366
     d90:	08 95       	ret
3367
 
3368
00000d92 <CamConfig_sendFifoCmds>:
3369
/***********************************************************
3370
	Function Name: CamConfig_sendFifoCmds
3371
	Function Description: This function is responsible for
3372
	sending the entire contents of the config fifo.  This
3373
	function won't return until the configuration process
3374
	is complete (or an error is encountered).
3375
	Inputs:  none
3376
	Outputs: none
3377
	Note: Since this function is written to use the TWI
3378
	interrupt in the I2CInterface module, there will be 
3379
	some busy-waiting here...no big deal, since we end up
3380
	having to trash the frame that we are executing this
3381
	slave write in anyway (since we can't meet the strict
3382
	timing requirements and write i2c at the same time).
3383
***********************************************************/	
3384
void CamConfig_sendFifoCmds(void)
3385
{
3386
     d92:	cf 93       	push	r28
3387
     d94:	df 93       	push	r29
3388
     d96:	cd b7       	in	r28, 0x3d	; 61
3389
     d98:	de b7       	in	r29, 0x3e	; 62
3390
     d9a:	22 97       	sbiw	r28, 0x02	; 2
3391
     d9c:	0f b6       	in	r0, 0x3f	; 63
3392
     d9e:	f8 94       	cli
3393
     da0:	de bf       	out	0x3e, r29	; 62
3394
     da2:	0f be       	out	0x3f, r0	; 63
3395
     da4:	cd bf       	out	0x3d, r28	; 61
3396
	i2cCmd_t cmd;
3397
 
3398
	while (CamConfig_txFifoHead != CamConfig_txFifoTail)
3399
     da6:	90 91 0a 01 	lds	r25, 0x010A
3400
     daa:	80 91 0b 01 	lds	r24, 0x010B
3401
     dae:	98 17       	cp	r25, r24
3402
     db0:	a9 f0       	breq	.+42     	; 0xddc
3403
	{
3404
		cmd = CamConfig_readTxFifo();
3405
     db2:	37 d0       	rcall	.+110    	; 0xe22
3406
     db4:	89 83       	std	Y+1, r24	; 0x01
3407
     db6:	9a 83       	std	Y+2, r25	; 0x02
3408
		I2CInt_writeData(CAM_ADDRESS,&cmd.configReg,SIZE_OF_I2C_CMD);
3409
     db8:	42 e0       	ldi	r20, 0x02	; 2
3410
     dba:	be 01       	movw	r22, r28
3411
     dbc:	6f 5f       	subi	r22, 0xFF	; 255
3412
     dbe:	7f 4f       	sbci	r23, 0xFF	; 255
3413
     dc0:	80 e6       	ldi	r24, 0x60	; 96
3414
     dc2:	04 df       	rcall	.-504    	; 0xbcc
3415
		Utility_delay(100);		
3416
     dc4:	84 e6       	ldi	r24, 0x64	; 100
3417
     dc6:	90 e0       	ldi	r25, 0x00	; 0
3418
     dc8:	3e d0       	rcall	.+124    	; 0xe46
3419
		/* wait for the I2C transaction to complete */
3420
		while(I2CInt_isI2cBusy() == TRUE);
3421
     dca:	36 df       	rcall	.-404    	; 0xc38
3422
     dcc:	81 30       	cpi	r24, 0x01	; 1
3423
     dce:	e9 f3       	breq	.-6      	; 0xdca
3424
     dd0:	90 91 0a 01 	lds	r25, 0x010A
3425
     dd4:	80 91 0b 01 	lds	r24, 0x010B
3426
     dd8:	98 17       	cp	r25, r24
3427
     dda:	59 f7       	brne	.-42     	; 0xdb2
3428
	} 
3429
}
3430
     ddc:	22 96       	adiw	r28, 0x02	; 2
3431
     dde:	0f b6       	in	r0, 0x3f	; 63
3432
     de0:	f8 94       	cli
3433
     de2:	de bf       	out	0x3e, r29	; 62
3434
     de4:	0f be       	out	0x3f, r0	; 63
3435
     de6:	cd bf       	out	0x3d, r28	; 61
3436
     de8:	df 91       	pop	r29
3437
     dea:	cf 91       	pop	r28
3438
     dec:	08 95       	ret
3439
 
3440
00000dee <CamConfig_writeTxFifo>:
3441
 
3442
/***********************************************************
3443
	Function Name: CamConfig_writeTxFifo
3444
	Function Description: This function is responsible for
3445
	adding a new command to the tx fifo.  It adjusts all
3446
	needed pointers.
3447
	Inputs:  cmd - the i2cCmd_t to add to the fifo
3448
	Outputs: bool_t - indicating if writing to the fifo
3449
	         causes it to wrap
3450
***********************************************************/	
3451
bool_t CamConfig_writeTxFifo(i2cCmd_t cmd)
3452
{
3453
     dee:	9c 01       	movw	r18, r24
3454
	unsigned char tmpHead;
3455
	bool_t retVal = TRUE;
3456
     df0:	51 e0       	ldi	r21, 0x01	; 1
3457
 
3458
	CamConfig_txFifo[CamConfig_txFifoHead] = cmd;
3459
     df2:	40 91 0a 01 	lds	r20, 0x010A
3460
     df6:	84 2f       	mov	r24, r20
3461
     df8:	99 27       	eor	r25, r25
3462
     dfa:	88 0f       	add	r24, r24
3463
     dfc:	99 1f       	adc	r25, r25
3464
     dfe:	fc 01       	movw	r30, r24
3465
     e00:	ec 52       	subi	r30, 0x2C	; 44
3466
     e02:	fd 4f       	sbci	r31, 0xFD	; 253
3467
     e04:	20 83       	st	Z, r18
3468
     e06:	31 83       	std	Z+1, r19	; 0x01
3469
 
3470
	/* see if we need to wrap */
3471
	tmpHead = (CamConfig_txFifoHead+1) & (CAM_CONFIG_TX_FIFO_MASK);
3472
     e08:	84 2f       	mov	r24, r20
3473
     e0a:	85 0f       	add	r24, r21
3474
     e0c:	87 70       	andi	r24, 0x07	; 7
3475
	CamConfig_txFifoHead = tmpHead;
3476
     e0e:	80 93 0a 01 	sts	0x010A, r24
3477
 
3478
	/* check to see if we have filled up the queue */
3479
	if (CamConfig_txFifoHead == CamConfig_txFifoTail)
3480
     e12:	90 91 0b 01 	lds	r25, 0x010B
3481
     e16:	89 17       	cp	r24, r25
3482
     e18:	09 f4       	brne	.+2      	; 0xe1c
3483
	{
3484
		/* we wrapped the fifo...return false */
3485
		retVal = FALSE;
3486
     e1a:	50 e0       	ldi	r21, 0x00	; 0
3487
	}
3488
	return(retVal);
3489
     e1c:	85 2f       	mov	r24, r21
3490
     e1e:	99 27       	eor	r25, r25
3491
}
3492
     e20:	08 95       	ret
3493
 
3494
00000e22 <CamConfig_readTxFifo>:
3495
 
3496
/***********************************************************
3497
	Function Name: CamConfig_readTxFifo
3498
	Function Description: This function is responsible for
3499
	reading a cmd out of the tx fifo.
3500
	Inputs:  none
3501
	Outputs: i2cCmd_t - the cmd read from the fifo
3502
***********************************************************/	
3503
static i2cCmd_t CamConfig_readTxFifo(void)
3504
{
3505
	i2cCmd_t cmd;
3506
	unsigned char tmpTail;
3507
 
3508
	/* just return the current tail from the rx fifo */
3509
	cmd = CamConfig_txFifo[CamConfig_txFifoTail];	
3510
     e22:	40 91 0b 01 	lds	r20, 0x010B
3511
     e26:	84 2f       	mov	r24, r20
3512
     e28:	99 27       	eor	r25, r25
3513
     e2a:	88 0f       	add	r24, r24
3514
     e2c:	99 1f       	adc	r25, r25
3515
     e2e:	fc 01       	movw	r30, r24
3516
     e30:	ec 52       	subi	r30, 0x2C	; 44
3517
     e32:	fd 4f       	sbci	r31, 0xFD	; 253
3518
     e34:	20 81       	ld	r18, Z
3519
     e36:	31 81       	ldd	r19, Z+1	; 0x01
3520
	tmpTail = (CamConfig_txFifoTail+1) & (CAM_CONFIG_TX_FIFO_MASK);
3521
     e38:	84 2f       	mov	r24, r20
3522
     e3a:	8f 5f       	subi	r24, 0xFF	; 255
3523
     e3c:	87 70       	andi	r24, 0x07	; 7
3524
	CamConfig_txFifoTail = tmpTail;
3525
     e3e:	80 93 0b 01 	sts	0x010B, r24
3526
 
3527
	return(cmd);
3528
}
3529
     e42:	c9 01       	movw	r24, r18
3530
     e44:	08 95       	ret
3531
 
3532
00000e46 <Utility_delay>:
3533
	if needed...this isn't really a millisecond, so DON'T
3534
    depend on it for exact timing...
3535
***********************************************************/	
3536
void Utility_delay(unsigned short numMs)
3537
{
3538
     e46:	cf 93       	push	r28
3539
     e48:	df 93       	push	r29
3540
     e4a:	cd b7       	in	r28, 0x3d	; 61
3541
     e4c:	de b7       	in	r29, 0x3e	; 62
3542
     e4e:	24 97       	sbiw	r28, 0x04	; 4
3543
     e50:	0f b6       	in	r0, 0x3f	; 63
3544
     e52:	f8 94       	cli
3545
     e54:	de bf       	out	0x3e, r29	; 62
3546
     e56:	0f be       	out	0x3f, r0	; 63
3547
     e58:	cd bf       	out	0x3d, r28	; 61
3548
     e5a:	9c 01       	movw	r18, r24
3549
	volatile unsigned short i=0,j=0;
3550
     e5c:	19 82       	std	Y+1, r1	; 0x01
3551
     e5e:	1a 82       	std	Y+2, r1	; 0x02
3552
     e60:	1b 82       	std	Y+3, r1	; 0x03
3553
     e62:	1c 82       	std	Y+4, r1	; 0x04
3554
#ifndef SIMULATION
3555
	for (i=0; i<numMs; i++)
3556
     e64:	19 82       	std	Y+1, r1	; 0x01
3557
     e66:	1a 82       	std	Y+2, r1	; 0x02
3558
     e68:	89 81       	ldd	r24, Y+1	; 0x01
3559
     e6a:	9a 81       	ldd	r25, Y+2	; 0x02
3560
     e6c:	82 17       	cp	r24, r18
3561
     e6e:	93 07       	cpc	r25, r19
3562
     e70:	e0 f4       	brcc	.+56     	; 0xeaa
3563
	{
3564
		for (j=0; j<1000; j++)
3565
     e72:	1b 82       	std	Y+3, r1	; 0x03
3566
     e74:	1c 82       	std	Y+4, r1	; 0x04
3567
     e76:	8b 81       	ldd	r24, Y+3	; 0x03
3568
     e78:	9c 81       	ldd	r25, Y+4	; 0x04
3569
     e7a:	88 5e       	subi	r24, 0xE8	; 232
3570
     e7c:	93 40       	sbci	r25, 0x03	; 3
3571
     e7e:	58 f4       	brcc	.+22     	; 0xe96
3572
		{
3573
			asm volatile("nop"::);
3574
     e80:	00 00       	nop
3575
     e82:	8b 81       	ldd	r24, Y+3	; 0x03
3576
     e84:	9c 81       	ldd	r25, Y+4	; 0x04
3577
     e86:	01 96       	adiw	r24, 0x01	; 1
3578
     e88:	8b 83       	std	Y+3, r24	; 0x03
3579
     e8a:	9c 83       	std	Y+4, r25	; 0x04
3580
     e8c:	8b 81       	ldd	r24, Y+3	; 0x03
3581
     e8e:	9c 81       	ldd	r25, Y+4	; 0x04
3582
     e90:	88 5e       	subi	r24, 0xE8	; 232
3583
     e92:	93 40       	sbci	r25, 0x03	; 3
3584
     e94:	a8 f3       	brcs	.-22     	; 0xe80
3585
     e96:	89 81       	ldd	r24, Y+1	; 0x01
3586
     e98:	9a 81       	ldd	r25, Y+2	; 0x02
3587
     e9a:	01 96       	adiw	r24, 0x01	; 1
3588
     e9c:	89 83       	std	Y+1, r24	; 0x01
3589
     e9e:	9a 83       	std	Y+2, r25	; 0x02
3590
     ea0:	89 81       	ldd	r24, Y+1	; 0x01
3591
     ea2:	9a 81       	ldd	r25, Y+2	; 0x02
3592
     ea4:	82 17       	cp	r24, r18
3593
     ea6:	93 07       	cpc	r25, r19
3594
     ea8:	20 f3       	brcs	.-56     	; 0xe72
3595
		}
3596
	}
3597
#endif	
3598
}
3599
     eaa:	24 96       	adiw	r28, 0x04	; 4
3600
     eac:	0f b6       	in	r0, 0x3f	; 63
3601
     eae:	f8 94       	cli
3602
     eb0:	de bf       	out	0x3e, r29	; 62
3603
     eb2:	0f be       	out	0x3f, r0	; 63
3604
     eb4:	cd bf       	out	0x3d, r28	; 61
3605
     eb6:	df 91       	pop	r29
3606
     eb8:	cf 91       	pop	r28
3607
     eba:	08 95       	ret
3608
 
3609
00000ebc <DebugInt_init>:
3610
	Inputs:  none
3611
	Outputs: none
3612
***********************************************************/	
3613
void DebugInt_init(void)
3614
{
3615
     ebc:	1f 93       	push	r17
3616
	/* set PortD pin6 for output */
3617
	DDRD  |= 0x40;
3618
     ebe:	8e 9a       	sbi	0x11, 6	; 17
3619
	/* turn on LED */
3620
	PORTD |= 0x40;
3621
     ec0:	96 9a       	sbi	0x12, 6	; 18
3622
    Utility_delay(500);
3623
     ec2:	84 ef       	ldi	r24, 0xF4	; 244
3624
     ec4:	91 e0       	ldi	r25, 0x01	; 1
3625
     ec6:	bf df       	rcall	.-130    	; 0xe46
3626
    PORTD &= 0xBF;
3627
     ec8:	1f eb       	ldi	r17, 0xBF	; 191
3628
     eca:	82 b3       	in	r24, 0x12	; 18
3629
     ecc:	81 23       	and	r24, r17
3630
     ece:	82 bb       	out	0x12, r24	; 18
3631
    Utility_delay(500);
3632
     ed0:	84 ef       	ldi	r24, 0xF4	; 244
3633
     ed2:	91 e0       	ldi	r25, 0x01	; 1
3634
     ed4:	b8 df       	rcall	.-144    	; 0xe46
3635
    PORTD |= 0x40;
3636
     ed6:	96 9a       	sbi	0x12, 6	; 18
3637
    Utility_delay(500);
3638
     ed8:	84 ef       	ldi	r24, 0xF4	; 244
3639
     eda:	91 e0       	ldi	r25, 0x01	; 1
3640
     edc:	b4 df       	rcall	.-152    	; 0xe46
3641
    PORTD &= 0xBF;
3642
     ede:	82 b3       	in	r24, 0x12	; 18
3643
     ee0:	81 23       	and	r24, r17
3644
     ee2:	82 bb       	out	0x12, r24	; 18
3645
    Utility_delay(500);
3646
     ee4:	84 ef       	ldi	r24, 0xF4	; 244
3647
     ee6:	91 e0       	ldi	r25, 0x01	; 1
3648
     ee8:	ae df       	rcall	.-164    	; 0xe46
3649
    PORTD |= 0x40;
3650
     eea:	96 9a       	sbi	0x12, 6	; 18
3651
    Utility_delay(500);
3652
     eec:	84 ef       	ldi	r24, 0xF4	; 244
3653
     eee:	91 e0       	ldi	r25, 0x01	; 1
3654
     ef0:	aa df       	rcall	.-172    	; 0xe46
3655
    PORTD &= 0xBF;
3656
     ef2:	82 b3       	in	r24, 0x12	; 18
3657
     ef4:	81 23       	and	r24, r17
3658
     ef6:	82 bb       	out	0x12, r24	; 18
3659
    Utility_delay(500);
3660
     ef8:	84 ef       	ldi	r24, 0xF4	; 244
3661
     efa:	91 e0       	ldi	r25, 0x01	; 1
3662
     efc:	a4 df       	rcall	.-184    	; 0xe46
3663
    PORTD |= 0x40;
3664
     efe:	96 9a       	sbi	0x12, 6	; 18
3665
}
3666
     f00:	1f 91       	pop	r17
3667
     f02:	08 95       	ret
3668
 
3669
00000f04 <CamIntAsm_waitForNewTrackingFrame>:
3670
;		set, and the function will return.
3671
;*****************************************************************
3672
 
3673
CamIntAsm_waitForNewTrackingFrame:
3674
		sbi		_SFR_IO_ADDR(PORTD),PD6  ; For testing...
3675
     f04:	96 9a       	sbi	0x12, 6	; 18
3676
		cbi		_SFR_IO_ADDR(PORTD),PD6		
3677
     f06:	96 98       	cbi	0x12, 6	; 18
3678
		sleep
3679
     f08:	88 95       	sleep
3680
 
3681
00000f0a <CamIntAsm_acquireTrackingLine>:
3682
 
3683
;*****************************************************************
3684
; REMEMBER...everything from here on out is critically timed to be
3685
; synchronized with the flow of pixel data from the camera...
3686
;*****************************************************************
3687
 
3688
CamIntAsm_acquireTrackingLine:
3689
		brts	_cleanUp
3690
     f0a:	e6 f1       	brts	.+120    	; 0xf84
3691
		;sbi		_SFR_IO_ADDR(PORTD),PD6 ; For testing...
3692
		;cbi		_SFR_IO_ADDR(PORTD),PD6
3693
 
3694
        in      tmp1,_SFR_IO_ADDR(TCCR1B) ; Enable the PCLK line to actually
3695
     f0c:	3e b5       	in	r19, 0x2e	; 46
3696
        ori     tmp1, 0x07                 ; feed Timer1
3697
     f0e:	37 60       	ori	r19, 0x07	; 7
3698
        out     _SFR_IO_ADDR(TCCR1B),tmp1 
3699
     f10:	3e bd       	out	0x2e, r19	; 46
3700
										; The line is about to start...		
3701
		ldi     pixelCount,0			; Initialize the RLE stats...
3702
     f12:	00 e0       	ldi	r16, 0x00	; 0
3703
		ldi		pixelRunStart,PIXEL_RUN_START_INITIAL  	; Remember, we always calculate
3704
     f14:	10 e5       	ldi	r17, 0x50	; 80
3705
														; the pixel run length as
3706
														; TCNT1L - pixelRunStart
3707
 
3708
		ldi		lastColor,0x00				; clear out the last color before we start
3709
     f16:	20 e0       	ldi	r18, 0x00	; 0
3710
 
3711
		mov   	XH,currLineBuffHigh    	; Load the pointer to the current line
3712
     f18:	b9 2f       	mov	r27, r25
3713
		mov		XL,currLineBuffLow		; buffer into the X pointer regs		 
3714
     f1a:	a8 2f       	mov	r26, r24
3715
 
3716
		mov   	ZH,colorMapHigh      	; Load the pointers to the membership
3717
     f1c:	f7 2f       	mov	r31, r23
3718
		mov		ZL,colorMapLow			; lookup tables (ZL and YL will be overwritten
3719
     f1e:	e6 2f       	mov	r30, r22
3720
		mov 	YH,colorMapHigh	 		; as soon as we start reading data) to Z and Y
3721
     f20:	d7 2f       	mov	r29, r23
3722
 
3723
		in		tmp1, _SFR_IO_ADDR(TIMSK)			; enable TIMER1 to start counting
3724
     f22:	39 b7       	in	r19, 0x39	; 57
3725
		ori		tmp1, ENABLE_PCLK_TIMER1_OVERFLOW_BITMASK 	; external PCLK pulses and interrupt on 
3726
     f24:	34 60       	ori	r19, 0x04	; 4
3727
		out		_SFR_IO_ADDR(TIMSK),tmp1			; overflow
3728
     f26:	39 bf       	out	0x39, r19	; 57
3729
 
3730
		ldi 	tmp1,PIXEL_RUN_START_INITIAL	; set up the TCNT1 to overflow (and
3731
     f28:	30 e5       	ldi	r19, 0x50	; 80
3732
		ldi 	tmp2,0xFF 						; interrupts) after 176 pixels		
3733
     f2a:	4f ef       	ldi	r20, 0xFF	; 255
3734
		out 	_SFR_IO_ADDR(TCNT1H),tmp2		
3735
     f2c:	4d bd       	out	0x2d, r20	; 45
3736
		out 	_SFR_IO_ADDR(TCNT1L),tmp1				
3737
     f2e:	3c bd       	out	0x2c, r19	; 44
3738
 
3739
		mov		YL,colorMapLow		
3740
     f30:	c6 2f       	mov	r28, r22
3741
 
3742
		in 		tmp1, _SFR_IO_ADDR(GICR)	; enable the HREF interrupt...remember, we
3743
     f32:	3b b7       	in	r19, 0x3b	; 59
3744
											; only use this interrupt to synchronize
3745
											; the beginning of the line
3746
		ori 	tmp1, HREF_INTERRUPT_ENABLE_MASK
3747
     f34:	30 68       	ori	r19, 0x80	; 128
3748
		out		_SFR_IO_ADDR(GICR), tmp1
3749
     f36:	3b bf       	out	0x3b, r19	; 59
3750
 
3751
00000f38 <_trackFrame>:
3752
 
3753
;*******************************************************************************************
3754
;   Track Frame handler 
3755
;*******************************************************************************************		
3756
 
3757
_trackFrame:		
3758
		sbi		_SFR_IO_ADDR(PORTD),PD6
3759
     f38:	96 9a       	sbi	0x12, 6	; 18
3760
		sleep   ; ...And we wait...
3761
     f3a:	88 95       	sleep
3762
 
3763
	; Returning from the interrupt/sleep wakeup will consume
3764
	; 14 clock cycles (7 to wakeup from idle sleep, 3 to vector, and 4 to return)	
3765
 
3766
	; Disable the HREF interrupt
3767
		cbi		_SFR_IO_ADDR(PORTD),PD6
3768
     f3c:	96 98       	cbi	0x12, 6	; 18
3769
		in 		tmp1, _SFR_IO_ADDR(GICR)
3770
     f3e:	3b b7       	in	r19, 0x3b	; 59
3771
		andi 	tmp1, HREF_INTERRUPT_DISABLE_MASK
3772
     f40:	3f 77       	andi	r19, 0x7F	; 127
3773
		out		_SFR_IO_ADDR(GICR), tmp1
3774
     f42:	3b bf       	out	0x3b, r19	; 59
3775
 
3776
	; A couple of NOPs are needed here to sync up the pixel data...the number (2)
3777
	; of NOPs was determined emperically by trial and error.
3778
		nop
3779
     f44:	00 00       	nop
3780
	...
3781
 
3782
00000f48 <_acquirePixelBlock>:
3783
		nop
3784
_acquirePixelBlock:							;							Clock Cycle Count
3785
		in		ZL,RB_PORT         			; sample the red value (PINB)		(1)
3786
     f48:	e6 b3       	in	r30, 0x16	; 22
3787
		in		YL,G_PORT         			; sample the green value (PINC)		(1)
3788
     f4a:	c3 b3       	in	r28, 0x13	; 19
3789
		andi	YL,0x0F            			; clear the high nibble				(1)
3790
     f4c:	cf 70       	andi	r28, 0x0F	; 15
3791
		ldd		color,Z+RED_MEM_OFFSET  	; lookup the red membership			(2)
3792
     f4e:	30 81       	ld	r19, Z
3793
		in		ZL,RB_PORT         			; sample the blue value (PINB)		(1)
3794
     f50:	e6 b3       	in	r30, 0x16	; 22
3795
		ldd		greenData,Y+GREEN_MEM_OFFSET; lookup the green membership		(2)
3796
     f52:	48 89       	ldd	r20, Y+16	; 0x10
3797
		ldd		blueData,Z+BLUE_MEM_OFFSET	; lookup the blue membership		(2)
3798
     f54:	50 a1       	ldd	r21, Z+32	; 0x20
3799
		and		color,greenData 			; mask memberships together			(1)
3800
     f56:	34 23       	and	r19, r20
3801
		and		color,blueData  			; to produce the final color		(1)
3802
     f58:	35 23       	and	r19, r21
3803
		brts    _cleanUpTrackingLine		; if some interrupt routine has		(1...not set)
3804
     f5a:	76 f0       	brts	.+28     	; 0xf78
3805
											; come in and set our T flag in 
3806
											; SREG, then we need to hop out
3807
											; and blow away this frames data (common cleanup)									
3808
		cp		color,lastColor     		; check to see if the run continues	(1)
3809
     f5c:	32 17       	cp	r19, r18
3810
		breq    _acquirePixelBlock  		;									(2...equal)
3811
     f5e:	a1 f3       	breq	.-24     	; 0xf48
3812
											;									___________
3813
											;								16 clock cycles 		
3814
											; (16 clock cycles = 1 uS = 1 pixelBlock time)
3815
 
3816
		; Toggle the debug line to indicate a color change
3817
		sbi     _SFR_IO_ADDR(PORTD),PD6
3818
     f60:	96 9a       	sbi	0x12, 6	; 18
3819
		nop
3820
     f62:	00 00       	nop
3821
		cbi		_SFR_IO_ADDR(PORTD),PD6
3822
     f64:	96 98       	cbi	0x12, 6	; 18
3823
 
3824
		mov		tmp2,pixelRunStart				; get the count value of the
3825
     f66:	41 2f       	mov	r20, r17
3826
												; current pixel run
3827
		in		pixelCount,_SFR_IO_ADDR(TCNT1L)	; get the current TCNT1 value 
3828
     f68:	0c b5       	in	r16, 0x2c	; 44
3829
		mov   	pixelRunStart,pixelCount		; reload pixelRunStart for the
3830
     f6a:	10 2f       	mov	r17, r16
3831
												; next run
3832
		sub		pixelCount,tmp2     			; pixelCount = TCNT1L - pixelRunStart
3833
     f6c:	04 1b       	sub	r16, r20
3834
 
3835
		st		X+,lastColor			; record the color run in the current line buffer
3836
     f6e:	2d 93       	st	X+, r18
3837
		st		X+,pixelCount			; with its length
3838
     f70:	0d 93       	st	X+, r16
3839
		mov		lastColor,color			; set lastColor so we can figure out when it changes
3840
     f72:	23 2f       	mov	r18, r19
3841
 
3842
		nop								; waste one more cycle for a total of 16
3843
     f74:	00 00       	nop
3844
		rjmp	_acquirePixelBlock	
3845
     f76:	e8 cf       	rjmp	.-48     	; 0xf48
3846
 
3847
00000f78 <_cleanUpTrackingLine>:
3848
 
3849
; _cleanUpTrackingLine is used to write the last run length block off to the currentLineBuffer so
3850
; that all 176 pixels in the line are accounted for.
3851
_cleanUpTrackingLine:		
3852
		ldi		pixelCount,0xFF		; the length of the last run is ALWAYS 0xFF minus the last
3853
     f78:	0f ef       	ldi	r16, 0xFF	; 255
3854
		sub		pixelCount,pixelRunStart  	; pixelRunStart
3855
     f7a:	01 1b       	sub	r16, r17
3856
 
3857
		inc		pixelCount				; increment pixelCount since we actually need to account
3858
     f7c:	03 95       	inc	r16
3859
										; for the overflow of TCNT1
3860
 
3861
		st		X+,color				; record the color run in the current line buffer
3862
     f7e:	3d 93       	st	X+, r19
3863
		st		X,pixelCount		
3864
     f80:	0c 93       	st	X, r16
3865
		rjmp	_cleanUp
3866
     f82:	00 c0       	rjmp	.+0      	; 0xf84
3867
 
3868
00000f84 <_cleanUp>:
3869
 
3870
_cleanUpDumpLine:		
3871
		; NOTE: If serial data is received, to interrupt the tracking of a line, we'll
3872
		; get a EV_SERIAL_DATA_RECEIVED event, and the T bit set so we will end the
3873
		; line's processing...however, the PCLK will keep on ticking for the rest of
3874
		; the frame/line, which will cause the TCNT to eventually overflow and
3875
		; interrupt us, generating a EV_ACQUIRE_LINE_COMPLETE event.  We don't want
3876
		; this, so we need to actually turn off the PCLK counting each time we exit
3877
		; this loop, and only turn it on when we begin acquiring lines....
3878
        ; NOT NEEDED FOR NOW...
3879
		;in		tmp1, _SFR_IO_ADDR(TIMSK)			; disable TIMER1 to stop counting
3880
		;andi	tmp1, DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK 	; external PCLK pulses
3881
		;out		_SFR_IO_ADDR(TIMSK),tmp1
3882
 
3883
_cleanUp:
3884
        ; Disable the external clocking of the Timer1 counter 
3885
        in      tmp1, _SFR_IO_ADDR(TCCR1B)
3886
     f84:	3e b5       	in	r19, 0x2e	; 46
3887
        andi    tmp1, 0xF8
3888
     f86:	38 7f       	andi	r19, 0xF8	; 248
3889
        out     _SFR_IO_ADDR(TCCR1B),tmp1
3890
     f88:	3e bd       	out	0x2e, r19	; 46
3891
 
3892
		; Toggle the debug line to indicate the line is complete
3893
		sbi     _SFR_IO_ADDR(PORTD),PD6
3894
     f8a:	96 9a       	sbi	0x12, 6	; 18
3895
		cbi		_SFR_IO_ADDR(PORTD),PD6
3896
     f8c:	96 98       	cbi	0x12, 6	; 18
3897
		clt				; clear out the T bit since we have detected
3898
     f8e:	e8 94       	clt
3899
 
3900
00000f90 <_exit>:
3901
						; the interruption and are exiting to handle it
3902
_exit:
3903
		ret
3904
     f90:	08 95       	ret
3905
 
3906
00000f92 <CamIntAsm_waitForNewDumpFrame>:
3907
 
3908
;*****************************************************************		
3909
;   	Function Name: CamIntAsm_waitForNewDumpFrame
3910
;       Function Description: This function is responsible for
3911
;       going to sleep until a new frame begins (indicated by
3912
;    	VSYNC transitioning from low to high.  This will wake
3913
;       the "VSYNC sleep" up and allow it to continue with 
3914
;       acquiring a line of pixel data to dump out to the UI.
3915
;       Inputs:  r25 - MSB of currentLineBuffer
3916
;                r24 - LSB of currentLineBuffer
3917
;				 r23 - MSB of prevLineBuffer
3918
;				 r22 - LSB of prevLineBuffer
3919
;       Outputs: none
3920
;       NOTES: This function doesn't really return...it sorta just
3921
;       floats into the acquireDumpLine function after the "VSYNC sleep"
3922
;       is awoken.
3923
;*****************************************************************		
3924
CamIntAsm_waitForNewDumpFrame:
3925
		sbi		_SFR_IO_ADDR(PORTD),PD6  ; For testing...
3926
     f92:	96 9a       	sbi	0x12, 6	; 18
3927
		cbi		_SFR_IO_ADDR(PORTD),PD6
3928
     f94:	96 98       	cbi	0x12, 6	; 18
3929
		sleep
3930
     f96:	88 95       	sleep
3931
 
3932
00000f98 <CamIntAsm_acquireDumpLine>:
3933
 
3934
;*****************************************************************
3935
; REMEMBER...everything from here on out is critically timed to be
3936
; synchronized with the flow of pixel data from the camera...
3937
;*****************************************************************
3938
 
3939
CamIntAsm_acquireDumpLine:
3940
		brts	_cleanUp
3941
     f98:	ae f3       	brts	.-22     	; 0xf84
3942
		;sbi		_SFR_IO_ADDR(PORTD),PD6 ; For testing...
3943
		;cbi		_SFR_IO_ADDR(PORTD),PD6
3944
 
3945
		mov   	XH,currLineBuffHigh    	; Load the pointer to the current line
3946
     f9a:	b9 2f       	mov	r27, r25
3947
		mov		XL,currLineBuffLow		; buffer into the X pointer regs
3948
     f9c:	a8 2f       	mov	r26, r24
3949
 
3950
		mov		YH,prevLineBuffHigh		; Load the pointer to the previous line
3951
     f9e:	d7 2f       	mov	r29, r23
3952
		mov		YL,prevLineBuffLow  	; buffer into the Y pointer regs
3953
     fa0:	c6 2f       	mov	r28, r22
3954
 
3955
		ldi 	tmp1,PIXEL_RUN_START_INITIAL	; set up the TCNT1 to overflow (and
3956
     fa2:	30 e5       	ldi	r19, 0x50	; 80
3957
		ldi 	tmp2,0xFF 						; interrupts) after 176 pixels		
3958
     fa4:	4f ef       	ldi	r20, 0xFF	; 255
3959
		out 	_SFR_IO_ADDR(TCNT1H),tmp2		
3960
     fa6:	4d bd       	out	0x2d, r20	; 45
3961
		out 	_SFR_IO_ADDR(TCNT1L),tmp1		
3962
     fa8:	3c bd       	out	0x2c, r19	; 44
3963
 
3964
        in      tmp1, _SFR_IO_ADDR(TCCR1B) ; Enable the PCLK line to actually
3965
     faa:	3e b5       	in	r19, 0x2e	; 46
3966
        ori     tmp1, 0x07                 ; feed Timer1
3967
     fac:	37 60       	ori	r19, 0x07	; 7
3968
        out     _SFR_IO_ADDR(TCCR1B),tmp1
3969
     fae:	3e bd       	out	0x2e, r19	; 46
3970
        nop
3971
     fb0:	00 00       	nop
3972
 
3973
		in		tmp1, _SFR_IO_ADDR(TIMSK)			; enable TIMER1 to start counting
3974
     fb2:	39 b7       	in	r19, 0x39	; 57
3975
		ori		tmp1, ENABLE_PCLK_TIMER1_OVERFLOW_BITMASK 	; external PCLK pulses and interrupt on 
3976
     fb4:	34 60       	ori	r19, 0x04	; 4
3977
		out		_SFR_IO_ADDR(TIMSK),tmp1			; overflow			
3978
     fb6:	39 bf       	out	0x39, r19	; 57
3979
 
3980
		in 		tmp1, _SFR_IO_ADDR(GICR)	; enable the HREF interrupt...remember, we
3981
     fb8:	3b b7       	in	r19, 0x3b	; 59
3982
											; only use this interrupt to synchronize
3983
											; the beginning of the line
3984
		ori 	tmp1, HREF_INTERRUPT_ENABLE_MASK
3985
     fba:	30 68       	ori	r19, 0x80	; 128
3986
		out		_SFR_IO_ADDR(GICR), tmp1
3987
     fbc:	3b bf       	out	0x3b, r19	; 59
3988
 
3989
00000fbe <_dumpFrame>:
3990
 
3991
;*******************************************************************************************
3992
;   Dump Frame handler 
3993
;*******************************************************************************************		
3994
 
3995
_dumpFrame:		
3996
		sbi		_SFR_IO_ADDR(PORTD),PD6
3997
     fbe:	96 9a       	sbi	0x12, 6	; 18
3998
		sleep   ; ...And we wait...
3999
     fc0:	88 95       	sleep
4000
 
4001
		cbi		_SFR_IO_ADDR(PORTD),PD6
4002
     fc2:	96 98       	cbi	0x12, 6	; 18
4003
		in 		tmp1, _SFR_IO_ADDR(GICR)			; disable the HREF interrupt
4004
     fc4:	3b b7       	in	r19, 0x3b	; 59
4005
		andi 	tmp1, HREF_INTERRUPT_DISABLE_MASK  	; so we don't get interrupted
4006
     fc6:	3f 77       	andi	r19, 0x7F	; 127
4007
		out		_SFR_IO_ADDR(GICR), tmp1			; while dumping the line
4008
     fc8:	3b bf       	out	0x3b, r19	; 59
4009
	...
4010
 
4011
00000fcc <_sampleDumpPixel>:
4012
 
4013
		nop		; Remember...if we ever remove the "cbi" instruction above,
4014
				; we need to add two more NOPs to cover this
4015
 
4016
; Ok...the following loop needs to run in 8 clock cycles, so we can get every
4017
; pixel in the line...this shouldn't be a problem, since the PCLK timing was
4018
; reduced by a factor of 2 whenever we go to dump a line (this is to give us
4019
; enough time to do the sampling and storing of the pixel data).  In addition,
4020
; it is assumed that we will have to do some minor processing on the data right
4021
; before we send it out, like mask off the top 4-bits of each, and then pack both
4022
; low nibbles into a single byte for transmission...we just don't have time to
4023
; do that here (only 8 instruction cycles :-)  )
4024
_sampleDumpPixel:
4025
		in		tmp1,G_PORT				; sample the G value					(1)
4026
     fcc:	33 b3       	in	r19, 0x13	; 19
4027
		in		tmp2,RB_PORT			; sample the R/B value					(1)
4028
     fce:	46 b3       	in	r20, 0x16	; 22
4029
		st		X+,tmp1					; store to the currLineBuff and inc ptrs(2)
4030
     fd0:	3d 93       	st	X+, r19
4031
		st		Y+,tmp2					; store to the prevLineBuff and inc ptrs(2)
4032
     fd2:	49 93       	st	Y+, r20
4033
		brtc	_sampleDumpPixel		; loop back unless flag is set			(2...if not set)
4034
     fd4:	de f7       	brtc	.-10     	; 0xfcc
4035
										;									___________
4036
										;									8 cycles normally
4037
 
4038
		; if we make it here, it means the T flag is set, and we must have been interrupted
4039
		; so we need to exit (what if we were interrupted for serial? should we disable it?)
4040
		rjmp	_cleanUpDumpLine
4041
     fd6:	d6 cf       	rjmp	.-84     	; 0xf84
4042
 
4043
00000fd8 <__vector_1>:
4044
 
4045
;***********************************************************
4046
;	Function Name: <interrupt handler for External Interrupt0> 
4047
;	Function Description: This function is responsible
4048
;	for handling a rising edge on the Ext Interrupt 0.  This
4049
;	routine simply returns, since we just want to wake up
4050
;	whenever the VSYNC transitions (meaning the start of a new
4051
;	frame).
4052
;	Inputs:  none
4053
;	Outputs: none
4054
;***********************************************************
4055
SIG_INTERRUPT0:
4056
; This will wake us up when VSYNC transitions high...we just want to return
4057
		reti
4058
     fd8:	18 95       	reti
4059
 
4060
00000fda <__vector_2>:
4061
 
4062
;***********************************************************
4063
;	Function Name: <interrupt handler for External Interrupt1> 
4064
;	Function Description: This function is responsible
4065
;	for handling a falling edge on the Ext Interrupt 1.  This
4066
;	routine simply returns, since we just want to wake up
4067
;	whenever the HREF transitions (meaning the pixels 
4068
;	are starting after VSYNC transitioned, and we need to
4069
; 	start acquiring the pixel blocks
4070
;	Inputs:  none
4071
;	Outputs: none
4072
;***********************************************************	
4073
SIG_INTERRUPT1:
4074
; This will wake us up when HREF transitions high...we just want to return
4075
		reti
4076
     fda:	18 95       	reti
4077
 
4078
00000fdc <__vector_8>:
4079
 
4080
;***********************************************************
4081
;	Function Name: <interrupt handler for Timer0 overflow>
4082
;	Function Description: This function is responsible
4083
;	for handling the Timer0 overflow (hooked up to indicate
4084
;	when we have reached the number of HREFs required in a
4085
;	single frame).  We set the T flag in the SREG to
4086
;	indicate to the _acquirePixelBlock routine that it needs
4087
;	to exit, and then set the appropriate action to take in
4088
;	the eventList of the Executive module.
4089
;	Inputs:  none
4090
;	Outputs: none
4091
;   Note: Originally, the HREF pulses were also going to
4092
;   be counted by a hardware counter, but it didn't end up
4093
;   being necessary
4094
;***********************************************************
4095
;SIG_OVERFLOW0:
4096
;		set				; set the T bit in SREG
4097
;		lds		tmp1,eventBitmask
4098
;		ori		tmp1,EV_ACQUIRE_FRAME_COMPLETE
4099
;		sts		eventBitmask,tmp1
4100
;		reti
4101
 
4102
;***********************************************************
4103
;	Function Name: <interrupt handler for Timer1 overflow>
4104
;	Function Description: This function is responsible
4105
;	for handling the Timer1 overflow (hooked up to indicate
4106
;	when we have reached the end of a line of pixel data,
4107
;	since PCLK is hooked up to overflow TCNT1 after 176 
4108
;	pixels).  This routine generates an acquire line complete
4109
;	event in the fastEventBitmask, which is streamlined for
4110
;	efficiency reasons.
4111
;***********************************************************
4112
SIG_OVERFLOW1:				
4113
		lds		tmp1,fastEventBitmask   		; set a flag indicating
4114
     fdc:	30 91 72 00 	lds	r19, 0x0072
4115
		ori		tmp1,FEV_ACQUIRE_LINE_COMPLETE	; a line is complete
4116
     fe0:	31 60       	ori	r19, 0x01	; 1
4117
		sts		fastEventBitmask,tmp1
4118
     fe2:	30 93 72 00 	sts	0x0072, r19
4119
		set		; set the T bit in SREG 
4120
     fe6:	68 94       	set
4121
		;sbi		_SFR_IO_ADDR(PORTD),PD6 ; For testing...
4122
		;cbi		_SFR_IO_ADDR(PORTD),PD6 ; For testing...
4123
 
4124
		reti
4125
     fe8:	18 95       	reti
4126
 
4127
00000fea <__vector_default>:
4128
 
4129
; This is the default handler for all interrupts that don't
4130
; have handler routines specified for them.
4131
        .global __vector_default              
4132
__vector_default:
4133
        reti
4134
     fea:	18 95       	reti
4135
 
4136
00000fec <atoi>:
4137
     fec:	fc 01       	movw	r30, r24
4138
     fee:	88 27       	eor	r24, r24
4139
     ff0:	99 27       	eor	r25, r25
4140
     ff2:	e8 94       	clt
4141
 
4142
00000ff4 <.atoi_loop>:
4143
     ff4:	21 91       	ld	r18, Z+
4144
     ff6:	22 23       	and	r18, r18
4145
     ff8:	e9 f0       	breq	.+58     	; 0x1034
4146
     ffa:	20 32       	cpi	r18, 0x20	; 32
4147
     ffc:	d9 f3       	breq	.-10     	; 0xff4
4148
     ffe:	29 30       	cpi	r18, 0x09	; 9
4149
    1000:	c9 f3       	breq	.-14     	; 0xff4
4150
    1002:	2a 30       	cpi	r18, 0x0A	; 10
4151
    1004:	b9 f3       	breq	.-18     	; 0xff4
4152
    1006:	2c 30       	cpi	r18, 0x0C	; 12
4153
    1008:	a9 f3       	breq	.-22     	; 0xff4
4154
    100a:	2d 30       	cpi	r18, 0x0D	; 13
4155
    100c:	99 f3       	breq	.-26     	; 0xff4
4156
    100e:	26 37       	cpi	r18, 0x76	; 118
4157
    1010:	89 f3       	breq	.-30     	; 0xff4
4158
    1012:	2b 32       	cpi	r18, 0x2B	; 43
4159
    1014:	19 f0       	breq	.+6      	; 0x101c
4160
    1016:	2d 32       	cpi	r18, 0x2D	; 45
4161
    1018:	21 f4       	brne	.+8      	; 0x1022
4162
 
4163
0000101a <.atoi_neg>:
4164
    101a:	68 94       	set
4165
 
4166
0000101c <.atoi_loop2>:
4167
    101c:	21 91       	ld	r18, Z+
4168
    101e:	22 23       	and	r18, r18
4169
    1020:	49 f0       	breq	.+18     	; 0x1034
4170
 
4171
00001022 <.atoi_digit>:
4172
    1022:	20 33       	cpi	r18, 0x30	; 48
4173
    1024:	3c f0       	brlt	.+14     	; 0x1034
4174
    1026:	2a 33       	cpi	r18, 0x3A	; 58
4175
    1028:	2c f4       	brge	.+10     	; 0x1034
4176
    102a:	20 53       	subi	r18, 0x30	; 48
4177
    102c:	2f d0       	rcall	.+94     	; 0x108c
4178
    102e:	82 0f       	add	r24, r18
4179
    1030:	91 1d       	adc	r25, r1
4180
    1032:	f4 cf       	rjmp	.-24     	; 0x101c
4181
 
4182
00001034 <.atoi_sig>:
4183
    1034:	81 15       	cp	r24, r1
4184
    1036:	91 05       	cpc	r25, r1
4185
    1038:	21 f0       	breq	.+8      	; 0x1042
4186
    103a:	1e f4       	brtc	.+6      	; 0x1042
4187
    103c:	80 95       	com	r24
4188
    103e:	90 95       	com	r25
4189
    1040:	01 96       	adiw	r24, 0x01	; 1
4190
 
4191
00001042 <.atoi_done>:
4192
    1042:	08 95       	ret
4193
 
4194
00001044 <eeprom_read_byte>:
4195
    1044:	e1 99       	sbic	0x1c, 1	; 28
4196
    1046:	fe cf       	rjmp	.-4      	; 0x1044
4197
    1048:	9f bb       	out	0x1f, r25	; 31
4198
    104a:	8e bb       	out	0x1e, r24	; 30
4199
    104c:	e0 9a       	sbi	0x1c, 0	; 28
4200
    104e:	99 27       	eor	r25, r25
4201
    1050:	8d b3       	in	r24, 0x1d	; 29
4202
    1052:	08 95       	ret
4203
 
4204
00001054 <eeprom_read_block>:
4205
    1054:	41 15       	cp	r20, r1
4206
    1056:	51 05       	cpc	r21, r1
4207
    1058:	69 f0       	breq	.+26     	; 0x1074
4208
    105a:	dc 01       	movw	r26, r24
4209
 
4210
0000105c <eeprom_read_block_busy>:
4211
    105c:	e1 99       	sbic	0x1c, 1	; 28
4212
    105e:	fe cf       	rjmp	.-4      	; 0x105c
4213
 
4214
00001060 <eeprom_read_block_loop>:
4215
    1060:	7f bb       	out	0x1f, r23	; 31
4216
    1062:	6e bb       	out	0x1e, r22	; 30
4217
    1064:	e0 9a       	sbi	0x1c, 0	; 28
4218
    1066:	6f 5f       	subi	r22, 0xFF	; 255
4219
    1068:	7f 4f       	sbci	r23, 0xFF	; 255
4220
    106a:	0d b2       	in	r0, 0x1d	; 29
4221
    106c:	0d 92       	st	X+, r0
4222
    106e:	41 50       	subi	r20, 0x01	; 1
4223
    1070:	50 40       	sbci	r21, 0x00	; 0
4224
    1072:	b1 f7       	brne	.-20     	; 0x1060
4225
 
4226
00001074 <eeprom_read_block_done>:
4227
    1074:	08 95       	ret
4228
 
4229
00001076 <eeprom_write_byte>:
4230
    1076:	e1 99       	sbic	0x1c, 1	; 28
4231
    1078:	fe cf       	rjmp	.-4      	; 0x1076
4232
    107a:	9f bb       	out	0x1f, r25	; 31
4233
    107c:	8e bb       	out	0x1e, r24	; 30
4234
    107e:	6d bb       	out	0x1d, r22	; 29
4235
    1080:	0f b6       	in	r0, 0x3f	; 63
4236
    1082:	f8 94       	cli
4237
    1084:	e2 9a       	sbi	0x1c, 2	; 28
4238
    1086:	e1 9a       	sbi	0x1c, 1	; 28
4239
    1088:	0f be       	out	0x3f, r0	; 63
4240
    108a:	08 95       	ret
4241
 
4242
0000108c <__mulhi_const_10>:
4243
    108c:	7a e0       	ldi	r23, 0x0A	; 10
4244
    108e:	97 9f       	mul	r25, r23
4245
    1090:	90 2d       	mov	r25, r0
4246
    1092:	87 9f       	mul	r24, r23
4247
    1094:	80 2d       	mov	r24, r0
4248
    1096:	91 0d       	add	r25, r1
4249
    1098:	11 24       	eor	r1, r1
4250
    109a:	08 95       	ret
4251
 
4252
0000109c <_exit>:
4253
    109c:	ff cf       	rjmp	.-2      	; 0x109c