⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isp1161hc.cpp

📁 ISP1161 USB Driver under WinCE for StrongARM processor implementation
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			}
		}
		else
		{
			//sPTD
			psPTDData = (PUSHORT)&sPTDReDump[index];
			for (i = 0; i< sizeof(SPhilipsTransferDescriptor)/sizeof(USHORT); i++)
			{
				*(psPTDData + i) = READ_PORT_USHORT((PUSHORT)m_regBase);
				STRONGARM_DELAY(10);
			}
			//Data	
			if ( pCurGTd->paCurBuffer) 
			{
				pData = (PUSHORT)m_pobMem->PaToVa(pCurGTd->paCurBuffer);
				//In odd case, we add one more byte. 
				for (i = 0; i< (dwBufferLen + 1)/sizeof(USHORT); i++)
				{
					*(pData + i) = READ_PORT_USHORT((PUSHORT)m_regBase);
					STRONGARM_DELAY(10);
				}

				/*=====================================================================/
					Read alignment (4 bytes) data out from ATL buffer 
				/======================================================================*/
									
				if (index < m_TdsPutToATLIndex -1) 
				{
					if (dwBufferLen %4)
					{
						DWORD dwPayLoad = 4 - dwBufferLen % 4;
						for (i=0; i< (dwPayLoad)/sizeof(USHORT); i++)
						{
							READ_PORT_USHORT((PUSHORT)m_regBase);
							STRONGARM_DELAY(10);
						}
					}
				}
			}
		}

		/*=====================================================================/
			Analyze the PTD read out
		/======================================================================*/
			
		if ((sPTDReDump[index].bfActive == 1) && (pEndpt->endptType != gcEndptTypeInterrupt))
		{
				
			/*=====================================================================/
				OK, now, we will redump the PTD again, and jump out of this routine
				that means, 1) we don't set m_ATLBeingReadOut to FALSE, So, in next
				frame, the service List routine will not be called to refresh 
				the TD array. 2). We don't put the TD to the done queue
			/======================================================================*/
			DEBUGMSG(ISP1161DBG, (TEXT("PHCD:: bfActive ---- 1\r\n")));
			m_bsPTDReDump[index] = TRUE;
			sPTDReDump[index].bCompletionCode = 0;
			m_bReDump = TRUE;

			/*===================================================
				This is presumed as NAK. What we need to do is to
				clear the error counter
			====================================================*/
			pCurGTd->bfErrorCount = 0;
			continue;
		}

		//Old codes, For interrupt, this is an NAK. means this PTD will not be tried, if it will be retired.
		if ((sPTDReDump[index].bfActive == 1) && (pEndpt->endptType == gcEndptTypeInterrupt))
		{
			sPTDReDump[index].bfActive = 0;
			pCurGTd->bfErrorCount = 0;
			continue;
		}

		//New codes, For interrupt, this is an NAK. means this PTD will not be tried, if it will be retired.
	/*	
		if (pEndpt->endptType == gcEndptTypeInterrupt)
		{
		//	sPTDReDump[index].bfActive = 0;
			if (sPTDReDump[index].bActualBytes == 0)
			{
				//pEndpt->fPhcdToggleBit =  sPTDReDump[index].bfToggle;
				if (sPTDReDump[index].bfToggle)
					pEndpt->fPhcdToggleBit = 0;
				else
					pEndpt->fPhcdToggleBit = 1;
				
				//pEndpt->fPhcdToggleBit =  sPTDReDump[index].bfToggle;

				//This is presumed as NAK. What we need to do is to	clear the error counter
				pCurGTd->bfErrorCount = 0;

				continue;
			}
		}
*/

		/*=====================================================================/
		(Sepc 6.4.4.5) Status Completion part.
			1) Completion code write back
			2) Update CurrentBufferPoint
		/======================================================================*/

		/*=====================================================================/
			1) Completion code write back 
		/======================================================================*/
	
		/*=================================================================
			Refer to USB spec page 172 packet error and 1161 spec 7.6 PTD
		==================================================================*/
			
		if( (sPTDReDump[index].bCompletionCode == 0x1) ||
			(sPTDReDump[index].bCompletionCode == 0x3) || 
			(sPTDReDump[index].bCompletionCode == 0x4) || 
			(sPTDReDump[index].bCompletionCode == 0x5) || 
			(sPTDReDump[index].bCompletionCode == 0x6) ||
			(sPTDReDump[index].bCompletionCode == 0x7))
		{
			
			RETAILMSG(0, (TEXT("PHCD:: PTD CC error: %d, EpNum %d, count: %d\r\n"), 
					sPTDReDump[index].bCompletionCode, pEndpt->endptArrayNum, 
					pCurGTd->bfErrorCount));
	
			pCurGTd->bfErrorCount++;
			
			/*
			if ( pEndpt->endptType == gcEndptTypeInterrupt)
			{
				if (pCurGTd->bfErrorCount < 3)
				{
					continue;
				}
			}
			else if ( pEndpt->endptType == gcEndptTypeControl)
			{
				if (pCurGTd->bfErrorCount < 3)
				{
					sPTDReDump[index].bfActive = 1;
					sPTDReDump[index].bCompletionCode = 0;

					m_bsPTDReDump[index] = TRUE;
					m_bReDump = TRUE;
					continue;
				}
			}
			*/
			continue;

		}
		else
		{
			/* ================================================
				No error has happened, clear the error counter
			 =================================================*/
			pCurGTd->bfErrorCount = 0;

		}

		pCurGTd->bfConditionCode = sPTDReDump[index].bCompletionCode;

		//	if( (sPTDReDump[index].bCompletionCode == 0x9) && (pCurGTd->bfShortPacketOk == 1))
		if (sPTDReDump[index].bCompletionCode == 0x9) 
		{
			pCurGTd->bfConditionCode = 0;
		}
		//Some devices may return more data than you request. don't treat them as error
		if (sPTDReDump[index].bCompletionCode == 0x8) 
		{
			pCurGTd->bfConditionCode = 0;
			RETAILMSG(1, (TEXT("PHCD:: PTD completion error: %d, EpNum %d\r\n"), 
					sPTDReDump[index].bCompletionCode, pEndpt->endptArrayNum));
		}

		if (sPTDReDump[index].bCompletionCode)
			RETAILMSG(1, (TEXT("PHCD:: PTD completion error: %d, EpNum %d\r\n"), 
					sPTDReDump[index].bCompletionCode, pEndpt->endptArrayNum));
	
		/*=====================================================================/
			2) Update CurrentBufferPoint
		/======================================================================*/

		pCurGTd->paCurBuffer = pCurGTd->paCurBuffer + sPTDReDump[index].bActualBytes;

		/*=====================================================================/
		(Sepc 6.4.4.6)  Transfer Desciptor Retirement 
			(1), put to the done queue
			(2), update Endpoints TD, put the next in the first place
			(3), DataToggleCarry bit
		/======================================================================*/

		/*=====================================================================/
			(3), DataToggleCarry bit. 
		/======================================================================*/

		if ( (sPTDReDump[index].bCompletionCode & gcPTDCompletionCodemask) == 0)
		{
			pEndpt->fPhcdToggleBit = sPTDReDump[index].bfToggle;
		}
			
		/*=====================================================================/
			(2), update Endpoints TD, put the next in the first place
		/======================================================================*/

		pEndptDesc->paTdQueueHead = pCurGTd->paNextTd;
		DEBUGMSG(ISPEP, 
			(TEXT("PHCD:: TD 0x%08X is put to the TdQueueHead\r\n"), 
			pCurGTd->paNextTd));
	
		/*=====================================================================/
			(1), put to the done queue
		/======================================================================*/
		
		ULONG paDoneHead;
		paDoneHead = READ_REGISTER_ULONG(HcDoneHead(m_regBase));
		pCurGTd->paNextTd = paDoneHead;
		WRITE_REGISTER_ULONG(HcDoneHead(m_regBase), paCurGTd);

		*pInterrupts |= gcHcInterruptStatusWDHmask;

		
		DEBUGMSG(ISP1161DBG, 
				(TEXT("PHCD: PTD(s) %u TD 0x%08X is passed to donehead\r\n"), 
				m_TdsPutToATLIndex, paCurGTd));
	} //End of For Loop, which read out the TD that has been processed by HC

	
	  /*======================================================================/
	   After reading out ATL buffer, we save the PTD that should be redumped 
	   to m_TdsRePutToATL array. And now we dump them again to ATL.
	   Note, this should be put outside of the for loop. 
	/======================================================================*/
	if (m_bReDump)
	{
		return;
	}

	/*=====================================================================/
		Reset m_TdsPutToATLIndex to 0. So the next time, When goes into
		ServiceTransferDescriptor to prepare ATLList, the TD "paCur" will 
		be put at the begining at the array m_TDsPutToATL[]

		Set m_ATLBeingReadOut to FALSE. means I have read them out. Cause
		when SOF comes, it will only call SeviceList, when this is FALSE. 
	/======================================================================*/

	m_TdsPutToATLIndex		= 0;
	m_ATLBeingReadOut		= FALSE;

}

VOID CPhcd::ReDumpPtd()
{

	DEBUGMSG(ISP1161DBG, 
		(TEXT("PHCD:: ReDumpPtd called, %d\r\n"), m_TdsPutToATLIndex));

	SGeneralTransferDescriptor*		pCurGTd;
	ULONG							paCurGTd;

	/*======================================================================/
	  Remove the PTDs that don't need to be dumped again. Remove the item 
	  in sPTDReDump array, if the corrosponding item in m_bsPTDReDump array 
	  is FALSE.
	  This is added on 22, Nov. This also means sPTDReDump[index].bfActive = 0
	  can be removed. m_bsPTDReDump is FALSE means this PTD needs not to be tried.
	/=======================================================================*/

	UINT i=0;
	
	while( i < m_TdsPutToATLIndex )
	{
		
		if ( m_bsPTDReDump[i] == FALSE ) 
		{
			if ( i == (m_TdsPutToATLIndex -1))
				m_TdsPutToATLIndex--;
			else
			{
				for ( UINT j=i; j< (m_TdsPutToATLIndex - 1); j++)
				{
					m_TdsPutToATL[j] = m_TdsPutToATL[j+1];
					sPTDReDump[j] = sPTDReDump[j+1];
					m_bsPTDReDump[j] = m_bsPTDReDump[j+1];
				}
				m_TdsPutToATLIndex--;
			}
		}
		else
			i++;
	}


	/*========================================================/
		Depending on OHCD spec page 101 to calcuate length.
		Calcuate data length of each TD and m_ATLTransferLen
	/========================================================*/
	m_ATLTransferLen = 0;

	for (UINT index =0; index < m_TdsPutToATLIndex; index++)
	{
		
		paCurGTd = m_TdsPutToATL[index];
		pCurGTd = (SGeneralTransferDescriptor*)m_pobMem->PaToVa(paCurGTd);

		SDevice *pDev;
		SEndpoint *pEndpt;
		SEndpointDescriptor *pEndptDesc;
    
		EnterCriticalSection(&m_csDeviceListLock);
		pDev = m_ppDevices[pCurGTd->bfAddr];
		LeaveCriticalSection(&m_csDeviceListLock);

		ASSERT(pDev);

		EnterCriticalSection(&pDev->csAccessingEndpointArray);
		pEndpt = pDev->ppEndpts[pCurGTd->bfEndptArrayNum];
		LeaveCriticalSection(&pDev->csAccessingEndpointArray);

		ASSERT(pEndpt);

		pEndptDesc = pEndpt->pEd;

		USHORT dwBufferLen;
							
		if (pCurGTd->paCurBuffer == 0)
		{
			dwBufferLen = 0;
		}
		else
		{
			USHORT uspaBufferEnd = (USHORT)(pCurGTd->paBufferEnd & 0xFFF);
			USHORT uspaCurBuffer = (USHORT)(pCurGTd->paCurBuffer & 0xFFF);
		//	dwBufferLen = (USHORT)((pCurGTd->paBufferEnd & 0xFFF) - (pCurGTd->paCurBuffer & 0xFFF));
			dwBufferLen = uspaBufferEnd - uspaCurBuffer;

			if ( (pCurGTd->paBufferEnd & 0xFFFFF000) != (pCurGTd->paCurBuffer & 0xFFFFF000))
				dwBufferLen += 4096;
			dwBufferLen += 1;

			/*===================================================================/
				Alignment of 4 bytes, If there are more than 1 PTD in ATL buffer,
				the next should be alignment in 4 bytes
			====================================================================*/
			if (index < m_TdsPutToATLIndex -1)
			{
				if (dwBufferLen %4)
				{
					USHORT dwPayLoad = 4 - dwBufferLen % 4;
					m_ATLTransferLen += dwPayLoad;
				}
			}
		}
			
		m_ATLTransferLen += dwBufferLen + sizeof(SPhilipsTransferDescriptor);
	
	}

	//Transfer counter
	
	WRITE_REGISTER_USHORT(HcWRTransCounter(m_regBase), m_ATLTransferLen);
			
	WRITE_PORT_USHORT((PUSHORT)(m_regBase+2), 0xc1);

	for ( index = 0; index < m_TdsPutToATLIndex ; index++)
	{
	
		paCurGTd = m_TdsPutToATL[index];
		pCurGTd = (SGeneralTransferDescriptor*)m_pobMem->PaToVa(paCurGTd);

		SDevice *pDev;
		SEndpoint *pEndpt;
		SEndpointDescriptor *pEndptDesc;
    
		EnterCriticalSection(&m_csDeviceListLock);
		pDev = m_ppDevices[pCurGTd->bfAddr];
		LeaveCriticalSection(&m_csDeviceListLock);

		ASSERT(pDev);

		EnterCriticalSection(&pDev->csAccessingEndpointArray);
		pEndpt = pDev->ppEndpts[pCurGTd->bfEndptArrayNum];
		LeaveCriticalSection(&pDev->csAccessingEndpointArray);

		ASSERT(pEndpt);

		pEndptDesc = pEndpt->pEd;

		//Depending on OHCD spec page 101 to calcuate length.
		USHORT dwBufferLen;
									
		//Calcuate the data length of each TD
					
		if (pCurGTd->paCurBuffer == 0)
		{
			dwBufferLen = 0;
		}
		else
		{
			dwBufferLen = (USHORT)((pCurGTd->paBufferEnd & 0xFFF) - (pCurGTd->paCurBuffer & 0xFFF));

			if ( (pCurGTd->paBufferEnd & 0xFFFFF000) != (pCurGTd->paCurBuffer & 0xFFFFF000))
				dwBufferLen += 4096;
			dwBufferLen += 1;

		}
					

		/*=====================================================================/
			Write PTD and data to ATL buffer 
		/======================================================================*/
				
		if (index == m_TdsPutToATLIndex -1)
			sPTDReDump[index].bfLastTd	= 1;
		else
			sPTDReDump[index].bfLastTd	= 0;

		PUSHORT psPTDData;
		PUSHORT pData;
		psPTDData = (PUSHORT)&sPTDReDump[index];
				
		for (UINT i = 0; i< sizeof(SPhilipsTransferDescriptor)/sizeof(USHORT); i++)
			WRITE_PORT_USHORT((PUSHORT)m_regBase, *(psPTDData+i));

		if ( pCurGTd->paCurBuffer) 
		{
			pData = (PUSHORT)m_pobMem->PaToVa(pCurGTd->paCurBuffer);
					
			// dwBufferLen += 1, In odd case, we add one more byte. 
			for (i=0;  i< (dwBufferLen + 1)/sizeof(USHORT); i++)
			{
				WRITE_PORT_USHORT((PUSHORT)m_regBase, *(pData + i));
			}
					
			/*=====================================================================/
				Send PayLoad data to ATL buffer 
			/======================================================================*/
				
			if  (index < m_TdsPutToATLIndex -1)
			{
				if (dwBufferLen %4)
				{
					DWORD dwPayLoad = 4 - dwBufferLen % 4;
					for (i=0; i< (dwPayLoad)/sizeof(USHORT); i++)
					{
						WRITE_PORT_USHORT((PUSHORT)m_regBase, 0);
					}
				}
			}
		}

		DEBUGMSG(ISP1161DBG, 
			(TEXT("PHCD::PTD(s) %d, TD 0x%08X -> [%d], bufferLen %u, ATL Len: %d, EdptType %d, CurBuffer 0x%08X\r\n"), 
			m_TdsPutToATLIndex, paCurGTd, index, dwBufferLen, m_ATLTransferLen, pEndpt->endptType, pCurGTd->paCurBuffer));
		
	} 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -