#include <hcs12.h>
#include <dbug12.h>

#include "lcd.h"

#define enable_interrupts() asm(" cli")
#define	wait_for_interrupts() asm(" wai")

#define TRUE 1
#define FALSE 0

/****************************************SCI START********************************/

/*1024 Byte circular FIFO output sci1_buffer*/
#define BUFSIZE 1024
unsigned char sci0_buffer[BUFSIZE] ;
unsigned char * volatile sci0_bufin = sci0_buffer ;
unsigned char * volatile sci0_bufout = sci0_buffer ;
volatile unsigned char sci0_charin = 0 ;

unsigned char sci1_buffer[BUFSIZE] ;
unsigned char * volatile sci1_bufin = sci1_buffer ;
unsigned char * volatile sci1_bufout = sci1_buffer ;
volatile unsigned char sci1_charin = 0 ;

void INTERRUPT sci0_isr( void );
void INTERRUPT sci1_isr( void );

void sci0_init(unsigned char baud) ;
unsigned char sci0_read_char(void) ;
void sci0_write_char(unsigned char val) ;
void sci0_write_string(const char *msg) ;

void sci1_init(unsigned char baud) ;
unsigned char sci1_read_char(void) ;
void sci1_write_char(unsigned char val) ;
void sci1_write_string(const char *msg) ;


/**
 * 39(38400bps), 
 * 78(19200bps), 
 * 156(9600bps), 
 * 313(4800bps),
 */
void INTERRUPT sci0_isr( void )
{
	if(SCI0SR1 & 0x20)
	{
		/* RDRF is set */
		sci0_charin = SCI0DRL ;
	}
	if(SCI0SR1 & 0x80)
	{
		/* TDRE is set */
		if ( sci0_bufin == sci0_bufout )
		{
			/* Done -> Disable transmitter interrupt */
			SCI0CR2 &= ~0x80 ;
		}
		else
		{
			SCI0DRL = *sci0_bufout++ ;
			if(sci0_bufout == sci0_buffer + BUFSIZE)
			{
				sci0_bufout = sci0_buffer ;
			}
		}
	}
}



/* Retreives a character from the serail port */
unsigned char sci0_read_char(void)
{
	unsigned char result ;
	while((result = sci0_charin) == 0)
	{
		wait_for_interrupts();
	}
	sci0_charin = 0 ;
	return result ;
}

/* Put a character onto serial port */
void sci0_write_char(unsigned char val)
{
	do
	{
		int used = sci0_bufin - sci0_bufout ;
		if ( used < 0 )
		{
			used += BUFSIZE ;
		}
		if(used < BUFSIZE - 1)
		{
			break ;
		}
		wait_for_interrupts();
	}
	while(1) ;
	*sci0_bufin++ = val ; 
	if(sci0_bufin == sci0_buffer + BUFSIZE)
	{
		sci0_bufin = sci0_buffer ;
	}
	/* Re-enable transmitter interrupt */
	SCI0CR2 |= 0x80 ;
}

/* Initialize serial line with 'baud' rate */
void sci0_init(unsigned char baud)
{
	UserSCI0 = (unsigned int) & sci0_isr;
		
	SCI0BDL = baud ;
	/* Set RIE, TE and RE bits */
	SCI0CR2 = 0x2c ;
}

/* Print a string onto the serial line */
void sci0_write_string(const char *msg)
{
	while (*msg != 0)
	{	
		unsigned char val = *msg++;
		
		do
		{
			int used = sci0_bufin - sci0_bufout ;
			if ( used < 0 )
			{
				used += BUFSIZE ;
			}
			if(used < BUFSIZE - 1)
			{
				break ;
			}
			wait_for_interrupts();
		}
		while(1) ;
		*sci0_bufin++ = val ; 
		if(sci0_bufin == sci0_buffer + BUFSIZE)
		{
			sci0_bufin = sci0_buffer ;
		}
		/* Re-enable transmitter interrupt */
		SCI0CR2 |= 0x80 ;
	
	}
}



void INTERRUPT sci1_isr( void )
{
	if(SCI1SR1 & 0x20)
	{
		/* RDRF is set */
		sci1_charin = SCI1DRL ;
	}
	if(SCI1SR1 & 0x80)
	{
		/* TDRE is set */
		if ( sci1_bufin == sci1_bufout )
		{
			/* Done -> Disable transmitter interrupt */
			SCI1CR2 &= ~0x80 ;
		}
		else
		{
			SCI1DRL = *sci1_bufout++ ;
			if(sci1_bufout == sci1_buffer + BUFSIZE)
			{
				sci1_bufout = sci1_buffer ;
			}
		}
	}
}

/* Retreives a character from the serail port */
unsigned char sci1_read_char(void)
{
	unsigned char result ;
	while((result = sci1_charin) == 0)
	{
		wait_for_interrupts();
	}
	sci1_charin = 0 ;
	return result ;
}

/* Put a character onto serial port */
void sci1_write_char(unsigned char val)
{
	do
	{
		int used = sci1_bufin - sci1_bufout ;
		if ( used < 0 )
		{
			used += BUFSIZE ;
		}
		if(used < BUFSIZE - 1)
		{
			break ;
		}
		wait_for_interrupts();
	}
	while(1) ;
	*sci1_bufin++ = val ; 
	if(sci1_bufin == sci1_buffer + BUFSIZE)
	{
		sci1_bufin = sci1_buffer ;
	}
	/* Re-enable transmitter interrupt */
	SCI1CR2 |= 0x80 ;
}

/* Initialize serial line with 'baud' rate */
void sci1_init(unsigned char baud)
{
	UserSCI1 = (unsigned int) & sci1_isr;
	
	SCI1BDL = baud ;
	/* Set RIE, TE and RE bits */
	SCI1CR2 = 0x2c ;
}

/* Print a string onto the serial line */
void sci1_write_string(const char *msg)
{
	while (*msg != 0)
		sci1_write_char(*msg++) ;
}




static char console_printer_buf[20];



void sci0_print_integer(int num);
void sci0_print_integer(int num)
{
	char digits[6];
	int i = 0;

	// zero as special case
	if(num == 0)
	{
		sci0_write_char('0');
		return;
	}
	

	if(num < 0)
	{
		sci0_write_char('-');
		num = -num;
	}
	
	for (i = 0; i <= 5; i++)
	{
		digits[i] = num % 10;
		num /= 10;	
	}

	char should_skip = 1;
	for (i = 5; i>= 0; i--)
	{
		if (digits[i] == 0 && should_skip)
			continue;
		else should_skip = 0;
		sci0_write_char('0' + digits[i]);
	}
}


void print_integer(int num, int sci_port);
void print_integer(int num, int sci_port)
{
	int i = 0;
	char sign = 0;

	if(num < 0){
		sign = TRUE;
		num = -num;
	}

	while(num != 0)
	{
		console_printer_buf[i] = ('0' + (num % 10));
		i++;
		num /= 10;
	}

	if(sign)
	{
		if (sci_port == 0) sci0_write_char('-');
		else  sci1_write_char('-');
	}

	while(i >= 0){
		if (sci_port == 0) sci0_write_char(console_printer_buf[i]);
		else  sci1_write_char(console_printer_buf[i]);
		i--;
	}	
}

/****************************************SCI DONE********************************/



int main(void)
{
/**
 * 39(38400bps), 
 * 78(19200bps), 
 * 156(9600bps), 
 * 313(4800bps),
 */	
	unsigned char input;
	sci1_init(156);
	while(1)
	{
		enable_interrupts();
		input = sci1_read_char();
		if (input == '1')
		{
			wait_for_interrupts();
			//PWM CODE
			DB12FNP->printf("PWM CODE\r\n");
			enable_interrupts();
			sci1_write_string("Received input");
		}
	}
}


