/********************************************/
/*USB.h - Header file                  */
/*PIC32MX795F512L-80I/PF                    */
/********************************************/

#ifndef USB_H
#define	USB_H

#define DETACHED    0
#define DEFAULT     1
#define ADDRESS     2
#define CONFIGURED  3

#define SETUP 0x0d
#define IN 0x09
#define OUT 0x01

#define GET_DESCRIPTOR 0x06
#define GET_CONFIGURATION 0x08
#define SET_ADDRESS 0x05

uint32_t USB_STATE;
uint32_t enum_state;
uint32_t PPBit;
uint32_t address_valid;

uint32_t PID;

uint32_t bmRequestType;
uint32_t bRequest;
uint16_t wValue;

//DEBUG
uint8_t dump;

//uint32_t *pBDT = (uint32_t *)&device_dsc;

//Endpoint 0
uint8_t EP0_0_Buffer[40];
uint8_t EP0_1_Buffer[40];
uint8_t EP0_2_Buffer[40];
uint8_t EP0_3_Buffer[40];

//Endpoint 1
uint8_t EP1_0_Buffer[40] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t EP1_1_Buffer[40] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t EP1_2_Buffer[40] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t EP1_3_Buffer[40] = {0, 0, 0, 0, 0, 0, 0, 0};



uint32_t ResetCount = 0;
uint32_t TRNIFCount = 0;
uint32_t count = 0;

void USBInit(void);
void DebugPacketData(void);

//array
//uint32_t BDT[8] __attribute__ ((coherent, aligned (512)));

typedef union __attribute__ ((packed))__PIC32_BDT
{
    struct __attribute__ ((packed))  
    {
        uint8_t                 :2;     //used by module
        uint8_t    BSTALL       :1;     //buffer Stall Enable
        uint8_t    DTS          :1;     //data Toggle Synchronization Enable
        uint8_t    NINC         :1;     //DMA Address Increment Disable
        uint8_t    KEEP         :1;     //BD Keep Enable bit
        uint8_t    DATA0        :1;     //Data Toggle Packet bit
        uint8_t    UOWN         :1;     //USB Ownership
        uint8_t                 :8;     //reserved
        uint16_t   BYTE_CNT     :10;    //byte count
        uint8_t                 :6;     //reserved
    };
    
    struct __attribute__ ((packed))  
    {
        uint32_t    FULL_DWORD;
    };
}PIC32_BDT;

//union
volatile PIC32_BDT BDT[8] __attribute__ ((coherent, aligned (512)));  

uint32_t addr = (uint32_t)&BDT[0];

typedef struct __attribute__ ((packed)) _USB_DEVICE_DESCRIPTOR
{
    uint8_t bLength;               // Length of this descriptor.
    uint8_t bDescriptorType;       // DEVICE descriptor type (USB_DESCRIPTOR_DEVICE).
    uint16_t bcdUSB;                // USB Spec Release Number (BCD).
    uint8_t bDeviceClass;          // Class code (assigned by the USB-IF). 0xFF-Vendor specific.
    uint8_t bDeviceSubClass;       // Subclass code (assigned by the USB-IF).
    uint8_t bDeviceProtocol;       // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
    uint8_t bMaxPacketSize0;       // Maximum packet size for endpoint 0.
    uint16_t idVendor;              // Vendor ID (assigned by the USB-IF).
    uint16_t idProduct;             // Product ID (assigned by the manufacturer).
    uint16_t bcdDevice;             // Device release number (BCD).
    uint8_t iManufacturer;         // Index of String Descriptor describing the manufacturer.
    uint8_t iProduct;              // Index of String Descriptor describing the product.
    uint8_t iSerialNumber;         // Index of String Descriptor with the device's serial number.
    uint8_t bNumConfigurations;    // Number of possible configurations.
} USB_DEVICE_DESCRIPTOR;

const USB_DEVICE_DESCRIPTOR device_dsc[] =
{
    0x12,                   // Size of this descriptor in bytes
    0x01,                   // DEVICE descriptor type
    0x0200,                 // USB Spec Release Number in BCD format
    0x02,                   // Class Code
    0x00,                   // Subclass code
    0x00,                   // Protocol code
    0x40,                   // Max packet size for EP0
    0x04D8,                 // Vendor ID
    0x000A,                 // Product ID: MainBrain32
    0x0100,                 // Device release number in BCD format
    0x01,                   // Manufacturer string index
    0x02,                   // Product string index
    0x00,                   // Device serial number string index
    0x01                    // Number of possible configurations
};

/* Configuration 1 Descriptor */
const uint8_t configDescriptor[] =
{
    /* Configuration Descriptor */
    0x09,//sizeof(USB_CFG_DSC),    // Size of this descriptor in bytes
    0x02,                // CONFIGURATION descriptor type
    53,0,                   // Total length of data for this cfg (was 67)
    2,                      // Number of interfaces in this cfg
    1,                      // Index value of this configuration
    0,                      // Configuration string index
    0xc0,               // Attributes, see usb_device.h
    50,                     // Max power consumption (2X mA)
							
    /* Interface Descriptor */
    9,//sizeof(USB_INTF_DSC),   // Size of this descriptor in bytes
    0x04,               // INTERFACE descriptor type
    0,                      // Interface Number
    0,                      // Alternate Setting Number
    1,                      // Number of endpoints in this intf
    0x02,              // Class code
    0x02, // Subclass code
    0x01,                 // Protocol code
    0,                      // Interface string index

    /* CDC Class-Specific Descriptors */
    0x05,
    0x24,
    0x00,
    0x10,0x01,

    0x04,
    0x24,
    0x02,
    0x02,

    0x05,
    0x24,
    0x06,
    0x00,
    0x01,

    0x05,
    0x24,
    0x01,
    0x00,
    0x01,

    /* Endpoint Descriptor */
    //sizeof(USB_EP_DSC),DSC_EP,_EP02_IN,_INT,CDC_INT_EP_SIZE,0x02,
    0x07,/*sizeof(USB_EP_DSC)*/
    0x05,    //Endpoint Descriptor
    0x82,            //EndpointAddress
    0x03,                       //Attributes
    0x08,0x00,                  //size
    0x02,                       //Interval

    /* Interface Descriptor */
    9,//sizeof(USB_INTF_DSC),   // Size of this descriptor in bytes
    0x04,               // INTERFACE descriptor type
    1,                      // Interface Number
    0,                      // Alternate Setting Number
    2,                      // Number of endpoints in this intf
    0x0a,              // Class code
    0,                      // Subclass code
    0x00,            // Protocol code
    0,                      // Interface string index
    
//    /* Endpoint Descriptor */
//    //sizeof(USB_EP_DSC),DSC_EP,_EP03_OUT,_BULK,CDC_BULK_OUT_EP_SIZE,0x00,
//    0x07,/*sizeof(USB_EP_DSC)*/
//    0x05,    //Endpoint Descriptor
//    0x03,            //EndpointAddress
//    0x03,                       //Attributes
//    0x40,0x00,                  //size
//    0x00,                       //Interval
//
//    /* Endpoint Descriptor */
//    //sizeof(USB_EP_DSC),DSC_EP,_EP03_IN,_BULK,CDC_BULK_IN_EP_SIZE,0x00
//    0x07,/*sizeof(USB_EP_DSC)*/
//    0x05,    //Endpoint Descriptor
//    0x83,            //EndpointAddress
//    0x02,                       //Attributes
//    0x40,0x00,                  //size
//    0x00,                       //Interval
};

#endif /*USB_H*/