#include <io.h>
#include <system.h>
#include <stdio.h>

#include <sys/alt_irq.h> // the irq functions
#include <alt_types.h>
#include <keyboard_ctrl.h>
#include "DM9000A.h"

#define IOWR_LED_DATA(base, offset, data) \
  IOWR_16DIRECT(base, (offset) * 2, data) 
#define IORD_LED_DATA(base, offset) \
  IORD_16DIRECT(base, (offset) * 2)
#define IOWR_LED_SPEED(base, data) \
  IOWR_16DIRECT(base + 32, 0, data)
  
void printbuf(int *buf, int length);

KB_CODE_TYPE decode_mode;
//alt_u8 key = 0;
int key = 0;
int time_count = 0;

int audio_irq_count = 0;

int currentT;

extern int audio;

int keyBuf1[10] ={0,0,0,0,0,0,0,0,0,0};
int timeBuf1[10]={0,0,0,0,0,0,0,0,0,0};
int buf1_s=0, buf1_e=0;

int keyBuf2[10] ={0,0,0,0,0,0,0,0,0,0};
int timeBuf2[10]={0,0,0,0,0,0,0,0,0,0};
int buf2_s=0, buf2_e=0;

#define MAX_MSG_LENGTH 128

// Ethernet MAC address.  Choose the last three bytes yourself
unsigned char mac_address[6] = { 0x01, 0x60, 0x6E, 0x11, 0x02, 0x0F  };

unsigned int receive_buffer_length;
unsigned char receive_buffer[1600];

#define UDP_PACKET_PAYLOAD_OFFSET 42
#define UDP_PACKET_LENGTH_OFFSET 38

#define UDP_PACKET_PAYLOAD (transmit_buffer + UDP_PACKET_PAYLOAD_OFFSET)
#define UDP_RECEIVE_PAYLOAD (receive_buffer + UDP_PACKET_PAYLOAD_OFFSET)

unsigned char transmit_buffer[] = {
  // Ethernet MAC header
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Destination MAC address
  0x01, 0x60, 0x6E, 0x11, 0x02, 0x0F, // Source MAC address
  0x08, 0x00,                         // Packet Type: 0x800 = IP
                          
  // IP Header
  0x45,                // version (IPv4), header length = 20 bytes
  0x00,                // differentiated services field
  0x00,0x9C,           // total length: 20 bytes for IP header +
                       // 8 bytes for UDP header + 128 bytes for payload
  0x3d, 0x35,          // packet ID
  0x00,                // flags
  0x00,                // fragment offset
  0x80,                // time-to-live
  0x11,                // protocol: 11 = UDP
  0xa3,0x43,           // header checksum: incorrect
  0xc0,0xa8,0x01,0x01, // source IP address
  0xc0,0xa8,0x01,0xff, // destination IP address
                          
  // UDP Header
  0x67,0xd9, // source port port (26585: garbage)
  0x27,0x2b, // destination port (10027: garbage)
  0x00,0x88, // length (136: 8 for UDP header + 128 for data)
  0x00,0x00, // checksum: 0 = none
                          
  // UDP payload
  0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x73, 0x67,
  0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x73, 0x67,
  0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x73, 0x67,
  0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x73, 0x67,
  0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x73, 0x67,
  0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x73, 0x67,
  0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x73, 0x67,
  0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x73, 0x67,
  0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x73, 0x67,
  0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x73, 0x67,
  0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x73, 0x67,
  0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x73, 0x67,
  0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x73, 0x67,
  0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x73, 0x67,
  0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x73, 0x67,
  0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x73, 0x67
};  

static void ethernet_interrupt_handler() {
  unsigned int receive_status;
  
  receive_status = ReceivePacket(receive_buffer, &receive_buffer_length);

  if (receive_status == DMFE_SUCCESS) {
    printf("\nPacket received is 0x%.2X",UDP_RECEIVE_PAYLOAD[0]);
  } 
  

  /* Clear the DM9000A ISR: PRS, PTS, ROS, ROOS 4 bits, by RW/C1 */
  dm9000a_iow(ISR, 0x3F);
              
  /* Re-enable DM9000A interrupts */
  dm9000a_iow(IMR, INTR_set);
}

static void audio_irqhandler (void * context, alt_u32 id)
{
    //printf("\n Audio irq!\n");
    IOWR_16DIRECT(AUDIO_INST_BASE, 0, 0); // reset request
    audio_irq_count += 1;
    int i;
    for (i=1;i<=48;i++){
        IOWR_16DIRECT(AUDIO_INST_BASE, 2*i, audio[i]);
    }

}

static void timer_irqhandler (void * context, alt_u32 id)
{    
    IOWR_16DIRECT(IRTIMER_INST_BASE, 0, 0); // reset request
    time_count += 1;
    printf("\n Audio irq %d!\n",audio_irq_count);
}

static void key_irqhandler (void * context, alt_u32 id)
{  
    read_make_code (&decode_mode, &key);
  
    if(decode_mode==P1_RELEASE_CODE || decode_mode==P2_RELEASE_CODE)
        key=key+10;
        
    printf("Key code is %d\n",key);
               
    if(decode_mode==P1_PRESS_CODE || decode_mode==P1_RELEASE_CODE){
        currentT=time_count;

        keyBuf1[buf1_e]=key;
        timeBuf1[buf1_e]=currentT;
        buf1_e++; 
    }
    
    if(decode_mode==P2_PRESS_CODE || decode_mode==P2_RELEASE_CODE){
        currentT=time_count;

        keyBuf2[buf2_e]=key;
        timeBuf2[buf2_e]=currentT;
        buf2_e++; 
    }
    
    UDP_PACKET_PAYLOAD[0]=key >> 8;
    UDP_PACKET_PAYLOAD[1]=key & 0xff;
    TransmitPacket(transmit_buffer, UDP_PACKET_PAYLOAD_OFFSET+2);
      
   
        printf("\nkeyBuf1 is :");
        printbuf(keyBuf1,10);
        printf("\ntimeBuf1 is :");
        printbuf(timeBuf1,10);
        
        printf("\nkeyBuf2 is :");
        printbuf(keyBuf2,10);
        printf("\ntimeBuf2 is :");
        printbuf(timeBuf2,10);
        
        printf("\nHoldBuf1 is :");
        printbuf(P1_holdBuf,8);
        printf("\nHoldBuf2 is :");
        printbuf(P2_holdBuf,8);
}

void printbuf(int *buf, int length){
    int i;
    for(i=0;i<length;i++)
        printf("%d ",buf[i]);
}


int main()
{
  //int i;
  printf("Hello Michael\n");
  printf("audio is %d",audio[1]);
  // Initalize the DM9000 and the Ethernet interrupt handler
  DM9000_init(mac_address);
  alt_irq_register(DM9000A_IRQ, NULL, (void*)ethernet_interrupt_handler); 
  
  alt_irq_register( DE2_PS2_INST_IRQ, NULL,( void*)key_irqhandler ); // register the irq
  alt_irq_register( IRTIMER_INST_IRQ, NULL,( void*)timer_irqhandler );
  alt_irq_register(   AUDIO_INST_IRQ, NULL,( void*)audio_irqhandler );
  
  while(1){  
    //printf("Goodbye!\n");
  }
  /* Get received byte */

  printf("Goodbye!\n");
    
  return 0;
}
