//#include "xc.h"
#include "sys/kmem.h"
#include <sys/attribs.h>


uint32_t __attribute__ ((aligned (512))) BDT[1000];
uint32_t *addr;

void main(void)
{
    //USBDisableInterrupts();
    IEC1bits.USBIE = 0;
    
    //Clear USB error flags
    U1EIR = 0;

    //Clear USB interrupts
    U1IR = 0xffff;

    //Clear endpoint registers
    U1EP0 = 0;
    
    U1PWRCbits.USBPWR = 1;
    
    addr = &BDT[0];
    
    //convert to physical address and split
    U1BDTP3 = (((uint32_t)KVA_TO_PA(addr)) >> 24);
    U1BDTP2 = (((uint32_t)KVA_TO_PA(addr)) >> 16);
    U1BDTP1 = (((uint32_t)KVA_TO_PA(addr)) >> 8);
       
    //EP0 Even Out    
   BDT[0] = (uint32_t)0x00400004; //00 40 00 04
   BDT[1] = (uint32_t)0x00000040;

   //    //The Buffers
//    //Device Descriptor
    BDT[96] = (uint32_t)0x02000112;
    
    BDT[100] = (uint32_t)0x0800000000;        // Class Code
    BDT[98] = (uint32_t)0x000a04d8;        // Vendor ID
    
    BDT[99] = (uint32_t)0x02010100;        // Device release number in BCD format
    
    BDT[100] = 0x00010000;        // Device serial number string index
      
    //clear the reset interrupt flag
    U1IRbits.URSTIF = 1;
           
    //USBEnableInterrupts();
    IEC1bits.USBIE = 1;
    
    //Setup EP0
    U1EP0bits.EPRXEN = 1;
    U1EP0bits.EPTXEN = 1;
    U1EP0bits.EPHSHK = 1;
    U1EP0bits.EPCONDIS = 0;
   
    //enable OTG
    U1OTGCONbits.OTGEN = 1;
    
    //Module Enable
    U1CONbits.USBEN = 1;
    
    U1OTGCONbits.DPPULUP = 1;    
}

//USB
void __ISR(45, IPL7SRS) USB_Srvc(void)
{
    if(U1IRbits.URSTIF)
    {
        PORTCbits.RC4 = 1;
        //Set Mode = Full Speed:
        BDT[0] = (uint32_t)0x00400084;
        
        U1IRbits.URSTIF = 1;
    }
    
    if(U1IRbits.UERRIF)
    {
        PORTCbits.RC3 = 1;
        U1IRbits.UERRIF = 1;
    }
    
    if(U1IRbits.SOFIF)
    {
        PORTCbits.RC2 = 1;
        U1IRbits.SOFIF = 1;
    }
      
    if(U1IRbits.TRNIF)
    {
        PORTCbits.RC1 = 1;
        U1IRbits.SOFIF = 1;
    }
    
    if(U1IRbits.IDLEIF)
    {
        PORTDbits.RD2 = 1;
        U1IRbits.IDLEIF = 1;
    }
    
    if(U1IRbits.STALLIF)
    {
        PORTGbits.RG13 = 1;
        U1IRbits.STALLIF = 1;
    }
    
    IFS1bits.USBIF = 0;
}

