📄 usbdev.c
字号:
// This is function for Control Transfer.
// If it occurs endpoint0 interrupt, this function is called.
// This function check Device Request for Control Transfer type and
// call each other functions.
// ======================================================================
void HandleEvent_EP0(void)
{
U32 DeviceRequestLength;
U16 ep0csr;
U16 ReadCnt, i;
U16 ReadBuf[64]={0x0000, };
U8 setaddress;
U32 uRemoteWakeUp;
U16 usConfig;
U32 tmp;
//test
#define TEST_PKT_SIZE 53
#define TEST_ARR_SIZE 54
U8 ahwTestPkt [TEST_ARR_SIZE] = {
0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00,
0xAA,0x00, 0xAA,0xAA, 0xAA,0xAA, 0xAA,0xAA,
0xEE,0xAA, 0xEE,0xEE, 0xEE,0xEE, 0xEE,0xEE,
0xFE,0xEE, 0xFF,0xFF, 0xFF,0xFF, 0xFF,0xFF,
0xFF,0xFF, 0xFF,0xFF, 0x7F,0xFF, 0xDF,0xBF,
0xF7,0xEF, 0xFD,0xFB, 0x7E,0xFC, 0xDF,0xBF,
0xF7,0xEF, 0xFD,0xFB, 0x00,0x7E
};
Outp32(INDEX_REG, EP0);
Inp32(EP0_STATUS_REG, ep0csr);
DbgUsb((" Endpoint0 CSR Register = %x \n", ep0csr));
// EP0 CSR register status check
if (ep0csr & EP0_SENT_STALL) // SENT STALL : protocol stall.
{
DbgUsb((" Sent Stall \n"));
Outp32(EP0_STATUS_REG, EP0_SENT_STALL);
if (ep0csr & EP0_RX_SUCCESS)
Outp32(EP0_STATUS_REG, EP0_RX_SUCCESS);
g_uEp0State = EP0_STATE_INIT;
return;
}
if (ep0csr & EP0_TX_SUCCESS)
{
DbgUsb((" EP0_TX_SUCCESS \n"));
Outp32(EP0_STATUS_REG, EP0_TX_SUCCESS);
}
DbgUsb((" g_uEp0State = %x \n", g_uEp0State));
if (g_uEp0State == EP0_STATE_INIT)
{
Inp32(BYTE_READ_CNT_REG, ReadCnt);
for(i=0;i<4;i++) Inp32(EP0_FIFO, ReadBuf[i]);
Outp32(EP0_STATUS_REG, EP0_RX_SUCCESS);
g_poDeviceRequest->bmRequestType=ReadBuf[0];
g_poDeviceRequest->bRequest=ReadBuf[0]>>8;
g_poDeviceRequest->wValue_L=ReadBuf[1];
g_poDeviceRequest->wValue_H=ReadBuf[1]>>8;
g_poDeviceRequest->wIndex_L=ReadBuf[2];
g_poDeviceRequest->wIndex_H=ReadBuf[2]>>8;
g_poDeviceRequest->wLength_L=ReadBuf[3];
g_poDeviceRequest->wLength_H=ReadBuf[3]>>8;
PrintEp0Pkt((U8 *)g_poDeviceRequest, 8);
switch (g_poDeviceRequest->bRequest)
{
case STANDARD_SET_ADDRESS:
setaddress = (g_poDeviceRequest->wValue_L); // Set Address Update bit
DbgUsb(("Func_ADDR_Setaddr : %d \n", setaddress));
g_uEp0State = EP0_STATE_INIT;
break;
case STANDARD_SET_DESCRIPTOR:
DbgUsb(("\n MCU >> Set Descriptor \n"));
break;
case STANDARD_SET_CONFIGURATION:
DbgUsb(("\n MCU >> Set Configuration \n"));
usConfig = g_poDeviceRequest->wValue_L; // Configuration value in configuration descriptor
g_uEnumerationDone = 1;
break;
case STANDARD_GET_CONFIGURATION:
// Uart_Printf("\n MCU >> Get Configruation \n");
Outp32(BYTE_WRITE_CNT_REG, 1);
Outp32(EP0_FIFO, usConfig);
break;
case STANDARD_GET_DESCRIPTOR:
switch (g_poDeviceRequest->wValue_H)
{
case DEVICE_DESCRIPTOR:
DbgUsb(("\n MCU >> Get Device Descriptor \n"));
g_uEp0State = EP0_STATE_GD_DEV_0;
break;
case CONFIGURATION_DESCRIPTOR:
DbgUsb(("\n MCU >> Get Configuration Descriptor \n"));
DeviceRequestLength = (U32)((g_poDeviceRequest->wLength_H << 8) |
g_poDeviceRequest->wLength_L);
if (DeviceRequestLength > CONFIG_DESC_SIZE){
// === GET_DESCRIPTOR:CONFIGURATION+INTERFACE+ENDPOINT0+ENDPOINT1 ===
// Windows98 gets these 4 descriptors all together by issuing only a request.
// Windows2000 gets each descriptor seperately.
g_uEp0State = EP0_STATE_GD_CFG_0;
}
else
g_uEp0State = EP0_STATE_GD_CFG_ONLY_0; // for win2k
break;
case STRING_DESCRIPTOR :
switch(g_poDeviceRequest->wValue_L)
{
case 0:
g_uEp0State = EP0_STATE_GD_STR_I0;
break;
case 1:
g_uEp0State = EP0_STATE_GD_STR_I1;
break;
case 2:
g_uEp0State = EP0_STATE_GD_STR_I2;
break;
default:
break;
}
break;
case ENDPOINT_DESCRIPTOR:
switch(g_poDeviceRequest->wValue_L&0xf)
{
case 0:
g_uEp0State=EP0_STATE_GD_EP0_ONLY_0;
break;
case 1:
g_uEp0State=EP0_STATE_GD_EP1_ONLY_0;
break;
default:
break;
}
break;
case DEVICE_QUALIFIER:
DbgUsb(("\n MCU >> Get Device Qualifier Descriptor \n"));
g_uEp0State = EP0_STATE_GD_DEV_QUALIFIER;
break;
}
break;
case STANDARD_CLEAR_FEATURE:
DbgUsb(("\n MCU >> Clear Feature \n"));
switch (g_poDeviceRequest->bmRequestType)
{
case DEVICE_RECIPIENT:
if (g_poDeviceRequest->wValue_L == 1)
uRemoteWakeUp = FALSE;
break;
case ENDPOINT_RECIPIENT:
if (g_poDeviceRequest->wValue_L == 0)
{
if ((g_poDeviceRequest->wIndex_L & 0x7f) == 0x00)
g_poStatusGet->Endpoint0= 0;
if ((g_poDeviceRequest->wIndex_L & 0x8f) == 0x01) // IN Endpoint 1
g_poStatusGet->Endpoint1= 0;
if ((g_poDeviceRequest->wIndex_L & 0x8f) == 0x03) // OUT Endpoint 3
g_poStatusGet->Endpoint3= 0;
}
break;
default:
break;
}
g_uEp0State = EP0_STATE_INIT;
break;
case STANDARD_SET_FEATURE:
DbgUsb(("\n MCU >> Set Feature \n"));
switch (g_poDeviceRequest->bmRequestType)
{
case DEVICE_RECIPIENT:
if (g_poDeviceRequest->wValue_L == 1)
uRemoteWakeUp = TRUE;
break;
case ENDPOINT_RECIPIENT:
if (g_poDeviceRequest->wValue_L == 0)
{
if ((g_poDeviceRequest->wIndex_L & 0x7f) == 0x00)
g_poStatusGet->Endpoint0= 1;
if ((g_poDeviceRequest->wIndex_L & 0x8f) == 0x01)
g_poStatusGet->Endpoint1= 1;
if ((g_poDeviceRequest->wIndex_L & 0x8f) == 0x03)
g_poStatusGet->Endpoint3= 1;
}
break;
default:
break;
}
//=======================================================
switch (g_poDeviceRequest->wValue_L) {
case EP_STALL:
// TBD: addnl processing if reqd
break;
case TEST_MODE:
if ((0 != g_poDeviceRequest->wIndex_L ) ||(0 != g_poDeviceRequest->bmRequestType))
break;
// Set TEST MODE
Inp32(TEST_REG,tmp);
tmp|=TR_TMD;
Outp32(TEST_REG,TR_TMD);
switch( g_poDeviceRequest->wIndex_H)
{
case TEST_J:
//Set Test J
Inp32(TEST_REG,tmp);
tmp|=TR_TJS;
Outp32(TEST_REG,tmp);
break;
case TEST_K:
//Set Test K
Inp32(TEST_REG,tmp);
tmp|=TR_TKS;
Outp32(TEST_REG,tmp);
break;
case TEST_SE0_NAK:
//Set Test SE0NAK
Inp32(TEST_REG,tmp);
tmp|=TR_TSNS;
Outp32(TEST_REG,tmp);
break;
case TEST_PACKET:
printf ("Test_packet\n");
Outp32(BYTE_WRITE_CNT_REG, 54);
WrPktEp0(ahwTestPkt, TEST_PKT_SIZE);
Inp32(TEST_REG,tmp);
tmp|=TR_TPS;
Outp32(TEST_REG,tmp);
printf ("tr=%0X\n", tmp);
break;
}
break;
default:
break;
}
//=======================================================
g_uEp0State = EP0_STATE_INIT;
break;
case STANDARD_GET_STATUS:
switch(g_poDeviceRequest->bmRequestType)
{
case (0x80):
g_poStatusGet->Device=((U8)uRemoteWakeUp<<1)|0x1; // SelfPowered
g_uEp0State = EP0_GET_STATUS0;
break;
case (0x81):
g_poStatusGet->Interface=0;
g_uEp0State = EP0_GET_STATUS1;
break;
case (0x82):
if ((g_poDeviceRequest->wIndex_L & 0x7f) == 0x00)
g_uEp0State = EP0_GET_STATUS2;
if ((g_poDeviceRequest->wIndex_L & 0x8f) == 0x01)
g_uEp0State = EP0_GET_STATUS3;
if ((g_poDeviceRequest->wIndex_L & 0x8f) == 0x03)
g_uEp0State = EP0_GET_STATUS4;
break;
default:
break;
}
break;
case STANDARD_GET_INTERFACE:
g_uEp0State = EP0_INTERFACE_GET;
break;
case STANDARD_SET_INTERFACE:
g_poInterfaceGet->AlternateSetting= g_poDeviceRequest->wValue_L;
g_uEp0State = EP0_STATE_INIT;
break;
case STANDARD_SYNCH_FRAME:
g_uEp0State = EP0_STATE_INIT;
break;
default:
break;
}
}
TransferEp0();
}
// Not Supporting About Set Descriptor for USB Standard
void StandardSetDescriptor(void)
{
// CLR_EP0_CSR_OUT_PACKET_READY;
}
// ======================================================================
// TransferEp0()
//
// This is function for Control Transfer Transmit.
// ======================================================================
void TransferEp0(void)
{
U32 i;
U32 dataLength;
U16 usSysStatus;
// CLR_EP0_CSR_OUT_PACKET_READY;
switch (g_uEp0State)
{
case EP0_STATE_INIT:
break;
// === GET_DESCRIPTOR:DEVICE ===
case EP0_STATE_GD_DEV_0:
if (g_eSpeed == 1)
{
Outp32(BYTE_WRITE_CNT_REG, 18);
WrPktEp0((U8 *)g_poDescDevice+0, 18); // EP0_PKT_SIZE
g_uEp0State = EP0_STATE_INIT;
DbgUsb(("EndpointZeroTransfer(EP0_STATE_GD_DEV)\n"));
}
else
{
Outp32(BYTE_WRITE_CNT_REG, 8);
WrPktEp0((U8 *)g_poDescDevice+0, 8); // EP0_PKT_SIZE
g_uEp0State = EP0_STATE_GD_DEV_1;
DbgUsb(("EndpointZeroTransfer(EP0_STATE_GD_DEV_0)\n"));
}
break;
case EP0_STATE_GD_DEV_1:
Outp32(BYTE_WRITE_CNT_REG, 8);
WrPktEp0((U8 *)g_poDescDevice+8, 8); // EP0_PKT_SIZE
g_uEp0State = EP0_STATE_GD_DEV_2;
DbgUsb(("EndpointZeroTransfer(EP0_STATE_GD_DEV_1)\n"));
break;
case EP0_STATE_GD_DEV_2:
Outp32(BYTE_WRITE_CNT_REG, 2);
WrPktEp0((U8 *)g_poDescDevice+16, 2); // EP0_PKT_SIZE
g_uEp0State = EP0_STATE_INIT;
DbgUsb(("EndpointZeroTransfer(EP0_STATE_GD_DEV_2)\n"));
break;
// === GET_DESCRIPTOR:CONFIGURATION+INTERFACE+ENDPOINT0+ENDPOINT1 ===
// Windows98 gets these 4 descriptors all together by issuing only a request.
// Windows2000 gets each descriptor seperately.
// === GET_DESCRIPTOR:CONFIGURATION ONLY for WIN2K===
case EP0_STATE_GD_CFG_0:
if (g_eSpeed == 1)
{
Outp32(BYTE_WRITE_CNT_REG, 32);
WrPktEp0((U8 *)&g_poDesc->oDescConfig+0, 32); // EP0_PKT_SIZE
g_uEp0State = EP0_STATE_INIT;
DbgUsb(("EndpointZeroTransfer(EP0_STATE_GD_CFG)\n"));
}
else
{
Outp32(BYTE_WRITE_CNT_REG, 8);
WrPktEp0((U8 *)&g_poDesc->oDescConfig+0, 8); // EP0_PKT_SIZE
g_uEp0State = EP0_STATE_GD_CFG_1;
DbgUsb(("EndpointZeroTransfer(EP0_STATE_GD_CFG_0)\n"));
}
break;
case EP0_STATE_GD_CFG_1:
Outp32(BYTE_WRITE_CNT_REG, 8);
WrPktEp0((U8 *)&g_poDesc->oDescConfig+8, 8); // EP0_PKT_SIZE WrPktEp0((U8 *)&descConf+8, 1); WrPktEp0((U8 *)&descIf+0, 7);
g_uEp0State = EP0_STATE_GD_CFG_2;
break;
case EP0_STATE_GD_CFG_2:
Outp32(BYTE_WRITE_CNT_REG, 8);
WrPktEp0((U8 *)&g_poDesc->oDescConfig+16, 8); // EP0_PKT_SIZE WrPktEp0((U8 *)&descIf+7, 2); WrPktEp0((U8 *)&descEndpt0+0, 6);
g_uEp0State = EP0_STATE_GD_CFG_3;
break;
case EP0_STATE_GD_CFG_3:
Outp32(BYTE_WRITE_CNT_REG, 8);
WrPktEp0((U8 *)&g_poDesc->oDescConfig+24, 8); // EP0_PKT_SIZE WrPktEp0((U8 *)&descEndpt0+6, 1); WrPktEp0((U8 *)&descEndpt1+0, 7);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -