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

📄 bvd_udc_hw.c

📁 自制PDA系列之usb驱动(处理器PXA270)
💻 C
📖 第 1 页 / 共 5 页
字号:
					else if (byte_count == 3)
					{
						pData[0] = (BYTE) (rx_word1 & 0xFF);
						pData[1] = (BYTE) ((rx_word1>>8)  & 0xFF);
						pData[2] = (BYTE) ((rx_word1>>16) & 0xFF);

//						if ((pData[0] == cEvtChar) || (pData[1] == cEvtChar) || (pData[2] == cEvtChar))
//				   		  fRXFlag = TRUE ;
					}

					pData+= byte_count;
					RxPacketLen += byte_count;
					RxPacketIndex += byte_count;
					byte_count -= byte_count;
				}

				// Clear the PC bit
				if( UDC_CSR_B( pHWHead ) & XLLP_UDC_UDCCSR_PC ) 
				{
			     UDCCSR_MWRITE(UDC_CSR_B( pHWHead), XLLP_UDC_UDCCSR_PC);

			     // Clear Interrupt
			     UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRB_0);
				}

				dw_udc_csr_b = UDC_CSR_B( pHWHead );

				// Clear the TRN bit
			    if(dw_udc_csr_b & XLLP_UDC_UDCCSR_TRN ) 
				{
	             UDCCSR_MWRITE( UDC_CSR_B(pHWHead), XLLP_UDC_UDCCSR_TRN );
		         //UDCTrace( pHWHead, UDCT_UDC_CSR_A, UDC_CSR_A( pHWHead ));
				}
				
				if (buflen >= bytes_to_read)
				{
					//memcpy(pRxBuffer, RxPacket, RxPacketLen );
					pRxBuffer += RxPacketLen;

					(*pBufflen) += RxPacketLen;
					bytes_to_read -=RxPacketLen;

					buflen-= RxPacketLen;
					RxPacketIndex =0;
					RxPacketLen = 0;
				}
				else if (buflen)
				{
					//RETAILMSG(1, (TEXT("***RX: RxPktLen:%X buflen%X\r\n"), RxPacketLen, buflen));

					memcpy(pRxBuffer, RxPacket, buflen );
					pRxBuffer += buflen;

					(*pBufflen) += buflen;
					bytes_to_read -=buflen;

					RxPacketLen -= buflen;
					RxPacketIndex += buflen;
					buflen-= buflen;

					//NKDbgPrintfW(TEXT("***RX: RxPktLen:%X buflen%X\r\n"), RxPacketLen, buflen);
				}
				else
				{
					//NKDbgPrintfW(TEXT("***RX: Buffer FULL RxPacketLen:%X buflen%X\r\n"), RxPacketLen, buflen);
				}
			 }

		}while(dw_udc_csr_b & XLLP_UDC_UDCCSR_PC && buflen);
    }
	
/*
	// If we didn't read the whole buffer we need to come back. Leave with
	// the interrupt still enabled so the MDD will recall.
	if ((UDC_CSR_B( pHWHead) & XLLP_UDC_UDCCSR_BNE_BNF ) || word_count || byte_count) 
	{
		DEBUGMSG( ZONE_USB, (TEXT("RNE")));
		//RETAILMSG( 1, (TEXT("\r\nRx: ****RNE*****bytes_to_read:%X Buflen:%X\r\n"), bytes_to_read, buflen));
		UDCTrace( pHWHead, UDCT_RX_INTR_DONE, UDC_CSR_B( pHWHead ));
		//UDCTrace( pHWHead, UDCT_UDC_RX_BUF_EMPTY, (bytes_to_read - word_count*4 - byte_count) );
		//return fRXFlag;
	}
	
*/	
	//UDCTrace( pHWHead, UDCT_RX_INTR_DONE, UDC_CSR_B( pHWHead ));

	// To do: Deal with EPB FIFO error intr
	//UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRB_1);
	// Clear Interrupt
	//UISR_IR2_CLR (pHWHead->pUDCRegs->uisr0);
	//UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRB_0);
    
	//UDCTrace( pHWHead, UDCT_INTR, UDC_ISR0(pHWHead) );

	UDCTrace( pHWHead, UDCT_RX_DATA, *pBufflen );

	//RETAILMSG( 1, (TEXT("Rx Data:%d UDC_CSR_B:%X UDC_ISR0:%X\r\n"),*pBufflen, UDC_CSR_B( pHWHead), UDC_ISR0(pHWHead)));
	//g_pBLReg->hex_led = 0xFFFFA00A;

	//if ( LineEvents )
	//{
	// RETAILMSG(1, (TEXT("***************RX: Calling EvaluateEvent...%X\r\n"), buflen));
	// pHWHead->EventCallback( pHWHead->pMddHead, LineEvents );
    //}

	return fRXFlag;
}



/*
 * SA_USB_TxIntHandler
 *
 * Send the next packet to the USB. The first packet gets sent by directly
 * calling this function (via dispatch table) from the MDD. After the first
 * call the interrupt mechanism will keep things going.
 *
 * We return the actual number of bytes we've queued to the UDC. Note that
 * until the next interrupt we wont know if it has been transmitted. We'll
 * deal with the failure by saving the original packet and retransmitting if
 * we get an error. In that case we'll return 0 as the number of bytes sent
 * since no new bytes have been consumed from the caller's buffer.
 *
 * When the packet is accepted we return the number of bytes and grab the next
 * packet (or portion thereof).
 *
 */
void SA_USB_TxIntHandler(PSER_INFO pHWHead,
						 PUCHAR pTxBuffer,
						 ULONG *pBuffLen) 
{
	
	unsigned int len = *pBuffLen;
	int skip = 0;
	static UCHAR lastPacket[EP1Len];
	static unsigned int lastPacketLen = 0;
	static unsigned int ZLP = 0;
	BOOL bSendShortPacket = FALSE;
	DWORD dw_udc_csr_a; //dw_udc_cr_a
	unsigned int word_count, byte_count;
	//unsigned long *pTxWord;
	//unsigned char *pTxByte;
	
	PBYTE pData;
	int nIndex;
	unsigned long tx_word;
	volatile  BYTE  *pEP_A_FIFO;
	//BYTE ch1, ch2, ch3;

	pEP_A_FIFO = (volatile  BYTE  *) &(UDC_DR_A( pHWHead ));
	//*pBuffLen = 0;
	
    /* 
     * We are called under a few different conditions:
	 * New packet - called directly and potentially while we are still sending
	 *  an old packet. We detect this by checking lastPacketLen and skipping
	 *  out if it is still set.
	 * Next packet - called by interrupt handler thread when TPC interrupt
	 *  is delivered. We check the TPE bit to see if we need to retransmit. If
	 *  so we ignore the caller's arguments, resend the packet and indicate we
	 *  sent no bytes so we'll get called back. The caller will either send a
	 *  NULL pointer if no more data to send or a non NULL pointer for the
	 *  next packet. If NULL we clear the interrupt and skip out. Otherwise we
	 *  queue the next packet.
	 */
	
	//g_pBLReg->hex_led = 0xFFFFB001;

	dw_udc_csr_a = UDC_CSR_A( pHWHead );
	//dw_udc_cr_a  = ENDPOINT_A(pHWHead) ;
	//RETAILMSG(1, (TEXT("TX: UDC_CR_A=%X , UDC_CSR_A=%X \r\n"), dw_udc_cr_a , dw_udc_csr_a ));
	
	UDCTrace( pHWHead, UDCT_TX_DATA, len );
	UDCTrace( pHWHead, UDCT_UDC_CSR_A, dw_udc_csr_a );
    
	//DEBUGMSG(ZONE_WRITE, (TEXT("TX Buff Len = %d, UDC_CSR_A=%X \r\n"), len, dw_udc_csr_a ));
	//RETAILMSG(1, (TEXT("TX: %d\r\n"),len));

	// To do: Deal with EPA FIFO error intr
	// Deal with EPB FIFO error intr
	if (UDC_ISR0(pHWHead) & XLLP_UDC_UDCISR0_IRA_1) 
	{
	 //NKDbgPrintfW(TEXT("****!!! EPA FIFO error\r\n"));
	 UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_1);
	}
	// Clear Interrupt
//A.K.
//	UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_0);
	//UDCTrace( pHWHead, UDCT_UDC_ISR0, UDC_ISR0(pHWHead) );


	// Clear any underrun conditions.
	//
	// TRN Usage Note:
	//   TRN is just a status bit for Bulverde.  
	//   It shows that the host is asking for data 
	//   faster than we can give it.
	//
	if( UDC_CSR_A( pHWHead ) & XLLP_UDC_UDCCSR_PC )
	{
		// Clear the TPC
		UDCCSR_MWRITE( UDC_CSR_A(pHWHead), XLLP_UDC_UDCCSR_PC );

		if( UDC_CSR_A( pHWHead ) & XLLP_UDC_UDCCSR_TRN ) 
		{
		    UDCCSR_MWRITE( UDC_CSR_A(pHWHead), XLLP_UDC_UDCCSR_TRN );
    	}
	}

//A.K.
	if ((! *pBuffLen ) && (lastPacketLen == 64))
	{
	   	UDCCSR_MWRITE( UDC_CSR_A(pHWHead) , (XLLP_UDC_UDCCSR_SP));

		// Clear the TPC
		UDCCSR_MWRITE( UDC_CSR_A(pHWHead), XLLP_UDC_UDCCSR_PC );

	    // Clear the interrupt (must be done after clearing TPC
	    UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_0);
		
		lastPacketLen = 0;
		*pBuffLen = 0;
		return;
	}

    //
    // If no bytes to send we're done. Interrupt has been cleared.
    //

	if ((! *pBuffLen ) && !ZLP ) 
	{
		// Clear the TPC
		UDCCSR_MWRITE( UDC_CSR_A(pHWHead), XLLP_UDC_UDCCSR_PC );

	    // Clear the interrupt (must be done after clearing TPC
	    UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_0);

		//UDCTrace( pHWHead, UDCT_UDC_ISR0, UDC_ISR0(pHWHead) );
		//UDCTrace( pHWHead, UDCT_TPC, len );
	    
		UDCTrace( pHWHead, UDCT_XMIT_DONE,  UDC_CSR_A(pHWHead)  );

		//g_pBLReg->hex_led = 0xFFFFB00C;
		return;
	}

	*pBuffLen = 0;
	
	do
	{
		// We are sending a new packet(pTxBuffer).
		//
		if (len || ZLP ) //(pTxBuffer || ZLP ) 
		{
			lastPacketLen = min(EP1Len,len);

			// Check if need to set the TSP bit.
			if( lastPacketLen < EP1Len )
				bSendShortPacket = TRUE;
          /*
			if ((UDC_CSR_A( pHWHead ) & XLLP_UDC_UDCCSR_FS) == 0)
			{
			 lastPacketLen = 0;
			 bSendShortPacket = FALSE;
			 UDCTrace( pHWHead, UDCT_XMIT_DONE,  UDC_CSR_A(pHWHead)  );

			 //RETAILMSG( 1, (TEXT("**************Tx FIFO full. Data Done:%X UDC_CSR_A:%X UDC_ISR0:%X\r\n"),
			 //						   *pBuffLen, UDC_CSR_A( pHWHead), UDC_ISR0(pHWHead)));

			 // Clear the interrupt (must be done after clearing TPC
			 //UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_0);
			 //return;
			}
		  */
			if (lastPacketLen) 
			{
				//memcpy( lastPacket, pTxBuffer, lastPacketLen );
				udcStats.goodWrPacketCount++;
				*pBuffLen += lastPacketLen;
			}
		} 
			
		DEBUGMSG( ZONE_WRITE,(TEXT("TX: lastPacketLen = %d, bSendShortPacket=%d\r\n"), lastPacketLen, bSendShortPacket ));

		
		UDCTrace( pHWHead, UDCT_EP1_XMIT, lastPacketLen );
		UDCTrace( pHWHead, UDCT_EP1_XMIT, bSendShortPacket );

		//
		// Write to the FIFO directly to send the bytes.
		//
		word_count = lastPacketLen/4;
		byte_count = lastPacketLen%4;

		pData  = pTxBuffer;  //lastPacket
		nIndex=0;

		if (word_count)
		{
   		 while (word_count--)
		 {	 
		  //tx_word = (((pData[nIndex+3])<<24) | ((pData[nIndex+2])<<16) | ((pData[nIndex+1])<<8) | (pData[nIndex]));
		  tx_word = (((pData[3])<<24) | ((pData[2])<<16) | ((pData[1])<<8) | (pData[0]));
		  UDC_DR_A( pHWHead ) = tx_word;
		  //RETAILMSG( 1, (TEXT("Tx: %x %x %x %x\r\n"), pData[0], pData[1], pData[2], pData[3]));
		  pData +=4;
		  nIndex +=4;
		 }
		 //pData  = pTxBuffer;  //lastPacket
		}

		//pTxByte  = (unsigned char *)  (pData + (word_count*4)); //word_count = 0 always

		//while (byte_count--)
		//{
		//  ch1 = pData[nIndex++];//*pTxByte++;
		//  *(pEP_A_FIFO) = ch1;
		//}

		if(byte_count==1)
		{ 
		  *(pEP_A_FIFO) = pData[0];

		  pData++;
		  nIndex++;
		}
		else if (byte_count==2)
		{
		  *(pEP_A_FIFO) = pData[0];
		  *(pEP_A_FIFO) = pData[1];

		  nIndex+=2;
		  pData+=2;
		
		}
		else if (byte_count==3)
		{
		  *(pEP_A_FIFO) = pData[0];
		  *(pEP_A_FIFO) = pData[1];
		  *(pEP_A_FIFO) = pData[2];

		  nIndex+=3;
		  pData+=3;
		}
  
		// Set the TSP bit.
		if( bSendShortPacket)
		{
			//UDCCSR_MWRITE( UDC_CSR_A(pHWHead) , (XLLP_UDC_UDCCSR_SP | XLLP_UDC_UDCCSR_PC) );
			UDCCSR_MWRITE( UDC_CSR_A(pHWHead) , (XLLP_UDC_UDCCSR_SP));
			
			//if (ZLP)
			//{
			// ZLP = 0;
			// RETAILMSG( 1, (TEXT("Tx: Clearing ZLP\r\n")));
			//}
		}
//A.K.
		dw_udc_csr_a = UDC_CSR_A( pHWHead );
//
		// Clear the interrupt
		if ( UDC_CSR_A( pHWHead ) & XLLP_UDC_UDCCSR_PC ) 
		{
			UDCCSR_MWRITE( UDC_CSR_A(pHWHead) , XLLP_UDC_UDCCSR_PC );

//A.K.			//Clear TRN bit
			if(dw_udc_csr_a & XLLP_UDC_UDCCSR_TRN ) 
			{
	     		UDCCSR_MWRITE( UDC_CSR_A(pHWHead), XLLP_UDC_UDCCSR_TRN );
			}
//
			UDCTrace( pHWHead, UDCT_UDC_CSR_A, UDC_CSR_A( pHWHead ));
			
			// Clear the interrupt (must be done after clearing PC
//			UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_0);
			//UDCTrace( pHWHead, UDCT_UDC_ISR0, UDC_ISR0(pHWHead) );
		}

//		dw_udc_csr_a = UDC_CSR_A( pHWHead );

		//Clear TRN bit
//		if(dw_udc_csr_a & XLLP_UDC_UDCCSR_TRN ) 
//		{
//	     UDCCSR_MWRITE( UDC_CSR_A(pHWHead), XLLP_UDC_UDCCSR_TRN );
//		}

		pTxBuffer += lastPacketLen;
		len -= lastPacketLen;

//	}while(dw_udc_csr_a & XLLP_UDC_UDCCSR_FS && len); 
	}while((dw_udc_csr_a & (XLLP_UDC_UDCCSR_BNE_BNF | XLLP_UDC_UDCCSR_FS)) && len); 

//A.K.
	// Clear the interrupt (must be done after clearing PC
	UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_0);

	UDCTrace( pHWHead, UDCT_XMIT_DONE,  dw_udc_csr_a); //UDC_CSR_A(pHWHead)  );

	//RETAILMSG( 1, (TEXT("Tx Data:%d UDC_CSR_A:%X UDC_ISR0:%X \r\n"),lastPacketLen, UDC_CSR_A( pHWHead), UDC_ISR0(pHWHead)));
 	// 
    // Clear the interrupt
    // This must be done last, after clearing TPC
    //
	// To do: Deal with EPB FIFO error intr
	// UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_1);
	// Clear Interrupt
	//UISR_IR1_CLR (pHWHead->pUDCRegs->uisr0);
	//UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_0);
	//UDCTrace( pHWHead, UDCT_UDC_ISR0, UDC_ISR0(pHWHead) );

	//g_pBLReg->hex_led = 0xFFFFB00D;

	return;
}

/*
 * SA_USB_PowerOff
 *
 *
 */
void SA_USB_PowerOff(
	PSER_INFO pHWHead
	)
{
 
	UDCCR_UDE_DISABLE( UDC_CR(pHWHead) );

}


/*
 * SA_USB_PowerOn
 *
 * 
 */    
void SA_USB_PowerOn(
	PSER_INFO pHWHead
	)
{
	unsigned long udc_crA_val, udc_crB_val ;
 	//Configuring Endpoint A
	//BULK IN with max pkt size 64
	udc_crA_val = ( XLLP_UDC_UDCCRZ_EE            | MAX_PKT_BULK_64     | 
		            EP_DIRECTION_IN        

⌨️ 快捷键说明

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