View Single Post
  #1   Spotlight this post!  
Unread 30-03-2004, 16:58
omega's Avatar
omega omega is offline
Registered User
#1352
 
Join Date: Mar 2004
Location: Stratford Northwestern
Posts: 11
omega is an unknown quantity at this point
Exclamation heres the code. y this not working

Code:
/*******************************************************************************
* FILE NAME: ifi_startup.c
*
* DESCRIPTION:
*  This file contains important startup code.
*
* USAGE:
*  This file should not be modified at all by the user.
*
*  DO NOT MODIFY THIS FILE!
*******************************************************************************/

#include "ifi_default.h"

extern void Clear_Memory (void);
extern void main (void);

void _entry (void);     /* prototype for the startup function */
void _startup (void);
void _do_cinit (void);  /* prototype for the initialized data setup */

extern volatile near unsigned long short TBLPTR;
extern near unsigned FSR0;
extern near char FPFLAGS;
#define RND 6

#pragma code _entry_scn=RESET_VECTOR
void _entry (void)
{
_asm goto _startup _endasm

}

#pragma code _startup_scn
void _startup (void)
{
  _asm
    /* Initialize the stack pointer */
    lfsr 1, _stack lfsr 2, _stack clrf TBLPTRU, 0 /* 1st silicon doesn't do this on POR */
    bcf  FPFLAGS,RND,0 /* Initialize rounding flag for floating point libs */
    
    /* initialize the flash memory access configuration. this is harmless */
    /* for non-flash devices, so we do it on all parts. */
    bsf 0xa6, 7, 0
    bcf 0xa6, 6, 0
  _endasm 

loop:

 	Clear_Memory();              
  _do_cinit ();
  /* Call the user's main routine */
  main ();

  goto loop;
}                               /* end _startup() */

/* MPLAB-C18 initialized data memory support */
/* The linker will populate the _cinit table */
extern far rom struct
{
  unsigned short num_init;
  struct _init_entry
  {
    unsigned long from;
    unsigned long to;
    unsigned long size;
  }
  entries[];
}
_cinit;

#pragma code _cinit_scn
void
_do_cinit (void)
{
  /* we'll make the assumption in the following code that these statics
   * will be allocated into the same bank.
   */
  static short long prom;
  static unsigned short curr_byte;
  static unsigned short curr_entry;
  static short long data_ptr;

  /* Initialized data... */
  TBLPTR = (short long)&_cinit;
  _asm
    movlb data_ptr
    tblrdpostinc
    movf  TABLAT, 0, 0
    movwf curr_entry, 1
    tblrdpostinc
    movf  TABLAT, 0, 0
    movwf curr_entry+1, 1
  _endasm
    test:
  _asm
     bnz 3
    tstfsz curr_entry, 1
    bra 1
  _endasm
  goto done;
    /* Count down so we only have to look up the data in _cinit
     * once.
     *
     * At this point we know that TBLPTR points to the top of the current
     * entry in _cinit, so we can just start reading the from, to, and
     * size values.
     */
  _asm
  /* read the source address */
    tblrdpostinc
    movf  TABLAT, 0, 0
    movwf prom, 1
    tblrdpostinc
    movf  TABLAT, 0, 0
    movwf prom+1, 1
    tblrdpostinc
    movf  TABLAT, 0, 0
    movwf prom+2, 1
    /* skip a byte since it's stored as a 32bit int */
    tblrdpostinc
    /* read the destination address directly into FSR0 */
    tblrdpostinc
    movf  TABLAT, 0, 0
    movwf FSR0L, 0
    tblrdpostinc
    movf  TABLAT, 0, 0
    movwf FSR0H, 0
    /* skip two bytes since it's stored as a 32bit int */
    tblrdpostinc
    tblrdpostinc
    /* read the destination address directly into FSR0 */
    tblrdpostinc
    movf  TABLAT, 0, 0
    movwf curr_byte, 1
    tblrdpostinc
    movf  TABLAT, 0, 0
    movwf curr_byte+1, 1
    /* skip two bytes since it's stored as a 32bit int */
    tblrdpostinc
    tblrdpostinc
  _endasm  

  /* the table pointer now points to the next entry. Save it
   * off since we'll be using the table pointer to do the copying
   * for the entry.
   */
  data_ptr = TBLPTR;

  /* now assign the source address to the table pointer */
  TBLPTR = prom;

  /* do the copy loop */
  _asm
          /* determine if we have any more bytes to copy */
    movlb curr_byte
    movf  curr_byte, 1, 1
copy_loop:
    bnz 2 /* copy_one_byte */
    movf  curr_byte + 1, 1, 1
    bz 7  /* done_copying */

copy_one_byte:
    tblrdpostinc
    movf  TABLAT, 0, 0
    movwf POSTINC0, 0

    /* decrement byte counter */
    decf  curr_byte, 1, 1
    bc -8   /* copy_loop */
    decf  curr_byte + 1, 1, 1
    bra -7  /* copy_one_byte */

done_copying:
  _endasm
      /* restore the table pointer for the next entry */
  TBLPTR = data_ptr;
  /* next entry... */
  curr_entry--;
  goto test;
done:
;
}


/*******************************************************************************
* FILE NAME: ifi_utilities.c
*
* DESCRIPTION:
*  This file contains some useful functions that you can call in your program.
*
* USAGE:
*  The user should NOT modify this file, so that if a new version is released
*  by Innovation First then it can be easily replaced.
*  The user should add their own functions to either user_routines.c or another
*  custom file.
*
*******************************************************************************/

#include <usart.h>
#include <spi.h>
#include <adc.h>
#include <capture.h>
#include <timers.h>
#include <string.h>
#include <pwm.h>
#include "delays.h"       /*defined locally*/
#include "ifi_aliases.h"
#include "ifi_default.h"
#include "ifi_utilities.h"
#include "user_routines.h"

int             ifi_packet_num1 = 0;
int             ifi_last_packet1 = 0;
char            ifi_printfBufr[80];
unsigned char   *ptr;
unsigned char   ifi_count;
unsigned char   ifi_analog_channels;


/*******************************************************************************
* FUNCTION NAME: Wait4TXEmpty
* PURPOSE:       Wait for serial transmit buffer to be empty.
* CALLED FROM:   anywhere
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
/* Used when transmitting data serially.  It waits for each byte to finish.   */
void Wait4TXEmpty(void)
{
#ifndef _SIMULATOR
  while (!TXINTF)
  {
    continue;
  }
#endif
}


/*******************************************************************************
* FUNCTION NAME: PrintByte
* PURPOSE:       A simple way to print a byte of data to the serial port.
* CALLED FROM:   anywhere
* ARGUMENTS:     none
*     Argument       Type             IO   Description
*     --------       -------------    --   -----------
*     odata          unsigned char    I    byte of data to be transmitted
* RETURNS:       void
*******************************************************************************/
void PrintByte(unsigned char odata)
{
  Hex_output((unsigned char) odata);
  TXREG = 13;  /* a carriage return */
  Wait4TXEmpty();
}


/*******************************************************************************
* FUNCTION NAME: PrintWord
* PURPOSE:       A simple way to print a word of data to the serial port.
* CALLED FROM:   anywhere
* ARGUMENTS:     none
*     Argument       Type             IO   Description
*     --------       -------------    --   -----------
*     odata          unsigned int     I    word of data to be transmitted
* RETURNS:       void
*******************************************************************************/
void PrintWord(unsigned int odata)
{
  ptr = (unsigned char *) &odata;
  Hex_output(ptr[1]);
  Hex_output(ptr[0]);
  TXREG = 13;  /* add a carriage return */
  Wait4TXEmpty();
}


/*******************************************************************************
* FUNCTION NAME: PrintString
* PURPOSE:       Prints a string to the serial port.
* CALLED FROM:   anywhere
* ARGUMENTS:     none
*     Argument       Type             IO   Description
*     --------       -------------    --   -----------
*     bufr           pointer          I    word of data to be transmitted
* RETURNS:       void
*******************************************************************************/
void PrintString(char *bufr)
{
  static int len,I;
    
  strcpypgm2ram (ifi_printfBufr,(rom char *) bufr); /*Move from flash to ram*/
  len = (int) strlen((const char *)ifi_printfBufr);
  if (len > 80) len = 80;

  for (I=0;I<len;I++)
  {
    TXREG = ifi_printfBufr[i];
    Wait4TXEmpty();
  }
}


/*******************************************************************************
* FUNCTION NAME: DisplayBufr
* PURPOSE:       Print the entire transmit or receive buffer over the serial 
*                port for viewing in a terminal program on your PC.
* CALLED FROM:   anywhere
* ARGUMENTS:     
*     Argument       Type        IO   Description
*     --------       --------    --   -----------
*     *bufr          pointer     I    points to beginning of buffer to transmit
* RETURNS:       void
*******************************************************************************/
void DisplayBufr(unsigned char *bufr)
{   
  for (ifi_count=0;ifi_count<26;ifi_count++)
  {
    Hex_output((unsigned char) *bufr++);
  }
  TXREG = 13;  /* add a carriage return */
  Wait4TXEmpty();
}


/*******************************************************************************
* FUNCTION NAME: PacketNum_Check
* PURPOSE:       Print the packet number over the serial port if a packet gets
*                dropped.  Handy for seeing if you are dropping data.
* CALLED FROM:   anywhere
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
void PacketNum_Check(void)
{
  /*    to print only the 10th (packet num) byte*/
  ptr = (unsigned char *) &rxdata.packet_num;
  ifi_packet_num1 = (int) rxdata.packet_num;
  if (ifi_packet_num1 != ifi_last_packet1)
  {
    if (statusflag.FIRST_TIME == 1)
    {
      statusflag.FIRST_TIME = 0;
    }
    else
    {
      Hex_output((unsigned char) ifi_last_packet1);
      Hex_output((unsigned char) ifi_packet_num1);
      TXREG = 13;
      Wait4TXEmpty();
      
      statusflag.FIRST_TIME = 0;
    }
    ifi_last_packet1 = ifi_packet_num1;
  }/*   if (ifi_packet_num1 != ifi_last_packet1)*/
  ifi_last_packet1++;
  if (ifi_last_packet1 > 255)
  { 
    ifi_last_packet1 = 0;
  }
}


/*******************************************************************************
* FUNCTION NAME: Initialize_Serial_Comms
* PURPOSE:       Opens the serial port 1 for communicating with your PC at
*                115k baud, 8 bits, no parity, one stop bit, and no flow control.
* CALLED FROM:   user_routines.c
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
void Initialize_Serial_Comms (void)
{
  OpenUSART(USART_TX_INT_OFF &
    USART_RX_INT_OFF &
    USART_ASYNCH_MODE &
    USART_EIGHT_BIT &
    USART_CONT_RX &
    USART_BRGH_HIGH,
    baud_115);   

  Delay1KTCYx( 50 ); /* Settling time */
}


/*******************************************************************************
* FUNCTION NAME: Set_Number_of_Analog_Channels
* PURPOSE:       Sets the variable used in Get_Analog_Value routine (below)
*                to the number of analog channels desired by the user.
* CALLED FROM:   user_routines.c initialization, typically
* ARGUMENTS:     
*      Argument            Type    IO   Description
*     -----------          -----   --   -----------
*     number_of_channels   alias   I    choose alias from ifi_aliases.h
* RETURNS:       void
*******************************************************************************/
void Set_Number_of_Analog_Channels (unsigned char number_of_channels)
{
  ifi_analog_channels = number_of_channels;
}


/*******************************************************************************
* FUNCTION NAME: Get_Analog_Value
* PURPOSE:       Reads the analog voltage on an A/D port and returns the
*                10-bit value read stored in an unsigned int.
* CALLED FROM:   user_routines.c, typically
* ARGUMENTS:     
*      Argument         Type        IO   Description
*     -----------   -------------   --   -----------
*     ADC_channel       alias       I    alias found in ifi_aliases.h
* RETURNS:       unsigned int
*******************************************************************************/
unsigned int Get_Analog_Value (unsigned char ADC_channel)
{
  unsigned int result;

  OpenADC( ADC_FOSC_RC & ADC_RIGHT_JUST & ifi_analog_channels,
          ADC_channel & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS );
  Delay10TCYx( 10 );
  ConvertADC();
  while( BusyADC() );
  ReadADC();
  CloseADC();
  result = (int) ADRESH << 8 | ADRESL;
  return result;
}


/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

/*******************************************************************************
* FILE NAME: user_routines_fast.c
*
* DESCRIPTION:
*  This file is where the user can add their custom code within the framework
*  of the routines below. 
*
* USAGE:
*  You can either modify this file to fit your needs, or remove it from your 
*  project and replace it with a modified copy. 
*
* OPTIONS:  Interrupts are disabled and not used by default.
*******************************************************************************/

#include "ifi_aliases.h"
#include "ifi_default.h"
#include "ifi_utilities.h"
#include "user_routines.h"
#include "receiver.h"
#include "tracker.h"
#include "navigate.h"


/*** DEFINE USER VARIABLES AND INITIALIZE THEM HERE ***/


/*******************************************************************************
* FUNCTION NAME: InterruptVectorLow
* PURPOSE:       Low priority interrupt vector
* CALLED FROM:   nowhere by default
* ARGUMENTS:     none
* RETURNS:       void
* DO NOT MODIFY OR DELETE THIS FUNCTION 
*******************************************************************************/
#pragma code InterruptVectorLow = LOW_INT_VECTOR
void InterruptVectorLow (void)
{
  _asm
    goto InterruptHandlerLow  /*jump to interrupt routine*/
  _endasm
}


/*******************************************************************************
* FUNCTION NAME: InterruptHandlerLow
* PURPOSE:       Low priority interrupt handler
* If you want to use these external low priority interrupts or any of the
* peripheral interrupts then you must enable them in your initialization
* routine.  Innovation First, Inc. will not provide support for using these
* interrupts, so be careful.  There is great potential for glitchy code if good
* interrupt programming practices are not followed.  Especially read p. 28 of
* the "MPLAB(R) C18 C Compiler User's Guide" for information on context saving.
* CALLED FROM:   this file, InterruptVectorLow routine
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
#pragma code
#pragma interruptlow InterruptHandlerLow

void InterruptHandlerLow ()     
{                               
	unsigned char Port_B;
	unsigned char Port_B_Delta;       
	static unsigned char Old_Port_B = 0xFF; // state of port b the last time
											// this function was called  
	
	if (INTCONbits.TMR0IF) // timer 0 Interrupt
	{
		INTCONbits.TMR0IF = 0; // clear the interrupt flag
		// if used, call the timer 0 interrupt handler here
	}

	else if (PIR1bits.TMR1IF) // timer 1 interrupt - used by the IR receiver
	{
		PIR1bits.TMR1IF = 0; // clear the interrupt flag
	Timer_1_Int_Handler(); // call the timer 1 interrupt handler (in receiver.c)
	}  

	else if (INTCON3bits.INT2IF) // external interrupt 1 - used by IR sensor 1
	{ 
		INTCON3bits.INT2IF = 0; // clear the interrupt flag
		Int_1_Handler(); // call the IR sensor 1 interrupt handler (in receiver.c)
	}

	else if (INTCON3bits.INT3IF) // external interrupt 2 - used by IR sensor 2
	{
		INTCON3bits.INT3IF = 0; // clear the interrupt flag
		Int_2_Handler(); // call the IR sensor 2 interrupt handler (in receiver.c)
	}

	else if (INTCONbits.RBIF) // external interrupts 3 through 6
	{
		Port_B = PORTB; // remove the "mismatch condition" by reading port b            
		INTCONbits.RBIF = 0; // clear the interrupt flag
		Port_B_Delta = Port_B ^ Old_Port_B; // determine which bits have changed
		Old_Port_B = Port_B; // save a copy of port b for next time around
	 
		if(Port_B_Delta & 0x10) // did external interrupt 3 change state?
		{
			// if used, call the interrupt 3 handler here
		}

		if(Port_B_Delta & 0x20) // did external interrupt 4 change state? - IR sensor 3
		{
			Int_4_Handler(Port_B & 0x20 ? 1 : 0); // call the interrupt 4 handler (in receiver.c)
		}

		if(Port_B_Delta & 0x40) // did external interrupt 5 change state? - IR sensor 4
		{
			Int_5_Handler(Port_B & 0x40 ? 1 : 0); // call the interrupt 5 handler (in receiver.c)
		}
		
		if(Port_B_Delta & 0x80) // did external interrupt 6 change state?
		{
			// if used, call the interrupt 6 handler here
		}
	}
}


/*******************************************************************************
* FUNCTION NAME: User_Autonomous_Code
* PURPOSE:       Execute user's code during autonomous robot operation.
* You should modify this routine by adding code which you wish to run in
* autonomous mode.  It will be executed every program loop, and not
* wait for or use any data from the Operator Interface.
* CALLED FROM:   main.c file, main() routine when in Autonomous mode
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
void User_Autonomous_Code(void)
{
  while (autonomous_mode)   /* DO NOT CHANGE! */
  {
    if (statusflag.NEW_SPI_DATA)      /* 26.2ms loop area */
    {
        Getdata(&rxdata);   /* DO NOT DELETE, or you will be stuck here forever! */

        /* Add your own autonomous code here. */

			Navigate();			

			if(rc_dig_in01 ==1 )
		 		{
				pwm13 = 137;
				pwm14=100;
				}
  			else
				{
				pwm13 = pwm14 = 140;
				}
			if(rc_dig_in02 == 1)
				{
				pwm13 = 100;
				pwm14 = 137;
				}
			else
				{
				pwm13 = pwm14 = 140;
				}
				
			Generate_Pwms(pwm13,pwm14,pwm15,pwm16);

        Putdata(&txdata);   /* DO NOT DELETE, or you will get no PWM outputs! */
    }
  }
}


/*******************************************************************************
* FUNCTION NAME: Process_Data_From_Local_IO
* PURPOSE:       Execute user's realtime code.
* You should modify this routine by adding code which you wish to run fast.
* It will be executed every program loop, and not wait for fresh data 
* from the Operator Interface.
* CALLED FROM:   main.c
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
void Process_Data_From_Local_IO(void)
{
  /* Add code here that you want to be executed every program loop. */

}


/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
/*******************************************************************************
* FILE NAME: user_routines_fast.c
*
* DESCRIPTION:
*  This file is where the user can add their custom code within the framework
*  of the routines below. 
*
* USAGE:
*  You can either modify this file to fit your needs, or remove it from your 
*  project and replace it with a modified copy. 
*
* OPTIONS:  Interrupts are disabled and not used by default.
*******************************************************************************/

#include "ifi_aliases.h"
#include "ifi_default.h"
#include "ifi_utilities.h"
#include "user_routines.h"
#include "receiver.h"
#include "tracker.h"
#include "navigate.h"


/*** DEFINE USER VARIABLES AND INITIALIZE THEM HERE ***/


/*******************************************************************************
* FUNCTION NAME: InterruptVectorLow
* PURPOSE:       Low priority interrupt vector
* CALLED FROM:   nowhere by default
* ARGUMENTS:     none
* RETURNS:       void
* DO NOT MODIFY OR DELETE THIS FUNCTION 
*******************************************************************************/
#pragma code InterruptVectorLow = LOW_INT_VECTOR
void InterruptVectorLow (void)
{
  _asm
    goto InterruptHandlerLow  /*jump to interrupt routine*/
  _endasm
}


/*******************************************************************************
* FUNCTION NAME: InterruptHandlerLow
* PURPOSE:       Low priority interrupt handler
* If you want to use these external low priority interrupts or any of the
* peripheral interrupts then you must enable them in your initialization
* routine.  Innovation First, Inc. will not provide support for using these
* interrupts, so be careful.  There is great potential for glitchy code if good
* interrupt programming practices are not followed.  Especially read p. 28 of
* the "MPLAB(R) C18 C Compiler User's Guide" for information on context saving.
* CALLED FROM:   this file, InterruptVectorLow routine
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
#pragma code
#pragma interruptlow InterruptHandlerLow

void InterruptHandlerLow ()     
{                               
	unsigned char Port_B;
	unsigned char Port_B_Delta;       
	static unsigned char Old_Port_B = 0xFF; // state of port b the last time
											// this function was called  
	
	if (INTCONbits.TMR0IF) // timer 0 Interrupt
	{
		INTCONbits.TMR0IF = 0; // clear the interrupt flag
		// if used, call the timer 0 interrupt handler here
	}

	else if (PIR1bits.TMR1IF) // timer 1 interrupt - used by the IR receiver
	{
		PIR1bits.TMR1IF = 0; // clear the interrupt flag
	Timer_1_Int_Handler(); // call the timer 1 interrupt handler (in receiver.c)
	}  

	else if (INTCON3bits.INT2IF) // external interrupt 1 - used by IR sensor 1
	{ 
		INTCON3bits.INT2IF = 0; // clear the interrupt flag
		Int_1_Handler(); // call the IR sensor 1 interrupt handler (in receiver.c)
	}

	else if (INTCON3bits.INT3IF) // external interrupt 2 - used by IR sensor 2
	{
		INTCON3bits.INT3IF = 0; // clear the interrupt flag
		Int_2_Handler(); // call the IR sensor 2 interrupt handler (in receiver.c)
	}

	else if (INTCONbits.RBIF) // external interrupts 3 through 6
	{
		Port_B = PORTB; // remove the "mismatch condition" by reading port b            
		INTCONbits.RBIF = 0; // clear the interrupt flag
		Port_B_Delta = Port_B ^ Old_Port_B; // determine which bits have changed
		Old_Port_B = Port_B; // save a copy of port b for next time around
	 
		if(Port_B_Delta & 0x10) // did external interrupt 3 change state?
		{
			// if used, call the interrupt 3 handler here
		}

		if(Port_B_Delta & 0x20) // did external interrupt 4 change state? - IR sensor 3
		{
			Int_4_Handler(Port_B & 0x20 ? 1 : 0); // call the interrupt 4 handler (in receiver.c)
		}

		if(Port_B_Delta & 0x40) // did external interrupt 5 change state? - IR sensor 4
		{
			Int_5_Handler(Port_B & 0x40 ? 1 : 0); // call the interrupt 5 handler (in receiver.c)
		}
		
		if(Port_B_Delta & 0x80) // did external interrupt 6 change state?
		{
			// if used, call the interrupt 6 handler here
		}
	}
}


/*******************************************************************************
* FUNCTION NAME: User_Autonomous_Code
* PURPOSE:       Execute user's code during autonomous robot operation.
* You should modify this routine by adding code which you wish to run in
* autonomous mode.  It will be executed every program loop, and not
* wait for or use any data from the Operator Interface.
* CALLED FROM:   main.c file, main() routine when in Autonomous mode
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
void User_Autonomous_Code(void)
{
  while (autonomous_mode)   /* DO NOT CHANGE! */
  {
    if (statusflag.NEW_SPI_DATA)      /* 26.2ms loop area */
    {
        Getdata(&rxdata);   /* DO NOT DELETE, or you will be stuck here forever! */

        /* Add your own autonomous code here. */

			Navigate();			

			if(rc_dig_in01 ==1 )
		 		{
				pwm13 = 137;
				pwm14=100;
				}
  			else
				{
				pwm13 = pwm14 = 140;
				}
			if(rc_dig_in02 == 1)
				{
				pwm13 = 100;
				pwm14 = 137;
				}
			else
				{
				pwm13 = pwm14 = 140;
				}
				
			Generate_Pwms(pwm13,pwm14,pwm15,pwm16);

        Putdata(&txdata);   /* DO NOT DELETE, or you will get no PWM outputs! */
    }
  }
}


/*******************************************************************************
* FUNCTION NAME: Process_Data_From_Local_IO
* PURPOSE:       Execute user's realtime code.
* You should modify this routine by adding code which you wish to run fast.
* It will be executed every program loop, and not wait for fresh data 
* from the Operator Interface.
* CALLED FROM:   main.c
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
void Process_Data_From_Local_IO(void)
{
  /* Add code here that you want to be executed every program loop. */

}


/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

/*******************************************************************************
* FILE NAME: main.c <FRC VERSION>
*
* DESCRIPTION:
*  This file contains the main program loop.
*
* USAGE:
*  You should not need to modify this file.
*  Note the different loop speed for the two routines:
*     Process_Data_From_Master_uP
*     Process_Data_From_Local_IO
*******************************************************************************/

#include "ifi_aliases.h"
#include "ifi_default.h"
#include "ifi_utilities.h"
#include "user_routines.h"

tx_data_record txdata;          /* DO NOT CHANGE! */
rx_data_record rxdata;          /* DO NOT CHANGE! */
packed_struct statusflag;       /* DO NOT CHANGE! */

/*******************************************************************************
* FUNCTION NAME: main
* PURPOSE:       Main program loop.
* CALLED FROM:   ifi_startup.c
* ARGUMENTS:     none
* RETURNS:       void
* DO NOT DELETE THIS FUNCTION 
*******************************************************************************/
void main (void)
{
#ifdef UNCHANGEABLE_DEFINITION_AREA
  IFI_Initialization ();        /* DO NOT CHANGE! */
#endif

  User_Initialization();        /* You edit this in user_routines.c */

  statusflag.NEW_SPI_DATA = 0;  /* DO NOT CHANGE! */ 

  while (1)   /* This loop will repeat indefinitely. */
  {
#ifdef _SIMULATOR
    statusflag.NEW_SPI_DATA = 1;
#endif

    if (statusflag.NEW_SPI_DATA)      /* 26.2ms loop area */
    {                                 /* I'm slow!  I only execute every 26.2ms because that's */
                                      /* how fast the Master uP gives me data. */
      Process_Data_From_Master_uP();  /* You edit this in user_routines.c */

      if (autonomous_mode)            /* DO NOT CHANGE! */
      {
        User_Autonomous_Code();        /* You edit this in user_routines_fast.c */
      }
    }
    Process_Data_From_Local_IO();     /* You edit this in user_routines_fast.c */
                                      /* I'm fast!  I execute during every loop.*/
  } /* while (1) */
}  /* END of Main */


/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

/*******************************************************************************
* FILE NAME: printf_lib.c
*
* DESCRIPTION:
*  This file contains generic routines that work like the standard C I/O library.
*  These unsupported routines have been modified to work with the Microchip 
*  C compiler.  The printf routine is limited as follows:
*
*  1.  Only the %s, %lx, %d, %x, %u, %X directives are parsed.  An additional %b 
*      directive is parsed for those who like to view data in binary (base 2).
*
*      Examples:   
*
*            rom const char *StrPtr = "Hello world!";
*            int x = 15;
*            int y = 0x50;
*            long z = 0xdeadface;
*
*            printf("%s\n",StrPtr);                         will display 'Hello world!'
*                                  
*            printf("X = %d, Y = %x, Z = %lx\n",x,y,z);     will display 'X = 15, Y = 0x50, Z = deadface'
*                                                      
*            printf("X = %b (base 2)\n",x);                 will display 'X = 1111 (base 2)'
*                   
*            printf("X = %16b\n",x);                        will display 'X = 0000000000001111'
*                           
*            printf("X = %04x\n",x);                        will display 'X = 000f'
*                           
*  2.  All bytes (8 bits) or bit references (rc_dig_in01) must be type-cast to a  
*      16 bit word.  The %c directive is unsupported.
*
*      Examples:   
*
*            unsigned char byte1 = 0xfa;
*            char byte2 = 25;
*
*            printf("1st byte = %x, 2nd byte = %d\n",(int)byte1,(int)byte2);
*                                                           will display '1st byte = fa, 2nd byte = 25
*            if (rc_dig_in01)
*              printf("On %d\n",(int)rc_dig_in01);          will display 'On 1'
*            else
*              printf("Off %d\n",(int)rc_dig_in01);         will display 'Off 0'
*
*  3.  The %s directive only supports a string of 40 bytes and the format string
*      may not exceed 80 bytes.  The sprintf routine is not included.  Keep in 
*      mind that the stack size has a 256 byte limit.
*
* USAGE:
*  These library routines  may be modified to suit the needs of the user.
*******************************************************************************/

#include "ifi_default.h"
#include "printf_lib.h"
#include "ifi_utilities.h"
#include "string.h"

/* the following should be enough for a 32 bit word */
#define PRINT_BUF_LEN 20

extern char ifi_printfBufr[]; /* declared in ifi_utilities.c */
rom char *nullStr = "(null)";

static char print_buf[PRINT_BUF_LEN];
static char scr[2];
static int  k;

/*******************************************************************************
* SUBROUTINE NAME: Write_Byte_To_Uart
* PURPOSE:       Writes a byte to the UART.
*     Argument       Type           IO   Description
*     --------       -----------    --   -----------
*         data       int            I    data to transmit to the UART
* RETURNS:       void
*******************************************************************************/

static void Write_Byte_To_Uart(int data)
{
  TXREG = data;  /* a carriage return */
  Wait4TXEmpty();
}

#define PAD_RIGHT 1
#define PAD_ZERO  2

/*******************************************************************************
* FUNCTION NAME: prints
* PURPOSE:       Pads the output stream.
* RETURNS:       void
*******************************************************************************/

static int prints(char *string, int width, int pad)
{
	register int pc = 0, padchar = ' ';

	if (width > 0) {
		register int len = 0;
		register char *ptr;
		for (ptr = string; *ptr; ++ptr) ++len;
		if (len >= width) width = 0;
		else width -= len;
		if (pad & PAD_ZERO) padchar = '0';
	}
	if (!(pad & PAD_RIGHT)) {
		for ( ; width > 0; --width) {
			Write_Byte_To_Uart (padchar);
			++pc;
		}
	}
	for ( ; *string ; ++string) {
		Write_Byte_To_Uart (*string);
		++pc;
	}
	for ( ; width > 0; --width) {
		Write_Byte_To_Uart (padchar);
		++pc;
	}

	return pc;
}

/*******************************************************************************
* FUNCTION NAME: printi
* PURPOSE:       Converts the output stream to the proper width and base.
* RETURNS:       void
*******************************************************************************/

static int printi(int i, int b, int sg, int width, int pad, int letbase)
{
	register char *s;
	register int t, neg = 0, pc = 0;
	register unsigned int u = i;

   print_buf[0] = 0xBE;
   print_buf[PRINT_BUF_LEN] = 0xEF;
	if (i == 0) {
		print_buf[0] = '0';
		print_buf[1] = '\0';
		return prints (print_buf, width, pad);
	}

	if (sg && b == 10 && i < 0) {
		neg = 1;
		u = -i;
	}

	s = print_buf + PRINT_BUF_LEN-1;
	*s = '\0';

	while (u) {
		t = u % b;
		if( t >= 10 )
			t += letbase - '0' - 10;
		*--s = t + '0';
		u /= b;
	}

	if (neg) {
		if( width && (pad & PAD_ZERO) ) {
			Write_Byte_To_Uart ('-');
			++pc;
			--width;
		}
		else {
			*--s = '-';
		}
	}

	return pc + prints (s, width, pad);
}

/*******************************************************************************
* FUNCTION NAME: print
* PURPOSE:       Parses the output stream.
* RETURNS:       void
*******************************************************************************/

static int print(char *format, int *varg)
{
  char tmpBufr[40];
	register int width, pad;
	register int pc = 0;

	for (; *format != 0; ++format) {
		if (*format == '%') {
			++format;
			width = pad = 0;
			if (*format == '\0') break;
			if (*format == '%') goto out;
			if (*format == '-') {
				++format;
				pad = PAD_RIGHT;
			}
			while (*format == '0') {
				++format;
				pad |= PAD_ZERO;
			}
			for ( ; *format >= '0' && *format <= '9'; ++format) {
				width *= 10;
				width += *format - '0';
			}
			if( *format == 's' ) 
      {
        strcpypgm2ram(tmpBufr,(rom char *) *varg--);
        if (tmpBufr[0] == 0)
          strcpypgm2ram(tmpBufr,nullStr);
				pc += prints (tmpBufr, width, pad);
				continue;
			}
			if( *format == 'd' ) {
				pc += printi (*varg--, 10, 1, width, pad, 'a');
				continue;
			}
			if( *format == 'x' ) {
				pc += printi (*varg--, 16, 0, width, pad, 'a');
				continue;
			}
			if( *format == 'X' ) {
				pc += printi (*varg--, 16, 0, width, pad, 'A');
				continue;
			}
			if( *format == 'u' ) {
				pc += printi (*varg--, 10, 0, width, pad, 'a');
				continue;
			}
			if( *format == 'l' ) {    /* assumes lx */
				pc += printi (*varg--, 16, 0, width, pad, 'a');
				pc += printi (*varg--, 16, 0, width, pad, 'a');
				format++;               /* skip over x*/
				continue;
			}
			if( *format == 'b' ) {
				pc += printi (*varg--, 2, 0, width, 2, 'a');
				continue;
			}
		}
		else {
		out:
      if (*format == '\n') *format = '\r';  /* replace line feed with cr */
			Write_Byte_To_Uart (*format);
			++pc;
		}
	}
	return pc;
}

/*******************************************************************************
* FUNCTION NAME: printf
* PURPOSE:       Formats an output stream.
* RETURNS:       void
*******************************************************************************/

int printf(rom const char *format, ...)
{
    register int *varg = (int *)(&format);
    /* 
       Since constant strings are kept in program (flash) memory, the strcpypgm2ram
       routine copies the string from flash to ram. 
    */
    strcpypgm2ram(ifi_printfBufr,(rom char *) format);

    varg--; /* adjust stack for Microchip C Compiler */
    return print(ifi_printfBufr, varg);
}

/******************************************************************************
* 
* The following routines are examples how to use the printf library routines
* to create your own output modules:
*  
*******************************************************************************/

/*******************************************************************************
* FUNCTION NAME: printid
* PURPOSE:       Prints a 16bit word (base 10) w/o a carriage return.
* RETURNS:       void
*******************************************************************************/

void printid(int data,int crtOn)
{
  printi (data, 10, 1, 4, 2, 'a');
  if (crtOn)
    Write_Byte_To_Uart('\r');
}

/*******************************************************************************
* FUNCTION NAME: printd
* PURPOSE:       Prints an 8bit word (base 10) w/o a carriage return.
* RETURNS:       void
*******************************************************************************/

void printd(unsigned char data,int crtOn)
{
  printi ((int) data, 10, 1, 3, 2, 'a');
  if (crtOn)
    Write_Byte_To_Uart('\r');
}

/*******************************************************************************
* FUNCTION NAME: printib
* PURPOSE:       Prints a 16bit binary word (base 2) w/o a carriage return.
* RETURNS:       void
*******************************************************************************/

void printib(unsigned int data,int crtOn)
{
  printi (data, 2, 0, 16, 2, 'a');
  if (crtOn)
    Write_Byte_To_Uart('\r');
}

/*******************************************************************************
* FUNCTION NAME: printb
* PURPOSE:       Prints an 8bit binary word (base 2) w/o a carriage return.
* RETURNS:       void
*******************************************************************************/

void printb(unsigned char data,int crtOn)
{
  printi ((int) data, 2, 0, 8, 2, 'a');
  if (crtOn)
    Write_Byte_To_Uart('\r');
}

/*******************************************************************************
* FUNCTION NAME: printix
* PURPOSE:       Prints a 16bit hex word (base 16) w/o a carriage return.
* RETURNS:       void
*******************************************************************************/

void printix(int data,int crtOn)
{
  printi (data, 16, 0, 2, 0, 'a');
  if (crtOn)
    Write_Byte_To_Uart('\r');
}

/*******************************************************************************
* FUNCTION NAME: printx
* PURPOSE:       Prints an 8bit hex word (base 16) w/o a carriage return.
* RETURNS:       void
*******************************************************************************/

void printx(unsigned char data,int crtOn)
{
  printi ((int) data, 16, 0, 2, 2, 'a');
  if (crtOn)
    Write_Byte_To_Uart('\r');
}

/*******************************************************************************
* FUNCTION NAME: debug_print
* PURPOSE:       Prints a header and a 16bit hex word (base 16) with a carriage 
*                return.
* RETURNS:       void
*******************************************************************************/

void debug_print(char *bufr,int data)
{
  strcpypgm2ram (ifi_printfBufr,(rom char *) bufr);
  for (k=0;k<strlen(ifi_printfBufr);k++)
    Write_Byte_To_Uart(ifi_printfBufr[k]);
  printix(data,1);
}

/*******************************************************************************
* FUNCTION NAME: debug_printb
* PURPOSE:       Prints a header and an 8bit binary word (base 2) with a carriage 
*                return.
* RETURNS:       void
*******************************************************************************/

void debug_printb(char *bufr,unsigned int data)
{
  strcpypgm2ram (ifi_printfBufr,(rom char *) bufr);
  for (k=0;k<strlen(ifi_printfBufr);k++)
    Write_Byte_To_Uart(ifi_printfBufr[k]);
  printib(data,1);
}

/*******************************************************************************
* FUNCTION NAME: debug_println
* PURPOSE:       Prints a header (assumming a carriage return is supplied).
* RETURNS:       void
*******************************************************************************/

void debug_println(char *bufr)
{
  strcpypgm2ram (ifi_printfBufr,(rom char *) bufr);
  for (k=0;k<strlen(ifi_printfBufr);k++)
    Write_Byte_To_Uart(ifi_printfBufr[k]);
}


/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

/*******************************************************************************
* FILE NAME: printf_lib.c
*
* DESCRIPTION:
*  This file contains generic routines that work like the standard C I/O library.
*  These unsupported routines have been modified to work with the Microchip 
*  C compiler.  The printf routine is limited as follows:
*
*  1.  Only the %s, %lx, %d, %x, %u, %X directives are parsed.  An additional %b 
*      directive is parsed for those who like to view data in binary (base 2).
*
*      Examples:   
*
*            rom const char *StrPtr = "Hello world!";
*            int x = 15;
*            int y = 0x50;
*            long z = 0xdeadface;
*
*            printf("%s\n",StrPtr);                         will display 'Hello world!'
*                                  
*            printf("X = %d, Y = %x, Z = %lx\n",x,y,z);     will display 'X = 15, Y = 0x50, Z = deadface'
*                                                      
*            printf("X = %b (base 2)\n",x);                 will display 'X = 1111 (base 2)'
*                   
*            printf("X = %16b\n",x);                        will display 'X = 0000000000001111'
*                           
*            printf("X = %04x\n",x);                        will display 'X = 000f'
*                           
*  2.  All bytes (8 bits) or bit references (rc_dig_in01) must be type-cast to a  
*      16 bit word.  The %c directive is unsupported.
*
*      Examples:   
*
*            unsigned char byte1 = 0xfa;
*            char byte2 = 25;
*
*            printf("1st byte = %x, 2nd byte = %d\n",(int)byte1,(int)byte2);
*                                                           will display '1st byte = fa, 2nd byte = 25
*            if (rc_dig_in01)
*              printf("On %d\n",(int)rc_dig_in01);          will display 'On 1'
*            else
*              printf("Off %d\n",(int)rc_dig_in01);         will display 'Off 0'
*
*  3.  The %s directive only supports a string of 40 bytes and the format string
*      may not exceed 80 bytes.  The sprintf routine is not included.  Keep in 
*      mind that the stack size has a 256 byte limit.
*
* USAGE:
*  These library routines  may be modified to suit the needs of the user.
*******************************************************************************/

#include "ifi_default.h"
#include "printf_lib.h"
#include "ifi_utilities.h"
#include "string.h"

/* the following should be enough for a 32 bit word */
#define PRINT_BUF_LEN 20

extern char ifi_printfBufr[]; /* declared in ifi_utilities.c */
rom char *nullStr = "(null)";

static char print_buf[PRINT_BUF_LEN];
static char scr[2];
static int  k;

/*******************************************************************************
* SUBROUTINE NAME: Write_Byte_To_Uart
* PURPOSE:       Writes a byte to the UART.
*     Argument       Type           IO   Description
*     --------       -----------    --   -----------
*         data       int            I    data to transmit to the UART
* RETURNS:       void
*******************************************************************************/

static void Write_Byte_To_Uart(int data)
{
  TXREG = data;  /* a carriage return */
  Wait4TXEmpty();
}

#define PAD_RIGHT 1
#define PAD_ZERO  2

/*******************************************************************************
* FUNCTION NAME: prints
* PURPOSE:       Pads the output stream.
* RETURNS:       void
*******************************************************************************/

static int prints(char *string, int width, int pad)
{
	register int pc = 0, padchar = ' ';

	if (width > 0) {
		register int len = 0;
		register char *ptr;
		for (ptr = string; *ptr; ++ptr) ++len;
		if (len >= width) width = 0;
		else width -= len;
		if (pad & PAD_ZERO) padchar = '0';
	}
	if (!(pad & PAD_RIGHT)) {
		for ( ; width > 0; --width) {
			Write_Byte_To_Uart (padchar);
			++pc;
		}
	}
	for ( ; *string ; ++string) {
		Write_Byte_To_Uart (*string);
		++pc;
	}
	for ( ; width > 0; --width) {
		Write_Byte_To_Uart (padchar);
		++pc;
	}

	return pc;
}

/*******************************************************************************
* FUNCTION NAME: printi
* PURPOSE:       Converts the output stream to the proper width and base.
* RETURNS:       void
*******************************************************************************/

static int printi(int i, int b, int sg, int width, int pad, int letbase)
{
	register char *s;
	register int t, neg = 0, pc = 0;
	register unsigned int u = i;

   print_buf[0] = 0xBE;
   print_buf[PRINT_BUF_LEN] = 0xEF;
	if (i == 0) {
		print_buf[0] = '0';
		print_buf[1] = '\0';
		return prints (print_buf, width, pad);
	}

	if (sg && b == 10 && i < 0) {
		neg = 1;
		u = -i;
	}

	s = print_buf + PRINT_BUF_LEN-1;
	*s = '\0';

	while (u) {
		t = u % b;
		if( t >= 10 )
			t += letbase - '0' - 10;
		*--s = t + '0';
		u /= b;
	}

	if (neg) {
		if( width && (pad & PAD_ZERO) ) {
			Write_Byte_To_Uart ('-');
			++pc;
			--width;
		}
		else {
			*--s = '-';
		}
	}

	return pc + prints (s, width, pad);
}

/*******************************************************************************
* FUNCTION NAME: print
* PURPOSE:       Parses the output stream.
* RETURNS:       void
*******************************************************************************/

static int print(char *format, int *varg)
{
  char tmpBufr[40];
	register int width, pad;
	register int pc = 0;

	for (; *format != 0; ++format) {
		if (*format == '%') {
			++format;
			width = pad = 0;
			if (*format == '\0') break;
			if (*format == '%') goto out;
			if (*format == '-') {
				++format;
				pad = PAD_RIGHT;
			}
			while (*format == '0') {
				++format;
				pad |= PAD_ZERO;
			}
			for ( ; *format >= '0' && *format <= '9'; ++format) {
				width *= 10;
				width += *format - '0';
			}
			if( *format == 's' ) 
      {
        strcpypgm2ram(tmpBufr,(rom char *) *varg--);
        if (tmpBufr[0] == 0)
          strcpypgm2ram(tmpBufr,nullStr);
				pc += prints (tmpBufr, width, pad);
				continue;
			}
			if( *format == 'd' ) {
				pc += printi (*varg--, 10, 1, width, pad, 'a');
				continue;
			}
			if( *format == 'x' ) {
				pc += printi (*varg--, 16, 0, width, pad, 'a');
				continue;
			}
			if( *format == 'X' ) {
				pc += printi (*varg--, 16, 0, width, pad, 'A');
				continue;
			}
			if( *format == 'u' ) {
				pc += printi (*varg--, 10, 0, width, pad, 'a');
				continue;
			}
			if( *format == 'l' ) {    /* assumes lx */
				pc += printi (*varg--, 16, 0, width, pad, 'a');
				pc += printi (*varg--, 16, 0, width, pad, 'a');
				format++;               /* skip over x*/
				continue;
			}
			if( *format == 'b' ) {
				pc += printi (*varg--, 2, 0, width, 2, 'a');
				continue;
			}
		}
		else {
		out:
      if (*format == '\n') *format = '\r';  /* replace line feed with cr */
			Write_Byte_To_Uart (*format);
			++pc;
		}
	}
	return pc;
}

/*******************************************************************************
* FUNCTION NAME: printf
* PURPOSE:       Formats an output stream.
* RETURNS:       void
*******************************************************************************/

int printf(rom const char *format, ...)
{
    register int *varg = (int *)(&format);
    /* 
       Since constant strings are kept in program (flash) memory, the strcpypgm2ram
       routine copies the string from flash to ram. 
    */
    strcpypgm2ram(ifi_printfBufr,(rom char *) format);

    varg--; /* adjust stack for Microchip C Compiler */
    return print(ifi_printfBufr, varg);
}

/******************************************************************************
* 
* The following routines are examples how to use the printf library routines
* to create your own output modules:
*  
*******************************************************************************/

/*******************************************************************************
* FUNCTION NAME: printid
* PURPOSE:       Prints a 16bit word (base 10) w/o a carriage return.
* RETURNS:       void
*******************************************************************************/

void printid(int data,int crtOn)
{
  printi (data, 10, 1, 4, 2, 'a');
  if (crtOn)
    Write_Byte_To_Uart('\r');
}

/*******************************************************************************
* FUNCTION NAME: printd
* PURPOSE:       Prints an 8bit word (base 10) w/o a carriage return.
* RETURNS:       void
*******************************************************************************/

void printd(unsigned char data,int crtOn)
{
  printi ((int) data, 10, 1, 3, 2, 'a');
  if (crtOn)
    Write_Byte_To_Uart('\r');
}

/*******************************************************************************
* FUNCTION NAME: printib
* PURPOSE:       Prints a 16bit binary word (base 2) w/o a carriage return.
* RETURNS:       void
*******************************************************************************/

void printib(unsigned int data,int crtOn)
{
  printi (data, 2, 0, 16, 2, 'a');
  if (crtOn)
    Write_Byte_To_Uart('\r');
}

/*******************************************************************************
* FUNCTION NAME: printb
* PURPOSE:       Prints an 8bit binary word (base 2) w/o a carriage return.
* RETURNS:       void
*******************************************************************************/

void printb(unsigned char data,int crtOn)
{
  printi ((int) data, 2, 0, 8, 2, 'a');
  if (crtOn)
    Write_Byte_To_Uart('\r');
}

/*******************************************************************************
* FUNCTION NAME: printix
* PURPOSE:       Prints a 16bit hex word (base 16) w/o a carriage return.
* RETURNS:       void
*******************************************************************************/

void printix(int data,int crtOn)
{
  printi (data, 16, 0, 2, 0, 'a');
  if (crtOn)
    Write_Byte_To_Uart('\r');
}

/*******************************************************************************
* FUNCTION NAME: printx
* PURPOSE:       Prints an 8bit hex word (base 16) w/o a carriage return.
* RETURNS:       void
*******************************************************************************/

void printx(unsigned char data,int crtOn)
{
  printi ((int) data, 16, 0, 2, 2, 'a');
  if (crtOn)
    Write_Byte_To_Uart('\r');
}

/*******************************************************************************
* FUNCTION NAME: debug_print
* PURPOSE:       Prints a header and a 16bit hex word (base 16) with a carriage 
*                return.
* RETURNS:       void
*******************************************************************************/

void debug_print(char *bufr,int data)
{
  strcpypgm2ram (ifi_printfBufr,(rom char *) bufr);
  for (k=0;k<strlen(ifi_printfBufr);k++)
    Write_Byte_To_Uart(ifi_printfBufr[k]);
  printix(data,1);
}

/*******************************************************************************
* FUNCTION NAME: debug_printb
* PURPOSE:       Prints a header and an 8bit binary word (base 2) with a carriage 
*                return.
* RETURNS:       void
*******************************************************************************/

void debug_printb(char *bufr,unsigned int data)
{
  strcpypgm2ram (ifi_printfBufr,(rom char *) bufr);
  for (k=0;k<strlen(ifi_printfBufr);k++)
    Write_Byte_To_Uart(ifi_printfBufr[k]);
  printib(data,1);
}

/*******************************************************************************
* FUNCTION NAME: debug_println
* PURPOSE:       Prints a header (assumming a carriage return is supplied).
* RETURNS:       void
*******************************************************************************/

void debug_println(char *bufr)
{
  strcpypgm2ram (ifi_printfBufr,(rom char *) bufr);
  for (k=0;k<strlen(ifi_printfBufr);k++)
    Write_Byte_To_Uart(ifi_printfBufr[k]);
}


/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

/*******************************************************************************
*
*	TITLE:		tracker.c 
*
*	VERSION:	1.0                           
*
*	DATE:		09-Jan-2004
*
*	AUTHOR:		R. Kevin Watson
*
*	COMMENTS:	This code assumes IR sensor 1 is the left sensor on the left tracker
*				         "        IR sensor 2 is the right sensor on the left tracker
*				         "        IR sensor 3 is the left sensor on the right tracker
*				         "        IR sensor 4 is the right sensor on the right tracker
*
*				         "        left IR beacon tracking servo motor is on PWM 1
*				         "        right IR beacon tracking servo motor is on PWM 2
*
*				         "        beacon type selector switch is on digital I/O 7
*
********************************************************************************
*
*	CHANGE LOG:
*
*	DATE         REV  DESCRIPTION
*	-----------  ---  ----------------------------------------------------------
*	03-Dec-2003  0.1  RKW Original
*	07-Dec-2003  0.2  RKW - Modified Track_Beacon() to handle an arbitrary number
*	                  of IR beam tracking assemblies. All state machine
*	                  information is now kept in the Tracker_Data data structure.
*	                  RKW - Cleaned-up Track_Beacon to make it understandable, 
*	                  hiding most of the tough-to-grasp code in tracker.h
*	09-Jan-2004  1.0  RKW - This version used for kick-off demo
*
*******************************************************************************/

#include "ifi_picdefs.h"
#include "ifi_default.h"
#include "ifi_aliases.h"
#include "printf_lib.h"
#include "user_routines.h"
#include "receiver.h"
#include "tracker.h"

Tracker_Data_Struct Tracker_Data[2]; // two trackers: left and right

/*******************************************************************************
*
*	FUNCTION:		Initialize_Tracker()
*
*	PURPOSE:		Initializes the infrared beacon tracker code.
*
*	CALLED FROM:	user_routines.c/User_Initialization()
*
*	PARAMETERS:		None
*
*	RETURNS:		Nothing
*
*	COMMENTS:		Adjustable tracker parameters are located in tracker.h

*******************************************************************************/
void Initialize_Tracker(void)
{
	// initialize servo PWM channels
	LEFT_TRACKER_SERVO = INITIAL_SERVO_POSITION; // rotate left tracker fully clockwise
	RIGHT_TRACKER_SERVO = INITIAL_SERVO_POSITION; // rotate right tracker fully clockwise

	// initialize the left tracker's state machine
	Tracker_Data[left].Status = NONE_IN_VIEW; // defined in tracker.h
	Tracker_Data[left].Position = INITIAL_SERVO_POSITION; // defined in tracker.h
	Tracker_Data[left].Search_Increment = INITIAL_SERVO_STEP_SIZE; // defined in tracker.h
	Tracker_Data[left].Beacon_Type = BEACON_TYPE; // defined in tracker.h
	Tracker_Data[left].Left_Sensor_Stats_Index = LEFT_TRACKER_LEFT_SENSOR; // defined in tracker.h
	Tracker_Data[left].Right_Sensor_Stats_Index = LEFT_TRACKER_RIGHT_SENSOR; // defined in tracker.h

	// initialize the right tracker's state machine
	Tracker_Data[right].Status = NONE_IN_VIEW; // defined in tracker.h
	Tracker_Data[right].Position = INITIAL_SERVO_POSITION; // defined in tracker.h
	Tracker_Data[right].Search_Increment = INITIAL_SERVO_STEP_SIZE; // defined in tracker.h
	Tracker_Data[right].Beacon_Type = BEACON_TYPE; // defined in tracker.h
	Tracker_Data[right].Left_Sensor_Stats_Index = RIGHT_TRACKER_LEFT_SENSOR; // defined in tracker.h
	Tracker_Data[right].Right_Sensor_Stats_Index = RIGHT_TRACKER_RIGHT_SENSOR; // defined in tracker.h
}

/*******************************************************************************
*
*	FUNCTION:		Track_Beacon()
*
*	PURPOSE:		Controls the servo motor(s) such that the pair of
*					infrared beacon sensors mounted on it will always
*					point at the selected IR beacon. Using two or more
*					beacon trackers, separated by a known baseline
*					distance, and some trigonometry will allow the user
*					to calculate the heading and distance to the beacon.
*
*	CALLED FROM:	navigate.c/navigate()
*
*	PARAMETERS:		unsigned char that identifies which tracker to use
*
*	RETURNS:		nothing		
*
*	COMMENTS:		There must be one Tracker_Data structure per tracker.
*					More than two trackers can be used.
*
*******************************************************************************/
void Track_Beacon(unsigned char Tracker)
{
	// which state was tracker <Tracker> in the last time through?
	switch(TRACKER_STATUS)
	{
		case NONE_IN_VIEW: // neither sensor sees the beacon
		{
			if(LEFT_SENSOR > 0)
			{
				// found the beacon
				TRACKER_STATUS = LEFT_IN_VIEW;
//				printf("Tracker: from none to left\n");
			}
			else
			{
				// continue to rotate left until the beacon comes into view
				TRACKER_POSITION += SEARCH_INCREMENT; // rolling over is okay
			}
			break;
		}
		case LEFT_IN_VIEW: // left sensor sees beacon, but the right sensor doesn't
		{			
			if(RIGHT_SENSOR > 0)
			{
				// found the beacon
				TRACKER_STATUS = BOTH_IN_VIEW;
//				printf("Tracker: from left to both\n");
			}
			else
			{
				// continue to rotate left until the beacon comes into view of the right sensor
				TRACKER_POSITION += SEARCH_INCREMENT; // rolling over is okay
			}
			break;
		}	
		case RIGHT_IN_VIEW:	// right sensor sees beacon, but the left sensor doesn't
		{
			if(LEFT_SENSOR > 0)
			{
				// found the beacon
				TRACKER_STATUS = BOTH_IN_VIEW;
//				printf("Tracker: from right to both\n");
			}
			else
			{
				// continue to rotate right until the beacon comes into view of the left sensor
				TRACKER_POSITION -= SEARCH_INCREMENT; // rolling over is okay
			}
			break;
		}
		case BOTH_IN_VIEW: // both sensors see the beacon
		{
			if((LEFT_SENSOR > 0) &&	(RIGHT_SENSOR > 0))
			{
				// do nothing because both sensors see the beacon
//				printf("Tracker: both\n", 0);
			}
			else
			{
				// is the beacon in view of the left sensor?
				if(LEFT_SENSOR > 0)
				{
					// left sensor sees beacon; change state and rotate left
					TRACKER_STATUS = LEFT_IN_VIEW;
					TRACKER_POSITION += SEARCH_INCREMENT; // rolling over is okay
//					printf("Tracker: from both to left\n");
				}
				// is the beacon in view of the right sensor?
				else if(RIGHT_SENSOR > 0)
				{
					// right sensor sees beacon; change state and rotate right
					TRACKER_STATUS = RIGHT_IN_VIEW;
					TRACKER_POSITION -= SEARCH_INCREMENT; // rolling over is okay
//					printf("Tracker: from both to right\n");
				}
				else
				{
					// neither sensor sees the beacon; change state and start search
					TRACKER_STATUS = NONE_IN_VIEW;
					TRACKER_POSITION += SEARCH_INCREMENT; // rolling over is okay
//					printf("Tracker: from both to none\n");
				}
			}
			break;
		} 
	}// end switch(TRACKER_STATUS)
}
/*******************************************************************************
* FILE NAME: user_routines_fast.c
*
* DESCRIPTION:
*  This file is where the user can add their custom code within the framework
*  of the routines below. 
*
* USAGE:
*  You can either modify this file to fit your needs, or remove it from your 
*  project and replace it with a modified copy. 
*
* OPTIONS:  Interrupts are disabled and not used by default.
*******************************************************************************/

#include "ifi_aliases.h"
#include "ifi_default.h"
#include "ifi_utilities.h"
#include "user_routines.h"
#include "receiver.h"
#include "tracker.h"
#include "navigate.h"


/*** DEFINE USER VARIABLES AND INITIALIZE THEM HERE ***/


/*******************************************************************************
* FUNCTION NAME: InterruptVectorLow
* PURPOSE:       Low priority interrupt vector
* CALLED FROM:   nowhere by default
* ARGUMENTS:     none
* RETURNS:       void
* DO NOT MODIFY OR DELETE THIS FUNCTION 
*******************************************************************************/
#pragma code InterruptVectorLow = LOW_INT_VECTOR
void InterruptVectorLow (void)
{
  _asm
    goto InterruptHandlerLow  /*jump to interrupt routine*/
  _endasm
}


/*******************************************************************************
* FUNCTION NAME: InterruptHandlerLow
* PURPOSE:       Low priority interrupt handler
* If you want to use these external low priority interrupts or any of the
* peripheral interrupts then you must enable them in your initialization
* routine.  Innovation First, Inc. will not provide support for using these
* interrupts, so be careful.  There is great potential for glitchy code if good
* interrupt programming practices are not followed.  Especially read p. 28 of
* the "MPLAB(R) C18 C Compiler User's Guide" for information on context saving.
* CALLED FROM:   this file, InterruptVectorLow routine
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
#pragma code
#pragma interruptlow InterruptHandlerLow

void InterruptHandlerLow ()     
{                               
	unsigned char Port_B;
	unsigned char Port_B_Delta;       
	static unsigned char Old_Port_B = 0xFF; // state of port b the last time
											// this function was called  
	
	if (INTCONbits.TMR0IF) // timer 0 Interrupt
	{
		INTCONbits.TMR0IF = 0; // clear the interrupt flag
		// if used, call the timer 0 interrupt handler here
	}

	else if (PIR1bits.TMR1IF) // timer 1 interrupt - used by the IR receiver
	{
		PIR1bits.TMR1IF = 0; // clear the interrupt flag
	Timer_1_Int_Handler(); // call the timer 1 interrupt handler (in receiver.c)
	}  

	else if (INTCON3bits.INT2IF) // external interrupt 1 - used by IR sensor 1
	{ 
		INTCON3bits.INT2IF = 0; // clear the interrupt flag
		Int_1_Handler(); // call the IR sensor 1 interrupt handler (in receiver.c)
	}

	else if (INTCON3bits.INT3IF) // external interrupt 2 - used by IR sensor 2
	{
		INTCON3bits.INT3IF = 0; // clear the interrupt flag
		Int_2_Handler(); // call the IR sensor 2 interrupt handler (in receiver.c)
	}

	else if (INTCONbits.RBIF) // external interrupts 3 through 6
	{
		Port_B = PORTB; // remove the "mismatch condition" by reading port b            
		INTCONbits.RBIF = 0; // clear the interrupt flag
		Port_B_Delta = Port_B ^ Old_Port_B; // determine which bits have changed
		Old_Port_B = Port_B; // save a copy of port b for next time around
	 
		if(Port_B_Delta & 0x10) // did external interrupt 3 change state?
		{
			// if used, call the interrupt 3 handler here
		}

		if(Port_B_Delta & 0x20) // did external interrupt 4 change state? - IR sensor 3
		{
			Int_4_Handler(Port_B & 0x20 ? 1 : 0); // call the interrupt 4 handler (in receiver.c)
		}

		if(Port_B_Delta & 0x40) // did external interrupt 5 change state? - IR sensor 4
		{
			Int_5_Handler(Port_B & 0x40 ? 1 : 0); // call the interrupt 5 handler (in receiver.c)
		}
		
		if(Port_B_Delta & 0x80) // did external interrupt 6 change state?
		{
			// if used, call the interrupt 6 handler here
		}
	}
}


/*******************************************************************************
* FUNCTION NAME: User_Autonomous_Code
* PURPOSE:       Execute user's code during autonomous robot operation.
* You should modify this routine by adding code which you wish to run in
* autonomous mode.  It will be executed every program loop, and not
* wait for or use any data from the Operator Interface.
* CALLED FROM:   main.c file, main() routine when in Autonomous mode
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
void User_Autonomous_Code(void)
{
  while (autonomous_mode)   /* DO NOT CHANGE! */
  {
    if (statusflag.NEW_SPI_DATA)      /* 26.2ms loop area */
    {
        Getdata(&rxdata);   /* DO NOT DELETE, or you will be stuck here forever! */

        /* Add your own autonomous code here. */

			Navigate();			

			if(rc_dig_in01 ==1 )
		 		{
				pwm13 = 137;
				pwm14=100;
				}
  			else
				{
				pwm13 = pwm14 = 140;
				}
			if(rc_dig_in02 == 1)
				{
				pwm13 = 100;
				pwm14 = 137;
				}
			else
				{
				pwm13 = pwm14 = 140;
				}
				
			Generate_Pwms(pwm13,pwm14,pwm15,pwm16);

        Putdata(&txdata);   /* DO NOT DELETE, or you will get no PWM outputs! */
    }
  }
}


/*******************************************************************************
* FUNCTION NAME: Process_Data_From_Local_IO
* PURPOSE:       Execute user's realtime code.
* You should modify this routine by adding code which you wish to run fast.
* It will be executed every program loop, and not wait for fresh data 
* from the Operator Interface.
* CALLED FROM:   main.c
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
void Process_Data_From_Local_IO(void)
{
  /* Add code here that you want to be executed every program loop. */

}


/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
/********************************************************************************
* FILE NAME: ifi_aliases.h <FRC VERSION>
*
* DESCRIPTION: 
*  This file contains common macros (known as aliases in PBASIC) for the 
*  I/O pins of the Robot Controller and elements in the data sent between the 
*  User processor and the Master processor.
*  
*  If you want to create your own macros, do so in the designated section of 
*  the user_routines.h file.
*  
*  DO NOT EDIT THIS FILE!
********************************************************************************/

#ifndef __ifi_aliases_h_
#define __ifi_aliases_h_

#include <adc.h>

/* PWM Type Definitions used in Setup_PWM_Output_Type(...) */
#define IFI_PWM   0     /* Standard IFI PWM output generated with Generate_PWM(...) */
#define USER_CCP  1     /* User can use PWM pin as digital I/O or CCP pin. */

/*
 *-----------------------------------------------------------------------------------------------------
 *---------- Aliases for each OI analog input ---------------------------------------------------------
 *-----------------------------------------------------------------------------------------------------
 *  Below are aliases for the analog inputs located on the Operator Interface.
 */
#define p1_y        rxdata.oi_analog01
#define p2_y        rxdata.oi_analog02
#define p3_y        rxdata.oi_analog03
#define p4_y        rxdata.oi_analog04
#define p1_x        rxdata.oi_analog05
#define p2_x        rxdata.oi_analog06
#define p3_x        rxdata.oi_analog07
#define p4_x        rxdata.oi_analog08
#define p1_wheel    rxdata.oi_analog09
#define p2_wheel    rxdata.oi_analog10
#define p3_wheel    rxdata.oi_analog11
#define p4_wheel    rxdata.oi_analog12

/*
 *-----------------------------------------------------------------------------------------------------
 *---------- Aliases for each OI switch input ---------------------------------------------------------
 *-----------------------------------------------------------------------------------------------------
 *  Below are aliases for the digital inputs located on the Operator Interface.
 *  Ports 1 & 3 have their inputs duplicated in ports 4 & 2 respectively.  The 
 *  inputs from ports 1 & 3 may be disabled via the 'Disable' dip switch 
 *  located on the Operator Interface.  See Users Manual for details.
 */
#define p1_sw_trig  rxdata.oi_swA_byte.bitselect.bit0 /* Joystick Trigger Button, same as Port4 pin5 */
#define p1_sw_top   rxdata.oi_swA_byte.bitselect.bit1 /* Joystick Top Button,     same as Port4 pin8 */
#define p1_sw_aux1  rxdata.oi_swA_byte.bitselect.bit2 /* Aux input,               same as Port4 pin9 */
#define p1_sw_aux2  rxdata.oi_swA_byte.bitselect.bit3 /* Aux input,               same as Port4 pin15*/

#define p3_sw_trig  rxdata.oi_swA_byte.bitselect.bit4 /* Joystick Trigger Button, same as Port2 pin5 */
#define p3_sw_top   rxdata.oi_swA_byte.bitselect.bit5 /* Joystick Top Button,     same as Port2 pin8 */
#define p3_sw_aux1  rxdata.oi_swA_byte.bitselect.bit6 /* Aux input,               same as Port2 pin9 */
#define p3_sw_aux2  rxdata.oi_swA_byte.bitselect.bit7 /* Aux input,               same as Port2 pin15*/

#define p2_sw_trig  rxdata.oi_swB_byte.bitselect.bit0 /* Joystick Trigger Button*/
#define p2_sw_top   rxdata.oi_swB_byte.bitselect.bit1 /* Joystick Top Button*/
#define p2_sw_aux1  rxdata.oi_swB_byte.bitselect.bit2 /* Aux input*/
#define p2_sw_aux2  rxdata.oi_swB_byte.bitselect.bit3 /* Aux input*/

#define p4_sw_trig  rxdata.oi_swB_byte.bitselect.bit4 /* Joystick Trigger Button*/
#define p4_sw_top   rxdata.oi_swB_byte.bitselect.bit5 /* Joystick Top Button*/
#define p4_sw_aux1  rxdata.oi_swB_byte.bitselect.bit6 /* Aux input*/
#define p4_sw_aux2  rxdata.oi_swB_byte.bitselect.bit7 /* Aux input*/

/*
 *-----------------------------------------------------------------------------------------------------
 *---------- Aliases for DIGITAL IN/OUT connectors ----------------------------------------------------
 *-----------------------------------------------------------------------------------------------------
 *  Below are aliases for the digital I/O located on the Robot Controller.
 *  They can be configured to be either Inputs or Outputs.
 */

#define INPUT   1
#define OUTPUT  0

/* Used in User_Initialization routine in user_routines.c file. */
/* Used to set pins as digital INPUTS or digital OUTPUTS. */
#define digital_io_01 TRISBbits.TRISB2
#define digital_io_02 TRISBbits.TRISB3
#define digital_io_03 TRISBbits.TRISB4
#define digital_io_04 TRISBbits.TRISB5
#define digital_io_05 TRISBbits.TRISB6
#define digital_io_06 TRISBbits.TRISB7
#define digital_io_07 TRISHbits.TRISH0
#define digital_io_08 TRISHbits.TRISH1
#define digital_io_09 TRISHbits.TRISH2
#define digital_io_10 TRISHbits.TRISH3
#ifdef _FRC_NC1
#define digital_io_11 TRISGbits.TRISG0
#define digital_io_12 TRISGbits.TRISG3
#define digital_io_13 TRISGbits.TRISG4
#else
#define digital_io_11 TRISJbits.TRISJ1
#define digital_io_12 TRISJbits.TRISJ2
#define digital_io_13 TRISJbits.TRISJ3
#endif
#define digital_io_14 TRISCbits.TRISC0
#define digital_io_15 TRISJbits.TRISJ4
#define digital_io_16 TRISJbits.TRISJ5
#define digital_io_17 TRISJbits.TRISJ6
#define digital_io_18 TRISJbits.TRISJ7

/* Aliases used to read the pins when used as INPUTS. */
#define rc_dig_in01 PORTBbits.RB2
#define rc_dig_in02 PORTBbits.RB3
#define rc_dig_in03 PORTBbits.RB4
#define rc_dig_in04 PORTBbits.RB5
#define rc_dig_in05 PORTBbits.RB6
#define rc_dig_in06 PORTBbits.RB7
#define rc_dig_in07 PORTHbits.RH0
#define rc_dig_in08 PORTHbits.RH1
#define rc_dig_in09 PORTHbits.RH2
#define rc_dig_in10 PORTHbits.RH3
#ifdef _FRC_NC1
#define rc_dig_in11 PORTGbits.RG0
#define rc_dig_in12 PORTGbits.RG3
#define rc_dig_in13 PORTGbits.RG4
#else
#define rc_dig_in11 PORTJbits.RJ1
#define rc_dig_in12 PORTJbits.RJ2
#define rc_dig_in13 PORTJbits.RJ3
#endif
#define rc_dig_in14 PORTCbits.RC0
#define rc_dig_in15 PORTJbits.RJ4
#define rc_dig_in16 PORTJbits.RJ5
#define rc_dig_in17 PORTJbits.RJ6
#define rc_dig_in18 PORTJbits.RJ7

/* Aliases used to drive the pins when used as OUTPUTS. */
#define rc_dig_out01 LATBbits.LATB2
#define rc_dig_out02 LATBbits.LATB3
#define rc_dig_out03 LATBbits.LATB4
#define rc_dig_out04 LATBbits.LATB5
#define rc_dig_out05 LATBbits.LATB6
#define rc_dig_out06 LATBbits.LATB7
#define rc_dig_out07 LATHbits.LATH0
#define rc_dig_out08 LATHbits.LATH1
#define rc_dig_out09 LATHbits.LATH2
#define rc_dig_out10 LATHbits.LATH3
#ifdef _FRC_NC1
#define rc_dig_out11 LATGbits.LATG0
#define rc_dig_out12 LATGbits.LATG3
#define rc_dig_out13 LATGbits.LATG4
#else
#define rc_dig_out11 LATJbits.LATJ1
#define rc_dig_out12 LATJbits.LATJ2
#define rc_dig_out13 LATJbits.LATJ3
#endif
#define rc_dig_out14 LATCbits.LATC0
#define rc_dig_out15 LATJbits.LATJ4
#define rc_dig_out16 LATJbits.LATJ5
#define rc_dig_out17 LATJbits.LATJ6
#define rc_dig_out18 LATJbits.LATJ7

/*
 *-----------------------------------------------------------------------------------------------------
 *---------- Aliases for PWM OUTPUTS ------------------------------------------------------------------
 *-----------------------------------------------------------------------------------------------------
 *  Below are aliases for the PWM OUTPUTS located on the Robot Controller.  
 */
#define pwm01       txdata.rc_pwm01
#define pwm02       txdata.rc_pwm02
#define pwm03       txdata.rc_pwm03
#define pwm04       txdata.rc_pwm04
#define pwm05       txdata.rc_pwm05
#define pwm06       txdata.rc_pwm06
#define pwm07       txdata.rc_pwm07
#define pwm08       txdata.rc_pwm08
#define pwm09       txdata.rc_pwm09
#define pwm10       txdata.rc_pwm10
#define pwm11       txdata.rc_pwm11
#define pwm12       txdata.rc_pwm12
#define pwm13       txdata.rc_pwm13
#define pwm14       txdata.rc_pwm14
#define pwm15       txdata.rc_pwm15
#define pwm16       txdata.rc_pwm16

/*
 *-----------------------------------------------------------------------------------------------------
 *---------- Aliases for RELAY OUTPUTS conncectors ----------------------------------------------------
 *-----------------------------------------------------------------------------------------------------
 *  Below are aliases for the relay outputs located on the Robot Controller.  
 */
#define relay1_fwd  LATDbits.LATD0
#define relay1_rev  LATEbits.LATE0
#define relay2_fwd  LATDbits.LATD1
#define relay2_rev  LATEbits.LATE1
#define relay3_fwd  LATDbits.LATD2
#define relay3_rev  LATEbits.LATE2
#define relay4_fwd  LATDbits.LATD3
#define relay4_rev  LATEbits.LATE3
#define relay5_fwd  LATDbits.LATD4
#define relay5_rev  LATEbits.LATE4
#define relay6_fwd  LATDbits.LATD5
#define relay6_rev  LATEbits.LATE5
#define relay7_fwd  LATDbits.LATD6
#define relay7_rev  LATEbits.LATE6
#define relay8_fwd  LATDbits.LATD7
#ifdef _FRC_NC1
#define relay8_rev  LATEbits.LATE7
#else
#define relay8_rev  LATJbits.LATJ0
#endif

/*
 *-----------------------------------------------------------------------------------------------------
 *---------- Aliases for ANALOG INPUTS connectors -----------------------------------------------------
 *-----------------------------------------------------------------------------------------------------
 *  Below are aliases for the analog input pins located on the Robot Controller.
 *    vvvvvvvv  You can change these aliases, but they are descriptive of the default setup.
 */
/* Used in Get_Analog_Value routine. */
#define rc_ana_in01  ADC_CH0
#define rc_ana_in02  ADC_CH1
#define rc_ana_in03  ADC_CH2
#define rc_ana_in04  ADC_CH3
#define rc_ana_in05  ADC_CH4
#define rc_ana_in06  ADC_CH5
#define rc_ana_in07  ADC_CH6
#define rc_ana_in08  ADC_CH7
#define rc_ana_in09  ADC_CH8
#define rc_ana_in10  ADC_CH9
#define rc_ana_in11  ADC_CH10
#define rc_ana_in12  ADC_CH11
#define rc_ana_in13  ADC_CH12
#define rc_ana_in14  ADC_CH13
#define rc_ana_in15  ADC_CH14
#define rc_ana_in16  ADC_CH15

/* Optionally used in User_Initialization routine in user_routines.c file. */
#define NO_ANALOG           ADC_0ANA    /* All digital */
#define ONE_ANALOG          ADC_1ANA    /* analog: AN0      digital: AN1->15 */
#define TWO_ANALOG          ADC_2ANA    /* analog: AN0->1   digital: AN2->15 */
#define THREE_ANALOG        ADC_3ANA    /* analog: AN0->2   digital: AN3->15 */
#define FOUR_ANALOG         ADC_4ANA    /* analog: AN0->3   digital: AN4->15 */
#define FIVE_ANALOG         ADC_5ANA    /* analog: AN0->4   digital: AN5->15 */
#define SIX_ANALOG          ADC_6ANA    /* analog: AN0->5   digital: AN6->15 */
#define SEVEN_ANALOG        ADC_7ANA    /* analog: AN0->6   digital: AN7->15 */
#define EIGHT_ANALOG        ADC_8ANA    /* analog: AN0->7   digital: AN8->15 */
#define NINE_ANALOG         ADC_9ANA    /* analog: AN0->8   digital: AN9->15 */
#define TEN_ANALOG          ADC_10ANA   /* analog: AN0->9   digital: AN10->15 */
#define ELEVEN_ANALOG       ADC_11ANA   /* analog: AN0->10  digital: AN11->15 */
#define TWELVE_ANALOG       ADC_12ANA   /* analog: AN0->11  digital: AN12->15 */
#define THIRTEEN_ANALOG     ADC_13ANA   /* analog: AN0->12  digital: AN13->15 */
#define FOURTEEN_ANALOG     ADC_14ANA   /* analog: AN0->13  digital: AN14->15 */
/* There is no FIFTEEN_ANALOG! */
#define SIXTEEN_ANALOG      ADC_16ANA   /* All analog */


/* The following aliases are probably not needed. */
#define rc_a2d_pin01  PORTAbits.RA0
#define rc_a2d_pin02  PORTAbits.RA1
#define rc_a2d_pin03  PORTAbits.RA2
#define rc_a2d_pin04  PORTAbits.RA3
#define rc_a2d_pin05  PORTAbits.RA5
#define rc_a2d_pin06  PORTFbits.RF0
#define rc_a2d_pin07  PORTFbits.RF1
#define rc_a2d_pin08  PORTFbits.RF2
#define rc_a2d_pin09  PORTFbits.RF3
#define rc_a2d_pin10  PORTFbits.RF4
#define rc_a2d_pin11  PORTFbits.RF5
#define rc_a2d_pin12  PORTFbits.RF6
#define rc_a2d_pin13  PORTHbits.RH4
#define rc_a2d_pin14  PORTHbits.RH5
#define rc_a2d_pin15  PORTHbits.RH6
#define rc_a2d_pin16  PORTHbits.RH7

/*
 *-----------------------------------------------------------------------------------------------------
 *---------- Aliases for the ROBOT FEEDBACK LEDs ------------------------------------------------------
 *-----------------------------------------------------------------------------------------------------
 *  Below are aliases for the ROBOT FEEDBACK LEDs located  on the Operator Interface.  
 */
#define pwm1_green    txdata.LED_byte1.bitselect.bit0
#define pwm1_red      txdata.LED_byte1.bitselect.bit1 
#define pwm2_green    txdata.LED_byte1.bitselect.bit2
#define pwm2_red      txdata.LED_byte1.bitselect.bit3 
#define Relay1_green  txdata.LED_byte1.bitselect.bit4
#define Relay1_red    txdata.LED_byte1.bitselect.bit5 
#define Relay2_green  txdata.LED_byte1.bitselect.bit6
#define Relay2_red    txdata.LED_byte1.bitselect.bit7 

#define Switch1_LED   txdata.LED_byte2.bitselect.bit0
#define Switch2_LED   txdata.LED_byte2.bitselect.bit1
#define Switch3_LED   txdata.LED_byte2.bitselect.bit2

/*
 *-----------------------------------------------------------------------------------------------------
 *---------- Alias for Battery Voltage  ---------------------------------------------------------------
 *-----------------------------------------------------------------------------------------------------
 * current voltage = battery_voltage * 0.038 + 0.05; 
 */

#define battery_voltage      rxdata.rc_analog01

/*
 *-----------------------------------------------------------------------------------------------------
 *---------- Aliases for User Modes  ------------------------------------------------------------------
 *-----------------------------------------------------------------------------------------------------
 */

#define user_display_mode rxdata.rc_mode_byte.mode.user_display
#define autonomous_mode rxdata.rc_mode_byte.mode.autonomous
#define competition_mode rxdata.rc_mode_byte.mode.disabled

#endif

/*---------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------*/
/*******************************************************************************
* FILE NAME: ifi_default.h
*
* DESCRIPTION: 
*  This file contains important data definitions.              
*
*  DO NOT EDIT THIS FILE!
*******************************************************************************/

#ifndef __ifi_default_h_
#define __ifi_default_h_

#include "ifi_picdefs.h"

#ifdef UNCHANGEABLE_DEFINITION_AREA

/*******************************************************************************
                             ALIAS DEFINITIONS
*******************************************************************************/
                           /* DO NOT CHANGE! */

#define   DATA_SIZE          30
#define   SPI_TRAILER_SIZE   2
#define   SPI_XFER_SIZE      DATA_SIZE + SPI_TRAILER_SIZE

#define   RESET_VECTOR      0x800
#define   HIGH_INT_VECTOR   0x808
#define   LOW_INT_VECTOR    0x818


/*******************************************************************************
                            VARIABLE DECLARATIONS
*******************************************************************************/
                            /* DO NOT CHANGE! */
/* This structure contains important system status information. */
typedef struct
{
  unsigned int  :5;
  unsigned int  user_display:1;  /* User display enabled = 1, disabled = 0 */
  unsigned int  autonomous:1;    /* Autonomous enabled = 1, disabled = 0 */
  unsigned int  disabled:1;      /* Competition enabled = 1, disabled = 0 */
} modebits;

/******************************************************************************/
                            /* DO NOT CHANGE! */
/* This structure allows you to address specific bits of a byte.*/
typedef struct
{
  unsigned int  bit0:1;
  unsigned int  bit1:1;
  unsigned int  bit2:1;
  unsigned int  bit3:1;
  unsigned int  bit4:1;
  unsigned int  bit5:1;
  unsigned int  bit6:1;
  unsigned int  bit7:1;
} bitid;

/******************************************************************************/
                            /* DO NOT CHANGE! */
/* This structure defines the contents of the data received from the Master
 * microprocessor. */
typedef struct  {     /* begin rx_data_record structure */
  unsigned char packet_num;
  union
  { 
    bitid bitselect;
    modebits mode;            /*rxdata.rc_mode_byte.mode.(user_display|autonomous|disabled)*/
    unsigned char allbits;    /*rxdata.rc_mode_byte.allbits*/
  } rc_mode_byte;
  union
  {
    bitid bitselect;          /*rxdata.oi_swA_byte.bitselect.bit0*/
    unsigned char allbits;    /*rxdata.oi_swA_byte.allbits*/
  } oi_swA_byte;  
  union
  {
    bitid bitselect;          /*rxdata.oi_swB_byte.bitselect.bit0*/
    unsigned char allbits;    /*rxdata.oi_swB_byte.allbits*/
  } oi_swB_byte;  
  union
  {
    bitid bitselect;          /*rxdata.rc_swA_byte.bitselect.bit0*/
    unsigned char allbits;    /*rxdata.rc_swA_byte.allbits*/
  } rc_swA_byte;
  union
  {
    bitid bitselect;          /*rxdata.rc_swB_byte.bitselect.bit0*/
    unsigned char allbits;    /*rxdata.rc_swB_byte.allbits*/
  } rc_swB_byte;
  unsigned char oi_analog01, oi_analog02, oi_analog03, oi_analog04;  /*rxdata.oi_analog01*/
  unsigned char oi_analog05, oi_analog06, oi_analog07, oi_analog08;         
  unsigned char oi_analog09, oi_analog10, oi_analog11, oi_analog12;
  unsigned char oi_analog13, oi_analog14, oi_analog15, oi_analog16;
  unsigned char rc_analog01, rc_analog02, rc_analog03, rc_analog04;       
  unsigned char rc_analog05, rc_analog06, rc_analog07, rc_analog08;         
  unsigned char res01, res02;         
} rx_data_record;

typedef rx_data_record *rx_data_ptr;

/******************************************************************************/
                            /* DO NOT CHANGE! */
/* This structure defines the contents of the data transmitted to the master  
 * microprocessor. */
typedef struct  {     /*begin tx_data_record structure*/
  union
  { 
    bitid bitselect;          /*txdata.LED_byte1.bitselect.bit0*/
    unsigned char data;       /*txdata.LED_byte1.data*/
  } LED_byte1;
  union
  { 
    bitid bitselect;          /*txdata.LED_byte1.bitselect.bit0*/
    unsigned char data;       /*txdata.LED_byte1.data*/
  } LED_byte2;
  union
  {
    bitid bitselect;          /*txdata.relayA.bitselect.bit0*/
    unsigned char allbits;    /*txdata.relayA.allbits*/
  } relayA;
  union
  {
    bitid bitselect;          /*txdata.relayB.bitselect.bit0*/
    unsigned char allbits;    /*txdata.relayB.allbits*/
  } relayB;
  unsigned char rc_pwm01, rc_pwm02, rc_pwm03, rc_pwm04;   /*txdata.rc_pwm01*/
  unsigned char rc_pwm05, rc_pwm06, rc_pwm07, rc_pwm08;
  unsigned char rc_pwm09, rc_pwm10, rc_pwm11, rc_pwm12;
  unsigned char rc_pwm13, rc_pwm14, rc_pwm15, rc_pwm16;

  unsigned char user_cmd;     /*reserved - for future use*/
  unsigned char cmd_byte1;    /*reserved - Don't use*/
  unsigned char pwm_mask;     /*<EDU> make sure you know how this works before changing*/
  unsigned char warning_code; /*reserved - Don't use*/
  unsigned char reserve[4];   /*reserved - Don't use (0-3)*/
  unsigned char error_code;   /*reserved - Don't use*/
  unsigned char packetnum;    /*reserved - Don't use*/
  unsigned char current_mode; /*reserved - Don't use*/
  unsigned char control;      /*reserved - Don't use*/
} tx_data_record;

typedef tx_data_record *tx_data_ptr;


/******************************************************************************/
                            /* DO NOT CHANGE! */
/* This structure defines some flags which are used by the system. */

typedef struct
{
  unsigned int  NEW_SPI_DATA:1;
  unsigned int  TX_UPDATED:1;
  unsigned int  FIRST_TIME:1;
  unsigned int  TX_BUFFSELECT:1;
  unsigned int  RX_BUFFSELECT:1;
  unsigned int  :3;
} packed_struct;

/******************************************************************************/

extern tx_data_record txdata; 
extern rx_data_record rxdata; 
extern packed_struct statusflag;

#else
#error  *** Error - Invalid Default File!
#endif

/*******************************************************************************
                           FUNCTION PROTOTYPES
*******************************************************************************/

/* These routines reside in ifi_library.lib */
void InterruptHandlerHigh (void);
void Initialize_Registers (void);
void IFI_Initialization (void);
void User_Proc_Is_Ready (void);
void Putdata(tx_data_ptr ptr);
void Getdata(rx_data_ptr ptr);
void Clear_SPIdata_flag(void);
void Setup_PWM_Output_Type(int pwmSpec1,int pwmSpec2,int pwmSpec3,int pwmSpec4);

#endif

/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
/*******************************************************************************
* FILE NAME: ifi_picdef.h
*
* DESCRIPTION: 
*  This include file contains definitions for the 18f8520 PICmicro.  All 
*  register definitions are explained in detail in the PIC18FXX20 Data Sheet.   
*
* USAGE:
*  Refer to this file to determine if a register is off-limits to the user.
*  Registers and bits marked by "Reserved - Do not use" should not be modified
*  by the user's code or else the Robot Controller will not function.

* WARNING:
*  DO NOT MODIFY THIS FILE!
*******************************************************************************/

#ifndef __ifi_picdefs_h_
#define __ifi_picdefs_h_

extern volatile near unsigned char       RCSTA2;
extern volatile near union {
  struct {
    unsigned RX9D:1;
    unsigned OERR:1;
    unsigned FERR:1;
    unsigned ADEN:1;
    unsigned CREN:1;
    unsigned SREN:1;
    unsigned RX9:1;
    unsigned SPEN:1;
  };
  struct {
    unsigned RCD8:1;
    unsigned :5;
    unsigned RC9:1;
  };
  struct {
    unsigned :6;
    unsigned NOT_RC8:1;
  };
  struct {
    unsigned :6;
    unsigned RC8_9:1;
  };
} RCSTA2bits;
extern volatile near unsigned char       TXSTA2;
extern volatile near union {
  struct {
    unsigned TX9D:1;
    unsigned TRMT:1;
    unsigned BRGH:1;
    unsigned :1;
    unsigned SYNC:1;
    unsigned TXEN:1;
    unsigned TX9:1;
    unsigned CSRC:1;
  };
  struct {
    unsigned TXD8:1;
    unsigned :5;
    unsigned TX8_9:1;
  };
  struct {
    unsigned :6;
    unsigned NOT_TX8:1;
  };
} TXSTA2bits;
extern volatile near unsigned char       TXREG2;
extern volatile near unsigned char       RCREG2;
extern volatile near unsigned char       SPBRG2;
extern volatile near unsigned char       CCP5CON;
extern volatile near union {
  struct {
    unsigned CCP5M0:1;
    unsigned CCP5M1:1;
    unsigned CCP5M2:1;
    unsigned CCP5M3:1;
    unsigned DCCP5Y:1;
    unsigned DCCP5X:1;
  };
  struct {
    unsigned :4;
    unsigned DC5B0:1;
    unsigned DC5B1:1;
  };
} CCP5CONbits;
extern volatile near unsigned            CCPR5;
extern volatile near unsigned char       CCPR5L;
extern volatile near unsigned char       CCPR5H;
extern volatile near unsigned char       CCP4CON;
extern volatile near union {
  struct {
    unsigned CCP4M0:1;
    unsigned CCP4M1:1;
    unsigned CCP4M2:1;
    unsigned CCP4M3:1;
    unsigned DCCP4Y:1;
    unsigned DCCP4X:1;
  };
  struct {
    unsigned :4;
    unsigned DC4B0:1;
    unsigned DC4B1:1;
  };
} CCP4CONbits;
extern volatile near unsigned            CCPR4;
extern volatile near unsigned char       CCPR4L;
extern volatile near unsigned char       CCPR4H;
extern volatile near unsigned char       T4CON;
extern volatile near struct {
  unsigned T4CKPS0:1;
  unsigned T4CKPS1:1;
  unsigned TMR4ON:1;
  unsigned T4OUTPS0:1;
  unsigned T4OUTPS1:1;
  unsigned T4OUTPS2:1;
  unsigned T4OUTPS3:1;
} T4CONbits;
extern volatile near unsigned char       PR4;
extern volatile near unsigned char       TMR4;
extern volatile near unsigned char       PORTA;
extern volatile near union {
  struct {
    unsigned RA0:1;
    unsigned RA1:1;
    unsigned RA2:1;
    unsigned RA3:1;
    unsigned RA4:1;     /* Reserved - Do not use */
    unsigned RA5:1;
    unsigned RA6:1;
  };
  struct {
    unsigned AN0:1;
    unsigned AN1:1;
    unsigned AN2:1;
    unsigned AN3:1;
    unsigned T0CKI:1;   /* Reserved - Do not use */
    unsigned AN4:1;
    unsigned OSC2:1;
  };
  struct {
    unsigned :2;
    unsigned VREFM:1;
    unsigned VREFP:1;
    unsigned :1;
    unsigned LVDIN:1;
    unsigned CLKO:1;
  };
} PORTAbits;
extern volatile near unsigned char       PORTB;
extern volatile near union {
  struct {
    unsigned RB0:1;     /* Reserved - Do not use */
    unsigned RB1:1;
    unsigned RB2:1;
    unsigned RB3:1;
    unsigned RB4:1;
    unsigned RB5:1;
    unsigned RB6:1;
    unsigned RB7:1;
  };
  struct {
    unsigned INT0:1;    /* Reserved - Do not use */
    unsigned INT1:1;
    unsigned INT2:1;
    unsigned INT3:1;
    unsigned KBI0:1;
    unsigned KBI1:1;
    unsigned KBI2:1;
    unsigned KBI3:1;
  };
  struct {
    unsigned :3;
    unsigned CCP2B:1;
    unsigned :1;
    unsigned PGM:1;
    unsigned PGC:1;
    unsigned PGD:1;
  };
} PORTBbits;
extern volatile near unsigned char       PORTC;
extern volatile near union {
  struct {
    unsigned RC0:1;
    unsigned RC1:1;     /* Reserved - Do not use */
    unsigned RC2:1;     /* Reserved - Do not use */
    unsigned RC3:1;     /* Reserved - Do not use */
    unsigned RC4:1;     /* Reserved - Do not use */
    unsigned RC5:1;     /* Reserved - Do not use */
    unsigned RC6:1;
    unsigned RC7:1;
  };
  struct {
    unsigned T1OSO:1;
    unsigned T1OSI:1;   /* Reserved - Do not use */
    unsigned CCP1:1;    /* Reserved - Do not use */
    unsigned SCK:1;     /* Reserved - Do not use */
    unsigned SDI:1;     /* Reserved - Do not use */
    unsigned SDO:1;     /* Reserved - Do not use */
    unsigned TX:1;
    unsigned RX:1;
  };
  struct {
    unsigned T13CKI:1;
    unsigned CCP2C:1;   /* Reserved - Do not use */
    unsigned :1;
    unsigned SCL:1;     /* Reserved - Do not use */
    unsigned SDA:1;     /* Reserved - Do not use */
    unsigned :1;        /* Reserved - Do not use */
    unsigned CK:1;
    unsigned DT:1;
  };
} PORTCbits;
extern volatile near unsigned char       PORTD;
extern volatile near union {
  struct {
    unsigned RD0:1;
    unsigned RD1:1;
    unsigned RD2:1;
    unsigned RD3:1;
    unsigned RD4:1;
    unsigned RD5:1;
    unsigned RD6:1;
    unsigned RD7:1;
  };
  struct {
    unsigned PSP0:1;
    unsigned PSP1:1;
    unsigned PSP2:1;
    unsigned PSP3:1;
    unsigned PSP4:1;
    unsigned PSP5:1;
    unsigned PSP6:1;
    unsigned PSP7:1;
  };
  struct {
    unsigned AD0:1;
    unsigned AD1:1;
    unsigned AD2:1;
    unsigned AD3:1;
    unsigned AD4:1;
    unsigned AD5:1;
    unsigned AD6:1;
    unsigned AD7:1;
  };
} PORTDbits;
extern volatile near unsigned char       PORTE;
extern volatile near union {
  struct {
    unsigned RE0:1;
    unsigned RE1:1;
    unsigned RE2:1;
    unsigned RE3:1;
    unsigned RE4:1;
    unsigned RE5:1;
    unsigned RE6:1;
    unsigned RE7:1;
  };
  struct {
    unsigned RD:1;
    unsigned WR:1;
    unsigned CS:1;
    unsigned :4;
    unsigned CCP2E:1;
  };
  struct {
    unsigned AD8:1;
    unsigned AD9:1;
    unsigned AD10:1;
    unsigned AD11:1;
    unsigned AD12:1;
    unsigned AD13:1;
    unsigned AD14:1;
    unsigned AD15:1;
  };
} PORTEbits;
extern volatile near unsigned char       PORTF;
extern volatile near union {
  struct {
    unsigned RF0:1;
    unsigned RF1:1;
    unsigned RF2:1;
    unsigned RF3:1;
    unsigned RF4:1;
    unsigned RF5:1;
    unsigned RF6:1;
    unsigned RF7:1;         /* Reserved - Do not use */
  };
  struct {
    unsigned AN5:1;
    unsigned AN6:1;
    unsigned AN7:1;
    unsigned AN8:1;
    unsigned AN9:1;
    unsigned AN10:1;
    unsigned AN11:1;
    unsigned SS:1;          /* Reserved - Do not use */
  };
  struct {
    unsigned :1;
    unsigned C2OUTF:1;
    unsigned C1OUTF:1;
    unsigned :2;
    unsigned CVREFF:1;     /* Reserved - Do not use */
  };
} PORTFbits;
extern volatile near unsigned char       PORTG;
extern volatile near union {
  struct {
    unsigned RG0:1;
    unsigned RG1:1;
    unsigned RG2:1;
    unsigned RG3:1;
    unsigned RG4:1;
  };
  struct {
    unsigned CCP3:1;
    unsigned TX2:1;
    unsigned RX2:1;
    unsigned CCP4:1;
    unsigned CCP5:1;
  };
  struct {
    unsigned :1;
    unsigned CK2:1;
    unsigned DT2:1;
  };
} PORTGbits;
extern volatile near unsigned char       PORTH;
extern volatile near union {
  struct {
    unsigned RH0:1;
    unsigned RH1:1;
    unsigned RH2:1;
    unsigned RH3:1;
    unsigned RH4:1;
    unsigned RH5:1;
    unsigned RH6:1;
    unsigned RH7:1;
  };
  struct {
    unsigned A16:1;
    unsigned A17:1;
    unsigned A18:1;
    unsigned A19:1;
    unsigned AN12:1;
    unsigned AN13:1;
    unsigned AN14:1;
    unsigned AN15:1;
  };
} PORTHbits;
extern volatile near unsigned char       PORTJ;
extern volatile near union {
  struct {
    unsigned RJ0:1;
    unsigned RJ1:1;
    unsigned RJ2:1;
    unsigned RJ3:1;
    unsigned RJ4:1;
    unsigned RJ5:1;
    unsigned RJ6:1;
    unsigned RJ7:1;
  };
  struct {
    unsigned ALE:1;
    unsigned OE:1;
    unsigned WRL:1;
    unsigned WRH:1;
    unsigned BA0:1;
    unsigned CE:1;
    unsigned LB:1;
    unsigned UB:1;
  };
} PORTJbits;
extern volatile near unsigned char       LATA;
extern volatile near struct {
  unsigned LATA0:1;
  unsigned LATA1:1;
  unsigned LATA2:1;
  unsigned LATA3:1;
  unsigned LATA4:1;     /* Reserved - Do not use */
  unsigned LATA5:1;
  unsigned LATA6:1;
} LATAbits;
extern volatile near unsigned char       LATB;
extern volatile near struct {
  unsigned LATB0:1;     /* Reserved - Do not use */
  unsigned LATB1:1;
  unsigned LATB2:1;
  unsigned LATB3:1;
  unsigned LATB4:1;
  unsigned LATB5:1;
  unsigned LATB6:1;
  unsigned LATB7:1;
} LATBbits;
extern volatile near unsigned char       LATC;
extern volatile near struct {
  unsigned LATC0:1;
  unsigned LATC1:1;     /* Reserved - Do not use */
  unsigned LATC2:1;     /* Reserved - Do not use */
  unsigned LATC3:1;     /* Reserved - Do not use */
  unsigned LATC4:1;     /* Reserved - Do not use */
  unsigned LATC5:1;     /* Reserved - Do not use */
  unsigned LATC6:1;
  unsigned LATC7:1;
} LATCbits;
extern volatile near unsigned char       LATD;
extern volatile near struct {
  unsigned LATD0:1;
  unsigned LATD1:1;
  unsigned LATD2:1;
  unsigned LATD3:1;
  unsigned LATD4:1;
  unsigned LATD5:1;
  unsigned LATD6:1;
  unsigned LATD7:1;
} LATDbits;
extern volatile near unsigned char       LATE;
extern volatile near struct {
  unsigned LATE0:1;
  unsigned LATE1:1;
  unsigned LATE2:1;
  unsigned LATE3:1;
  unsigned LATE4:1;
  unsigned LATE5:1;
  unsigned LATE6:1;
  unsigned LATE7:1;
} LATEbits;
extern volatile near unsigned char       LATF;
extern volatile near struct {
  unsigned LATF0:1;
  unsigned LATF1:1;
  unsigned LATF2:1;
  unsigned LATF3:1;
  unsigned LATF4:1;
  unsigned LATF5:1;
  unsigned LATF6:1;
  unsigned LATF7:1;     /* Reserved - Do not use */
} LATFbits;
extern volatile near unsigned char       LATG;
extern volatile near struct {
  unsigned LATG0:1;
  unsigned LATG1:1;
  unsigned LATG2:1;
  unsigned LATG3:1;
  unsigned LATG4:1;
} LATGbits;
extern volatile near unsigned char       LATH;
extern volatile near struct {
  unsigned LATH0:1;
  unsigned LATH1:1;
  unsigned LATH2:1;
  unsigned LATH3:1;
  unsigned LATH4:1;
  unsigned LATH5:1;
  unsigned LATH6:1;
  unsigned LATH7:1;
} LATHbits;
extern volatile near unsigned char       LATJ;
extern volatile near struct {
  unsigned LATJ0:1;
  unsigned LATJ1:1;
  unsigned LATJ2:1;
  unsigned LATJ3:1;
  unsigned LATJ4:1;
  unsigned LATJ5:1;
  unsigned LATJ6:1;
  unsigned LATJ7:1;
} LATJbits;
extern volatile near unsigned char       TRISA;
extern volatile near struct {
  unsigned TRISA0:1;
  unsigned TRISA1:1;
  unsigned TRISA2:1;
  unsigned TRISA3:1;
  unsigned TRISA4:1;     /* Reserved - Do not use */
  unsigned TRISA5:1;
  unsigned TRISA6:1;
} TRISAbits;
extern volatile near unsigned char       DDRA;
extern volatile near struct {
  unsigned RA0:1;
  unsigned RA1:1;
  unsigned RA2:1;
  unsigned RA3:1;
  unsigned RA4:1;     /* Reserved - Do not use */
  unsigned RA5:1;
  unsigned RA6:1;
} DDRAbits;
extern volatile near unsigned char       DDRB;
extern volatile near struct {
  unsigned RB0:1;     /* Reserved - Do not use */
  unsigned RB1:1;
  unsigned RB2:1;
  unsigned RB3:1;
  unsigned RB4:1;
  unsigned RB5:1;
  unsigned RB6:1;
  unsigned RB7:1;
} DDRBbits;
extern volatile near unsigned char       TRISB;
extern volatile near struct {
  unsigned TRISB0:1;     /* Reserved - Do not use */
  unsigned TRISB1:1;
  unsigned TRISB2:1;
  unsigned TRISB3:1;
  unsigned TRISB4:1;
  unsigned TRISB5:1;
  unsigned TRISB6:1;
  unsigned TRISB7:1;
} TRISBbits;
extern volatile near unsigned char       DDRC;
extern volatile near struct {
  unsigned RC0:1;
  unsigned RC1:1;     /* Reserved - Do not use */
  unsigned RC2:1;     /* Reserved - Do not use */
  unsigned RC3:1;     /* Reserved - Do not use */
  unsigned RC4:1;     /* Reserved - Do not use */
  unsigned RC5:1;     /* Reserved - Do not use */
  unsigned RC6:1;
  unsigned RC7:1;
} DDRCbits;
extern volatile near unsigned char       TRISC;
extern volatile near struct {
  unsigned TRISC0:1;
  unsigned TRISC1:1;    /* Reserved - Do not use */
  unsigned TRISC2:1;    /* Reserved - Do not use */
  unsigned TRISC3:1;    /* Reserved - Do not use */
  unsigned TRISC4:1;    /* Reserved - Do not use */
  unsigned TRISC5:1;    /* Reserved - Do not use */
  unsigned TRISC6:1;
  unsigned TRISC7:1;
} TRISCbits;
extern volatile near unsigned char       DDRD;
extern volatile near struct {
  unsigned RD0:1;
  unsigned RD1:1;
  unsigned RD2:1;
  unsigned RD3:1;
  unsigned RD4:1;
  unsigned RD5:1;
  unsigned RD6:1;
  unsigned RD7:1;
} DDRDbits;
extern volatile near unsigned char       TRISD;
extern volatile near struct {
  unsigned TRISD0:1;
  unsigned TRISD1:1;
  unsigned TRISD2:1;
  unsigned TRISD3:1;
  unsigned TRISD4:1;
  unsigned TRISD5:1;
  unsigned TRISD6:1;
  unsigned TRISD7:1;
} TRISDbits;
extern volatile near unsigned char       DDRE;
extern volatile near struct {
  unsigned RE0:1;
  unsigned RE1:1;
  unsigned RE2:1;
  unsigned RE3:1;
  unsigned RE4:1;
  unsigned RE5:1;
  unsigned RE6:1;
  unsigned RE7:1;
} DDREbits;
extern volatile near unsigned char       TRISE;
extern volatile near struct {
  unsigned TRISE0:1;
  unsigned TRISE1:1;
  unsigned TRISE2:1;
  unsigned TRISE3:1;
  unsigned TRISE4:1;
  unsigned TRISE5:1;
  unsigned TRISE6:1;
  unsigned TRISE7:1;
} TRISEbits;
extern volatile near unsigned char       TRISF;
extern volatile near struct {
  unsigned TRISF0:1;
  unsigned TRISF1:1;
  unsigned TRISF2:1;
  unsigned TRISF3:1;
  unsigned TRISF4:1;
  unsigned TRISF5:1;
  unsigned TRISF6:1;
  unsigned TRISF7:1;  /* Reserved - Do not use */
} TRISFbits;
extern volatile near unsigned char       DDRF;
extern volatile near struct {
  unsigned RF0:1;
  unsigned RF1:1;
  unsigned RF2:1;
  unsigned RF3:1;
  unsigned RF4:1;
  unsigned RF5:1;
  unsigned RF6:1;
  unsigned RF7:1;     /* Reserved - Do not use */
} DDRFbits;
extern volatile near unsigned char       DDRG;
extern volatile near struct {
  unsigned RG0:1;
  unsigned RG1:1;
  unsigned RG2:1;
  unsigned RG3:1;
  unsigned RG4:1;
} DDRGbits;
extern volatile near unsigned char       TRISG;
extern volatile near struct {
  unsigned TRISG0:1;
  unsigned TRISG1:1;
  unsigned TRISG2:1;
  unsigned TRISG3:1;
  unsigned TRISG4:1;
} TRISGbits;
extern volatile near unsigned char       DDRH;
extern volatile near struct {
  unsigned RH0:1;
  unsigned RH1:1;
  unsigned RH2:1;
  unsigned RH3:1;
  unsigned RH4:1;
  unsigned RH5:1;
  unsigned RH6:1;
  unsigned RH7:1;
} DDRHbits;
extern volatile near unsigned char       TRISH;
extern volatile near struct {
  unsigned TRISH0:1;
  unsigned TRISH1:1;
  unsigned TRISH2:1;
  unsigned TRISH3:1;
  unsigned TRISH4:1;
  unsigned TRISH5:1;
  unsigned TRISH6:1;
  unsigned TRISH7:1;
} TRISHbits;
extern volatile near unsigned char       DDRJ;
extern volatile near struct {
  unsigned RJ0:1;
  unsigned RJ1:1;
  unsigned RJ2:1;
  unsigned RJ3:1;
  unsigned RJ4:1;
  unsigned RJ5:1;
  unsigned RJ6:1;
  unsigned RJ7:1;
} DDRJbits;
extern volatile near unsigned char       TRISJ;
extern volatile near struct {
  unsigned TRISJ0:1;
  unsigned TRISJ1:1;
  unsigned TRISJ2:1;
  unsigned TRISJ3:1;
  unsigned TRISJ4:1;
  unsigned TRISJ5:1;
  unsigned TRISJ6:1;
  unsigned TRISJ7:1;
} TRISJbits;
extern volatile near unsigned char       MEMCON;     /* Reserved - Do not use */
extern volatile near struct {
  unsigned WM0:1;
  unsigned WM1:1;
  unsigned :2;
  unsigned WAIT0:1;
  unsigned WAIT1:1;
  unsigned :1;
  unsigned EBDIS:1;
} MEMCONbits;     /* Reserved - Do not use */
extern volatile near unsigned char       PIE1;
extern volatile near union {
  struct {
    unsigned TMR1IE:1;
    unsigned TMR2IE:1;
    unsigned CCP1IE:1;
    unsigned SSPIE:1;     /* Reserved - Do not use */
    unsigned TX1IE:1;
    unsigned RC1IE:1;
    unsigned ADIE:1;
    unsigned PSPIE:1;     /* Reserved - Do not use */
  };
  struct {
    unsigned :4;
    unsigned TXIE:1;
    unsigned RCIE:1;
  };
} PIE1bits;
extern volatile near unsigned char       PIR1;
extern volatile near union {
  struct {
    unsigned TMR1IF:1;
    unsigned TMR2IF:1;
    unsigned CCP1IF:1;
    unsigned SSPIF:1;     /* Reserved - Do not use */
    unsigned TX1IF:1;
    unsigned RC1IF:1;
    unsigned ADIF:1;
    unsigned PSPIF:1;     /* Reserved - Do not use */
  };
  struct {
    unsigned :4;
    unsigned TXIF:1;
    unsigned RCIF:1;
  };
} PIR1bits;
extern volatile near unsigned char       IPR1;     /* Reserved - Do not use */
extern volatile near union {
  struct {
    unsigned TMR1IP:1;
    unsigned TMR2IP:1;
    unsigned CCP1IP:1;
    unsigned SSPIP:1;
    unsigned TX1IP:1;
    unsigned RC1IP:1;
    unsigned ADIP:1;
    unsigned PSPIP:1;
  };
  struct {
    unsigned :4;
    unsigned TXIP:1;
    unsigned RCIP:1;
  };
} IPR1bits;             /* Reserved - Do not use */
extern volatile near unsigned char       PIE2;
extern volatile near struct {
  unsigned CCP2IE:1;
  unsigned TMR3IE:1;
  unsigned LVDIE:1;     /* Reserved - Do not use */
  unsigned BCLIE:1;     /* Reserved - Do not use */
  unsigned EEIE:1;      /* Reserved - Do not use */
  unsigned :1;
  unsigned CMIE:1;
} PIE2bits;
extern volatile near unsigned char       PIR2;
extern volatile near struct {
  unsigned CCP2IF:1;
  unsigned TMR3IF:1;
  unsigned LVDIF:1;     /* Reserved - Do not use */
  unsigned BCLIF:1;     /* Reserved - Do not use */
  unsigned EEIF:1;      /* Reserved - Do not use */
  unsigned :1;
  unsigned CMIF:1;
} PIR2bits;
extern volatile near unsigned char       IPR2;     /* Reserved - Do not use */
extern volatile near struct {
  unsigned CCP2IP:1;
  unsigned TMR3IP:1;
  unsigned LVDIP:1;
  unsigned BCLIP:1;
  unsigned EEIP:1;
  unsigned :1;
  unsigned CMIP:1;
} IPR2bits;     /* Reserved - Do not use */
extern volatile near unsigned char       PIE3;
extern volatile near struct {
  unsigned CCP3IE:1;
  unsigned CCP4IE:1;
  unsigned CCP5IE:1;
  unsigned TMR4IE:1;
  unsigned TX2IE:1;
  unsigned RC2IE:1;
} PIE3bits;
extern volatile near unsigned char       PIR3;
extern volatile near struct {
  unsigned CCP3IF:1;
  unsigned CCP4IF:1;
  unsigned CCP5IF:1;
  unsigned TMR4IF:1;
  unsigned TX2IF:1;
  unsigned RC2IF:1;
} PIR3bits;
extern volatile near unsigned char       IPR3;     /* Reserved - Do not use */
extern volatile near struct {
  unsigned CCP3IP:1;
  unsigned CCP4IP:1;
  unsigned CCP5IP:1;
  unsigned TMR4IP:1;
  unsigned TX2IP:1;
  unsigned RC2IP:1;
} IPR3bits;     /* Reserved - Do not use */
extern volatile near unsigned char       EECON1;     /* Use with caution. */
extern volatile near struct {
  unsigned RD:1;
  unsigned WR:1;
  unsigned WREN:1;
  unsigned WRERR:1;
  unsigned FREE:1;     /* Use with caution. Could result in program corruption. */
  unsigned :1;
  unsigned CFGS:1;
  unsigned EEPGD:1;
} EECON1bits;
extern volatile near unsigned char       EECON2;
extern volatile near unsigned char       EEDATA;
extern volatile near unsigned char       EEADR;
extern volatile near unsigned char       EEADRH;
extern volatile near unsigned char       RCSTA1;
extern volatile near union {
  struct {
    unsigned RX9D:1;
    unsigned OERR:1;
    unsigned FERR:1;
    unsigned ADEN:1;
    unsigned CREN:1;
    unsigned SREN:1;
    unsigned RX9:1;
    unsigned SPEN:1;
  };
  struct {
    unsigned :3;
    unsigned ADDEN:1;
  };
} RCSTA1bits;
extern volatile near unsigned char       TXSTA1;
extern volatile near struct {
  unsigned TX9D:1;
  unsigned TRMT:1;
  unsigned BRGH:1;
  unsigned :1;
  unsigned SYNC:1;
  unsigned TXEN:1;
  unsigned TX9:1;
  unsigned CSRC:1;
} TXSTA1bits;
extern volatile near unsigned char       TXREG1;
extern volatile near unsigned char       RCREG1;
extern volatile near unsigned char       SPBRG1;
extern volatile near unsigned char       PSPCON;     /* Reserved - Do not use */
extern volatile near struct {
  unsigned :4;
  unsigned PSPMODE:1;
  unsigned IBOV:1;
  unsigned OBF:1;
  unsigned IBF:1;
} PSPCONbits;     /* Reserved - Do not use */
extern volatile near unsigned char       T3CON;
extern volatile near union {
  struct {
    unsigned TMR3ON:1;
    unsigned TMR3CS:1;
    unsigned T3SYNC:1;
    unsigned T3CCP1:1;
    unsigned T3CKPS0:1;
    unsigned T3CKPS1:1;
    unsigned T3CCP2:1;
    unsigned RD16:1;
  };
  struct {
    unsigned :2;
    unsigned T3NSYNC:1;
  };
  struct {
    unsigned :2;
    unsigned NOT_T3SYNC:1;
  };
} T3CONbits;
extern volatile near unsigned            TMR3;
extern volatile near unsigned char       TMR3L;
extern volatile near unsigned char       TMR3H;
extern volatile near unsigned char       CMCON;
extern volatile near struct {
  unsigned CM0:1;
  unsigned CM1:1;
  unsigned CM2:1;
  unsigned CIS:1;
  unsigned C1INV:1;
  unsigned C2INV:1;
  unsigned C1OUT:1;
  unsigned C2OUT:1;
} CMCONbits;
extern volatile near unsigned char       CVRCON;
extern volatile near struct {
  unsigned CVR0:1;
  unsigned CVR1:1;
  unsigned CVR2:1;
  unsigned CVR3:1;
  unsigned CVREF:1;
  unsigned CVRR:1;
  unsigned CVROE:1;
  unsigned CVREN:1;
} CVRCONbits;
extern volatile near unsigned char       CCP3CON;
extern volatile near union {
  struct {
    unsigned CCP3M0:1;
    unsigned CCP3M1:1;
    unsigned CCP3M2:1;
    unsigned CCP3M3:1;
    unsigned DCCP3Y:1;
    unsigned DCCP3X:1;
  };
  struct {
    unsigned :4;
    unsigned DC3B0:1;
    unsigned DC3B1:1;
  };
} CCP3CONbits;
extern volatile near unsigned            CCPR3;
extern volatile near unsigned char       CCPR3L;
extern volatile near unsigned char       CCPR3H;
extern volatile near unsigned char       CCP2CON;
extern volatile near union {
  struct {
    unsigned CCP2M0:1;
    unsigned CCP2M1:1;
    unsigned CCP2M2:1;
    unsigned CCP2M3:1;
    unsigned DCCP2Y:1;
    unsigned DCCP2X:1;
  };
  struct {
    unsigned :4;
    unsigned CCP2Y:1;
    unsigned CCP2X:1;
  };
  struct {
    unsigned :4;
    unsigned DC2B0:1;
    unsigned DC2B1:1;
  };
} CCP2CONbits;
extern volatile near unsigned            CCPR2;
extern volatile near unsigned char       CCPR2L;
extern volatile near unsigned char       CCPR2H;
extern volatile near unsigned char       CCP1CON;
extern volatile near union {
  struct {
    unsigned CCP1M0:1;
    unsigned CCP1M1:1;
    unsigned CCP1M2:1;
    unsigned CCP1M3:1;
    unsigned DCCP1Y:1;
    unsigned DCCP1X:1;
  };
  struct {
    unsigned :4;
    unsigned CCP1Y:1;
    unsigned CCP1X:1;
  };
  struct {
    unsigned :4;
    unsigned DC1B0:1;
    unsigned DC1B1:1;
  };
} CCP1CONbits;
extern volatile near unsigned char       CCPR1L;
extern volatile near unsigned            CCPR1;
extern volatile near unsigned char       CCPR1H;
extern volatile near unsigned char       ADCON2;
extern volatile near struct {
  unsigned ADCS0:1;
  unsigned ADCS1:1;
  unsigned ADCS2:1;
  unsigned :4;
  unsigned ADFM:1;
} ADCON2bits;
extern volatile near unsigned char       ADCON1;
extern volatile near struct {
  unsigned PCFG0:1;
  unsigned PCFG1:1;
  unsigned PCFG2:1;
  unsigned PCFG3:1;
  unsigned VCFG0:1;
  unsigned VCFG1:1;
} ADCON1bits;
extern volatile near unsigned char       ADCON0;
extern volatile near union {
  struct {
    unsigned ADON:1;
    unsigned GO_DONE:1;
    unsigned CHS0:1;
    unsigned CHS1:1;
    unsigned CHS2:1;
    unsigned CHS3:1;
  };
  struct {
    unsigned :1;
    unsigned DONE:1;
  };
  struct {
    unsigned :1;
    unsigned GO:1;
  };
  struct {
    unsigned :1;
    unsigned NOT_DONE:1;
  };
} ADCON0bits;
extern volatile near unsigned            ADRES;
extern volatile near unsigned char       ADRESL;
extern volatile near unsigned char       ADRESH;
extern volatile near unsigned char       SSPCON2;     /* Reserved - Do not use */
extern volatile near struct {
  unsigned SEN:1;
  unsigned RSEN:1;
  unsigned PEN:1;
  unsigned RCEN:1;
  unsigned ACKEN:1;
  unsigned ACKDT:1;
  unsigned ACKSTAT:1;
  unsigned GCEN:1;
} SSPCON2bits;     /* Reserved - Do not use */
extern volatile near unsigned char       SSPCON1;     /* Reserved - Do not use */
                                      /* SSPCON1bits  Reserved */
extern volatile near unsigned char       SSPSTAT;     /* Reserved - Do not use */
extern volatile near union {
  struct {
    unsigned BF:1;
    unsigned UA:1;
    unsigned R_W:1;
    unsigned S:1;
    unsigned P:1;
    unsigned D_A:1;
    unsigned CKE:1;
    unsigned SMP:1;
  };
  struct {
    unsigned :2;
    unsigned I2C_READ:1;
    unsigned I2C_START:1;
    unsigned I2C_STOP:1;
    unsigned I2C_DAT:1;
  };
  struct {
    unsigned :2;
    unsigned NOT_W:1;
    unsigned :2;
    unsigned NOT_A:1;
  };
  struct {
    unsigned :2;
    unsigned NOT_WRITE:1;
    unsigned :2;
    unsigned NOT_ADDRESS:1;
  };
  struct {
    unsigned :2;
    unsigned READ_WRITE:1;
    unsigned :2;
    unsigned DATA_ADDRESS:1;
  };
  struct {
    unsigned :2;
    unsigned R:1;
    unsigned :2;
    unsigned D:1;
  };
} SSPSTATbits;     /* Reserved - Do not use */
extern volatile near unsigned char       SSPADD;     /* Reserved - Do not use */
extern volatile near unsigned char       SSPBUF;     /* Reserved - Do not use */
extern volatile near unsigned char       T2CON;
extern volatile near struct {
  unsigned T2CKPS0:1;
  unsigned T2CKPS1:1;
  unsigned TMR2ON:1;
  unsigned T2OUTPS0:1;
  unsigned T2OUTPS1:1;
  unsigned T2OUTPS2:1;
  unsigned T2OUTPS3:1;
} T2CONbits;
extern volatile near unsigned char       PR2;
extern volatile near unsigned char       TMR2;
extern volatile near unsigned char       T1CON;
extern volatile near union {
  struct {
    unsigned TMR1ON:1;
    unsigned TMR1CS:1;
    unsigned T1SYNC:1;
    unsigned T1OSCEN:1;
    unsigned T1CKPS0:1;
    unsigned T1CKPS1:1;
    unsigned :1;
    unsigned RD16:1;
  };
  struct {
    unsigned :2;
    unsigned T1INSYNC:1;
  };
  struct {
    unsigned :2;
    unsigned NOT_T1SYNC:1;
  };
} T1CONbits;
extern volatile near unsigned char       TMR1L;
extern volatile near unsigned            TMR1;
extern volatile near unsigned char       TMR1H;
extern volatile near unsigned char       RCON;     /* Reserved - Do not use */
extern volatile near union {
  struct {
    unsigned NOT_BOR:1;
    unsigned NOT_POR:1;
    unsigned NOT_PD:1;
    unsigned NOT_TO:1;
    unsigned NOT_RI:1;
    unsigned :2;
    unsigned NOT_IPEN:1;
  };
  struct {
    unsigned BOR:1;
    unsigned POR:1;
    unsigned PD:1;
    unsigned TO:1;
    unsigned RI:1;
    unsigned :2;
    unsigned IPEN:1;
  };
} RCONbits;     /* Reserved - Do not use */
extern volatile near unsigned char       WDTCON;     /* Reserved - Do not use */
extern volatile near union {
  struct {
    unsigned SWDTEN:1;
  };
  struct {
    unsigned SWDTE:1;
  };
} WDTCONbits;     /* Reserved - Do not use */
extern volatile near unsigned char       LVDCON;     /* Reserved - Do not use */
extern volatile near union {
  struct {
    unsigned LVDL0:1;
    unsigned LVDL1:1;
    unsigned LVDL2:1;
    unsigned LVDL3:1;
    unsigned LVDEN:1;
    unsigned IRVST:1;
  };
  struct {
    unsigned LVV0:1;
    unsigned LVV1:1;
    unsigned LVV2:1;
    unsigned LVV3:1;
    unsigned :1;
    unsigned BGST:1;
  };
} LVDCONbits;     /* Reserved - Do not use */
extern volatile near unsigned char       OSCCON;     /* Reserved - Do not use */
extern volatile near struct {
  unsigned SCS:1;
} OSCCONbits;                                        /* Reserved - Do not use */
extern volatile near unsigned char       T0CON;      /* Reserved - Do not use if you are using ifi_library.lib */
extern volatile near struct {
  unsigned T0PS0:1;
  unsigned T0PS1:1;
  unsigned T0PS2:1;
  unsigned PSA:1;
  unsigned T0SE:1;
  unsigned T0CS:1;
  unsigned T08BIT:1;
  unsigned TMR0ON:1;
} T0CONbits;                                     /* Reserved - Do not use if you are using ifi_library.lib */
extern volatile near unsigned            TMR0;   /* Reserved - Do not modify if you are using ifi_library.lib */
extern volatile near unsigned char       TMR0L;  /* Reserved - Do not modify if you are using ifi_library.lib */
extern volatile near unsigned char       TMR0H;  /* Reserved - Do not modify if you are using ifi_library.lib */
extern          near unsigned char       STATUS;
extern          near struct {
  unsigned C:1;
  unsigned DC:1;
  unsigned Z:1;
  unsigned OV:1;
  unsigned N:1;
} STATUSbits;
extern          near unsigned            FSR2;  /* Reserved - Do not use */
extern          near unsigned char       FSR2L;  /* Reserved - Do not use */
extern          near unsigned char       FSR2H;  /* Reserved - Do not use */
extern volatile near unsigned char       PLUSW2;  /* Reserved - Do not use */
extern volatile near unsigned char       PREINC2;  /* Reserved - Do not use */
extern volatile near unsigned char       POSTDEC2;  /* Reserved - Do not use */
extern volatile near unsigned char       POSTINC2;  /* Reserved - Do not use */
extern          near unsigned char       INDF2;  /* Reserved - Do not use */
extern          near unsigned char       BSR;  /* Reserved - Do not use */
extern          near unsigned            FSR1;  /* Reserved - Do not use */
extern          near unsigned char       FSR1L;  /* Reserved - Do not use */
extern          near unsigned char       FSR1H;  /* Reserved - Do not use */
extern volatile near unsigned char       PLUSW1;  /* Reserved - Do not use */
extern volatile near unsigned char       PREINC1;  /* Reserved - Do not use */
extern volatile near unsigned char       POSTDEC1;  /* Reserved - Do not use */
extern volatile near unsigned char       POSTINC1;  /* Reserved - Do not use */
extern          near unsigned char       INDF1;  /* Reserved - Do not use */
extern          near unsigned char       WREG;  /* Use at your own risk. */
extern          near unsigned char       FSR0L;  /* Use at your own risk. */
extern          near unsigned            FSR0;  /* Use at your own risk. */
extern          near unsigned char       FSR0H;  /* Use at your own risk. */
extern volatile near unsigned char       PLUSW0;  /* Use at your own risk. */
extern volatile near unsigned char       PREINC0;  /* Use at your own risk. */
extern volatile near unsigned char       POSTDEC0;  /* Use at your own risk. */
extern volatile near unsigned char       POSTINC0;  /* Use at your own risk. */
extern          near unsigned char       INDF0;  /* Use at your own risk. */
extern volatile near unsigned char       INTCON3;
extern volatile near union {
  struct {
    unsigned INT1IF:1;
    unsigned INT2IF:1;
    unsigned INT3IF:1;
    unsigned INT1IE:1;
    unsigned INT2IE:1;
    unsigned INT3IE:1;
    unsigned INT1IP:1;     /* Reserved - Do not use */
    unsigned INT2IP:1;     /* Reserved - Do not use */  /* Must be set to 0 (low priority) */
  };
  struct {
    unsigned INT1F:1;
    unsigned INT2F:1;
    unsigned INT3F:1;
    unsigned INT1E:1;
    unsigned INT2E:1;
    unsigned INT3E:1;
    unsigned INT1P:1;     /* Reserved - Do not use */
    unsigned INT2P:1;     /* Reserved - Do not use */
  };
} INTCON3bits;
extern volatile near unsigned char       INTCON2;
extern volatile near union {
  struct {
    unsigned RBIP:1;        /* Reserved - Do not use */
    unsigned INT3IP:1;      /* Reserved - Do not use */
    unsigned TMR0IP:1;      /* Reserved - Do not use */
    unsigned INTEDG3:1;
    unsigned INTEDG2:1;
    unsigned INTEDG1:1;
    unsigned INTEDG0:1;     /* Reserved - Do not use */
    unsigned NOT_RBPU:1;    /* Reserved - Do not use */
  };
  struct {
    unsigned :1;
    unsigned INT3P:1;     /* Reserved - Do not use */
    unsigned T0IP:1;      /* Reserved - Do not use */
    unsigned :4;
    unsigned RBPU:1;      /* Reserved - Do not use */
  };
} INTCON2bits;
extern volatile near unsigned char       INTCON;
extern volatile near union {
  struct {
    unsigned RBIF:1;
    unsigned INT0IF:1;  /* Reserved - Do not use */
    unsigned TMR0IF:1;  /* Reserved - Do not modify if you are using ifi_library.lib */
    unsigned RBIE:1;
    unsigned INT0IE:1;  /* Reserved - Do not use */
    unsigned TMR0IE:1;  /* Reserved - Do not use if you are using ifi_library.lib */
    unsigned PEIE:1;
    unsigned GIE:1;     /* Reserved - Do not use */
  };
  struct {
    unsigned :1;
    unsigned INT0F:1;   /* Reserved - Do not use */
    unsigned T0IF:1;
    unsigned :1;
    unsigned INT0E:1;   /* Reserved - Do not use */
    unsigned T0IE:1;
    unsigned GIEL:1;    /* Use of this bit could lead to unexpected results */
    unsigned GIEH:1;    /* Reserved - Do not use */
  };
} INTCONbits;
extern          near unsigned char       PRODL;
extern          near unsigned            PROD;
extern          near unsigned char       PRODH;
extern volatile near unsigned char       TABLAT;
extern volatile near unsigned char       TBLPTRL;
extern volatile near unsigned short long TBLPTR;
extern volatile near unsigned char       TBLPTRH;
extern volatile near unsigned char       TBLPTRU;
extern volatile near unsigned char       PCL;
extern volatile near unsigned short long PC;
extern volatile near unsigned char       PCLATH;
extern volatile near unsigned char       PCLATU;
extern volatile near unsigned char       STKPTR;
extern volatile near union {
  struct {
    unsigned STKPTR0:1;
    unsigned STKPTR1:1;
    unsigned STKPTR2:1;
    unsigned STKPTR3:1;
    unsigned STKPTR4:1;
    unsigned :1;
    unsigned STKUNF:1;
    unsigned STKOVF:1;
  };
  struct {
    unsigned :7;
    unsigned STKFUL:1;
  };
} STKPTRbits;
extern          near unsigned short long TOS;
extern          near unsigned char       TOSL;
extern          near unsigned char       TOSH;
extern          near unsigned char       TOSU;

#if defined(BANKED)
#error  *** Error - Invalid 18f8520 header file!
#else
#define UNCHANGEABLE_DEFINITION_AREA 1
#endif
/*-------------------------------------------------------------------------
 * Some useful defines for inline assembly stuff
 *-------------------------------------------------------------------------*/
#define ACCESS 0
#define BANKED 1

/*-------------------------------------------------------------------------
 * Some useful macros for inline assembly stuff
 *-------------------------------------------------------------------------*/
#define Nop()    {_asm nop _endasm}
#define ClrWdt() {_asm clrwdt _endasm}
#define Sleep()  {_asm sleep _endasm}
#define Reset()  {_asm reset _endasm}

#define Rlcf(f,dest,access)  {_asm movlb f rlcf f,dest,access _endasm}
#define Rlncf(f,dest,access) {_asm movlb f rlncf f,dest,access _endasm}
#define Rrcf(f,dest,access)  {_asm movlb f rrcf f,dest,access _endasm}
#define Rrncf(f,dest,access) {_asm movlb f rrncf f,dest,access _endasm}
#define Swapf(f,dest,access) {_asm movlb f swapf f,dest,access _endasm }

/*-------------------------------------------------------------------------
 * A fairly inclusive set of registers to save for interrupts.
 * These are locations which are commonly used by the compiler.
 *-------------------------------------------------------------------------*/
#define INTSAVELOCS TBLPTR, TABLAT, PROD

#endif
/*******************************************************************************
* FILE NAME: ifi_utilities.h
*
* DESCRIPTION: 
*  This is the include file which corresponds to ifi_utilities.c
*  It contains some aliases and function prototypes used in that file.
*
* USAGE:
*  This file should not be modified by the user.
*  DO NOT EDIT THIS FILE!
*******************************************************************************/

#ifndef __ifi_utilities_h_
#define __ifi_utilities_h_

#ifdef _SNOOP_ON_COM1    /* FOR FUTURE USE */
#define RXINTF              PIR3bits.RC2IF
#define RXINTE              PIE3bits.RC2IE
#define TXINTF              PIR3bits.TX2IF 
#define TXINTE              PIE3bits.TX2IE
#define RCSTAbits           RCSTA2bits
#define RCSTA               RCSTA2
#define TXSTA               TXSTA2
#define TXREG               TXREG2
#define RCREG               RCREG2
#define SPBRG               SPBRG2
#define OpenUSART           Open2USART
#else
#define RXINTF              PIR1bits.RCIF
#define RXINTE              PIE1bits.RCIE
#define TXINTF              PIR1bits.TXIF 
#define TXINTE              PIE1bits.TXIE
#define RCSTAbits           RCSTA1bits
#define RCSTA               RCSTA1
#define TXSTA               TXSTA1
#define TXREG               TXREG1
#define RCREG               RCREG1
#define SPBRG               SPBRG1
#define OpenUSART           Open1USART
#endif

/*******************************************************************************
                             MACRO DEFINITIONS
*******************************************************************************/

typedef enum
{
  baud_19 = 15,
  baud_38 = 64,
  baud_56 = 42,
  baud_115 = 21
} SERIAL_SPEED;


/*******************************************************************************
                           FUNCTION PROTOTYPES
*******************************************************************************/

void Hex_output(unsigned char temp);  /* located in ifi_library.lib */

#ifdef _FRC_BOARD
  /* located in ifi_library.lib */
void Generate_Pwms(unsigned char pwm_13,unsigned char pwm_14,
                   unsigned char pwm_15,unsigned char pwm_16);
#else
  /* located in ifi_library.lib */
void Generate_Pwms(unsigned char pwm_1,unsigned char pwm_2,
                   unsigned char pwm_3,unsigned char pwm_4,
                   unsigned char pwm_5,unsigned char pwm_6,
                   unsigned char pwm_7,unsigned char pwm_8);
#endif

/* These routines reside in ifi_utilities.c */
void Wait4TXEmpty(void);
void PrintByte(unsigned char odata);
void PrintWord(unsigned int odata);
void PrintString(char *bufr);
void DisplayBufr(unsigned char *bufr);
void PacketNum_Check(void);
void Initialize_Serial_Comms (void);
void Set_Number_of_Analog_Channels (unsigned char number_of_channels);
unsigned int Get_Analog_Value(unsigned char channel);

#endif


/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
/*******************************************************************************
*
*	TITLE:		navigate.h 
*
*	VERSION:	1.0                          
*
*	DATE:		08-Jan-2004
*
*	AUTHOR:		Richard D. Petras
*
*	COMMENTS:
*
********************************************************************************
*
*	CHANGE LOG:
*
*	DATE         REV  DESCRIPTION
*	-----------  ---  ----------------------------------------------------------
*	03-Dec-2003  0.1  
*   08-Jan-2004  1.0  RDP The version used at the 2004 kickoff
*
*******************************************************************************/
#ifndef _navigate_h
#define _navigate_h

#include "tracker.h"

// Navigator state machine values
// These values will be stored in a global variable called 
// Navigator_State.  As each state transition is detected,
// the state will change to describe how the vehicle should
// operate.
#define WAIT_TO_DRIVE 0
#define	DRIVE_TO_CENTER 1
#define	TURN_TO_TARGET 2
#define	DRIVE_TO_TARGET 3
#define	PASSED_TARGET 4
#define	AT_TARGET 5
#define OVER_CURRENT 6

// Drive state 
// These values are stored in the drive_state variable.  They tell
// us where the beacon is with respect to each tracker on the robot.
#define DR_UNDEFINED 0
#define DR_BOTH_LEFT 1
#define DR_BOTH_RIGHT 2
#define DR_BOTH_STRAIGHT 3
#define DR_BOTH_CENTER 4
#define DR_LEFT_STRAIGHT 5
#define DR_RIGHT_STRAIGHT 6
#define DR_REFLECTION 7

// Some values for each individual tracker
#define DR_LEFT 0
#define DR_CENTER 1
#define DR_RIGHT 2

// Which pwms are our tracker servoes and drive motors?  It
// is nice to only have to change this in one place.
#define left_servo pwm10
#define right_servo pwm11
#define left_drive pwm14 
#define right_drive pwm15

// Simplify the big structure for beacon quality
// from the tracker code.
#define LL Sensor_Stats[0].Beacon_Quality[Tracker_Data[left].Beacon_Type]
#define LR Sensor_Stats[1].Beacon_Quality[Tracker_Data[left].Beacon_Type]
#define RL Sensor_Stats[2].Beacon_Quality[Tracker_Data[right].Beacon_Type]
#define RR Sensor_Stats[3].Beacon_Quality[Tracker_Data[right].Beacon_Type]

// The rest of these defines are tweekable parameters to fit
// the characteristics of different drive trains.  You might
// want to divide these into a separate set of values for the
// left and right side drives if your motor characteristics
// are sufficiently different.  This would require changing
// navigator.c, but the places to make the changes should be 
// obvious. :-)

//  Stop values
#define LSTOP 127      
#define RSTOP 127

// Fast backward
#define FBWD (LSTOP - 90)

// Slow Backward
#define SBWD (LSTOP - 55)

// Very Slow Backward
#define VSBWD (LSTOP - 10)

// Very Slow Forward
#define VSFWD (LSTOP + 10)

// Slow Forward
#define SFWD (LSTOP + 55)

// Fast Forward
#define FFWD (LSTOP + 90)

// Note: All the logic assumes the servo max points right
// Its not too hard to change the code to accomidate the other
// direction, in fact the code started out that way...

// These values are the servo settings (assuming 127 is straight
// ahead) that tells you that the beacon is between the trackers
// and about 1/2 meter ahead.  The exact values will depend on the
// baseline of your trackers.
#define LEFT_GOAL 135
#define RIGHT_GOAL 120

// These values tell you when the target is far to the left of the
// left servo, or far to the right of the right servo.  We switch
// navigator states at this point
#define LEFT_PASS 60
#define RIGHT_PASS 195

// Adjust these for your drive train

// This is the gain that is multiplied by your pointing error.
// It can be used as part of a feedback loop to steer toward the
// goal.  Note: the error calculation is included in the code
// as an example, but was not used in the actual kickoff demo.
// (we wanted to drive straight until we passed the goal)
#define DRIVE_GAIN 2

// This is a timer for the short drive away from the wall before
// we start to turn in place toward the beacon.
#define DRIVE_TO_CENTER_TIME 5

// I bet you didn't know we were using the current sensors in the
// kickoff demo.  If the current sensor reading got above this 
// value, we might be up against the wall.  In that case we might
// want to stop driving for a short time to allow the robot to level 
// out.
#define MAX_CURRENT 700


// If we haven't seen the target with any of the trackers for 
// a while,  just start searching again by turning in place.  
#define LOST_TARGET_TIMEOUT 100

// Declaration for the Navigate function
void Navigate(void);

#endif // _navigate_h
/*******************************************************************************
* FILE NAME: printf_lib.h
*
* DESCRIPTION: 
*  This is the include file which corresponds to printf_lib.c
*
* USAGE:
*  If you add your own routines to that file, this is a good place
*  to add function prototypes.
*******************************************************************************/

#ifndef __printf_lib_h_
#define __printf_lib_h_

int printf(rom const char *format, ...);

void printid(int data,int crtOn);
void printb(unsigned char data,int crtOn);
void printd(unsigned char data,int crtOn);
void printix(int data,int crtOn);
void printx(unsigned char data,int crtOn);
void debug_print(char *bufr,int data);
void debug_printb(char *bufr,unsigned int data);
void debug_println(char *bufr);

#endif


/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
/*******************************************************************************
*
*	TITLE:		receiver.h 
*
*	VERSION:	1.1                          
*
*	DATE:		04-Feb-2004
*
*	AUTHOR:		R. Kevin Watson
*
*	COMMENTS:
*
********************************************************************************
*
*	CHANGE LOG:
*
*	DATE         REV  DESCRIPTION
*	-----------  ---  ----------------------------------------------------------
*	28-Nov-2003  0.3  RKW Original
*	30-Nov-2003  0.4  RKW - Changed Sensor_Stats definition, making Beacon_Count
*	                  and Beacon_Quality an array.
*	04-Dec-2003  0.5  RKW - Changed timer 1 prescaler to 4:1 from 8:1 to double
*	                  the tracker control rate to 38Hz.
*	07-Dec-2003  0.6  RKW - Turned Sensor_Stats into an array so that the code
*	                  in tracker.c can be simplified.
*	09-Jan-2004  1.0  RKW - This version used for kick-off demo
*	04-Feb-2004  1.1  RKW - Fixed minor bug in the interrupt handlers that
*	                  erroneously incremented Sensor_Stats[n].Beacon_Quality[0]
*
*******************************************************************************/
#ifndef _receiver_h
#define _receiver_h

// function prototypes
void Initialize_Receiver(void);
void Timer_1_Int_Handler(void);		// timer 1 interrupt handler
void Int_1_Handler(void);			// IR sensor 1 interrupt handler
void Int_2_Handler(void);			// IR sensor 2 interrupt handler
void Int_4_Handler(unsigned char);	// IR sensor 3 interrupt handler
void Int_5_Handler(unsigned char);	// IR sensor 4 interrupt handler

// some handy macros
#define HIBYTE(value) ((unsigned char)(((unsigned int)(value)>>8)&0xFF))
#define LOBYTE(value) ((unsigned char)(value))

// pulse-width discrimination defines
// type 0 average = 2720 clock ticks
#define BEACON_0_LOWER_BOUND 2040 // average-25% 
#define BEACON_0_UPPER_BOUND 3400 // average+25%

// type 1 average = 5224 clock ticks
#define BEACON_1_LOWER_BOUND 3918 // average-25%
#define BEACON_1_UPPER_BOUND 6530 // average+25%

// state machine defines
#define WAITING_FOR_UP_EDGE 0
#define WAITING_FOR_DOWN_EDGE 1

// Sensor_Stats definition -- tracker.c/Track_Beacon() directly accesses this data
typedef struct tagSensor_Stats
{
	unsigned long Total_Count;		 // number of IR pulses detected
	unsigned long Invalid_Count;	 // number of IR pulses that couldn't be catagorized
	unsigned long Beacon_Count[2];   // number of IR pulses that were type 0 or 1
	unsigned char Beacon_Quality[2]; // number of valid type 0 or 1 beacons in the last 26 milliseconds
}Sensor_Stats_Struct;

// variable definitions

extern unsigned int Clock; // in receiver.c

extern Sensor_Stats_Struct Sensor_Stats[4]; // in receiver.c

#endif // _receiver_h
/*******************************************************************************
*
*	TITLE:		tracker.h 
*
*	VERSION:	1.0                           
*
*	DATE:		09-Jan-2004
*
*	AUTHOR:		R. Kevin Watson
*
*	COMMENTS:
*
********************************************************************************
*
*	CHANGE LOG:
*
*	DATE         REV  DESCRIPTION
*	-----------  ---  ----------------------------------------------------------
*	03-Dec-2003  0.1  RKW Original
*	07-Dec-2003  0.2  RKW - Modified Track_Beacon() to handle an arbitrary number
*	                  of IR beam tracking assemblies. All state machine
*	                  information is now kept in the Tracker_Data data structure.
*	                  RKW - Cleaned-up Track_Beacon to make it understandable,
*	                  hiding most of the tough-to-grasp code here.
*	09-Jan-2004  1.0  RKW - This version used for kick-off demo
*
*******************************************************************************/
#ifndef _tracker_h
#define _tracker_h

#include "receiver.h"

// type of beacon to search for
#define BEACON_TYPE rc_dig_in07 // this assumes that rc_dig_in07 is a digital input

// assign sensors to the trackers
#define LEFT_TRACKER_LEFT_SENSOR 0		// entry 0 of Sensor_Stats[] will provide this beacon data
#define LEFT_TRACKER_RIGHT_SENSOR 1		// entry 1 of Sensor_Stats[] will provide this beacon data
#define RIGHT_TRACKER_LEFT_SENSOR 2		// entry 2 of Sensor_Stats[] will provide this beacon data
#define RIGHT_TRACKER_RIGHT_SENSOR 3	// entry 3 of Sensor_Stats[] will provide this beacon data

// define the PWM channels to use for the tracker servo motors
#define LEFT_TRACKER_SERVO pwm01
#define RIGHT_TRACKER_SERVO pwm02

// define the starting position of the servo motors
#define INITIAL_SERVO_POSITION 127

// define the initial servo motor step size
// this may be a negitive value for some types of servo motors
// if your servo oscillates in the presence of the IR beacon try
// changing the sign
#define INITIAL_SERVO_STEP_SIZE -4

// define the beacon types
#define BEACON_TYPE_0 0
#define BEACON_TYPE_1 1

// define the tracker identification numbers
#define LEFT 0
#define RIGHT 1

// define the tracker states
#define NONE_IN_VIEW 0
#define RIGHT_IN_VIEW 1
#define LEFT_IN_VIEW 2
#define BOTH_IN_VIEW 3

// this expression is the state of the current tracker
#define TRACKER_STATUS Tracker_Data[Tracker].Status

// this expression is the current tracker servo motor position
#define TRACKER_POSITION Tracker_Data[Tracker].Position

// this expression is the step increment for the current trackers servo motor
#define SEARCH_INCREMENT Tracker_Data[Tracker].Search_Increment

// this lengthy expression is just the number of IR beacon pulses received 
// by the current trackers left sensor in the last clock period.
#define LEFT_SENSOR Sensor_Stats[Tracker_Data[Tracker].Left_Sensor_Stats_Index].Beacon_Quality[Tracker_Data[Tracker].Beacon_Type]

// this lengthy expression is just the number of IR beacon pulses received
// by the current trackers right sensor in the last clock period.
#define RIGHT_SENSOR Sensor_Stats[Tracker_Data[Tracker].Right_Sensor_Stats_Index].Beacon_Quality[Tracker_Data[Tracker].Beacon_Type]

// function prototypes
void Initialize_Tracker(void);
void Track_Beacon(unsigned char); 

// define the tracker data structure
typedef struct tagTracker_Data
{
	unsigned char Status;					// tracker state (defined above)
	unsigned char Position;					// current commanded servo motor position
	unsigned char Search_Increment;			// servo motor search step increment
	unsigned char Beacon_Type;				// beacon type to search for
	unsigned char Left_Sensor_Stats_Index;	// which sensor entry, in sensor stats, will provide data
	unsigned char Right_Sensor_Stats_Index;	// for the left and right sensors of this tracker
}Tracker_Data_Struct;

extern Tracker_Data_Struct Tracker_Data[2];


#endif // _tracker_h
/*******************************************************************************
* FILE NAME: user_routines.h
*
* DESCRIPTION: 
*  This is the include file which corresponds to user_routines.c and
*  user_routines_fast.c
*  It contains some aliases and function prototypes used in those files.
*
* USAGE:
*  If you add your own routines to those files, this is a good place to add
*  your custom macros (aliases), type definitions, and function prototypes.
*******************************************************************************/

#ifndef __user_program_h_
#define __user_program_h_


/*******************************************************************************
                            MACRO DECLARATIONS
*******************************************************************************/
/* Add your macros (aliases and constants) here.                              */
/* Do not edit the ones in ifi_aliases.h                                      */
/* Macros are substituted in at compile time and make your code more readable */
/* as well as making it easy to change a constant value in one place, rather  */
/* than at every place it is used in your code.                               */
/*
 EXAMPLE CONSTANTS:
#define MAXIMUM_LOOPS   5
#define THE_ANSWER      42
#define TRUE            1
#define FALSE           0
#define PI_VAL          3.1415

 EXAMPLE ALIASES:
#define LIMIT_SWITCH_1  rc_dig_int1  (Points to another macro in ifi_aliases.h)
#define MAIN_SOLENOID   solenoid1    (Points to another macro in ifi_aliases.h)
*/

/* Used in limit switch routines in user_routines.c */
#define OPEN        1     /* Limit switch is open (input is floating high). */
#define CLOSED      0     /* Limit switch is closed (input connected to ground). */


/*******************************************************************************
                            TYPEDEF DECLARATIONS
*******************************************************************************/
/* EXAMPLE DATA STRUCTURE */
/*
typedef struct
{
  unsigned int  NEW_CAPTURE_DATA:1;
  unsigned int  LAST_IN1:1;
  unsigned int  LAST_IN2:1;
  unsigned int  WHEEL_COUNTER_UP:1;
  unsigned int  :4;
  unsigned int wheel_left_counter;
  unsigned int wheel_right_counter;
} user_struct;
*/


/*******************************************************************************
                           FUNCTION PROTOTYPES
*******************************************************************************/

/* These routines reside in user_routines.c */
void User_Initialization(void);
void Process_Data_From_Master_uP(void);
void Default_Routine(void);

/* These routines reside in user_routines_fast.c */
void InterruptHandlerLow (void);  /* DO NOT CHANGE! */
void User_Autonomous_Code(void);  /* Only in full-size FRC system. */
void Process_Data_From_Local_IO(void);


#endif
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/