📄 phc_hcs.c
字号:
PHC_ResetPort(DnPort);
Hal4Sys_WaitinMS(20); // reset Recovery Time >10ms
}
void HcS_InitPHC(void)
{
SLH_REG_ULONG SlhReg;
USHORT i;
// Initialize HcS_CtrlBlock;
HcS_InitPHCInfo();
//Reset HC+OTG
Hal4Hc_RegOutW(REG_RESET_DEV,0xF6);
Hal4Sys_WaitinMS(5);
// set INT1 active high for ISA kit
if( ISP1362_ISAKIT == TRUE)
{
Hal4Hc_RegOutW(REG_HW_MODE, 0x2c);
}
//Reset PHC
SlhReg.SlhCommand.Bits.SoftReset = 1;
PHC_Command(SlhReg.FlexLong);
Hal4Sys_WaitinUS(10);
// Set SKIPMAP
Hal4Hc_RegOutDW(REG_ATL_PTD_SKIP_MAP, 0xfffffffe);
Hal4Hc_RegOutDW(REG_INTL_PTD_SKIP_MAP, 0xffffffff);
// Config ATL Buffer & ITL Buffer
// Hal4Hc_RegOutW(REG_ITL_BUFLEN,HCCNFG_ITLBUFLEN);// 1KBytes
// Hal4Hc_RegOutW(REG_ATL_BUFLEN,HCCNFG_ATLBUFLEN);// 2KBytes
Hal4Hc_RegOutW(REG_ISTL_BUFF_SIZE,HCCNFG_ITLBUFLEN);// 1KBytes
Hal4Hc_RegOutW(REG_ATL_BUFF_SIZE,HCCNFG_ATLBUFLEN);// 2KBytes
// Clear HC Buffer Memory
Hal4Hc_RegOutDW(REG_DIRECT_ADDRESS_LENGTH,0x0fff0000); //start from 0, total 4k
Hal4Hc_CommandOutW(REG_DIRECT_ADDRESS_DATA|0x80); //HcDirectAdressData Reg
for(i=0;i<0xfff;i++)
{
Hal4Hc_DataOutW(0x0);
}
// Config OHC-ITCL RootHub Descriptor_A
SlhReg.SlhRootHubDescriptorA.Bits.NumOfDnPorts = 2;
SlhReg.SlhRootHubDescriptorA.Bits.NoPowerSwitch = 0; // 1:NoPowerSwitch/0:PowerSwitch
SlhReg.SlhRootHubDescriptorA.Bits.PowerSwitchMode = 1; // 1:PerPort/0:Global
SlhReg.SlhRootHubDescriptorA.Bits.DeviceType = 0;
SlhReg.SlhRootHubDescriptorA.Bits.OvrCurProtectMode = 0;
SlhReg.SlhRootHubDescriptorA.Bits.NoOvrCurProtect = 0;
SlhReg.SlhRootHubDescriptorA.Bits.PowerOn2PowerGoodTime = 0x80; //in 2ms = 256 ms
PHC_ConfigRootHubDescA(SlhReg.FlexLong);
// Config OHC-ITCL RootHub Descriptor_B
SlhReg.SlhRootHubDescriptorB.Bits.DeviceRemovableMap = 0;
SlhReg.SlhRootHubDescriptorB.Bits.PortPowerControlMask = 0x06; // 1:PerPort/0:Global
PHC_ConfigRootHubDescB(SlhReg.FlexLong);
// Config Frame
SlhReg.SlhFrameInterval.Bits.FrameInterval = MAX_FRAMEINTERVAL; //0x2edf == 11999bits, fixed at 1.5KBytes
SlhReg.SlhFrameInterval.Bits.FrameLargestPktSize = (MAX_FRAMEINTERVAL-MAX_OVRHEAD)*6L/7L;//bits, = 1023Bytes
SlhReg.SlhFrameInterval.Bits.FrameIntervalToggel = 0;
PHC_ConfigFrame(SlhReg.FlexLong);
// Config LS Threshold
SlhReg.SlhFrameLSThreashold.Bits.LSThreshold = 0x1000; // >0628h
SlhReg.SlhFrameLSThreashold.Bits.Reserv0 = 0;
SlhReg.SlhFrameLSThreashold.Bits.Reserv1 = 0;
PHC_ConfigLSThreashold(SlhReg.FlexLong);
// Enable all interrupts MIE_DISABLE is set to 1 after Reset
SlhReg.SlhIntEnable.Bits.ScheduleOverrun = FALSE;
SlhReg.SlhIntEnable.Bits.ATLisDone = FALSE;
SlhReg.SlhIntEnable.Bits.SOF = FALSE;
SlhReg.SlhIntEnable.Bits.ResumeDeteced = FALSE;
SlhReg.SlhIntEnable.Bits.FatalError = FALSE;
SlhReg.SlhIntEnable.Bits.FrameNumOverflow = FALSE;
SlhReg.SlhIntEnable.Bits.RootHubStatusChange = TRUE;
SlhReg.SlhIntEnable.Bits.MasterInterrupt = TRUE;
PHC_EnableInterrupts(SlhReg.FlexLong);
// Disable all interrupts MIE_DISABLE is set to 1 after Reset
SlhReg.SlhIntDisable.Bits.ScheduleOverrun = 1;
SlhReg.SlhIntDisable.Bits.ATLisDone = 1;
SlhReg.SlhIntDisable.Bits.SOF = 1;
SlhReg.SlhIntDisable.Bits.ResumeDeteced = 1;
SlhReg.SlhIntDisable.Bits.FatalError = 1;
SlhReg.SlhIntDisable.Bits.FrameNumOverflow = 1;
SlhReg.SlhIntDisable.Bits.RootHubStatusChange = 1;
SlhReg.SlhIntDisable.Bits.MasterInterrupt = 1;
PHC_DisableInterrupts(SlhReg.FlexLong);
//Initiliaze port 1&2
SlhReg.SlhRootHubPortStatusWr.Bits.ClearPortEnable = TRUE;
SlhReg.SlhRootHubPortStatusWr.Bits.SetPortEnable = FALSE;
SlhReg.SlhRootHubPortStatusWr.Bits.SetPortSuspend= FALSE;
SlhReg.SlhRootHubPortStatusWr.Bits.ClearPortSuspend = TRUE;
SlhReg.SlhRootHubPortStatusWr.Bits.SetPortReset = FALSE;
SlhReg.SlhRootHubPortStatusWr.Bits.SetPortPower = TRUE;
SlhReg.SlhRootHubPortStatusWr.Bits.ClearPortPower= FALSE;
SlhReg.SlhRootHubPortStatusWr.Bits.ClearConnectStatusChange = TRUE;
SlhReg.SlhRootHubPortStatusWr.Bits.ClearPortStatusChange = TRUE;
SlhReg.SlhRootHubPortStatusWr.Bits.ClearPortSuspendStatusChange = TRUE;
SlhReg.SlhRootHubPortStatusWr.Bits.ClearPortOvrCurIndicatorChange = TRUE;
SlhReg.SlhRootHubPortStatusWr.Bits.ClearPortResetStatusChange = TRUE;
PHC_SetRootHubPort( 2, SlhReg.FlexLong);
PHC_SetRootHubPort( 1, SlhReg.FlexLong);
Hal4Sys_WaitinMS(100); // USB1.1 reset Recovery Time >10ms
// Start OHC-ITCL
SlhReg.SlhControl.Bits.Reserv0 = 0x0;
SlhReg.SlhControl.Bits.HcFuncState = SLHR_CTRL_HCFS_OP;
SlhReg.SlhControl.Bits.RemoteWakeupConnect = 1;
SlhReg.SlhControl.Bits.RemoteWakeupEnable = 1;
PHC_Control(SlhReg.FlexLong);
}
UCHAR HcS_CheckDnDevs(USHORT DnPort)
{
USHORT i = DnPort;
SLH_REG_ULONG SlhReg;
// HcS_CtrlBlock.byNumOfDevAttached = 0;
// for( i = 1; i <= HcS_CtrlBlock.byDownPortsNum; i ++)
// {
SlhReg.FlexLong = PHC_PollRootHubPort(i);
if(SlhReg.SlhRootHubPortStatus.Bits.CurrentConnectStatusChange)
{
if(SlhReg.SlhRootHubPortStatus.Bits.CurrentConnectStatus)
{
// HcS_CtrlBlock.byNumOfDevAttached ++;
HcS_SetConnectBitmap(i,TRUE);
if(SlhReg.SlhRootHubPortStatus.Bits.LSDeviceAttached)
{
HcS_SetSpeedBitmap(i,PTD_SPEED_LS);
printf("OTG Port: Low Speed USB Device attached.\n");
}
else
{
HcS_SetSpeedBitmap(i,PTD_SPEED_FS);
printf("OTG Port: Full Speed USB Device attached.\n");
}
}
else
{
HcS_SetConnectBitmap(i,FALSE);
printf("OTG Port: USB Device dettached.\n");
}
}
else
{
if(SlhReg.SlhRootHubPortStatus.Bits.CurrentConnectStatus)
{
// HcS_CtrlBlock.byNumOfDevAttached ++;
HcS_SetConnectBitmap(i,TRUE);
if(SlhReg.SlhRootHubPortStatus.Bits.LSDeviceAttached)
{
HcS_SetSpeedBitmap(i,PTD_SPEED_LS);
printf("OTG Port: Low Speed USB Device still attached\n");
}
else
{
HcS_SetSpeedBitmap(i,PTD_SPEED_FS);
printf("OTG Port: Full Speed USB Device still attached\n");
}
}
else
{
HcS_SetConnectBitmap(i,FALSE);
printf("OTG Port: No USB Device attached.\n");
}
// }
}
// printf("%d Device[s] are attached and Bitmap=0x%x\n",HcS_CtrlBlock.byNumOfDevAttached, HcS_CtrlBlock.bmDevAttached.FlexByte);
return HcS_CtrlBlock.bmDevAttached.FlexByte;
}
BOOLEAN Hc_CnfgDnPortDev(UCHAR DnPort)
{
UCHAR DevAddr = 0;
UCHAR NewDevAddr = 0;
UCHAR PktSize;
UCHAR Speed;
UCHAR Connect;
PVOID Ptr2Descrip ;
UCHAR index;
BOOL Enum_OK = TRUE;
Speed = HcS_GetDevSpeedAtDnPort(DnPort);
PktSize = HcS_CtrlBlock.strucDnPortDev[DnPort].byEndp0PktSize;
// Set ATL
Hal4Hc_RegOutDW(REG_ATL_PTD_SKIP_MAP, 0xfffffffe);
Hal4Hc_RegOutW(REG_ATL_BLK_SIZE, 0x40);
// GetDeviceDescriptor
printf("HC: Get Device Descriptor @default address ... ");
if(TRUE == UsbStd_GetDescrip(
DevAddr,
Speed,
8,//HcS_CtrlBlock.strucDnPortDev[DnPort].byEndp0PktSize, // PktSize
USB_DEVICE_DESCRIPTOR_TYPE,// byDescriptorType
0, // byDescriptorIndex
0, // wLanguageID
8 //wLength
)
)
{
Ptr2Descrip = (PUSB_DEVICE_DESCRIPTOR) &HcS_UsbDataInStage.Payload;
PktSize = ((PUSB_DEVICE_DESCRIPTOR)Ptr2Descrip)->bMaxPacketSize0;
if( PktSize != 8 && PktSize != 16 && PktSize != 32 && PktSize != 64)
{
PktSize = 64;
}
HcS_CtrlBlock.strucDnPortDev[DnPort].byEndp0PktSize = PktSize;
printf("done.\n");
// USB_StructDescriptorPrnProcessor(USB_DEVICE_DESCRIPTOR_TYPE);
}
else
{
printf("fail!!!\n");
Enum_OK = FALSE;
}
if(Enum_OK == TRUE)
{
// SetAddress
if(OtgTcb.id == 0) //A-device
{
NewDevAddr = 0xB;
printf("HC: Set Address to 0xB ... ");
}
else //B-device
{
NewDevAddr = 0xA;
printf("HC: Set Address to 0xA ... ");
}
if( TRUE == UsbStd_SetAddress(
DevAddr,
Speed,
PktSize,
NewDevAddr
)
)
{
printf("done.\n");
OtgTcb.DevAddr = NewDevAddr;
}
else
{
printf("fail!!!\n");
Enum_OK = FALSE;
}
}
if(Enum_OK == TRUE)
{
Hal4Sys_WaitinMS(5); //Spec requires >= 2 ms.
// GetDeviceDescriptor
printf("HC: Get Device Descriptor @address 0x%X ... ",NewDevAddr);
if(TRUE == UsbStd_GetDescrip(
NewDevAddr,
Speed,
PktSize, // PktSize
USB_DEVICE_DESCRIPTOR_TYPE,// byDescriptorType
0, // byDescriptorIndex
0, // wLanguageID
MAX_PAYLOAD //wLength
)
)
{
Ptr2Descrip = (PUSB_DEVICE_DESCRIPTOR) &HcS_UsbDataInStage.Payload;
HcS_CtrlBlock.strucDnPortDev[DnPort].byDevCnfgNum = ((PUSB_DEVICE_DESCRIPTOR)Ptr2Descrip)->bNumConfigurations;
HcS_CtrlBlock.strucDnPortDev[DnPort].uVendorID = ((PUSB_DEVICE_DESCRIPTOR)Ptr2Descrip)->idVendor;
HcS_CtrlBlock.strucDnPortDev[DnPort].uProductID = ((PUSB_DEVICE_DESCRIPTOR)Ptr2Descrip)->idProduct;
HcS_CtrlBlock.strucDnPortDev[DnPort].byManufaturerIndex = ((PUSB_DEVICE_DESCRIPTOR)Ptr2Descrip)->iManufacturer;
HcS_CtrlBlock.strucDnPortDev[DnPort].byProductIndex = ((PUSB_DEVICE_DESCRIPTOR)Ptr2Descrip)->iProduct;
HcS_CtrlBlock.strucDnPortDev[DnPort].bySerialNumberIndex = ((PUSB_DEVICE_DESCRIPTOR)Ptr2Descrip)->iSerialNumber;
printf("done.\n");
// USB_StructDescriptorPrnProcessor(USB_DEVICE_DESCRIPTOR_TYPE);
/* printf(" -- Vendor ID: %4X, Product ID: %4X\n", \
HcS_CtrlBlock.strucDnPortDev[DnPort].uVendorID, \
HcS_CtrlBlock.strucDnPortDev[DnPort].uProductID);*/
OtgTcb.VendorID = HcS_CtrlBlock.strucDnPortDev[DnPort].uVendorID;
OtgTcb.ProductID = HcS_CtrlBlock.strucDnPortDev[DnPort].uProductID;
}
else
{
printf("fail!!!\n");
Enum_OK = FALSE;
}
}
if(Enum_OK == TRUE)
{
printf("HC: Get Configuration Descriptor ... ");
if(TRUE == UsbStd_GetDescrip(
NewDevAddr,
Speed,
PktSize, // PktSize
USB_CONFIGURATION_DESCRIPTOR_TYPE,// byDescriptorType
0, // byDescriptorIndex
0, // wLanguageID
MAX_PAYLOAD //wLength
)
)
{
Ptr2Descrip = (PUSB_CONFIGURATION_DESCRIPTOR) &HcS_UsbDataInStage.Payload;
HcS_CtrlBlock.strucDnPortDev[DnPort].byDevIFNum = ((PUSB_CONFIGURATION_DESCRIPTOR)Ptr2Descrip)->bNumInterfaces;
HcS_CtrlBlock.strucDnPortDev[DnPort].byConfigurationIndex = ((PUSB_CONFIGURATION_DESCRIPTOR)Ptr2Descrip)->iConfiguration;
HcS_CtrlBlock.strucDnPortDev[DnPort].bmAttributes = ((PUSB_CONFIGURATION_DESCRIPTOR)Ptr2Descrip)->bmAttributes;
HcS_CtrlBlock.strucDnPortDev[DnPort].byMaxPower = ((PUSB_CONFIGURATION_DESCRIPTOR)Ptr2Descrip)->MaxPower;
printf("done.\n");
// USB_StructDescriptorPrnProcessor(USB_CONFIGURATION_DESCRIPTOR_TYPE);
}
else
{
printf("fail!!!\n");
Enum_OK = FALSE;
}
}
if(Enum_OK == TRUE && OtgTcb.id == 0) //for A device only
{
HcS_GetOTGDescriptor(NewDevAddr,Speed,PktSize);
}
if(Enum_OK == TRUE)
{
// GetConfiguration
printf("HC: Get Configuration @Config ... ");
if( TRUE == UsbStd_GetCnfg(
NewDevAddr,
Speed,
PktSize
)
)
{
printf("%d.\n",HcS_UsbDataInStage.Payload[0]);
}
else
{
printf("fail!!!\n");
Enum_OK = FALSE;
}
}
if(Enum_OK == TRUE)
{
// SetConfiguration
printf("HC: Set Configuration @Config 1 ... ");
if( TRUE == UsbStd_SetCnfg(
NewDevAddr,
Speed,
PktSize,
1 //Cnfg
)
)
{
printf("done.\n");
}
else
{
printf("fail!!!\n");
Enum_OK = FALSE;
}
}
#if 0
if(Enum_OK == TRUE)
{
// GetStringDescriptor-LanguageID
printf("HC: Get Language String Descriptor ...");
if(TRUE == UsbStd_GetDescrip(
NewDevAddr,
Speed,
PktSize, // PktSize
USB_STRING_DESCRIPTOR_TYPE,// byDescriptorType
STR_INDEX_LANGUAGE, // byDescriptorIndex
0, // wLanguageID
MAX_PAYLOAD //wLength
)
)
{
printf("done.\n");
// USB_StringDescriptorPrinter(STR_INDEX_LANGUAGE);
}
else
{
printf("fail!!!\n");
// Enum_OK = FALSE;
}
}
#endif
#if 0
if(Enum_OK == TRUE)
{
// GetStringDescriptor-Manufacturer
index = HcS_CtrlBlock.strucDnPortDev[DnPort].byManufaturerIndex;
if( 0 != index)
{
printf("HC: Get Manufacturer String Descriptor ... ");
if(TRUE == UsbStd_GetDescrip(
NewDevAddr,
Speed,
PktSize, // PktSize
USB_STRING_DESCRIPTOR_TYPE,// byDescriptorType
index, // byDescriptorIndex
0, // wLanguageID
MAX_PAYLOAD //wLength
)
)
{
printf("done.\n");
// USB_StringDescriptorPrinter(STR_INDEX_MANUFACTURER);
}
else
{
printf("fail!!!\n");
// Enum_OK = FALSE;
}
}
}
if(Enum_OK == TRUE)
{
// GetStringDescriptor-Product
index = HcS_CtrlBlock.strucDnPortDev[DnPort].byProductIndex;
if( 0 != index)
{
printf("HC: Get Product String Descriptor ... ");
if(TRUE == UsbStd_GetDescrip(
NewDevAddr,
Speed,
PktSize, // PktSize
USB_STRING_DESCRIPTOR_TYPE,// byDescriptorType
index, // byDescriptorIndex
0, // wLanguageID
MAX_PAYLOAD //wLength
)
)
{
printf("done.\n");
// printf("HC: ");
// USB_StringDescriptorPrinter(STR_INDEX_PRODUCT);
}
else
{
printf("fail!!!\n");
// Enum_OK = FALSE;
}
}
}
if(Enum_OK == TRUE)
{
// GetStringDescriptor-SerialNum
index = HcS_CtrlBlock.strucDnPortDev[DnPort].bySerialNumberIndex;
if( 0 != index)
{
printf("HC: Get Serial Number String Descriptor ... ");
if(TRUE == UsbStd_GetDescrip(
NewDevAddr,
Speed,
PktSize, // PktSize
USB_STRING_DESCRIPTOR_TYPE,// byDescriptorType
index, // byDescriptorIndex
0, // wLanguageID
MAX_PAYLOAD //wLength
)
)
{
printf("done.\n");
// printf("HC: ");
// USB_StringDescriptorPrinter(STR_INDEX_SERIALNUMBER);
}
else
{
printf("fail!!!\n");
// Enum_OK = FALSE;
}
}
}
#endif
return Enum_OK;
} //End of Hc_CnfgDnPortDev()
BOOLEAN HcS_EnumPHCDevs(void)
{
USHORT DownPort;
DownPort = OTG_PORT;
// Hal4Sys_WaitinMS(100); //long debounce
// Check out Downstream Device Attachment status
HcS_CheckDnDevs(DownPort);
// Reset the OTG Port
PHC_ResetPort(DownPort);
Hal4Sys_WaitinMS(20); // reset Recovery Time >10ms
// Enumerate the device
return Hc_CnfgDnPortDev(DownPort);
}
void HcS_AcquireHC(void)
{
RaiseIRQL();
bIRQL = 1;
Hal4ISA_AcquirePIO4HC();
Hal4ISA_AcquireDMA4HC();
// Hal4ISA_AcquireIRQ4HC();
HcS_InitPHC();
bIRQL = 0;
LowerIRQL();
}
void HcS_ReleaseHC(void)
{
RaiseIRQL();
bIRQL = 1;
HcS_InitPHC();
Hal4ISA_ReleasePIO4HC();
Hal4ISA_ReleaseDMA4HC();
// Hal4ISA_ReleaseIRQ4HC();
bIRQL = 0;
LowerIRQL();
}
void HcS_GetOTGDescriptor(UCHAR DevAddr,UCHAR Speed,UCHAR PktSize)
{
PVOID Ptr2Descrip ;
UCHAR OTG_byte;
//GetHNPCapabilityDescriptor - Set/Clear OtgTcb.b_hnp_support bit
printf("HC: Get OTG Descriptor ... ");
if(TRUE == UsbStd_GetDescrip(
DevAddr,
Speed,
PktSize, // PktSize
USB_OTG_DESCRIPTOR_TYPE,// byDescriptorType
0, // byDescriptorIndex
0, // wLanguageID
3 //wLength
)
)
{
Ptr2Descrip = (PUSB_OTG_DESCRIPTOR) &HcS_UsbDataInStage.Payload;
OTG_byte = ((PUSB_OTG_DESCRIPTOR)Ptr2Descrip)->bmAttribute;
printf("done.\n");
// printf("OTG_byte=%x\n",OTG_byte);
if( ( OTG_byte & 0x1) )
{
OtgTcb.b_hnp_support = 1;
OtgTcb.b_srp_support = 1;
// printf(" -- Remote Device is HNP/SRP support!\n");
}
else if( OTG_byte & 0x2 )
{
OtgTcb.b_hnp_support = 0;
OtgTcb.b_srp_support = 1;
// printf(" -- Remote Device is SRP support!\n");
}
else
{
OtgTcb.b_hnp_support = 0;
OtgTcb.b_srp_support = 0;
// printf(" -- Remote Device is Slave Only!\n");
}
}
else
{
OtgTcb.b_hnp_support = 0;
OtgTcb.b_srp_support = 0;
printf("failed.\n");
// printf(" -- Remote Device is Slave Only!\n");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -