0,0 → 1,4253 |
|
AVRcam.elf: file format elf32-avr |
|
Sections: |
Idx Name Size VMA LMA File off Algn |
0 .noinit 00000030 00800300 00800300 00001162 2**0 |
ALLOC |
1 .bss 00000274 00800070 00800070 00001162 2**0 |
ALLOC |
2 .data 00000010 00800060 0000109e 00001152 2**0 |
CONTENTS, ALLOC, LOAD, DATA |
3 .text 0000109e 00000000 00000000 000000b4 2**1 |
CONTENTS, ALLOC, LOAD, READONLY, CODE |
4 .eeprom 00000000 00810000 00810000 00001162 2**0 |
CONTENTS |
5 .stab 00003f30 00000000 00000000 00001164 2**2 |
CONTENTS, READONLY, DEBUGGING |
6 .stabstr 0000181e 00000000 00000000 00005094 2**0 |
CONTENTS, READONLY, DEBUGGING |
Disassembly of section .text: |
|
00000000 <__vectors>: |
0: 63 c0 rjmp .+198 ; 0xc8 |
2: ea c7 rjmp .+4052 ; 0xfd8 |
4: ea c7 rjmp .+4052 ; 0xfda |
6: 7a c0 rjmp .+244 ; 0xfc |
8: 79 c0 rjmp .+242 ; 0xfc |
a: 78 c0 rjmp .+240 ; 0xfc |
c: 77 c0 rjmp .+238 ; 0xfc |
e: 76 c0 rjmp .+236 ; 0xfc |
10: e5 c7 rjmp .+4042 ; 0xfdc |
12: 74 c0 rjmp .+232 ; 0xfc |
14: 73 c0 rjmp .+230 ; 0xfc |
16: a8 c5 rjmp .+2896 ; 0xb68 |
18: 71 c0 rjmp .+226 ; 0xfc |
1a: 70 c0 rjmp .+224 ; 0xfc |
1c: 6f c0 rjmp .+222 ; 0xfc |
1e: 6e c0 rjmp .+220 ; 0xfc |
20: 6d c0 rjmp .+218 ; 0xfc |
22: 13 c6 rjmp .+3110 ; 0xc4a |
24: 6b c0 rjmp .+214 ; 0xfc |
|
00000026 <__ctors_end>: |
26: 2a c6 rjmp .+3156 ; 0xc7c |
28: 93 c6 rjmp .+3366 ; 0xd50 |
2a: 92 c6 rjmp .+3364 ; 0xd50 |
2c: 91 c6 rjmp .+3362 ; 0xd50 |
2e: 90 c6 rjmp .+3360 ; 0xd50 |
30: 8f c6 rjmp .+3358 ; 0xd50 |
32: 8e c6 rjmp .+3356 ; 0xd50 |
34: 8d c6 rjmp .+3354 ; 0xd50 |
36: 22 c6 rjmp .+3140 ; 0xc7c |
38: 8b c6 rjmp .+3350 ; 0xd50 |
3a: 8a c6 rjmp .+3348 ; 0xd50 |
3c: 89 c6 rjmp .+3346 ; 0xd50 |
3e: 88 c6 rjmp .+3344 ; 0xd50 |
40: 87 c6 rjmp .+3342 ; 0xd50 |
42: 86 c6 rjmp .+3340 ; 0xd50 |
44: 85 c6 rjmp .+3338 ; 0xd50 |
46: 2a c6 rjmp .+3156 ; 0xc9c |
48: 83 c6 rjmp .+3334 ; 0xd50 |
4a: 82 c6 rjmp .+3332 ; 0xd50 |
4c: 81 c6 rjmp .+3330 ; 0xd50 |
4e: 80 c6 rjmp .+3328 ; 0xd50 |
50: 7f c6 rjmp .+3326 ; 0xd50 |
52: 7e c6 rjmp .+3324 ; 0xd50 |
54: 7d c6 rjmp .+3322 ; 0xd50 |
56: 25 c6 rjmp .+3146 ; 0xca2 |
58: 7b c6 rjmp .+3318 ; 0xd50 |
5a: 7a c6 rjmp .+3316 ; 0xd50 |
5c: 79 c6 rjmp .+3314 ; 0xd50 |
5e: 78 c6 rjmp .+3312 ; 0xd50 |
60: 77 c6 rjmp .+3310 ; 0xd50 |
62: 76 c6 rjmp .+3308 ; 0xd50 |
64: 75 c6 rjmp .+3306 ; 0xd50 |
66: 25 c6 rjmp .+3146 ; 0xcb2 |
68: 73 c6 rjmp .+3302 ; 0xd50 |
6a: 72 c6 rjmp .+3300 ; 0xd50 |
6c: 71 c6 rjmp .+3298 ; 0xd50 |
6e: 70 c6 rjmp .+3296 ; 0xd50 |
70: 6f c6 rjmp .+3294 ; 0xd50 |
72: 6e c6 rjmp .+3292 ; 0xd50 |
74: 6d c6 rjmp .+3290 ; 0xd50 |
76: 64 c6 rjmp .+3272 ; 0xd40 |
78: 6b c6 rjmp .+3286 ; 0xd50 |
7a: 6a c6 rjmp .+3284 ; 0xd50 |
7c: 69 c6 rjmp .+3282 ; 0xd50 |
7e: 68 c6 rjmp .+3280 ; 0xd50 |
80: 67 c6 rjmp .+3278 ; 0xd50 |
82: 66 c6 rjmp .+3276 ; 0xd50 |
84: 65 c6 rjmp .+3274 ; 0xd50 |
86: 64 c6 rjmp .+3272 ; 0xd50 |
88: 63 c6 rjmp .+3270 ; 0xd50 |
8a: 62 c6 rjmp .+3268 ; 0xd50 |
8c: 61 c6 rjmp .+3266 ; 0xd50 |
8e: 60 c6 rjmp .+3264 ; 0xd50 |
90: 5f c6 rjmp .+3262 ; 0xd50 |
92: 5e c6 rjmp .+3260 ; 0xd50 |
94: 5d c6 rjmp .+3258 ; 0xd50 |
96: 23 c6 rjmp .+3142 ; 0xcde |
98: 5b c6 rjmp .+3254 ; 0xd50 |
9a: 5a c6 rjmp .+3252 ; 0xd50 |
9c: 59 c6 rjmp .+3250 ; 0xd50 |
9e: 58 c6 rjmp .+3248 ; 0xd50 |
a0: 57 c6 rjmp .+3246 ; 0xd50 |
a2: 56 c6 rjmp .+3244 ; 0xd50 |
a4: 55 c6 rjmp .+3242 ; 0xd50 |
a6: fd c5 rjmp .+3066 ; 0xca2 |
a8: 53 c6 rjmp .+3238 ; 0xd50 |
aa: 52 c6 rjmp .+3236 ; 0xd50 |
ac: 51 c6 rjmp .+3234 ; 0xd50 |
ae: 50 c6 rjmp .+3232 ; 0xd50 |
b0: 4f c6 rjmp .+3230 ; 0xd50 |
b2: 4e c6 rjmp .+3228 ; 0xd50 |
b4: 4d c6 rjmp .+3226 ; 0xd50 |
b6: 1f c6 rjmp .+3134 ; 0xcf6 |
b8: 4b c6 rjmp .+3222 ; 0xd50 |
ba: 4a c6 rjmp .+3220 ; 0xd50 |
bc: 49 c6 rjmp .+3218 ; 0xd50 |
be: 48 c6 rjmp .+3216 ; 0xd50 |
c0: 47 c6 rjmp .+3214 ; 0xd50 |
c2: 46 c6 rjmp .+3212 ; 0xd50 |
c4: 45 c6 rjmp .+3210 ; 0xd50 |
c6: 36 c6 rjmp .+3180 ; 0xd34 |
|
000000c8 <__init>: |
c8: 11 24 eor r1, r1 |
ca: 1f be out 0x3f, r1 ; 63 |
cc: cf e5 ldi r28, 0x5F ; 95 |
ce: d4 e0 ldi r29, 0x04 ; 4 |
d0: de bf out 0x3e, r29 ; 62 |
d2: cd bf out 0x3d, r28 ; 61 |
|
000000d4 <__do_copy_data>: |
d4: 10 e0 ldi r17, 0x00 ; 0 |
d6: a0 e6 ldi r26, 0x60 ; 96 |
d8: b0 e0 ldi r27, 0x00 ; 0 |
da: ee e9 ldi r30, 0x9E ; 158 |
dc: f0 e1 ldi r31, 0x10 ; 16 |
de: 02 c0 rjmp .+4 ; 0xe4 |
|
000000e0 <.do_copy_data_loop>: |
e0: 05 90 lpm r0, Z+ |
e2: 0d 92 st X+, r0 |
|
000000e4 <.do_copy_data_start>: |
e4: a0 37 cpi r26, 0x70 ; 112 |
e6: b1 07 cpc r27, r17 |
e8: d9 f7 brne .-10 ; 0xe0 |
|
000000ea <__do_clear_bss>: |
ea: 12 e0 ldi r17, 0x02 ; 2 |
ec: a0 e7 ldi r26, 0x70 ; 112 |
ee: b0 e0 ldi r27, 0x00 ; 0 |
f0: 01 c0 rjmp .+2 ; 0xf4 |
|
000000f2 <.do_clear_bss_loop>: |
f2: 1d 92 st X+, r1 |
|
000000f4 <.do_clear_bss_start>: |
f4: a4 3e cpi r26, 0xE4 ; 228 |
f6: b1 07 cpc r27, r17 |
f8: e1 f7 brne .-8 ; 0xf2 |
fa: 31 c0 rjmp .+98 ; 0x15e |
|
000000fc <__bad_interrupt>: |
fc: 76 c7 rjmp .+3820 ; 0xfea |
|
000000fe <CamInt_init>: |
#endif |
|
/* set up the mega8 ports that will be interfacing |
with the camera */ |
CAM_CONTROL_PORT_DIR |= (1<<CAM_RESET_LINE); /* cam reset is output */ |
fe: 8f 9a sbi 0x11, 7 ; 17 |
CAM_CONTROL_PORT_DIR |= 0x80; /* set just the MSB as an output */ |
100: 8f 9a sbi 0x11, 7 ; 17 |
CAM_CONTROL_PORT_DIR &= 0xFB; /* make sure bit2 is clear (input) */ |
102: 8a 98 cbi 0x11, 2 ; 17 |
CAM_CONTROL_PORT &= 0x7F; /* set reset line low */ |
104: 97 98 cbi 0x12, 7 ; 18 |
CAM_G_BUS_DIR &= 0xF0; /* 4-bit G bus all inputs */ |
106: 90 ef ldi r25, 0xF0 ; 240 |
108: 87 b3 in r24, 0x17 ; 23 |
10a: 89 23 and r24, r25 |
10c: 87 bb out 0x17, r24 ; 23 |
CAM_G_BUS_DIR |= 0xF0; /* disable the pull-up on PB4 and PB5 */ |
10e: 87 b3 in r24, 0x17 ; 23 |
110: 89 2b or r24, r25 |
112: 87 bb out 0x17, r24 ; 23 |
CAM_RB_BUS_DIR &= 0xF0; /* 4-bit RB bus all inputs */ |
114: 84 b3 in r24, 0x14 ; 20 |
116: 89 23 and r24, r25 |
118: 84 bb out 0x14, r24 ; 20 |
|
/* ensure that timer1 is disabled to start...eventually, when PCLK needs |
to feed timer1 through the external counter, it will be enabled on an |
"as needed" basis...*/ |
TCCR1B &= ~( (1<<CS12)|(1<<CS11)|(1<<CS10) ); |
11a: 8e b5 in r24, 0x2e ; 46 |
11c: 88 7f andi r24, 0xF8 ; 248 |
11e: 8e bd out 0x2e, r24 ; 46 |
|
/* we'll turn on the interrupt after we assign the initial TCNT value */ |
|
/* set up External Interrupt1 to interrupt us on rising edges (HREF)... |
this is needed to indicate when the first pixel of each line is about to start, so |
we can synch up with it...this interrupt will be disabled once HREF goes high */ |
|
MCUCR |= (1<<ISC11) | (1<<ISC10); /* rising edge interrupt */ |
120: 85 b7 in r24, 0x35 ; 53 |
122: 8c 60 ori r24, 0x0C ; 12 |
124: 85 bf out 0x35, r24 ; 53 |
/* the interrupt will be enabled when we are ready to detect the rising edge of |
HREF...its now primed and ready to go */ |
|
/* set up External Interrupt0 to interrupt us on rising edges (VSYNC) */ |
MCUCR |= (1<<ISC01) | (1<<ISC00); /* rising edge interrupt */ |
126: 85 b7 in r24, 0x35 ; 53 |
128: 83 60 ori r24, 0x03 ; 3 |
12a: 85 bf out 0x35, r24 ; 53 |
GICR |= (1<<INT0); /* interrupt request enabled */ |
12c: 8b b7 in r24, 0x3b ; 59 |
12e: 80 64 ori r24, 0x40 ; 64 |
130: 8b bf out 0x3b, r24 ; 59 |
|
/* set up TimerO to count and be clocked from an external pulse source |
(HREF) on falling edges...eventually, we need to enable the interrupt |
for this! FIX THIS */ |
TCCR0 = (1<<CS02)|(1<<CS01)|(0<<CS00); |
132: 86 e0 ldi r24, 0x06 ; 6 |
134: 83 bf out 0x33, r24 ; 51 |
|
/* setting up the PCLK counter with Timer1 will be done right after |
we start receiving pixels in each line...we sacrifice the first pixel |
in each line, but we'll account for it...*/ |
|
/* set up the mega8 so that its sleep mode puts it in an IDLE sleep |
mode, where it can wake up as fast as possible */ |
set_sleep_mode(SLEEP_MODE_IDLE); |
136: 85 b7 in r24, 0x35 ; 53 |
138: 8f 78 andi r24, 0x8F ; 143 |
13a: 85 bf out 0x35, r24 ; 53 |
/* umm....we need to actually enable the sleep mode...*/ |
MCUCR |= 0x80; |
13c: 85 b7 in r24, 0x35 ; 53 |
13e: 80 68 ori r24, 0x80 ; 128 |
140: 85 bf out 0x35, r24 ; 53 |
|
/* initialize the memLookup table */ |
memset(colorMap,0x00,NUM_ELEMENTS_IN_COLOR_MAP); |
142: 80 e0 ldi r24, 0x00 ; 0 |
144: 93 e0 ldi r25, 0x03 ; 3 |
146: 20 e3 ldi r18, 0x30 ; 48 |
148: fc 01 movw r30, r24 |
14a: 11 92 st Z+, r1 |
14c: 2a 95 dec r18 |
14e: e9 f7 brne .-6 ; 0x14a |
|
/* read the color map out of EEPROM */ |
eeprom_read_block(colorMap, (unsigned char*)0x01,NUM_ELEMENTS_IN_COLOR_MAP); |
150: 40 e3 ldi r20, 0x30 ; 48 |
152: 50 e0 ldi r21, 0x00 ; 0 |
154: 61 e0 ldi r22, 0x01 ; 1 |
156: 70 e0 ldi r23, 0x00 ; 0 |
158: 7d d7 rcall .+3834 ; 0x1054 |
|
#if OUTPUT_INITIAL_COLOR_MAP |
UIMgr_txBuffer("\r\n",2); |
for (i=0; i<NUM_ELEMENTS_IN_COLOR_MAP; i++) |
{ |
memset(asciiBuffer,0x00,5); |
itoa(colorMap[i],asciiBuffer,10); |
UIMgr_txBuffer(asciiBuffer,3); |
UIMgr_txBuffer(" ",1); |
if (i==15 || i == 31) |
{ |
/* break up the output */ |
UIMgr_txBuffer("\r\n",2); |
} |
} |
#endif |
|
#ifndef NO_CRYSTAL |
CamInt_resetCam(); |
#endif |
} |
15a: 08 95 ret |
|
0000015c <CamInt_resetCam>: |
|
/*********************************************************** |
Function Name: CamInt_resetCam |
Function Description: This function is responsible |
for resetting the camera. This is accomplished by |
toggling the reset line on the OV6620 for ~100 mS. |
Inputs: none |
Outputs: none |
IMPORTANT NOTE: This function has effectively been removed |
since resetting the camera now causes the camera to not |
output the clock signal. Thus, if we reset the cam, the |
AVR has no clock, and thus doesn't run... |
***********************************************************/ |
void CamInt_resetCam(void) |
{ |
15c: 08 95 ret |
|
0000015e <main>: |
Inputs: none |
Outputs: int |
***********************************************************/ |
int main(void) |
{ |
15e: cf e5 ldi r28, 0x5F ; 95 |
160: d4 e0 ldi r29, 0x04 ; 4 |
162: de bf out 0x3e, r29 ; 62 |
164: cd bf out 0x3d, r28 ; 61 |
/* initialize all of the interface modules */ |
DebugInt_init(); |
166: aa d6 rcall .+3412 ; 0xebc |
UartInt_init(); |
168: f1 d4 rcall .+2530 ; 0xb4c |
I2CInt_init(); |
16a: 2c d5 rcall .+2648 ; 0xbc4 |
CamInt_init(); |
16c: c8 df rcall .-112 ; 0xfe |
|
/* initialize the remaining modules that will process |
data...interrupts need to be on for these */ |
ENABLE_INTS(); |
16e: 78 94 sei |
CamConfig_init(); |
170: fa d5 rcall .+3060 ; 0xd66 |
UIMgr_init(); |
172: 94 d2 rcall .+1320 ; 0x69c |
FrameMgr_init(); |
174: 7f d0 rcall .+254 ; 0x274 |
|
/* provide a short delay for the camera to stabilize before |
we let the executive start up */ |
Utility_delay(1000); |
176: 88 ee ldi r24, 0xE8 ; 232 |
178: 93 e0 ldi r25, 0x03 ; 3 |
17a: 65 d6 rcall .+3274 ; 0xe46 |
|
/* the rest of the application will be under the |
control of the Executive. */ |
Exec_run(); |
17c: 03 d0 rcall .+6 ; 0x184 |
|
/* this should never be reached */ |
return(0); |
} |
17e: 80 e0 ldi r24, 0x00 ; 0 |
180: 90 e0 ldi r25, 0x00 ; 0 |
182: 8c c7 rjmp .+3864 ; 0x109c |
|
00000184 <Exec_run>: |
Inputs: none |
Outputs: none |
***********************************************************/ |
void Exec_run(void) |
{ |
184: cf 93 push r28 |
unsigned char eventGenerated; |
|
while(1) |
{ |
if (fastEventBitmask) |
186: 80 91 72 00 lds r24, 0x0072 |
18a: 88 23 and r24, r24 |
18c: b9 f0 breq .+46 ; 0x1bc |
{ |
/* an event needing fast processing has been received */ |
/* a received line needs to be processed...this |
needs to be processed as quickly as possible */ |
if (fastEventBitmask & FEV_ACQUIRE_LINE_COMPLETE) |
18e: 80 ff sbrs r24, 0 |
190: 09 c0 rjmp .+18 ; 0x1a4 |
{ |
DISABLE_INTS(); |
192: f8 94 cli |
fastEventBitmask &= ~FEV_ACQUIRE_LINE_COMPLETE; |
194: 80 91 72 00 lds r24, 0x0072 |
198: 8e 7f andi r24, 0xFE ; 254 |
19a: 80 93 72 00 sts 0x0072, r24 |
ENABLE_INTS(); |
19e: 78 94 sei |
FrameMgr_processLine(); |
1a0: f8 d0 rcall .+496 ; 0x392 |
|
/* also check if serial data needs to be sent |
out through UIMgr */ |
UIMgr_transmitPendingData(); |
1a2: ac d2 rcall .+1368 ; 0x6fc |
|
/* we can't just call acquire line again here, |
since we don't know if we need to acquire another |
line or not (it depends on the FrameMgr to figure |
this out) */ |
} |
if (fastEventBitmask & FEV_PROCESS_LINE_COMPLETE) |
1a4: 80 91 72 00 lds r24, 0x0072 |
1a8: 81 ff sbrs r24, 1 |
1aa: 08 c0 rjmp .+16 ; 0x1bc |
{ |
DISABLE_INTS(); |
1ac: f8 94 cli |
fastEventBitmask &= ~FEV_PROCESS_LINE_COMPLETE; |
1ae: 80 91 72 00 lds r24, 0x0072 |
1b2: 8d 7f andi r24, 0xFD ; 253 |
1b4: 80 93 72 00 sts 0x0072, r24 |
ENABLE_INTS(); |
1b8: 78 94 sei |
FrameMgr_acquireLine(); |
1ba: b9 d0 rcall .+370 ; 0x32e |
} |
} |
|
if (IS_DATA_IN_EVENT_FIFO() == TRUE) |
1bc: 90 91 70 00 lds r25, 0x0070 |
1c0: 80 91 71 00 lds r24, 0x0071 |
1c4: 98 17 cp r25, r24 |
1c6: f9 f2 breq .-66 ; 0x186 |
{ |
eventGenerated = Exec_readEventFifo(); |
1c8: 32 d0 rcall .+100 ; 0x22e |
1ca: c8 2f mov r28, r24 |
switch(eventGenerated) |
1cc: 99 27 eor r25, r25 |
1ce: 80 31 cpi r24, 0x10 ; 16 |
1d0: 91 05 cpc r25, r1 |
1d2: 11 f1 breq .+68 ; 0x218 |
1d4: 81 31 cpi r24, 0x11 ; 17 |
1d6: 91 05 cpc r25, r1 |
1d8: 7c f4 brge .+30 ; 0x1f8 |
1da: 82 30 cpi r24, 0x02 ; 2 |
1dc: 91 05 cpc r25, r1 |
1de: 09 f1 breq .+66 ; 0x222 |
1e0: 83 30 cpi r24, 0x03 ; 3 |
1e2: 91 05 cpc r25, r1 |
1e4: 1c f4 brge .+6 ; 0x1ec |
1e6: 01 97 sbiw r24, 0x01 ; 1 |
1e8: d1 f0 breq .+52 ; 0x21e |
1ea: cd cf rjmp .-102 ; 0x186 |
1ec: 84 30 cpi r24, 0x04 ; 4 |
1ee: 91 05 cpc r25, r1 |
1f0: c1 f0 breq .+48 ; 0x222 |
1f2: 08 97 sbiw r24, 0x08 ; 8 |
1f4: b1 f0 breq .+44 ; 0x222 |
1f6: c7 cf rjmp .-114 ; 0x186 |
1f8: 80 38 cpi r24, 0x80 ; 128 |
1fa: 91 05 cpc r25, r1 |
1fc: 91 f0 breq .+36 ; 0x222 |
1fe: 81 38 cpi r24, 0x81 ; 129 |
200: 91 05 cpc r25, r1 |
202: 1c f4 brge .+6 ; 0x20a |
204: 80 97 sbiw r24, 0x20 ; 32 |
206: 69 f0 breq .+26 ; 0x222 |
208: be cf rjmp .-132 ; 0x186 |
20a: 81 38 cpi r24, 0x81 ; 129 |
20c: 91 05 cpc r25, r1 |
20e: 49 f0 breq .+18 ; 0x222 |
210: 80 39 cpi r24, 0x90 ; 144 |
212: 91 05 cpc r25, r1 |
214: 49 f0 breq .+18 ; 0x228 |
216: b7 cf rjmp .-146 ; 0x186 |
{ |
case (EV_DUMP_FRAME): |
FrameMgr_dispatchEvent(eventGenerated); |
break; |
|
case (EV_ENABLE_TRACKING): |
FrameMgr_dispatchEvent(eventGenerated); |
break; |
|
case (EV_DISABLE_TRACKING): |
FrameMgr_dispatchEvent(eventGenerated); |
break; |
|
case (EV_ACQUIRE_LINE_COMPLETE): |
FrameMgr_dispatchEvent(eventGenerated); |
218: 8c 2f mov r24, r28 |
21a: 33 d0 rcall .+102 ; 0x282 |
UIMgr_dispatchEvent(eventGenerated); |
21c: 05 c0 rjmp .+10 ; 0x228 |
break; |
|
case (EV_ACQUIRE_FRAME_COMPLETE): |
FrameMgr_dispatchEvent(eventGenerated); |
break; |
|
case (EV_PROCESS_LINE_COMPLETE): |
FrameMgr_dispatchEvent(eventGenerated); |
break; |
|
case (EV_PROCESS_FRAME_COMPLETE): |
FrameMgr_dispatchEvent(eventGenerated); |
break; |
|
case (EV_SERIAL_DATA_RECEIVED): |
UIMgr_dispatchEvent(eventGenerated); |
21e: 8c 2f mov r24, r28 |
220: 58 d2 rcall .+1200 ; 0x6d2 |
FrameMgr_dispatchEvent(eventGenerated); |
222: 8c 2f mov r24, r28 |
224: 2e d0 rcall .+92 ; 0x282 |
break; |
226: af cf rjmp .-162 ; 0x186 |
|
case (EV_SERIAL_DATA_PENDING_TX): |
UIMgr_dispatchEvent(eventGenerated); |
228: 8c 2f mov r24, r28 |
22a: 53 d2 rcall .+1190 ; 0x6d2 |
break; |
22c: ac cf rjmp .-168 ; 0x186 |
|
0000022e <Exec_readEventFifo>: |
|
default: |
break; |
} |
} |
|
/* toggle the debug line */ |
|
} |
} |
|
/*********************************************************** |
Function Name: Exec_readEventFifo |
Function Description: This function is responsible for |
reading a single event out of the event fifo. |
Inputs: none |
Outputs: unsigned char-the data read |
***********************************************************/ |
static unsigned char Exec_readEventFifo(void) |
{ |
unsigned char dataByte, tmpTail; |
|
DISABLE_INTS(); |
22e: f8 94 cli |
/* just return the current tail from the tx fifo */ |
dataByte = Exec_eventFifo[Exec_eventFifoTail]; |
230: 20 91 71 00 lds r18, 0x0071 |
234: 8c e6 ldi r24, 0x6C ; 108 |
236: 92 e0 ldi r25, 0x02 ; 2 |
238: fc 01 movw r30, r24 |
23a: e2 0f add r30, r18 |
23c: f1 1d adc r31, r1 |
23e: 90 81 ld r25, Z |
tmpTail = (Exec_eventFifoTail+1) & (EXEC_EVENT_FIFO_MASK); |
240: 82 2f mov r24, r18 |
242: 8f 5f subi r24, 0xFF ; 255 |
244: 87 70 andi r24, 0x07 ; 7 |
Exec_eventFifoTail = tmpTail; |
246: 80 93 71 00 sts 0x0071, r24 |
ENABLE_INTS(); |
24a: 78 94 sei |
|
return(dataByte); |
24c: 89 2f mov r24, r25 |
24e: 99 27 eor r25, r25 |
} |
250: 08 95 ret |
|
00000252 <Exec_writeEventFifo>: |
|
/*********************************************************** |
Function Name: Exec_writeEventFifo |
Function Description: This function is responsible for |
writing a single event to the event fifo and |
updating the appropriate pointers. |
Inputs: data - the byte to write to the Fifo |
Outputs: none |
***********************************************************/ |
void Exec_writeEventFifo(unsigned char event) |
{ |
252: 38 2f mov r19, r24 |
unsigned char tmpHead; |
|
DISABLE_INTS(); |
254: f8 94 cli |
Exec_eventFifo[Exec_eventFifoHead] = event; |
256: 20 91 70 00 lds r18, 0x0070 |
25a: 8c e6 ldi r24, 0x6C ; 108 |
25c: 92 e0 ldi r25, 0x02 ; 2 |
25e: fc 01 movw r30, r24 |
260: e2 0f add r30, r18 |
262: f1 1d adc r31, r1 |
264: 30 83 st Z, r19 |
|
/* now move the head up */ |
tmpHead = (Exec_eventFifoHead + 1) & (EXEC_EVENT_FIFO_MASK); |
266: 82 2f mov r24, r18 |
268: 8f 5f subi r24, 0xFF ; 255 |
26a: 87 70 andi r24, 0x07 ; 7 |
Exec_eventFifoHead = tmpHead; |
26c: 80 93 70 00 sts 0x0070, r24 |
ENABLE_INTS(); |
270: 78 94 sei |
} |
272: 08 95 ret |
|
00000274 <FrameMgr_init>: |
Outputs: none |
***********************************************************/ |
void FrameMgr_init(void) |
{ |
memset(trackedObjectTable,0x00,sizeof(trackedObjectTable)); |
274: 80 e4 ldi r24, 0x40 ; 64 |
276: e8 e7 ldi r30, 0x78 ; 120 |
278: f0 e0 ldi r31, 0x00 ; 0 |
27a: 11 92 st Z+, r1 |
27c: 8a 95 dec r24 |
27e: e9 f7 brne .-6 ; 0x27a |
} |
280: 08 95 ret |
|
00000282 <FrameMgr_dispatchEvent>: |
|
|
/*********************************************************** |
Function Name: FrameMgr_dispatchEvent |
Function Description: This function is responsible for |
taking an incoming event and performing the needed |
actions with it as pertains to the FrameMgr. |
Inputs: event - the generated event |
Outputs: none |
***********************************************************/ |
void FrameMgr_dispatchEvent(unsigned char event) |
{ |
switch(event) |
282: 99 27 eor r25, r25 |
284: 84 30 cpi r24, 0x04 ; 4 |
286: 91 05 cpc r25, r1 |
288: 51 f1 breq .+84 ; 0x2de |
28a: 85 30 cpi r24, 0x05 ; 5 |
28c: 91 05 cpc r25, r1 |
28e: 34 f4 brge .+12 ; 0x29c |
290: 81 30 cpi r24, 0x01 ; 1 |
292: 91 05 cpc r25, r1 |
294: 31 f1 breq .+76 ; 0x2e2 |
296: 02 97 sbiw r24, 0x02 ; 2 |
298: 71 f0 breq .+28 ; 0x2b6 |
{ |
case EV_DUMP_FRAME: |
/* try re-initializing the camera before we start dumping */ |
|
CamConfig_setCamReg(0x11,0x01); /* reduce the frame rate for dumping*/ |
CamConfig_sendFifoCmds(); |
Utility_delay(1000); /* allow the new frame rate to settle */ |
lineCount = 0; |
currentState = ST_FrameMgr_DumpingFrame; |
//CamIntAsm_waitForNewDumpFrame(currentLineBuffer,previousLineBuffer); |
FrameMgr_acquireLine(); |
break; |
|
case EV_ENABLE_TRACKING: |
currentState = ST_FrameMgr_TrackingFrame; |
FrameMgr_acquireFrame(); |
break; |
|
case EV_ACQUIRE_FRAME_COMPLETE: |
FrameMgr_processFrame(); |
break; |
|
case EV_PROCESS_FRAME_COMPLETE: |
FrameMgr_acquireFrame(); |
break; |
|
case EV_SERIAL_DATA_RECEIVED: |
if (currentState != ST_FrameMgr_idle) |
{ |
/* we need to go back to processing line data, since |
serial data reception interrupted us....just trash the |
frame and act like the frame has been processed, which |
will kick off the system to wait for the next line */ |
PUBLISH_EVENT(EV_PROCESS_FRAME_COMPLETE); |
} |
break; |
|
case EV_DISABLE_TRACKING: |
/* tracking needs to be turned off */ |
currentState = ST_FrameMgr_idle; |
break; |
} |
} |
29a: 08 95 ret |
29c: 80 38 cpi r24, 0x80 ; 128 |
29e: 91 05 cpc r25, r1 |
2a0: c1 f0 breq .+48 ; 0x2d2 |
2a2: 81 38 cpi r24, 0x81 ; 129 |
2a4: 91 05 cpc r25, r1 |
2a6: 1c f4 brge .+6 ; 0x2ae |
2a8: 80 97 sbiw r24, 0x20 ; 32 |
2aa: b9 f0 breq .+46 ; 0x2da |
2ac: 08 95 ret |
2ae: 81 38 cpi r24, 0x81 ; 129 |
2b0: 91 05 cpc r25, r1 |
2b2: f1 f0 breq .+60 ; 0x2f0 |
2b4: 08 95 ret |
2b6: 61 e0 ldi r22, 0x01 ; 1 |
2b8: 81 e1 ldi r24, 0x11 ; 17 |
2ba: 66 d5 rcall .+2764 ; 0xd88 |
2bc: 6a d5 rcall .+2772 ; 0xd92 |
2be: 88 ee ldi r24, 0xE8 ; 232 |
2c0: 93 e0 ldi r25, 0x03 ; 3 |
2c2: c1 d5 rcall .+2946 ; 0xe46 |
2c4: 10 92 73 00 sts 0x0073, r1 |
2c8: 82 e0 ldi r24, 0x02 ; 2 |
2ca: 80 93 74 00 sts 0x0074, r24 |
2ce: 2f d0 rcall .+94 ; 0x32e |
2d0: 08 95 ret |
2d2: 81 e0 ldi r24, 0x01 ; 1 |
2d4: 80 93 74 00 sts 0x0074, r24 |
2d8: 02 c0 rjmp .+4 ; 0x2de |
2da: 18 d1 rcall .+560 ; 0x50c |
2dc: 08 95 ret |
2de: 0c d0 rcall .+24 ; 0x2f8 |
2e0: 08 95 ret |
2e2: 80 91 74 00 lds r24, 0x0074 |
2e6: 88 23 and r24, r24 |
2e8: 29 f0 breq .+10 ; 0x2f4 |
2ea: 84 e0 ldi r24, 0x04 ; 4 |
2ec: b2 df rcall .-156 ; 0x252 |
2ee: 08 95 ret |
2f0: 10 92 74 00 sts 0x0074, r1 |
2f4: 08 95 ret |
2f6: 08 95 ret |
|
000002f8 <FrameMgr_acquireFrame>: |
|
/*********************************************************** |
Function Name: FrameMgr_acquireFrame |
Function Description: This function is responsible for |
beginning of the acquisition of a new frame of data |
from the camera interface. The acquisition of this line |
depends on the current state of the FrameMgr. |
Inputs: none |
Outputs: none |
***********************************************************/ |
void FrameMgr_acquireFrame(void) |
{ |
if (currentState == ST_FrameMgr_TrackingFrame) |
2f8: 80 91 74 00 lds r24, 0x0074 |
2fc: 81 30 cpi r24, 0x01 ; 1 |
2fe: a9 f4 brne .+42 ; 0x32a |
{ |
trackedLineCount = 0; |
300: 10 92 77 00 sts 0x0077, r1 |
numPrevTrackedObjects = numCurrTrackedObjects; |
304: 80 91 75 00 lds r24, 0x0075 |
308: 80 93 76 00 sts 0x0076, r24 |
numCurrTrackedObjects = 0; |
30c: 10 92 75 00 sts 0x0075, r1 |
|
/* clear out the tracking table, and wait for the new frame |
to start */ |
memset(trackedObjectTable,0x00,sizeof(trackedObjectTable)); |
310: 80 e4 ldi r24, 0x40 ; 64 |
312: e8 e7 ldi r30, 0x78 ; 120 |
314: f0 e0 ldi r31, 0x00 ; 0 |
316: 11 92 st Z+, r1 |
318: 8a 95 dec r24 |
31a: e9 f7 brne .-6 ; 0x316 |
//CamIntAsm_waitForNewTrackingFrame(currentLineBuffer,colorMap); |
WAIT_FOR_VSYNC_HIGH(); |
31c: 82 9b sbis 0x10, 2 ; 16 |
31e: fe cf rjmp .-4 ; 0x31c |
CamIntAsm_acquireTrackingLine(currentLineBuffer,colorMap); |
320: 60 e0 ldi r22, 0x00 ; 0 |
322: 73 e0 ldi r23, 0x03 ; 3 |
324: 8c eb ldi r24, 0xBC ; 188 |
326: 91 e0 ldi r25, 0x01 ; 1 |
328: f0 d5 rcall .+3040 ; 0xf0a |
} |
} |
32a: 08 95 ret |
32c: 08 95 ret |
|
0000032e <FrameMgr_acquireLine>: |
|
/*********************************************************** |
Function Name: FrameMgr_acquireLine |
Function Description: This function is responsible for |
acquiring a line of data from the camera interface. |
The acquisition of this line depends on the current |
state of the FrameMgr. |
Inputs: none |
Outputs: none |
***********************************************************/ |
void FrameMgr_acquireLine(void) |
{ |
unsigned char tmpLineCount; |
|
/* clearing out the buffers takes too long...we should |
just overwrite the data here without a problem when |
we start acquiring...at no point do we check for |
a 0x00 value in the current or previous lineBuffers, |
so it was a bit excessive :-) */ |
|
/* check which state we are in and proceed as needed */ |
if (currentState == ST_FrameMgr_DumpingFrame) |
32e: 80 91 74 00 lds r24, 0x0074 |
332: 82 30 cpi r24, 0x02 ; 2 |
334: 11 f5 brne .+68 ; 0x37a |
{ |
tmpLineCount = lineCount*2; |
336: 80 91 73 00 lds r24, 0x0073 |
33a: 88 0f add r24, r24 |
|
/* clearing out the line data in dump mode is ok, and actually |
is needed, since it is possible for the first dump line in |
a frame to come back with the last line captured of the |
last capture session...*/ |
memset(currentLineBuffer,0x00,LENGTH_OF_LINE_BUFFER); |
33c: 90 eb ldi r25, 0xB0 ; 176 |
33e: ec eb ldi r30, 0xBC ; 188 |
340: f1 e0 ldi r31, 0x01 ; 1 |
342: 11 92 st Z+, r1 |
344: 9a 95 dec r25 |
346: e9 f7 brne .-6 ; 0x342 |
memset(previousLineBuffer,0x00,LENGTH_OF_LINE_BUFFER); |
348: 90 eb ldi r25, 0xB0 ; 176 |
34a: ec e0 ldi r30, 0x0C ; 12 |
34c: f1 e0 ldi r31, 0x01 ; 1 |
34e: 11 92 st Z+, r1 |
350: 9a 95 dec r25 |
352: e9 f7 brne .-6 ; 0x34e |
/* wait for another VSYNC so we know which frame to use |
to start looking for a line to receive */ |
WAIT_FOR_VSYNC_HIGH(); |
354: 82 9b sbis 0x10, 2 ; 16 |
356: fe cf rjmp .-4 ; 0x354 |
WAIT_FOR_VSYNC_LOW(); |
358: 82 99 sbic 0x10, 2 ; 16 |
35a: fe cf rjmp .-4 ; 0x358 |
|
/* look at lineCount to determine how many HREFs we should |
wait before we start sampling */ |
while(tmpLineCount != 0) |
35c: 88 23 and r24, r24 |
35e: 39 f0 breq .+14 ; 0x36e |
{ |
WAIT_FOR_HREF_HIGH(); |
360: 84 9b sbis 0x10, 4 ; 16 |
362: fe cf rjmp .-4 ; 0x360 |
tmpLineCount--; |
364: 81 50 subi r24, 0x01 ; 1 |
WAIT_FOR_HREF_LOW(); |
366: 84 99 sbic 0x10, 4 ; 16 |
368: fe cf rjmp .-4 ; 0x366 |
36a: 88 23 and r24, r24 |
36c: c9 f7 brne .-14 ; 0x360 |
} |
|
/* we should now be ready to sample our line...*/ |
CamIntAsm_acquireDumpLine(currentLineBuffer,previousLineBuffer); |
36e: 6c e0 ldi r22, 0x0C ; 12 |
370: 71 e0 ldi r23, 0x01 ; 1 |
372: 8c eb ldi r24, 0xBC ; 188 |
374: 91 e0 ldi r25, 0x01 ; 1 |
376: 10 d6 rcall .+3104 ; 0xf98 |
} |
else if (currentState == ST_FrameMgr_TrackingFrame) |
{ |
WAIT_FOR_HREF_LOW(); |
CamIntAsm_acquireTrackingLine(currentLineBuffer,colorMap); |
} |
} |
378: 08 95 ret |
37a: 80 91 74 00 lds r24, 0x0074 |
37e: 81 30 cpi r24, 0x01 ; 1 |
380: 39 f4 brne .+14 ; 0x390 |
382: 84 99 sbic 0x10, 4 ; 16 |
384: fe cf rjmp .-4 ; 0x382 |
386: 60 e0 ldi r22, 0x00 ; 0 |
388: 73 e0 ldi r23, 0x03 ; 3 |
38a: 8c eb ldi r24, 0xBC ; 188 |
38c: 91 e0 ldi r25, 0x01 ; 1 |
38e: bd d5 rcall .+2938 ; 0xf0a |
390: 08 95 ret |
|
00000392 <FrameMgr_processLine>: |
|
/*********************************************************** |
Function Name: FrameMgr_processLine |
Function Description: This function is responsible for |
parsing the received image line and performing either |
connected region mapping (if in the Tracking state) or |
sending out the raw sampled data (if in the Dumping |
state). |
Inputs: none |
Outputs: none |
***********************************************************/ |
void FrameMgr_processLine(void) |
{ |
392: df 92 push r13 |
394: ef 92 push r14 |
396: ff 92 push r15 |
398: 0f 93 push r16 |
39a: 1f 93 push r17 |
39c: cf 93 push r28 |
39e: df 93 push r29 |
3a0: cd b7 in r28, 0x3d ; 61 |
3a2: de b7 in r29, 0x3e ; 62 |
3a4: 21 97 sbiw r28, 0x01 ; 1 |
3a6: 0f b6 in r0, 0x3f ; 63 |
3a8: f8 94 cli |
3aa: de bf out 0x3e, r29 ; 62 |
3ac: 0f be out 0x3f, r0 ; 63 |
3ae: cd bf out 0x3d, r28 ; 61 |
unsigned char i; |
volatile unsigned char dataToSend; |
unsigned char *pTrackedObjectData = (unsigned char *)pCurrentTrackedObjectTable; |
3b0: 00 91 60 00 lds r16, 0x0060 |
3b4: 10 91 61 00 lds r17, 0x0061 |
#ifdef DEBUG_TRACKED_LINE |
unsigned char *pSendData; |
unsigned char asciiBuffer[5]; |
unsigned char pixelCount = 0; |
#endif |
|
if (currentState == ST_FrameMgr_DumpingFrame) |
3b8: 80 91 74 00 lds r24, 0x0074 |
3bc: 82 30 cpi r24, 0x02 ; 2 |
3be: 09 f0 breq .+2 ; 0x3c2 |
3c0: 54 c0 rjmp .+168 ; 0x46a |
{ |
/* we want to sit in a tight loop and send the acquired data |
sitting in current and previous line buffers out the serial |
port...it is sent out the serial port immediately instead |
of going into the UIMgr tx fifo because we can't do anything |
until its sent out anyway...may as well just get it out now */ |
|
/* currentLineBuffer is getting "g" previousLineBuffer is getting "b-r" */ |
UartInt_txByte(0x0B); /* send the header byte */ |
3c2: 8b e0 ldi r24, 0x0B ; 11 |
3c4: cd d3 rcall .+1946 ; 0xb60 |
UartInt_txByte(lineCount); /* send the line count */ |
3c6: 80 91 73 00 lds r24, 0x0073 |
3ca: ca d3 rcall .+1940 ; 0xb60 |
for (i=0; i<NUM_PIXELS_IN_A_DUMP_LINE; i+=2) |
3cc: dd 24 eor r13, r13 |
{ |
/* when a dump line is sampled, the upper byte can potentially |
have garbage in it...we don't have time to mask it off as we're |
sampling, so it is done here before we send it out...we also |
combine the samples together so we really are sending up a |
sample for line N as well as line N+1 */ |
dataToSend = currentLineBuffer[i]; |
3ce: 2d 2d mov r18, r13 |
3d0: 33 27 eor r19, r19 |
3d2: 0f 2e mov r0, r31 |
3d4: fc eb ldi r31, 0xBC ; 188 |
3d6: ef 2e mov r14, r31 |
3d8: f1 e0 ldi r31, 0x01 ; 1 |
3da: ff 2e mov r15, r31 |
3dc: f0 2d mov r31, r0 |
3de: e2 0e add r14, r18 |
3e0: f3 1e adc r15, r19 |
3e2: f7 01 movw r30, r14 |
3e4: 80 81 ld r24, Z |
3e6: 89 83 std Y+1, r24 ; 0x01 |
dataToSend &= 0x0F; |
3e8: 89 81 ldd r24, Y+1 ; 0x01 |
3ea: 8f 70 andi r24, 0x0F ; 15 |
3ec: 89 83 std Y+1, r24 ; 0x01 |
dataToSend <<= 4; |
3ee: 89 81 ldd r24, Y+1 ; 0x01 |
3f0: 82 95 swap r24 |
3f2: 80 7f andi r24, 0xF0 ; 240 |
3f4: 89 83 std Y+1, r24 ; 0x01 |
dataToSend |= (previousLineBuffer[i] & 0x0F); |
3f6: 89 01 movw r16, r18 |
3f8: 04 5f subi r16, 0xF4 ; 244 |
3fa: 1e 4f sbci r17, 0xFE ; 254 |
3fc: f8 01 movw r30, r16 |
3fe: 80 81 ld r24, Z |
400: 98 2f mov r25, r24 |
402: 9f 70 andi r25, 0x0F ; 15 |
404: 89 81 ldd r24, Y+1 ; 0x01 |
406: 89 2b or r24, r25 |
408: 89 83 std Y+1, r24 ; 0x01 |
|
/* dataToSend should be packed now */ |
UartInt_txByte(dataToSend); |
40a: 89 81 ldd r24, Y+1 ; 0x01 |
40c: a9 d3 rcall .+1874 ; 0xb60 |
|
/* flip the colors around since we are doing all G on Y and BR on UV */ |
dataToSend = previousLineBuffer[i+1]; |
40e: f8 01 movw r30, r16 |
410: 81 81 ldd r24, Z+1 ; 0x01 |
412: 89 83 std Y+1, r24 ; 0x01 |
dataToSend &= 0x0F; |
414: 89 81 ldd r24, Y+1 ; 0x01 |
416: 8f 70 andi r24, 0x0F ; 15 |
418: 89 83 std Y+1, r24 ; 0x01 |
dataToSend <<= 4; |
41a: 89 81 ldd r24, Y+1 ; 0x01 |
41c: 82 95 swap r24 |
41e: 80 7f andi r24, 0xF0 ; 240 |
420: 89 83 std Y+1, r24 ; 0x01 |
dataToSend |= (currentLineBuffer[i+1] & 0x0F); |
422: f7 01 movw r30, r14 |
424: 81 81 ldd r24, Z+1 ; 0x01 |
426: 98 2f mov r25, r24 |
428: 9f 70 andi r25, 0x0F ; 15 |
42a: 89 81 ldd r24, Y+1 ; 0x01 |
42c: 89 2b or r24, r25 |
42e: 89 83 std Y+1, r24 ; 0x01 |
|
/* dataToSend should be packed now */ |
UartInt_txByte(dataToSend); |
430: 89 81 ldd r24, Y+1 ; 0x01 |
432: 96 d3 rcall .+1836 ; 0xb60 |
434: f2 e0 ldi r31, 0x02 ; 2 |
436: df 0e add r13, r31 |
438: 4f ea ldi r20, 0xAF ; 175 |
43a: 4d 15 cp r20, r13 |
43c: 40 f6 brcc .-112 ; 0x3ce |
} |
UartInt_txByte(0x0F); /* send line end */ |
43e: 8f e0 ldi r24, 0x0F ; 15 |
440: 8f d3 rcall .+1822 ; 0xb60 |
/* once all the data is sent, increment out line count by 2 since |
we really get 2 lines worth of pixels on each pass */ |
/* Update...increment only by 1, but only send 72 double-lines */ |
lineCount++; |
442: 80 91 73 00 lds r24, 0x0073 |
446: 8f 5f subi r24, 0xFF ; 255 |
448: 80 93 73 00 sts 0x0073, r24 |
|
/* check to see if we have retrieved all of the needed lines */ |
if (lineCount >= 72) /* half 144, since we send two lines at a time */ |
44c: 88 34 cpi r24, 0x48 ; 72 |
44e: 08 f4 brcc .+2 ; 0x452 |
450: 4a c0 rjmp .+148 ; 0x4e6 |
{ |
/* we're done, so send the dump complete?...nope, just change |
states and we should be fine */ |
lineCount = 0; |
452: 10 92 73 00 sts 0x0073, r1 |
currentState = ST_FrameMgr_idle; |
456: 10 92 74 00 sts 0x0074, r1 |
|
/* disable the PCLK counting overflow interrupt */ |
TIMSK &= DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK; |
45a: 89 b7 in r24, 0x39 ; 57 |
45c: 8b 7f andi r24, 0xFB ; 251 |
45e: 89 bf out 0x39, r24 ; 57 |
|
CamConfig_setCamReg(0x11,0x00); /* reset the frame rate to normal*/ |
460: 60 e0 ldi r22, 0x00 ; 0 |
462: 81 e1 ldi r24, 0x11 ; 17 |
464: 91 d4 rcall .+2338 ; 0xd88 |
CamConfig_sendFifoCmds(); |
466: 95 d4 rcall .+2346 ; 0xd92 |
468: 43 c0 rjmp .+134 ; 0x4f0 |
} |
else |
{ |
/* we have more lines to acquire in this frame, so keep on truckin...*/ |
PUBLISH_FAST_EVENT(FEV_PROCESS_LINE_COMPLETE); |
} |
} |
else if (currentState == ST_FrameMgr_TrackingFrame) |
46a: 80 91 74 00 lds r24, 0x0074 |
46e: 81 30 cpi r24, 0x01 ; 1 |
470: 09 f0 breq .+2 ; 0x474 |
472: 3e c0 rjmp .+124 ; 0x4f0 |
{ |
#ifdef DEBUG_TRACKED_LINE |
/* send the received line over serial...this should only send |
until a pixelCount == 176 */ |
pSendData = currentLineBuffer; |
itoa(trackedLineCount,asciiBuffer,10); |
UIMgr_txBuffer(asciiBuffer,3); |
UIMgr_txBuffer(" ",1); |
while(pixelCount < ACTUAL_NUM_PIXELS_IN_A_LINE) |
{ |
memset(asciiBuffer,0x00,5); |
itoa(*pSendData++,asciiBuffer,10); /* color is first byte */ |
UIMgr_txBuffer(asciiBuffer,3); /* 3 ascii bytes for data */ |
UIMgr_txBuffer(" ",1); |
|
pixelCount += *pSendData; /* run-length is second byte */ |
memset(asciiBuffer,0x00,5); |
itoa(*pSendData++,asciiBuffer,10); |
UIMgr_txBuffer(asciiBuffer,3); |
UIMgr_txBuffer(" ",1); |
} |
UIMgr_txBuffer("\n\r",2); |
|
trackedLineCount++; |
if (trackedLineCount == 144) |
{ |
UIMgr_txBuffer(" FC \n\r",8); |
trackedLineCount = 0; |
PUBLISH_EVENT(EV_PROCESS_FRAME_COMPLETE); |
} |
else |
{ |
PUBLISH_EVENT(EV_PROCESS_LINE_COMPLETE); |
} |
#else |
/* determine if any of the RLE blocks overlap */ |
FrameMgr_findConnectedness(); |
474: a1 d0 rcall .+322 ; 0x5b8 |
|
/* we also want to remove any objects that are less than |
a minimum height...we already removed portions of the |
run-length that are less than MIN_PIXEL_WIDTH in the |
findConnectedness() routine...doing it here instead of |
a function to speed things up...this may end up slowing down the |
frame rate slightly, and can be removed if this isn't needed */ |
|
/* run this routine once every 8 lines */ |
if ( (trackedLineCount & RUN_OBJECT_FILTER_MASK) == RUN_OBJECT_FILTER_MASK) |
476: 80 91 77 00 lds r24, 0x0077 |
47a: 99 27 eor r25, r25 |
47c: 87 70 andi r24, 0x07 ; 7 |
47e: 90 70 andi r25, 0x00 ; 0 |
480: 07 97 sbiw r24, 0x07 ; 7 |
482: 11 f5 brne .+68 ; 0x4c8 |
{ |
for (i=0; i<MAX_TRACKED_OBJECTS; i++) |
484: dd 24 eor r13, r13 |
{ |
if ( *(pTrackedObjectData + VALID_OBJECT_OFFSET) == TRUE) |
486: f8 01 movw r30, r16 |
488: 87 81 ldd r24, Z+7 ; 0x07 |
48a: 81 30 cpi r24, 0x01 ; 1 |
48c: b9 f4 brne .+46 ; 0x4bc |
{ |
/* check to see if the object is already in |
our past...i.e., its last */ |
if ( (*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) - |
48e: 86 81 ldd r24, Z+6 ; 0x06 |
490: 28 2f mov r18, r24 |
492: 33 27 eor r19, r19 |
494: 84 81 ldd r24, Z+4 ; 0x04 |
496: a9 01 movw r20, r18 |
498: 48 1b sub r20, r24 |
49a: 51 09 sbc r21, r1 |
49c: 43 30 cpi r20, 0x03 ; 3 |
49e: 51 05 cpc r21, r1 |
4a0: 6c f4 brge .+26 ; 0x4bc |
*(pTrackedObjectData + Y_UPPER_LEFT_OFFSET)) < MIN_OBJECT_TRACKING_HEIGHT) |
{ |
/* the object is less than the minimum height...see if it is adjacent |
to the current line we just processed...if so, leave it here...otherwise, |
it needs to be invalidated since its too small */ |
if ( trackedLineCount - *(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) > 2) |
4a2: 80 91 77 00 lds r24, 0x0077 |
4a6: 99 27 eor r25, r25 |
4a8: 82 1b sub r24, r18 |
4aa: 93 0b sbc r25, r19 |
4ac: 03 97 sbiw r24, 0x03 ; 3 |
4ae: 34 f0 brlt .+12 ; 0x4bc |
{ |
/* invalidate the object */ |
*(pTrackedObjectData + VALID_OBJECT_OFFSET) = FALSE; |
4b0: 17 82 std Z+7, r1 ; 0x07 |
numCurrTrackedObjects--; |
4b2: 80 91 75 00 lds r24, 0x0075 |
4b6: 81 50 subi r24, 0x01 ; 1 |
4b8: 80 93 75 00 sts 0x0075, r24 |
} |
} |
} |
pTrackedObjectData += SIZE_OF_TRACKED_OBJECT; |
4bc: 08 5f subi r16, 0xF8 ; 248 |
4be: 1f 4f sbci r17, 0xFF ; 255 |
4c0: d3 94 inc r13 |
4c2: 57 e0 ldi r21, 0x07 ; 7 |
4c4: 5d 15 cp r21, r13 |
4c6: f8 f6 brcc .-66 ; 0x486 |
} |
} |
|
trackedLineCount++; |
4c8: 80 91 77 00 lds r24, 0x0077 |
4cc: 8f 5f subi r24, 0xFF ; 255 |
4ce: 80 93 77 00 sts 0x0077, r24 |
if (trackedLineCount == ACTUAL_NUM_LINES_IN_A_FRAME) |
4d2: 80 39 cpi r24, 0x90 ; 144 |
4d4: 41 f4 brne .+16 ; 0x4e6 |
{ |
/* an entire frame of tracking data has been acquired, so |
publish an event letting the system know this fact */ |
PUBLISH_EVENT(EV_ACQUIRE_FRAME_COMPLETE); |
4d6: 80 e2 ldi r24, 0x20 ; 32 |
4d8: bc de rcall .-648 ; 0x252 |
/* disable the PCLK counting overflow interrupt */ |
TIMSK &= DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK; |
4da: 89 b7 in r24, 0x39 ; 57 |
4dc: 8b 7f andi r24, 0xFB ; 251 |
4de: 89 bf out 0x39, r24 ; 57 |
trackedLineCount = 0; |
4e0: 10 92 77 00 sts 0x0077, r1 |
4e4: 05 c0 rjmp .+10 ; 0x4f0 |
} |
else |
{ |
PUBLISH_FAST_EVENT(FEV_PROCESS_LINE_COMPLETE); |
4e6: 80 91 72 00 lds r24, 0x0072 |
4ea: 82 60 ori r24, 0x02 ; 2 |
4ec: 80 93 72 00 sts 0x0072, r24 |
} |
#endif |
} |
else |
{ |
/* ...and here? */ |
} |
} |
4f0: 21 96 adiw r28, 0x01 ; 1 |
4f2: 0f b6 in r0, 0x3f ; 63 |
4f4: f8 94 cli |
4f6: de bf out 0x3e, r29 ; 62 |
4f8: 0f be out 0x3f, r0 ; 63 |
4fa: cd bf out 0x3d, r28 ; 61 |
4fc: df 91 pop r29 |
4fe: cf 91 pop r28 |
500: 1f 91 pop r17 |
502: 0f 91 pop r16 |
504: ff 90 pop r15 |
506: ef 90 pop r14 |
508: df 90 pop r13 |
50a: 08 95 ret |
|
0000050c <FrameMgr_processFrame>: |
|
/*********************************************************** |
Function Name: FrameMgr_processFrame |
Function Description: This function is responsible for |
parsing the completed frame and performing all actions |
needed at this level. |
Inputs: none |
Outputs: none |
***********************************************************/ |
void FrameMgr_processFrame(void) |
{ |
50c: df 92 push r13 |
50e: ef 92 push r14 |
510: ff 92 push r15 |
512: 0f 93 push r16 |
514: 1f 93 push r17 |
516: cf 93 push r28 |
518: df 93 push r29 |
unsigned char i,k,color; |
#if DEBUG_FRAME_DATA |
unsigned char asciiBuffer[5]; |
unsigned char j; |
#endif |
unsigned char *pTableData = (unsigned char *)pCurrentTrackedObjectTable; |
unsigned char tmpUpperLeftX,tmpUpperLeftY,tmpLowerRightX,tmpLowerRightY; |
|
#if DEBUG_FRAME_DATA |
/* we want to send all of the currently tracked table out |
the serial port for debugging */ |
for (i=0; i<numCurrTrackedObjects; i++) |
{ |
UIMgr_txBuffer("----------\r\n",12); |
for (j=0; j<SIZE_OF_TRACKED_OBJECT; j++) |
{ |
memset(asciiBuffer,0x00,5); |
itoa(*pTableData++,asciiBuffer,10); |
UIMgr_txBuffer(asciiBuffer,3); /* 3 ascii bytes for data |
+ 1 space */ |
UIMgr_txBuffer("\r\n",2); |
} |
} |
|
/* finally, send a new line */ |
UIMgr_txBuffer("\r\n",2); |
|
memset(asciiBuffer,0x00,5); |
itoa(numCurrTrackedObjects,asciiBuffer,10); |
UIMgr_txBuffer(asciiBuffer,3); |
UIMgr_txBuffer(" PFC\r\n",5); |
|
#else |
/* we only send tracking packets if there are tracked objects */ |
|
if (numCurrTrackedObjects > 0) |
51a: 80 91 75 00 lds r24, 0x0075 |
51e: 88 23 and r24, r24 |
520: 09 f4 brne .+2 ; 0x524 |
522: 40 c0 rjmp .+128 ; 0x5a4 |
{ |
UIMgr_writeTxFifo(0x0A); /* header byte for a tracking packet */ |
524: 8a e0 ldi r24, 0x0A ; 10 |
526: 01 d3 rcall .+1538 ; 0xb2a |
/* reset the pointer */ |
pTableData = (unsigned char *)pCurrentTrackedObjectTable; |
528: c0 91 60 00 lds r28, 0x0060 |
52c: d0 91 61 00 lds r29, 0x0061 |
|
UIMgr_writeTxFifo(numCurrTrackedObjects); /* num of objects tracked */ |
530: 80 91 75 00 lds r24, 0x0075 |
534: fa d2 rcall .+1524 ; 0xb2a |
for (i=0; i<MAX_TRACKED_OBJECTS; i++) |
536: dd 24 eor r13, r13 |
{ |
/* we only want to process objects that have their objectValid flag |
set to TRUE */ |
if ( *(pTableData + VALID_OBJECT_OFFSET) == TRUE) |
538: 8f 81 ldd r24, Y+7 ; 0x07 |
53a: 81 30 cpi r24, 0x01 ; 1 |
53c: 61 f5 brne .+88 ; 0x596 |
{ |
/* the object is valid...convert the color from bit position to value...remember, |
each bit in the "color" byte corresponds to a color */ |
k=0; |
53e: 80 e0 ldi r24, 0x00 ; 0 |
color = *(pTableData + COLOR_OFFSET); |
540: 98 81 ld r25, Y |
if (color == 128) k=0; |
542: 90 38 cpi r25, 0x80 ; 128 |
544: d9 f0 breq .+54 ; 0x57c |
else if (color == 64) k=1; |
546: 90 34 cpi r25, 0x40 ; 64 |
548: 11 f4 brne .+4 ; 0x54e |
54a: 81 e0 ldi r24, 0x01 ; 1 |
54c: 17 c0 rjmp .+46 ; 0x57c |
else if (color == 32) k=2; |
54e: 90 32 cpi r25, 0x20 ; 32 |
550: 11 f4 brne .+4 ; 0x556 |
552: 82 e0 ldi r24, 0x02 ; 2 |
554: 13 c0 rjmp .+38 ; 0x57c |
else if (color == 16) k=3; |
556: 90 31 cpi r25, 0x10 ; 16 |
558: 11 f4 brne .+4 ; 0x55e |
55a: 83 e0 ldi r24, 0x03 ; 3 |
55c: 0f c0 rjmp .+30 ; 0x57c |
else if (color == 8) k=4; |
55e: 98 30 cpi r25, 0x08 ; 8 |
560: 11 f4 brne .+4 ; 0x566 |
562: 84 e0 ldi r24, 0x04 ; 4 |
564: 0b c0 rjmp .+22 ; 0x57c |
else if (color == 4) k=5; |
566: 94 30 cpi r25, 0x04 ; 4 |
568: 11 f4 brne .+4 ; 0x56e |
56a: 85 e0 ldi r24, 0x05 ; 5 |
56c: 07 c0 rjmp .+14 ; 0x57c |
else if (color == 2) k=6; |
56e: 92 30 cpi r25, 0x02 ; 2 |
570: 11 f4 brne .+4 ; 0x576 |
572: 86 e0 ldi r24, 0x06 ; 6 |
574: 03 c0 rjmp .+6 ; 0x57c |
else if (color == 1) k=7; |
576: 91 30 cpi r25, 0x01 ; 1 |
578: 09 f4 brne .+2 ; 0x57c |
57a: 87 e0 ldi r24, 0x07 ; 7 |
|
tmpUpperLeftX = *(pTableData + X_UPPER_LEFT_OFFSET); /* get the upper left X */ |
57c: 1b 81 ldd r17, Y+3 ; 0x03 |
tmpUpperLeftY = *(pTableData + Y_UPPER_LEFT_OFFSET); /* get the upper left Y */ |
57e: 0c 81 ldd r16, Y+4 ; 0x04 |
tmpLowerRightX = *(pTableData + X_LOWER_RIGHT_OFFSET); /* get the lower right X */ |
580: fd 80 ldd r15, Y+5 ; 0x05 |
tmpLowerRightY = *(pTableData + Y_LOWER_RIGHT_OFFSET); /* get the lower right Y */ |
582: ee 80 ldd r14, Y+6 ; 0x06 |
|
UIMgr_writeTxFifo(k); /* send the color first */ |
584: d2 d2 rcall .+1444 ; 0xb2a |
UIMgr_writeTxFifo(tmpUpperLeftX); |
586: 81 2f mov r24, r17 |
588: d0 d2 rcall .+1440 ; 0xb2a |
UIMgr_writeTxFifo(tmpUpperLeftY); |
58a: 80 2f mov r24, r16 |
58c: ce d2 rcall .+1436 ; 0xb2a |
UIMgr_writeTxFifo(tmpLowerRightX); |
58e: 8f 2d mov r24, r15 |
590: cc d2 rcall .+1432 ; 0xb2a |
UIMgr_writeTxFifo(tmpLowerRightY); |
592: 8e 2d mov r24, r14 |
594: ca d2 rcall .+1428 ; 0xb2a |
} |
|
/* move our pointer up to the beginning of the next object */ |
pTableData += SIZE_OF_TRACKED_OBJECT; |
596: 28 96 adiw r28, 0x08 ; 8 |
598: d3 94 inc r13 |
59a: 87 e0 ldi r24, 0x07 ; 7 |
59c: 8d 15 cp r24, r13 |
59e: 60 f6 brcc .-104 ; 0x538 |
} |
|
/* all done...send the end of tracking packets char */ |
UIMgr_writeTxFifo(0xFF); |
5a0: 8f ef ldi r24, 0xFF ; 255 |
5a2: c3 d2 rcall .+1414 ; 0xb2a |
} |
#endif |
|
/* the tracked object table will be cleared out right before we start |
to wait for VSYNC to indicate a new frame...so it doesn't need to be |
done now */ |
|
/* schedule the next action to acquire a new frame */ |
PUBLISH_EVENT(EV_PROCESS_FRAME_COMPLETE); |
5a4: 84 e0 ldi r24, 0x04 ; 4 |
5a6: 55 de rcall .-854 ; 0x252 |
} |
5a8: df 91 pop r29 |
5aa: cf 91 pop r28 |
5ac: 1f 91 pop r17 |
5ae: 0f 91 pop r16 |
5b0: ff 90 pop r15 |
5b2: ef 90 pop r14 |
5b4: df 90 pop r13 |
5b6: 08 95 ret |
|
000005b8 <FrameMgr_findConnectedness>: |
|
/*********************************************************** |
Function Name: FrameMgr_findConnectedness |
Function Description: This function is responsible for |
finding the connectedness between two particular run- |
length encoded lines of pixel data. It updates the |
trackingTable as needed. |
Inputs: none |
Outputs: none |
***********************************************************/ |
static void FrameMgr_findConnectedness(void) |
{ |
5b8: 1f 93 push r17 |
5ba: cf 93 push r28 |
trackedColor_t currColor; |
unsigned char *pCurrLineColorInfo = currentLineBuffer; |
5bc: ac eb ldi r26, 0xBC ; 188 |
5be: b1 e0 ldi r27, 0x01 ; 1 |
unsigned char *pTrackedObjectData; |
register unsigned char currPixelRunStart=0; |
5c0: 60 e0 ldi r22, 0x00 ; 0 |
register unsigned char currPixelRunFinish=0; |
5c2: c6 2f mov r28, r22 |
register unsigned char lastLineXStart=0; |
register unsigned char lastLineXFinish=0; |
register unsigned char runLength=1; |
5c4: 71 e0 ldi r23, 0x01 ; 1 |
unsigned char i; |
bool_t colorConnected; |
|
do |
{ |
/* grab both the current color and the number of pixels |
in the run...remember, pixels start at 1, not 0! */ |
colorConnected = FALSE; |
5c6: 10 e0 ldi r17, 0x00 ; 0 |
currColor = *pCurrLineColorInfo++; |
5c8: 5d 91 ld r21, X+ |
currPixelRunStart += runLength; |
5ca: c7 0f add r28, r23 |
runLength = *pCurrLineColorInfo++; |
5cc: 7d 91 ld r23, X+ |
currPixelRunFinish += runLength; |
5ce: 67 0f add r22, r23 |
|
/* make sure that the run-length is at least as wide as |
the minimum horizontal tracking width, and we care about the color */ |
|
if ( (currColor != notTracked) && (runLength > MIN_OBJECT_TRACKING_WIDTH) ) |
5d0: 55 23 and r21, r21 |
5d2: 09 f4 brne .+2 ; 0x5d6 |
5d4: 5d c0 rjmp .+186 ; 0x690 |
5d6: 74 30 cpi r23, 0x04 ; 4 |
5d8: 08 f4 brcc .+2 ; 0x5dc |
5da: 5a c0 rjmp .+180 ; 0x690 |
{ |
/* this run contains a color we care about, so |
either it will begin a new tracked object, or it |
is connected to a currently tracked object... |
compare it with each object in the tracking |
table...we can't just look at the numTrackedObjects because |
it is entirely possible that the first couple of objects could |
be invalid... |
|
NOTE: Instead of accessing each element in the trackedObjectTable |
through the 'i' index, and then accessing the fields in each structure, |
a pointer to each entry is established each time through the loop, followed |
by accessing the elements through specified offsets. GCC seems to be |
able to optimize this code much better than simply accessing the elements |
of each structure in the array the more normal way...*/ |
|
pTrackedObjectData = (unsigned char *)pCurrentTrackedObjectTable; |
5dc: e0 91 60 00 lds r30, 0x0060 |
5e0: f0 91 61 00 lds r31, 0x0061 |
for (i=0; i<MAX_TRACKED_OBJECTS; i++) |
5e4: 41 2f mov r20, r17 |
{ |
if ( (currColor == *(pTrackedObjectData + COLOR_OFFSET)) && |
5e6: 80 81 ld r24, Z |
5e8: 58 17 cp r21, r24 |
5ea: 51 f5 brne .+84 ; 0x640 |
5ec: 87 81 ldd r24, Z+7 ; 0x07 |
5ee: 81 30 cpi r24, 0x01 ; 1 |
5f0: 39 f5 brne .+78 ; 0x640 |
5f2: 86 81 ldd r24, Z+6 ; 0x06 |
5f4: 28 2f mov r18, r24 |
5f6: 33 27 eor r19, r19 |
5f8: 80 91 77 00 lds r24, 0x0077 |
5fc: 99 27 eor r25, r25 |
5fe: 01 97 sbiw r24, 0x01 ; 1 |
600: 28 17 cp r18, r24 |
602: 39 07 cpc r19, r25 |
604: e9 f4 brne .+58 ; 0x640 |
(*(pTrackedObjectData + VALID_OBJECT_OFFSET) == TRUE) && |
(*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) == trackedLineCount - 1) ) |
{ |
/* found a color match and the object is valid...check to see if there is |
connectedness */ |
lastLineXStart = *(pTrackedObjectData + LAST_LINE_X_START_OFFSET); |
606: 81 81 ldd r24, Z+1 ; 0x01 |
lastLineXFinish = *(pTrackedObjectData + LAST_LINE_X_FINISH_OFFSET); |
608: 92 81 ldd r25, Z+2 ; 0x02 |
|
/* Check for the 5 following types of line connectedness: |
--------------------- |
| | |
--------------------- |
------------------------- |
| | |
------------------------- */ |
if ( ( (currPixelRunStart >= lastLineXStart) && |
60a: c8 17 cp r28, r24 |
60c: 10 f0 brcs .+4 ; 0x612 |
60e: 9c 17 cp r25, r28 |
610: 40 f4 brcc .+16 ; 0x622 |
612: 68 17 cp r22, r24 |
614: 10 f0 brcs .+4 ; 0x61a |
616: 96 17 cp r25, r22 |
618: 20 f4 brcc .+8 ; 0x622 |
61a: 8c 17 cp r24, r28 |
61c: 88 f0 brcs .+34 ; 0x640 |
61e: 69 17 cp r22, r25 |
620: 78 f0 brcs .+30 ; 0x640 |
(currPixelRunStart <= lastLineXFinish) ) || |
|
/* --------------------- |
| | |
--------------------- |
------------------- |
| | |
------------------- |
OR |
------------------------------ |
| | |
------------------------------ |
--------- |
| | |
--------- */ |
( (currPixelRunFinish >= lastLineXStart) && |
(currPixelRunFinish <= lastLineXFinish) ) || |
|
|
/* ------------------------------- |
| | |
------------------------------- |
------------------------------- |
| | |
------------------------------- |
OR |
------------- |
| | |
------------- |
------------------------------- |
| | |
------------------------------- */ |
( (currPixelRunStart <= lastLineXStart) && |
(currPixelRunFinish >= lastLineXFinish) ) ) |
{ |
/* THERE IS CONNECTEDNESS...update the lastLineXStart and lastLineXFinish |
data pointed to by pTrackedObjectData */ |
*(pTrackedObjectData + LAST_LINE_X_START_OFFSET) = currPixelRunStart; |
622: c1 83 std Z+1, r28 ; 0x01 |
*(pTrackedObjectData + LAST_LINE_X_FINISH_OFFSET) = currPixelRunFinish; |
624: 62 83 std Z+2, r22 ; 0x02 |
|
/* check if the bounding box needs to be updated */ |
if (*(pTrackedObjectData + X_UPPER_LEFT_OFFSET) > currPixelRunStart) |
626: 83 81 ldd r24, Z+3 ; 0x03 |
628: c8 17 cp r28, r24 |
62a: 08 f4 brcc .+2 ; 0x62e |
{ |
/* need to update the bounding box for the upper left point to |
enclose this new left-most point...we never have to update the |
upper left Y point, since each scan line we process moves from |
top to bottom */ |
*(pTrackedObjectData + X_UPPER_LEFT_OFFSET) = currPixelRunStart; |
62c: c3 83 std Z+3, r28 ; 0x03 |
} |
|
if ( *(pTrackedObjectData + X_LOWER_RIGHT_OFFSET) < currPixelRunFinish) |
62e: 85 81 ldd r24, Z+5 ; 0x05 |
630: 86 17 cp r24, r22 |
632: 08 f4 brcc .+2 ; 0x636 |
{ |
/* need to update the bounding box for the lower right X point to |
enclose this new right-most point */ |
*(pTrackedObjectData + X_LOWER_RIGHT_OFFSET) = currPixelRunFinish; |
634: 65 83 std Z+5, r22 ; 0x05 |
} |
|
/* the lower right 'y' point always gets updated when connectedness is found */ |
*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) = trackedLineCount; |
636: 80 91 77 00 lds r24, 0x0077 |
63a: 86 83 std Z+6, r24 ; 0x06 |
|
/* set a flag indicating that that color run is part of another |
object and thus doesn't need to be added as a new entry into the |
tracking table */ |
colorConnected = TRUE; |
63c: 11 e0 ldi r17, 0x01 ; 1 |
break; |
63e: 04 c0 rjmp .+8 ; 0x648 |
} |
} |
|
/* go to the next object */ |
pTrackedObjectData += SIZE_OF_TRACKED_OBJECT; |
640: 38 96 adiw r30, 0x08 ; 8 |
642: 4f 5f subi r20, 0xFF ; 255 |
644: 48 30 cpi r20, 0x08 ; 8 |
646: 78 f2 brcs .-98 ; 0x5e6 |
} |
|
if (colorConnected == FALSE) |
648: 11 23 and r17, r17 |
64a: 11 f5 brne .+68 ; 0x690 |
{ |
/* a new entry needs to be made to the tracking table, since we have |
a run-length with a color, and it isn't connected to anything...but we |
can only do this if there is space left in the trackedObject table */ |
if (numCurrTrackedObjects < MAX_TRACKED_OBJECTS) |
64c: 80 91 75 00 lds r24, 0x0075 |
650: 88 30 cpi r24, 0x08 ; 8 |
652: f0 f4 brcc .+60 ; 0x690 |
{ |
/* space is available...add the object...but first we need to find an |
invalid object in the object tracking table */ |
pTrackedObjectData = (unsigned char *)pCurrentTrackedObjectTable; |
654: e0 91 60 00 lds r30, 0x0060 |
658: f0 91 61 00 lds r31, 0x0061 |
for (i=0; i<MAX_TRACKED_OBJECTS; i++) |
65c: 41 2f mov r20, r17 |
{ |
if ( *(pTrackedObjectData + VALID_OBJECT_OFFSET) == FALSE) break; |
65e: 87 81 ldd r24, Z+7 ; 0x07 |
660: 88 23 and r24, r24 |
662: 21 f0 breq .+8 ; 0x66c |
|
/* if we haven't broken above, then the object must have been valid... |
go ahead and move the pointer to the next object to check it */ |
pTrackedObjectData += SIZE_OF_TRACKED_OBJECT; |
664: 38 96 adiw r30, 0x08 ; 8 |
666: 4f 5f subi r20, 0xFF ; 255 |
668: 48 30 cpi r20, 0x08 ; 8 |
66a: c8 f3 brcs .-14 ; 0x65e |
} |
|
|
/* now that we have a pointer to the tracked object to be updated, update all |
the fields */ |
*(pTrackedObjectData + COLOR_OFFSET) = currColor; /* color */ |
66c: 50 83 st Z, r21 |
*(pTrackedObjectData + LAST_LINE_X_START_OFFSET) = currPixelRunStart; /* lastLineXStart */ |
66e: c1 83 std Z+1, r28 ; 0x01 |
*(pTrackedObjectData + LAST_LINE_X_FINISH_OFFSET) = currPixelRunFinish; /* lastLineXFinish */ |
670: 62 83 std Z+2, r22 ; 0x02 |
*(pTrackedObjectData + X_UPPER_LEFT_OFFSET) = currPixelRunStart; /* x_upperLeft */ |
672: c3 83 std Z+3, r28 ; 0x03 |
*(pTrackedObjectData + Y_UPPER_LEFT_OFFSET) = trackedLineCount; /* y_upperLeft */ |
674: 80 91 77 00 lds r24, 0x0077 |
678: 84 83 std Z+4, r24 ; 0x04 |
*(pTrackedObjectData + X_LOWER_RIGHT_OFFSET) = currPixelRunFinish; /* x_lowerRight */ |
67a: 65 83 std Z+5, r22 ; 0x05 |
*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) = trackedLineCount; /* y_lowerRight */ |
67c: 80 91 77 00 lds r24, 0x0077 |
680: 86 83 std Z+6, r24 ; 0x06 |
*(pTrackedObjectData + VALID_OBJECT_OFFSET) = TRUE; /* objectValid flag */ |
682: 81 e0 ldi r24, 0x01 ; 1 |
684: 87 83 std Z+7, r24 ; 0x07 |
|
numCurrTrackedObjects++; |
686: 80 91 75 00 lds r24, 0x0075 |
68a: 8f 5f subi r24, 0xFF ; 255 |
68c: 80 93 75 00 sts 0x0075, r24 |
} |
} |
|
/* move the pointer to the beginning of the next tracked object */ |
pTrackedObjectData += SIZE_OF_TRACKED_OBJECT; |
} |
} while(currPixelRunFinish < ACTUAL_NUM_PIXELS_IN_A_LINE); |
690: 60 3b cpi r22, 0xB0 ; 176 |
692: 08 f4 brcc .+2 ; 0x696 |
694: 98 cf rjmp .-208 ; 0x5c6 |
} |
696: cf 91 pop r28 |
698: 1f 91 pop r17 |
69a: 08 95 ret |
|
0000069c <UIMgr_init>: |
Outputs: none |
***********************************************************/ |
void UIMgr_init(void) |
{ |
memset(asciiTokenBuffer,0x00,MAX_TOKEN_LENGTH+1); |
69c: 10 92 bf 00 sts 0x00BF, r1 |
6a0: 10 92 c0 00 sts 0x00C0, r1 |
6a4: 10 92 c1 00 sts 0x00C1, r1 |
6a8: 10 92 c2 00 sts 0x00C2, r1 |
memset(tokenBuffer,0x00,MAX_TOKEN_COUNT); |
6ac: 80 e4 ldi r24, 0x40 ; 64 |
6ae: e3 ec ldi r30, 0xC3 ; 195 |
6b0: f0 e0 ldi r31, 0x00 ; 0 |
6b2: 11 92 st Z+, r1 |
6b4: 8a 95 dec r24 |
6b6: e9 f7 brne .-6 ; 0x6b2 |
memset(UIMgr_txFifo,0x00,UI_MGR_TX_FIFO_SIZE); |
6b8: 80 e4 ldi r24, 0x40 ; 64 |
6ba: e4 e9 ldi r30, 0x94 ; 148 |
6bc: f2 e0 ldi r31, 0x02 ; 2 |
6be: 11 92 st Z+, r1 |
6c0: 8a 95 dec r24 |
6c2: e9 f7 brne .-6 ; 0x6be |
memset(UIMgr_rxFifo,0x00,UI_MGR_RX_FIFO_SIZE); |
6c4: 80 e2 ldi r24, 0x20 ; 32 |
6c6: e4 e7 ldi r30, 0x74 ; 116 |
6c8: f2 e0 ldi r31, 0x02 ; 2 |
6ca: 11 92 st Z+, r1 |
6cc: 8a 95 dec r24 |
6ce: e9 f7 brne .-6 ; 0x6ca |
} |
6d0: 08 95 ret |
|
000006d2 <UIMgr_dispatchEvent>: |
|
/*********************************************************** |
Function Name: UIMgr_dispatchEvent |
Function Description: This function is responsible for |
processing events that pertain to the UIMgr. |
Inputs: event - the generated event |
Outputs: none |
***********************************************************/ |
void UIMgr_dispatchEvent(unsigned char event) |
{ |
switch(event) |
6d2: 99 27 eor r25, r25 |
6d4: 80 31 cpi r24, 0x10 ; 16 |
6d6: 91 05 cpc r25, r1 |
6d8: 51 f0 breq .+20 ; 0x6ee |
6da: 81 31 cpi r24, 0x11 ; 17 |
6dc: 91 05 cpc r25, r1 |
6de: 1c f4 brge .+6 ; 0x6e6 |
6e0: 01 97 sbiw r24, 0x01 ; 1 |
6e2: 39 f0 breq .+14 ; 0x6f2 |
{ |
case EV_ACQUIRE_LINE_COMPLETE: |
UIMgr_transmitPendingData(); |
break; |
|
case EV_SERIAL_DATA_RECEIVED: |
UIMgr_processReceivedData(); |
break; |
|
case EV_SERIAL_DATA_PENDING_TX: |
UIMgr_flushTxBuffer(); |
break; |
} |
} |
6e4: 08 95 ret |
6e6: 80 39 cpi r24, 0x90 ; 144 |
6e8: 91 05 cpc r25, r1 |
6ea: 29 f0 breq .+10 ; 0x6f6 |
6ec: 08 95 ret |
6ee: 06 d0 rcall .+12 ; 0x6fc |
6f0: 08 95 ret |
6f2: 0e d0 rcall .+28 ; 0x710 |
6f4: 08 95 ret |
6f6: e6 d1 rcall .+972 ; 0xac4 |
6f8: 08 95 ret |
6fa: 08 95 ret |
|
000006fc <UIMgr_transmitPendingData>: |
/*********************************************************** |
Function Name: UIMgr_transmitPendingData |
Function Description: This function is responsible for |
transmitting a single byte of data if data is waiting |
to be sent. Otherwise, if nothing is waiting, the |
function just returns. |
Inputs: none |
Outputs: none |
***********************************************************/ |
void UIMgr_transmitPendingData(void) |
{ |
if (IS_DATA_IN_TX_FIFO() == TRUE) |
6fc: 90 91 ba 00 lds r25, 0x00BA |
700: 80 91 bb 00 lds r24, 0x00BB |
704: 98 17 cp r25, r24 |
706: 11 f0 breq .+4 ; 0x70c |
{ |
/* data is waiting...send a single byte */ |
UartInt_txByte( UIMgr_readTxFifo() ); |
708: fe d1 rcall .+1020 ; 0xb06 |
70a: 2a d2 rcall .+1108 ; 0xb60 |
} |
} |
70c: 08 95 ret |
70e: 08 95 ret |
|
00000710 <UIMgr_processReceivedData>: |
/*********************************************************** |
Function Name: UIMgr_processReceivedData |
Function Description: This function is responsible for |
parsing any serial data waiting in the rx fifo |
Inputs: none |
Outputs: none |
***********************************************************/ |
void UIMgr_processReceivedData(void) |
{ |
710: cf 93 push r28 |
unsigned char tmpData = 0; |
|
/* still need to add a mechanism to handle token counts |
that are excessive!!! FIX ME!!! */ |
|
while(IS_DATA_IN_RX_FIFO() == TRUE) |
712: 90 91 b8 00 lds r25, 0x00B8 |
716: 80 91 b9 00 lds r24, 0x00B9 |
71a: 98 17 cp r25, r24 |
71c: 09 f4 brne .+2 ; 0x720 |
71e: 6f c0 rjmp .+222 ; 0x7fe |
720: c9 e0 ldi r28, 0x09 ; 9 |
{ |
tmpData = UIMgr_readRxFifo(); |
722: df d1 rcall .+958 ; 0xae2 |
724: 38 2f mov r19, r24 |
if (tmpData == '\r') |
726: 8d 30 cpi r24, 0x0D ; 13 |
728: 29 f5 brne .+74 ; 0x774 |
{ |
/* we have reached a token separator */ |
if (tokenCount == 0) |
72a: 80 91 be 00 lds r24, 0x00BE |
72e: 88 23 and r24, r24 |
730: 11 f4 brne .+4 ; 0x736 |
{ |
/* convert the command */ |
UIMgr_convertTokenToCmd(); |
732: 2c d1 rcall .+600 ; 0x98c |
734: 06 c0 rjmp .+12 ; 0x742 |
} |
else |
{ |
/* convert a value */ |
UIMgr_convertTokenToValue(); |
736: 02 d1 rcall .+516 ; 0x93c |
tokenCount++; |
738: 80 91 be 00 lds r24, 0x00BE |
73c: 8f 5f subi r24, 0xFF ; 255 |
73e: 80 93 be 00 sts 0x00BE, r24 |
} |
/* either way, it is time to try to process the received |
token list since we have reached the end of the cmd. */ |
Utility_delay(100); |
742: 84 e6 ldi r24, 0x64 ; 100 |
744: 90 e0 ldi r25, 0x00 ; 0 |
746: 7f d3 rcall .+1790 ; 0xe46 |
if (receivedCmd == invalidCmd || |
748: 80 91 62 00 lds r24, 0x0062 |
74c: 88 50 subi r24, 0x08 ; 8 |
74e: 82 30 cpi r24, 0x02 ; 2 |
750: 20 f4 brcc .+8 ; 0x75a |
receivedCmd == noCmd ) |
{ |
UIMgr_sendNck(); |
752: 84 d1 rcall .+776 ; 0xa5c |
PUBLISH_EVENT(EV_SERIAL_DATA_PENDING_TX); |
754: 80 e9 ldi r24, 0x90 ; 144 |
756: 7d dd rcall .-1286 ; 0x252 |
758: 04 c0 rjmp .+8 ; 0x762 |
} |
else |
{ |
UIMgr_sendAck(); |
75a: 77 d1 rcall .+750 ; 0xa4a |
/* publish the serial data pending event, so it |
will push the ACK out before we execute the cmd */ |
PUBLISH_EVENT(EV_SERIAL_DATA_PENDING_TX); |
75c: 80 e9 ldi r24, 0x90 ; 144 |
75e: 79 dd rcall .-1294 ; 0x252 |
UIMgr_executeCmd(); |
760: 51 d0 rcall .+162 ; 0x804 |
} |
|
/* reset any necessary data */ |
tokenCount = 0; |
762: 10 92 be 00 sts 0x00BE, r1 |
memset(tokenBuffer,0x00,MAX_TOKEN_COUNT); |
766: 80 e4 ldi r24, 0x40 ; 64 |
768: e3 ec ldi r30, 0xC3 ; 195 |
76a: f0 e0 ldi r31, 0x00 ; 0 |
76c: 11 92 st Z+, r1 |
76e: 8a 95 dec r24 |
770: e9 f7 brne .-6 ; 0x76c |
772: 3e c0 rjmp .+124 ; 0x7f0 |
} |
else if (tmpData == ' ') /* space char */ |
774: 80 32 cpi r24, 0x20 ; 32 |
776: d9 f4 brne .+54 ; 0x7ae |
{ |
/* the end of a token has been reached */ |
if (tokenCount == 0) |
778: 80 91 be 00 lds r24, 0x00BE |
77c: 88 23 and r24, r24 |
77e: 11 f4 brne .+4 ; 0x784 |
{ |
UIMgr_convertTokenToCmd(); |
780: 05 d1 rcall .+522 ; 0x98c |
tokenCount++; /* check this...why is this being incremented here??? This |
782: 0f c0 rjmp .+30 ; 0x7a2 |
means we have received a token, with tokenCount == 0, which means it is a |
command...why is this contributing to tokenCount? |
This might cause the set color map command to include too much data, since |
it sets the color map based on tokenCount...CHECK*/ |
} |
else |
{ |
/* check to see if this token is going to push |
us over the limit...if so, abort the transaction */ |
if (tokenCount+1 >= MAX_TOKEN_COUNT) |
784: 80 91 be 00 lds r24, 0x00BE |
788: 99 27 eor r25, r25 |
78a: 01 96 adiw r24, 0x01 ; 1 |
78c: 80 34 cpi r24, 0x40 ; 64 |
78e: 91 05 cpc r25, r1 |
790: 3c f0 brlt .+14 ; 0x7a0 |
{ |
/* we received too many tokens, and |
need to NCK this request, since its too |
large...reset everything...*/ |
charCount=0; |
792: 10 92 bc 00 sts 0x00BC, r1 |
charIndex=0; |
796: 10 92 bd 00 sts 0x00BD, r1 |
tokenCount=0; |
79a: 10 92 be 00 sts 0x00BE, r1 |
receivedCmd = invalidCmd; |
79e: 26 c0 rjmp .+76 ; 0x7ec |
} |
else |
{ |
/* tokenCount is still in range...*/ |
UIMgr_convertTokenToValue(); |
7a0: cd d0 rcall .+410 ; 0x93c |
tokenCount++; |
7a2: 80 91 be 00 lds r24, 0x00BE |
7a6: 8f 5f subi r24, 0xFF ; 255 |
7a8: 80 93 be 00 sts 0x00BE, r24 |
7ac: 21 c0 rjmp .+66 ; 0x7f0 |
} |
} |
} |
else if ( (tmpData >= 'A' && tmpData <= 'Z') || |
7ae: 81 54 subi r24, 0x41 ; 65 |
7b0: 8a 31 cpi r24, 0x1A ; 26 |
7b2: 18 f0 brcs .+6 ; 0x7ba |
7b4: 8f 5e subi r24, 0xEF ; 239 |
7b6: 8a 30 cpi r24, 0x0A ; 10 |
7b8: c8 f4 brcc .+50 ; 0x7ec |
(tmpData >= '0' && tmpData <= '9') ) |
{ |
/* a valid range of token was received */ |
asciiTokenBuffer[charIndex] = tmpData; |
7ba: 20 91 bd 00 lds r18, 0x00BD |
7be: 82 2f mov r24, r18 |
7c0: 99 27 eor r25, r25 |
7c2: fc 01 movw r30, r24 |
7c4: e1 54 subi r30, 0x41 ; 65 |
7c6: ff 4f sbci r31, 0xFF ; 255 |
7c8: 30 83 st Z, r19 |
charCount++; |
7ca: 80 91 bc 00 lds r24, 0x00BC |
7ce: 98 2f mov r25, r24 |
7d0: 9f 5f subi r25, 0xFF ; 255 |
7d2: 90 93 bc 00 sts 0x00BC, r25 |
charIndex++; |
7d6: 82 2f mov r24, r18 |
7d8: 8f 5f subi r24, 0xFF ; 255 |
7da: 80 93 bd 00 sts 0x00BD, r24 |
if (charCount > MAX_TOKEN_LENGTH) |
7de: 94 30 cpi r25, 0x04 ; 4 |
7e0: 38 f0 brcs .+14 ; 0x7f0 |
{ |
/* we have received a token that cannot be handled... |
set the received cmd to an invalid cmd, and wait |
for the \r to process it */ |
receivedCmd = invalidCmd; |
7e2: c0 93 62 00 sts 0x0062, r28 |
charIndex = 0; /* ...so we won't overwrite memory */ |
7e6: 10 92 bd 00 sts 0x00BD, r1 |
7ea: 02 c0 rjmp .+4 ; 0x7f0 |
} |
} |
else |
{ |
/* an invalid character was received */ |
receivedCmd = invalidCmd; |
7ec: c0 93 62 00 sts 0x0062, r28 |
7f0: 90 91 b8 00 lds r25, 0x00B8 |
7f4: 80 91 b9 00 lds r24, 0x00B9 |
7f8: 98 17 cp r25, r24 |
7fa: 09 f0 breq .+2 ; 0x7fe |
7fc: 92 cf rjmp .-220 ; 0x722 |
} |
} /* end while */ |
|
asm volatile("clt"::); /* clear out the T flag in case it wasn't |
7fe: e8 94 clt |
cleared already */ |
} |
800: cf 91 pop r28 |
802: 08 95 ret |
|
00000804 <UIMgr_executeCmd>: |
|
/*********************************************************** |
Function Name: UIMgr_executeCmd |
Function Description: This function is responsible for |
executing whatever cmd is stored in the receivedCmd |
object. |
Inputs: none |
Outputs: none |
***********************************************************/ |
static void UIMgr_executeCmd(void) |
{ |
804: df 92 push r13 |
806: ef 92 push r14 |
808: ff 92 push r15 |
80a: 0f 93 push r16 |
80c: 1f 93 push r17 |
80e: cf 93 push r28 |
810: df 93 push r29 |
unsigned char i,eepromData, num_writes=0; |
812: ee 24 eor r14, r14 |
unsigned char *pData; |
unsigned char eeprom_write_succeeded = FALSE; |
#if DEBUG_COLOR_MAP |
unsigned char asciiBuffer[5]; |
#endif |
|
if (receivedCmd == pingCmd) |
814: 80 91 62 00 lds r24, 0x0062 |
818: 81 30 cpi r24, 0x01 ; 1 |
81a: 09 f4 brne .+2 ; 0x81e |
81c: 87 c0 rjmp .+270 ; 0x92c |
{ |
} |
else if (receivedCmd == getVersionCmd) |
81e: 88 23 and r24, r24 |
820: 69 f4 brne .+26 ; 0x83c |
{ |
pData = AVRcamVersion; |
822: c3 e6 ldi r28, 0x63 ; 99 |
824: d0 e0 ldi r29, 0x00 ; 0 |
while(*pData != 0) |
826: 80 91 63 00 lds r24, 0x0063 |
82a: 88 23 and r24, r24 |
82c: 09 f4 brne .+2 ; 0x830 |
82e: 7e c0 rjmp .+252 ; 0x92c |
{ |
UIMgr_writeTxFifo(*pData++); |
830: 89 91 ld r24, Y+ |
832: 7b d1 rcall .+758 ; 0xb2a |
834: 88 81 ld r24, Y |
836: 88 23 and r24, r24 |
838: d9 f7 brne .-10 ; 0x830 |
83a: 78 c0 rjmp .+240 ; 0x92c |
} |
} |
else if (receivedCmd == resetCameraCmd) |
83c: 80 91 62 00 lds r24, 0x0062 |
840: 87 30 cpi r24, 0x07 ; 7 |
842: 11 f4 brne .+4 ; 0x848 |
{ |
CamInt_resetCam(); |
844: 8b dc rcall .-1770 ; 0x15c |
846: 72 c0 rjmp .+228 ; 0x92c |
} |
else if (receivedCmd == dumpFrameCmd) |
848: 80 91 62 00 lds r24, 0x0062 |
84c: 83 30 cpi r24, 0x03 ; 3 |
84e: 29 f4 brne .+10 ; 0x85a |
{ |
/* publish the event that will indicate that |
a request has come to dump a frame...this will |
be received by the FrameMgr, which will begin |
dumping the frame...a short delay is needed |
here to keep the Java demo app happy (sometimes |
it wouldn't be able to receive the serial data |
as quickly as AVRcam can provide it). */ |
Utility_delay(100); |
850: 84 e6 ldi r24, 0x64 ; 100 |
852: 90 e0 ldi r25, 0x00 ; 0 |
854: f8 d2 rcall .+1520 ; 0xe46 |
PUBLISH_EVENT(EV_DUMP_FRAME); |
856: 82 e0 ldi r24, 0x02 ; 2 |
858: 28 c0 rjmp .+80 ; 0x8aa |
} |
else if (receivedCmd == setCameraRegsCmd) |
85a: 80 91 62 00 lds r24, 0x0062 |
85e: 82 30 cpi r24, 0x02 ; 2 |
860: b1 f4 brne .+44 ; 0x88e |
{ |
/* we need to gather the tokens and |
build config cmds to be sent to the camera */ |
for (i=1; i<tokenCount; i+=2) /* starts at 1 since first token |
862: ff 24 eor r15, r15 |
864: f3 94 inc r15 |
866: 80 91 be 00 lds r24, 0x00BE |
86a: f8 16 cp r15, r24 |
86c: 70 f4 brcc .+28 ; 0x88a |
is the CR cmd */ |
{ |
CamConfig_setCamReg(tokenBuffer[i],tokenBuffer[i+1]); |
86e: 8f 2d mov r24, r15 |
870: 99 27 eor r25, r25 |
872: fc 01 movw r30, r24 |
874: ed 53 subi r30, 0x3D ; 61 |
876: ff 4f sbci r31, 0xFF ; 255 |
878: 61 81 ldd r22, Z+1 ; 0x01 |
87a: 80 81 ld r24, Z |
87c: 85 d2 rcall .+1290 ; 0xd88 |
87e: 82 e0 ldi r24, 0x02 ; 2 |
880: f8 0e add r15, r24 |
882: 80 91 be 00 lds r24, 0x00BE |
886: f8 16 cp r15, r24 |
888: 90 f3 brcs .-28 ; 0x86e |
} |
CamConfig_sendFifoCmds(); |
88a: 83 d2 rcall .+1286 ; 0xd92 |
88c: 4f c0 rjmp .+158 ; 0x92c |
} |
else if (receivedCmd == enableTrackingCmd) |
88e: 80 91 62 00 lds r24, 0x0062 |
892: 84 30 cpi r24, 0x04 ; 4 |
894: 29 f4 brne .+10 ; 0x8a0 |
{ |
/* publish the event...again with a short delay */ |
Utility_delay(100); |
896: 84 e6 ldi r24, 0x64 ; 100 |
898: 90 e0 ldi r25, 0x00 ; 0 |
89a: d5 d2 rcall .+1450 ; 0xe46 |
PUBLISH_EVENT(EV_ENABLE_TRACKING); |
89c: 80 e8 ldi r24, 0x80 ; 128 |
89e: 05 c0 rjmp .+10 ; 0x8aa |
} |
else if (receivedCmd == disableTrackingCmd) |
8a0: 80 91 62 00 lds r24, 0x0062 |
8a4: 85 30 cpi r24, 0x05 ; 5 |
8a6: 19 f4 brne .+6 ; 0x8ae |
{ |
PUBLISH_EVENT(EV_DISABLE_TRACKING); |
8a8: 81 e8 ldi r24, 0x81 ; 129 |
8aa: d3 dc rcall .-1626 ; 0x252 |
8ac: 3f c0 rjmp .+126 ; 0x92c |
} |
else if (receivedCmd == setColorMapCmd) |
8ae: 80 91 62 00 lds r24, 0x0062 |
8b2: 86 30 cpi r24, 0x06 ; 6 |
8b4: d9 f5 brne .+118 ; 0x92c |
{ |
/* copy the received tokens into the color map */ |
for (i=0; i<tokenCount; i++) |
8b6: ff 24 eor r15, r15 |
8b8: 80 91 be 00 lds r24, 0x00BE |
8bc: f8 16 cp r15, r24 |
8be: b0 f5 brcc .+108 ; 0x92c |
{ |
colorMap[i] = tokenBuffer[i+1]; |
8c0: 8f 2d mov r24, r15 |
8c2: 99 27 eor r25, r25 |
8c4: 8c 01 movw r16, r24 |
8c6: 00 50 subi r16, 0x00 ; 0 |
8c8: 1d 4f sbci r17, 0xFD ; 253 |
8ca: fc 01 movw r30, r24 |
8cc: ed 53 subi r30, 0x3D ; 61 |
8ce: ff 4f sbci r31, 0xFF ; 255 |
8d0: 21 81 ldd r18, Z+1 ; 0x01 |
8d2: f8 01 movw r30, r16 |
8d4: 20 83 st Z, r18 |
|
/* write each colorMap byte to EEPROM, but only those |
that changed...this will help reduce wear on the EEPROM */ |
eepromData = eeprom_read_byte( (unsigned char*)(i+1)); |
8d6: 01 96 adiw r24, 0x01 ; 1 |
8d8: b5 d3 rcall .+1898 ; 0x1044 |
8da: 98 2f mov r25, r24 |
if (eepromData != colorMap[i]) |
8dc: f8 01 movw r30, r16 |
8de: 80 81 ld r24, Z |
8e0: 98 17 cp r25, r24 |
8e2: f9 f0 breq .+62 ; 0x922 |
{ |
/* need to actually perform the write because the |
data in eeprom is different than the current colorMap */ |
eeprom_write_succeeded = FALSE; |
8e4: dd 24 eor r13, r13 |
while(eeprom_write_succeeded == FALSE && num_writes < MAX_EEPROM_WRITE_ATTEMPTS) |
8e6: f2 e0 ldi r31, 0x02 ; 2 |
8e8: fe 15 cp r31, r14 |
8ea: d0 f0 brcs .+52 ; 0x920 |
8ec: 8f 2d mov r24, r15 |
8ee: 99 27 eor r25, r25 |
8f0: 8c 01 movw r16, r24 |
8f2: 00 50 subi r16, 0x00 ; 0 |
8f4: 1d 4f sbci r17, 0xFD ; 253 |
8f6: ec 01 movw r28, r24 |
8f8: 21 96 adiw r28, 0x01 ; 1 |
{ |
eeprom_write_byte((unsigned char*)(i+1),colorMap[i]); |
8fa: f8 01 movw r30, r16 |
8fc: 60 81 ld r22, Z |
8fe: ce 01 movw r24, r28 |
900: ba d3 rcall .+1908 ; 0x1076 |
num_writes++; |
902: e3 94 inc r14 |
eepromData = eeprom_read_byte( (unsigned char*)(i+1)); |
904: ce 01 movw r24, r28 |
906: 9e d3 rcall .+1852 ; 0x1044 |
908: 98 2f mov r25, r24 |
if (eepromData == colorMap[i]) |
90a: f8 01 movw r30, r16 |
90c: 80 81 ld r24, Z |
90e: 98 17 cp r25, r24 |
910: 11 f4 brne .+4 ; 0x916 |
{ |
eeprom_write_succeeded = TRUE; |
912: dd 24 eor r13, r13 |
914: d3 94 inc r13 |
916: dd 20 and r13, r13 |
918: 19 f4 brne .+6 ; 0x920 |
91a: f2 e0 ldi r31, 0x02 ; 2 |
91c: fe 15 cp r31, r14 |
91e: 68 f7 brcc .-38 ; 0x8fa |
} |
} |
num_writes = 0; |
920: ee 24 eor r14, r14 |
922: f3 94 inc r15 |
924: 80 91 be 00 lds r24, 0x00BE |
928: f8 16 cp r15, r24 |
92a: 50 f2 brcs .-108 ; 0x8c0 |
} |
} |
|
#if DEBUG_COLOR_MAP |
/* for debugging...send out the entire color map */ |
UIMgr_txBuffer("\r\n",2); |
for (i=0; i<NUM_ELEMENTS_IN_COLOR_MAP; i++) |
{ |
memset(asciiBuffer,0x00,5); |
itoa(colorMap[i],asciiBuffer,10); |
UIMgr_txBuffer(asciiBuffer,3); |
UIMgr_txBuffer(" ",1); |
if (i==15 || i == 31) |
{ |
/* break up the output */ |
UIMgr_txBuffer("\r\n",2); |
} |
} |
#endif |
} |
} |
92c: df 91 pop r29 |
92e: cf 91 pop r28 |
930: 1f 91 pop r17 |
932: 0f 91 pop r16 |
934: ff 90 pop r15 |
936: ef 90 pop r14 |
938: df 90 pop r13 |
93a: 08 95 ret |
|
0000093c <UIMgr_convertTokenToValue>: |
|
/*********************************************************** |
Function Name: UIMgr_convertTokenToValue |
Function Description: This function is responsible for |
converting a received token to a hex value It will |
access the asciiTokenBuffer directly, and store the |
result in the appropriate token buffer. |
Inputs: none |
Outputs: none |
***********************************************************/ |
static void UIMgr_convertTokenToValue(void) |
{ |
unsigned int newValue; |
|
newValue = atoi(asciiTokenBuffer); |
93c: 8f eb ldi r24, 0xBF ; 191 |
93e: 90 e0 ldi r25, 0x00 ; 0 |
940: 55 d3 rcall .+1706 ; 0xfec |
942: ac 01 movw r20, r24 |
if (newValue > 255) |
944: 8f 3f cpi r24, 0xFF ; 255 |
946: 91 05 cpc r25, r1 |
948: 71 f0 breq .+28 ; 0x966 |
94a: 68 f0 brcs .+26 ; 0x966 |
{ |
/* the value is too large */ |
receivedCmd = invalidCmd; |
94c: 89 e0 ldi r24, 0x09 ; 9 |
94e: 80 93 62 00 sts 0x0062, r24 |
tokenBuffer[tokenCount] = 0xFF; /* to indicate an error */ |
952: 20 91 be 00 lds r18, 0x00BE |
956: 83 ec ldi r24, 0xC3 ; 195 |
958: 90 e0 ldi r25, 0x00 ; 0 |
95a: fc 01 movw r30, r24 |
95c: e2 0f add r30, r18 |
95e: f1 1d adc r31, r1 |
960: 8f ef ldi r24, 0xFF ; 255 |
962: 80 83 st Z, r24 |
964: 08 c0 rjmp .+16 ; 0x976 |
} |
else |
{ |
/* copy the value into the tokenBuffer */ |
tokenBuffer[tokenCount] = newValue; |
966: 80 91 be 00 lds r24, 0x00BE |
96a: 23 ec ldi r18, 0xC3 ; 195 |
96c: 30 e0 ldi r19, 0x00 ; 0 |
96e: f9 01 movw r30, r18 |
970: e8 0f add r30, r24 |
972: f1 1d adc r31, r1 |
974: 40 83 st Z, r20 |
} |
memset(asciiTokenBuffer,0x00,MAX_TOKEN_LENGTH); |
976: 83 e0 ldi r24, 0x03 ; 3 |
978: ef eb ldi r30, 0xBF ; 191 |
97a: f0 e0 ldi r31, 0x00 ; 0 |
97c: 11 92 st Z+, r1 |
97e: 8a 95 dec r24 |
980: e9 f7 brne .-6 ; 0x97c |
charIndex = 0; |
982: 10 92 bd 00 sts 0x00BD, r1 |
charCount = 0; |
986: 10 92 bc 00 sts 0x00BC, r1 |
} |
98a: 08 95 ret |
|
0000098c <UIMgr_convertTokenToCmd>: |
/*********************************************************** |
Function Name: UIMgr_convertTokenToCmd |
Function Description: This function is responsible for |
parsing a received 2-character command. It will |
access the asciiTokenBuffer directly. |
Inputs: none |
Outputs: none |
***********************************************************/ |
static void UIMgr_convertTokenToCmd(void) |
{ |
if ( (asciiTokenBuffer[0] == 'P') && |
98c: 80 91 bf 00 lds r24, 0x00BF |
990: 80 35 cpi r24, 0x50 ; 80 |
992: 31 f4 brne .+12 ; 0x9a0 |
994: 80 91 c0 00 lds r24, 0x00C0 |
998: 87 34 cpi r24, 0x47 ; 71 |
99a: 11 f4 brne .+4 ; 0x9a0 |
(asciiTokenBuffer[1] == 'G') ) |
{ |
/* we got a "ping" command...but we still need to see |
if we are going to get the \r */ |
receivedCmd = pingCmd; |
99c: 81 e0 ldi r24, 0x01 ; 1 |
99e: 48 c0 rjmp .+144 ; 0xa30 |
} |
else if ( (asciiTokenBuffer[0] == 'G') && |
9a0: 80 91 bf 00 lds r24, 0x00BF |
9a4: 87 34 cpi r24, 0x47 ; 71 |
9a6: 39 f4 brne .+14 ; 0x9b6 |
9a8: 80 91 c0 00 lds r24, 0x00C0 |
9ac: 86 35 cpi r24, 0x56 ; 86 |
9ae: 19 f4 brne .+6 ; 0x9b6 |
(asciiTokenBuffer[1] == 'V') ) |
{ |
/* we got the "get version" command */ |
receivedCmd = getVersionCmd; |
9b0: 10 92 62 00 sts 0x0062, r1 |
9b4: 3f c0 rjmp .+126 ; 0xa34 |
} |
else if ( (asciiTokenBuffer[0] == 'D') && |
9b6: 80 91 bf 00 lds r24, 0x00BF |
9ba: 84 34 cpi r24, 0x44 ; 68 |
9bc: 31 f4 brne .+12 ; 0x9ca |
9be: 80 91 c0 00 lds r24, 0x00C0 |
9c2: 86 34 cpi r24, 0x46 ; 70 |
9c4: 11 f4 brne .+4 ; 0x9ca |
(asciiTokenBuffer[1] == 'F') ) |
{ |
/* we should go into frame dump mode */ |
receivedCmd = dumpFrameCmd; |
9c6: 83 e0 ldi r24, 0x03 ; 3 |
9c8: 33 c0 rjmp .+102 ; 0xa30 |
} |
else if ( (asciiTokenBuffer[0] == 'C') && |
9ca: 80 91 bf 00 lds r24, 0x00BF |
9ce: 83 34 cpi r24, 0x43 ; 67 |
9d0: 31 f4 brne .+12 ; 0x9de |
9d2: 80 91 c0 00 lds r24, 0x00C0 |
9d6: 82 35 cpi r24, 0x52 ; 82 |
9d8: 11 f4 brne .+4 ; 0x9de |
(asciiTokenBuffer[1] == 'R') ) |
{ |
/* the user wants to set registers in the OV6620 */ |
receivedCmd = setCameraRegsCmd; |
9da: 82 e0 ldi r24, 0x02 ; 2 |
9dc: 29 c0 rjmp .+82 ; 0xa30 |
} |
else if ( (asciiTokenBuffer[0] == 'E') && |
9de: 80 91 bf 00 lds r24, 0x00BF |
9e2: 85 34 cpi r24, 0x45 ; 69 |
9e4: 31 f4 brne .+12 ; 0x9f2 |
9e6: 80 91 c0 00 lds r24, 0x00C0 |
9ea: 84 35 cpi r24, 0x54 ; 84 |
9ec: 11 f4 brne .+4 ; 0x9f2 |
(asciiTokenBuffer[1] == 'T') ) |
{ |
/* the user wants to enable tracking */ |
receivedCmd = enableTrackingCmd; |
9ee: 84 e0 ldi r24, 0x04 ; 4 |
9f0: 1f c0 rjmp .+62 ; 0xa30 |
} |
else if ( (asciiTokenBuffer[0] == 'S') && |
9f2: 80 91 bf 00 lds r24, 0x00BF |
9f6: 83 35 cpi r24, 0x53 ; 83 |
9f8: 31 f4 brne .+12 ; 0xa06 |
9fa: 80 91 c0 00 lds r24, 0x00C0 |
9fe: 8d 34 cpi r24, 0x4D ; 77 |
a00: 11 f4 brne .+4 ; 0xa06 |
(asciiTokenBuffer[1] == 'M') ) |
{ |
/* the user wants to set the color map */ |
receivedCmd = setColorMapCmd; |
a02: 86 e0 ldi r24, 0x06 ; 6 |
a04: 15 c0 rjmp .+42 ; 0xa30 |
} |
else if ( (asciiTokenBuffer[0] == 'D') && |
a06: 80 91 bf 00 lds r24, 0x00BF |
a0a: 84 34 cpi r24, 0x44 ; 68 |
a0c: 31 f4 brne .+12 ; 0xa1a |
a0e: 80 91 c0 00 lds r24, 0x00C0 |
a12: 84 35 cpi r24, 0x54 ; 84 |
a14: 11 f4 brne .+4 ; 0xa1a |
(asciiTokenBuffer[1] == 'T') ) |
{ |
receivedCmd = disableTrackingCmd; |
a16: 85 e0 ldi r24, 0x05 ; 5 |
a18: 0b c0 rjmp .+22 ; 0xa30 |
} |
else if ( (asciiTokenBuffer[0] == 'R') && |
a1a: 80 91 bf 00 lds r24, 0x00BF |
a1e: 82 35 cpi r24, 0x52 ; 82 |
a20: 31 f4 brne .+12 ; 0xa2e |
a22: 80 91 c0 00 lds r24, 0x00C0 |
a26: 83 35 cpi r24, 0x53 ; 83 |
a28: 11 f4 brne .+4 ; 0xa2e |
(asciiTokenBuffer[1] == 'S') ) |
{ |
receivedCmd = resetCameraCmd; |
a2a: 87 e0 ldi r24, 0x07 ; 7 |
a2c: 01 c0 rjmp .+2 ; 0xa30 |
} |
else |
{ |
/* don't recognize the cmd */ |
receivedCmd = invalidCmd; |
a2e: 89 e0 ldi r24, 0x09 ; 9 |
a30: 80 93 62 00 sts 0x0062, r24 |
} |
memset(asciiTokenBuffer,0x00,MAX_TOKEN_LENGTH); |
a34: 83 e0 ldi r24, 0x03 ; 3 |
a36: ef eb ldi r30, 0xBF ; 191 |
a38: f0 e0 ldi r31, 0x00 ; 0 |
a3a: 11 92 st Z+, r1 |
a3c: 8a 95 dec r24 |
a3e: e9 f7 brne .-6 ; 0xa3a |
charIndex = 0; |
a40: 10 92 bd 00 sts 0x00BD, r1 |
charCount = 0; |
a44: 10 92 bc 00 sts 0x00BC, r1 |
} |
a48: 08 95 ret |
|
00000a4a <UIMgr_sendAck>: |
/*********************************************************** |
Function Name: UIMgr_sendAck |
Function Description: This function is responsible for |
queuing up an ACK to be sent to the user. |
Inputs: none |
Outputs: none |
***********************************************************/ |
static void UIMgr_sendAck(void) |
{ |
UIMgr_writeTxFifo('A'); |
a4a: 81 e4 ldi r24, 0x41 ; 65 |
a4c: 6e d0 rcall .+220 ; 0xb2a |
UIMgr_writeTxFifo('C'); |
a4e: 83 e4 ldi r24, 0x43 ; 67 |
a50: 6c d0 rcall .+216 ; 0xb2a |
UIMgr_writeTxFifo('K'); |
a52: 8b e4 ldi r24, 0x4B ; 75 |
a54: 6a d0 rcall .+212 ; 0xb2a |
UIMgr_writeTxFifo('\r'); |
a56: 8d e0 ldi r24, 0x0D ; 13 |
a58: 68 d0 rcall .+208 ; 0xb2a |
} |
a5a: 08 95 ret |
|
00000a5c <UIMgr_sendNck>: |
|
/*********************************************************** |
Function Name: UIMgr_sendNck |
Function Description: This function is responsible for |
queueing up an NCK to be sent to the user. |
Inputs: none |
Outputs: none |
***********************************************************/ |
static void UIMgr_sendNck(void) |
{ |
UIMgr_writeTxFifo('N'); |
a5c: 8e e4 ldi r24, 0x4E ; 78 |
a5e: 65 d0 rcall .+202 ; 0xb2a |
UIMgr_writeTxFifo('C'); |
a60: 83 e4 ldi r24, 0x43 ; 67 |
a62: 63 d0 rcall .+198 ; 0xb2a |
UIMgr_writeTxFifo('K'); |
a64: 8b e4 ldi r24, 0x4B ; 75 |
a66: 61 d0 rcall .+194 ; 0xb2a |
UIMgr_writeTxFifo('\r'); |
a68: 8d e0 ldi r24, 0x0D ; 13 |
a6a: 5f d0 rcall .+190 ; 0xb2a |
} |
a6c: 08 95 ret |
|
00000a6e <UIMgr_writeBufferToTxFifo>: |
|
|
/*********************************************************** |
Function Name: UIMgr_writeBufferToTxFifo |
Function Description: This function is responsible for |
placing "length" bytes into the tx FIFO. |
Inputs: pData - a pointer to the data to send |
length - the number of bytes to send |
Outputs: none |
***********************************************************/ |
void UIMgr_writeBufferToTxFifo(unsigned char *pData, unsigned char length) |
{ |
a6e: dc 01 movw r26, r24 |
unsigned char tmpHead; |
if (length == 0) |
a70: 66 23 and r22, r22 |
a72: a9 f0 breq .+42 ; 0xa9e |
{ |
return; |
} |
|
DISABLE_INTS(); |
a74: f8 94 cli |
while(length-- != 0) |
a76: 61 50 subi r22, 0x01 ; 1 |
a78: 6f 3f cpi r22, 0xFF ; 255 |
a7a: 81 f0 breq .+32 ; 0xa9c |
a7c: 24 e9 ldi r18, 0x94 ; 148 |
a7e: 32 e0 ldi r19, 0x02 ; 2 |
{ |
UIMgr_txFifo[UIMgr_txFifoHead] = *pData++; |
a80: 90 91 ba 00 lds r25, 0x00BA |
a84: f9 01 movw r30, r18 |
a86: e9 0f add r30, r25 |
a88: f1 1d adc r31, r1 |
a8a: 8d 91 ld r24, X+ |
a8c: 80 83 st Z, r24 |
|
/* now move the head up */ |
tmpHead = (UIMgr_txFifoHead + 1) & (UI_MGR_TX_FIFO_MASK); |
a8e: 89 2f mov r24, r25 |
a90: 8f 5f subi r24, 0xFF ; 255 |
a92: 8f 73 andi r24, 0x3F ; 63 |
UIMgr_txFifoHead = tmpHead; |
a94: 80 93 ba 00 sts 0x00BA, r24 |
a98: 61 50 subi r22, 0x01 ; 1 |
a9a: 90 f7 brcc .-28 ; 0xa80 |
} |
ENABLE_INTS(); |
a9c: 78 94 sei |
} |
a9e: 08 95 ret |
|
00000aa0 <UIMgr_txBuffer>: |
|
/*********************************************************** |
Function Name: UIMgr_txBuffer |
Function Description: This function is responsible for |
sending 'length' bytes out using the UartInterface |
module. |
Inputs: pData - a pointer to the data to send |
length - the number of bytes to send |
Outputs: none |
***********************************************************/ |
void UIMgr_txBuffer(unsigned char *pData, unsigned char length) |
{ |
aa0: 0f 93 push r16 |
aa2: 1f 93 push r17 |
aa4: cf 93 push r28 |
aa6: 8c 01 movw r16, r24 |
aa8: c6 2f mov r28, r22 |
while(length-- != 0) |
aaa: c1 50 subi r28, 0x01 ; 1 |
aac: cf 3f cpi r28, 0xFF ; 255 |
aae: 31 f0 breq .+12 ; 0xabc |
{ |
UartInt_txByte(*pData++); |
ab0: f8 01 movw r30, r16 |
ab2: 81 91 ld r24, Z+ |
ab4: 8f 01 movw r16, r30 |
ab6: 54 d0 rcall .+168 ; 0xb60 |
ab8: c1 50 subi r28, 0x01 ; 1 |
aba: d0 f7 brcc .-12 ; 0xab0 |
} |
} |
abc: cf 91 pop r28 |
abe: 1f 91 pop r17 |
ac0: 0f 91 pop r16 |
ac2: 08 95 ret |
|
00000ac4 <UIMgr_flushTxBuffer>: |
|
/*********************************************************** |
Function Name: UIMgr_flushTxBuffer |
Function Description: This function is responsible for |
sending all data currently in the serial tx buffer |
to the user. |
Inputs: none |
Outputs: none |
***********************************************************/ |
void UIMgr_flushTxBuffer(void) |
{ |
while(IS_DATA_IN_TX_FIFO() == TRUE) |
ac4: 90 91 ba 00 lds r25, 0x00BA |
ac8: 80 91 bb 00 lds r24, 0x00BB |
acc: 98 17 cp r25, r24 |
ace: 41 f0 breq .+16 ; 0xae0 |
{ |
UartInt_txByte(UIMgr_readTxFifo() ); |
ad0: 1a d0 rcall .+52 ; 0xb06 |
ad2: 46 d0 rcall .+140 ; 0xb60 |
ad4: 90 91 ba 00 lds r25, 0x00BA |
ad8: 80 91 bb 00 lds r24, 0x00BB |
adc: 98 17 cp r25, r24 |
ade: c1 f7 brne .-16 ; 0xad0 |
} |
} |
ae0: 08 95 ret |
|
00000ae2 <UIMgr_readRxFifo>: |
|
/*********************************************************** |
Function Name: UIMgr_readRxFifo |
Function Description: This function is responsible for |
reading a single byte of data from the rx fifo, and |
updating the appropriate pointers. |
Inputs: none |
Outputs: unsigned char-the data read |
***********************************************************/ |
static unsigned char UIMgr_readRxFifo(void) |
{ |
unsigned char dataByte, tmpTail; |
|
/* just return the current tail from the rx fifo */ |
DISABLE_INTS(); |
ae2: f8 94 cli |
dataByte = UIMgr_rxFifo[UIMgr_rxFifoTail]; |
ae4: 20 91 b9 00 lds r18, 0x00B9 |
ae8: 84 e7 ldi r24, 0x74 ; 116 |
aea: 92 e0 ldi r25, 0x02 ; 2 |
aec: fc 01 movw r30, r24 |
aee: e2 0f add r30, r18 |
af0: f1 1d adc r31, r1 |
af2: 90 81 ld r25, Z |
tmpTail = (UIMgr_rxFifoTail+1) & (UI_MGR_RX_FIFO_MASK); |
af4: 82 2f mov r24, r18 |
af6: 8f 5f subi r24, 0xFF ; 255 |
af8: 8f 71 andi r24, 0x1F ; 31 |
UIMgr_rxFifoTail = tmpTail; |
afa: 80 93 b9 00 sts 0x00B9, r24 |
ENABLE_INTS(); |
afe: 78 94 sei |
|
return(dataByte); |
b00: 89 2f mov r24, r25 |
b02: 99 27 eor r25, r25 |
} |
b04: 08 95 ret |
|
00000b06 <UIMgr_readTxFifo>: |
|
/*********************************************************** |
Function Name: UIMgr_readTxFifo |
Function Description: This function is responsible for |
reading a single byte of data from the tx fifo, and |
updating the appropriate pointers. |
Inputs: none |
Outputs: unsigned char-the data read |
***********************************************************/ |
static unsigned char UIMgr_readTxFifo(void) |
{ |
unsigned char dataByte, tmpTail; |
|
/* just return the current tail from the tx fifo */ |
DISABLE_INTS(); |
b06: f8 94 cli |
dataByte = UIMgr_txFifo[UIMgr_txFifoTail]; |
b08: 20 91 bb 00 lds r18, 0x00BB |
b0c: 84 e9 ldi r24, 0x94 ; 148 |
b0e: 92 e0 ldi r25, 0x02 ; 2 |
b10: fc 01 movw r30, r24 |
b12: e2 0f add r30, r18 |
b14: f1 1d adc r31, r1 |
b16: 90 81 ld r25, Z |
tmpTail = (UIMgr_txFifoTail+1) & (UI_MGR_TX_FIFO_MASK); |
b18: 82 2f mov r24, r18 |
b1a: 8f 5f subi r24, 0xFF ; 255 |
b1c: 8f 73 andi r24, 0x3F ; 63 |
UIMgr_txFifoTail = tmpTail; |
b1e: 80 93 bb 00 sts 0x00BB, r24 |
ENABLE_INTS(); |
b22: 78 94 sei |
|
return(dataByte); |
b24: 89 2f mov r24, r25 |
b26: 99 27 eor r25, r25 |
} |
b28: 08 95 ret |
|
00000b2a <UIMgr_writeTxFifo>: |
|
/*********************************************************** |
Function Name: UIMgr_writeTxFifo |
Function Description: This function is responsible for |
writing a single byte to the TxFifo and |
updating the appropriate pointers. |
Inputs: data - the byte to write to the Fifo |
Outputs: none |
***********************************************************/ |
void UIMgr_writeTxFifo(unsigned char data) |
{ |
b2a: 38 2f mov r19, r24 |
unsigned char tmpHead; |
|
DISABLE_INTS(); |
b2c: f8 94 cli |
UIMgr_txFifo[UIMgr_txFifoHead] = data; |
b2e: 20 91 ba 00 lds r18, 0x00BA |
b32: 84 e9 ldi r24, 0x94 ; 148 |
b34: 92 e0 ldi r25, 0x02 ; 2 |
b36: fc 01 movw r30, r24 |
b38: e2 0f add r30, r18 |
b3a: f1 1d adc r31, r1 |
b3c: 30 83 st Z, r19 |
|
/* now move the head up */ |
tmpHead = (UIMgr_txFifoHead + 1) & (UI_MGR_TX_FIFO_MASK); |
b3e: 82 2f mov r24, r18 |
b40: 8f 5f subi r24, 0xFF ; 255 |
b42: 8f 73 andi r24, 0x3F ; 63 |
UIMgr_txFifoHead = tmpHead; |
b44: 80 93 ba 00 sts 0x00BA, r24 |
ENABLE_INTS(); |
b48: 78 94 sei |
|
} |
b4a: 08 95 ret |
|
00000b4c <UartInt_init>: |
void UartInt_init(void) |
{ |
/* set up the baud rate registers so the UART will operate |
at 115.2 Kbps */ |
UBRRH = 0x00; |
b4c: 10 bc out 0x20, r1 ; 32 |
|
#ifdef NO_CRYSTAL |
UBRRL = 18; /* 18 for double clocking at 115.2 kbps */ |
b4e: 82 e1 ldi r24, 0x12 ; 18 |
b50: 89 b9 out 0x09, r24 ; 9 |
#else |
UBRRL = 0x08; /* for 16 MHz crystal at 115.2 kbps */ |
#endif |
|
/* enable the tx and rx capabilities of the UART...as well |
as the receive complete interrupt */ |
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN); |
b52: 88 e9 ldi r24, 0x98 ; 152 |
b54: 8a b9 out 0x0a, r24 ; 10 |
|
/* set up the control registers so the UART works at 8N1 */ |
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); |
b56: 86 e8 ldi r24, 0x86 ; 134 |
b58: 80 bd out 0x20, r24 ; 32 |
|
#ifdef NO_CRYSTAL |
/* set the baud rate to use the double-speed */ |
UCSRA = (1<<U2X); |
b5a: 82 e0 ldi r24, 0x02 ; 2 |
b5c: 8b b9 out 0x0b, r24 ; 11 |
#endif |
|
} |
b5e: 08 95 ret |
|
00000b60 <UartInt_txByte>: |
|
/*********************************************************** |
Function Name: UartInt_txByte |
Function Description: This function is responsible for |
transmitting a single byte on the uart. |
Inputs: txByte - the byte to send |
Outputs: none |
NOTES: When the TX UDRE (data register empty) is set, there |
is puposefully no interrupt...thus, to send a string of |
data out, the calling routine needs to hold up the entire |
application while this takes place (or just send one |
byte at a time at strtegically timed intervals, like |
the stats data is sent out :-) |
***********************************************************/ |
void UartInt_txByte(unsigned char txByte) |
{ |
/* Wait for empty transmit buffer */ |
while ( !( UCSRA & (1<<UDRE)) ); |
b60: 5d 9b sbis 0x0b, 5 ; 11 |
b62: fe cf rjmp .-4 ; 0xb60 |
/* Put data into buffer, sends the data */ |
UDR = txByte; |
b64: 8c b9 out 0x0c, r24 ; 12 |
} |
b66: 08 95 ret |
|
00000b68 <__vector_11>: |
|
/*********************************************************** |
Function Name: SIG_UART_RECV ISR |
Function Description: This function is responsible for |
handling the interrupt caused when a data byte is |
received by the UART. |
Inputs: none |
Outputs: none |
NOTES: This function was originally written in assembly, |
but moved over to C when the setting of the "T" bit at |
the end of the routine was no longer necessary (this |
theoretically allowed the AVRcam to respond to serial |
bytes in the middle of tracking or dumping a frame. |
But it wasn't really needed, and understanding the C |
is easier :-) |
***********************************************************/ |
SIGNAL(SIG_UART_RECV) |
{ |
b68: 1f 92 push r1 |
b6a: 0f 92 push r0 |
b6c: 0f b6 in r0, 0x3f ; 63 |
b6e: 0f 92 push r0 |
b70: 11 24 eor r1, r1 |
b72: 2f 93 push r18 |
b74: 8f 93 push r24 |
b76: 9f 93 push r25 |
b78: ef 93 push r30 |
b7a: ff 93 push r31 |
unsigned char tmpHead; |
/* read the data byte, put it in the serial queue, and |
post the event */ |
|
UIMgr_rxFifo[UIMgr_rxFifoHead] = UDR; |
b7c: 20 91 b8 00 lds r18, 0x00B8 |
b80: 84 e7 ldi r24, 0x74 ; 116 |
b82: 92 e0 ldi r25, 0x02 ; 2 |
b84: fc 01 movw r30, r24 |
b86: e2 0f add r30, r18 |
b88: f1 1d adc r31, r1 |
b8a: 8c b1 in r24, 0x0c ; 12 |
b8c: 80 83 st Z, r24 |
|
/* now move the head up */ |
tmpHead = (UIMgr_rxFifoHead + 1) & (UI_MGR_RX_FIFO_MASK); |
b8e: 2f 5f subi r18, 0xFF ; 255 |
b90: 2f 71 andi r18, 0x1F ; 31 |
UIMgr_rxFifoHead = tmpHead; |
b92: 20 93 b8 00 sts 0x00B8, r18 |
|
/* write the serial received event to the event fifo */ |
Exec_eventFifo[Exec_eventFifoHead] = EV_SERIAL_DATA_RECEIVED; |
b96: 20 91 70 00 lds r18, 0x0070 |
b9a: 8c e6 ldi r24, 0x6C ; 108 |
b9c: 92 e0 ldi r25, 0x02 ; 2 |
b9e: fc 01 movw r30, r24 |
ba0: e2 0f add r30, r18 |
ba2: f1 1d adc r31, r1 |
ba4: 81 e0 ldi r24, 0x01 ; 1 |
ba6: 80 83 st Z, r24 |
|
/* now move the head up */ |
tmpHead = (Exec_eventFifoHead + 1) & (EXEC_EVENT_FIFO_MASK); |
ba8: 28 0f add r18, r24 |
baa: 27 70 andi r18, 0x07 ; 7 |
Exec_eventFifoHead = tmpHead; |
bac: 20 93 70 00 sts 0x0070, r18 |
} |
bb0: ff 91 pop r31 |
bb2: ef 91 pop r30 |
bb4: 9f 91 pop r25 |
bb6: 8f 91 pop r24 |
bb8: 2f 91 pop r18 |
bba: 0f 90 pop r0 |
bbc: 0f be out 0x3f, r0 ; 63 |
bbe: 0f 90 pop r0 |
bc0: 1f 90 pop r1 |
bc2: 18 95 reti |
|
00000bc4 <I2CInt_init>: |
Outputs: none |
***********************************************************/ |
void I2CInt_init(void) |
{ |
TWSR = 0; |
bc4: 11 b8 out 0x01, r1 ; 1 |
|
/* init the speed of the I2C interface, running at |
100 Kbps */ |
TWBR = (FOSC / I2C_SPEED - 16)/2; |
bc6: 88 e4 ldi r24, 0x48 ; 72 |
bc8: 80 b9 out 0x00, r24 ; 0 |
} |
bca: 08 95 ret |
|
00000bcc <I2CInt_writeData>: |
|
/*********************************************************** |
Function Name: I2CInt_writeData |
Function Description: This function is responsible for |
initiating the process of writing a sequence of bytes |
an I2C slave address. This function will try to write |
the data three times before giving up. |
Inputs: address: the address of the I2C slave device |
data: a pointer to the data to be written |
to the slave...for camera interfacing, |
the data follows a <register #><data> |
format |
bytes: the number of bytes to write |
Outputs: none |
***********************************************************/ |
void I2CInt_writeData(unsigned char address, unsigned char *data, unsigned char bytes) |
{ |
bcc: 98 2f mov r25, r24 |
while(status & (1<<BUSY)); /* Bus is busy wait (or exit with error code) */ |
bce: 80 91 08 01 lds r24, 0x0108 |
bd2: 88 23 and r24, r24 |
bd4: e4 f3 brlt .-8 ; 0xbce |
while(TWCR & (1<<TWSTO)); |
bd6: 06 b6 in r0, 0x36 ; 54 |
bd8: 04 fc sbrc r0, 4 |
bda: fd cf rjmp .-6 ; 0xbd6 |
|
/* copy the needed data and state info to our local I2C command structure */ |
twi_address = address; |
bdc: 90 93 03 01 sts 0x0103, r25 |
twi_data = data; |
be0: 70 93 05 01 sts 0x0105, r23 |
be4: 60 93 04 01 sts 0x0104, r22 |
twi_bytes = bytes; |
be8: 40 93 07 01 sts 0x0107, r20 |
twi_ddr = TW_WRITE; |
bec: 10 92 06 01 sts 0x0106, r1 |
|
retry_cnt = 0; |
bf0: 10 92 09 01 sts 0x0109, r1 |
|
/* Generate start condition, the remainder of the transfer is interrupt driven and |
will be performed in the background */ |
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE); |
bf4: 85 ea ldi r24, 0xA5 ; 165 |
bf6: 86 bf out 0x36, r24 ; 54 |
|
status |= (1<<BUSY); |
bf8: 80 91 08 01 lds r24, 0x0108 |
bfc: 80 68 ori r24, 0x80 ; 128 |
bfe: 80 93 08 01 sts 0x0108, r24 |
} |
c02: 08 95 ret |
|
00000c04 <I2CInt_readData>: |
|
/*********************************************************** |
Function Name: I2CInt_readData |
Function Description: This funcion is responsible for |
reading the specified number of bytes from a slave |
device. |
Inputs: address: the slave address to read from |
data: a pointer to where the data will be stored |
bytes: the number of bytes to read |
Outputs: none |
***********************************************************/ |
void I2CInt_readData(unsigned char address, unsigned char *data, unsigned char bytes) |
{ |
c04: 98 2f mov r25, r24 |
/* Bus is busy wait (or exit with error code) */ |
while(status & (1<<BUSY)); |
c06: 80 91 08 01 lds r24, 0x0108 |
c0a: 88 23 and r24, r24 |
c0c: e4 f3 brlt .-8 ; 0xc06 |
|
twi_address = address; |
c0e: 90 93 03 01 sts 0x0103, r25 |
twi_data = data; |
c12: 70 93 05 01 sts 0x0105, r23 |
c16: 60 93 04 01 sts 0x0104, r22 |
twi_bytes = bytes; |
c1a: 40 93 07 01 sts 0x0107, r20 |
twi_ddr = TW_READ; |
c1e: 81 e0 ldi r24, 0x01 ; 1 |
c20: 80 93 06 01 sts 0x0106, r24 |
|
retry_cnt = 0; |
c24: 10 92 09 01 sts 0x0109, r1 |
|
/* Generate start condition, the remainder of the transfer is interrupt driven and |
will be performed in the background */ |
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE); |
c28: 85 ea ldi r24, 0xA5 ; 165 |
c2a: 86 bf out 0x36, r24 ; 54 |
|
status |= (1<<BUSY); |
c2c: 80 91 08 01 lds r24, 0x0108 |
c30: 80 68 ori r24, 0x80 ; 128 |
c32: 80 93 08 01 sts 0x0108, r24 |
} |
c36: 08 95 ret |
|
00000c38 <I2CInt_isI2cBusy>: |
|
/*********************************************************** |
Function Name: I2CInt_isI2cBusy |
Function Description: This funcion is responsible for |
indicating if the I2C bus is currently busy to external |
modules. |
device. |
Inputs: none |
Outputs: bool_t - indicating if bus is busy |
***********************************************************/ |
bool_t I2CInt_isI2cBusy(void) |
{ |
bool_t retVal = FALSE; |
c38: 90 e0 ldi r25, 0x00 ; 0 |
if ( (status & (1<<BUSY)) != 0) |
c3a: 80 91 08 01 lds r24, 0x0108 |
c3e: 88 23 and r24, r24 |
c40: 0c f4 brge .+2 ; 0xc44 |
{ |
retVal = TRUE; |
c42: 91 e0 ldi r25, 0x01 ; 1 |
} |
|
return(retVal); |
c44: 89 2f mov r24, r25 |
c46: 99 27 eor r25, r25 |
} |
c48: 08 95 ret |
|
00000c4a <__vector_17>: |
|
/*********************************************************** |
Function Name: <interrupt handler for I2C> |
Function Description: This function is responsible for |
implementing the control logic needed to perform a |
read or write operation with an I2C slave. |
Inputs: none |
Outputs: none |
***********************************************************/ |
SIGNAL(SIG_2WIRE_SERIAL) |
{ |
c4a: 1f 92 push r1 |
c4c: 0f 92 push r0 |
c4e: 0f b6 in r0, 0x3f ; 63 |
c50: 0f 92 push r0 |
c52: 11 24 eor r1, r1 |
c54: 8f 93 push r24 |
c56: 9f 93 push r25 |
c58: af 93 push r26 |
c5a: bf 93 push r27 |
c5c: ef 93 push r30 |
c5e: ff 93 push r31 |
unsigned char TWI_status = TWSR & TW_STATUS_MASK; /* grab just the status bits */ |
c60: 81 b1 in r24, 0x01 ; 1 |
c62: 88 7f andi r24, 0xF8 ; 248 |
|
/* the entire I2C handler is state-based...determine |
what needs to be done based on TWI_status */ |
switch(TWI_status) |
c64: 99 27 eor r25, r25 |
c66: aa 27 eor r26, r26 |
c68: bb 27 eor r27, r27 |
c6a: fc 01 movw r30, r24 |
c6c: 38 97 sbiw r30, 0x08 ; 8 |
c6e: e1 35 cpi r30, 0x51 ; 81 |
c70: f1 05 cpc r31, r1 |
c72: 08 f0 brcs .+2 ; 0xc76 |
c74: 6d c0 rjmp .+218 ; 0xd50 |
c76: ed 5e subi r30, 0xED ; 237 |
c78: ff 4f sbci r31, 0xFF ; 255 |
c7a: 09 94 ijmp |
{ |
case TW_START: /* Start condition */ |
case TW_REP_START: /* Repeated start condition */ |
if(retry_cnt > MAX_TWI_RETRIES) |
c7c: 80 91 09 01 lds r24, 0x0109 |
c80: 83 30 cpi r24, 0x03 ; 3 |
c82: 08 f0 brcs .+2 ; 0xc86 |
c84: 5d c0 rjmp .+186 ; 0xd40 |
{ |
/* generate stop condition if we've reached our retry limit */ |
TWCR |= (1<<TWINT)|(1<<TWSTO); |
status &= ~(1<<BUSY); |
return; |
} |
/* indicate read or write */ |
TWDR = (twi_address<<1) + twi_ddr; |
c86: 80 91 03 01 lds r24, 0x0103 |
c8a: 98 2f mov r25, r24 |
c8c: 99 0f add r25, r25 |
c8e: 80 91 06 01 lds r24, 0x0106 |
c92: 89 0f add r24, r25 |
c94: 83 b9 out 0x03, r24 ; 3 |
/* TWSTA must be cleared...also clears TWINT */ |
TWCR &= ~(1<<TWSTA); |
c96: 86 b7 in r24, 0x36 ; 54 |
c98: 8f 7d andi r24, 0xDF ; 223 |
c9a: 4a c0 rjmp .+148 ; 0xd30 |
break; |
|
case TW_MT_SLA_ACK: /* Slave acknowledged address, */ |
retry_cnt = 0; |
c9c: 10 92 09 01 sts 0x0109, r1 |
/* tx the data, and increment the data pointer */ |
TWDR = *twi_data; |
ca0: 11 c0 rjmp .+34 ; 0xcc4 |
twi_data++; |
|
/* clear the int to continue */ |
TWCR |= (1<<TWINT); |
break; |
|
case TW_MT_SLA_NACK: /* Slave didn't acknowledge address, */ |
case TW_MR_SLA_NACK: |
retry_cnt++; |
ca2: 80 91 09 01 lds r24, 0x0109 |
ca6: 8f 5f subi r24, 0xFF ; 255 |
ca8: 80 93 09 01 sts 0x0109, r24 |
|
/* retry...*/ |
TWCR |= (1<<TWINT)|(1<<TWSTA)|(1<<TWSTO); |
cac: 86 b7 in r24, 0x36 ; 54 |
cae: 80 6b ori r24, 0xB0 ; 176 |
cb0: 3f c0 rjmp .+126 ; 0xd30 |
break; |
|
case TW_MT_DATA_ACK: /* Slave Acknowledged data, */ |
if(--twi_bytes > 0) |
cb2: 80 91 07 01 lds r24, 0x0107 |
cb6: 81 50 subi r24, 0x01 ; 1 |
cb8: 80 93 07 01 sts 0x0107, r24 |
cbc: 80 91 07 01 lds r24, 0x0107 |
cc0: 88 23 and r24, r24 |
cc2: f1 f1 breq .+124 ; 0xd40 |
{ |
/* more data to send, so send it */ |
TWDR = *twi_data; |
cc4: e0 91 04 01 lds r30, 0x0104 |
cc8: f0 91 05 01 lds r31, 0x0105 |
ccc: 80 81 ld r24, Z |
cce: 83 b9 out 0x03, r24 ; 3 |
twi_data++; |
cd0: cf 01 movw r24, r30 |
cd2: 01 96 adiw r24, 0x01 ; 1 |
cd4: 90 93 05 01 sts 0x0105, r25 |
cd8: 80 93 04 01 sts 0x0104, r24 |
TWCR |= (1<<TWINT); |
cdc: 09 c0 rjmp .+18 ; 0xcf0 |
} |
else |
{ |
/* generate the stop condition if needed */ |
TWCR |= (1<<TWSTO)|(1<<TWINT); |
status &= ~(1<<BUSY); |
} |
break; |
|
case TW_MT_DATA_NACK: /* Slave didn't acknowledge data */ |
/* send the stop condition */ |
TWCR |= (1<<TWINT)|(1<<TWSTO); |
status &= ~(1<<BUSY); |
break; |
|
case TW_MR_SLA_ACK: /* Slave acknowledged address */ |
if(--twi_bytes > 0) |
cde: 80 91 07 01 lds r24, 0x0107 |
ce2: 81 50 subi r24, 0x01 ; 1 |
ce4: 80 93 07 01 sts 0x0107, r24 |
ce8: 80 91 07 01 lds r24, 0x0107 |
cec: 88 23 and r24, r24 |
cee: d9 f4 brne .+54 ; 0xd26 |
{ |
/* if there is more than one byte to read, acknowledge */ |
TWCR |= (1<<TWEA)|(1<<TWINT); |
} |
else |
{ |
/* no acknowledge */ |
TWCR |= (1<<TWINT); |
cf0: 86 b7 in r24, 0x36 ; 54 |
cf2: 80 68 ori r24, 0x80 ; 128 |
cf4: 1d c0 rjmp .+58 ; 0xd30 |
} |
break; |
|
case TW_MR_DATA_ACK: /* Master acknowledged data */ |
|
/* grab the received data */ |
*twi_data = TWDR; |
cf6: e0 91 04 01 lds r30, 0x0104 |
cfa: f0 91 05 01 lds r31, 0x0105 |
cfe: 83 b1 in r24, 0x03 ; 3 |
d00: 80 83 st Z, r24 |
twi_data++; |
d02: 80 91 04 01 lds r24, 0x0104 |
d06: 90 91 05 01 lds r25, 0x0105 |
d0a: 01 96 adiw r24, 0x01 ; 1 |
d0c: 90 93 05 01 sts 0x0105, r25 |
d10: 80 93 04 01 sts 0x0104, r24 |
if(--twi_bytes > 0) |
d14: 80 91 07 01 lds r24, 0x0107 |
d18: 81 50 subi r24, 0x01 ; 1 |
d1a: 80 93 07 01 sts 0x0107, r24 |
d1e: 80 91 07 01 lds r24, 0x0107 |
d22: 88 23 and r24, r24 |
d24: 19 f0 breq .+6 ; 0xd2c |
{ |
/* get the next data byte and ack */ |
TWCR |= (1<<TWEA)|(1<<TWINT); |
d26: 86 b7 in r24, 0x36 ; 54 |
d28: 80 6c ori r24, 0xC0 ; 192 |
d2a: 02 c0 rjmp .+4 ; 0xd30 |
} |
else |
{ |
/* clear out the enable acknowledge bit */ |
TWCR &= ~(1<<TWEA); |
d2c: 86 b7 in r24, 0x36 ; 54 |
d2e: 8f 7b andi r24, 0xBF ; 191 |
d30: 86 bf out 0x36, r24 ; 54 |
} |
break; |
d32: 0e c0 rjmp .+28 ; 0xd50 |
|
case TW_MR_DATA_NACK: /* Master didn't acknowledge data -> end of read process */ |
/* read data, and generate the stop condition */ |
*twi_data = TWDR; |
d34: e0 91 04 01 lds r30, 0x0104 |
d38: f0 91 05 01 lds r31, 0x0105 |
d3c: 83 b1 in r24, 0x03 ; 3 |
d3e: 80 83 st Z, r24 |
TWCR |= (1<<TWSTO)|(1<<TWINT); |
d40: 86 b7 in r24, 0x36 ; 54 |
d42: 80 69 ori r24, 0x90 ; 144 |
d44: 86 bf out 0x36, r24 ; 54 |
status &= ~(1<<BUSY); |
d46: 80 91 08 01 lds r24, 0x0108 |
d4a: 8f 77 andi r24, 0x7F ; 127 |
d4c: 80 93 08 01 sts 0x0108, r24 |
break; |
} |
} |
d50: ff 91 pop r31 |
d52: ef 91 pop r30 |
d54: bf 91 pop r27 |
d56: af 91 pop r26 |
d58: 9f 91 pop r25 |
d5a: 8f 91 pop r24 |
d5c: 0f 90 pop r0 |
d5e: 0f be out 0x3f, r0 ; 63 |
d60: 0f 90 pop r0 |
d62: 1f 90 pop r1 |
d64: 18 95 reti |
|
00000d66 <CamConfig_init>: |
Outputs: none |
***********************************************************/ |
void CamConfig_init(void) |
{ |
CamConfig_setCamReg(0x14,0x20); /* reduce frame size */ |
d66: 60 e2 ldi r22, 0x20 ; 32 |
d68: 84 e1 ldi r24, 0x14 ; 20 |
d6a: 0e d0 rcall .+28 ; 0xd88 |
CamConfig_setCamReg(0x39,0x40); /* gate PCLK with HREF */ |
d6c: 60 e4 ldi r22, 0x40 ; 64 |
d6e: 89 e3 ldi r24, 0x39 ; 57 |
d70: 0b d0 rcall .+22 ; 0xd88 |
CamConfig_setCamReg(0x12,0x28); /* set RGB mode, with no AWB */ |
d72: 68 e2 ldi r22, 0x28 ; 40 |
d74: 82 e1 ldi r24, 0x12 ; 18 |
d76: 08 d0 rcall .+16 ; 0xd88 |
CamConfig_setCamReg(0x28,0x05); /* set color sequencer */ |
d78: 65 e0 ldi r22, 0x05 ; 5 |
d7a: 88 e2 ldi r24, 0x28 ; 40 |
d7c: 05 d0 rcall .+10 ; 0xd88 |
CamConfig_setCamReg(0x13,0x01); /* un-tri-state the Y/UV lines */ |
d7e: 61 e0 ldi r22, 0x01 ; 1 |
d80: 83 e1 ldi r24, 0x13 ; 19 |
d82: 02 d0 rcall .+4 ; 0xd88 |
|
/* send the first four cmds in the I2C fifo */ |
CamConfig_sendFifoCmds(); |
d84: 06 d0 rcall .+12 ; 0xd92 |
} |
d86: 08 95 ret |
|
00000d88 <CamConfig_setCamReg>: |
|
|
/*********************************************************** |
Function Name: CamConfig_setCamReg |
Function Description: This function is responsible for |
creating an I2C cmd structure and placing it into the |
cmd fifo. |
Inputs: reg - the register to modify |
val - the new value of the register |
Outputs: none |
***********************************************************/ |
void CamConfig_setCamReg(unsigned char reg, unsigned char val) |
{ |
i2cCmd_t cmd; |
|
cmd.configReg = reg; |
d88: 28 2f mov r18, r24 |
cmd.data = val; |
d8a: 36 2f mov r19, r22 |
#ifndef SIMULATION |
CamConfig_writeTxFifo(cmd); |
d8c: c9 01 movw r24, r18 |
d8e: 2f d0 rcall .+94 ; 0xdee |
#endif |
} |
d90: 08 95 ret |
|
00000d92 <CamConfig_sendFifoCmds>: |
/*********************************************************** |
Function Name: CamConfig_sendFifoCmds |
Function Description: This function is responsible for |
sending the entire contents of the config fifo. This |
function won't return until the configuration process |
is complete (or an error is encountered). |
Inputs: none |
Outputs: none |
Note: Since this function is written to use the TWI |
interrupt in the I2CInterface module, there will be |
some busy-waiting here...no big deal, since we end up |
having to trash the frame that we are executing this |
slave write in anyway (since we can't meet the strict |
timing requirements and write i2c at the same time). |
***********************************************************/ |
void CamConfig_sendFifoCmds(void) |
{ |
d92: cf 93 push r28 |
d94: df 93 push r29 |
d96: cd b7 in r28, 0x3d ; 61 |
d98: de b7 in r29, 0x3e ; 62 |
d9a: 22 97 sbiw r28, 0x02 ; 2 |
d9c: 0f b6 in r0, 0x3f ; 63 |
d9e: f8 94 cli |
da0: de bf out 0x3e, r29 ; 62 |
da2: 0f be out 0x3f, r0 ; 63 |
da4: cd bf out 0x3d, r28 ; 61 |
i2cCmd_t cmd; |
|
while (CamConfig_txFifoHead != CamConfig_txFifoTail) |
da6: 90 91 0a 01 lds r25, 0x010A |
daa: 80 91 0b 01 lds r24, 0x010B |
dae: 98 17 cp r25, r24 |
db0: a9 f0 breq .+42 ; 0xddc |
{ |
cmd = CamConfig_readTxFifo(); |
db2: 37 d0 rcall .+110 ; 0xe22 |
db4: 89 83 std Y+1, r24 ; 0x01 |
db6: 9a 83 std Y+2, r25 ; 0x02 |
I2CInt_writeData(CAM_ADDRESS,&cmd.configReg,SIZE_OF_I2C_CMD); |
db8: 42 e0 ldi r20, 0x02 ; 2 |
dba: be 01 movw r22, r28 |
dbc: 6f 5f subi r22, 0xFF ; 255 |
dbe: 7f 4f sbci r23, 0xFF ; 255 |
dc0: 80 e6 ldi r24, 0x60 ; 96 |
dc2: 04 df rcall .-504 ; 0xbcc |
Utility_delay(100); |
dc4: 84 e6 ldi r24, 0x64 ; 100 |
dc6: 90 e0 ldi r25, 0x00 ; 0 |
dc8: 3e d0 rcall .+124 ; 0xe46 |
/* wait for the I2C transaction to complete */ |
while(I2CInt_isI2cBusy() == TRUE); |
dca: 36 df rcall .-404 ; 0xc38 |
dcc: 81 30 cpi r24, 0x01 ; 1 |
dce: e9 f3 breq .-6 ; 0xdca |
dd0: 90 91 0a 01 lds r25, 0x010A |
dd4: 80 91 0b 01 lds r24, 0x010B |
dd8: 98 17 cp r25, r24 |
dda: 59 f7 brne .-42 ; 0xdb2 |
} |
} |
ddc: 22 96 adiw r28, 0x02 ; 2 |
dde: 0f b6 in r0, 0x3f ; 63 |
de0: f8 94 cli |
de2: de bf out 0x3e, r29 ; 62 |
de4: 0f be out 0x3f, r0 ; 63 |
de6: cd bf out 0x3d, r28 ; 61 |
de8: df 91 pop r29 |
dea: cf 91 pop r28 |
dec: 08 95 ret |
|
00000dee <CamConfig_writeTxFifo>: |
|
/*********************************************************** |
Function Name: CamConfig_writeTxFifo |
Function Description: This function is responsible for |
adding a new command to the tx fifo. It adjusts all |
needed pointers. |
Inputs: cmd - the i2cCmd_t to add to the fifo |
Outputs: bool_t - indicating if writing to the fifo |
causes it to wrap |
***********************************************************/ |
bool_t CamConfig_writeTxFifo(i2cCmd_t cmd) |
{ |
dee: 9c 01 movw r18, r24 |
unsigned char tmpHead; |
bool_t retVal = TRUE; |
df0: 51 e0 ldi r21, 0x01 ; 1 |
|
CamConfig_txFifo[CamConfig_txFifoHead] = cmd; |
df2: 40 91 0a 01 lds r20, 0x010A |
df6: 84 2f mov r24, r20 |
df8: 99 27 eor r25, r25 |
dfa: 88 0f add r24, r24 |
dfc: 99 1f adc r25, r25 |
dfe: fc 01 movw r30, r24 |
e00: ec 52 subi r30, 0x2C ; 44 |
e02: fd 4f sbci r31, 0xFD ; 253 |
e04: 20 83 st Z, r18 |
e06: 31 83 std Z+1, r19 ; 0x01 |
|
/* see if we need to wrap */ |
tmpHead = (CamConfig_txFifoHead+1) & (CAM_CONFIG_TX_FIFO_MASK); |
e08: 84 2f mov r24, r20 |
e0a: 85 0f add r24, r21 |
e0c: 87 70 andi r24, 0x07 ; 7 |
CamConfig_txFifoHead = tmpHead; |
e0e: 80 93 0a 01 sts 0x010A, r24 |
|
/* check to see if we have filled up the queue */ |
if (CamConfig_txFifoHead == CamConfig_txFifoTail) |
e12: 90 91 0b 01 lds r25, 0x010B |
e16: 89 17 cp r24, r25 |
e18: 09 f4 brne .+2 ; 0xe1c |
{ |
/* we wrapped the fifo...return false */ |
retVal = FALSE; |
e1a: 50 e0 ldi r21, 0x00 ; 0 |
} |
return(retVal); |
e1c: 85 2f mov r24, r21 |
e1e: 99 27 eor r25, r25 |
} |
e20: 08 95 ret |
|
00000e22 <CamConfig_readTxFifo>: |
|
/*********************************************************** |
Function Name: CamConfig_readTxFifo |
Function Description: This function is responsible for |
reading a cmd out of the tx fifo. |
Inputs: none |
Outputs: i2cCmd_t - the cmd read from the fifo |
***********************************************************/ |
static i2cCmd_t CamConfig_readTxFifo(void) |
{ |
i2cCmd_t cmd; |
unsigned char tmpTail; |
|
/* just return the current tail from the rx fifo */ |
cmd = CamConfig_txFifo[CamConfig_txFifoTail]; |
e22: 40 91 0b 01 lds r20, 0x010B |
e26: 84 2f mov r24, r20 |
e28: 99 27 eor r25, r25 |
e2a: 88 0f add r24, r24 |
e2c: 99 1f adc r25, r25 |
e2e: fc 01 movw r30, r24 |
e30: ec 52 subi r30, 0x2C ; 44 |
e32: fd 4f sbci r31, 0xFD ; 253 |
e34: 20 81 ld r18, Z |
e36: 31 81 ldd r19, Z+1 ; 0x01 |
tmpTail = (CamConfig_txFifoTail+1) & (CAM_CONFIG_TX_FIFO_MASK); |
e38: 84 2f mov r24, r20 |
e3a: 8f 5f subi r24, 0xFF ; 255 |
e3c: 87 70 andi r24, 0x07 ; 7 |
CamConfig_txFifoTail = tmpTail; |
e3e: 80 93 0b 01 sts 0x010B, r24 |
|
return(cmd); |
} |
e42: c9 01 movw r24, r18 |
e44: 08 95 ret |
|
00000e46 <Utility_delay>: |
if needed...this isn't really a millisecond, so DON'T |
depend on it for exact timing... |
***********************************************************/ |
void Utility_delay(unsigned short numMs) |
{ |
e46: cf 93 push r28 |
e48: df 93 push r29 |
e4a: cd b7 in r28, 0x3d ; 61 |
e4c: de b7 in r29, 0x3e ; 62 |
e4e: 24 97 sbiw r28, 0x04 ; 4 |
e50: 0f b6 in r0, 0x3f ; 63 |
e52: f8 94 cli |
e54: de bf out 0x3e, r29 ; 62 |
e56: 0f be out 0x3f, r0 ; 63 |
e58: cd bf out 0x3d, r28 ; 61 |
e5a: 9c 01 movw r18, r24 |
volatile unsigned short i=0,j=0; |
e5c: 19 82 std Y+1, r1 ; 0x01 |
e5e: 1a 82 std Y+2, r1 ; 0x02 |
e60: 1b 82 std Y+3, r1 ; 0x03 |
e62: 1c 82 std Y+4, r1 ; 0x04 |
#ifndef SIMULATION |
for (i=0; i<numMs; i++) |
e64: 19 82 std Y+1, r1 ; 0x01 |
e66: 1a 82 std Y+2, r1 ; 0x02 |
e68: 89 81 ldd r24, Y+1 ; 0x01 |
e6a: 9a 81 ldd r25, Y+2 ; 0x02 |
e6c: 82 17 cp r24, r18 |
e6e: 93 07 cpc r25, r19 |
e70: e0 f4 brcc .+56 ; 0xeaa |
{ |
for (j=0; j<1000; j++) |
e72: 1b 82 std Y+3, r1 ; 0x03 |
e74: 1c 82 std Y+4, r1 ; 0x04 |
e76: 8b 81 ldd r24, Y+3 ; 0x03 |
e78: 9c 81 ldd r25, Y+4 ; 0x04 |
e7a: 88 5e subi r24, 0xE8 ; 232 |
e7c: 93 40 sbci r25, 0x03 ; 3 |
e7e: 58 f4 brcc .+22 ; 0xe96 |
{ |
asm volatile("nop"::); |
e80: 00 00 nop |
e82: 8b 81 ldd r24, Y+3 ; 0x03 |
e84: 9c 81 ldd r25, Y+4 ; 0x04 |
e86: 01 96 adiw r24, 0x01 ; 1 |
e88: 8b 83 std Y+3, r24 ; 0x03 |
e8a: 9c 83 std Y+4, r25 ; 0x04 |
e8c: 8b 81 ldd r24, Y+3 ; 0x03 |
e8e: 9c 81 ldd r25, Y+4 ; 0x04 |
e90: 88 5e subi r24, 0xE8 ; 232 |
e92: 93 40 sbci r25, 0x03 ; 3 |
e94: a8 f3 brcs .-22 ; 0xe80 |
e96: 89 81 ldd r24, Y+1 ; 0x01 |
e98: 9a 81 ldd r25, Y+2 ; 0x02 |
e9a: 01 96 adiw r24, 0x01 ; 1 |
e9c: 89 83 std Y+1, r24 ; 0x01 |
e9e: 9a 83 std Y+2, r25 ; 0x02 |
ea0: 89 81 ldd r24, Y+1 ; 0x01 |
ea2: 9a 81 ldd r25, Y+2 ; 0x02 |
ea4: 82 17 cp r24, r18 |
ea6: 93 07 cpc r25, r19 |
ea8: 20 f3 brcs .-56 ; 0xe72 |
} |
} |
#endif |
} |
eaa: 24 96 adiw r28, 0x04 ; 4 |
eac: 0f b6 in r0, 0x3f ; 63 |
eae: f8 94 cli |
eb0: de bf out 0x3e, r29 ; 62 |
eb2: 0f be out 0x3f, r0 ; 63 |
eb4: cd bf out 0x3d, r28 ; 61 |
eb6: df 91 pop r29 |
eb8: cf 91 pop r28 |
eba: 08 95 ret |
|
00000ebc <DebugInt_init>: |
Inputs: none |
Outputs: none |
***********************************************************/ |
void DebugInt_init(void) |
{ |
ebc: 1f 93 push r17 |
/* set PortD pin6 for output */ |
DDRD |= 0x40; |
ebe: 8e 9a sbi 0x11, 6 ; 17 |
/* turn on LED */ |
PORTD |= 0x40; |
ec0: 96 9a sbi 0x12, 6 ; 18 |
Utility_delay(500); |
ec2: 84 ef ldi r24, 0xF4 ; 244 |
ec4: 91 e0 ldi r25, 0x01 ; 1 |
ec6: bf df rcall .-130 ; 0xe46 |
PORTD &= 0xBF; |
ec8: 1f eb ldi r17, 0xBF ; 191 |
eca: 82 b3 in r24, 0x12 ; 18 |
ecc: 81 23 and r24, r17 |
ece: 82 bb out 0x12, r24 ; 18 |
Utility_delay(500); |
ed0: 84 ef ldi r24, 0xF4 ; 244 |
ed2: 91 e0 ldi r25, 0x01 ; 1 |
ed4: b8 df rcall .-144 ; 0xe46 |
PORTD |= 0x40; |
ed6: 96 9a sbi 0x12, 6 ; 18 |
Utility_delay(500); |
ed8: 84 ef ldi r24, 0xF4 ; 244 |
eda: 91 e0 ldi r25, 0x01 ; 1 |
edc: b4 df rcall .-152 ; 0xe46 |
PORTD &= 0xBF; |
ede: 82 b3 in r24, 0x12 ; 18 |
ee0: 81 23 and r24, r17 |
ee2: 82 bb out 0x12, r24 ; 18 |
Utility_delay(500); |
ee4: 84 ef ldi r24, 0xF4 ; 244 |
ee6: 91 e0 ldi r25, 0x01 ; 1 |
ee8: ae df rcall .-164 ; 0xe46 |
PORTD |= 0x40; |
eea: 96 9a sbi 0x12, 6 ; 18 |
Utility_delay(500); |
eec: 84 ef ldi r24, 0xF4 ; 244 |
eee: 91 e0 ldi r25, 0x01 ; 1 |
ef0: aa df rcall .-172 ; 0xe46 |
PORTD &= 0xBF; |
ef2: 82 b3 in r24, 0x12 ; 18 |
ef4: 81 23 and r24, r17 |
ef6: 82 bb out 0x12, r24 ; 18 |
Utility_delay(500); |
ef8: 84 ef ldi r24, 0xF4 ; 244 |
efa: 91 e0 ldi r25, 0x01 ; 1 |
efc: a4 df rcall .-184 ; 0xe46 |
PORTD |= 0x40; |
efe: 96 9a sbi 0x12, 6 ; 18 |
} |
f00: 1f 91 pop r17 |
f02: 08 95 ret |
|
00000f04 <CamIntAsm_waitForNewTrackingFrame>: |
; set, and the function will return. |
;***************************************************************** |
|
CamIntAsm_waitForNewTrackingFrame: |
sbi _SFR_IO_ADDR(PORTD),PD6 ; For testing... |
f04: 96 9a sbi 0x12, 6 ; 18 |
cbi _SFR_IO_ADDR(PORTD),PD6 |
f06: 96 98 cbi 0x12, 6 ; 18 |
sleep |
f08: 88 95 sleep |
|
00000f0a <CamIntAsm_acquireTrackingLine>: |
|
;***************************************************************** |
; REMEMBER...everything from here on out is critically timed to be |
; synchronized with the flow of pixel data from the camera... |
;***************************************************************** |
|
CamIntAsm_acquireTrackingLine: |
brts _cleanUp |
f0a: e6 f1 brts .+120 ; 0xf84 |
;sbi _SFR_IO_ADDR(PORTD),PD6 ; For testing... |
;cbi _SFR_IO_ADDR(PORTD),PD6 |
|
in tmp1,_SFR_IO_ADDR(TCCR1B) ; Enable the PCLK line to actually |
f0c: 3e b5 in r19, 0x2e ; 46 |
ori tmp1, 0x07 ; feed Timer1 |
f0e: 37 60 ori r19, 0x07 ; 7 |
out _SFR_IO_ADDR(TCCR1B),tmp1 |
f10: 3e bd out 0x2e, r19 ; 46 |
; The line is about to start... |
ldi pixelCount,0 ; Initialize the RLE stats... |
f12: 00 e0 ldi r16, 0x00 ; 0 |
ldi pixelRunStart,PIXEL_RUN_START_INITIAL ; Remember, we always calculate |
f14: 10 e5 ldi r17, 0x50 ; 80 |
; the pixel run length as |
; TCNT1L - pixelRunStart |
|
ldi lastColor,0x00 ; clear out the last color before we start |
f16: 20 e0 ldi r18, 0x00 ; 0 |
|
mov XH,currLineBuffHigh ; Load the pointer to the current line |
f18: b9 2f mov r27, r25 |
mov XL,currLineBuffLow ; buffer into the X pointer regs |
f1a: a8 2f mov r26, r24 |
|
mov ZH,colorMapHigh ; Load the pointers to the membership |
f1c: f7 2f mov r31, r23 |
mov ZL,colorMapLow ; lookup tables (ZL and YL will be overwritten |
f1e: e6 2f mov r30, r22 |
mov YH,colorMapHigh ; as soon as we start reading data) to Z and Y |
f20: d7 2f mov r29, r23 |
|
in tmp1, _SFR_IO_ADDR(TIMSK) ; enable TIMER1 to start counting |
f22: 39 b7 in r19, 0x39 ; 57 |
ori tmp1, ENABLE_PCLK_TIMER1_OVERFLOW_BITMASK ; external PCLK pulses and interrupt on |
f24: 34 60 ori r19, 0x04 ; 4 |
out _SFR_IO_ADDR(TIMSK),tmp1 ; overflow |
f26: 39 bf out 0x39, r19 ; 57 |
|
ldi tmp1,PIXEL_RUN_START_INITIAL ; set up the TCNT1 to overflow (and |
f28: 30 e5 ldi r19, 0x50 ; 80 |
ldi tmp2,0xFF ; interrupts) after 176 pixels |
f2a: 4f ef ldi r20, 0xFF ; 255 |
out _SFR_IO_ADDR(TCNT1H),tmp2 |
f2c: 4d bd out 0x2d, r20 ; 45 |
out _SFR_IO_ADDR(TCNT1L),tmp1 |
f2e: 3c bd out 0x2c, r19 ; 44 |
|
mov YL,colorMapLow |
f30: c6 2f mov r28, r22 |
|
in tmp1, _SFR_IO_ADDR(GICR) ; enable the HREF interrupt...remember, we |
f32: 3b b7 in r19, 0x3b ; 59 |
; only use this interrupt to synchronize |
; the beginning of the line |
ori tmp1, HREF_INTERRUPT_ENABLE_MASK |
f34: 30 68 ori r19, 0x80 ; 128 |
out _SFR_IO_ADDR(GICR), tmp1 |
f36: 3b bf out 0x3b, r19 ; 59 |
|
00000f38 <_trackFrame>: |
|
;******************************************************************************************* |
; Track Frame handler |
;******************************************************************************************* |
|
_trackFrame: |
sbi _SFR_IO_ADDR(PORTD),PD6 |
f38: 96 9a sbi 0x12, 6 ; 18 |
sleep ; ...And we wait... |
f3a: 88 95 sleep |
|
; Returning from the interrupt/sleep wakeup will consume |
; 14 clock cycles (7 to wakeup from idle sleep, 3 to vector, and 4 to return) |
|
; Disable the HREF interrupt |
cbi _SFR_IO_ADDR(PORTD),PD6 |
f3c: 96 98 cbi 0x12, 6 ; 18 |
in tmp1, _SFR_IO_ADDR(GICR) |
f3e: 3b b7 in r19, 0x3b ; 59 |
andi tmp1, HREF_INTERRUPT_DISABLE_MASK |
f40: 3f 77 andi r19, 0x7F ; 127 |
out _SFR_IO_ADDR(GICR), tmp1 |
f42: 3b bf out 0x3b, r19 ; 59 |
|
; A couple of NOPs are needed here to sync up the pixel data...the number (2) |
; of NOPs was determined emperically by trial and error. |
nop |
f44: 00 00 nop |
... |
|
00000f48 <_acquirePixelBlock>: |
nop |
_acquirePixelBlock: ; Clock Cycle Count |
in ZL,RB_PORT ; sample the red value (PINB) (1) |
f48: e6 b3 in r30, 0x16 ; 22 |
in YL,G_PORT ; sample the green value (PINC) (1) |
f4a: c3 b3 in r28, 0x13 ; 19 |
andi YL,0x0F ; clear the high nibble (1) |
f4c: cf 70 andi r28, 0x0F ; 15 |
ldd color,Z+RED_MEM_OFFSET ; lookup the red membership (2) |
f4e: 30 81 ld r19, Z |
in ZL,RB_PORT ; sample the blue value (PINB) (1) |
f50: e6 b3 in r30, 0x16 ; 22 |
ldd greenData,Y+GREEN_MEM_OFFSET; lookup the green membership (2) |
f52: 48 89 ldd r20, Y+16 ; 0x10 |
ldd blueData,Z+BLUE_MEM_OFFSET ; lookup the blue membership (2) |
f54: 50 a1 ldd r21, Z+32 ; 0x20 |
and color,greenData ; mask memberships together (1) |
f56: 34 23 and r19, r20 |
and color,blueData ; to produce the final color (1) |
f58: 35 23 and r19, r21 |
brts _cleanUpTrackingLine ; if some interrupt routine has (1...not set) |
f5a: 76 f0 brts .+28 ; 0xf78 |
; come in and set our T flag in |
; SREG, then we need to hop out |
; and blow away this frames data (common cleanup) |
cp color,lastColor ; check to see if the run continues (1) |
f5c: 32 17 cp r19, r18 |
breq _acquirePixelBlock ; (2...equal) |
f5e: a1 f3 breq .-24 ; 0xf48 |
; ___________ |
; 16 clock cycles |
; (16 clock cycles = 1 uS = 1 pixelBlock time) |
|
; Toggle the debug line to indicate a color change |
sbi _SFR_IO_ADDR(PORTD),PD6 |
f60: 96 9a sbi 0x12, 6 ; 18 |
nop |
f62: 00 00 nop |
cbi _SFR_IO_ADDR(PORTD),PD6 |
f64: 96 98 cbi 0x12, 6 ; 18 |
|
mov tmp2,pixelRunStart ; get the count value of the |
f66: 41 2f mov r20, r17 |
; current pixel run |
in pixelCount,_SFR_IO_ADDR(TCNT1L) ; get the current TCNT1 value |
f68: 0c b5 in r16, 0x2c ; 44 |
mov pixelRunStart,pixelCount ; reload pixelRunStart for the |
f6a: 10 2f mov r17, r16 |
; next run |
sub pixelCount,tmp2 ; pixelCount = TCNT1L - pixelRunStart |
f6c: 04 1b sub r16, r20 |
|
st X+,lastColor ; record the color run in the current line buffer |
f6e: 2d 93 st X+, r18 |
st X+,pixelCount ; with its length |
f70: 0d 93 st X+, r16 |
mov lastColor,color ; set lastColor so we can figure out when it changes |
f72: 23 2f mov r18, r19 |
|
nop ; waste one more cycle for a total of 16 |
f74: 00 00 nop |
rjmp _acquirePixelBlock |
f76: e8 cf rjmp .-48 ; 0xf48 |
|
00000f78 <_cleanUpTrackingLine>: |
|
; _cleanUpTrackingLine is used to write the last run length block off to the currentLineBuffer so |
; that all 176 pixels in the line are accounted for. |
_cleanUpTrackingLine: |
ldi pixelCount,0xFF ; the length of the last run is ALWAYS 0xFF minus the last |
f78: 0f ef ldi r16, 0xFF ; 255 |
sub pixelCount,pixelRunStart ; pixelRunStart |
f7a: 01 1b sub r16, r17 |
|
inc pixelCount ; increment pixelCount since we actually need to account |
f7c: 03 95 inc r16 |
; for the overflow of TCNT1 |
|
st X+,color ; record the color run in the current line buffer |
f7e: 3d 93 st X+, r19 |
st X,pixelCount |
f80: 0c 93 st X, r16 |
rjmp _cleanUp |
f82: 00 c0 rjmp .+0 ; 0xf84 |
|
00000f84 <_cleanUp>: |
|
_cleanUpDumpLine: |
; NOTE: If serial data is received, to interrupt the tracking of a line, we'll |
; get a EV_SERIAL_DATA_RECEIVED event, and the T bit set so we will end the |
; line's processing...however, the PCLK will keep on ticking for the rest of |
; the frame/line, which will cause the TCNT to eventually overflow and |
; interrupt us, generating a EV_ACQUIRE_LINE_COMPLETE event. We don't want |
; this, so we need to actually turn off the PCLK counting each time we exit |
; this loop, and only turn it on when we begin acquiring lines.... |
; NOT NEEDED FOR NOW... |
;in tmp1, _SFR_IO_ADDR(TIMSK) ; disable TIMER1 to stop counting |
;andi tmp1, DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK ; external PCLK pulses |
;out _SFR_IO_ADDR(TIMSK),tmp1 |
|
_cleanUp: |
; Disable the external clocking of the Timer1 counter |
in tmp1, _SFR_IO_ADDR(TCCR1B) |
f84: 3e b5 in r19, 0x2e ; 46 |
andi tmp1, 0xF8 |
f86: 38 7f andi r19, 0xF8 ; 248 |
out _SFR_IO_ADDR(TCCR1B),tmp1 |
f88: 3e bd out 0x2e, r19 ; 46 |
|
; Toggle the debug line to indicate the line is complete |
sbi _SFR_IO_ADDR(PORTD),PD6 |
f8a: 96 9a sbi 0x12, 6 ; 18 |
cbi _SFR_IO_ADDR(PORTD),PD6 |
f8c: 96 98 cbi 0x12, 6 ; 18 |
clt ; clear out the T bit since we have detected |
f8e: e8 94 clt |
|
00000f90 <_exit>: |
; the interruption and are exiting to handle it |
_exit: |
ret |
f90: 08 95 ret |
|
00000f92 <CamIntAsm_waitForNewDumpFrame>: |
|
;***************************************************************** |
; Function Name: CamIntAsm_waitForNewDumpFrame |
; Function Description: This function is responsible for |
; going to sleep until a new frame begins (indicated by |
; VSYNC transitioning from low to high. This will wake |
; the "VSYNC sleep" up and allow it to continue with |
; acquiring a line of pixel data to dump out to the UI. |
; Inputs: r25 - MSB of currentLineBuffer |
; r24 - LSB of currentLineBuffer |
; r23 - MSB of prevLineBuffer |
; r22 - LSB of prevLineBuffer |
; Outputs: none |
; NOTES: This function doesn't really return...it sorta just |
; floats into the acquireDumpLine function after the "VSYNC sleep" |
; is awoken. |
;***************************************************************** |
CamIntAsm_waitForNewDumpFrame: |
sbi _SFR_IO_ADDR(PORTD),PD6 ; For testing... |
f92: 96 9a sbi 0x12, 6 ; 18 |
cbi _SFR_IO_ADDR(PORTD),PD6 |
f94: 96 98 cbi 0x12, 6 ; 18 |
sleep |
f96: 88 95 sleep |
|
00000f98 <CamIntAsm_acquireDumpLine>: |
|
;***************************************************************** |
; REMEMBER...everything from here on out is critically timed to be |
; synchronized with the flow of pixel data from the camera... |
;***************************************************************** |
|
CamIntAsm_acquireDumpLine: |
brts _cleanUp |
f98: ae f3 brts .-22 ; 0xf84 |
;sbi _SFR_IO_ADDR(PORTD),PD6 ; For testing... |
;cbi _SFR_IO_ADDR(PORTD),PD6 |
|
mov XH,currLineBuffHigh ; Load the pointer to the current line |
f9a: b9 2f mov r27, r25 |
mov XL,currLineBuffLow ; buffer into the X pointer regs |
f9c: a8 2f mov r26, r24 |
|
mov YH,prevLineBuffHigh ; Load the pointer to the previous line |
f9e: d7 2f mov r29, r23 |
mov YL,prevLineBuffLow ; buffer into the Y pointer regs |
fa0: c6 2f mov r28, r22 |
|
ldi tmp1,PIXEL_RUN_START_INITIAL ; set up the TCNT1 to overflow (and |
fa2: 30 e5 ldi r19, 0x50 ; 80 |
ldi tmp2,0xFF ; interrupts) after 176 pixels |
fa4: 4f ef ldi r20, 0xFF ; 255 |
out _SFR_IO_ADDR(TCNT1H),tmp2 |
fa6: 4d bd out 0x2d, r20 ; 45 |
out _SFR_IO_ADDR(TCNT1L),tmp1 |
fa8: 3c bd out 0x2c, r19 ; 44 |
|
in tmp1, _SFR_IO_ADDR(TCCR1B) ; Enable the PCLK line to actually |
faa: 3e b5 in r19, 0x2e ; 46 |
ori tmp1, 0x07 ; feed Timer1 |
fac: 37 60 ori r19, 0x07 ; 7 |
out _SFR_IO_ADDR(TCCR1B),tmp1 |
fae: 3e bd out 0x2e, r19 ; 46 |
nop |
fb0: 00 00 nop |
|
in tmp1, _SFR_IO_ADDR(TIMSK) ; enable TIMER1 to start counting |
fb2: 39 b7 in r19, 0x39 ; 57 |
ori tmp1, ENABLE_PCLK_TIMER1_OVERFLOW_BITMASK ; external PCLK pulses and interrupt on |
fb4: 34 60 ori r19, 0x04 ; 4 |
out _SFR_IO_ADDR(TIMSK),tmp1 ; overflow |
fb6: 39 bf out 0x39, r19 ; 57 |
|
in tmp1, _SFR_IO_ADDR(GICR) ; enable the HREF interrupt...remember, we |
fb8: 3b b7 in r19, 0x3b ; 59 |
; only use this interrupt to synchronize |
; the beginning of the line |
ori tmp1, HREF_INTERRUPT_ENABLE_MASK |
fba: 30 68 ori r19, 0x80 ; 128 |
out _SFR_IO_ADDR(GICR), tmp1 |
fbc: 3b bf out 0x3b, r19 ; 59 |
|
00000fbe <_dumpFrame>: |
|
;******************************************************************************************* |
; Dump Frame handler |
;******************************************************************************************* |
|
_dumpFrame: |
sbi _SFR_IO_ADDR(PORTD),PD6 |
fbe: 96 9a sbi 0x12, 6 ; 18 |
sleep ; ...And we wait... |
fc0: 88 95 sleep |
|
cbi _SFR_IO_ADDR(PORTD),PD6 |
fc2: 96 98 cbi 0x12, 6 ; 18 |
in tmp1, _SFR_IO_ADDR(GICR) ; disable the HREF interrupt |
fc4: 3b b7 in r19, 0x3b ; 59 |
andi tmp1, HREF_INTERRUPT_DISABLE_MASK ; so we don't get interrupted |
fc6: 3f 77 andi r19, 0x7F ; 127 |
out _SFR_IO_ADDR(GICR), tmp1 ; while dumping the line |
fc8: 3b bf out 0x3b, r19 ; 59 |
... |
|
00000fcc <_sampleDumpPixel>: |
|
nop ; Remember...if we ever remove the "cbi" instruction above, |
; we need to add two more NOPs to cover this |
|
; Ok...the following loop needs to run in 8 clock cycles, so we can get every |
; pixel in the line...this shouldn't be a problem, since the PCLK timing was |
; reduced by a factor of 2 whenever we go to dump a line (this is to give us |
; enough time to do the sampling and storing of the pixel data). In addition, |
; it is assumed that we will have to do some minor processing on the data right |
; before we send it out, like mask off the top 4-bits of each, and then pack both |
; low nibbles into a single byte for transmission...we just don't have time to |
; do that here (only 8 instruction cycles :-) ) |
_sampleDumpPixel: |
in tmp1,G_PORT ; sample the G value (1) |
fcc: 33 b3 in r19, 0x13 ; 19 |
in tmp2,RB_PORT ; sample the R/B value (1) |
fce: 46 b3 in r20, 0x16 ; 22 |
st X+,tmp1 ; store to the currLineBuff and inc ptrs(2) |
fd0: 3d 93 st X+, r19 |
st Y+,tmp2 ; store to the prevLineBuff and inc ptrs(2) |
fd2: 49 93 st Y+, r20 |
brtc _sampleDumpPixel ; loop back unless flag is set (2...if not set) |
fd4: de f7 brtc .-10 ; 0xfcc |
; ___________ |
; 8 cycles normally |
|
; if we make it here, it means the T flag is set, and we must have been interrupted |
; so we need to exit (what if we were interrupted for serial? should we disable it?) |
rjmp _cleanUpDumpLine |
fd6: d6 cf rjmp .-84 ; 0xf84 |
|
00000fd8 <__vector_1>: |
|
;*********************************************************** |
; Function Name: <interrupt handler for External Interrupt0> |
; Function Description: This function is responsible |
; for handling a rising edge on the Ext Interrupt 0. This |
; routine simply returns, since we just want to wake up |
; whenever the VSYNC transitions (meaning the start of a new |
; frame). |
; Inputs: none |
; Outputs: none |
;*********************************************************** |
SIG_INTERRUPT0: |
; This will wake us up when VSYNC transitions high...we just want to return |
reti |
fd8: 18 95 reti |
|
00000fda <__vector_2>: |
|
;*********************************************************** |
; Function Name: <interrupt handler for External Interrupt1> |
; Function Description: This function is responsible |
; for handling a falling edge on the Ext Interrupt 1. This |
; routine simply returns, since we just want to wake up |
; whenever the HREF transitions (meaning the pixels |
; are starting after VSYNC transitioned, and we need to |
; start acquiring the pixel blocks |
; Inputs: none |
; Outputs: none |
;*********************************************************** |
SIG_INTERRUPT1: |
; This will wake us up when HREF transitions high...we just want to return |
reti |
fda: 18 95 reti |
|
00000fdc <__vector_8>: |
|
;*********************************************************** |
; Function Name: <interrupt handler for Timer0 overflow> |
; Function Description: This function is responsible |
; for handling the Timer0 overflow (hooked up to indicate |
; when we have reached the number of HREFs required in a |
; single frame). We set the T flag in the SREG to |
; indicate to the _acquirePixelBlock routine that it needs |
; to exit, and then set the appropriate action to take in |
; the eventList of the Executive module. |
; Inputs: none |
; Outputs: none |
; Note: Originally, the HREF pulses were also going to |
; be counted by a hardware counter, but it didn't end up |
; being necessary |
;*********************************************************** |
;SIG_OVERFLOW0: |
; set ; set the T bit in SREG |
; lds tmp1,eventBitmask |
; ori tmp1,EV_ACQUIRE_FRAME_COMPLETE |
; sts eventBitmask,tmp1 |
; reti |
|
;*********************************************************** |
; Function Name: <interrupt handler for Timer1 overflow> |
; Function Description: This function is responsible |
; for handling the Timer1 overflow (hooked up to indicate |
; when we have reached the end of a line of pixel data, |
; since PCLK is hooked up to overflow TCNT1 after 176 |
; pixels). This routine generates an acquire line complete |
; event in the fastEventBitmask, which is streamlined for |
; efficiency reasons. |
;*********************************************************** |
SIG_OVERFLOW1: |
lds tmp1,fastEventBitmask ; set a flag indicating |
fdc: 30 91 72 00 lds r19, 0x0072 |
ori tmp1,FEV_ACQUIRE_LINE_COMPLETE ; a line is complete |
fe0: 31 60 ori r19, 0x01 ; 1 |
sts fastEventBitmask,tmp1 |
fe2: 30 93 72 00 sts 0x0072, r19 |
set ; set the T bit in SREG |
fe6: 68 94 set |
;sbi _SFR_IO_ADDR(PORTD),PD6 ; For testing... |
;cbi _SFR_IO_ADDR(PORTD),PD6 ; For testing... |
|
reti |
fe8: 18 95 reti |
|
00000fea <__vector_default>: |
|
; This is the default handler for all interrupts that don't |
; have handler routines specified for them. |
.global __vector_default |
__vector_default: |
reti |
fea: 18 95 reti |
|
00000fec <atoi>: |
fec: fc 01 movw r30, r24 |
fee: 88 27 eor r24, r24 |
ff0: 99 27 eor r25, r25 |
ff2: e8 94 clt |
|
00000ff4 <.atoi_loop>: |
ff4: 21 91 ld r18, Z+ |
ff6: 22 23 and r18, r18 |
ff8: e9 f0 breq .+58 ; 0x1034 |
ffa: 20 32 cpi r18, 0x20 ; 32 |
ffc: d9 f3 breq .-10 ; 0xff4 |
ffe: 29 30 cpi r18, 0x09 ; 9 |
1000: c9 f3 breq .-14 ; 0xff4 |
1002: 2a 30 cpi r18, 0x0A ; 10 |
1004: b9 f3 breq .-18 ; 0xff4 |
1006: 2c 30 cpi r18, 0x0C ; 12 |
1008: a9 f3 breq .-22 ; 0xff4 |
100a: 2d 30 cpi r18, 0x0D ; 13 |
100c: 99 f3 breq .-26 ; 0xff4 |
100e: 26 37 cpi r18, 0x76 ; 118 |
1010: 89 f3 breq .-30 ; 0xff4 |
1012: 2b 32 cpi r18, 0x2B ; 43 |
1014: 19 f0 breq .+6 ; 0x101c |
1016: 2d 32 cpi r18, 0x2D ; 45 |
1018: 21 f4 brne .+8 ; 0x1022 |
|
0000101a <.atoi_neg>: |
101a: 68 94 set |
|
0000101c <.atoi_loop2>: |
101c: 21 91 ld r18, Z+ |
101e: 22 23 and r18, r18 |
1020: 49 f0 breq .+18 ; 0x1034 |
|
00001022 <.atoi_digit>: |
1022: 20 33 cpi r18, 0x30 ; 48 |
1024: 3c f0 brlt .+14 ; 0x1034 |
1026: 2a 33 cpi r18, 0x3A ; 58 |
1028: 2c f4 brge .+10 ; 0x1034 |
102a: 20 53 subi r18, 0x30 ; 48 |
102c: 2f d0 rcall .+94 ; 0x108c |
102e: 82 0f add r24, r18 |
1030: 91 1d adc r25, r1 |
1032: f4 cf rjmp .-24 ; 0x101c |
|
00001034 <.atoi_sig>: |
1034: 81 15 cp r24, r1 |
1036: 91 05 cpc r25, r1 |
1038: 21 f0 breq .+8 ; 0x1042 |
103a: 1e f4 brtc .+6 ; 0x1042 |
103c: 80 95 com r24 |
103e: 90 95 com r25 |
1040: 01 96 adiw r24, 0x01 ; 1 |
|
00001042 <.atoi_done>: |
1042: 08 95 ret |
|
00001044 <eeprom_read_byte>: |
1044: e1 99 sbic 0x1c, 1 ; 28 |
1046: fe cf rjmp .-4 ; 0x1044 |
1048: 9f bb out 0x1f, r25 ; 31 |
104a: 8e bb out 0x1e, r24 ; 30 |
104c: e0 9a sbi 0x1c, 0 ; 28 |
104e: 99 27 eor r25, r25 |
1050: 8d b3 in r24, 0x1d ; 29 |
1052: 08 95 ret |
|
00001054 <eeprom_read_block>: |
1054: 41 15 cp r20, r1 |
1056: 51 05 cpc r21, r1 |
1058: 69 f0 breq .+26 ; 0x1074 |
105a: dc 01 movw r26, r24 |
|
0000105c <eeprom_read_block_busy>: |
105c: e1 99 sbic 0x1c, 1 ; 28 |
105e: fe cf rjmp .-4 ; 0x105c |
|
00001060 <eeprom_read_block_loop>: |
1060: 7f bb out 0x1f, r23 ; 31 |
1062: 6e bb out 0x1e, r22 ; 30 |
1064: e0 9a sbi 0x1c, 0 ; 28 |
1066: 6f 5f subi r22, 0xFF ; 255 |
1068: 7f 4f sbci r23, 0xFF ; 255 |
106a: 0d b2 in r0, 0x1d ; 29 |
106c: 0d 92 st X+, r0 |
106e: 41 50 subi r20, 0x01 ; 1 |
1070: 50 40 sbci r21, 0x00 ; 0 |
1072: b1 f7 brne .-20 ; 0x1060 |
|
00001074 <eeprom_read_block_done>: |
1074: 08 95 ret |
|
00001076 <eeprom_write_byte>: |
1076: e1 99 sbic 0x1c, 1 ; 28 |
1078: fe cf rjmp .-4 ; 0x1076 |
107a: 9f bb out 0x1f, r25 ; 31 |
107c: 8e bb out 0x1e, r24 ; 30 |
107e: 6d bb out 0x1d, r22 ; 29 |
1080: 0f b6 in r0, 0x3f ; 63 |
1082: f8 94 cli |
1084: e2 9a sbi 0x1c, 2 ; 28 |
1086: e1 9a sbi 0x1c, 1 ; 28 |
1088: 0f be out 0x3f, r0 ; 63 |
108a: 08 95 ret |
|
0000108c <__mulhi_const_10>: |
108c: 7a e0 ldi r23, 0x0A ; 10 |
108e: 97 9f mul r25, r23 |
1090: 90 2d mov r25, r0 |
1092: 87 9f mul r24, r23 |
1094: 80 2d mov r24, r0 |
1096: 91 0d add r25, r1 |
1098: 11 24 eor r1, r1 |
109a: 08 95 ret |
|
0000109c <_exit>: |
109c: ff cf rjmp .-2 ; 0x109c |