/*
**************************************************************************
* Project modified for the hardware platform PIC24-Eval RevC
* Date: 22th Jan 2008
* Programmer: John Leung
* Web presence: www.TechToys.com.hk
* Changes necessary for PIC24-Eval RevC
* (1) because board RevC uses UART2 and SPI2, it is necessary to use
*		explicit defintion like "SPI2STATbits.SPIRBF" instead of _SPIRBF
*		because such definition has been assigned ot SPI1 module in
*		Microchip header file p24FJ128GA010.h.
*		Similarly, all _UARTEN and _UTXEN have been changed to 
*		U2MODEbits.UARTEN & U2STAbits.UTXEN, respectively under comm.c
**************************************************************************
*/

#include <string.h>
#include <p24FJ128GA010.h>
#include "pic24f.h"
#include "comm.h"

#define BUFFER_SIZE 128
#define BPS 		19200UL

static int TxRun;
static volatile struct
{
	int		rptr;
	int		wptr;
	int		count;
	BYTE	buff[BUFFER_SIZE];
} TxFifo, RxFifo;




void __attribute__((interrupt, auto_psv)) _U2RXInterrupt (void)
{
	BYTE d;
	int n;


	d = (BYTE)U2RXREG;
	_U2RXIF = 0;
	n = RxFifo.count;
	if (n < BUFFER_SIZE) {
		n++;
		RxFifo.count = n;
		n = RxFifo.wptr;
		RxFifo.buff[n] = d;
		RxFifo.wptr = (n + 1) % BUFFER_SIZE;
	}
}




void __attribute__((interrupt, auto_psv)) _U2TXInterrupt (void)
{
	int n;


	_U2TXIF = 0;
	n = TxFifo.count;
	if (n) {
		n--;
		TxFifo.count = n;
		n = TxFifo.rptr;
		U2TXREG = TxFifo.buff[n];
		TxFifo.rptr = (n + 1) % BUFFER_SIZE;
	} else {
		TxRun = 0;
	}
}




int uart_test (void)
{
	return RxFifo.count;
}




BYTE uart_get (void)
{
	BYTE d;
	int n;


	while (!RxFifo.count);

	n = RxFifo.rptr;
	d = RxFifo.buff[n];
	RxFifo.rptr = (n + 1) % BUFFER_SIZE;
	_DI();
	RxFifo.count--;
	_EI();

	return d;
}




void uart_put (BYTE d)
{
	int n;


	while (TxFifo.count >= BUFFER_SIZE);

	n = TxFifo.wptr;
	TxFifo.buff[n] = d;
	TxFifo.wptr = (n + 1) % BUFFER_SIZE;
	_DI();
	TxFifo.count++;
	if (!TxRun) {
		TxRun = 1;
		_U2TXIF = 1;
	}
	_EI();
}




void uart_init (void)
{
	/* Disable Tx/Rx interruptrs */
	_U2RXIE = 0;
	_U2TXIE = 0;

	/* Initialize UART2 */
	// BRG2 = (FCY/baudrate/16)-1 with FCY=FOSC/2 for PIC24 series when BRGH=0
	U2BRG = FCY / 16 / BPS - 1;
	U2MODEbits.UARTEN = 1;		// enable UART, BREGH=0, 1 stop, no parity
	U2STAbits.UTXEN = 1;		// enable the transmitter

	/* Clear Tx/Rx FIFOs */
	TxFifo.rptr = TxFifo.wptr = TxFifo.count = 0;
	RxFifo.rptr = RxFifo.wptr = RxFifo.count = 0;
	TxRun = 0;

	/* Enable Tx/Rx interruptrs */
	_U2RXIE = 1;
	_U2TXIE = 1;
}


