/*
 *
 */
/**************************Hlavickove soubory**************************************************************************************/
#include <machine/intrinsics.h>
#include <machine/cint.h>
#include <machine/wdtcon.h>

#include <tc27xc/IfxDma_reg.h>
#include <tc27xc/IfxDma_regdef.h>


#include <tc27xc/IfxQspi_reg.h>
#include <tc27xc/IfxQspi_regdef.h>

#include <tc27xc/IfxSrc_reg.h>
#include <tc27xc/IfxSrc_regdef.h>

#include <tc27xc/IfxSbcu_reg.h>
#include <tc27xc/IfxSbcu_regdef.h>

#include <tc27xc/IfxPort_reg.h>
#include <tc27xc/IfxPort_regdef.h>

#include <tc27xc/IfxGpt12_reg.h>
#include <tc27xc/IfxGpt12_regdef.h>
/***************************************Vlasna knihovna***************************************/

#include "QspiDmaDriverV2.h"
/*************************************Externi objeky*********************************************/

/********************************Globalni promene*********************************************/

volatile unsigned int InitSlave[11] = {1,2,3,4,5,6,7,8,9,10};
volatile unsigned int RecSlave[11] = {0};


/*******************************Makra********************************************************************************/

#define ADDRESS(cpu, address) ((((((unsigned)(address) & 0xF0000000) == 0xD0000000) ? ((((unsigned)(address) & 0x000fffff) | 0x70000000) - ((cpu) * 0x10000000)) : (unsigned)(address))))
#define Tx_PRIO  10
#define Rx_PRIO  11
#define ReloadTimer_2_PRIO 0xFF


/**************************Lokalni promene******************************************************************/
typedef struct BaconBits
{
    unsigned int LAST:1;                    /**< \brief [0:0] Last Word in a Frame (rh) */
    unsigned int IPRE:3;                    /**< \brief [3:1] Prescaler for the Idle Delay (rh) */
    unsigned int IDLE:3;                    /**< \brief [6:4] Idle Delay Length (rh) */
    unsigned int LPRE:3;                    /**< \brief [9:7] Prescaler for the Leading Delay (rh) */
    unsigned int LEAD:3;                    /**< \brief [12:10] Leading Delay Length (rh) */
    unsigned int TPRE:3;                    /**< \brief [15:13] Prescaler for the Trailing Delay (rh) */
    unsigned int TRAIL:3;                   /**< \brief [18:16] Trailing Delay Length (rh) */
    unsigned int PARTYP:1;                  /**< \brief [19:19] Parity Type (rh) */
    unsigned int UINT:1;                    /**< \brief [20:20] User Interrupt at the PT1 Event in the Subsequent Frames (rh) */
    unsigned int MSB:1;                     /**< \brief [21:21] Shift MSB or LSB First (rh) */
    unsigned int BYTE:1;                    /**< \brief [22:22] Byte (rh) */
    unsigned int DL:5;                      /**< \brief [27:23] Data Length (rh) */
    unsigned int CS:4;                      /**< \brief [31:28] Channel Select (rh) */
} BaconBits;

/**************************Staticke globalni promene**************************************/
static volatile BaconBits pom;
static volatile unsigned int BaconReg = 0;//
static volatile unsigned int ReadReg1 = 0;//
static volatile unsigned int pom1 = 0;//
static volatile unsigned int SAdr1 = 0;//Store source address
static volatile unsigned int SAdr0 = 0;//Store source address
static volatile unsigned int DAdr1 =  0;//Store destination address
static volatile unsigned int DAdr0 = 0;//Store destination address
static volatile unsigned int res = 0;


/**************************funkci prototypy**************************************/

extern void Init(void);
extern void Start(void);

static void IrqTx(int arg);
static void IrqRx (int arg);
static void InitOSPI(void);
static void InitDma_0(void);
static void InitDma_1(void);
static void intit_GPTR1_Tim3(void);
static void irq_Tim2(int arg);


/***************************Definice Globalnich funkci********************************************/

extern void Init(void)
{
	InitOSPI();//Initialization of module QSPI
	InitDma_0();//Initialization of module DMA with predefined channel 1, 2
	InitDma_1();
	intit_GPTR1_Tim3();// Initialization of module General Purpose Timer set as autoreload timer.
}
extern void Start(void)
{
	MODULE_QSPI0.BACONENTRY.U = BaconReg;//Set up configuration
	MODULE_QSPI0.DATAENTRY[0].U = 0x00000000;
	MODULE_DMA.CH[0].CHCSR.B.SCH = 1;
	while(MODULE_DMA.TSR[0].B.CH != 0)
			;

	MODULE_QSPI0.GLOBALCON.B.EN = 1;
	MODULE_GPT120.T3CON.B.T3R = 0b1;

}
/***************************Definice Lokalnich funkci********************************************/
static void IrqTx(int arg)/*ISR QSPI function transmit*/
{
	(void) arg;
}

static void IrqRx (int arg)/*ISR QSPI function receive*/
{
	(void) arg;
}

static void InitOSPI(void)
{

	unlock_wdtcon ();//reset ENDINIT bit
	MODULE_QSPI0.CLC.U = 0;/*enable clc modlue*/
	ReadReg1 = MODULE_QSPI0.CLC.U;/*Read back*/
	lock_wdtcon ();//set ENDINIT bit


	MODULE_SRC.QSPI.QSPI[0].TX.B.SRPN = Tx_PRIO;//Service Request Priority Number
	MODULE_SRC.QSPI.QSPI[0].TX.B.TOS = 0;//Type of Service Control 0 = CPU 0
	MODULE_SRC.QSPI.QSPI[0].TX.B.SRE = 1; //Service Request Enable

	MODULE_SRC.QSPI.QSPI[0].RX.B.SRPN = Rx_PRIO;
	MODULE_SRC.QSPI.QSPI[0].RX.B.TOS = 0;
	MODULE_SRC.QSPI.QSPI[0].RX.B.SRE = 1;


	_install_int_handler(Tx_PRIO, IrqTx, 0); //interrupt handler QSPI0 Req tx
	_install_int_handler(Rx_PRIO, IrqRx, 0);//interrupt handler QSPI0 Req rx
	_enable ();


	pom.LAST = 1;/*Last Word in a Frame*/
	pom.IPRE = 0b111;;/*Prescaler for the Idle Delay*/
	pom.IDLE = 7; /*Idle Delay Length*/
	pom.LPRE = 0b111;/*Prescaler for the Leading Delay*/
	pom.LEAD = 7;/*Leading Delay Length*/
	pom.TPRE = 0b111;/*Prescaler for the Trailing Delay*/
	pom.TRAIL = 7; /*Trailing Delay Length*/
	pom.PARTYP = 0; /*Parity Type*/
	pom.UINT = 0;/*User Interrupt at the PT1 Event in the Subsequent Frames*/
	pom.MSB = 0b1;/*Shift MSB or LSB First*/
	pom.BYTE = 0b0; /*0B DL defines the data length in bits*/
	pom.DL = 31;/*31D 32 bits or bytes*/
	pom.CS = 0x2;/*Channel Select*/


	BaconReg |= (pom.CS  << 28 ) ;
	BaconReg |=	(pom.DL  << 23 ) ;
	BaconReg |= (pom.BYTE  << 22 ) ;
	BaconReg |= (pom.MSB  << 21 ) ;
	BaconReg |= (pom.UINT  << 20 ) ;
	BaconReg |= (pom.PARTYP  << 16 ) ;
	BaconReg |= (pom.TRAIL  << 16 ) ;
	BaconReg |= (pom.TPRE << 13 ) ;
	BaconReg |= (pom.LEAD << 10 ) ;
	BaconReg |= (pom.LPRE << 7 ) ;
	BaconReg |= (pom.IDLE << 4 ) ;
	BaconReg |= (pom.IPRE << 1 ) ;
	BaconReg |= (pom.LAST << 0);

	//MODULE_QSPI0.FLAGSCLEAR.U = 0x9FFF;/*Clear all flags*/
	/*******GLOBALCON Register page 1832*************/
	MODULE_QSPI0.GLOBALCON.B.TQ = 255;/*Global Time Quantum Length*/
	MODULE_QSPI0.GLOBALCON.B.MS= 0;/*Master Slave Mode - 00B Master Transmit and Receive*/
	MODULE_QSPI0.GLOBALCON.B.LB= 1;/*Loop-Back Control*/
	MODULE_QSPI0.GLOBALCON.B.STIP= 0;/**/
	MODULE_QSPI0.GLOBALCON.B.MS= 0b00;/*Master Slave Mode*/
	MODULE_QSPI0.GLOBALCON.B.SI= 0b0;/*Status Injection*/
	MODULE_QSPI0.GLOBALCON.B.SRF= 0b0;
	MODULE_QSPI0.GLOBALCON.B.EXPECT = 0;
	MODULE_QSPI0.GLOBALCON.B.RESETS = 0b0111;
	/*******GLOBALCON1 Register page*************/
	MODULE_QSPI0.GLOBALCON1.B.TXFM = 0b01;/*01B Single Move Mode*/
	MODULE_QSPI0.GLOBALCON1.B.RXFM = 0b01;/*RXFIFO Mode*/
	MODULE_QSPI0.GLOBALCON1.B.TXFIFOINT = 0b01;
	MODULE_QSPI0.GLOBALCON1.B.RXFIFOINT = 0b00;
	MODULE_QSPI0.GLOBALCON1.B.TXEN = 0b1;//Tx Interrupt Event Enable
	MODULE_QSPI0.GLOBALCON1.B.RXEN = 0b1;//Rx Interrupt Event Enable
	/*******ECON Register page 1844*************/
	MODULE_QSPI0.ECON[2].B.Q = 0x3F;/*Time Quantum*/
	MODULE_QSPI0.ECON[2].B.A = 0b01;/*A - Bit Segment 1*/
	MODULE_QSPI0.ECON[2].B.B = 0b00;/*A - Bit Segment 2*/
	MODULE_QSPI0.ECON[2].B.C = 0b10;/*A - Bit Segment 3*/
	MODULE_QSPI0.ECON[2].B.CPH = 0b0;/*Delay of one half SCLK clock cycle.*/
	MODULE_QSPI0.ECON[2].B.CPOL = 0b0;/*Clock Polarity*/
	MODULE_QSPI0.ECON[2].B.PAREN = 0b0;/*Enable Parity Check*/
	MODULE_QSPI0.ECON[2].B.BE = 0b00;/*Permutate bytes to / from Big Endian*/
	/***************RESET FLAGS***********************************************************/
	MODULE_QSPI0.PISEL.B.MRIS = 0;
	MODULE_P20.IOCR8.B.PC11 = 0x13;/*QSPI0 output SCLK0 1X011B, p.1230*/
	MODULE_P20.IOCR12.B.PC12 = 0x01;/*QSPI0 input MRST0A 0XXXXB*/
	MODULE_P20.IOCR12.B.PC14 = 0x13;/*QSPI0 output MTSR0 1X011B*/
	MODULE_P20.IOCR12.B.PC13 = 0x13;/*QSPI0 output SLSO02 1X011B*/
	//MODULE_P20.PDR1.B.PD11 = 0x2;
	//MODULE_P20.PDR1.B.PD12 = 0x2;
	//MODULE_P20.PDR1.B.PD13 = 0x2;
	//MODULE_P20.PDR1.B.PD14 = 0x2;

	MODULE_QSPI0.SSOC.B.OEN = 0;//0x0004;/*Enable Bits for the SLSO Outputs*/
	MODULE_QSPI0.SSOC.B.AOL = 0x0000;/*Active Output Level for the SLSO Outputs*/



}

static void InitDma_0(void)
{
	/*Enable CLC module*/
	unlock_wdtcon ();
		MODULE_DMA.CLC.U = 8;/*Enable Clock control module*/
		pom1 = MODULE_DMA.CLC.U;
	lock_wdtcon ();

	SAdr0 = ADDRESS(0, (unsigned int) &InitSlave);/*Source address*/
	DAdr0 = ADDRESS(0,  (unsigned int) &MODULE_QSPI0.DATAENTRY[0].U);/*receive address*/
	MODULE_DMA.CH[0].SADR.B.SADR = SAdr0;//Set up source address
	MODULE_DMA.CH[0].DADR.B.DADR = DAdr0;//set up destination adress

	MODULE_DMA.CH[0].CHCFGR.B.DMAPRIO = 0b00; //channel priority in the bus

	MODULE_DMA.CH[0].CHCFGR.B.CHDW = 0b010; /*Channel Data Width*/
	MODULE_DMA.CH[0].CHCFGR.B.BLKM = 0b000;/*One DMA transfer has 4 DMA move, BLKM determines the number of DMA moves executed
	//during one DMA transfer.*/
	MODULE_DMA.CH[0].CHCFGR.B.TREL = 1;/*Transfer Reload Value*/
	MODULE_DMA.CH[0].CHCFGR.B.CHMODE = 0;/*Channel Operation Mode*/

	MODULE_DMA.TSR[0].B.DCH = 1;/*Disable Hardware Transfer Request*/

	MODULE_DMA.CH[0].ADICR.B.SMF = 0b000;/*Source Address Modification Factor*/
	MODULE_DMA.CH[0].ADICR.B.INCS = 1;/*Increment of Source Address*/
    MODULE_DMA.CH[0].ADICR.B.DMF = 0b000;/*Destination Address Modification Factor*/
	MODULE_DMA.CH[0].ADICR.B.INCD = 1;/*Increment of Destination Address*/
	MODULE_DMA.CH[0].ADICR.B.INTCT = 0b01;

	MODULE_DMA.CH[0].CHCFGR.B.RROAT = 0;// 0b0, Reset Request Only After Transaction

}

static void InitDma_1(void)
{
	/*Enable CLC module*/
	unlock_wdtcon ();
		MODULE_DMA.CLC.U = 8;
		pom1 = MODULE_DMA.CLC.U;
	lock_wdtcon ();

	SAdr1 = ADDRESS(0,  (unsigned int) &MODULE_QSPI0.RXEXIT.U);/*Source address*/
	DAdr1 = ADDRESS(0,  (unsigned int) &RecSlave);/*receive address*/
	MODULE_DMA.CH[1].SADR.B.SADR = SAdr1;
	MODULE_DMA.CH[1].DADR.B.DADR = DAdr1;

	MODULE_DMA.CH[1].CHCFGR.B.DMAPRIO = 0b00;

	MODULE_DMA.CH[1].CHCFGR.B.CHDW = 0b010; /*Channel Data Width*/
	MODULE_DMA.CH[1].CHCFGR.B.BLKM = 0b000;/**/
	MODULE_DMA.CH[1].CHCFGR.B.TREL = 1;/*Transfer Reload Value*/
	MODULE_DMA.CH[1].CHCFGR.B.CHMODE = 0;/*Channel Operation Mode*/

	MODULE_DMA.TSR[1].B.DCH = 1;/*Disable Hardware Transfer Request*/

	MODULE_DMA.CH[1].ADICR.B.SMF = 0b000;/*Source Address Modification Factor*/
	MODULE_DMA.CH[1].ADICR.B.INCS = 1;/*Increment of Source Address*/
    MODULE_DMA.CH[1].ADICR.B.DMF = 0b000;/*Destination Address Modification Factor*/
	MODULE_DMA.CH[1].ADICR.B.INCD = 1;/*Increment of Destination Address*/
	MODULE_DMA.CH[1].ADICR.B.INTCT = 0b01;

	MODULE_DMA.CH[1].CHCFGR.B.RROAT = 0;
}



static void irq_Tim2(int arg)
{
	(void)arg;
	/********************************************/

	/*Initialization slave */
	MODULE_DMA.CH[0].CHCSR.B.SCH = 1;
	while(MODULE_DMA.TSR[0].B.CH != 0);
	MODULE_DMA.CH[0].SADR.B.SADR = SAdr0;
	MODULE_DMA.CH[0].DADR.B.DADR = DAdr0;
		/*Transmit data xxxxx*/

	MODULE_GPT120.T3CON.B.T3EDGE = 0;//Timer T3 Edge Detection Flag
	MODULE_GPT120.T2CON.B.T2EDGE = 0;//Timer T2 Edge Detection
}


static void intit_GPTR1_Tim3(void)
{
	unlock_wdtcon ();
	res = MODULE_GPT120.CLC.U;
	MODULE_GPT120.CLC.U = 0;
	res = MODULE_GPT120.CLC.U;
	lock_wdtcon ();

	MODULE_SRC.GPT12.GPT12[0].T2.B.SRPN = ReloadTimer_2_PRIO;/*Highest priority*/
	MODULE_SRC.GPT12.GPT12[0].T2.B.SRE = 0b1;/*enable service request*/
	MODULE_SRC.GPT12.GPT12[0].T2.B.TOS = 0b00; /*Type of Service Control ;0H CPU0 service is initiated*/

	_install_int_handler(ReloadTimer_2_PRIO, irq_Tim2, 0);//interupt handler irq_Tim2();
	_enable(); //enable global interrupt

	res  = MODULE_GPT120.T2CON.U;
	MODULE_GPT120.T2CON.B.T2UDE = 0b0;/*Count direction is controlled by bit T3UD;input T3EUD is disconnected*/
	MODULE_GPT120.T2CON.B.T2RC = 0b0; /*Timer T2 is controlled by its own run bit T2R*/
	MODULE_GPT120.T2CON.B.T2UD = 0b0;/*1B - Timer T3 counts down*/
	MODULE_GPT120.T2CON.B.T2M = 0b100;/*100B Reload Mode*/
	MODULE_GPT120.T2CON.B.T2I = 0b101;/*Positive transition (rising edge) of T3 toggle latch T3OTL2)*/
	MODULE_GPT120.T2.U = 0x5000;/*reload value*/ /*Realoaded value*/
	res  = MODULE_GPT120.T2CON.U;

	res  = MODULE_GPT120.T3CON.U;
	MODULE_GPT120.T3CON.B.T3OTL = 0b1;/*Timer T3 Overflow Toggle Latch*/
	MODULE_GPT120.T3CON.B.T3UDE = 0b0;/*Count direction is controlled by bit T3UD;
     input T3EUD is disconnected*/
	MODULE_GPT120.T3CON.B.T3UD = 0b1;/*0B Timer T3 counts down*/
	MODULE_GPT120.T3CON.B.T3M = 0b000;/*Timer Mode*/
	MODULE_GPT120.T3CON.B.T3I = 0b100;/*Prescaler*/
	MODULE_GPT120.T3CON.B.BPS1 = 0b10;/*prescaler*/

	//MODULE_GPT120.T3CON.B.T3R = 0b1;/*run*/
	//MODULE_GPT120.T2CON.B.T2R = 0b1; /*Timer T3 Run Bit; 0B Timer T3 stops*/
}
