USB driver

/*******************************************************************************
 *
 *  File Name   :  USBProcessing.C
 *
 *  Version     :  6
 *
 *  Description :  The USB Processing file
 *
 *  Author      :  mrh
 *
 ******************************************************************************/
 
#ifndef USB_PROCESSING_H
#define USB_PROCESSING_H
 
 
 
/*******************************************************************************
 *                             # I n c l u d e s                               *
 ******************************************************************************/
 
#include "USB.h"
 
 
 
/*******************************************************************************
 *                      E x t e r n a l   # D e f i n e s                      *
 ******************************************************************************/
 
#define   BIT31       0x80000000
#define   BIT30       0x40000000
#define   BIT29       0x20000000
#define   BIT28       0x10000000
#define   BIT27       0x8000000
#define   BIT26       0x4000000
#define   BIT25       0x2000000
#define   BIT24       0x1000000
#define   BIT23       0x800000
#define   BIT22       0x400000
#define   BIT21       0x200000
#define   BIT20       0x100000
#define   BIT19       0x80000
#define   BIT18       0x40000
#define   BIT17       0x20000
#define   BIT16       0x10000
#define   BIT15       0x8000
#define   BIT14       0x4000
#define   BIT13       0x2000
#define   BIT12       0x1000
#define   BIT11       0x800
#define   BIT10       0x400
#define   BIT9        0x200
#define   BIT8        0x100
#define   BIT7        0x80
#define   BIT6        0x40
#define   BIT5        0x20
#define   BIT4        0x10
#define   BIT3        0x8
#define   BIT2        0x4
#define   BIT1        0x2
#define   BIT0        0x1
 
 
/* Define the String Descriptors */
#define USB_RDPS_STR_MANUFACTURER   "Maufacturer"
#define USB_RDPS_STR_PRODUCT        "Product"
#define USB_RDPS_STR_SERIAL_NO      "1""2""3""4"
#define USB_RDPS_STR_CONFIG         "Standard Confi"\
                                    "guration"
#define USB_RDPS_STR_INTERFACE      "Interface"
 
typedef enum
{
  /* MAX3420E Endpoint 0 FIFO */
  USB_3420REG_EP0FIFO,
 
  /* MAX3420E Endpoint 1-OUT FIFO (double-buffered 64 byte FIFO)  */
  USB_3420REG_EP1OUTFIFO,
 
  /* MAX3420E Endpoint 2-IN FIFO (double-buffered 64 byte FIFOS) */
  USB_3420REG_EP2INFIFO,
 
  /* MAX3420E Endpoint 3-IN FIFO (double-buffered 64 byte FIFOS) */
  USB_3420REG_EP3INFIFO,
 
  /* MAX3420E Setup Data FIFO */
  USB_3420REG_SUDFIFO,
 
  /* MAX3420E Endpoint 0 Byte Count */
  USB_3420REG_EP0BC,
 
  /* MAX3420E Endpoint 1-0UT Byte Count */
  USB_3420REG_EP1OUTBC,
 
  /* MAX3420E Endpoint 2-IN Byte Count Register */
  USB_3420REG_EP2INBC,
 
  /* MAX3420E Endpoint 3-IN Byte Count Register */
  USB_3420REG_EP3INBC,
 
  /* MAX3420E End-Point STALLS Register */
  USB_3420REG_EPSTALLS,
 
  /* MAX3420E Control Toggles Register */
  USB_3420REG_CLRTOGS,
 
  /* MAX3420E End-Point Interrupt Request Register */
  USB_3420REG_EPIRQ,
 
  /* MAX3420E End-Point Interrupt Enable Register */
  USB_3420REG_EPIEN,
 
  /* MAX3420E USB Interrupt Request Register */
  USB_3420REG_USBIRQ,
 
  /* MAX3420E USB Interrupt Enable Register */
  USB_3420REG_USBIEN,
 
  /* MAX3420E USB Control Register */
  USB_3420REG_USBCTL,
 
  /* MAX3420E CPU Control Register */
  USB_3420REG_CPUCTL,
 
  /* MAX3420E Pin Control Register */
  USB_3420REG_PINCTL,
 
  /* MAX3420E Revision Register */
  USB_3420REG_REVISION,
 
  /* MAX3420E Functional Address Register (assigned by the host controller) */
  USB_3420REG_FNADDR,
 
  /* MAX3420E General Purpose Input/Output Lines Register */
  USB_3420REG_IOPINS
 
} USB_3420REG_IDX_TYPE;
 
 
 
/*******************************************************************************
 *             E x t e r n a l   T y p e   D e c l a r a t i o n s             *
 ******************************************************************************/
 
typedef  unsigned char                  UINT8;
typedef  unsigned short                 UINT16;
typedef  unsigned long                  UINT32;
 
typedef enum
{
    FALSE = 0,
    TRUE  = 1
} BOOL;
 
 
/* ----------------------------------------------------------------------- */
/*             D e f i n i t i o n   o f   t h e  M A X 3 4 2 0            */
/*             C o n f i g u r a t i o n   D e s c r i p t o r             */
/* ----------------------------------------------------------------------- */
typedef struct
{
  USB_CONFIGURATION_DESCRIPTOR_TYPE  ConfigDescriptor;
  USB_INTERFACE_DESCRIPTOR_TYPE      InterfaceDescriptor;
  USB_ENDPOINT_DESCRIPTOR_TYPE       EndpointDescriptorEP1Out;
  USB_ENDPOINT_DESCRIPTOR_TYPE       EndpointDescriptorEP2In;
 
} USB_CONFIG_DATA_TYPE;
 
 
/* ----------------------------------------------------------------------- */
/*     D e f i n i t i o n   o f   t h e  v a r i o u s   S T R I N G      */
/*      D e s c r i p t o r s   a s   r e q u e s t e d   b y   t h e      */
/*               G E T _ D E S C R I P T O R   C o m m a n d               */
/* ----------------------------------------------------------------------- */
typedef struct
{
  UINT8              Length,
                     DescriptorType;
  UINT16             LANGID0;
 
} USB_LANGID_DESCRIPTOR_TYPE;
 
typedef struct
{
  UINT8              Length,
                     DescriptorType;
  UINT8              String[sizeof(USB_RDPS_STR_MANUFACTURER)];
 
} USB_MANUFACTURER_DESCRIPTOR_TYPE;
 
typedef struct
{
  UINT8              Length,
                     DescriptorType;
  UINT8              String[sizeof(USB_RDPS_STR_PRODUCT)];
 
} USB_PRODUCT_ID_DESCRIPTOR_TYPE;
 
typedef struct
{
  UINT8              Length,
                     DescriptorType;
  UINT8              String[sizeof(USB_RDPS_STR_SERIAL_NO)];
 
} USB_SERIAL_NO_DESCRIPTOR_TYPE;
 
typedef struct
{
  UINT8              Length,
                     DescriptorType;
  UINT8              String[sizeof(USB_RDPS_STR_CONFIG)];
 
} USB_CONFIG_ID_DESCRIPTOR_TYPE;
 
 
typedef struct
{
  UINT8              Length,
                     DescriptorType;
  UINT8              String[sizeof(USB_RDPS_STR_INTERFACE)];
 
}USB_INTERFACE_ID_DESCRIPTOR_TYPE;
 
/* ----------------------------------------------------------------------- */
/* Define MAX3420 Register Initialization Table which ecapsulates the      */
/* information needed to initialize a MAX3420 register.                    */
/* ----------------------------------------------------------------------- */
typedef struct
{
  UINT8 RegIdx,
        InitData;
} USB_MAX_REG_INIT_TYPE;
 
/*******************************************************************************
 *             E x t e r n a l   D a t a   D e c l a r a t i o n s             *
 ******************************************************************************/
 
extern USB_MAX_REG_INIT_TYPE USB_3420RegInitTable[];
 
 
 
/*******************************************************************************
 *           E x t e r n a l   F u n c t i o n   P r o t o t y p e s           *
 ******************************************************************************/
 
void   USB_IsrWrapperHandler( void );
void   USB_InterruptHandler( void );
UINT8  USB_ReadMAX3420Reg( USB_3420REG_IDX_TYPE reg, UINT8 ackStatFlag );
void   USB_WriteMAX3420Reg( USB_3420REG_IDX_TYPE reg,
                            UINT8                dataToWrite,
                            UINT8                ackStatFlag );
UINT16 USB_ReadData( UINT8* buff, UINT16 length );
UINT16 USB_WriteData( UINT8* buff, UINT16 length );
 
#endif





/*******************************************************************************
 *
 *  File Name   :  USBProcessing.C
 *
 *  Version     :  6
 *
 *  Description :  The USB Processing file
 *
 *  Author      :  mrh
 *
 ******************************************************************************/
 
/******************************************************************************
 *                             # I n c l u d e s                              *
 ******************************************************************************/
 
#include "USBProcessing.h"
 
 
 
/******************************************************************************
 *                     I n t e r n a l   # D e f i n e s                      *
 ******************************************************************************/
 
/* Define the USB Interrupt to be Level Active */
#define USB_MAX3420_INT_LVL_ACTIVE     TRUE
 
/* Define the USB Register Data Direction states */
#define USB_MAX3420_DD_WRITE           1
#define USB_MAX3420_DD_READ            0
 
/* Define the MAX3430 End-Point Buffer Sizes */
#define USB_MAX3420_EP0_SIZE           64
#define USB_MAX3420_EP1_SIZE           64
#define USB_MAX3420_EP2_SIZE           64
#define USB_MAX3420_EP3_SIZE           64
 
/* Define the MAX3420 GPX Output States */
#define USB_MAX3420_GPX_OPERATE        0
#define USB_MAX3420_GPX_VBDETECT       1
#define USB_MAX3420_GPX_BUSACT         2
#define USB_MAX3420_GPX_SOF            3
 
/* Define the USB Vendor ID, Product ID and Device ID */
#define USB_VENDOR_ID                  0xFFE0
#define USB_PRODUCT_ID                 0x0001
#define USB_DEVICE_ID                  0x0000
 
/* Define the USB Spec the RDPS is compliant to */
#define USB_COMPLIANT_2PT0             0x0200
 
/* Define the attribute of the Configuration Data Descriptor */
#define USB_CFG_ATTRIBUTES  (USB_CFG_ATTIB_SELF_PWR | USB_CFG_ATTIB_PWR_BY_BUS)
 
/* ----------------------------------------------------------------------- */
/* Define the USB Class, Sub-Class and Protocol types                      */
/* ----------------------------------------------------------------------- */
 
/* Define the Device Class to use Class Information In the Interface
   Descriptors and Class to be defined in the Interface Descriptor which
   indentifes the Class to be Vendor Specific                              */
#define USB_DEVICE_CLASS_RDPS          0x00
#define USB_DEVICE_CLASS_RDPS_IF       0xFF
 
/* Define the Device Sub-Class to use Class Information In the Interface
   Descriptors and Sub-Class to be defined in the Interface Descriptor
   which indentifes the Sub-Class to be Vendor Specific                    */
#define USB_DEVICE_SUB_CLASS_RDPS      0x00
#define USB_DEVICE_SUB_CLASS_RDPS_IF   0xFF
 
/* Define the Device Protocol to use Class Information In the Interface
   Descriptors and Protocol to be defined in the Interface Descriptor which
   indentifes the Protcol to be Vendor Specific                            */
#define USB_DEVICE_PROTOCOL_RDPS       0x00
#define USB_DEVICE_PROTOCOL_RDPS_IF    0xFF
 
/* Define the Max Power the MAX3420 will use (1 count = 2 mA)              */
#define USB_MAX3420_MAX_PWR            0
 
/* Define the Primary and Sub Language Identifier (see USB_LANGIDs.pdf
   from USB.org)                                                           */
#define USB_LANG_ENGLISH_US            0x0409
 
/* Define the constant to set the End-Points 0 to a stall state */
#define USB_MAX3420_SET_ENDPTS0_STALL  0x23
 
/* Define the mask for the End-Point Interrupt Register */
#define USB_MAX3420_EPIR_SETUP_IRQ     0x20
#define USB_MAX3420_EPIR_EP3IB_IRQ     0x10
#define USB_MAX3420_EPIR_EP2IB_IRQ     0x08
#define USB_MAX3420_EPIR_EP1OB_IRQ     0x04
#define USB_MAX3420_EPIR_EP0OB_IRQ     0x02
#define USB_MAX3420_EPIR_EP0IB_IRQ     0x01
 
#define USB_MAX3420_EPIR_CLR_REAMINDER_IRQS  (  USB_MAX3420_EPIR_EP3IB_IRQ \
                                              | USB_MAX3420_EPIR_EP0OB_IRQ \
                                              | USB_MAX3420_EPIR_EP0IB_IRQ   )
 
 
/* ----------------------------------------------------------------------- */
/* Define the End-Point Buffer Lengths                                     */
/* ----------------------------------------------------------------------- */
 
        /* Set-Up Req Data Buffer                   */
#define USB_SETUP_REQ_BUF_LEN          10
 
        /* Set-Up Req Rspn Data Buffer              */
#define USB_SETUP_REQ_RSPN_BUF_LEN     128
 
        /* End-Point Buffer                         */
#define USB_EP_BUF_LEN                 512
 
 
 
/******************************************************************************
 *            I n t e r n a l   T y p e   D e c l a r a t i o n s             *
 ******************************************************************************/
 
/* ------------------------------------------------------------------------ */
/* MAX3420E End-Point Interrupt Register                                    */
/* ------------------------------------------------------------------------ */
typedef union
{
  struct
  {        /* Reserved */
    UINT8  ReservedB7_B6           : 2,
 
           /* SETUP Data Available Interrupt Request */
           SetupDataAvailIntReq    : 1,
 
           /* Endpoint 3 IN Buffer Available Interrupt Request */
           EndPt3InBufAvailIntReq  : 1,
 
           /* Endpoint 2 IN Buffer Available Interrupt Request */
           EndPt2InBufAvailIntReq  : 1,
 
           /* Endpoint 1 OUT Data Available Interrupt Request */
           EndPt1OutBufAvailIntReq : 1,
 
           /* Endpoint 0 OUT Data Available Interrupt Request */
           EndPt0OutBufAvailIntReq : 1,
 
           /* Endpoint 0 IN Buffer Available Interrupt Request */
           EndPt0InBufAvailIntReq  : 1;
 
  } Fields;
  UINT8 Packed;
 
} USB_EPIRQ_TYPE;
 
 
/* ------------------------------------------------------------------------ */
/* MAX3420E USB Interrupt Request Register                                  */
/* ------------------------------------------------------------------------ */
typedef union
{
  struct
  {        /* USB Bus Reset Done Interrupt Request */
    UINT8  UsbBusResetDoneIntReq  : 1,
 
           /* VBUS present Interrupt Request */
           VbusDetectIntReq       : 1,
 
           /* No VBUS Interrupt Request */
           NoVbusIntReq           : 1,
 
           /* SUSPEND Interrupt Request */
           SuspendIntReq          : 1,
 
           /* USB Bus Reset Interrupt Request */
           UsbBusResetIntReq       : 1,
 
           /* Bus Active Interrupt Request */
           BusActiveIntReq        : 1,
 
           /* Remote Wakeup Signaling Done Interrupt Request */
           RemoteWakupIntReq      : 1,
 
           /* Oscillator OK Interrupt Request */
           OscOkIntReq            : 1;
 
  } Fields;
  UINT8 Packed;
 
} USB_USBIRQ_TYPE;
 
 
/* ----------------------------------------------------------------------- */
/* MAX3420 Command Word
/* ----------------------------------------------------------------------- */
typedef union
{
  struct
  {        /* Register Number */
    UINT8  Register  : 5,
 
           /* Reserved */
           Reserved  : 1,
 
           /* Data Direction: 1 - Write, 0 - Read */
           Direction : 1,
 
           /* AckStat sets the ACTSTAT but in the EPSTALLS register */
           AckStat   : 1;
 
  } Fields;
  UINT8 Packed;
 
} USB_3420_CMD_TYPE;
 
 
typedef struct
{
  UINT16  ReadIdx,
          WriteIdx;
  UINT8   Buffer[USB_EP_BUF_LEN],
          OverflowCount;
} USB_END_PT_BUFF_DESCRIPTOR_TYPE;
 
 
 
/******************************************************************************
 *            I n t e r n a l   D a t a   D e c l a r a t i o n s             *
 ******************************************************************************/
 
       /* Set-Up Req Data Buffer                   */
UINT8 USB_SetUpReqData[USB_SETUP_REQ_BUF_LEN] = {0},
 
      /* The Configuration Value */
      USB_ConfigurationValue = 0;
 
       /* Set-Up Req Rspn Data Buffer              */
UINT8 USB_SetUpReqRspnData[USB_SETUP_REQ_RSPN_BUF_LEN] = {0};
 
       /* End-Point 1 (INTERRUPT Point) OUT Buffer */
USB_END_PT_BUFF_DESCRIPTOR_TYPE USB_EndPt1OutBuffer = {0};
       /* End-Point 2 (INTERRUPT Point) IN Buffer  */
USB_END_PT_BUFF_DESCRIPTOR_TYPE USB_EndPt2InBuffer = {0};
 
/* The MAX3420 Register Initialization Table */
USB_MAX_REG_INIT_TYPE USB_3420RegInitTable[] =
{
  {USB_3420REG_PINCTL,0x1B},
  {USB_3420REG_USBCTL,0x28},
  {USB_3420REG_USBCTL,0x08},
  {USB_3420REG_EPIEN, 0x24},
  {USB_3420REG_USBIEN,0x80},
  {USB_3420REG_USBCTL,0x48},
  {USB_3420REG_CPUCTL,0x01}
};
 
/* ----------------------------------------------------------------------- */
/* Declared the USB Device Descriptor                                      */
/* ----------------------------------------------------------------------- */
const USB_DEVICE_DESCRIPTOR_TYPE USB_DeviceDescriptor =
{
  sizeof(USB_DEVICE_DESCRIPTOR_TYPE),         /* Length              */
  USB_DESC_TYPE_DEVICE_DESCRIPTOR,            /* DescriptorType      */
  ENDIAN_CONVERT_UINT16(USB_COMPLIANT_2PT0),  /* USBComplianceSpec   */
  USB_DEVICE_CLASS_RDPS,                      /* DeviceClass         */
  USB_DEVICE_SUB_CLASS_RDPS,                  /* DeviceSubClass      */
  USB_DEVICE_PROTOCOL_RDPS,                   /* DeviceProtocol      */
  USB_MAX3420_EP0_SIZE,                       /* MaxPacketSize0      */
  ENDIAN_CONVERT_UINT16(USB_VENDOR_ID),       /* VendorID            */
  ENDIAN_CONVERT_UINT16(USB_PRODUCT_ID),      /* ProductID           */
  ENDIAN_CONVERT_UINT16(USB_DEVICE_ID),       /* DeviceID            */
  1,                                          /* Manufacturer        */
  2,                                          /* Product             */
  3,                                          /* SerialNumber        */
  1                                           /* NumConfigurations   */
};
 
 
/* ----------------------------------------------------------------------- */
/* Declared the USB Configuration Data                                     */
/* ----------------------------------------------------------------------- */
const USB_CONFIG_DATA_TYPE  USB_ConfigurationData =
{
  /* USB_CONFIGURATION_DESCRIPTOR  ConfigDescriptor                        */
  {
    sizeof(USB_CONFIGURATION_DESCRIPTOR_TYPE),          /* Length             */
    USB_DESC_TYPE_CONFIGURATION_DESCRIPTOR,             /* DescriptorType     */
    ENDIAN_CONVERT_UINT16(sizeof(USB_CONFIG_DATA_TYPE)),/* TotalLength        */
    1,                                                  /* NumInterfaces      */
    1,                                                  /* ConfigurationValue */
    4,                                                  /* ConfigurationIdx   */
    USB_CFG_ATTRIBUTES,                                 /* Attributes         */
    USB_MAX3420_MAX_PWR                                 /* MaxPower           */
  },
 
  /* USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor                         */
  {
    sizeof(USB_INTERFACE_DESCRIPTOR_TYPE),        /* Length                */
    USB_DESC_TYPE_INTERFACE_DESCRIPTOR,           /* DescriptorType        */
    0,                                            /* InterfaceNumber       */
    0,                                            /* AlternateSetting      */
    2,                                            /* NumEndpoints          */
    USB_DEVICE_CLASS_RDPS_IF,                     /* InterfaceClass        */
    USB_DEVICE_SUB_CLASS_RDPS_IF,                 /* InterfaceSubClass     */
    USB_DEVICE_PROTOCOL_RDPS_IF,                  /* InterfaceProtocol     */
    5                                             /* InterfaceIdx          */
  },
 
  /* USB_ENDPOINT_DESCRIPTOR  EndpointDescriptorEP1Out                     */
  {
    sizeof(USB_ENDPOINT_DESCRIPTOR_TYPE),         /* Length                */
    USB_DESC_TYPE_ENDPOINT_DESCRIPTOR,            /* DescriptorType        */
    USB_CFG_EP_DIR_OUT | USB_CFG_EP_ADDR_01,      /* EndPointAddress       */
    USB_EP_XFER_BULK,                             /* Attributes            */
    ENDIAN_CONVERT_UINT16(USB_MAX3420_EP1_SIZE),  /* MaxPacketSize         */
    0                                             /* Interval              */
  },
 
  /* USB_ENDPOINT_DESCRIPTOR  EndpointDescriptorEP2In                      */
  {
    sizeof(USB_ENDPOINT_DESCRIPTOR_TYPE),         /* Length                */
    USB_DESC_TYPE_ENDPOINT_DESCRIPTOR,            /* DescriptorType        */
    USB_CFG_EP_DIR_IN | USB_CFG_EP_ADDR_02,       /* EndpointAddress       */
    USB_EP_XFER_BULK,                             /* Attributes            */
    ENDIAN_CONVERT_UINT16(USB_MAX3420_EP2_SIZE),  /* MaxPacketSize         */
    0                                             /* Interval              */
  }
};
 
 
/* ----------------------------------------------------------------------- */
/* Declared the USB String Data                                            */
/* ----------------------------------------------------------------------- */
const USB_LANGID_DESCRIPTOR_TYPE  USB_LanguageIDString =
{
  sizeof(USB_LANGID_DESCRIPTOR_TYPE),             /* Length                */
  USB_SRT_GD_STRING,                              /* DescriptorType        */
  ENDIAN_CONVERT_UINT16(USB_LANG_ENGLISH_US)      /* LANGID0               */
};
 
 
const USB_MANUFACTURER_DESCRIPTOR_TYPE  USB_ManufactureIDString =
{
  sizeof(USB_MANUFACTURER_DESCRIPTOR_TYPE),       /* Length                */
  USB_SRT_GD_STRING,                              /* DescriptorType        */
  USB_RDPS_STR_MANUFACTURER                       /* String                */
};
 
 
const USB_PRODUCT_ID_DESCRIPTOR_TYPE  USB_ProductIDString =
{
  sizeof(USB_PRODUCT_ID_DESCRIPTOR_TYPE),         /* Length                */
  USB_SRT_GD_STRING,                              /* DescriptorType        */
  USB_RDPS_STR_PRODUCT                            /* String                */
};
 
 
const USB_SERIAL_NO_DESCRIPTOR_TYPE   USB_SerialNoIDString =
{
  sizeof(USB_SERIAL_NO_DESCRIPTOR_TYPE),          /* Length                */
  USB_SRT_GD_STRING,                              /* DescriptorType        */
  USB_RDPS_STR_SERIAL_NO                          /* String                */
};
 
const USB_CONFIG_ID_DESCRIPTOR_TYPE  USB_ConfigIDString =
{
  sizeof(USB_CONFIG_ID_DESCRIPTOR_TYPE),          /* Length                */
  USB_SRT_GD_STRING,                              /* DescriptorType        */
  USB_RDPS_STR_CONFIG                             /* String                */
};
 
 
const USB_INTERFACE_ID_DESCRIPTOR_TYPE  USB_InterfaceIDString =
{
  sizeof(USB_INTERFACE_ID_DESCRIPTOR_TYPE),       /* Length                */
  USB_SRT_GD_STRING,                              /* DescriptorType        */
  USB_RDPS_STR_INTERFACE                          /* String                */
};
 
 
 
/******************************************************************************
 *          I n t e r n a l   F u n c t i o n   P r o t o t y p e s           *
 ******************************************************************************/
 
UINT8  USB_ReadMAX3420Reg( USB_3420REG_IDX_TYPE reg, UINT8 ackStatFlag );
void   USB_WriteMAX3420Reg( USB_3420REG_IDX_TYPE reg,
                            UINT8 dataToWrite,
                            UINT8 ackStatFlag );
void   USB_SetUpDataHandler( void );
void   USB_EndPt1OutReqHandler( void );
void   USB_EndPt2InReqHandler( void );
void   USB_SetUpDataStandardReqHandler( void );
void   USB_SetEndPts0ToStall( void );
void   USB_SendEndPt0InData( UINT8* buff, UINT16 length );
 
/* This is the interface requirement for this USB device to talk with the
   SPI device driver                                                         */
void USB_SpiXfer( UINT8 *txBuf, UINT8 *rxBuf, UINT8 numOfBytes );
 
 
 
/******************************************************************************
 *                   F u n c t i o n   D e f i n i t i o n s                  *
 ******************************************************************************/
 
/*******************************************************************************
 *
 *  Function    :  USB_ReadMAX3420Reg
 *
 *  Description :  Reads the MAX3420 registers via the SPI bus
 *
 *  Rate        :  Upon Demand
 *
 *  Parameter   :  USB_3420REG_IDX_TYPE  - The MAX3420 register to read
 *                 UINT8                 - The flag state of ACKSTAT in the
 *                                         EPSTALLS register
 *
 *  Returns     :  UINT8                   The register value read
 *
 ******************************************************************************/
 
UINT8 USB_ReadMAX3420Reg( USB_3420REG_IDX_TYPE reg, UINT8 ackStatFlag )
{
  USB_3420_CMD_TYPE usbCmd;
  UINT8             txBuffer[2],
                    rxBuffer[2];
 
  /* Craft the Command Word */
  usbCmd.Packed = 0;
  usbCmd.Fields.Register  = reg;
  usbCmd.Fields.Direction = USB_MAX3420_DD_READ;
  usbCmd.Fields.AckStat   = ackStatFlag;
 
  /* Package the Message (Cmd Word and Data */
  txBuffer[0] = usbCmd.Packed;
  txBuffer[1] = 0;   /* Dummy Data */
 
  /* Transmit the Pin Control Init Data, use the same buffer for Tx and Rx
     since don't care about the Rx data and the Tx will have been shifted
     into the device before the data is over written                          */
  USB_SpiXfer( txBuffer, rxBuffer, 2 );
 
  return rxBuffer[1];
}
 
 
 
/*******************************************************************************
 *
 *  Function    :  USB_WriteMAX3420Reg
 *
 *  Description :  Write the MAX3420 registers via the SPI bus
 *
 *  Rate        :  Upon Demand
 *
 *  Parameter   :  USB_3420REG_IDX_TYPE  - The MAX3420 register to write
 *                 UINT8                 - The write data value
 *                 UINT8                 - The flag state of ACKSTAT in the
 *                                         EPSTALLS register
 *
 *  Returns     :  None
 *
 ******************************************************************************/
 
void USB_WriteMAX3420Reg( USB_3420REG_IDX_TYPE reg,
                          UINT8                dataToWrite,
                          UINT8                ackStatFlag )
{
  USB_3420_CMD_TYPE usbCmd;
  UINT8             txBuffer[2],
                    rxBuffer[2];
 
 
  /* Craft the Command Word */
  usbCmd.Packed = 0;
  usbCmd.Fields.Register  = reg;
  usbCmd.Fields.Direction = USB_MAX3420_DD_WRITE;
  usbCmd.Fields.AckStat   = ackStatFlag;
 
  /* Package the Message (Cmd Word and Data */
  txBuffer[0] = usbCmd.Packed;
  txBuffer[1] = dataToWrite;
 
  /* Transmit the Pin Control Init Data, use the same buffer for Tx and Rx
     since don't care about the Rx data and the Tx will have been shifted
     into the device before the data is over written                          */
  USB_SpiXfer( txBuffer, rxBuffer, 2 );
}
 
/*******************************************************************************
 *
 *  Function    :  USB_ReadData
 *
 *  Description :  The interface used to read the data received from the USB.
 *
 *  Rate        :  Upon Demand
 *
 *  Parameter   :  UINT8  - The destination buffer where the data from the USB
 *                          End-Point 1 OUT buffer is copied.
 *                 UINT16 - The maximum number of bytes to copy
 *
 *  Returns     :  UINT16 - The actual number of bytes copied
 *
 ******************************************************************************/
 
UINT16 USB_ReadData( UINT8* buff, UINT16 length )
{
  UINT16 cnt;
  UINT32 idx;
 
  cnt = 0;
 
  /* Disable the USB interrupt - This is hardware depend or can disable the
     interrupt on the USB device.  Disabling it on the microprocessor was
     easier in my case.                                                       */
//  IRQCR &= ~BIT6;
 
  /* Disable the End-Point 1 OUT Data Available Interrupt */
  USB_3420RegInitTable[3].InitData &= ~BIT2;
  USB_WriteMAX3420Reg( USB_3420RegInitTable[3].RegIdx,
                       USB_3420RegInitTable[3].InitData,
                       FALSE );
 
  /* Enable the USB interrupt */
//  IRQCR |= BIT6;
 
  // Iterate through the data and write the data to memory
  for ( idx = 0;
        ( (idx < length) &&
          (USB_EndPt1OutBuffer.ReadIdx != USB_EndPt1OutBuffer.WriteIdx) );
        idx++ )
  {
    /* Copy the data from the source buffer, as defined by
       USB_EndPt1OutBuffer.Buffer[] into the caller's buffer */
    buff[idx] = USB_EndPt1OutBuffer.Buffer[USB_EndPt1OutBuffer.ReadIdx];
 
    USB_EndPt1OutBuffer.ReadIdx++;
    if (USB_EndPt1OutBuffer.ReadIdx == USB_EP_BUF_LEN)
    {
      USB_EndPt1OutBuffer.ReadIdx = 0;
    }
 
    cnt++;
  }
 
  /* Disable the USB interrupt */
//  IRQCR &= ~BIT6;
 
  /* Re-enable the End-Point 1 OUT Data Available Interrupt */
  USB_3420RegInitTable[3].InitData |= BIT2;
  USB_WriteMAX3420Reg( USB_3420RegInitTable[3].RegIdx,
                       USB_3420RegInitTable[3].InitData,
                       FALSE );
 
  /* Enable the USB interrupt */
//  IRQCR |= BIT6;
 
  return cnt;
}
 
/*******************************************************************************
 *
 *  Function    :  USB_WriteData
 *
 *  Description :  The interface used to write (i.e., send) data to the USB.
 *
 *  Rate        :  Upon Demand
 *
 *  Parameter   :  UINT8  - The source buffer containing the data that is
 *                          copied to the USB End-Point 2 IN buffer.
 *                 UINT16 - The number of bytes to copy
 *
 *  Returns     :  UINT16 - The actual number of bytes copied
 *
 ******************************************************************************/
 
UINT16 USB_WriteData( UINT8* buff, UINT16 length )
{
  UINT16 cnt;
  UINT32 idx,
         writeIdx;
 
  cnt = 0;
 
  // Initialize local variable to USB_EndPt2InBuffer.WriteIdx
  writeIdx = USB_EndPt2InBuffer.WriteIdx;
 
  /* Disable the USB interrupt */
  //  Need code to disable the USB interrupt, either at the processor or at
  //  the USB device
 
  /* Disable the End-Point 2 IN Data Available Interrupt */
  USB_3420RegInitTable[3].InitData &= ~BIT3;
  USB_WriteMAX3420Reg( USB_3420RegInitTable[3].RegIdx,
                       USB_3420RegInitTable[3].InitData,
                       FALSE );
 
  /* Enable the USB interrupt */
  //  Need code to enable the USB interrupt, either at the processor or at
  //  the USB device
 
  // Iterate through the data and write the data to memory
  for ( idx = 0; idx < length; idx++ )
  {
    /* Copy the data from the caller's buffer into the destination
       buffer, as defined by USB_EndPt2InBuffer.Buffer[], while not
       execeeding the capacity of the desintation buffer.  */
 
    writeIdx++;
    if (writeIdx == USB_EP_BUF_LEN)
    {
      writeIdx = 0;
    }
 
    if ( writeIdx != USB_EndPt2InBuffer.ReadIdx )
    {
      USB_EndPt2InBuffer.Buffer[USB_EndPt2InBuffer.WriteIdx] = buff[idx] ;
 
      USB_EndPt2InBuffer.WriteIdx = writeIdx;
 
      cnt++;
    }
    // Increment the overflow count by one for each data byte not copied.
    else
    {
      USB_EndPt2InBuffer.OverflowCount++;
 
      // Reset the local variable to keep it from wrapping
      writeIdx = USB_EndPt2InBuffer.WriteIdx;
    }
  }
 
  /* Disable the USB interrupt */
  //  Need code to disable the USB interrupt, either at the processor or at
  //  the USB device
 
  /* Re-enable the End-Point 2 IN Data Available Interrupt */
  USB_3420RegInitTable[3].InitData |= BIT3;
  USB_WriteMAX3420Reg( USB_3420RegInitTable[3].RegIdx,
                       USB_3420RegInitTable[3].InitData,
                       FALSE );
 
  /* Enable the USB interrupt */
  //  Need code to enable the USB interrupt, either at the processor or at
  //  the USB device
 
  return cnt;
}
 
 
 
/*******************************************************************************
 *
 *  Function    :  USB_InterruptHandler
 *
 *  Description :  The interrupt handler for the USB Peripheral Controller
 *
 *  Rate        :  Upon Demand
 *
 *  Parameter   :  None
 *
 *  Returns     :  None
 *
 ******************************************************************************/
 
void USB_InterruptHandler( void )
{
  USB_EPIRQ_TYPE     endPtReg;
  USB_USBIRQ_TYPE    usbReg;
 
  /* -------------------------------------------------------------------- */
  /* ------------- First get the End-Point IRQ Register Data ------------ */
  /* -------------------------------------------------------------------- */
  endPtReg.Packed = USB_ReadMAX3420Reg( USB_3420REG_EPIRQ, FALSE );
 
  /* Process the Set-Up Data Request */
  if ( endPtReg.Fields.SetupDataAvailIntReq )
  {
    USB_SetUpDataHandler();
 
    /* Clear the SETUP Data Available Interrupt */
    USB_WriteMAX3420Reg( USB_3420REG_EPIRQ, USB_MAX3420_EPIR_SETUP_IRQ, FALSE );
  }
 
  /* Process the End-Point 1 OUT Request*/
  if ( endPtReg.Fields.EndPt1OutBufAvailIntReq )
  {
    USB_EndPt1OutReqHandler();
 
    /* Clear the Endpoint 1 Out Data Available Interrupt */
    USB_WriteMAX3420Reg( USB_3420REG_EPIRQ, USB_MAX3420_EPIR_EP1OB_IRQ, FALSE );
  }
 
  /* Process the End-Point 2 IN Request if Enabled */
  if ( ( endPtReg.Fields.EndPt2InBufAvailIntReq ) &&
       ( USB_3420RegInitTable[3].InitData & BIT3 ) )
  {
    USB_EndPt2InReqHandler();
 
    /* The CPU Clears this Interrupt by Writing the
       Byte Count Register EP2INBC */
  }
 
  /* Clear all remaining End-Point Interrupts */
  USB_WriteMAX3420Reg( USB_3420REG_EPIRQ,
                       USB_MAX3420_EPIR_CLR_REAMINDER_IRQS,
                       FALSE );
 
  /* -------------------------------------------------------------------- */
  /* -------------- Secondly, get the USB IRQ Register Data ------------- */
  /* -------------------------------------------------------------------- */
  usbReg.Packed = USB_ReadMAX3420Reg( USB_3420REG_USBIRQ, FALSE );
 
  /* Check the USB Bus Reset Done Request */
  if ( usbReg.Fields.UsbBusResetDoneIntReq )
  {
    /* Re-enable the End-Point Interrupts */
    USB_WriteMAX3420Reg( USB_3420RegInitTable[3].RegIdx,
                         USB_3420RegInitTable[3].InitData,
                         FALSE );
  }
 
  /* Clear all USB Interrupts */
  USB_WriteMAX3420Reg( USB_3420REG_USBIRQ, 0xFF, FALSE );
}
 
 
 
/*******************************************************************************
 *
 *  Function    :  USB_SetUpDataHandler
 *
 *  Description :  This function handles the Set-Up Data request from the Host
 *
 *  Rate        :  Upon Demand
 *
 *  Parameter   :  None
 *
 *  Returns     :  None
 *
 ******************************************************************************/
 
void USB_SetUpDataHandler( void )
{
  USB_3420_CMD_TYPE  cmdWord;
  UINT8              idx;
  USB_REQUEST_TYPE   *reqTypePtr;
  UINT8              txBuffer[USB_SETUP_REQ_BUF_LEN];
 
 
  /* Set command to fetech the Set-Up Data from the USB */
  cmdWord.Packed = 0;
  cmdWord.Fields.Register  = USB_3420REG_SUDFIFO;
  cmdWord.Fields.Direction = USB_MAX3420_DD_READ;
  cmdWord.Fields.AckStat   = FALSE;
 
  /* Package the Data to fetch the Set-Up Data FIFO */
  txBuffer[0] = cmdWord.Packed;   /* Package the Command Word */
 
  /* Fill with dummy data */
  for ( idx = 1; idx < 9; idx++ )
  {
    txBuffer[idx] = 0;
  }
 
  /* Read the Set-Up Data from the MAX3420 via the SPI to the USB Device */
  USB_SpiXfer( txBuffer, USB_SetUpReqData, 9 );
 
  /* Set the buffer to point to the Set-Up Data at the correct offset */
  reqTypePtr = (USB_REQUEST_TYPE*)&USB_SetUpReqData[USB_SUD_REQ_TYPE_IDX];
 
  /* Check the Request Type (i.e., USB.org's bmRequestType) bitmapped field
     to see what 'Type' of request was issued then call the appropriate
     request handler  */
  switch ( reqTypePtr->Fields.Type )
  {
    case USB_REQ_TYPE_STD:
      USB_SetUpDataStandardReqHandler();
      break;
 
    default:  /* Unsupported Request Types */
      USB_SetEndPts0ToStall();
      break;
  }
}
 
 
 
/*******************************************************************************
 *
 *  Function    :  USB_EndPt1OutReqHandler
 *
 *  Description :  This function copies the data from the End-Point 1 OUT FIFO
 *                 to the USB End-Point 1 OUT buffer.
 *
 *  Rate        :  Upon Demand
 *
 *  Parameter   :  None
 *
 *  Returns     :  None
 *
 ******************************************************************************/
 
void USB_EndPt1OutReqHandler( void )
{
  USB_3420_CMD_TYPE  cmdWord;
  UINT8              bytesToRead,
                     length,
                     idx,
                     writeIdx;
  UINT8              tempBuff[USB_MAX3420_EP1_SIZE+1];
 
  // Initialize local variable to USB_EndPt1OutBuffer.WriteIdx
  writeIdx = USB_EndPt1OutBuffer.WriteIdx;
 
  /* First determine the number of data bytes in the End-Point 1 Output FIFO */
  bytesToRead = USB_ReadMAX3420Reg( USB_3420REG_EP1OUTBC, FALSE );
 
  /* Set command to read the data from the End-Point 1 Output FIFO */
  cmdWord.Packed = 0;
  cmdWord.Fields.Register  = USB_3420REG_EP1OUTFIFO;
  cmdWord.Fields.Direction = USB_MAX3420_DD_READ;
  cmdWord.Fields.AckStat   = TRUE;
 
  /* Package the Command Word */
  tempBuff[0] = cmdWord.Packed;
 
  /* Fill with dummy data */
  for ( length = 1; length < bytesToRead + 1; length++ )
  {
    tempBuff[length] = 0;
  }
 
  if ( length > 1 )
  {
    /* Transmit the Request via the SPI to the USB Device */
    USB_SpiXfer( tempBuff, tempBuff, length );
  }
 
  /* Iterate through the data and write the data to memory                    */
  for ( idx = 1; idx < length; idx++ )
  {
    /* Copy the data from the temporary buffer into the destination
       buffer, as defined by USB_EndPt1OutBuffer.Buffer[], while not
       execeeding the capacity of the desintation buffer. */
 
    writeIdx++;
    if (writeIdx == USB_EP_BUF_LEN)
    {
      writeIdx = 0;
    }
 
    if ( writeIdx != USB_EndPt1OutBuffer.ReadIdx )
    {
      USB_EndPt1OutBuffer.Buffer[USB_EndPt1OutBuffer.WriteIdx] = tempBuff[idx] ;
 
      USB_EndPt1OutBuffer.WriteIdx++;
      if (USB_EndPt1OutBuffer.WriteIdx == USB_EP_BUF_LEN)
      {
        USB_EndPt1OutBuffer.WriteIdx = 0;
      }
    }
    /* Increment the overflow count by one for each data byte not copied. */
    else
    {
      USB_EndPt1OutBuffer.OverflowCount++;
 
      /* Reset the local variable to keep it from wrapping */
      writeIdx = USB_EndPt1OutBuffer.WriteIdx;
    }
  }
}
 
 
 
/*******************************************************************************
 *
 *  Function    :  USB_EndPt2InReqHandler
 *
 *  Description :  This function copies data from the USB End-Point 2 IN buffer
 *                 to the End-Point 2 IN FIFO.
 *
 *  Rate        :  Upon Demand
 *
 *  Parameter   :  None
 *
 *  Returns     :  None
 *
 ******************************************************************************/
 
void USB_EndPt2InReqHandler( void )
{
  USB_3420_CMD_TYPE  cmdWord;
  UINT8              length,
                     tempBuff[USB_MAX3420_EP2_SIZE+1];
 
  /* Set command to write the data to the End-Point 2 Input FIFO */
  cmdWord.Packed = 0;
  cmdWord.Fields.Register  = USB_3420REG_EP2INFIFO;
  cmdWord.Fields.Direction = USB_MAX3420_DD_WRITE;
  cmdWord.Fields.AckStat   = FALSE;
 
  /* Package the Command Word */
  tempBuff[0] = cmdWord.Packed;
 
  /* Iterate through the data while not exceeding the capacity of the
     source buffer and the number of data bytes copied are no more than
     64 data bytes */
  for ( length = 1;
        ( (length < USB_MAX3420_EP2_SIZE+1) &&
          (USB_EndPt2InBuffer.ReadIdx != USB_EndPt2InBuffer.WriteIdx) );
        length++)
  {
    /* Copy the data from the source buffer, as defined by
       USB_EndPt2InBuffer.Buffer[] into the temporary buffer */
    tempBuff[length] = USB_EndPt2InBuffer.Buffer[USB_EndPt2InBuffer.ReadIdx];
 
    USB_EndPt2InBuffer.ReadIdx++;
    if (USB_EndPt2InBuffer.ReadIdx == USB_EP_BUF_LEN)
    {
      USB_EndPt2InBuffer.ReadIdx = 0;
    }
  }
 
  /* Check if there are any data bytes to send */
  if ( length > 1 )
  {
    /* Transmit the Request via the SPI to the USB Device */
    USB_SpiXfer( tempBuff, tempBuff, length );
 
    /* Set up the command to write to the EP2 Byte-Count Register */
    USB_WriteMAX3420Reg( USB_3420REG_EP2INBC, (length - 1), TRUE );
  }
 
  /* Disable the End-Point 2 IN Data Available Interrupt if the number of
     data bytes copied is less than 64 or if the End-Point 2 IN buffer is
     empty */
  if ( (USB_EndPt2InBuffer.ReadIdx == USB_EndPt2InBuffer.WriteIdx) ||
       ((length -1) < USB_MAX3420_EP2_SIZE) )
  {
    USB_3420RegInitTable[3].InitData &= ~BIT3;
    USB_WriteMAX3420Reg( USB_3420RegInitTable[3].RegIdx,
                         USB_3420RegInitTable[3].InitData,
                         FALSE );
  }
}
 
 
 
/*******************************************************************************
 *
 *  Function    :  USB_SetUpDataStandardReqHandler
 *
 *  Description :  This function handles the Set-Up Data Standard Request.
 *
 *  Rate        :  Upon Demand
 *
 *  Parameter   :  None
 *
 *  Returns     :  None
 *
 ******************************************************************************/
 
void USB_SetUpDataStandardReqHandler( void )
{
  UINT8                  isRequestSupported,
                         (*dataPtr),
                         idx,
                         tempBuff[2];
  UINT16                 bytesToSend = 0,
                         reqLength;
  USB_SETUP_REQUEST_TYPE *setUpDataPtr;
 
 
  setUpDataPtr =
    (USB_SETUP_REQUEST_TYPE*)&USB_SetUpReqData[USB_SUD_REQ_TYPE_IDX];
  isRequestSupported = TRUE;
 
  switch ( setUpDataPtr->Request )
  {
    case USB_SRT_SET_ADDRESS:
      USB_ReadMAX3420Reg( USB_3420REG_FNADDR, TRUE );
      break;
 
    case USB_SRT_SET_CONFIGURATION:
      /* Store the Configuration Value */
      USB_ConfigurationValue = USB_SetUpReqData[USB_SUD_VALUE_LOW_IDX];
 
      /* Perform a dummy read on the Function Address to ACK request */
      USB_ReadMAX3420Reg( USB_3420REG_FNADDR, TRUE );
      break;
 
    case USB_SRT_GET_CONFIGURATION:
      /* Package the Configuration Value to send to the Host and indicate how
         many bytes to send */
      tempBuff[0] = USB_ConfigurationValue;
      bytesToSend = 1;
      break;
 
    case USB_SRT_GET_DESCRIPTOR:
      switch (  setUpDataPtr->Value & 0xFF )
      {
        case USB_SRT_GD_DEVICE:
          dataPtr = (UINT8*)&USB_DeviceDescriptor;
          bytesToSend = sizeof(USB_DeviceDescriptor);
          break;
 
        case USB_SRT_GD_CONFIGURATION:
          dataPtr = (UINT8*)&USB_ConfigurationData;
          bytesToSend = sizeof(USB_ConfigurationData);
 
          break;
 
        case USB_SRT_GD_STRING:
          switch ( (setUpDataPtr->Value & 0xFF00) >> 8 )
          {
            case 0:
              dataPtr = (UINT8*)&USB_LanguageIDString;
              bytesToSend = sizeof(USB_LanguageIDString);
              break;
 
            case 1:
              dataPtr = (UINT8*)&USB_ManufactureIDString;
              bytesToSend = sizeof(USB_ManufactureIDString);
              break;
 
            case 2:
              dataPtr = (UINT8*)&USB_ProductIDString;
              bytesToSend = sizeof(USB_ProductIDString);
              break;
 
            case 3:
              dataPtr = (UINT8*)&USB_SerialNoIDString;
              bytesToSend = sizeof(USB_SerialNoIDString);
              break;
 
            case 4:
              dataPtr = (UINT8*)&USB_ConfigIDString;
              bytesToSend = sizeof(USB_ConfigIDString);
              break;
 
            case 5:
              dataPtr = (UINT8*)&USB_InterfaceIDString;
              bytesToSend = sizeof(USB_InterfaceIDString);
              break;
 
            /* No additional String Types */
            default:
              isRequestSupported = FALSE;
              break;
          }
          break;
 
        /* All other Get-Descriptor Request are not support */
        default:
          isRequestSupported = FALSE;
          break;
      }
      break;
 
    /* All other Set-Up Data Request are not supported,send STALL */
    default:
      isRequestSupported = FALSE;
      break;
  }
 
  /* Send the appropriate data for the Get-Descriptor Request */
  if ( isRequestSupported )
  {
    /* Determine how many bytes to send, if the 'wLength' field is
       shorter than the descriptor then send only what the Host
       specified in the request. Remember, 'wLenth' is stored in
       Little-Endian format */
    reqLength = ENDIAN_CONVERT_UINT16( setUpDataPtr->Length );
    if ( reqLength < bytesToSend )
    {
      bytesToSend = reqLength;
    }
 
    /* Check for zero length response (USB_SRT_SET_ADDRESS) */
    if ( bytesToSend )
    {
      USB_SendEndPt0InData( dataPtr, bytesToSend );
    }
  }
 
  /* Otherwise the Get-Descriptor Request is not support, send STALL */
  else
  {
    USB_SetEndPts0ToStall();
  }
}
 
 
 
/*******************************************************************************
 *
 *  Function    :  USB_SetEndPts0ToStall
 *
 *  Description :  This function sets each of the End-Points 0 to stall. When
 *                 a request is issued that is not supported a STALL handshake
 *                 is issued.
 *
 *  Rate        :  Upon Demand
 *
 *  Parameter   :  None
 *
 *  Returns     :  None
 *
 ******************************************************************************/
 
void USB_SetEndPts0ToStall( void )
{
  /* Set up the command to set the EPSTALLS Register */
  USB_WriteMAX3420Reg( USB_3420REG_EPSTALLS,
                       USB_MAX3420_SET_ENDPTS0_STALL,
                       FALSE );
}
 
 
 
/*******************************************************************************
 *
 *  Function    :  USB_SendEndPt0InData
 *
 *  Description :  The USB_SendEndPt0InData() transmits the Set-Up
 *                 Request Response data to the Host via End-Point 0 IN pipe.
 *
 *  Rate        :  Upon Demand
 *
 *  Parameter   :  UINT8*  - The source buffer copied to the End-Point 0 IN FIFO
 *                 UINT16  - The number of bytes to copy
 *
 *  Returns     :  None
 *
 ******************************************************************************/
 
void USB_SendEndPt0InData( UINT8* buff, UINT16 length )
{
  UINT16 idx;
  USB_3420_CMD_TYPE  cmdWord;
  UINT8              buffer[2];
 
  /* Set up the command to write to the EPO FIFO Register */
  cmdWord.Packed = 0;
  cmdWord.Fields.Register  = USB_3420REG_EP0FIFO;
  cmdWord.Fields.Direction = USB_MAX3420_DD_WRITE;
  cmdWord.Fields.AckStat   = FALSE;
 
  /* Create the package to send to the MAX3420 End-Point 0 FIFO */
  USB_SetUpReqRspnData[0] = cmdWord.Packed;
  for ( idx = 0; idx < length; idx++ )
  {
    USB_SetUpReqRspnData[idx + 1] = buff[idx];
  }
 
  /* Send the data to the USB via SPI, use the same buffer for Tx and Rx since
     don't care about the Rx data and the Tx will have been shifted into the
     device before the data is over written, Plus One for the CMD   */
  USB_SpiXfer( USB_SetUpReqRspnData, USB_SetUpReqRspnData, (length + 1) );
 
 
  /* Set up the command to write to the EPO Byte-Count Register */
  USB_WriteMAX3420Reg( USB_3420REG_EP0BC, length, TRUE );
}
 
 
 

One Response to “USB driver”

  1. Tariq Says:

    nice job author, Can you plz guide how to implement ms13-027 kernel mode vulnerability ????

Leave a comment