/*
 * main.c
 */
#include "stdint.h"
#include "hw_types.h"
#include "stw_dataTypes.h"
#include "stw_types.h"
#include "interrupt.h"
#include "soc.h"
#include "stdio.h"
#include "interrupt.h"
#include "timer.h"
#define MAILBOX_BASE_ADDR		0x480c8000
#define RD_MEM_32(addr) 	  	 *(volatile unsigned int*)(addr)
#define WR_MEM_32(addr, data)    do {*(volatile unsigned int*)(addr) =(unsigned int)(data);}while(0)
/*
 *mailbox 9 used for M3
 *mailbox 10 for dsp
 *mailbox 11 for arm
 * */
#define MAILBOX_MESSAGE_M3   (MAILBOX_BASE_ADDR+0x40+0x4*9)
#define MAILBOX_FIFOSTATUS_M3    (MAILBOX_BASE_ADDR+0x80+0x4*9)
#define MAILBOX_MSGSTATUS_M3   (MAILBOX_BASE_ADDR+0xc0+0x4*9)
#define MAILBOX_IRQSTATUS_RAW_U_M3   (MAILBOX_BASE_ADDR+0x100+0x10*2)
#define MAILBOX_IRQSTATUS_CLR_U_M3   (MAILBOX_BASE_ADDR+0x104+0x10*2)
#define MAILBOX_IRQENABLE_SET_U_M3   (MAILBOX_BASE_ADDR+0x108+0x10*2)
#define MAILBOX_IRQENABLE_CLR_U_M3   (MAILBOX_BASE_ADDR+0x10c+0x10*2)

#define MAILBOX_MESSAGE_A8   (MAILBOX_BASE_ADDR+0x40+0x4*11)
#define MAILBOX_FIFOSTATUS_A8    (MAILBOX_BASE_ADDR+0x80+0x4*11)
#define MAILBOX_MSGSTATUS_A8   (MAILBOX_BASE_ADDR+0xc0+0x4*11)
#define MAILBOX_IRQSTATUS_RAW_U_A8   (MAILBOX_BASE_ADDR+0x100+0x10*0)
#define MAILBOX_IRQSTATUS_CLR_U_A8   (MAILBOX_BASE_ADDR+0x104+0x10*0)
#define MAILBOX_IRQENABLE_SET_U_A8   (MAILBOX_BASE_ADDR+0x108+0x10*0)
#define MAILBOX_IRQENABLE_CLR_U_A8   (MAILBOX_BASE_ADDR+0x10c+0x10*0)

#define MAILBOX_MESSAGE_DSP   (MAILBOX_BASE_ADDR+0x40+0x4*10)
#define MAILBOX_FIFOSTATUS_DSP    (MAILBOX_BASE_ADDR+0x80+0x4*10)
#define MAILBOX_MSGSTATUS_DSP   (MAILBOX_BASE_ADDR+0xc0+0x4*10)
#define MAILBOX_IRQSTATUS_RAW_U_DSP   (MAILBOX_BASE_ADDR+0x100+0x10*1)
#define MAILBOX_IRQSTATUS_CLR_U_DSP   (MAILBOX_BASE_ADDR+0x104+0x10*1)
#define MAILBOX_IRQENABLE_SET_U_DSP   (MAILBOX_BASE_ADDR+0x108+0x10*1)
#define MAILBOX_IRQENABLE_CLR_U_DSP   (MAILBOX_BASE_ADDR+0x10c+0x10*1)



/******************************************************************************
**                      INTERNAL FUNCTION PROTOTYPES
*******************************************************************************/
static void MailBoxIntcConfigure(void);
static void MailboxSetUp(void);
static void MailboxIsr();


int i = 0;
/******************************************************************************
**                          FUNCTION DEFINITIONS
*******************************************************************************/
int main(void)
{
	int j = 0;
	MailBoxIntcConfigure();

    MailboxSetUp();
    do{
    	for(j=0;j<10000;j++);
    //	WR_MEM_32(MAILBOX_MESSAGE_M3,i++);
    }while (1);
    return 0;
}

/*
** Do the necessary MB1INT2 configurations on to INTC.
*/
static void MailBoxIntcConfigure(void)
{
    /* Enable the interrupt */
    Intc_IntEnable(0);

    /* Initialize the interrupt control */
    Intc_Init();

    /* Registering TimerIsr */
    Intc_IntRegister(53, (IntrFuncPtr) MailboxIsr, NULL);

    /* Set the priority */
    Intc_IntPrioritySet(53, 1, 0);

    /* Enable the system interrupt */
    Intc_SystemEnable(53);
}

/*
** Setup the timer for one-shot and compare mode.
*/
static void MailboxSetUp(void)
{
	WR_MEM_32(MAILBOX_IRQENABLE_CLR_U_M3,RD_MEM_32(MAILBOX_IRQENABLE_CLR_U_M3) | (0x1<<18));
	WR_MEM_32(MAILBOX_IRQENABLE_SET_U_M3,RD_MEM_32(MAILBOX_IRQENABLE_SET_U_M3) | (0x1<<18));
}

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_dsp(int msg)
{
	WR_MEM_32(MAILBOX_IRQENABLE_SET_U_DSP,RD_MEM_32(MAILBOX_IRQENABLE_SET_U_DSP) | (0x1<<20));
	WR_MEM_32(MAILBOX_MESSAGE_DSP,msg);
}
/*mailbox10*/
static void MailboxIsr(void)
{
    unsigned int temp;

    if(RD_MEM_32(MAILBOX_IRQSTATUS_CLR_U_M3)&(0x1<<18))
    {
    	while(RD_MEM_32(MAILBOX_MSGSTATUS_M3))
    	{
    		temp = RD_MEM_32(MAILBOX_MESSAGE_M3);
    		printf("0x%x\n",temp);
    	}
    	WR_MEM_32(MAILBOX_IRQSTATUS_CLR_U_M3,(0x1<<18));
    }
    sendmsg_dsp(temp);	//forward this message to a8
}
