
#include "cpu1_board.h"

uint32_t testCnt = 0;
uint32_t jumpCnt = 0;

bool ipc1_ret = false;

IPC_MessageQueue_t messageQueue1;
IPC_Message_t TxMsg1, RxMsg1;

#define IPC1_CMD_CPU1_READ_MEM   	0x10010000

#define IPC1_CMD_CM_READ_ENET_MEM	0x10040000
#define IPC1_CMD_CPU1_DFU		 	0x10050000

#define ALLOCATE_TO_CM           0x1U
#define ESC_USE_INT_PHY_CLK      0x1U

#define BOOT_KEY                 0x5A000000UL
#define CM_BOOT_FREQ_125MHZ      0x7D00U
#define BOOTMODE_BOOT_TO_WAIT    0x0U
#define BOOTMODE_BOOT_TO_RAM     0x5U
#define BOOTMODE_BOOT_TO_FLASH   0x3U

void configureAndReleaseCMToWait(void);
void releaseCMToApplication(void);

/**
 * main.c
 */
uint32_t main(void)
{
    //
    // Initialize device clock and peripherals
    //
    Device_init();

#if 0
    //
    // Allocate Ethercat to CM
    //
    SysCtl_allocateSharedPeripheral(SYSCTL_PALLOCATE_ETHERCAT,
                                    ALLOCATE_TO_CM);

    //
    // Setup CM clocks and release from reset to Wait Boot Mode
    //
    configureAndReleaseCMToWait();

    //
    // Setup EtherCAT Clocks
    //
    // Aux = 500MHz and use /5 to get 100MHz for ECAT IP
    // (There is a built in /4 to get 25MHz for PHY when using
    //  internal clocking for PHY)
    //
    SysCtl_setECatClk(SYSCTL_ECATCLKOUT_DIV_5, SYSCTL_SOURCE_AUXPLL,
                      ESC_USE_INT_PHY_CLK);

    //
    // Set boot mode to RAM or Flash and release from Wait Boot Mode
    //
    releaseCMToApplication();

#else
    Device_bootCM(BOOTMODE_BOOT_TO_FLASH_SECTOR0);
#endif

    //
    // init interrupt and vectorTable, drivelib.
    //
    Interrupt_initModule();
    Interrupt_initVectorTable();

    //
    // SYSCFG
    //
    Board_init();

    SysCtl_setEnetClk(SYSCTL_ENETCLKOUT_DIV_2, SYSCTL_SOURCE_SYSPLL);

//    // Enet PHY Reset
//    GPIO_writePin(mPhyRest, 0);
//    DEVICE_DELAY_US(15000);
//    GPIO_writePin(mPhyRest, 1);

    GPIO_writePin(mGPIO_PIN_LED4, 1);

    IPC_sync(IPC_CPU1_L_CM_R, IPC_SYNC);

    GPIO_writePin(mGPIO_PIN_LED4, 0);

    IPC_clearFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG_ALL);
//    IPC_initMessageQueue(IPC_CPU1_L_CM_R, &messageQueue1, IPC_INT1, IPC_INT1);

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    EINT;
    ERTM;

//	return 0;
    while(1)
    {
    	GPIO_togglePin(mGPIO_PIN_LED4);
		DEVICE_DELAY_US(300000);
    	GPIO_togglePin(mGPIO_PIN_LED4);
		DEVICE_DELAY_US(300000);
    	GPIO_togglePin(mGPIO_PIN_LED4);
		DEVICE_DELAY_US(300000);
    	GPIO_togglePin(mGPIO_PIN_LED4);
		DEVICE_DELAY_US(300000);
    	GPIO_togglePin(mGPIO_PIN_LED4);
		DEVICE_DELAY_US(300000);
    	GPIO_togglePin(mGPIO_PIN_LED4);
		DEVICE_DELAY_US(300000);
    	GPIO_togglePin(mGPIO_PIN_LED4);
		DEVICE_DELAY_US(300000);
    	GPIO_togglePin(mGPIO_PIN_LED4);
		DEVICE_DELAY_US(300000);

		asm("    LB 0x080000");
    }
}

void
configureAndReleaseCMToWait(void)
{
    //
    // Configuring CM to run at 125MHz (AUX Raw = 500MHz)
    //
    SysCtl_setCMClk(SYSCTL_CMCLKOUT_DIV_4, SYSCTL_SOURCE_AUXPLL);

    //
    // Configure CM boot up configurations and boot mode as wait boot
    //
    IPC_setBootMode(IPC_CPU1_L_CM_R,
                    (BOOT_KEY | CM_BOOT_FREQ_125MHZ | BOOTMODE_BOOT_TO_WAIT));

    //
    // Set IPC flag (required for boot)
    //
    IPC_setFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG0);

    //
    // Release CM from reset
    //
    SysCtl_controlCMReset(SYSCTL_CORE_DEACTIVE);
}

void
releaseCMToApplication(void)
{
    //
    // Configure CM boot up configurations and boot mode
    //

#ifdef _FLASH
    IPC_setBootMode(IPC_CPU1_L_CM_R,
                    (BOOT_KEY | CM_BOOT_FREQ_125MHZ | BOOTMODE_BOOT_TO_FLASH));
//    IPC_setBootMode(IPC_CPU1_L_CM_R,
//                    (BOOT_KEY | CM_BOOT_FREQ_125MHZ | BOOTMODE_BOOT_TO_FLASH_SECTOR4));
#else
    IPC_setBootMode(IPC_CPU1_L_CM_R,
                    (BOOT_KEY | CM_BOOT_FREQ_125MHZ | BOOTMODE_BOOT_TO_RAM));
#endif

    //
    // Set IPC flag (required for leaving wait boot mode)
    //
    IPC_setFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG0);
}
