📄 bul_usbfn.cpp
字号:
MmUnmapIoSpace((PVOID)m_pUsbDevReg,0UL);
}
if (m_pDCCLKReg) {
m_pDCCLKReg->cken &= ~XLLP_CLKEN_USBCLIENT ;
MmUnmapIoSpace(m_pDCCLKReg,0);
}
if (m_hParent)
CloseBusAccessHandle(m_hParent);
}
DWORD BulUsbDevice::Init(
PVOID pvMddContext,
PUFN_MDD_INTERFACE_INFO pMddInterfaceInfo,
PUFN_PDD_INTERFACE_INFO pPddInterfaceInfo
)
{
m_pvMddContext = pvMddContext;
m_pfnNotify = pMddInterfaceInfo->pfnNotify;
pPddInterfaceInfo->pvPddContext = this;
if ( !IsKeyOpened())
return ERROR_INVALID_DATA;
DDKISRINFO dii;
DDKWINDOWINFO dwi;
DWORD dwRet = GetWindowInfo(&dwi);
if(dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_INIT, (_T("BulUsbDevice:: DDKReg_GetWindowInfo() failed %d\r\n"), dwRet));
return dwRet;
} else if(dwi.dwNumMemWindows != 1) {
return ERROR_INVALID_DATA;
} else if (dwi.memWindows[0].dwLen < sizeof(BULVERDE_USBD_REG)) {
DEBUGMSG(ZONE_INIT, (_T("memLen of 0x%x is less than required 0x%x\r\n"),
dwi.memWindows[0].dwLen, sizeof(BULVERDE_USBD_REG)));
return ERROR_INVALID_DATA;
}
m_fIsCableAttached = FALSE;
m_fResumeOccurred = FALSE;
if (m_pDCCLKReg == NULL ) {
PHYSICAL_ADDRESS ioPhysicalBase = {BULVERDE_BASE_REG_PA_CLKMGR, 0 };
m_pDCCLKReg = (PBULVERDE_CLKMGR_REG)MmMapIoSpace(ioPhysicalBase, sizeof(BULVERDE_CLKMGR_REG),FALSE);
if (m_pDCCLKReg != NULL)
m_pDCCLKReg->cken |= XLLP_CLKEN_USBCLIENT ;
else
return ERROR_INVALID_DATA;
}
// Map Windows.
// Translate to System Address.
if (m_pUsbDevReg==NULL ) {
PHYSICAL_ADDRESS ioPhysicalBase = { dwi.memWindows[0].dwBase, 0};
m_pUsbDevReg = (PULONG) MmMapIoSpace(ioPhysicalBase, dwi.memWindows[0].dwLen,FALSE);
if (m_pUsbDevReg==NULL )
return ERROR_INVALID_DATA;
}
// get ISR configuration information
dwRet = GetIsrInfo( &dii);
if(dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_INIT, (_T("BulUsbDevice DDKReg_GetIsrInfo() failed %d\r\n"), dwRet));
return dwRet;
} else if(dii.dwSysintr == SYSINTR_NOP){
DEBUGMSG(ZONE_INIT, (_T("BulUsbDevice no SYSINTR value specified\r\n")));
return ERROR_INVALID_DATA;
};
m_dwSysIntr = dii.dwSysintr;
m_hISTEvent= CreateEvent(0,FALSE,FALSE,NULL);
if (m_hISTEvent!=NULL)
InterruptInitialize(m_dwSysIntr,m_hISTEvent,0,0);
else
return ERROR_INVALID_DATA;
// Optional Registry.
DWORD dwDataSize = sizeof(DWORD);
DWORD dwDoubleBuffer = 1;
if (!GetRegValue(BUL_USBFUNCTION_DOUBLEBUFFER_VALNAME, (LPBYTE) &dwDoubleBuffer,dwDataSize)){
dwDoubleBuffer = 1;
};
m_fDoubleBuffer = (dwDoubleBuffer==1);
// Read the IST priority
dwDataSize = sizeof(m_dwPriority);
if (!GetRegValue(BUL_USBFUNCTION_PRIORITY_VALNAME,(LPBYTE) &m_dwPriority, dwDataSize)) {
m_dwPriority = BUL_USBFUNCTION_DEFAULT_PRIORITY;
}
CeSetPriority(m_dwPriority);
if (HardwareInit()) {
ThreadStart();
if (BusChildIoControl(m_hParent,IOCTL_BUS_USBOTG_BULVERDE_GET_EVENT,&m_hOTGEvent,sizeof(m_hOTGEvent)) && m_hOTGEvent!=NULL){
m_pOTGEventThread = new BulOTGEventThread(*this,m_hOTGEvent,m_dwPriority);
if (m_pOTGEventThread && !m_pOTGEventThread->Init()){
delete m_pOTGEventThread;
m_pOTGEventThread = NULL;
}
}
return ERROR_SUCCESS;
}
else
return ERROR_INVALID_DATA;
}
BOOL BulUsbDevice::HardwareInit()
{
BOOL bReturn = TRUE;
SETFNAME();
FUNCTION_ENTER_MSG();
Lock();
// Disable Hardware
UDCCR udccr;
udccr.ulValue = ReadControlRegister();
udccr.bit.UDE= udccr.bit.EMCE = 0;
WriteControlRegister(udccr.ulValue);
WriteIntrCtr0Register(0);
WriteIntrCtr1Register(0);
// Ack all outstanding interrupt.
WriteIntrStatus0Register(0xffffffff);
WriteIntrStatus1Register(0xffffffff);
Unlock();
FUNCTION_LEAVE_MSG();
return bReturn;
}
BOOL BulUsbDevice::ReInit() // For Cable Detach & Attach , We have to re-init the Device Controller.
{
Lock();
HardwareInit();
for (DWORD dwIndex=0; dwIndex<MAX_ENDPOINT_NUMBER; dwIndex++) {
BulEndpoint *pEndpoint = ObjectIndex(dwIndex);
if (pEndpoint!=NULL) {
pEndpoint->ReInit();
pEndpoint->DeRef();
}
}
//PVOID pvMddContext = m_pvMddContext;
//m_pvMddContext = NULL;
Start();
for (dwIndex=0; dwIndex<MAX_ENDPOINT_NUMBER; dwIndex++) {
if ( RawObjectIndex(dwIndex)!=NULL) {
EnableEndpointInterrupt(dwIndex, TRUE);
}
}
Unlock();
return FALSE;
}
BOOL BulUsbDevice::DeleteAllEndpoint()
{
for (DWORD dwIndex=0; dwIndex<MAX_ENDPOINT_NUMBER; dwIndex++)
RemoveObjectBy( dwIndex );
return TRUE;
}
//
#define UDCIR0_MAX 0x10
BOOL BulUsbDevice::EnableEndpointInterrupt(DWORD dwEndpointIndex,BOOL bEnable)
{
SETFNAME();
DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Enter. dwEndpoint:0x%x,Enable:0x%x --\r\n"), pszFname,dwEndpointIndex,bEnable));
if (dwEndpointIndex < MAX_ENDPOINT_NUMBER ) {
Lock();
if (dwEndpointIndex <UDCIR0_MAX) {
DWORD dwIntrCtrBit = ((EPINT_PACKET_COMPLETE | EPINT_FIFO_ERROR) <<(dwEndpointIndex*2));
DWORD dwIntrCtl = ReadIntrCtr0Register() ;
if (bEnable)
dwIntrCtl |= dwIntrCtrBit;
else
dwIntrCtl &= ~dwIntrCtrBit;
WriteIntrCtr0Register(dwIntrCtl);
}
else {
dwEndpointIndex -= UDCIR0_MAX;
DWORD dwIntrCtrBit = ((EPINT_PACKET_COMPLETE | EPINT_FIFO_ERROR) <<(dwEndpointIndex*2));
DWORD dwIntrCtl = ReadIntrCtr1Register() ;
if (bEnable)
dwIntrCtl |= dwIntrCtl;
else
dwIntrCtl &= ~dwIntrCtl;
WriteIntrCtr1Register(dwIntrCtl);
}
Unlock();
return TRUE;
}
return FALSE;
}
DWORD BulUsbDevice::GetEndpointIntrStatus(DWORD dwEndpointIndex)
{
DWORD dwReturnStatus = 0;
if (dwEndpointIndex < MAX_ENDPOINT_NUMBER ) {
if (dwEndpointIndex <UDCIR0_MAX) {
dwReturnStatus = (ReadIntrStatus0Register()>>(dwEndpointIndex*2)) & (EPINT_PACKET_COMPLETE | EPINT_FIFO_ERROR);
}
else {
dwEndpointIndex -= MAX_ENDPOINT_NUMBER;
dwReturnStatus = (ReadIntrStatus1Register()>>(dwEndpointIndex*2)) & (EPINT_PACKET_COMPLETE | EPINT_FIFO_ERROR);
}
}
return dwReturnStatus;
}
// Interface Function.
DWORD BulUsbDevice::IsEndpointSupportable (DWORD dwEndpoint,UFN_BUS_SPEED Speed,PUSB_ENDPOINT_DESCRIPTOR pEndpointDesc,
BYTE bConfigurationValue, BYTE bInterfaceNumber, BYTE bAlternateSetting )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
DEBUGMSG(ZONE_FUNCTION, (_T("%s Enter. dwEndpoint:0x%x,Speed:0x%x --\r\n"), pszFname,dwEndpoint,Speed));
Lock();
if ((Speed & BS_FULL_SPEED)==BS_FULL_SPEED && pEndpointDesc &&
dwEndpoint < MAX_ENDPOINT_NUMBER && RawObjectIndex(dwEndpoint)==0 ) {
BulEndpoint *pEndpoint = NULL;
if (dwEndpoint == 0 ) // Endpoint Zero.
pEndpoint = new BulEndpointZero(this,m_fDoubleBuffer);
else {
if ( (pEndpointDesc->bEndpointAddress & 0x80)!=0)
pEndpoint = new BulEndpointIn(this,dwEndpoint,m_fDoubleBuffer);
else
pEndpoint = new BulEndpointOut(this,dwEndpoint,m_fDoubleBuffer);
}
if (pEndpoint && pEndpoint->Init(pEndpointDesc,bConfigurationValue,bInterfaceNumber,bAlternateSetting)) {
dwError = ERROR_SUCCESS;
InsertObject(dwEndpoint, pEndpoint) ;
}
else {
if (pEndpoint) {
delete pEndpoint;
}
}
}
Unlock();
ASSERT(dwError == ERROR_SUCCESS);
DEBUGMSG(ZONE_FUNCTION, (_T("%s return errorcode = %d --\r\n"), pszFname,dwError));
return dwError;
}
DWORD BulUsbDevice::InitEndpoint(DWORD dwEndpoint,UFN_BUS_SPEED Speed,PUSB_ENDPOINT_DESCRIPTOR pEndpointDesc,
BYTE bConfigurationValue, BYTE bInterfaceNumber, BYTE bAlternateSetting )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
BulEndpoint *pEndpoint = ObjectIndex(dwEndpoint);
if (pEndpoint) {
dwError = pEndpoint->InitEndpoint(Speed, pEndpointDesc);
pEndpoint->DeRef();
}
FUNCTION_LEAVE_MSG();
return dwError;
};
DWORD BulUsbDevice::DeinitEndpoint(DWORD dwEndpoint )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
BulEndpoint *pEndpoint = ObjectIndex(dwEndpoint);
if (pEndpoint) {
dwError = pEndpoint->DeinitEndpoint();
pEndpoint->DeRef();
}
FUNCTION_LEAVE_MSG();
return dwError;
}
DWORD BulUsbDevice::StallEndpoint(DWORD dwEndpoint )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
BulEndpoint *pEndpoint = ObjectIndex(dwEndpoint);
if (pEndpoint) {
dwError = pEndpoint->StallEndpoint();
pEndpoint->DeRef();
}
FUNCTION_LEAVE_MSG();
return dwError;
}
DWORD BulUsbDevice::ClearEndpointStall( DWORD dwEndpoint )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
BulEndpoint *pEndpoint = ObjectIndex(dwEndpoint);
if (pEndpoint) {
dwError = pEndpoint->ClearEndpointStall();
pEndpoint->DeRef();
}
FUNCTION_LEAVE_MSG();
return dwError;
}
DWORD BulUsbDevice::ResetEndpoint(DWORD dwEndpoint )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
BulEndpoint *pEndpoint = ObjectIndex(dwEndpoint);
if (pEndpoint) {
dwError = pEndpoint->ResetEndpoint();
pEndpoint->DeRef();
}
FUNCTION_LEAVE_MSG();
return dwError;
}
DWORD BulUsbDevice::IsEndpointHalted( DWORD dwEndpoint, PBOOL pfHalted )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
BulEndpoint *pEndpoint = ObjectIndex(dwEndpoint);
if (pEndpoint) {
dwError = pEndpoint->IsEndpointHalted(pfHalted);
pEndpoint->DeRef();
}
FUNCTION_LEAVE_MSG();
return dwError;
}
DWORD BulUsbDevice::IssueTransfer(DWORD dwEndpoint,PSTransfer pTransfer )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
BulEndpoint *pEndpoint = ObjectIndex(dwEndpoint);
if (pEndpoint) {
dwError = pEndpoint->IssueTransfer(pTransfer);
pEndpoint->DeRef();
}
FUNCTION_LEAVE_MSG();
return dwError;
}
DWORD BulUsbDevice::AbortTransfer(DWORD dwEndpoint, PSTransfer pTransfer)
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
if (pTransfer) {
BulEndpoint *pEndpoint = ObjectIndex(dwEndpoint);
if (pEndpoint) {
dwError = pEndpoint->AbortTransfer(pTransfer);
pEndpoint->DeRef();
}
}
FUNCTION_LEAVE_MSG();
return dwError;
}
// Endpoint Zero Special
DWORD BulUsbDevice::SendControlStatusHandshake(DWORD dwEndpoint)
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
BulEndpoint *pEndpoint = ObjectIndex(0);
if (pEndpoint) {
dwError = pEndpoint->SendControlStatusHandshake();
pEndpoint->DeRef();
}
FUNCTION_LEAVE_MSG();
return dwError;
}
// Device Function.
DWORD BulUsbDevice::Start()
{
SETFNAME();
FUNCTION_ENTER_MSG();
DWORD dwReturn = ERROR_SUCCESS;
Lock();
//ASSERT(m_pvMddContext==NULL);
m_dwCurConfigure = MAXDWORD;
m_dwCurInterface = MAXDWORD;
// Enable Device Interrupt.
WriteIntrCtr1Register( ReadIntrCtr1Register() |
(UDCISR1_IRCC | UDCISR1_IRRU | UDCISR1_IRSU |UDCISR1_IRRS ));
// Enable UDC.
UDCCR udccr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -