#include "CAN.h"
#include "terasic_includes.h"
#include "altera_avalon_uart_regs.h"
//#include "SEG7.h"

volatile int leddata0;
volatile int leddata1;

/////////////////////////sub routine///////////////////////////////////
void Can0_ISR(void * context,alt_u32 id)
{
    int temp0;
    //read the rx reg
    temp0=IORD_ALTERA_AVALON_UART_RXDATA(CAN_0_BASE);
    leddata0=temp0;
    //clear the rx reg
    IOWR_ALTERA_AVALON_UART_RXDATA(CAN_0_BASE, 0x0);
    //clear the irq flag
    IOWR_ALTERA_AVALON_UART_STATUS(CAN_0_BASE, 0x0);  
    //rx irq disable
    alt_irq_disable(CAN_0_IRQ);
        
}

//Can0 ISR initial
void Can0_init()
{
    //register the irq of can 0
    alt_irq_register(CAN_0_IRQ,0,Can0_ISR);
    //rx irq enable
    IOWR_ALTERA_AVALON_UART_CONTROL(CAN_0_BASE, 0x80);
    //clear the irq flag
    IOWR_ALTERA_AVALON_UART_STATUS(CAN_0_BASE, 0x0); 
    //enable the irq
    alt_irq_enable(CAN_0_IRQ);
    
    //IOWR_ALTERA_AVALON_UART_TXDATA(CAN_1_BASE,0);

}
//Can0 send 1 byte data
void Can0_send(unsigned char data)
{
    alt_u16 status;
    //read the state reg
    status=IORD_ALTERA_AVALON_UART_STATUS(CAN_0_BASE);
    while(!(status&0x0040)) //wait until finish tx
        status=IORD_ALTERA_AVALON_UART_STATUS(CAN_0_BASE);
    //set the tx reg
    IOWR_ALTERA_AVALON_UART_TXDATA(CAN_0_BASE,data);
}

//Can1 send 1 byte data
void Can1_send(unsigned char data)
{
    alt_u16 status;
    //read the state reg
    status=IORD_ALTERA_AVALON_UART_STATUS(CAN_1_BASE);
    while(!(status&0x0040)) //wait until finish tx
        status=IORD_ALTERA_AVALON_UART_STATUS(CAN_1_BASE);
    //set the tx reg
    IOWR_ALTERA_AVALON_UART_TXDATA(CAN_1_BASE,data);
}

//Can0 rx
int Can0_receive(void)
{
    alt_u16 status;
    int temp;
    //read the state reg
    status=IORD_ALTERA_AVALON_UART_STATUS(CAN_0_BASE);
    while(!(status&0x0080))//wait until rx finished
        status=IORD_ALTERA_AVALON_UART_STATUS(CAN_0_BASE);
    //read the rx reg
    temp=IORD_ALTERA_AVALON_UART_RXDATA(CAN_0_BASE);
    return temp;
}

//Can1 rx
int Can1_receive(void)
{
    alt_u16 status;
    int temp;
    //read the state reg
    status=IORD_ALTERA_AVALON_UART_STATUS(CAN_1_BASE);
    while(!(status&0x0080))//wait until rx finished
        status=IORD_ALTERA_AVALON_UART_STATUS(CAN_1_BASE);        
    //read the rx reg
    temp=IORD_ALTERA_AVALON_UART_RXDATA(CAN_1_BASE);
    return temp;
}

//Can1 rx ISR
void Can1_ISR(void * context,alt_u32 id)
{
    int temp1;
    //read the rx reg
    temp1=IORD_ALTERA_AVALON_UART_RXDATA(CAN_1_BASE);
    leddata1=temp1;
    //clear the rx reg
    IOWR_ALTERA_AVALON_UART_RXDATA(CAN_1_BASE, 0x0);
    
    //clear the irq flag
    IOWR_ALTERA_AVALON_UART_STATUS(CAN_1_BASE, 0x0);
    
    //rx irq disable
    alt_irq_disable(CAN_1_IRQ);
    //Can0_init();
}

//Can1 ISR initial
void Can1_init()
{

    //rx irq enable
    IOWR_ALTERA_AVALON_UART_CONTROL(CAN_1_BASE, 0x80);
    //clear the irq flag
    IOWR_ALTERA_AVALON_UART_STATUS(CAN_1_BASE, 0x0);
    //register the irq of can 1
    alt_irq_register(CAN_1_IRQ,0,Can1_ISR);
    //enable the irq
    alt_irq_enable(CAN_1_IRQ);
    
    //IOWR_ALTERA_AVALON_UART_TXDATA(CAN_0_BASE,0);
}

int can_loopback( void )
{
    int senddata ; //the sending data 

    const alt_u32 time_out0 = alt_ticks_per_second()*1;
    const alt_u32 time_out1 = alt_ticks_per_second()*2;
    

    alt_u32 time_start;
    time_start = alt_nticks();
        
    //Can1_init(); isr open
    Can1_init();
    leddata0 = 0;
    leddata1 = 0;
    //read the switch value ,so you can set the senddata via the sw[7:0]
    senddata = (IORD_ALTERA_AVALON_PIO_DATA(SW_BASE)) & 0x0ff;
    
    if(senddata==0)
    {
        senddata = 0x5a;
    }

    while( (alt_nticks() - time_start) < time_out0 ){
        //can 0 tx
        Can0_send(senddata);
    }//end while(1)
   
   
    usleep(800*1000);
    Can0_init();
    
    while( (alt_nticks() - time_start) < time_out1 ){
        //can 1 tx
        Can1_send(leddata1);
    }//end while(1)    
    
    if((leddata1 == leddata0) &&(senddata == leddata0) )
    {
       printf("--------tx data:%x---------\n",senddata);
       printf("--------loopback data:%x---------\n",leddata0);
//       SEG7_Hex(senddata,0xff);
//       SEG7_SET(2, 0x40);
//       SEG7_SET(3, 0x6D);
//       SEG7_SET(4, 0x0);
//       SEG7_SET(5, 0x0);
//       SEG7_SET(6, 0x0);
//       SEG7_SET(7, 0x0);
//       
//       return 1; 
//    }
//    else
//    {
//       //FAIL 
//       SEG7_SET(0, 0x38);
//       SEG7_SET(1, 6);
//       SEG7_SET(2, 119);
//       SEG7_SET(3, 113);
//       SEG7_SET(4, 0x0);
//       SEG7_SET(5, 0x0);
//       SEG7_SET(6, 0x0);
//       SEG7_SET(7, 0x0);
//       
//       return 0;
    }
//    
    
}//end main

