//###########################################################################
//
// FILE:   main.c
//
// TITLE:   
//
//###########################################################################
// $FDMTEK Release: $
// $Release Date:  $
// $Copyright:
//  (C) Copyright 2023 QingDao Fundamental Microelectronic .Ltd - http://www.fdmtek.com
//###########################################################################

#include "RV335_Project.h"     // Device Headerfile and Examples Include File
#include "RV335_SysCtrl.h"
#include "../routines/include/RV335_Device.h"
//
// Defines
//

//
// Amount BRR will be incremented between each autobaud lock
//
#define BAUDSTEP 100

//
// Function Prototypes
//
void scia_init(void);
void scib_init(void);
void scia_xmit(int a);
void scib_xmit(int a);
void scia_AutobaudLock(void);
void error();
void rxaint_isr(void);

//
// Globals
//
Uint16 LoopCount;
//Uint16 xmitCount;
Uint16 ReceivedCount;
Uint16 ErrorCount;
Uint16 SendChar;
Uint16 ReceivedAChar;   // scia received character
Uint16 ReceivedBChar;   // scib received character
Uint16 BRRVal;
Uint16 Buff[10] = {0x55, 0xAA, 0xF0, 0x0F, 0x00, 0xFF, 0xF5, 0x5F, 0xA5, 0x5A};


int main(void)
{
	// Initialize trap
	trap_init();
		init_plic(); //init_priority();
	// Initialize System Control
	InitSysCtrl();
	/* --- add your code below ---*/

	InitSciGpio();

	//
	// Interrupts that are used in this example are re-mapped to
	// ISR functions found within this file.
	//

	IntVectTable.st.SCIRXINTA = &rxaint_isr;


	//
	// Step 4. Initialize all the Device Peripherals:
	// This function is found in RV335_InitPeripherals.c
	//
	// InitPeripherals(); // Not required for this example

	scia_init();       // Initialize SCIA
	scib_init();       // Initialize SCIB

	//
	// Step 5. User specific code, enable interrupts
	//
	LoopCount = 0;
	ErrorCount = 0;

	//
	// Enable interrupts
	//
	enable_interrupt( GET_INT_NUM(IntVectTable.st.SCIRXINTA));  // Enable all SCIA RXINT interrupt


	//
	// Start with BRR = 1, work through each baud rate setting
	// incrementing BRR by BAUDSTEP
	//
	for (BRRVal = 0x0000; BRRVal < (Uint32)0xFFFF; BRRVal+=BAUDSTEP)
	{
		//
		// SCIB has a known baud rate.  SCIA will autobaud to match
		//
		ScibRegs.SCIHBAUD = (BRRVal >> 8);
		ScibRegs.SCILBAUD = (BRRVal);

		//
		// Initiate an autobaud lock with scia.  Check
		// returned character against baud lock character 'A'
		//
		scia_AutobaudLock();
		while(ScibRegs.SCIRXST.bit.RXRDY != 1)
		{

		}
		ReceivedBChar = 0;
		ReceivedBChar =  ScibRegs.SCIRXBUF.bit.RXDT;
		if(ReceivedBChar != 'A')
		{
			error(0);
		}

		//
		// Send/echoback characters
		// 55 AA F0 0F 00 FF F5 5F A5 5A
		//
		for(int i= 0; i<=9; i++)
		{
			SendChar = Buff[i];
			scib_xmit(SendChar);	// Initiate interrupts and xmit data in isr

			//
			// Wait to get the character back and check against the
			// sent character.
			//
			while(ScibRegs.SCIRXST.bit.RXRDY != 1)
			{
				__asm("   NOP");
			}
			ReceivedBChar = 0;
			ReceivedBChar =  ScibRegs.SCIRXBUF.bit.RXDT;

			if(ReceivedBChar != SendChar)
			{
				error(1);
			}
		}
	}

	//
	// Stop here, no more
	//
	for(;;)
	{
	}
	return 0;
}

void rxaint_isr(void)
{
    //
    // Insert ISR Code here
    //

    //
    // If autobaud detected, we must clear CDC
    //
    if(SciaRegs.SCIFFCT.bit.ABD == 1)
    {
        SciaRegs.SCIFFCT.bit.ABDCLR = 1;
        SciaRegs.SCIFFCT.bit.CDC = 0;

        //
        // Check received character - should be 'A'
        //
        ReceivedAChar = 0;
        ReceivedAChar = SciaRegs.SCIRXBUF.all;

        if(ReceivedAChar != 'A')
        {
            error(2);
        }
        else
        {
            scia_xmit(ReceivedAChar);
        }
    }

    //
    // This was not autobaud detect
    //
    else
    {
        //
        // Check received character against sendchar
        //
        ReceivedAChar = 0;
        ReceivedAChar = SciaRegs.SCIRXBUF.all;

        if(ReceivedAChar != SendChar)
        {
            error(3);
        }
        else
        {
            scia_xmit(ReceivedAChar);
        }
    }

    SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;	// clear Receive interrupt flag
    ReceivedCount++;
}

//
// error -
//
void error()
{
    ErrorCount++;
    for (;;);
}

//
// scia_init - SCIA  8-bit word, baud rate 0x000F, default, 1 STOP bit,
// no parity
//
void scia_init()
{
    //
    // Note: Clocks were turned on to the SCIA peripheral
    // in the InitSysCtrl() function
    //

    //
    // Reset FIFO's
    //
    SciaRegs.SCIFFTX.all=0x8000;

    //
    // 1 stop bit,  No loopback, No parity,8 char bits, async mode,
    // idle-line protocol
    //
    SciaRegs.SCICCR.all =0x0007;

    //
    // enable TX, RX, internal SCICLK, Disable RX ERR, SLEEP, TXWAKE
    //
    SciaRegs.SCICTL1.all =0x0003;
    SciaRegs.SCICTL2.all =0x0003;
    SciaRegs.SCICTL2.bit.RXBKINTENA =1;
    SciaRegs.SCICTL1.all =0x0023;     // Relinquish SCI from Reset
}

//
// scib_init - SCIB  8-bit word, baud rate 0x000F, default,
// 1 STOP bit, no parity
//
void scib_init()
{
    //
    // Reset FIFO's
    //
    ScibRegs.SCIFFTX.all=0x8000;

    //
    // 1 stop bit, No parity, 8-bit character, No loopback
    //
    ScibRegs.SCICCR.all = 0x0007;

    //
    // Enable TX, RX, Use internal SCICLK
    //
    ScibRegs.SCICTL1.all = 0x0003;

    //
    // Disable RxErr, Sleep, TX Wake, Disable Rx Interrupt, Tx Interrupt
    //
    ScibRegs.SCICTL2.all = 0x0000;

    //
    // Relinquish SCI-A from reset
    //
    ScibRegs.SCICTL1.all = 0x0023;

    return;
}

//
// scia_xmit - Transmit a character from the SCI-A'
//
void scia_xmit(int a)
{
    SciaRegs.SCITXBUF=a;
}

//
// scib_xmit - Transmit a character from the SCI-B'
//
void scib_xmit(int a)
{
    ScibRegs.SCITXBUF=a;
}

//
// scia_AutobaudLock - Perform autobaud lock with the host. Note that if
// autobaud never occurs the program will hang in this routine as there is
// no timeout mechanism included.
//
void scia_AutobaudLock()
{
    SciaRegs.SCICTL1.bit.SWRESET = 0;
    SciaRegs.SCICTL1.bit.SWRESET = 1;

    //
    // Must prime baud register with >= 1
    //
    SciaRegs.SCIHBAUD = 0;
    SciaRegs.SCILBAUD = 1;

    //
    // Prepare for autobaud detection
    // Make sure the ABD bit is clear by writing a 1 to ABDCLR
    // Set the CDC bit to enable autobaud detection
    //
    SciaRegs.SCIFFCT.bit.ABDCLR = 1;
    SciaRegs.SCIFFCT.bit.CDC = 1;

    //
    // Wait until we correctly read an
    // 'A' or 'a' and lock
    //
    // As long as Autobaud calibration is enabled (CDC = 1),
    // SCI-B (host) will continue transmitting 'A'. This will
    // continue until interrupted by the SCI-A RX ISR, where
    // SCI-A RXBUF receives 'A', autobaud-locks (ABDCLR=1
    // CDC=0),and returns an 'A' back to the host. Then control
    // is returned to this loop and the loop is exited.
    //
    // NOTE: ABD will become set sometime between
    //       scib_xmit and the DELAY_US loop, and
    //       the SCI-A RX ISR will be triggered.
    //       Upon returning and reaching the if-statement,
    //       ABD will have been cleared again by the ISR.
    //

    while(SciaRegs.SCIFFCT.bit.CDC== 1)
    {
        //
        // Note the lower the baud rate the longer
        // this delay has to be to allow the other end
        // to echo back a character (about 4 characters long)
        // Make this really long since we are going through all
        // the baud rates.
        //

        if(SciaRegs.SCIFFCT.bit.CDC == 1)
        {

        }
        scib_xmit('A');  // host transmits 'A'
        DELAY_US(280000L);

    }
    return;
}

//
// End of File
//

