/*******************************************************************************
*
* 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 );
}
This entry was posted on December 13, 2010 at 11:16 pm and is filed under Uncategorized. You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackback from your own site.
May 12, 2014 at 6:51 am |
nice job author, Can you plz guide how to implement ms13-027 kernel mode vulnerability ????