/*
 *  ======== main.c ========
 */

#include <xdc/std.h>

#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>

#include <ti/sysbios/BIOS.h>

#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/family/c64p/Hwi.h>
#include <ti/sysbios/family/c64p/EventCombiner.h>
#include "common.h"

#define SOC_INTC_0_REGS                     (0x01800000)
#define DSPINTC_EVTCLR(n)		(0x00040 + ((n)*4))
#define DSPINTC_EVTCLR_EC(n)			(0x1 << ((n) & 31))
#define HWREG(x)                                                              \
        (*((volatile unsigned int *)(x)))
#define SYS_INT_MAILBOX 		56
void IntEventClear(unsigned int sysINT)
{
    unsigned int dspintcREG;

    /* Get the address of the correct event register */
    dspintcREG = SOC_INTC_0_REGS + DSPINTC_EVTCLR((sysINT >> 5));

    /* Clear the corresponding bit within the event clear register */
    HWREG(dspintcREG) = DSPINTC_EVTCLR_EC(sysINT);
}

/*
 * mailbox 10 arm->dsp
 * mailbox 11 dsp->arm
 * */
/*
 * we use mailbox10 for the test
 * */
void sendmsg_a8(int msg)
{
	WR_MEM_32(MAILBOX_IRQENABLE_SET_U_A8,RD_MEM_32(MAILBOX_IRQENABLE_SET_U_A8) | (0x1<<22));
	WR_MEM_32(MAILBOX_MESSAGE_A8,msg);
}
void sendmsg_m3(int msg)
{
	WR_MEM_32(MAILBOX_IRQENABLE_SET_U_M3,RD_MEM_32(MAILBOX_IRQENABLE_SET_U_M3) | (0x1<<18));
	WR_MEM_32(MAILBOX_MESSAGE_M3,msg);
}

void MailBoxIsr(void) {
	unsigned int temp = 0;

	Hwi_disableInterrupt(5);

	//EventCombiner_disableEvent(56);
	IntEventClear(SYS_INT_MAILBOX);

	if (RD_MEM_32(MAILBOX_IRQSTATUS_CLR_U_DSP) & (0x1 << 20)) {
		while (RD_MEM_32(MAILBOX_MSGSTATUS_DSP)) {
			temp = RD_MEM_32(MAILBOX_MESSAGE_DSP);
		}
		WR_MEM_32(MAILBOX_IRQSTATUS_CLR_U_DSP, (0x1 << 20));
	}

	Hwi_enableInterrupt(5);

    sendmsg_a8(temp);
}

/*
 *  ======== taskFxn ========
 */
Void taskFxn(UArg a0, UArg a1)
{
    System_printf("enter taskFxn()\n");

    Task_sleep(10);

    System_printf("exit taskFxn()\n");

    System_flush(); /* force SysMin output to console */
}

/*
 *  ======== main ========
 */
Int main()
{ 
    Task_Handle task;
    Error_Block eb;

    System_printf("enter main()\n");

    Error_init(&eb);
    task = Task_create(taskFxn, NULL, &eb);
    if (task == NULL) {
        System_printf("Task_create() failed!\n");
        BIOS_exit(0);
    }

    BIOS_start();    /* does not return */
    return(0);
}
