#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <c6x.h>
#include <math.h>
#include <log.h>
#include <std.h>
#include <swi.h>

#include <csl.h>
#include <csl_timer.h>
#include <csl_irq.h>

//#include "Debug\\SS_USERcfg.h"
#include "Debug/ceNM_PEcfg.h"
#include "c6711_hrrm.h"
#include "mk_lib\\mk_common.h"
#include "mk_lib\\mk_aio.h"
#include "mk_lib\\mk_dio.h"
#include "mk_lib\\mk_motion.h"
#include "mk_lib\\mk_flash.h"
#include "mk_lib\\mk_extdef.h"
#include "mk_lib\\mk_extgvar.h"
#include "Defines.h"
#include "Functions.h"
#include "ESCStack/function.h"
#include "ESCStack/ComiAppl.h"
#include "ESCStack/ecatappl.h"
#define _MAIN_SOURCE_C_
#include "GlobVar.h"

#define BUFSIZE 256
#define CM01A_ERR_BITS 0x7A

#define ECHO_TEST   0
#define _CN_SUPPORT_UDP_
#define _CN_SUPPORT_TCP_

extern void Delay_us(t_ui32 usec);

typedef void (*TfpEntryPoint) (void);
void Reboot(int nProgMode)
{
    TfpEntryPoint EntryFunct = NULL;
    if(nProgMode == 0){ // Bootloader program
        EntryFunct = (TfpEntryPoint)flsReadDword(0x90000400); // 실제 Memory Map 주소는 0x90001000 에 주의
    }else{ // User application
        EntryFunct = (TfpEntryPoint)flsReadDword(0x90004000); // 실제 Memory Map 주소는 0x90010000 에 주의
    }

    if(EntryFunct != (TfpEntryPoint)0xffffffff){
        EntryFunct();
    }
}

//-------------------------------------------------------------------------------------------------------
// LoopEssense(): 항상 호출되어야 하는 루틴들을 모아놓은 루프 함수이다. 이 함수는 일정 시간(약 10ms)
//  이상 지연을 해야 하는 경우에 지연 루프내에서 반드시 호출되어야 한다.
//-------------------------------------------------------------------------------------------------------
void LoopEssense(void)
{
    t_ui32 i;
}

/**
 * main.c
 */
int main(void)
{
    // CPU 초기화 루틴
    Init_6711(); // in c6711_hrrm.c => 인터럽트 초기화, PLL설정(175MHz), EMIF초기화,
    GnInitMcBSP();

    //mkcBootup(); // COMIZOA LIBRARY INITIALIZATION
    #ifndef OYS_20130823
        OpenSockets();
    #endif

    //cnetSetComSpeed(BAUD_20M);

    //Err_LED_On(0);
	return 0;
}

void MainTask(Arg id_arg)
{
    IRQ_globalEnable();
    dioBootup();
    mcBootup();
    aioBootup();
    initaioset();

    // EtherCAT Initialization
    MainInit();

    IRQ_enable(IRQ_EVT_EXTINT4);

    while(1)
    {
        MainLoop();
    }
}

void Init_6711(void)    // DSP Initialize Code
{
    CSL_init();

    CSR = 0x100;        // Disable all interrupts
    IER = 1;            // Disable all interrupts except NMI
    ICR = 0xffff;       // Clear all pending interrupts

    *(unsigned volatile int *)PLL_M = 0x000A;           // PLLM x7 설정 200MHz (Base 20MHz)
//    *(unsigned vola                 tile int *)PLL_DIV2 = 0x8001;            // PLL_DIV1 설정
    *(unsigned volatile int *)PLL_DIV3 = 0x8003;            // PLL_DIV2 설정
    *(unsigned volatile int *)PLL_CSR &= ~0x0008;       // PLL Reset Release
    *(unsigned volatile int *)PLL_CSR |= 0x0001;        // PLL Enable
    Delay_us(10);

#if 1
    *(unsigned volatile int *)EMIF_GCR = 0x3078;        // EMIF global control

    *(unsigned volatile int *)EMIF_CE0 = 0x00000033;    // EMIF CE0 control (32bit SDRAM 8M x16)
    *(unsigned volatile int *)EMIF_CE1 = CE1_32;        // EMIF CE1 control (8bit ROM) 16bit로 ^^^^^^^^
    *(unsigned volatile int *)EMIF_CE2 = CE2_32;        // EMIF CE2 control (I/O)
    *(unsigned volatile int *)EMIF_CE3 = CE3_32;        // EMIF CE3 control (I/O)

    *(unsigned volatile int *)EMIF_SDCTRL = 0x6348F000; // EMIF SDRAM control
    *(unsigned volatile int *)EMIF_SDRP = 0x0200030D;       // EMIF SDRM refresh period // SDTIM
    *(unsigned volatile int *)EMIF_SDEXT= 0x00058D29;       // EMIF SDRM extension
    Delay_us(10);
#endif
    /*****************************************************************************
     * Start state
     ****************************************************************************/
    *(unsigned volatile int *)GPEN = 0x00F4;        // Enable GPIO2  (bit2)(Flash Busy Input), GPIO7(DI2)
    *(unsigned volatile int *)GPDIR = 0x0004;       // OUT : GPIO2 (bit2)
    *(unsigned volatile int *)GPVAL = 0x0004;       // OUT : GPIO2 (bit2)

    *(unsigned volatile int *)IEXTPOL |= 0x0007;            // EINT4,5,6 Falling Edge
    IRQ_enable(IRQ_EVT_EXTINT6);    // EXT6(PCL6045) IER(interrupt register) use set.
    IER |= 0x0050;              // enable int  6(EINT6) for RTEX
}


void OpenSockets(void)
{

}

void SWI_Timer100usFunc(void)
{
   //mkcTimerCallback();
    static t_bool bToggle = 0;

    //bToggle = !bToggle;
//    SetLED(1);
//    Delay_us(40);
//    SetLED(0);
}

void SWI_Timer1msFunc(void)
{
   mkcTimerCallback();
}

t_i32 Count=0;
void SWI_Timer500msFunc(void)
{
    //bToggle = !bToggle;
    //SetLED(bToggle);
}

void HWI_PCL6045(void)
{
    mcISR();
}

void HWI_ECAT_0(void)
{
    ECAT_CheckTimer();
    PDI_Isr();
    Sync0_Isr();
}

void HWI_ECAT_1(void)
{
    ;
}
