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

📄 isp1161hc.cpp

📁 ISP1161 USB Driver under WinCE for StrongARM processor implementation
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			ULONG paDoneHead;
			paDoneHead = READ_REGISTER_ULONG(HcDoneHead(m_regBase));
			pCurITd->paNextTd = paDoneHead;
			WRITE_REGISTER_ULONG(HcDoneHead(m_regBase), paCurITd);

			while( pEndptDesc->paTdQueueHead != pEndptDesc->paTdQueueTail)
			{
				//Put the next to TdQueueHead
				paCurITd = pEndptDesc->paTdQueueHead;
				pCurITd = (SIsochTransferDescriptor*)m_pobMem->PaToVa(paCurITd);
				
				pEndptDesc->paTdQueueHead = pCurITd->paNextTd;

				//Put itself to DoneHead
				ULONG paDoneHead;
				paDoneHead = READ_REGISTER_ULONG(HcDoneHead(m_regBase));
				pCurITd->paNextTd = paDoneHead;
				WRITE_REGISTER_ULONG(HcDoneHead(m_regBase), paCurITd);
			}

			*pInterrupts |= gcHcInterruptStatusWDHmask;

			//Everything over, set them to 0
			m_TdsPutToITLFirstIndex = 0;
			m_TdsPutToITLSecondIndex = 0;

			return;
				
		}


		/*=====================================================================/
			(1), put to the done queue
		/======================================================================*/
		ULONG paDoneHead;
		paDoneHead = READ_REGISTER_ULONG(HcDoneHead(m_regBase));
		pCurITd->paNextTd = paDoneHead;
		WRITE_REGISTER_ULONG(HcDoneHead(m_regBase), paCurITd);

		*pInterrupts |= gcHcInterruptStatusWDHmask;


		RETAILMSG(0, (TEXT("PHCD: PTD(s), TD 0x%08X is passed to donehead, FrameNumber %08X\r\n"), 
					paCurITd, uFrameNumber));

	} //End of For Loop, which read out the TD that has been processed by HC

	
	//After throwing back the TD to donequeue
	*p_TdsPutToITLIndex = 0;
	
}


void CPhcd::ServiceATLTransferDescriptor()
{
	
	ULONG							paCurGTd;
	SGeneralTransferDescriptor*		pCurGTd;

	DEBUGMSG(ISP1161DBG, (TEXT("+PHCD::ServiceTransferDescriptor\r\n")));
		
	//Set Length, transfer counter
	m_ATLTransferLen		= 0;

	for(UINT i=0; i< sizeof(m_bsPTDReDump)/sizeof(BOOL); i++)
		m_bsPTDReDump[i] = FALSE;

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

	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);
	
	}

	/*=====================================================================/
				Prepare Transfer counter
	/=====================================================================*/

	//Transfer counter
	WRITE_REGISTER_USHORT(HcWRTransCounter(m_regBase), m_ATLTransferLen); 
	
	/*=====================================================================/
		Go through the array and push them one by one to ATL  
	/=====================================================================*/
	WRITE_PORT_USHORT((PUSHORT)(m_regBase+2), 0xc1);
	STRONGARM_DELAY(10);
	
	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, m_ATLTransferLen
		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;

		}
			
		//ExecuteUSBTransanction 
		UCHAR dwEndpointType = pEndpt->endptType;	

		SPhilipsTransferDescriptor		sPTD;
		sPTD.bActualBytes		= 0;
			
		/*=====================================================================/
			The following code is to calcuate the data toggling. For control
			pipe, I am clear, the code is right. 
			As for Bulk transfer, cause ISP1161 can toggle itself. So, just
			set the toggle bit to 0. 
		/======================================================================*/
		{
					
			if (dwEndpointType == gcEndptTypeControl) 
			{
				if (pCurGTd->bfDataToggle & 0x2)
				{
					sPTD.bfToggle = pCurGTd->bfDataToggle & 0x1;
					m_DataToggleBit = 1;
				}
				else
				{
					sPTD.bfToggle = m_DataToggleBit;
					if (m_DataToggleBit == 0)
						m_DataToggleBit = 1;
					else
						m_DataToggleBit = 0;
				}
			}
			else
			{
				sPTD.bfToggle = pEndpt->fPhcdToggleBit;
			}

		}

		sPTD.bfActive			= 1; //Start the transfer
		sPTD.bCompletionCode    = 0;
		sPTD.bMaxPacketSize		= pEndptDesc->bfMaxPacketSize; //Lost the MSB
		sPTD.bfSpeed			= pEndptDesc->bfIsLowSpeed;

//		sPTD.bfLastTd			= pCurGTd->bfLastTd;
				
		if (index == m_TdsPutToATLIndex -1)
			sPTD.bfLastTd			= 1;
		else
			sPTD.bfLastTd			= 0;

		sPTD.bEndpointNumber	= pEndptDesc->bfEndpointNumber;
		
		sPTD.bTotalBytes		= dwBufferLen;

		sPTD.bfPID				= pCurGTd->bfPID;
		if (dwEndpointType == gcEndptTypeInterrupt)
			sPTD.bTokenOnce = 1;
		else
			sPTD.bTokenOnce = 0;

		sPTD.bfAddr				= pCurGTd->bfAddr;
		sPTD.bFormat			= pEndptDesc->bfIsIsochronous;
		sPTD.bUnused1			= 0;
		sPTD.bUnused2			= 0;
		sPTD.bUnused3			= 0;

		/*=====================================================================/
				Send the PTD and the data inside TD to ATL 
		/======================================================================*/

		UINT i;
		PUSHORT pData;
		PUSHORT psPTDData;

		//PTD structure 
		psPTDData = (PUSHORT)(&sPTD);
						
		for (i = 0; i< sizeof(SPhilipsTransferDescriptor)/sizeof(USHORT); i++)
		{
			WRITE_PORT_USHORT((PUSHORT)m_regBase, *(psPTDData+i));
			STRONGARM_DELAY(10);
		}
										
		//Data in the TD 

		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));
				
				//Zouying, This should be removed to reach 14 packets for bulk
				STRONGARM_DELAY(10);
			}

			/*=====================================================================/
				Send Alignment (4 bytes) data to ATL buffer 
			/======================================================================*/
			if (index < m_TdsPutToATLIndex -1)
			{
				if (dwBufferLen %4)
				{
					DWORD dwPayLoad = 4 - dwBufferLen % 4;
					
					DEBUGMSG(ISP1161DBG, (TEXT("PHCD:: Payload data is written, %u, atl Len %u\r\n"), 
						dwPayLoad, m_ATLTransferLen));
					
					for (i=0; i< dwPayLoad/sizeof(USHORT); i++)
					{
						WRITE_PORT_USHORT((PUSHORT)m_regBase, 0);
						STRONGARM_DELAY(10);
					}
				}
			}
	
		}

		DEBUGMSG(ISP1161DBG, 
			(TEXT("PHCD::PTD(s)%d,TD 0x%08X->[%d],bufLen %u,EP %d,CurBuf 0x%08X\r\n"), 
			m_TdsPutToATLIndex, paCurGTd, index, dwBufferLen, pEndpt->endptType, pCurGTd->paCurBuffer));

	}//End of For loop

	/*=====================================================================/
		Set m_ATLBeingReadOut to TRUE. When the next interrupt comes, 
		even though we expect it to be ATLInt, which means the ATL we have
		just input is finished, so the IspTDTransferComplete will be called
		to read it out and put to the done queue.
		But it is still possible, that the next interrupt coming in is
		SOF interrupt, our program will happily go to ServieList and find
		other TDs and put them to ATL buffer, even though the existing ATL
		buffer is not read out. 
	/======================================================================*/
	
	m_ATLBeingReadOut = TRUE;
	DEBUGMSG(ISP1161DBG, (TEXT("-PHCD::ServiceTransferDescriptor\r\n")));
}


VOID CPhcd::IspTDTransferComplete(PULONG pInterrupts)
{
	
	DEBUGMSG(ISP1161DBG, (TEXT("PHCD:: A TD is transferred completely\r\n")));
	
	SGeneralTransferDescriptor*		pCurGTd;
	ULONG							paCurGTd;
		
	UINT i = 0;
	/*=====================================================================/
		The TDs we have just put are finished, we will go through the 
		m_TdsPutToATL array to check whether this item needs to be dumped
		again.
	/======================================================================*/
	if ( m_TdsPutToATLIndex != 1)
	{
		//Transfer counter
		WRITE_REGISTER_USHORT(HcWRTransCounter(m_regBase), m_ATLTransferLen);
		//Read ATL command
		WRITE_PORT_USHORT((PUSHORT)(m_regBase+2), 0x41);
		STRONGARM_DELAY(10);
	}
		
	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);

		pEndptDesc = pEndpt->pEd;

		/*=====================================================================/
				Calcuate the data length of each TD 
		/=====================================================================*/

		USHORT dwBufferLen;
					
		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;
		}

		/*=====================================================================/
			Read PTD and Data out from ATL buffer 
			If there is only one PTD and the PID direction is out (either SETUP
			or OUT), we need to read out the PTD only. This can dramastically
			increase the BULK out performance, if there is only one PTD. In 
			this case, we reset the transfer count.
		/======================================================================*/
			
		PUSHORT pData;
		PUSHORT psPTDData;
		
		if ( m_TdsPutToATLIndex == 1) 
		{
			if ( pCurGTd->bfPID == 0x00 || pCurGTd->bfPID == 0x01) 
			{
				//Transfer counter
				WRITE_REGISTER_USHORT(HcWRTransCounter(m_regBase), 
					sizeof(SPhilipsTransferDescriptor));

				//Read ATL command
				WRITE_PORT_USHORT((PUSHORT)(m_regBase+2), 0x41);
				STRONGARM_DELAY(10);

				//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);
				}

			}
			else
			{
				//Transfer counter
				WRITE_REGISTER_USHORT(HcWRTransCounter(m_regBase), 
					sizeof(SPhilipsTransferDescriptor) + dwBufferLen);
				
				//Read ATL command
				WRITE_PORT_USHORT((PUSHORT)(m_regBase+2), 0x41);
				STRONGARM_DELAY(10);
				
				//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);
					}

					/*
					RETAILMSG(1, (TEXT("PHCD:****************************\r\n")));
					//Display the data
					for (i = 0; i< (dwBufferLen + 1)/sizeof(USHORT); i++)
					{
						RETAILMSG(1, (TEXT(" 0x%04X\r\n"), *(pData + i)));
					}
					*/
				}

⌨️ 快捷键说明

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