/*
 * sci.c
 *
 *  Created on: Apr 7, 2016
 *      Author: de360684 SAILESH PANDEY
 */
#include "sci.h"

#define CPU_FREQ 	 100E6
#define LSPCLK_FREQ  CPU_FREQ/4
#define SCI_FREQ 	 100E3
#define SCI_PRD 	 (LSPCLK_FREQ/(SCI_FREQ*8))-1


//unsigned char Data_Receive;
//unsigned char SCIFLAG;

unsigned short sdataA[8];    // Send data for SCI-A
unsigned short rdataA[8];    // Received data for SCI-A

unsigned short sdataB[8];    // Send data for SCI-B
unsigned short rdataB[8];    // Received data for SCI-B

unsigned short sdataC[8];    // Send data for SCI-C
unsigned short rdataC[8];    // Received data for SCI-C

unsigned short *rdata_pointA; // Used for checking the received data
unsigned short *rdata_pointB; // Used for checking the received data
unsigned short *rdata_pointC; // Used for checking the received data


void scia_fifo_init();
void scib_fifo_init();
void scic_fifo_init();

void Gpio_SciA_init(void);
void Gpio_SciB_init(void);
void Gpio_SciC_init(void);

__interrupt void sciaRxFifoIsr(void);
__interrupt void sciaTxFifoIsr(void);

__interrupt void scibRxFifoIsr(void);
__interrupt void scibTxFifoIsr(void);

__interrupt void scicRxFifoIsr(void);
__interrupt void scicTxFifoIsr(void);

void InitSci(void)
{
	unsigned char i;

	/* Configuration of gpio as SCI TX and RX */
	Gpio_SciA_init();
	Gpio_SciB_init();
	Gpio_SciC_init();

	scia_fifo_init();  // Init SCI-A
	scib_fifo_init();  // Init SCI-B
	scic_fifo_init();  // Init SCI-C

	EALLOW;	// This is needed to write to EALLOW protected registers
	/*  SCI-A Interrupts */
	PieVectTable.SCIRXINTA = &sciaRxFifoIsr;
	PieVectTable.SCITXINTA = &sciaTxFifoIsr;
	/*  SCI-B Interrupts */
	PieVectTable.SCIRXINTB = &scibRxFifoIsr;
	PieVectTable.SCITXINTB = &scibTxFifoIsr;
	/*  SCI-C Interrupts */
	PieVectTable.SCIRXINTC = &scicRxFifoIsr;
	PieVectTable.SCITXINTC = &scicTxFifoIsr;
	EDIS;

	 /*loop*/
	for(i = 0; i<8; i++)
	{
		sdataA[i] = ('A' + i);
	}
	rdata_pointA = sdataA;
	rdata_pointB = sdataB;


	// Enable interrupts required for this example
	PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // Enable the PIE block
	PieCtrlRegs.PIEIER9.bit.INTx1=1;     // PIE Group 9, int1 SCI RX for SCI A INTERRUPT
	PieCtrlRegs.PIEIER9.bit.INTx2=1;     // PIE Group 9, int2 SCI TX for SCI A INTERRUPT

	PieCtrlRegs.PIEIER9.bit.INTx3=1;     // PIE Group 9, int1 SCI RX for SCI A INTERRUPT
	PieCtrlRegs.PIEIER9.bit.INTx4=1;     // PIE Group 9, int2 SCI TX for SCI A INTERRUPT

	PieCtrlRegs.PIEIER8.bit.INTx5=1;     // PIE Group 9, int1 SCI RX for SCI A INTERRUPT
	PieCtrlRegs.PIEIER8.bit.INTx6=1;     // PIE Group 9, int2 SCI TX for SCI A INTERRUPT
	IER = 0x100;	// Enable CPU INT
	IER = 0x80;	// Enable CPU INT
	EINT;
}

void error(void)
{
    __asm("     ESTOP0"); // Test failed!! Stop!
    for (;;);
}

void ReceiveSCIBuff(unsigned char *buf)
{
	if(ScicRegs.SCIRXST.bit.RXRDY)
	{
		EALLOW;
		*buf                             	=   ScicRegs.SCIRXBUF.bit.RXDT ;
		ScicRegs.SCICTL2.bit.RXBKINTENA	 	=   ENABLE;     // Receive interrupt enable
		PieCtrlRegs.PIEACK.all 				= PIEACK_GROUP8;
		IER |= 0x080; // Enable INT9
		EINT;   // Enable Global interrupt INTM
		EDIS;
	}
}

__interrupt void sciaRxFifoIsr(void)
{
    unsigned short i;

	for(i=0;i<8;i++)
	{
	   rdataA[i]=SciaRegs.SCIRXBUF.all;	 // Read data
	}
	for(i=0;i<8;i++)                     // Check received data
	{
	   if(rdataA[i] != ( *(rdata_pointA+i) & 0x00FF) ) error();
	}
	//rdata_pointA = (rdata_pointA+1) & 0x00FF;

	SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1;   // Clear Overflow flag
	SciaRegs.SCIFFRX.bit.RXFFINTCLR=1;   // Clear Interrupt flag

	PieCtrlRegs.PIEACK.all|=0x100;       // Issue PIE ack
}

__interrupt void sciaTxFifoIsr(void)
{
	unsigned short i;

    for(i=0; i< 8; i++)
    {
 	   SciaRegs.SCITXBUF=sdataA[i];     // Send data
	}
    //	SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;	// Clear SCI Interrupt flag
	PieCtrlRegs.PIEACK.all|=0x100;      // Issue PIE ACK
}

__interrupt void scibRxFifoIsr(void)
{
    unsigned short i;

	for(i=0;i<8;i++)
	{
	   rdataB[i]=ScibRegs.SCIRXBUF.all;	 // Read data
	}
	for(i=0;i<8;i++)                     // Check received data
	{
	   if(rdataB[i] != ( *(rdata_pointB+i) & 0x00FF) ) error();
	}

	ScibRegs.SCIFFRX.bit.RXFFOVRCLR=1;   // Clear Overflow flag
	ScibRegs.SCIFFRX.bit.RXFFINTCLR=1;   // Clear Interrupt flag

	PieCtrlRegs.PIEACK.all|=0x100;       // Issue PIE ack
}

__interrupt void scibTxFifoIsr(void)
{
	unsigned short i;

    for(i=0; i< 8; i++)
    {
 	   ScibRegs.SCITXBUF=sdataB[i];     // Send data
	}

	PieCtrlRegs.PIEACK.all|=0x100;      // Issue PIE ACK
}

__interrupt void scicRxFifoIsr(void)
{
    unsigned short i;

	for(i=0;i<8;i++)
	{
	   rdataC[i]=ScicRegs.SCIRXBUF.all;	 // Read data
	}
	for(i=0;i<8;i++)                     // Check received data
	{
	   if(rdataC[i] != ( *(rdata_pointC+i) & 0x00FF) ) error();
	}

	ScicRegs.SCIFFRX.bit.RXFFOVRCLR=1;   // Clear Overflow flag
	ScicRegs.SCIFFRX.bit.RXFFINTCLR=1;   // Clear Interrupt flag

	PieCtrlRegs.PIEACK.all|=0x80;       // Issue PIE ack
}

__interrupt void scicTxFifoIsr(void)
{
	unsigned short i;
    for(i=0; i< 8; i++)
    {
 	   ScicRegs.SCITXBUF=sdataC[i];     // Send data
	}

	PieCtrlRegs.PIEACK.all|=0x80;      // Issue PIE ACK
}

void scia_fifo_init()
{
   SciaRegs.SCICCR.all =0x0007;   // 1 stop bit,  No loopback
                                  // No parity,8 char bits,
                                  // async mode, idle-line protocol
   SciaRegs.SCICTL1.all =0x0003;  // enable TX, RX, internal SCICLK,
                                  // Disable RX ERR, SLEEP, TXWAKE
   SciaRegs.SCICTL2.bit.TXINTENA =1;
   SciaRegs.SCICTL2.bit.RXBKINTENA =1;
   SciaRegs.SCIHBAUD = 0x0000;
   SciaRegs.SCILBAUD = SCI_PRD;
   SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back
   //SciaRegs.SCIFFTX.all=0xC028;  // loopback working
   //SciaRegs.SCIFFRX.all=0x0028;  // loopback working
   SciaRegs.SCIFFTX.all=0xE028; // trying normal mode
   SciaRegs.SCIFFRX.all=0x2028; // trying normal mode
   SciaRegs.SCIFFCT.all=0x00;

   SciaRegs.SCICTL1.all =0x0023;     // Relinquish SCI from Reset
   SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1;
   SciaRegs.SCIFFRX.bit.RXFIFORESET=1;

}

void scib_fifo_init()
{
   ScibRegs.SCICCR.all =0x0007;   // 1 stop bit,  No loopback
                                  // No parity,8 char bits,
                                  // async mode, idle-line protocol
   ScibRegs.SCICTL1.all =0x0003;  // enable TX, RX, internal SCICLK,
                                  // Disable RX ERR, SLEEP, TXWAKE
   ScibRegs.SCICTL2.bit.TXINTENA =1;
   ScibRegs.SCICTL2.bit.RXBKINTENA =1;
   ScibRegs.SCIHBAUD = 0x0000;
   ScibRegs.SCILBAUD = SCI_PRD;
   ScibRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back

   ScibRegs.SCIFFTX.all=0xE028; // trying normal mode
   ScibRegs.SCIFFRX.all=0x2028; // trying normal mode
   ScibRegs.SCIFFCT.all=0x00;

   ScibRegs.SCICTL1.all =0x0023;     // Relinquish SCI from Reset
   ScibRegs.SCIFFTX.bit.TXFIFOXRESET=1;
   ScibRegs.SCIFFRX.bit.RXFIFORESET=1;

}

void scic_fifo_init()
{
   ScicRegs.SCICCR.all =0x0007;   // 1 stop bit,  No loopback
                                  // No parity,8 char bits,
                                  // async mode, idle-line protocol
   ScicRegs.SCICTL1.all =0x0003;  // enable TX, RX, internal SCICLK,
                                  // Disable RX ERR, SLEEP, TXWAKE
   ScicRegs.SCICTL2.bit.TXINTENA =1;
   ScicRegs.SCICTL2.bit.RXBKINTENA =1;
   ScicRegs.SCIHBAUD = 0x0000;
   ScicRegs.SCILBAUD = SCI_PRD;
   ScicRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back

   ScicRegs.SCIFFTX.all=0xE028; // trying normal mode
   ScicRegs.SCIFFRX.all=0x2028; // trying normal mode
   ScicRegs.SCIFFCT.all=0x00;

   ScicRegs.SCICTL1.all =0x0023;     // Relinquish SCI from Reset
   ScicRegs.SCIFFTX.bit.TXFIFOXRESET=1;
   ScicRegs.SCIFFRX.bit.RXFIFORESET=1;

}

void Gpio_SciA_init(void)
{
		/* Enable internal pull-up for the selected pins */
		// Pull-ups can be enabled or disabled disabled by the user.
		// This will enable the pullups for the specified pins.

		GpioCtrlRegs.GPBPUD.bit.GPIO35 = 0;    // Enable pull-up for GPIO29 (SCITXDA)
		//GpioCtrlRegs.GPAPUD.bit.GPIO29 = 0;    // Enable pull-up for GPIO29 (SCITXDA)
		GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0;	   // Enable pull-up for GPIO28 (SCIRXDA)

		/* Set qualification for selected pins to asynch only */
		// Inputs are synchronized to SYSCLKOUT by default.
		// This will select asynch (no qualification) for the selected pins.

		GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3;  // Asynch input GPIO28 (SCIRXDA)

		/* Configure SCI-A pins using GPIO regs*/
		// This specifies which of the possible GPIO pins will be SCI functional pins.

		GpioCtrlRegs.GPBMUX1.bit.GPIO35 = 1;   // Configure GPIO29 for SCITXDA operation
		//GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1;   // Configure GPIO29 for SCITXDA operation
		GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1;   // Configure GPIO28 for SCIRXDA operation
}

void Gpio_SciB_init(void)
{
		/* Enable internal pull-up for the selected pins */
		// Pull-ups can be enabled or disabled disabled by the user.
		// This will enable the pullups for the specified pins.

		GpioCtrlRegs.GPAPUD.bit.GPIO22 = 0;    // Enable pull-up for GPIO22 (SCITXDA)
		GpioCtrlRegs.GPAPUD.bit.GPIO23 = 0;	   // Enable pull-up for GPIO23 (SCIRXDA)

		/* Set qualification for selected pins to asynch only */
		// Inputs are synchronized to SYSCLKOUT by default.
		// This will select asynch (no qualification) for the selected pins.

		GpioCtrlRegs.GPAQSEL2.bit.GPIO23 = 3;  // Asynch input GPIO23 (SCIRXDA)

		/* Configure SCI-A pins using GPIO regs*/
		// This specifies which of the possible GPIO pins will be SCI functional pins.

		GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 3;   // Configure GPIO29 for SCITXDA operation
		GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 3;   // Configure GPIO28 for SCIRXDA operation
}

void Gpio_SciC_init(void)
{
		/* Enable internal pull-up for the selected pins */
		// Pull-ups can be enabled or disabled disabled by the user.
		// This will enable the pullups for the specified pins.

		GpioCtrlRegs.GPBPUD.bit.GPIO62 = 0;    // Enable pull-up for GPIO62 (SCIRXDA)
		GpioCtrlRegs.GPBPUD.bit.GPIO63 = 0;    // Enable pull-up for GPIO63 (SCITXDA)

		/* Set qualification for selected pins to asynch only */
		// Inputs are synchronized to SYSCLKOUT by default.
		// This will select asynch (no qualification) for the selected pins.

		GpioCtrlRegs.GPBQSEL2.bit.GPIO62 = 3;  // Asynch input GPIO62 (SCIRXDA)

		/* Configure SCI-A pins using GPIO regs*/
		// This specifies which of the possible GPIO pins will be SCI functional pins.

		GpioCtrlRegs.GPBMUX2.bit.GPIO62 = 1;   // Configure GPIO62 for SCITXDA operation
		GpioCtrlRegs.GPBMUX2.bit.GPIO63 = 1;   // Configure GPIO63 for SCIRXDA operation
}

