#ifndef FX2_H
#define FX2_H

// ----------------------------------------------------------------------------
// Constants
// ----------------------------------------------------------------------------
#define TRUE    1
#define FALSE   0

#define true    1
#define false   0


typedef	unsigned char	bool;

typedef unsigned char   BYTE;
typedef unsigned short  WORD;
typedef unsigned long   DWORD;


#define DSCR_DEVICE         	1   // Descriptor type: Device
#define DSCR_CONFIG         	2   // Descriptor type: Configuration
#define DSCR_STRING         	3   // Descriptor type: String
#define DSCR_INTRFC         	4   // Descriptor type: Interface
#define DSCR_ENDPNT         	5   // Descriptor type: Endpoint
#define DSCR_DEVQUAL        	6   // Descriptor type: Device Qualifier
#define DSCR_OTHERSPEED     	7   // Descriptor type: Other Speed Configuration

#define bmBIT0      			0x01
#define bmBIT1      			0x02
#define bmBIT2      			0x04
#define bmBIT3      			0x08
#define bmBIT4      			0x10
#define bmBIT5      			0x20
#define bmBIT6      			0x40
#define bmBIT7      			0x80

#define bmBUSPWR    			bmBIT7
#define bmSELFPWR   			bmBIT6
#define bmRWU       			bmBIT5

#define bmEPOUT     			bmBIT7
#define bmEPIN      			0

#define EP_VALID				0x80
#define	EP_INVALID				0x00

#define EP_IN					0x40
#define EP_OUT					0x00

#define EP_INT					0x30
#define EP_BULK					0x20
#define EP_ISO					0x10

#define EP_1024					0x08
#define EP_512					0x00
#define EP_64					0x00

#define EP_3x					0x03
#define EP_2x					0x02
#define EP_4x					0x00

#define	IRQ_EP0IN				bmBIT0
#define	IRQ_EP0OUT				bmBIT1
#define	IRQ_EP1IN				bmBIT2
#define	IRQ_EP1OUT				bmBIT3
#define	IRQ_EP2					bmBIT4
#define	IRQ_EP4					bmBIT5
#define IRQ_EP6					bmBIT6
#define IRQ_EP8					bmBIT7

#define SUD_SIZE    		 	 8           // Setup data size


#define  VECT_INT0  			 0
#define  VECT_TMR0  			 1
#define  VECT_INT1  			 2
#define  VECT_TMR1  			 3
#define  VECT_COM0  			 4
#define  VECT_TMR2  			 5
#define  VECT_WKUP  			 6
#define  VECT_COM1  			 7
#define  VECT_USB   			 8
#define  VECT_I2C   			 9
#define  VECT_INT4  			10
#define  VECT_INT5  			11
#define  VECT_INT6  			12

// ----------------------------------------------------------------------------
// USB interrupt INT2IVEC values
// ----------------------------------------------------------------------------
#define	INT2_SUDAV				0x00
#define	INT2_SOF				0x04
#define	INT2_SUTOK				0x08
#define	INT2_SUSPEND			0x0C
#define INT2_RESET				0x10
#define INT2_HISPEED			0x14
#define	INT2_EP0ACK				0x18
#define	INT2_EP0IN				0x20
#define	INT2_EP0OUT				0x24
#define	INT2_EP1IN				0x28
#define	INT2_EP1OUT				0x2C
#define	INT2_EP2				0x30
#define	INT2_EP4				0x34
#define	INT2_EP6				0x38
#define	INT2_EP8				0x3C
#define	INT2_IBN				0x40
#define	INT2_EP0PING			0x48
#define	INT2_EP1PING			0x4C
#define	INT2_EP2PING			0x50
#define	INT2_EP4PING			0x54
#define	INT2_EP6PING			0x58
#define	INT2_EP8PING			0x5C
#define	INT2_ERRLIMIT			0x60
#define	INT2_EP2ISOERR			0x70
#define	INT2_EP4ISOERR			0x74
#define	INT2_EP6ISOERR			0x78
#define	INT2_EP8ISOERR			0x7C

// ----------------------------------------------------------------------------
// GPIF/FIFO interrupt INT4IVEC values
// ----------------------------------------------------------------------------
#define	INT4_EP2PF				0x80
#define	INT4_EP4PF				0x84
#define	INT4_EP6PF				0x88
#define	INT4_EP8PF				0x8C

#define	INT4_EP2EF				0x90
#define	INT4_EP4EF				0x94
#define	INT4_EP6EF				0x98
#define	INT4_EP8EF				0x9C

#define	INT4_EP2FF				0xA0
#define	INT4_EP4FF				0xA4
#define	INT4_EP6FF				0xA8
#define	INT4_EP8FF				0xAC

#define	INT4_GPIF_DONE			0xB0
#define	INT4_GPIF_WF			0xB4



// ----------------------------------------------------------------------------
// HID constants
// ----------------------------------------------------------------------------
#define SETUP_MASK              0x60    // Used to mask off request type
#define SETUP_REQ_STANDARD      0x00    // Standard request
#define SETUP_REQ_CLASS         0x20    // Class request
#define SETUP_REQ_VENDOR        0x40    // Vendor request
#define SETUP_REQ_RESERVED      0x60    // Reserved or illegal request

// ----------------------------------------------------------------------------
// Setup commands
// ----------------------------------------------------------------------------
#define SC_GET_STATUS           0x00
#define SC_CLEAR_FEATURE        0x01
#define SC_RESERVED             0x02
#define SC_SET_FEATURE          0x03
#define SC_SET_ADDRESS          0x05
#define SC_GET_DESCRIPTOR       0x06
#define SC_SET_DESCRIPTOR       0x07
#define SC_GET_CONFIGURATION    0x08
#define SC_SET_CONFIGURATION    0x09
#define SC_GET_INTERFACE        0x0a
#define SC_SET_INTERFACE        0x0b
#define SC_SYNC_FRAME           0x0c
#define SC_ANCHOR_LOAD          0xa0

#define GD_DEVICE               0x01
#define GD_CONFIGURATION        0x02
#define GD_STRING               0x03
#define GD_INTERFACE            0x04
#define GD_ENDPOINT             0x05
#define GD_DEVICE_QUALIFIER     0x06
#define GD_OTHER_SPEED_CONFIG   0x07
#define GD_INTERFACE_POWER      0x08
#define GD_HID                  0x21
#define GD_REPORT               0x22

#define GS_DEVICE               0x80    // Get Status: Device
#define GS_INTERFACE            0x81    // Get Status: Interface
#define GS_ENDPOINT             0x82    // Get Status: Endpoint

#define FT_DEVICE               0x00    // Feature: Device
#define FT_ENDPOINT             0x02    // Feature: Endpoint



// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//                              Data types
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// ----------------------------------------------------------------------------
// Descriptor header
// ----------------------------------------------------------------------------
typedef struct
{
    BYTE    length;
    BYTE    type;
} DSCR;

// ----------------------------------------------------------------------------
// Device descriptor [type=1]
// ----------------------------------------------------------------------------
typedef struct
{
    BYTE    length;             // descriptor length ( = sizeof(DEVICE_DSCR) )
    BYTE    type;               // descriptor type   ( Device = 1)

    BYTE    spec_ver_minor;     // specification version (BCD) minor
    BYTE    spec_ver_major;     // specification version (BCD) major

    BYTE    dev_class;          // device class
    BYTE    dev_subclass;       // device subclass
    BYTE    dev_protocol;       // device protocol

    BYTE    max_packet;         // maximum packet size

    WORD    id_vendor;          // vendor ID
    WORD    id_product;         // product ID
    WORD    id_version;         // product version ID

    BYTE    str_manufacturer;   // manufacturer string index
    BYTE    str_product;        // product string index
    BYTE    str_serial;         // serial number string index

    BYTE    configs;            // number of configurations
} DEVICE_DSCR;

// ----------------------------------------------------------------------------
// Device qualifier descriptor [type=6]
// ----------------------------------------------------------------------------
typedef struct
{
    BYTE    length;             // descriptor length ( = sizeof(DEVICEQUAL_DSCR) )
    BYTE    type;               // descriptor type   ( Device Qualifier = 6)

    BYTE    spec_ver_minor;     // specification version (BCD) minor
    BYTE    spec_ver_major;     // specification version (BCD) major

    BYTE    dev_class;          // device class
    BYTE    dev_subclass;       // device subclass
    BYTE    dev_protocol;       // device protocol

    BYTE    max_packet;         // maximum packet size

    BYTE    configs;            // number of configurations
    BYTE    reserved;
} DEVICEQUAL_DSCR;

// ----------------------------------------------------------------------------
// Configuration descriptor [type=2]
// ----------------------------------------------------------------------------
typedef struct
{
    BYTE    length;             // descriptor length ( = sizeof(CONFIG_DSCR) )
    BYTE    type;               // descriptor type   ( Configuration = 2)

    WORD    config_length;      // configuration + endpoints length
    BYTE    interfaces;         // number of interfaces
    BYTE    index;              // configuration number
    BYTE    str_config;         // configuration string index
    BYTE    attrib;             // attributes (buspwr,selfpwr,rwu)
    BYTE    power;              // power requirement (div 2 mA)
} CONFIG_DSCR;

// ----------------------------------------------------------------------------
// Interface descriptor [type=4]
// ----------------------------------------------------------------------------
typedef struct
{
    BYTE    length;             // descriptor length ( = sizeof(INTERFACE_DSCR) )
    BYTE    type;               // descriptor type   ( Interface = 4)

    BYTE    index;              // zero-based index of this interface
    BYTE    alt_setting;        // alternate setting
    BYTE    ep_count;           // number of endpoints

    BYTE    if_class;           // interface class
    BYTE    if_subclass;        // interface subclass
    BYTE    if_protocol;        // interface protocol

    BYTE    str_interface;      // interface string index
} INTERFACE_DSCR;

// ----------------------------------------------------------------------------
// Endpoint descriptor [type=5]
// ----------------------------------------------------------------------------
typedef struct
{
    BYTE    length;             // descriptor length ( = sizeof(ENDPOINT_DSCR) )
    BYTE    type;               // descriptor type   ( Endpoint = 5)

    BYTE    ep_address;         // endpoint address
    BYTE    ep_type;            // endpoint type

    BYTE    mp_low;             // maximum packet size (LOW)
    BYTE    mp_high;            // maximum packet size (HIGH)

    BYTE    interval;           // interrupt polling interval
} ENDPOINT_DSCR;

// ----------------------------------------------------------------------------
// String descriptor [type=3]
// ----------------------------------------------------------------------------
typedef struct
{
    BYTE    length;             // descriptor length ( = sizeof(STRING_DSCR) )
    BYTE    type;               // descriptor type   ( String = 3)
} STRING_DSCR;



// ----------------------------------------------------------------------------
// Setup Data Valid structure
// ----------------------------------------------------------------------------
typedef struct SUDAV
{
	BYTE	RequestType;
	BYTE	Request;
	
	union
	{
		WORD Word;
		
		struct
		{
			BYTE	Hi;
			BYTE	Lo;
		} Byte;
	} Value;
	
	union
	{
		WORD Word;
		
		struct
		{
			BYTE	Hi;
			BYTE	Lo;
		} Byte;
	} Index;
} SUDAV;

typedef SUDAV xdata* PSUDAV;

// ----------------------------------------------------------------------------
// Macros
// ----------------------------------------------------------------------------
#define min(a,b) 	(((a)<(b))?(a):(b))
#define max(a,b) 	(((a)>(b))?(a):(b))

#define MSB(word) 	(BYTE)(((WORD)(word) >> 8) & 0xff)
#define LSB(word) 	(BYTE)(((WORD)(word) >> 0) & 0xff)

#define	SWAP(word)	((BYTE*)&word)[0] ^= ((BYTE*)&word)[1];	\
					((BYTE*)&word)[1] ^= ((BYTE*)&word)[0];	\
					((BYTE*)&word)[0] ^= ((BYTE*)&word)[1]

#define I2C_IRQ_ENABLE()		(EI2C = 1)
#define I2C_IRQ_DISABLE()		(EI2C = 0)
#define I2C_IRQ_CLEAR()			(EXIF &= ~0x20)
#define I2C_IRQ_FIRE()			(EXIF |=  0x20)

#define USB_IRQ_ENABLE()        EUSB = 1
#define USB_IRQ_DISABLE()       EUSB = 0
#define USB_IRQ_CLEAR()         EXIF &= ~0x10

#define USB_IRQ_CLEAR_EP0IN()	EPIRQ = IRQ_EP0IN
#define USB_IRQ_CLEAR_EP0OUT()	EPIRQ = IRQ_EP0OUT
#define USB_IRQ_CLEAR_EP1IN()	EPIRQ = IRQ_EP1IN
#define USB_IRQ_CLEAR_EP1OUT()	EPIRQ = IRQ_EP1OUT
#define USB_IRQ_CLEAR_EP2()		EPIRQ = IRQ_EP2
#define USB_IRQ_CLEAR_EP4()		EPIRQ = IRQ_EP4
#define USB_IRQ_CLEAR_EP6()		EPIRQ = IRQ_EP6
#define USB_IRQ_CLEAR_EP8()		EPIRQ = IRQ_EP8

#define FX2_TOG_CLEAR( a)		TOGCTL = a & 0x1F; TOGCTL = (a | 0x20) & 0x3F

#define RSM_IRQ_ENABLE()        (EICON |=  0x20)
#define RSM_IRQ_DISABLE()       (EICON &= ~0x20)
#define RSM_IRQ_CLEAR()         (EICON &= ~0x10)

#define FX2_STALL_EP0()         EP0CS 		|= bmEPSTALL
#define FX2_STALL_EP1IN()		EP1INCS		|= bmEPSTALL
#define FX2_STALL_EP1OUT()		EP1OUTCS	|= bmEPSTALL
#define FX2_STALL_EP2()			EP2CS		|= bmEPSTALL
#define FX2_STALL_EP4()			EP4CS		|= bmEPSTALL
#define FX2_STALL_EP6()			EP6CS		|= bmEPSTALL
#define	FX2_STALL_EP8()			EP8CS		|= bmEPSTALL

extern const DEVICE_DSCR        code DscrDevice;
extern const DEVICEQUAL_DSCR    code DscrDeviceQual;
extern const CONFIG_DSCR        code DscrHsConfig;
extern const CONFIG_DSCR        code DscrFsConfig;
extern const STRING_DSCR        code DscrString;

extern void FX2_Disconnect(bool renum);
extern void FX2_Delay(WORD ms);

extern bool	FX2_Init();
extern void FX2_Suspend();
extern void FX2_Resume();



#endif
