📄 usb.c
字号:
//=========================================================================================
//usb.c
//=========================================================================================
#include "addr.h"
#include "usb.h"
#include "lib.h"
#include "libs.h"
struct USB_SETUP_DATA SetupData;
struct USB_DEVICE_DESCRIPTOR DescriptorDevice;
struct USB_CONFIGURATION_DESCRIPTOR DescriptorConfiguration;
struct USB_INTERFACE_DESCRIPTOR DescriptorInterface;
struct USB_ENDPOINT_DESCRIPTOR DescriptorEndpoint_0;
struct USB_ENDPOINT_DESCRIPTOR DescriptorEndpoint_1;
struct USB_GET_STATUS StatusGet;
U8 ConfiguratioSet;
U8 InterfaceSet;
static const U8 DescriptorString0[]={ //codes representing languages
4,TYPE_STRING,LANGID_US_L,LANGID_US_H,
};
static const U8 DescriptorString1[]={ //Manufacturer
(0x14+2),TYPE_STRING,
'S',0x0,'y',0x0,'s',0x0,'t',0x0,'e',0x0,'m',0x0,' ',0x0,'M',0x0,
'C',0x0,'U',0x0,
};
static const U8 DescriptorString2[]={ //Product
(0x2a+2),TYPE_STRING,
'S',0x0,'E',0x0,'C',0x0,' ',0x0,'S',0x0,'3',0x0,'C',0x0,'2',0x0,
'4',0x0,'1',0x0,'0',0x0,'X',0x0,' ',0x0,'T',0x0,'e',0x0,'s',0x0,
't',0x0,' ',0x0,'B',0x0,'/',0x0,'D',0x0
};
volatile U8 DownStatus;
volatile U32 uDownSize;
volatile U32 uDownAddr;
volatile U16 uCheckSum;
volatile U32 uTempDownSize;
U8 * pDownAddr;
void Handler_Ep0( void );
void Handler_Ep1( void );
void Handler_Ep3( void );
void ResetUsbdReg( void );
void __irq IsrDma2( void );
void USBD_ReadFIFO( U8 * buf, volatile U8 * pFIFO, U32 size )
{
U32 i;
for( i = 0; i < size; i++ )
{
buf[i] = *pFIFO;
}
}
U16 USBD_ReadFIFO_WithChecksumReturn( U8 * buf, volatile U8 * pFIFO, U32 size )
{
U32 i;
U16 uChecksum = 0;
for( i = 0; i < size; i++ )
{
buf[i] = *pFIFO;
uChecksum += buf[i];
}
return uChecksum;
}
void USBD_WriteFIFO( U8 * buf, volatile U8 * pFIFO, U32 size )
{
U32 i;
for( i = 0; i < size; i++ )
{
*pFIFO = buf[i];
}
}
void ResetUsbdReg( void )
{
// *** End point information ***
// EP0: control
// EP1: bulk in end point
// EP2: not used
// EP3: bulk out end point
// EP4: not used
rPWR_REG = 0x0; //disable suspend mode
rINDEX_REG = 0;
rMAXP_REG = FIFO_SIZE_8;
rEP0_CSR = BIT_EP0_CSR_SERVICED_OUT_PKT_RDY | BIT_EP0_CSR_SERVICED_SETUP_END;
rINDEX_REG = 1;
#if (EP1_PKT_SIZE == 32)
rMAXP_REG = FIFO_SIZE_32;
#else
rMAXP_REG = FIFO_SIZE_64;
#endif
rIN_CSR1_REG = BIT_EPIN1_FIFO_FLUSH | BIT_EPIN1_CLR_DATA_TOGGLE;
rIN_CSR2_REG = BIT_EPIN2_MODE_IN | BIT_EPIN2_IN_DMA_INT_MASK | BIT_EPIN2_BULK;
rOUT_CSR1_REG = BIT_EPOUT1_CLR_DATA_TOGGLE;
//The data toggle bit should be cleared when initialization.
rOUT_CSR2_REG = BIT_EPOUT2_BULK | BIT_EPOUT2_OUT_DMA_INT_MASK;
rINDEX_REG = 2;
#if (EP2_PKT_SIZE == 32)
rMAXP_REG = FIFO_SIZE_32;
#else
rMAXP_REG = FIFO_SIZE_64;
#endif
rIN_CSR1_REG = BIT_EPIN1_FIFO_FLUSH | BIT_EPIN1_CLR_DATA_TOGGLE;
rIN_CSR2_REG = BIT_EPIN2_MODE_IN | BIT_EPIN2_IN_DMA_INT_MASK;
rOUT_CSR1_REG = BIT_EPOUT1_CLR_DATA_TOGGLE;
//The data toggle bit should be cleared when initialization.
rOUT_CSR2_REG = BIT_EPOUT2_BULK | BIT_EPOUT2_OUT_DMA_INT_MASK;
rINDEX_REG = 3;
#if (EP3_PKT_SIZE == 32)
rMAXP_REG = FIFO_SIZE_32;
#else
rMAXP_REG = FIFO_SIZE_64;
#endif
rIN_CSR1_REG = BIT_EPIN1_FIFO_FLUSH | BIT_EPIN1_CLR_DATA_TOGGLE;
rIN_CSR2_REG = BIT_EPIN2_MODE_OUT | BIT_EPIN2_IN_DMA_INT_MASK;
rOUT_CSR1_REG = BIT_EPOUT1_CLR_DATA_TOGGLE;
//The data toggle bit should be cleared when initialization.
rOUT_CSR2_REG = BIT_EPOUT2_BULK | BIT_EPOUT2_OUT_DMA_INT_MASK;
rINDEX_REG = 4;
#if (EP4_PKT_SIZE == 32)
rMAXP_REG = FIFO_SIZE_32;
#else
rMAXP_REG = FIFO_SIZE_64;
#endif
rIN_CSR1_REG = BIT_EPIN1_FIFO_FLUSH | BIT_EPIN1_CLR_DATA_TOGGLE;
rIN_CSR2_REG = BIT_EPIN2_MODE_OUT | BIT_EPIN2_IN_DMA_INT_MASK;
rOUT_CSR1_REG = BIT_EPOUT1_CLR_DATA_TOGGLE;
//The data toggle bit should be cleared when initialization.
rOUT_CSR2_REG = BIT_EPOUT2_BULK | BIT_EPOUT2_OUT_DMA_INT_MASK;
rEP_INT_REG = BIT_USBD_EP0_INT | BIT_USBD_EP1_INT | BIT_USBD_EP2_INT |
BIT_USBD_EP3_INT | BIT_USBD_EP4_INT;
rUSB_INT_REG = BIT_USBD_SUSPEND_INT | BIT_USBD_SUSPEND_INT | BIT_USBD_RESET_INT;
rEP_INT_EN_REG = BIT_USBD_EP0_INT | BIT_USBD_EP1_INT | BIT_USBD_EP3_INT;
rUSB_INT_EN_REG = BIT_USBD_RESET_INT;
uDownSize = 0;
uDownAddr = 0;
uCheckSum = 0;
DownStatus = 0;
}
void InitDescriptorTable(void)
{
//Standard device descriptor
DescriptorDevice.bLength = 0x12; //EP0_DEV_DESC_SIZE=0x12 bytes
DescriptorDevice.bDescriptorType = TYPE_DEVICE;
DescriptorDevice.bcdUSBL = 0x10;
DescriptorDevice.bcdUSBH = 0x01; //Ver 1.10
DescriptorDevice.bDeviceClass = 0xFF; //0x0
DescriptorDevice.bDeviceSubClass = 0x0;
DescriptorDevice.bDeviceProtocol = 0x0;
DescriptorDevice.bMaxPacketSize0 = 0x8;
DescriptorDevice.idVendorL = 0x45;
DescriptorDevice.idVendorH = 0x53;
DescriptorDevice.idProductL = 0x34;
DescriptorDevice.idProductH = 0x12;
DescriptorDevice.bcdDeviceL = 0x00;
DescriptorDevice.bcdDeviceH = 0x01;
DescriptorDevice.iManufacturer = 0x1; //index of string descriptor
DescriptorDevice.iProduct = 0x2; //index of string descriptor
DescriptorDevice.iSerialNumber = 0x0;
DescriptorDevice.bNumConfigurations = 0x1;
//Standard configuration descriptor
DescriptorConfiguration.bLength = 0x9;
DescriptorConfiguration.bDescriptorType = TYPE_CONFIGURATION;
DescriptorConfiguration.wTotalLengthL = 0x20; //<cfg desc>+<if desc>+<endp0 desc>+<endp1 desc>
DescriptorConfiguration.wTotalLengthH = 0;
DescriptorConfiguration.bNumInterfaces = 1;
DescriptorConfiguration.bConfigurationValue = 1;
DescriptorConfiguration.iConfiguration = 0;
DescriptorConfiguration.bmAttributes = CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED; //bus powered only.
DescriptorConfiguration.maxPower = 25; //draws 50mA current from the USB bus.
//Standard interface descriptor
DescriptorInterface.bLength = 0x9;
DescriptorInterface.bDescriptorType = TYPE_INTERFACE;
DescriptorInterface.bInterfaceNumber = 0x0;
DescriptorInterface.bAlternateSetting = 0x0; //?
DescriptorInterface.bNumEndpoints = 2; //# of endpoints except EP0
DescriptorInterface.bInterfaceClass = 0xff; //0x0 ?
DescriptorInterface.bInterfaceSubClass = 0x0;
DescriptorInterface.bInterfaceProtocol = 0x0;
DescriptorInterface.iInterface = 0x0;
//Standard endpoint0 descriptor
DescriptorEndpoint_0.bLength = 0x7;
DescriptorEndpoint_0.bDescriptorType = TYPE_ENDPOINT;
DescriptorEndpoint_0.bEndpointAddress = 1|EP_ADDR_IN; // 2400Xendpoint 1 is IN endpoint.
DescriptorEndpoint_0.bmAttributes = EP_ATTR_BULK;
DescriptorEndpoint_0.wMaxPacketSizeL = EP1_PKT_SIZE; //64
DescriptorEndpoint_0.wMaxPacketSizeH = 0x0;
DescriptorEndpoint_0.bInterval = 0x0; //not used
//Standard endpoint1 descriptor
DescriptorEndpoint_1.bLength = 0x7;
DescriptorEndpoint_1.bDescriptorType = TYPE_ENDPOINT;
DescriptorEndpoint_1.bEndpointAddress = 3|EP_ADDR_OUT; // 2400X endpoint 3 is OUT endpoint.
DescriptorEndpoint_1.bmAttributes = EP_ATTR_BULK;
DescriptorEndpoint_1.wMaxPacketSizeL = EP3_PKT_SIZE; //64
DescriptorEndpoint_1.wMaxPacketSizeH = 0x0;
DescriptorEndpoint_1.bInterval = 0x0; //not used
}
void UsbTest( void )
{
//rGPGUP &= ~(1<<9); /* Enable GPG9 */
//rGPGDAT |= (1<<9); /* set GPG9 high */
rGPHCON = rGPHCON & ~(0xf<<18) | (0x5<<18);
Delay(200);
Irq_InstallHandler( BIT_USBD, USBDIsr );
Irq_InstallHandler( BIT_DMA2, IsrDma2 );
ClearPending( BIT_USBD );
ClearPending( BIT_DMA2 );
//To enhance the USB signal quality.
//CLKOUT 0,1=OUTPUT to reduce the power consumption.
rMISCCR=rMISCCR & ~(1<<3); // USBD is selected instead of USBH1
rMISCCR=rMISCCR & ~(1<<13); // USB port 1 is enabled.
// MMU_EnableICache();
InitDescriptorTable();
ResetUsbdReg();
Irq_Enable( BIT_USBD );
}
void Handler_Ep0( void )
{
static U8* pBuffer;
static U32 uSize;
static U32 uPos;
U8 ustatus_EP0_CSR;
U8 ubakup_rINDEX_REG;
ubakup_rINDEX_REG = rINDEX_REG;
rINDEX_REG = 0;
ustatus_EP0_CSR = rEP0_CSR;
// exception, host end the control transfer befor DATA_END is set
if ( ustatus_EP0_CSR & BIT_EP0_SETUP_END )
{
rEP0_CSR = ( ustatus_EP0_CSR & ( BIT_EP0_WR_BITS )
| BIT_EP0_CSR_SERVICED_SETUP_END );
if ( ustatus_EP0_CSR & BIT_EP0_OUT_PKT_RDY )
{
rEP0_CSR = ( ustatus_EP0_CSR & ( BIT_EP0_WR_BITS )
| BIT_EP0_CSR_SERVICED_OUT_PKT_RDY );
DbgPrintf("ex if\n");
}
else
{
DbgPrintf("ex else\n");
}
pBuffer = 0;
}
// exception, protocol violation.
else if ( ustatus_EP0_CSR & BIT_EP0_SENT_STALL )
{
if ( ustatus_EP0_CSR & BIT_EP0_OUT_PKT_RDY )
rEP0_CSR = ( ustatus_EP0_CSR & ( BIT_EP0_WR_BITS )
| BIT_EP0_SENT_STALL | BIT_EP0_CSR_SERVICED_OUT_PKT_RDY );
else
rEP0_CSR = ( ustatus_EP0_CSR & ( BIT_EP0_WR_BITS )
| BIT_EP0_SENT_STALL );
DbgPrintf("exception, protocol violation\n");
}
else if( ( ustatus_EP0_CSR & BIT_EP0_OUT_PKT_RDY ) )
{
USBD_ReadFIFO((U8 *)&SetupData, &rEP0_FIFO, EP0_PKT_SIZE);
switch( SetupData.bRequest )
{
case GET_DESCRIPTOR:
switch( SetupData.bValueH )
{
case TYPE_DEVICE:
DbgPrintf( "GT_DE\n" );
pBuffer = ( U8 * )&DescriptorDevice;
uSize = sizeof( DescriptorDevice );
uPos = 0;
rEP0_CSR = ( ustatus_EP0_CSR & ( BIT_EP0_WR_BITS )
| BIT_EP0_CSR_SERVICED_OUT_PKT_RDY );
break;
case TYPE_CONFIGURATION:
DbgPrintf( "GT_CF\n" );
pBuffer = ( U8 * )&DescriptorConfiguration;
if ( ( SetupData.bLengthL + ( SetupData.bLengthH << 8 ) ) > 0x09 )
//bLengthH should be used for bLength=0x209 at WIN2K.
uSize = sizeof( DescriptorConfiguration )
+ sizeof( DescriptorInterface )
+ 2 * sizeof( DescriptorEndpoint_0 );
else //for WIN2K
uSize = sizeof( DescriptorConfiguration );
uPos = 0;
rEP0_CSR = ( ustatus_EP0_CSR & ( BIT_EP0_WR_BITS )
| BIT_EP0_CSR_SERVICED_OUT_PKT_RDY );
break;
case TYPE_INTERFACE:
DbgPrintf( "GT_IF\n" );
pBuffer = ( U8 * )&DescriptorInterface;
uSize = sizeof( DescriptorInterface );
uPos = 0;
rEP0_CSR = ( ustatus_EP0_CSR & ( BIT_EP0_WR_BITS )
| BIT_EP0_CSR_SERVICED_OUT_PKT_RDY );
break;
case TYPE_ENDPOINT:
DbgPrintf( "GT_EP\n" );
switch( SetupData.bValueL & 0xf )
{
case 0:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -