/*
 * fray_node0.c
 *
 *  Created on: Sep 25, 2015
 *      Author: a0324020
 */

#include "fray.h"
#include "LED_Show.h"
#include "sci_common.h"
#include "file_io.h"
#include "stdio.h"
#include "fray_node_config.h"


#if ((FrayNodeNumber == 0) && (FRAY_ENABLE_FTU == 0))

static void configure_node_header(FRAY_ST *Fray_Ptr);
static void transmit_check_node(FRAY_ST *Fray_Ptr);
static void transmit_static_data(FRAY_ST *Fray_Ptr);
static void transmit_dynamic_data(FRAY_ST *Fray_Ptr);
static void receive_data(FRAY_ST *Fray_Ptr);

void Fray_Test(FRAY_ST *Fray_Ptr);

void Fray_Test(FRAY_ST *Fray_Ptr)
{
	unsigned int index = 0;

	Fray_testInit(Fray_Ptr);
	configure_node_header(Fray_Ptr);
	Fray_CC_READY(Fray_Ptr, 1, 1);
	Fray_AllowColdStart(Fray_Ptr);
	Fray_StartCommunication(Fray_Ptr);

#if defined (EXPORT_FRAY_STATUS)
    FILE *fp_er;
#endif
    while(1)
	{
#if defined (EXPORT_FRAY_STATUS)
		    if(index == 0){           //only save the data in cycle 0
			fp_er = fopen("ccStat02.txt", "w");

			fprintf(fp_er,"Those are Status and Error.\n");
			fprintf(fp_er, "CCSV :   %8X  \n", *(int *)0xFFF7C900);
			fprintf(fp_er, "CCEV :   %8X  \n", *(int *)0xFFF7C904);
			fprintf(fp_er, "SCV  :   %8X  \n", *(int *)0xFFF7C908);
			fprintf(fp_er, "TXRQ1:   %8X  \n", *(int *)0xFFF7CB20);
			fprintf(fp_er, "TXRQ2:   %8X  \n", *(int *)0xFFF7CB24);
			fprintf(fp_er, "TXRQ3:   %8X  \n", *(int *)0xFFF7CB28);
			fprintf(fp_er, "TXRQ4:   %8X  \n", *(int *)0xFFF7CB2C);
			fprintf(fp_er, "EIR  :   %8X  \n", *(int *)0xFFF7C820);
			fprintf(fp_er, "SIR  :   %8X  \n", *(int *)0xFFF7C824);

			fclose(fp_er);
		}
		index = 1;
#endif
	}

}

static void configure_node_header(FRAY_ST *Fray_Ptr)
{
	HEADER_ST Header;
	BC_ST BufCMD;
	HEADER_ST *Header_Ptr = &Header;
	BC_ST *BC_Ptr = &BufCMD;

	// Buffer config initialization
	Header_Ptr->mbi  = 1;   // message buffer interrupt
	Header_Ptr->txm  = 0;   // transmission mode - continuous mode
	Header_Ptr->ppit = 0;   // Payload Preamble Indicator
	Header_Ptr->cfg  = 0;   // message buffer configuration bit (0=RX, 1 = TX)
	Header_Ptr->chb  = 1;   // Ch B
	Header_Ptr->cha  = 1;   // Ch A
	Header_Ptr->cyc  = 0;   // Cycle Filtering Code (no cycle filtering)
	Header_Ptr->fid  = 0;   // Frame ID
	Header_Ptr->plc  = 0;   // Payload Length
	Header_Ptr->dp   = 0;   // Pointer to start of data in message RAM
	Header_Ptr->sfi  = 0;   // startup frame indicator
	Header_Ptr->syn  = 0;   // sync frame indicator

	BC_Ptr->ibrh = 0;  // input buffer number
	BC_Ptr->stxrh= 0;  // set transmission request
	BC_Ptr->ldsh = 0;  // load data section
	BC_Ptr->lhsh = 0;  // load header section
	BC_Ptr->ibsyh = 1; // check for input buffer busy shadow
	BC_Ptr->ibsys = 1; // check for input buffer busy host
	BC_Ptr->obrs = 0;  // output buffer number
	BC_Ptr->rdss = 0;  // read data section
	BC_Ptr->rhss = 0;  // read header section

	// Message buffers
    // Message buffer 0 or 1 is dedicated to hold the startup frame, the sync frame, or the designated single slot
    // frame as configured by SUCC1.TXST, SUCC1.TXSY, and SUCC1.TSM in the SUC Configuration register
    // 1. In this case it can be reconfigured in DEFAULT_CONFIG or CONFIG state only. This ensures that any
    // node transmits at most one startup / sync frame per communication cycle.

	// Buffer #0
	// The protocol requires that both bits SUCC1.TXST and SUCC1.TXSY are set
	// for coldstart nodes
	Header_Ptr->fid  = 1;    // frame ID
	Header_Ptr->dp   = 0x80; // Pointer to start of data in message RAM
	Header_Ptr->cfg  = 1;    // TX frame
	Header_Ptr->cyc  = 0x00; //All cycles
	Header_Ptr->syn  = 1;    // sync frame indicator
	Header_Ptr->sfi  = 1;    // startup frame indicator
	Header_Ptr->cha  = 1;    // Ch A
	Header_Ptr->chb  = 1;    // Ch B
	Header_Ptr->plc  = 16;	 // 32 byte payload
	Header_Ptr->crc  = header_crc_calc(Header_Ptr);

	BC_Ptr->lhsh = 1;  // load header section
	BC_Ptr->ibrh = 0;  // input buffer number:0x80, 0x85, 0x8A, 0x8F, 0x94, 0x99, 0x9E, 0xA3

	Fray_PrepareHeader(Fray_Ptr, Header_Ptr);
	Fray_Transmit(Fray_Ptr, BC_Ptr);          //transfer header and data to FRAY MSG RAM

	// Buffer #1, receive msg
	Header_Ptr->fid  = 2;    // frame ID
	Header_Ptr->dp   = 0x88; // Pointer to start of data in message RAM
	Header_Ptr->cfg  = 0;    // RX frame
	Header_Ptr->cyc  = 0x04;  //every 4th. 0,4,8,...
	Header_Ptr->syn  = 1;    // sync frame indicator
	Header_Ptr->sfi  = 0;    // startup frame indicator
	Header_Ptr->cha  = 1;    // Ch A
	Header_Ptr->chb  = 1;    // Ch B
	Header_Ptr->plc  =16;
	Header_Ptr->crc  = 0;

	BC_Ptr->lhsh = 1;  // load header section
	BC_Ptr->ibrh = 1;  // input buffer numberinput buffer number:0x80, 0x85, 0x8A, 0x8F, 0x94, 0x99, 0x9E, 0xA3

	Fray_PrepareHeader(Fray_Ptr, Header_Ptr);
	Fray_Transmit(Fray_Ptr, BC_Ptr);          //transfer header and data to FRAY MSG RAM

	// Buffer #3, TX msg
	Header_Ptr->fid  = 5;    // frame ID
	Header_Ptr->dp   = 0xA0; // Pointer to start of data in message RAM
	Header_Ptr->cfg  = 1;    // TX frame
	Header_Ptr->cyc  = 0x23;  //every 32th cycle at 3/35 cycle
	Header_Ptr->syn  = 0;    // sync frame indicator
	Header_Ptr->sfi  = 0;    // startup frame indicator
	Header_Ptr->cha  = 1;    // Ch A
	Header_Ptr->chb  = 1;    // Ch B
	Header_Ptr->plc  = 16;	 // 32 byte payload
	Header_Ptr->crc  = header_crc_calc(Header_Ptr);

	BC_Ptr->lhsh = 1;  // load header section
	BC_Ptr->ibrh = 3;  // input buffer number:0x80, 0x85, 0x8A, 0x8F, 0x94, 0x99, 0x9E, 0xA3

	Fray_PrepareHeader(Fray_Ptr, Header_Ptr);
	Fray_Transmit(Fray_Ptr, BC_Ptr);          //transfer header and data to FRAY MSG RAM

	// buffer #5   -- dynamic
	Header_Ptr->fid  = 9;   // frame ID
	Header_Ptr->dp   = 0x200; // Pointer to start of data in message RAM
	Header_Ptr->cfg  = 1;    // TX frame
	Header_Ptr->cyc  = 0x26;  //every 32th cycle at 6/38 cycle
	Header_Ptr->syn  = 0;    // sync frame indicator
	Header_Ptr->sfi  = 0;    // startup frame indicator
	Header_Ptr->cha  = 1;    // Ch A
	Header_Ptr->chb  = 0;    // Ch B
	Header_Ptr->plc  = 16;	 // 32 byte payload
	Header_Ptr->crc  = header_crc_calc(Header_Ptr);

	BC_Ptr->lhsh = 1;  // load header section
	BC_Ptr->ibrh = 5;  // input buffer number

	Fray_PrepareHeader(Fray_Ptr, Header_Ptr);
	Fray_Transmit(Fray_Ptr, BC_Ptr);          //transfer header and data to FRAY MSG RAM

	// buffer #6
	Header_Ptr->fid  = 15;     // frame ID
	Header_Ptr->dp   = 0x380; // Pointer to start of data in message RAM
	Header_Ptr->cfg  = 0;    // RX frame
	Header_Ptr->cyc  = 0x14;  //every 16th cycle at 4/20/36/52 cycle
	Header_Ptr->syn  = 0;    // sync frame indicator
	Header_Ptr->sfi  = 0;    // startup frame indicator
	Header_Ptr->cha  = 1;    // Ch A
	Header_Ptr->chb  = 0;    // Ch B
	Header_Ptr->plc  = 16;	 // 32 byte payload
	Header_Ptr->crc  = 0;

	BC_Ptr->lhsh = 1;  // load header section
	BC_Ptr->ibrh = 6;  // input buffer number

	Fray_PrepareHeader(Fray_Ptr, Header_Ptr);
	Fray_Transmit(Fray_Ptr, BC_Ptr);          //transfer header and data to FRAY MSG RAM

	// buffer #7, RX MSG
	Header_Ptr->fid  = 16;     // frame ID
	Header_Ptr->dp   = 0x3C0; // Pointer to start of data in message RAM
	Header_Ptr->cfg  = 0;    // RX frame
	Header_Ptr->cyc  = 0x13;  //every 16th cycle at 3/19/35/51 cycle
	Header_Ptr->syn  = 0;    // sync frame indicator
	Header_Ptr->sfi  = 0;    // startup frame indicator
	Header_Ptr->cha  = 1;    // Ch A
	Header_Ptr->chb  = 0;    // Ch B
	Header_Ptr->plc  = 16;
	Header_Ptr->crc  = 0;

	BC_Ptr->lhsh = 1;  // load header section
	BC_Ptr->ibrh = 7;  // input buffer number

	Fray_PrepareHeader(Fray_Ptr, Header_Ptr);
	Fray_Transmit(Fray_Ptr, BC_Ptr);          //transfer header and data to FRAY MSG RAM

}

static void transmit_static_data(FRAY_ST *Fray_Ptr)
{
	BC_ST INBUF;    //input buffer cmd
	BC_ST *IB_Ptr = &INBUF;    //input buffer cmd
	unsigned int i;
	gio_LED_Blinky(0);

	IB_Ptr->ibrh  = 0;  // input buffer number
	IB_Ptr->stxrh = 1;  // set transmission request
	IB_Ptr->ldsh  = 1;  // load data section
	IB_Ptr->lhsh  = 0;  // load header section
	IB_Ptr->ibsys = 0; // check for input buffer busy shadow
	IB_Ptr->ibsyh = 1; // check for input buffer busy host

	// write payload for buffers
	// buffer #0, fid=1
	IB_Ptr->ibrh  = 0;  // input buffer number
	for (i=0; i<8; i++)
    	(Fray_Ptr->WRDS[i] = 0x01010101);    // Node 0, slote 1
	Fray_Transmit(Fray_Ptr, IB_Ptr);

	// write payload for buffers
	// buffer #3, FID=5
	IB_Ptr->ibrh  = 3;  // input buffer number
	for (i=0; i<8; i++)
    	(Fray_Ptr->WRDS[0] = 0x05050505);    // Node 0, slote 5
	Fray_Transmit(Fray_Ptr, IB_Ptr);

	// buffer #5
	IB_Ptr->ibrh = 5;
	for (i=0; i<8; i++)
		(Fray_Ptr->WRDS[i] = 0x09090909);	 // Node 0, slote 1
	Fray_Transmit(Fray_Ptr, IB_Ptr);

}

static void transmit_dynamic_data(FRAY_ST *Fray_Ptr)
{
	BC_ST INBUF;    //input buffer cmd
	BC_ST *IB_Ptr = &INBUF;    //input buffer cmd
	unsigned int i;

	gio_LED_Blinky(1);   //LED 1 for dynmaic seg tx data

	IB_Ptr->ibrh  = 0;  // input buffer number
	IB_Ptr->stxrh = 1;  // set transmission request
	IB_Ptr->ldsh  = 1;  // load data section
	IB_Ptr->lhsh  = 0;  // load header section
	IB_Ptr->ibsys = 0; // check for input buffer busy shadow
	IB_Ptr->ibsyh = 1; // check for input buffer busy host

	// write payload for buffers
	// buffer #0, fid=1
	IB_Ptr->ibrh  = 5;  // input buffer number
	for (i=0; i<8; i++)
    	(Fray_Ptr->WRDS[i] = 0x09090909);    // Node 0, slote 9
	Fray_Transmit(Fray_Ptr, IB_Ptr);
}

static void receive_data(FRAY_ST *Fray_Ptr)
{
	BC_ST OUTBUF;    //output buffer cmd
	BC_ST *OB_Ptr = &OUTBUF;    //output buffer cmd
	unsigned int ndat1;

    ndat1 = Fray_Ptr->NDAT1_UN.NDAT1_UL;

    if ((ndat1 & (0x1 << 1)) != 0) //buffer 1 from Node 1, slot  2
    {
      OB_Ptr->obrs=1;  // output buffer number
      OB_Ptr->rdss=1;  // read data section
      OB_Ptr->rhss=0;  // read header section
      // Transfer message buffer 1 data to output buffer registers
      Fray_Receive(Fray_Ptr, OB_Ptr);
      if (Fray_Ptr->RDDS[0] == 0x12121212)
           gio_LED_Blinky(5);  //4: from Node 0
	}
    if (ndat1 & (0x1 << 6)) //buffer 6 from Node 1, slot  15
    {
        OB_Ptr->obrs=6;  // output buffer number
        OB_Ptr->rdss=1;  // read data section
        OB_Ptr->rhss=0;  // read header section
        // Transfer message buffer 1 data to output buffer registers
        Fray_Receive(Fray_Ptr, OB_Ptr);
        if (Fray_Ptr->RDDS[0] == 0x1F1F1F1F)
            gio_LED_Blinky(5);  //4: from Node 0
    }
    if (ndat1 & (0x1 << 7)) //buffer 7 from Node 1, slot 16
    {
        OB_Ptr->obrs=7;  // output buffer number
        OB_Ptr->rdss=1;  // read data section
        OB_Ptr->rhss=0;  // read header section
        // Transfer message buffer 1 data to output buffer registers
        Fray_Receive(Fray_Ptr, OB_Ptr);
        if (Fray_Ptr->RDDS[1] == 0x10101010)
            gio_LED_Blinky(5);  //4: from Node 0
    }
}


static void transmit_check_node(FRAY_ST *Fray_Ptr)
{
	BC_ST INBUF;    //input buffer cmd
	BC_ST OUTBUF;    //output buffer cmd

	BC_ST *IB_Ptr = &INBUF;    //input buffer cmd
	BC_ST *OB_Ptr = &OUTBUF;    //output buffer cmd

	unsigned int  ndat1, i;

#if defined(FRAY_TEST_MODE)
	unsigned int SSEL;
#endif

	IB_Ptr->ibrh  = 0;  // input buffer number
	IB_Ptr->stxrh = 1;  // set transmission request
	IB_Ptr->ldsh  = 1;  // load data section
	IB_Ptr->lhsh  = 0;  // load header section
	IB_Ptr->ibsys = 0; // check for input buffer busy shadow
	IB_Ptr->ibsyh = 1; // check for input buffer busy host

    // wait for cycle start interrupt flag
    Fray_Ptr->SIR_UN.SIR_UL = 0xFFFFFFFF;            // clear all status int. flags
    while ((Fray_Ptr->SIR_UN.SIR_UL & 0x4) == 0x0);    // wait for CYCS interrupt flag
    Fray_Ptr->SIR_UN.SIR_UL = 0xFFFFFFFF;            // clear all status int. flags

	// write payload for buffers
	// buffer #0, fid=1
	IB_Ptr->ibrh  = 0;  // input buffer number
	for (i=0; i<8; i++)
    	(Fray_Ptr->WRDS[i] = 0x01010101);    // Node 0, slote 1
	Fray_Transmit(Fray_Ptr, IB_Ptr);

	// write payload for buffers
	// buffer #3, FID=5
	IB_Ptr->ibrh  = 3;  // input buffer number
	for (i=0; i<8; i++)
    	(Fray_Ptr->WRDS[0] = 0x05050505);    // Node 0, slote 5
	Fray_Transmit(Fray_Ptr, IB_Ptr);

	// buffer #5
	IB_Ptr->ibrh = 5;
	for (i=0; i<8; i++)
		(Fray_Ptr->WRDS[i] = 0x09090909);	 // Node 0, slote 1
	Fray_Transmit(Fray_Ptr, IB_Ptr);

	// Test mode is used to check the RAM content  (QJ)

#if defined(FRAY_TEST_MODE)
{
	PrintString("\n\rFlexray Message RAM Test Mode!");
	SSEL = 0;
	for (SSEL=0; SSEL<8; SSEL++)
	{
        Fray_TestMode(Fray_Ptr, SSEL);
        file_write((int *)0xFFF7CC00, WRITE_SIZE, SSEL);
	}

	// To return from test mode operation to regular FlexRay operation we strongly recommend to
	// apply a hardware reset (Power on Reset or nReset) to reset all FlexRay internal state
	// machines to their initial state.
	Fray_NormalMode(Fray_Ptr); // this is not a good way to retore to normal mode
}
#endif

	// check received frames
    ndat1 = Fray_Ptr->NDAT1_UN.NDAT1_UL;

    if ((ndat1 & (0x1 << 1)) != 0) //buffer 1 from Node 1, slot  2
    {
      OB_Ptr->obrs=1;  // output buffer number
      OB_Ptr->rdss=1;  // read data section
      OB_Ptr->rhss=0;  // read header section
      // Transfer message buffer 1 data to output buffer registers
      Fray_Receive(Fray_Ptr, OB_Ptr);
      if (Fray_Ptr->RDDS[1] != 0x12121212)
    	  PrintString("\n\rNode 0 got wrong data from Node 1, Slot 2\n");
	}
    else if (ndat1 & (0x1 << 6)) //buffer 6 from Node 1, slot  15
    {
        OB_Ptr->obrs=6;  // output buffer number
        OB_Ptr->rdss=1;  // read data section
        OB_Ptr->rhss=0;  // read header section
        // Transfer message buffer 1 data to output buffer registers
        Fray_Receive(Fray_Ptr, OB_Ptr);
        if (Fray_Ptr->RDDS[1] != 0x1F1F1F1F)
      	  PrintString("\n\rNode 0 got wrong data from Node 1, Slot 15\n");
    }
    else if (ndat1 & (0x1 << 7)) //buffer 7 from Node 1, slot 16
    {
        OB_Ptr->obrs=7;  // output buffer number
        OB_Ptr->rdss=1;  // read data section
        OB_Ptr->rhss=0;  // read header section
        // Transfer message buffer 1 data to output buffer registers
        Fray_Receive(Fray_Ptr, OB_Ptr);
        if (Fray_Ptr->RDDS[1] != 0x10101010)
      	  PrintString("\n\rNode 0 got wrong data from Node 1, Slot 16\n");
    }
}


#pragma WEAK(frayErrorNotification)
void frayErrorNotification(FRAY_ST *Fray_PST, unsigned int notification)
{

}

#pragma WEAK(frayStatusChangeNotification)
void frayStatusChangeNotification(FRAY_ST *Fray_Ptr, unsigned int notification)
{
	if (notification == ( 0x1 << 2))   //CYCS
	{
		transmit_static_data(Fray_Ptr);
	}

	if (notification == ( 0x1 << 4))   //RXI
	{
		receive_data(Fray_Ptr);
	}

	if (notification == ( 0x1 << 15))   //SDS
	{
		transmit_dynamic_data(Fray_Ptr);
	}
}

#endif


