#include "p24FJ64GA002.h"

#include "uart.h"

#if UART1==1
unsigned int	uart1_start;
unsigned int	uart1_stop;
unsigned int	uart1_overflow;
unsigned char	uart1_buffer[UART_BUFFER_SIZE];
#endif

#if UART2==1
unsigned int	uart2_start;
unsigned int	uart2_stop;
unsigned int	uart2_overflow;
unsigned char	uart2_buffer[UART_BUFFER_SIZE];
#endif

unsigned char tmp;

#if UART1 == 1
void __attribute__((__interrupt__, auto_psv)) _U1RXInterrupt(void) {

	IFS0bits.U1RXIF = 0;	// 割込み要因フラグをクリアする	

	// UART1 の受信割込み
	while( U1STAbits.URXDA ) {
		if (!uart1_overflow) {
			uart1_buffer[uart1_stop++] = U1RXREG;
			uart1_stop &= UART_BUFFER_SIZE_MASK;
			if (uart1_start == uart1_stop) {
				uart1_overflow = 1;
			}
		} else {
			tmp = U1RXREG;
		}
	}

	// 全て受信したあとに Over Run をクリアする
	if ( U1STAbits.OERR) {
		U1STAbits.OERR = 0;
	}

}
#endif

#if UART2 == 1
void __attribute__((__interrupt__, auto_psv)) _U2RXInterrupt(void) {

	IFS0bits.U2RXIF = 0;	// 割込み要因フラグをクリアする	

	// UART2 の受信割込み
	while( U2STAbits.URXDA ) {
		if (!uart2_overflow) {
			uart2_buffer[uart2_stop++] = U2RXREG;
			uart2_stop &= UART_BUFFER_SIZE_MASK;
			if (uart2_start == uart2_stop) {
				uart2_overflow = 1;
			}
		} else {
			tmp = U2RXREG;
		}
	}

	if ( U2STAbits.OERR) {
		U2STAbits.OERR = 0;
	}

}
#endif

void uart_init(unsigned int buad1, unsigned int buad2 ) {
//===============================================================================
// ハードウェア UARTへのピンアサインに合わせて RPピンの情報を記述
//
//  U1  TX: RB6 (15pin)
//	    RX: RB5 (14pin)

	RPINR18bits.U1RXR = 5;	 // U1RX;	// RX 割り当て
	RPOR3bits.RP6R = 	3;   // U1TX;	// TX 割り当て


//==============================================================================

#if UART1==1
	uart1_start = uart1_stop = 0;
#else
	buad1 = 0;
#endif

#if UART2==1
	uart2_start = uart2_stop = 0;
#else
	buad2 = 0;
#endif

#if BRGH==1
	#define BRGH_PARAM	4
#else
	#define BRGH_PARAM	16
#endif

	if (buad1) {

#if UART1 == 1
		U1BRG 	= FCYL / ( BRGH_PARAM * buad1 ) - 1;     // ボーレートの決定
		U1MODE 	= 0x0808;				// データ通信モードの設定 (除　UART有効化bit)
		IEC0bits.U1RXIE  = 1;			// 受信時の割り込みを有効にする
		IPC2bits.U1RXIP  = 1;			// 割込みの優先順位
		U1STAbits.URXISEL = 0;			// 1バイト毎に割込みを発生
		U1MODEbits.UARTEN = 1;			// UART1 を有効化
		U1STAbits.UTXEN = 1;			// TXを有効化

		uart1_start = uart1_stop = uart1_overflow = 0;
#endif

	}

	if (buad2) {

#if UART2 == 1
		U2BRG 	= FCYL / ( BRGH_PARAM * buad1 ) - 1;     // ボーレートの決定
		U2MODE 	= 0x0808;				// データ通信モードの設定 (除　UART有効化bit)
		IEC0bits.U2RXIE  = 1;			// 受信時の割り込みを有効にする
		IPC2bits.U2RXIP  = 1;			// 割込みの優先順位
		U2STAbits.URXISEL = 0;			// 1バイト毎に割込みを発生
		U2MODEbits.UARTEN = 1;			// UART1 を有効化
		U2STAbits.UTXEN = 1;			// TXを有効化

		uart1_start = uart1_stop = uart1_overflow = 0;
#endif

	}

	return;
}

#if UART1==1
void uart1_send( unsigned char *buffer, unsigned int size ) {

	unsigned int left = size;
	while( left-- ) {
		while(U1STAbits.UTXBF);
		U1TXREG = *buffer++;
	}

	return;

}

void uart1_send_string( unsigned char *buffer) {

	unsigned int length = 0;
	unsigned char *p = buffer;

	while( *p++ ) {
		length++;
	}

	uart1_send( buffer, length );
	return;

}

unsigned int uart1_recv_char(unsigned char *c) {

	if (uart1_overflow == 0 &&  uart1_start == uart1_stop) {
		return 0;
	}

	*c = uart1_buffer[uart1_start++];
	uart1_start &= UART_BUFFER_SIZE_MASK;
	uart1_overflow = 0;

	return 1;
 
}

unsigned char uart1_recv_char_wait( void ) {

	unsigned char c;
	while((uart1_overflow == 0 &&  uart1_start == uart1_stop));

	c = uart1_buffer[uart1_start++];
	uart1_start &= UART_BUFFER_SIZE_MASK;
	uart1_overflow = 0;

	return c;
 
}


unsigned int uart1_recv_check(void) {

	if (uart1_overflow == 0 &&  uart1_start == uart1_stop) {
		return 0;
	}

	return 1;
 
}


#endif

#if UART2 == 1
void uart2_send( unsigned char *buffer, unsigned int size ) {

	unsigned int left = size;
	while( left-- ) {
		while(U2STAbits.UTXBF);
		U2TXREG = *buffer++;
	}

	return;

}

void uart2_send_string( unsigned char *buffer) {

	unsigned int length = 0;
	unsigned char *p = buffer;

	while( *p++ ) {
		length++;
	}

	uart2_send( buffer, length );
	return;

}

unsigned int uart2_recv_char(unsigned char *c) {

	if (uart2_overflow == 0 &&  uart2_start == uart2_stop) {
		return 0;
	}

	*c = uart2_buffer[uart2_start++];
	uart2_start &= UART_BUFFER_SIZE_MASK;
	uart2_overflow = 0;

	return 1;
 
}

unsigned char uart2_recv_char_wait( void ) {

	unsigned char c;
	while((uart2_overflow == 0 &&  uart2_start == uart2_stop));

	c = uart2_buffer[uart2_start++];
	uart2_start &= UART_BUFFER_SIZE_MASK;
	uart2_overflow = 0;

	return c;
 
}


unsigned int uart2_recv_check(void) {

	if (uart2_overflow == 0 &&  uart2_start == uart2_stop) {
		return 0;
	}

	return 1;
 
}


#endif

