/*
 * main.c
 *
 *  Created on: 2018. 5. 16.
 *      Author: BGKim
 */

/**
 * This project linked USBlib files.
 * So that is connection two libraries.
 * When user try examples codes, follow below link codes modify
 * - F28x_Project.h - (C:\ti\controlSUITE\device_support\F2837xD\v210\F2837xD_common\include): set #include "F2837xD_device.h"
 * And added "#define ccs_c2k" in usblib.h
 */

    /* DSP(bit)
     * char: 16(2byte)
     * short: 16(2byte)
     * int: 16(2byte)
     * long: 32(4byte)
     * longlong: X
     * float: 32(4byte)
     * double: 32(4byte)
     * long double: 64(8byte)
     *
     * If you check to sizeof function, you will check 1byte, because DSP(28x) processor minimum value is "word"
     * 1 word = 16bit
     * */

#include <stdio.h>
#include "../../../common/include/F28x_Project.h"
#include "../../../common/include/driverlib.h"
#include "../../../common/include/device.h"
#include "../../../common/include/F2837xD_Ipc_drivers.h"
#include "loopback.h"
#include "wizchip_conf.h"
#include "W5300_types.h"
#include "ftpd.h"
#include "ConfigData.h"
#include "ConfigMessage.h"
#include "flash_programming.h"

// FPU header file to access memcpy_fast_far().
//
//#include "../include/PhoenixonControls_FPU.h"

/*
 * If use SCI in CPU1, should clear "Exclude from Build" in PhoenixonControls_SCI.c
 * */
//#define SCI_CPU1_ENABLE

//
// PhoenixonControls_COMMUNICATION.c
//
volatile S_COMMUNICATION_GSRAM_CPU1 s_CPU_1_GSRAM[COMMUNICATION_CHANNEL];
volatile S_COMMUNICATION_GSRAM_CPU2 s_CPU_2_GSRAM[COMMUNICATION_CHANNEL];
volatile Uint16 ui_UpdateflagCPU1 = 0;
volatile Uint16 ui_UpdateflagCPU2 = 0;
volatile Uint16 ui_Updateflag = 0;

volatile Uint16 SCIATxBuff[DSP_SCIA_TX_MAX_BUFFER_LENGTH] 	= {0,};
volatile Uint16 SCIARxBuff[DSP_SCIA_RX_MAX_BUFFER_LENGTH]	= {0,};

#pragma DATA_SECTION(s_CPU_1_GSRAM,"SHARERAMGS15");
#pragma DATA_SECTION(s_CPU_2_GSRAM,"SHARERAMGS4");
#pragma DATA_SECTION(ui_UpdateflagCPU1,"SHARERAMGS15");
#pragma DATA_SECTION(ui_UpdateflagCPU2,"SHARERAMGS4");

#pragma DATA_SECTION(SCIARxBuff,"SHARERAMGS4");
#pragma DATA_SECTION(SCIATxBuff,"SHARERAMGS4");

#pragma CODE_SECTION(sprintf, ".TI.ramfunc");

extern volatile S_COMMUNICATION_DRAM *s_SDRAMp[];
extern volatile Uint16 ui_TimerFlag500ms;

extern uint8_t *ETHERNET_RxBuffer;
extern uint8_t *ETHERNET_TxBuffer;

Uint16 ReceivedChar = 0;

#ifdef _DEBUG
Uint16 DEBUG_ = 0;
#endif//_DEBUG END
uint8_t test_buf1[_MAX_SS] = { 0, };

char *msg;

volatile Uint16 SCIARxBuff_CPU1[];

extern wiz_NetInfo gWIZNETINFO;

// USB
extern volatile int g_con_flag;
extern volatile int g_check_flag;
extern char rtext[15];
uint8_t test_usb_buf[1024] = { 0, };

// Flash
uint16   Buffer2[0xFF + 1];
uint32   *Buffer322 = (uint32 *)Buffer2;
char USB_STACK_BUF[10]={0,};

volatile uint16 config_flash_set_flag = 0;
volatile uint16 config_set_flag = 0;

void main(void)
{
    uint8_t i = 0;
    //
    // Initialize device clock and peripherals
    //
    Device_init();
    //InitFlash();
    //SeizeFlashPump();
    DSP_EmifInit();

    //USB_GPIOEnable();
    //
    // GPIO35 is the LED pin.
    //
    GPIO_setPinConfig(GPIO_35_GPIO35);
	GPIO_setDirectionMode(35, GPIO_DIR_MODE_OUT);

    //
    // GPIO9 is the SCI Rx pin.
    //
    GPIO_setMasterCore(9, GPIO_CORE_CPU2);
    GPIO_setPinConfig(GPIO_9_SCIRXDA);
    GPIO_setDirectionMode(9, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(9, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(9, GPIO_QUAL_ASYNC);

    //
    // GPIO8 is the SCI Tx pin.
    //
    GPIO_setMasterCore(8, GPIO_CORE_CPU2);
    GPIO_setPinConfig(GPIO_8_SCITXDA);
    GPIO_setDirectionMode(8, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(8, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(8, GPIO_QUAL_ASYNC);
#ifdef SCI_CPU1_ENABLE
    DSP_SCIA_Init();

    msg = "hello\r\n";
    DSP_SCIA_Write(msg, 7);
#endif

    //
    // GPIO14 is the W5300 /Reset pin.
    //
    GPIO_setPinConfig(GPIO_14_GPIO14);
    GPIO_setDirectionMode(14, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(14, GPIO_PIN_TYPE_STD);

    // GPIO62 is the USB operation time check pin
    GPIO_setPinConfig(GPIO_62_GPIO62);
    GPIO_setDirectionMode(62, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(62, GPIO_PIN_TYPE_STD);
    GpioDataRegs.GPBCLEAR.bit.GPIO62 = 1;
#ifdef SCI_CPU1_ENABLE
    SysCtl_selectCPUForPeripheral(SYSCTL_CPUSEL5_SCI, 1, SYSCTL_CPUSEL_CPU1);
#else
    SysCtl_selectCPUForPeripheral(SYSCTL_CPUSEL5_SCI, 1, SYSCTL_CPUSEL_CPU2);
#endif
    DSP_TimerInit();

    ETHERNET_Init();
    //COMMUNICATION_INIT();

    //ftpd_init(gWIZNETINFO.ip);

#ifdef _DEBUG
#endif
    DINT;
    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();
    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    IER = 0x0000;
    IFR = 0x0000;
    Interrupt_initVectorTable();

    //
    // ISRs
    //
    Interrupt_register(INT_TIMER0, &DSP_Timer0_ISR);
    Interrupt_register(INT_TIMER1, &DSP_Timer1_ISR);
    Interrupt_register(INT_TIMER2, &DSP_Timer2_ISR);
#ifdef SCI_CPU1_ENABLE
    Interrupt_register(INT_SCIA_RX, &DSP_SCIA_RX_ISR);
    Interrupt_register(INT_SCIA_TX, &DSP_SCIA_TX_ISR);
#endif
    //USB_IntRegister();
    //
    // To ensure precise timing, use write-only instructions to write to the
    // entire register. Therefore, if any of the configuration bits are changed
    // in configCPUTimer and initCPUTimers, the below settings must also
    // be updated.
    //
    CPUTimer_enableInterrupt(CPUTIMER0_BASE);
    CPUTimer_enableInterrupt(CPUTIMER1_BASE);
    CPUTimer_enableInterrupt(CPUTIMER2_BASE);

    //
    // Enables CPU int1, int13, and int14 which are connected to CPU-Timer 0,
    // CPU-Timer 1, and CPU-Timer 2 respectively.
    // Enable TINT0 in the PIE: Group 1 interrupt 7
    //
    Interrupt_enable(INT_TIMER0);
    Interrupt_enable(INT_TIMER1);
    Interrupt_enable(INT_TIMER2);
#ifdef SCI_CPU1_ENABLE
    Interrupt_enable(INT_SCIA_RX);
    Interrupt_enable(INT_SCIA_TX);
#endif
    //USB_IntMasterEnable();
//    EINT; // Enable Global interrupt INTM
//    ERTM; // Enable Global realtime interrupt DBGM
//    usb_host_msc();

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    while(SDRAM_Init());

#ifdef _STANDALONE
    IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH);
#endif
    EINT; // Enable Global interrupt INTM
    ERTM; // Enable Global realtime interrupt DBGM
    //
    // Starts CPU-Timer 0, CPU-Timer 1, and CPU-Timer 2.
    //
    CPUTimer_startTimer(CPUTIMER0_BASE);
    CPUTimer_startTimer(CPUTIMER1_BASE);
    CPUTimer_startTimer(CPUTIMER2_BASE);

    //usb_host_msc(); // USB HOST MODE SETUP
    //Flash_erase();
#if 1
    while(1) {
#ifdef SCI_CPU1_ENABLE
        if(SCIARxBuff_CPU1[0] == 0x0061) // a
        {
            Flash_write(); // Flash
        }
        else if(SCIARxBuff_CPU1[0] == 0x0062) // b
        {
            Flash_read(Buffer322); // Flash
        }
        else if(SCIARxBuff_CPU1[0] == 0x0063) // c
        {
            Flash_erase(); // Flash
        }
        else if(SCIARxBuff_CPU1[0] == 0x0064) // d
        {
            SCIARxBuff_CPU1[0] = 0x0065; // Flash
            DSP_SCIA_Write(Buffer322, 0xFF); // Flash serial write
        }
#endif
        do_udp_config(4); // config socket 4
        if(config_flash_set_flag == 1) // a
        {
            config_flash_set_flag = 0;
            Flash_write(); // Flash
        }
        else if(config_flash_set_flag == 2) // c
        {
            config_flash_set_flag = 0;
            Flash_erase(); // Flash

        }
//        ftpd_run(test_buf1); // socket 2,3
//        loopback_udps(0, test_buf1, 1000);
//        loopback_tcps(7, test_buf1, 1000);
//        loopback_tcpc(4, test_buf5, destip1, 5000);
    }
#endif

    //
    // Loop Forever
    //
    i = 0;
    for(;;)
    {
        ReadLine2(); // USB operation loop
		if(ui_UpdateflagCPU1 != ui_UpdateflagCPU2)
		{
			COMMUNICATION_Read(s_SDRAMp, s_CPU_1_GSRAM, s_CPU_2_GSRAM);
			COMMUNICATION_Write(s_SDRAMp, s_CPU_1_GSRAM, s_CPU_2_GSRAM);

//			// Store data USB stack
//			sprintf(USB_STACK_BUF,"0:/%d.bin",i);
//		    //f_mount(0, &g_sFatFs1); // Mount check
//			GpioDataRegs.GPBSET.bit.GPIO62 = 1;
//			f_open(&g_sFileObject1, USB_STACK_BUF, FA_CREATE_ALWAYS | FA_WRITE); // create Example.txt file
//		    f_write(&g_sFileObject1, &s_CPU_2_GSRAM, sizeof(s_CPU_2_GSRAM), (void *) &byteswrite); // Write message
//		    f_close(&g_sFileObject1);
//		    GpioDataRegs.GPBCLEAR.bit.GPIO62 = 1;
//		    i++;
//		    if(i > 9) i=0;

//			ETHERNET_TCPs(0, COMMUNICATION_ETHERNET_PORT, 0, ETHERNET_RxBuffer, ETHERNET_TxBuffer, s_SDRAMp, s_CPU_1_GSRAM, s_CPU_2_GSRAM);
			ui_Updateflag = SET;
			ui_UpdateflagCPU1 = ui_UpdateflagCPU2;
		}
		ETHERNET_TCPs(0, COMMUNICATION_ETHERNET_PORT, 0, ETHERNET_RxBuffer, ETHERNET_TxBuffer, s_SDRAMp, s_CPU_1_GSRAM, s_CPU_2_GSRAM);


#ifdef _DEBUG
    	PHOENIXON_CONTROLS_Funtion();
#endif//_DEBUG END
    }
}

void PHOENIXON_CONTROLS_Funtion(void)
{

}

//
// End of file
//

