/**
 * This example for the PIC16f628a repeats data read through serial, back
 * at a given baud.  It has been tested on a PIC16f628a operating 
 * at 4MHz with at 9600 baud.  See the PIC16f628a manual for tables of 
 * allowable clock rate and baud rate combinations.
 *
 * NOTE:  The PIC's serial port has the same timings as a normal PC
 * serial port, but the wrong voltages.  A PIC only has 0V and 5V, while
 * a serial port produces, and expects +12V/-12V!  You can't hook it up
 * directly, a translator chip is needed.
 *
 * The MAX232 IC and its clones are among the most popular for this.
 * They have built-in voltage inverters and doublers allowing them to
 * run off the same 5V supply as your PIC, and are really simple to use.
 * See http://burningsmell.org/biollante/max232.gif for an outline.
 */
#define __16f628a
#include "pic/pic16f628a.h"
#include "tsmtypes.h"

// Set the __CONFIG word:
Uint16 at 0x2007  __CONFIG = CONFIG_WORD;

// If KHZ is not specified by the makefile, assume it to be 4 MHZ
#ifndef KHZ
#define KHZ	4000
#endif

// These are fixed.  The 16f628a can only use these as transmit and recieve.
#define TX_PORT	2
#define RX_PORT	1
#define TX_BIT	(1<<TX_PORT)
#define RX_BIT	(1<<RX_PORT)


// Twiddle these as you like BUT remember that not all values work right!
// See the datasheet for what values can work with what clock frequencies.
#define	BAUD	9600
#define BAUD_HI	1

// This section calculates the proper value for SPBRG from the given
// values of BAUD and BAUD_HI.  Derived from Microchip's datasheet.
#if	(BAUD_HI == 1)
#define	BAUD_FACTOR	(16L*BAUD)
#else
#define	BAUD_FACTOR	(64L*BAUD)
#endif
#define SPBRG_VALUE	(unsigned char)(((KHZ*1000L)-BAUD_FACTOR)/BAUD_FACTOR)

static void main(void)
{
	static unsigned char i;

	TRISB=TX_BIT|RX_BIT;	// These need to be 1 for USART to work

	SPBRG=SPBRG_VALUE;	// Baud Rate register, calculated by macro
	BRGH=BAUD_HI;

	SYNC=0;			// Disable Synchronous/Enable Asynchronous
	SPEN=1;			// Enable serial port
	TXEN=1;			// Enable transmission mode
	CREN=1;			// Enable reception mode

	while(1)
	{
		while(!RCIF);	// Wait until data recieved
		i=RCREG;	// Store for later

		while(!TRMT);	// Wait until we're free to transmit
		TXREG=i;	// Transmit
	}
}
