kevins serial driver code

i’m trying to use kevins serial driver code version 0.3

i’ve changed all the registers to work on a 18f452 (which i have on a demo board with a serial port hooked up) the serial port is live as we used a multimeter to test and its data ready line is open at 10.8 volts if i remember correctly. so i don’t think its the connection from board to PC

when i step thorugh on my icd 2 debugger the code loops and gets stuck here:


	// if the queue is full, wait here until space is available
	while(Tx_2_Queue_Full);//<----------the queue never empties

	// put the byte on the circular queue
	Tx_2_Queue[Tx_2_Queue_Write_Index] = byte;

	// increment the queue byte count
	Tx_2_Queue_Byte_Count++;

	// increment the write pointer
	Tx_2_Queue_Write_Index++;


 

any ideas? i’ve been trying to get this serial driver working for a week now. i’m seriously stuck and at a loss for ways to fix it

heres the whole files
serial_ports.c

 
/**************************************************  *****************************
*
*	TITLE:		serial_ports.c 
*
*	VERSION:	0.3 (Beta)                           
*
*	DATE:		05-Feb-2005
*
*	AUTHOR:		R. Kevin Watson
*				kevinw@jpl.nasa.gov
*
*	COMMENTS:	The source code in this file implements a fully buffered,
*				interrupt-driven serial port driver that can be used with
*				either or both on-board serial ports.
*
*				This source code will work with the Robovation (A/K/A EDU-RC) 
*				robot controller and the FIRST Robotics robot controller.
*
*				By default, serial port one will operate at 115200 baud, which
*				is compatible with InnovationFIRST's terminal program, and
*				serial port two will operate at 9600 baud. These values can be
*				easily changed by modifying the	serial port initialization 
*				functions mentioned below.
*
*               This file is best viewed with tabs set to four characters.
*
*				Nine things must be done before this software will work 
*				correctly:
*
*				  1a) FRC-RC: As this software is intended to replace IFI's
*				  serial port driver, the call to Serial_Driver_Initialize()
*				  in user_routines.c / User_Initialization() should be 
*				  removed or commented out.	In addition, all references to
*				  "user_Serialdrv.c" and "user_Serialdrv.h" must be removed 
*				  from the project and all project source files.
*
*				  1b) EDU-RC: As this software is intended to replace IFI's
*				  serial port driver, the call to Initialize_Serial_Comms()
*				  in user_routines.c / User_Initialization() should be 
*				  removed or commented out.	In addition, all references to
*				  "printf_lib.c" and "printf_lib.h" must be removed from 
*				  the project and all project source files.
*
*				  2) You must add the serial_ports.c/.h source files to
*				  your MPLAB project.
*
*				  3) A #include statement for the serial_ports.h header
*				  file must be included at the beginning of each source
*				  file that uses the serial ports. The statement should
*				  look like this: #include "serial_ports.h".
*
*				  4) If you intend to use the C18 output stream functions,
*				  A #include statement for the stdio.h header file must be 
*				  included at the beginning of each source file that calls
*				  any of these functions. The statement should look like 
*				  this: #include <serial_ports.h>.
*
*				  5) Init_Serial_Port_One() and/or Init_Serial_Port_Two()
*				  must be called from the User_Initialization() function 
*				  located in the user_routines.c source file.
*
*				  6) The interrupt handler(s) must be installed in the
*				  InterruptHandlerLow() function located in the 
*				  user_routines_fast.c source file. See the accompanying
*				  copy of user_routines_fast.c to see how this is done.
*
*				  7) Decide what functionality you need and comment out the
*				  #define ENABLE_SERIAL_PORT_xxx_yy entries in serial_ports.h
*				  as necessary. As an example, if you only need to send data
*				  using serial port one and would like to reclaim the resources
*				  used by serial port two and serial port one's receiver
*				  source code, the top of the serial_ports.h file would look
*				  like this:
*
*				  // comment out the next line to disable all serial port one
*				  // receive functionality
*				  // #define ENABLE_SERIAL_PORT_ONE_RX
*
*				  // comment out the next line to disable all serial port one
*				  // transmit functionality
*				  #define ENABLE_SERIAL_PORT_ONE_TX
*
*				  // comment out the next line to disable all serial port two
*				  // receive functionality
*				  // #define ENABLE_SERIAL_PORT_TWO_RX
*
*				  // comment out the next line to disable all serial port two
*				  // transmit functionality
*				  // #define ENABLE_SERIAL_PORT_TWO_TX
*
*				  By default, both serial ports and their respective receive
*				  and transmit sections are enabled.
*
*				  8) As the default output device for C18's output stream 
*				  functions is the null device, you'll presumably want to 
*				  change the value of stdout_serial_port to "SERIAL_PORT_ONE" 
*				  or "SERIAL_PORT_TWO" if you want to see printf()'s output.
*				  User_Initialization() is a good place to do this.
*
*				  9) To support terminal emulation software, 
 should 
*				  be used instead of just 
 in the printf() format string.
*
*
*				This serial port driver can send output stream data to either 
*				of the serial ports by setting the value of the global variable
*				stdout_serial_port before calling output stream	functions like
*				printf(). Setting the value	to "SERIAL_PORT_ONE" will send the 
*				output to serial port one. Likewise, setting the value to 
*				"SERIAL_PORT_TWO" will send the output to serial port two. 
*				Setting the value to "NUL" will send the output to the null 
*				device, meaning that the output is sent	nowhere. These values 
*				are #define'd in serial_ports.h. As an example,
*
*				  stdout_serial_port = SERIAL_PORT_ONE;
*				  printf("Kernighan");
*				  stdout_serial_port = NUL;
*				  printf("and");
*				  stdout_serial_port = SERIAL_PORT_TWO;
*				  printf("Ritchie");
*
*				will send the text "Kernighan" to the peripheral device attached
*				to serial port one, the text "Ritchie" to the device attached to 
*				serial port two and the text "and" won't be sent anywhere.
*				By default, output is sent to the null device, which is the only
*				output device guaranteed to be present.
*
*				You are free to use this source code for any non-commercial
*				use. Please do not make copies of this source code, modified
*				or un-modified, publicly available on the internet or
*				elsewhere without permission. Thanks.
*
*				Copyright ©2004-2005 R. Kevin Watson. All rights are reserved.
*		
**************************************************  ******************************
*
*	CHANGE LOG:
*
*	DATE         REV  DESCRIPTION
*	-----------  ---  ----------------------------------------------------------
*	22-Dec-2004  0.1  RKW - Original code.
*	28-Dec-2004  0.2  RKW - Using preprocessor directives, added the ability 
*	                  to enable/disable individual serial port receive and 
*	                  transmit code. Updated documentation.
*	05-Feb-2005  0.3  RKW - Added _user_putc() interface to C18's new output
*	                  stream capabilities. Updated documentation.
*
**************************************************  *****************************/
#include <stdio.h>
#include "p18f452.h"
#include "serial_ports.h"

// by default stdout stream output is sent to the null device, 
// which is the only device guaranteed to be present. 
unsigned char stdout_serial_port = NUL;

//
// Serial Port 2 Receive Variables:
//

#ifdef ENABLE_SERIAL_PORT_TWO_RX

volatile unsigned char Rx_2_Queue[RX_2_QUEUE_SIZE];	// serial port 2's receive circular queue

volatile unsigned char Rx_2_Queue_Full = FALSE;		// flag that indicates that serial port 2's
													// receive circular queue is full and cannot
													// accept any more data

unsigned char Rx_2_Queue_Empty = TRUE;				// flag that indicates that there is no more 
													// data present in serial port 2's receive
													// circular queue
		
unsigned char Rx_2_Queue_Read_Index = 0;			// read index into serial port 2's receive
													// circular queue

volatile unsigned char Rx_2_Queue_Write_Index = 0;	// write index into serial port 2's receive
													// circular queue

volatile unsigned char Rx_2_Queue_Byte_Count = 0;	// number of bytes in serial port 2's receive
													// circular queue

volatile unsigned char RX_2_Overrun_Errors = 0;		// number of overrun errors that have occurred
													// in serial port 2's receive circuitry since
													// the last reset

volatile unsigned char RX_2_Framing_Errors = 0;		// number of framing errors that have occurred
													// in serial port 2's receive circuitry since
													// the last reset
#endif

//
// Serial Port 2 Transmit Variables:
//

#ifdef ENABLE_SERIAL_PORT_TWO_TX

volatile unsigned char Tx_2_Queue[TX_2_QUEUE_SIZE];	// serial port 2's transmit circular queue

volatile unsigned char Tx_2_Queue_Full = FALSE;		// flag that indicates that serial port 2's
													// transmit circular queue is full and cannot
													// accept any more data

volatile unsigned char Tx_2_Queue_Empty = TRUE;		// flag that indicates that there is no more 
													// data to send in serial port 2's transmit
													// circular queue

volatile unsigned char Tx_2_Queue_Read_Index = 0;	// read index into serial port 2's transmit
													// circular queue

unsigned char Tx_2_Queue_Write_Index = 0;			// write index into serial port 2's transmit
													// circular queue

volatile unsigned char Tx_2_Queue_Byte_Count = 0;	// number of bytes in serial port 2's transmit
													// circular queue
#endif



/**************************************************  *****************************
*
*	FUNCTION:		Init_Serial_Port_Two()
*
*	PURPOSE:		Initializes serial port two for asynchronous operation
*
*	CALLED FROM:	user_routines.c/User_Initialization()
*
*	PARAMETERS:		None
*
*	RETURNS:		Nothing
*
*	COMMENTS:		This function must be called before you try to use serial
*					port two.
*
*					By default, this serial port is set to 9600 baud with
*					the transmitter and receiver enabled. 
*
*					The	serial port's baud rate is programmed by entering
*					a value into the SPBRG2 register and possibly changing
*					the value of the BRGH bit. Several example values are 
*					included in the serial_ports.h file.
*
*					Numbers within brackets refer to the PIC18F8520	data
*					sheet page number where more information can be found.
*					This document can be found at microchip's website at
*					http://www.microchip.com or at the author's website at
*					http://www.kevin.org/frc
*
*					This function will not be included in the build unless
*					ENABLE_SERIAL_PORT_TWO_RX or ENABLE_SERIAL_PORT_TWO_TX
*					is #define'd in serial_ports.h
*
**************************************************  *****************************/
void Init_Serial_Port_Two(void)
{
	// Start by initializing the serial port with code 
	// common to receive and transmit functions
	SPBRG = BAUD_19200;		// baud rate generator register [200]
							//
	TXSTAbits.BRGH = 1;	// high baud rate select bit (asynchronous mode only) [198]
							//  0: low speed
							//  1: high speed
							//
	PIE1bits.RCIE = 0;		// receive interrupt enable bit [95]
							//  0: disables received data interrupt
							//  1: enables received data interrupt
							//
	PIE1bits.TXIE = 0;		// transmit interrupt enable bit [95]
							//  0: disables transmit register empty interrupt
							//  1: enables transmit register empty interrupt
							//
	TXSTAbits.SYNC = 0;	// USART mode select bit [198]
							//  0: asynchronous mode
							//  1: synchronous mode
							//
	TXSTAbits.CSRC = 0;	// clock source select bit (synchronous mode only) [198]
							//  0: Slave mode (clock generated by external source)
							//  1: Master mode (clock generated internally from BRG)

	// if receive functionality is to be included in the
	// software build, include code that is specific to
	// initializing the receiver
	#ifdef ENABLE_SERIAL_PORT_TWO_RX
							//
	TRISCbits.TRISC2 = 1;	// make sure the RG2/RX2/DT2 pin is configured as an input [120]
							//
	RCSTAbits.RX9 = 0;		// 9-bit receive enable bit [199]
							//  0: 8-bit reception mode
							//  1: 9-bit reception mode
							//
	RCSTAbits.ADDEN = 0;	// address detect enable bit (9-bit asynchronous mode only) [199]
							//  0: disables address detection
							//  1: enables address detection
							//
	RCSTAbits.SREN = 1;	// single receive enable bit (master synchronous mode only) [199]
							//  0: disables single receive mode
							//  1: enables single receive mode
							//
	RCSTAbits.CREN = 1;	// continuous receive mode enable bit [199]
							// asynchronous mode:
							//  0: disables receiver
							//  1: enable receiver
							// synchronous mode:
							//  0: disables continuous receive
							//  1: enables continuous receive until CREN is cleared [199]
							//
	IPR1bits.RCIP = 0;		// receive interrupt priority bit (must be 0 for IFI controllers) [98]
							//  0: low-priority
							//  1: high-priority
							//
	PIE1bits.RCIE = 1;		// receive interrupt enable bit [95]
							//  0: disables received data interrupt
							//  1: enables received data interrupt
	#endif					//

	// if transmit functionality is to be included in the
	// software build, include code that is specific to
	// initializing the serial port transmitter
	#ifdef ENABLE_SERIAL_PORT_TWO_TX
							//
	stdout = _H_USER;		// use this driver for output stream functions
							//
							//
	TRISCbits.TRISC1 = 0;	// make sure the RG1/TX2/CK2 pin is configured as an output [120] changed to trisC
							//
	TXSTAbits.TX9 = 0;		// 9-bit transmit enable bit [198]
							//  0: 8-bit transmission mode
							//  1: 9-bit transmission mode
							//
	IPR1bits.TXIP = 0;		// transmit interrupt priority bit (must be 0 for IFI controllers) [98]
							//  0: low-priority
							//  1: high-priority
							//
	PIE1bits.TXIE = 1;		// transmit interrupt enable bit [95]
							//  0: disables transmit register empty interrupt
							//  1: enables transmit register empty interrupt
							//
	TXSTAbits.TXEN = 1;  	// Enable transmitter [198]
							//  0: serial transmitter is disabled
							//  1: serial transmitter 
	#endif					//

	// finally, turn on the serial port
	RCSTAbits.SPEN = 1;  	// Serial Port Enable [199]
							//  0: serial port is disabled
							//  1: serial port is enabled
}



/**************************************************  *****************************
*
*	FUNCTION:		Serial_Port_Two_Byte_Count()
*
*	PURPOSE:		Returns the number of bytes in serial port 
*					two's received data queue.		
*
*	CALLED FROM:
*
*	PARAMETERS:		none
*
*	RETURNS:		unsigned char
*
*	COMMENTS:		This function must be called to determine how much data,
*					if any, is present in serial port two's received data
*					queue. If the returned number is greater than zero, then
*					a call to Read_Serial_Port_Two() can be made to retrieve
*					the next byte.
*
*					This function will not be included in the build unless
*					ENABLE_SERIAL_PORT_TWO_RX is #define'd in serial_ports.h
*
**************************************************  *****************************/
#ifdef ENABLE_SERIAL_PORT_TWO_RX
unsigned char Serial_Port_Two_Byte_Count(void)
{
	unsigned char temp;

	// since we're about to use the Rx_1_Queue_Byte_Count variable,
	// which can also be modified in the interrupt service routine,
	// let's briefly disable the serial port interrupt to make sure 
	// that Rx_1_Queue_Byte_Count doesn't get altered while we're 
	// using it.
	PIE1bits.RCIE = 0;

	// now we can get a local copy of the byte count without fear
	// that we'll get corrupted data
	temp = Rx_2_Queue_Byte_Count;

	// okay, we have a local copy of the byte count, so turn the 
	// serial port interrupt back on.
	PIE1bits.RCIE = 1;

	// return the byte count
	return(temp);
}
#endif



/**************************************************  *****************************
*
*	FUNCTION:		Read_Serial_Port_Two()
*
*	PURPOSE:		
*
*	CALLED FROM:
*
*	PARAMETERS:		none
*
*	RETURNS:		unsigned char
*
*	COMMENTS:		This function will not be included in the build unless
*					ENABLE_SERIAL_PORT_TWO_RX is #define'd in serial_ports.h 		
*
**************************************************  *****************************/
#ifdef ENABLE_SERIAL_PORT_TWO_RX
unsigned char Read_Serial_Port_Two(void)
{
	unsigned char byte;

	if(Rx_2_Queue_Empty)
	{
		// error: no data to read
		return(0);
	}
	else
	{
		// get a byte from the circular queue and store it temporarily
		byte = Rx_2_Queue[Rx_2_Queue_Read_Index];

		// decrement the queue byte count
		Rx_2_Queue_Byte_Count--;

		// increment the read pointer
		Rx_2_Queue_Read_Index++;

		// If the index pointer overflowed, cut-off the high-order bit. Doing this
		// every time is quicker than checking for overflow every time with an if()
		// statement and only then occasionally setting it back to zero. For this 
		// to work, the queue size must be a power of 2 (e.g., 16,32,64,128...).
		Rx_2_Queue_Read_Index &= RX_2_QUEUE_INDEX_MASK;

		// since we're about to use the Rx_2_Queue_Write_Index variable, which can
		// also be modified in the interrupt service routine, let's briefly disable
		// the serial port interrupt to make sure that Rx_2_Queue_Write_Index doesn't 
		// get altered while we're using it.
		PIE1bits.RCIE = 0;

		// is the circular queue now empty?
		if(Rx_2_Queue_Read_Index == Rx_2_Queue_Write_Index)
		{
			Rx_2_Queue_Empty = TRUE;
		}

		// okay, we're done using Rx_2_Queue_Write_Index, so turn the serial port
		// interrupt back on.
		PIE1bits.RCIE = 1;

 		// Since we've just removed a byte to the queue, it can't possibly be full.
		// Again, this is quicker than using an if() statement every time
		Rx_2_Queue_Full = FALSE;

		// return the data
		return(byte);
	}
}
#endif



/**************************************************  *****************************
*
*	FUNCTION:		Write_Serial_Port_Two()
*
*	PURPOSE:		Sends a byte of data using serial port two.
*
*	CALLED FROM:
*
*	PARAMETERS:		unsigned char
*
*	RETURNS:		nothing
*
*	COMMENTS:		If you don't initialize the serial port before calling
*					this function, the robot controller will stop functioning
*					and you'll get the much dreaded red-light-of-death. This 
*					is because the while() statement below is waiting for the
*					transmit circuitry to send another byte, but if the serial
*					port hasn't been configured, nothing will be transmitted
*					and we'll be stuck in the while() loop.
*
*					This function will not be included in the build unless
*					ENABLE_SERIAL_PORT_TWO_TX is #define'd in serial_ports.h
*
**************************************************  *****************************/
#ifdef ENABLE_SERIAL_PORT_TWO_TX
void Write_Serial_Port_Two(unsigned char byte)
{
	// if the queue is full, wait here until space is available
	while(Tx_2_Queue_Full);

	// put the byte on the circular queue
	Tx_2_Queue[Tx_2_Queue_Write_Index] = byte;

	// increment the queue byte count
	Tx_2_Queue_Byte_Count++;

	// increment the write pointer
	Tx_2_Queue_Write_Index++;

	// If the index pointer overflowed, cut-off the high-order bit. Doing this
	// every time is quicker than checking for overflow every time with an if()
	// statement and only then occasionally setting it back to zero. For this 
	// to work, the queue size must be a power of 2 (e.g., 16,32,64,128...).
	Tx_2_Queue_Write_Index &= TX_2_QUEUE_INDEX_MASK;

	// since we're about to use the Tx_2_Queue_Write_Index variable, which can
	// also be modified in the interrupt service routine, let's briefly disable
	// the serial port interrupt to make sure that Tx_2_Queue_Write_Index doesn't 
	// get altered while we're using it.
	PIE1bits.TXIE = 0;

	// is the circular queue now full?
	if(Tx_2_Queue_Read_Index == Tx_2_Queue_Write_Index)
	{ 
		Tx_2_Queue_Full = TRUE;
	}

	// okay, we're done using Tx_2_Queue_Write_Index, so turn the serial port
	// interrupt back on.
	PIE1bits.TXIE = 1;

	// Since we've just added a byte to the queue, it can't possibly be empty.
	// Again, this is quicker than using an if() statement every time
	Tx_2_Queue_Empty = FALSE;
}
#endif



/**************************************************  *****************************
*
*	FUNCTION:		Rx_2_Int_Handler()
*
*	PURPOSE:		Serial port two new data interrupt handler.		
*
*	CALLED FROM:	user_routines_fast()
*
*	PARAMETERS:		None
*
*	RETURNS:		Nothing
*
*	COMMENTS:		If the interrupt handler was installed correctly, this
*					function will be called every time a new byte of data
*					is received by serial port two.
*
*					This function will not be included in the build unless
*					ENABLE_SERIAL_PORT_TWO_RX is #define'd in serial_ports.h 		
*
**************************************************  *****************************/
#ifdef ENABLE_SERIAL_PORT_TWO_RX
void Rx_2_Int_Handler(void)
{
	if(Rx_2_Queue_Full)
	{
		// just turn off the serial port interrupt if we can't store any more data.
		// the interrupt will be re-enabled within the Receive_Byte() function when
		// more data is read.
		PIE1bits.RCIE = 0;
	}
	else
	{
		// put the byte on the circular queue
		Rx_2_Queue[Rx_2_Queue_Write_Index] = RCREG;

		// if the interrupt handler was disabled while data was being received,
		// data may have backed-up in the receiver circuitry, causing an overrun
		// condition. So let's check the OERR bit to see if this has happened
		// and if it has, we'll need to reset the serial port receiver circuitry
		// to get data flowing again.
		if(RCSTAbits.OERR)
		{
			// reset by turning off the receiver circuitry, then...
			RCSTAbits.CREN = 0;
			
			// ...turn it back on
			RCSTAbits.CREN = 1;

			// indicate that we've had an error
			RX_2_Overrun_Errors++;
		}

		// if incoming data gets misaligned and the receiver doesn't receive a
		// stop bit where it expects to detect it, the receiver circuitry will
		// set the FERR bit to indicate that it's received corrupted data. The
		// likely reason for this is an incorrectly set baud rate on either the
		// receiver or transmitter end.
		if(RCSTAbits.FERR)
		{
			RX_2_Framing_Errors++;
		}

		// increment the queue byte count
		Rx_2_Queue_Byte_Count++;
	
		// increment the write pointer
		Rx_2_Queue_Write_Index++;

		// If the index pointer overflowed, cut-off the high-order bit. Doing this
		// every time is quicker than checking for overflow every time with an if()
		// statement and only then occasionally setting it back to zero. For this 
		// to work, the queue size must be a power of 2 (e.g., 16,32,64,128...).
		Rx_2_Queue_Write_Index &= RX_2_QUEUE_INDEX_MASK;
		
		// is the circular queue now full?
		if(Rx_2_Queue_Read_Index == Rx_2_Queue_Write_Index)
		{ 
			Rx_2_Queue_Full = TRUE;
		}
		
		// Since we've just added a byte to the queue, it can't possibly be empty.
		// Again, this is quicker than using an if() statement every time
		Rx_2_Queue_Empty = FALSE;
	}
}
#endif



/**************************************************  *****************************
*
*	FUNCTION:		Tx_2_Int_Handler()
*
*	PURPOSE:		Serial port two empty transmit buffer interrupt handler.		
*
*	CALLED FROM:	user_routines_fast()
*
*	PARAMETERS:		None
*
*	RETURNS:		Nothing
*
*	COMMENTS:		If the interrupt handler was installed correctly, this
*					function will be called every time serial port two is
*					ready to start sending a byte of data.
*
*					This function will not be included in the build unless
*					ENABLE_SERIAL_PORT_TWO_TX is #define'd in serial_ports.h 			
*
**************************************************  *****************************/
#ifdef ENABLE_SERIAL_PORT_TWO_TX
void Tx_2_Int_Handler(void)
{
	if(Tx_2_Queue_Empty)
	{
		// just turn off the serial port interrupt if we don't have data to send.
		// the interrupt will be re-enabled within the Send_Byte() function when
		// more data is sent.
		PIE1bits.TXIE = 0;
	}
	else
	{
		// get a byte from the circular queue and send it to the USART
		TXREG = Tx_2_Queue[Tx_2_Queue_Read_Index];

		// decrement the queue byte count
		Tx_2_Queue_Byte_Count--;

		// increment the read pointer
		Tx_2_Queue_Read_Index++;

		// If the index pointer overflowed, cut-off the high-order bit. Doing this
		// every time is quicker than checking for overflow every time with an if()
		// statement and only then occasionally setting it back to zero. For this 
		// to work, the queue size must be a power of 2 (e.g., 16,32,64,128...).
		Tx_2_Queue_Read_Index &= TX_2_QUEUE_INDEX_MASK;

		// is the circular queue now empty?
		if(Tx_2_Queue_Read_Index == Tx_2_Queue_Write_Index)
		{
			Tx_2_Queue_Empty = TRUE;
		}

 		// Since we've just removed a byte from the queue, it can't possibly be full.
		// Again, this is quicker than using an if() statement every time
		Tx_2_Queue_Full = FALSE;
	}
}
#endif

/**************************************************  *****************************
*
*	FUNCTION:		_user_putc()
*
*	PURPOSE:		putc() interface to C18 2.4 output stream functions		
*
*	CALLED FROM:
*
*	PARAMETERS:		None
*
*	RETURNS:		Nothing
*
*	COMMENTS:			
*
**************************************************  *****************************/
void _user_putc(unsigned char byte)
{
	if(stdout_serial_port == NUL)
	{
		// send the data to the bit bucket
	}
	#ifdef ENABLE_SERIAL_PORT_ONE_TX
	else if(stdout_serial_port == SERIAL_PORT_ONE)
	{
		// send the data to serial port one
		Write_Serial_Port_One(byte);
	}
	#endif
	#ifdef ENABLE_SERIAL_PORT_TWO_TX
	else if(stdout_serial_port == SERIAL_PORT_TWO)
	{
		// send the data to serial port two
		Write_Serial_Port_Two(byte);
	}
	#endif
}

serial_ports.h


/**************************************************  *****************************
*
*	TITLE:		serial_ports.h 
*
*	VERSION:	0.3 (Beta)                           
*
*	DATE:		05-Feb-2005
*
*	AUTHOR:		R. Kevin Watson
*				kevinw@jpl.nasa.gov
*
*	COMMENTS:	You are free to use this source code for any non-commercial
*				use. Please do not make copies of this source code, modified
*				or un-modified, publicly available on the internet or elsewhere
*				without permission. Thanks.
*
*				Copyright ©2004-2005 R. Kevin Watson. All rights are reserved.
*
**************************************************  ******************************
*
*	CHANGE LOG:
*
*	DATE         REV  DESCRIPTION
*	-----------  ---  ----------------------------------------------------------
*	22-Dec-2004  0.1  RKW - Original code.
*	28-Dec-2004  0.2  RKW - Using preprocessor directives, added the ability 
*	                  to enable/disable individual serial port receive and 
*	                  transmit code. Updated documentation.
*	05-Feb-2005  0.3  RKW - Added _user_putc() interface to C18's new output
*	                  stream capabilities. Updated documentation.
*
**************************************************  *****************************/
#ifndef _SERIAL_PORTS_H
#define _SERIAL_PORTS_H

// comment out the next line to disable serial port one 
// receive functionality
//#define ENABLE_SERIAL_PORT_ONE_RX

// comment out the next line to disable serial port one 
// transmit functionality
//#define ENABLE_SERIAL_PORT_ONE_TX

// comment out the next line to disable serial port two 
// receive functionality
#define ENABLE_SERIAL_PORT_TWO_RX

// comment out the next line to disable serial port two 
// transmit functionality
#define ENABLE_SERIAL_PORT_TWO_TX

// Sample values that can be plugged into the SPBRGx register to program the 
// baud rate generator for a specific baud rate. Make sure to also set the BRGH
// bit accordingly. See the Init_Serial_Port_One() and Init_Serial_Port_Two() 
// functions in the serial_ports.c source file for more information. 
#define BAUD_4800  129	// set BRGH = 0
#define BAUD_9600 	64	// set BRGH = 0
#define BAUD_14400  42	// set BRGH = 0
#define BAUD_19200 129	// set BRGH = 1
#define BAUD_38400  64 	// set BRGH = 1
#define BAUD_57600  42	// set BRGH = 1
#define BAUD_115200 21	// set BRGH = 1
#define BAUD_230400 10  // set BRGH = 1

// These values define the size, in bytes, of the four circular queues used to 
// buffer incoming and outgoing serial port data. The size of the receive queue 
// is critical to prevent data loss. As an example, if you're continuously 
// receiving data at 38,400 baud and only call Read_Serial_Port_xxx() in the 
// Process_Data_From_Master_uP() loop, which is called every 26.2ms, you'll 
// need to size the queue to accept all of the data you expect to receive in 
// those 26.2ms. To do this, multiply the rate at which bytes of data are being 
// received times the amount of time between calls to Read_Serial_Port_xxx(). 
// In the above example, we're receiving data at a rate of 3840 bytes per second 
// (8 bits of data plus 2 bits of overhead per byte transferred) and we need to 
// store at least 26.2ms-worth of that data for a calculated queue size of 101 
// bytes. Because the queue size must be a power of two, we'll need to round-up 
// to a queue size of 128. Another solution is to check for received serial data 
// at a higher rate by putting the call to Read_Serial_Port_xxx() in the much 
// faster Process_Data_From_Local_IO() loop. As mentioned above, these values 
// must be a power of two (i.e.,8,16,32,64,128) for the circular queue algorithm 
// to function correctly.
#define RX_1_QUEUE_SIZE 32
#define TX_1_QUEUE_SIZE 16
#define RX_2_QUEUE_SIZE 32
#define TX_2_QUEUE_SIZE 16

// The circular queue algorithm will break if these values are altered.
#define RX_1_QUEUE_INDEX_MASK RX_1_QUEUE_SIZE-1
#define TX_1_QUEUE_INDEX_MASK TX_1_QUEUE_SIZE-1
#define RX_2_QUEUE_INDEX_MASK RX_2_QUEUE_SIZE-1
#define TX_2_QUEUE_INDEX_MASK TX_2_QUEUE_SIZE-1

#ifndef FALSE
#define TRUE 1
#define FALSE 0
#endif

// #defines used with the stdout_serial_port global variable
#define NUL 0
#define SERIAL_PORT_ONE 1
#define SERIAL_PORT_TWO 2

// if needed, declare functions and global variables that
// are specific to serial port one receiver functionality
#ifdef ENABLE_SERIAL_PORT_ONE_RX
void Init_Serial_Port_One(void);
unsigned char Serial_Port_One_Byte_Count(void);
unsigned char Read_Serial_Port_One(void);
void Rx_1_Int_Handler(void);
extern volatile unsigned char RX_1_Framing_Errors;
extern volatile unsigned char RX_1_Overrun_Errors;
#endif

// if needed, declare functions that are specific to serial
// port one transmit functionality
#ifdef ENABLE_SERIAL_PORT_ONE_TX
extern unsigned char stdout_serial_port;
void _user_putc(unsigned char);
void Init_Serial_Port_One(void);
void Write_Serial_Port_One(unsigned char);
void Tx_1_Int_Handler(void);
#endif

// if needed, declare functions and global variables that
// are specific to serial port two receiver functionality
#ifdef ENABLE_SERIAL_PORT_TWO_RX
void Init_Serial_Port_Two(void);
unsigned char Serial_Port_Two_Byte_Count(void);
unsigned char Read_Serial_Port_Two(void);
void Rx_2_Int_Handler(void);
extern volatile unsigned char RX_2_Framing_Errors;
extern volatile unsigned char RX_2_Overrun_Errors;
#endif

// if needed, declare functions that are specific to serial
// port two transmit functionality
#ifdef ENABLE_SERIAL_PORT_TWO_TX
extern unsigned char stdout_serial_port;
void _user_putc(unsigned char);
void Init_Serial_Port_Two(void);
void Write_Serial_Port_Two(unsigned char);
void Tx_2_Int_Handler(void);
#endif

#endif

 

user_routines.c

 
 
**************************************************  *****************************/
#include <stdio.h>
#include "user_routines.h"
#include "p18f452.h"
#include "accel.h"
#include "default.h"
#include "interrupts.h"
#include "encoders.h"
#include "ifi_utilities.h"
#include "serial_ports.h"


/**************************************************  *****************************
* FUNCTION NAME: User_Initialization
* PURPOSE:       This routine is called first (and only once) in the Main function.  
*                You may modify and add to this function.
* CALLED FROM:   main.c
* ARGUMENTS:     none
* RETURNS:       void
**************************************************  *****************************/
void User_Initialization(void)
{
 
/* FIRST: Set up the I/O pins you want to use as digital INPUTS. */
    

/* SECOND: Set up the I/O pins you want to use as digital OUTPUTS. */
  

/* THIRD: Initialize the values on the digital outputs. */
  


  /* Add any other initialization code here. */

  Initialize_Accel();
  Initialize_Interrupts();
  Initialize_Timer_0();
  Initialize_Timer_1();
  Initialize_Timer_2();
  Initialize_Timer_3();
  Initialize_Encoder();
  Init_Serial_Port_Two();
  stdout_serial_port = SERIAL_PORT_TWO;


}

/**************************************************  *****************************
* FUNCTION NAME: Process_Data
* PURPOSE:       duh, processes all the data
* CALLED FROM:   main.c
* ARGUMENTS:     none
* RETURNS:       void
**************************************************  *****************************/
void Process_Data(void)
{

  static unsigned char i;
  static unsigned char delay;
  int leftencode;
  int rightencode;
  int x_accel;
  int y_accel;


  

leftencode=Get_Left_Encoder_Count();
rightencode=Get_Right_Encoder_Count();

x_accel=get_x_accel();
y_accel=get_y_accel();

//printf("lefte = %d
",leftencode);
//printf("righte = %d
",rightencode);
//printf("yaccel = %d
",x_accel);
//printf("xaccel = %d
",y_accel);  

printf("matt's a noob
");


}

/**************************************************  ****************************/
/**************************************************  ****************************/
/**************************************************  ****************************/
//the following used to be in a seperate file but it was unecessary for my purposes
/**************************************************  *****************************
* 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.  
* CALLED FROM:   this file, InterruptVectorLow routine
* ARGUMENTS:     none
* RETURNS:       void
**************************************************  *****************************/


void InterruptHandlerLow()     
{                               
	if(PIR1bits.CCP1IF && PIE1bits.CCP1IE) // CCP1 Interrupt?
	{
		PIR1bits.CCP1IF = 0;
		CCP_1_ISR(); // call the CCP1 ISR (in accel.c)
	}

	else if (PIR2bits.CCP2IF && PIE2bits.CCP2IE) // CCP2 Interrupt?
	{
		PIR2bits.CCP2IF = 0;
		CCP_2_ISR(); // call the CCP2 ISR (in accel.c)
	}
	else if (INTCONbits.RBIF && INTCONbits.RBIE) // external interrupts 3 through 6?
	{
		//Port_B = PORTB; // remove the "mismatch condition" by reading port b            
		INTCONbits.RBIF = 0; // clear the interrupt flag [89]
	
		EncoderTask(PORTB);
	}
///////////////////////////////////////////////////////////////////////////
	                           
	else if (PIR1bits.RCIF && PIE1bits.RCIE) // rx2 interrupt?
	{
		#ifdef ENABLE_SERIAL_PORT_TWO_RX
		Rx_2_Int_Handler(); // call the rx2 interrupt handler (in serial_ports.c)
		#endif
	}                           
	else if (PIR1bits.TXIF && PIE1bits.TXIE) // tx2 interrupt?
	{
		#ifdef ENABLE_SERIAL_PORT_TWO_TX
		Tx_2_Int_Handler(); // call the tx2 interrupt handler (in serial_ports.c)
		#endif
	}
///////////////////////////////////////////////////////////////////////


}


While i cant specifically help you on the programming issue i can direct you to Kevin Watson on these forums. He is the developer and i bet he would be more then willing to help out, i just don’t know how often he looks at CD in the summer. In his profile theres an option to send him an email.

it seems the original problem was hardware related.

we swithced to using the red tether cable on the serial port and now it gets passed the queue loop and gets stuck in an integer divide loop which is a completely different issue.