Subversion Repositories svnkaklik

Rev

Blame | Last modification | View Log | Download


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