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

📄 bvd_udc_hw.c

📁 自制PDA系列之usb驱动(处理器PXA270)
💻 C
📖 第 1 页 / 共 5 页
字号:
		 //pRxWord++;

		 pData[0] = (BYTE) (rx_word1 & 0xFF);
		 pData[1] = (BYTE) ((rx_word1>>8)  & 0xFF);
		 pData[2] = (BYTE) ((rx_word1>>16) & 0xFF);
		 pData[3] = (BYTE) ((rx_word1>>24) & 0xFF);

		 pData +=4;
		 word_count--;
	 }
	}
	  
	if (byte_count)
	{
		//temp_byte_count = byte_count;
		rx_word1 = UDC_DR_0( pHWHead );

		//while (temp_byte_count)
		//{
		//	pData[0] = (BYTE) (rx_word1 & 0xFF);
		//	pData++;
		//	rx_word1 = (rx_word1>>8);
		//	temp_byte_count--;
		//}
	    
		if (byte_count == 1)
		{
			pData[0] = (BYTE) (rx_word1 & 0xFF);
		}
		else if (byte_count == 2)
		{
			pData[0] = (BYTE) (rx_word1 & 0xFF);
			pData[1] = (BYTE) ((rx_word1>>8)  & 0xFF);
		}
		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);
		}

		pData+= byte_count;
		byte_count -= byte_count;
	}

	UDCTrace( pHWHead, UDCT_GET_COMMAND, (unsigned long)pData - (unsigned long)dataP );	// bpc: pD-dP was nTotalBytes
    udcStats.readCount++;
	return 0;
}


BOOL UsbRequestGetStringDescriptor(XLLP_UINT16_T wValue, XLLP_UINT8_T **txDatP, XLLP_UINT8_T *txDatLen)
{
	XLLP_UINT16_T	descriptorIndex;
    P_XLLP_UINT8_T  stringDescriptor;

        descriptorIndex = USBData_LowByte (wValue);    // get the descriptor index in the low byte
        if (descriptorIndex <= lastStringIndex)
        {
            switch (descriptorIndex)
            {
                case languagesStringIndex:
                    stringDescriptor = (P_XLLP_UINT8_T)LanguagesStringDescriptor;
                    break;
                case manufactureStringIndex:
                    stringDescriptor = (P_XLLP_UINT8_T)ManufactureStringDescriptor;
                    break;
                case productStringIndex:
                    stringDescriptor = (P_XLLP_UINT8_T)ProductStringDescriptor;
                    break;
/*
                case configurationStringIndex:
                    stringDescriptor = (UsbStringDescriptorPtr) & ConfigurationStringDescriptor;
                    break;
                case interfaceStringIndex:
                    stringDescriptor = (UsbStringDescriptorPtr) & InterfaceStringDescriptor;
                    break;
                case SerialNumberStringIndex:
                    stringDescriptor = (UsbStringDescriptorPtr) & SerialNumberStringDescriptor;
                    break;
*/
            }

            *txDatLen = stringDescriptor[0];
            *txDatP = stringDescriptor;
            return TRUE;
        }
        else
        {
            return FALSE;
        }

}


/*
 * getCommandEightBytes 
 * 
 * Read 8 Bytes from the endpoint 0 FIFO
 *
 * Returns  1 if read failed,
 *          0, success
 */
static
int getCommandEightBytes(PSER_INFO pHWHead, void * dataP)
{
	unsigned long * bufP_a = (unsigned long*) dataP;
	unsigned int nTotalBytes = 8;
    //DWORD dwFrame;
	//unsigned int *bufP_b = (unsigned char*) dataP;
	memset(bufP_a,0x55,8);

	// Include the frame numbers on each trace instead of the signature.
	//dwFrame = (UDC_FNR(pHWHead) & 0x7ff);

	while (nTotalBytes)
	{
		*bufP_a++ = (unsigned long) UDC_DR_0(pHWHead);
		nTotalBytes =-4;
	}
/*
	nTotalBytes = 8;
	bufP_b = (unsigned char*)dataP;

	NKDbgPrintfW(TEXT("0x81 Bytes :%x %x %x %x %x %x %x %x Frame:%d\r\n"),
               bufP_b[0],bufP_b[1],bufP_b[2],bufP_b[3],
			   bufP_b[4],bufP_b[5],bufP_b[6],bufP_b[7], dwFrame);
	
	UDCTrace( pHWHead, UDCT_GET_COMMAND, nTotalBytes );
    udcStats.readCount++;
*/
	return 0;
}


//
// SA_USB_Init
//
// Initialize the UDC.
//
extern
void SA_USB_Init(PSER_INFO pHWHead)
{
	unsigned long udc_crA_val, udc_crB_val ;
//	PUCHAR  pVMem;

	DEBUGMSG( ZONE_FUNCTION,
		(TEXT("+SA_USB_Init\r\n")));
	
	RETAILMSG(1, (TEXT("**************SA_USB_Init\r\n")));

	pHWHead->dConfIdx = 0;
	pHWHead->dSetting = 0;
	pHWHead->dInterface = 0;
	pHWHead->dAddress = 0;
	pHWHead->ModemStatus = 0;  // All lines low till we get connected.

	//Enable UDC clock
	pHWHead->pCLKRegs->cken |= XLLP_CLKEN_USBCLIENT;

	//if (!(StartClock(CLK_USB,NOTINPOWERHANDLER)))
	//	 DEBUGMSG(ZONE_ERROR,(TEXT("HW_XSC1_Init: Unable to start USB clock!\r\n")));
	
	//Configure endpoint registers

	//Clear UDE
	UDCCR_UDE_DISABLE( UDC_CR(pHWHead) );

	//Configuring Endpoint A
	//BULK IN with max pkt size 64
	udc_crA_val = ( XLLP_UDC_UDCCRZ_EE            | MAX_PKT_BULK_64     | 
		            EP_DIRECTION_IN               | EP_TYPE_BULK        | EP_NUM_1   |
                    ALTERNATE_INTERFACE_SETTING_0 | INTERFACE_SETTING_0 | CONFIG_NUM_1 ) ;

    #ifdef DISABLE_DOUBLE_BUFFER
	 //Disable double buffer
	 udc_crA_val &= ~(XLLP_UDC_UDCCRZ_DE);
	#else
	  //Enable double buffer
	 udc_crA_val |= (XLLP_UDC_UDCCRZ_DE);
    #endif
	
	//Configure Endpoint A
	ENDPOINT_A(pHWHead) = udc_crA_val;

	//Configuring Endpoint B
	//BULK OUT with max pkt size 64
	udc_crB_val = ( XLLP_UDC_UDCCRZ_EE            | MAX_PKT_BULK_64     | 
		            EP_DIRECTION_OUT              | EP_TYPE_BULK        | EP_NUM_2   |
                    ALTERNATE_INTERFACE_SETTING_0 | INTERFACE_SETTING_0 | CONFIG_NUM_1 ) ;
	
    #ifdef DISABLE_DOUBLE_BUFFER
	 //Disable double buffer
	 udc_crB_val &= ~(XLLP_UDC_UDCCRZ_DE);
    #else
     //Enable double buffer
	 udc_crB_val |= (XLLP_UDC_UDCCRZ_DE);
    #endif
	
	//Configure Endpoint B
	ENDPOINT_B(pHWHead) = udc_crB_val;

    //Enable UDE
	UDCCR_UDE_ENABLE( UDC_CR(pHWHead) );

	//Check for Endpoint Memory configuration error
	if (UDC_CR(pHWHead) & XLLP_UDC_UDCCR_EMCE)
	{
	 //We should not get here
	 //NKDbgPrintfW(TEXT("Error: UDC Endpoint Memory configuration error\r\n"));
	 //RETAILMSG(1, (TEXT("Error: UDC Endpoint Memory configuration error\r\n")));
	 ASSERT(0);
	}
	else
    {
	 //NKDbgPrintfW(TEXT("UDC Endpoint Memory configured\r\n"));
	 //RETAILMSG(1, (TEXT("**************UDC Endpoint Memory configured\r\n")));
	}

	//Enable endpoint interrupts
	//For endpoint 0, enable Packet Complete intr request and FIFO error intr request
	//For endpoints A and B, enable Packet Complete intr request.
	 UDCICR0_INT_EN( UDC_ICR0(pHWHead), XLLP_UDC_UDCICR0_IE0_0 | /*XLLP_UDC_UDCICR0_IE0_1 |*/	// bpc stuff: no fifoerr ep0 handling
		                               XLLP_UDC_UDCICR0_IEA_0 | XLLP_UDC_UDCICR0_IEB_0 );
	
	//UDCICR0_INT_EN( UDC_ICR0(pHWHead), (XLLP_UDC_UDCICR0_IE0_0 | XLLP_UDC_UDCICR0_IE0_1 |
	//	                                 XLLP_UDC_UDCICR0_IEA_0 | XLLP_UDC_UDCICR0_IEA_1 |
	//									 XLLP_UDC_UDCICR0_IEB_0 | XLLP_UDC_UDCICR0_IEB_1 ));

	//Enable Reset interrupt
    UDCICR1_INT_EN( UDC_ICR1(pHWHead), XLLP_UDC_UDCICR1_IERS);

	//Enable Config change intr
	ENABLE_CONFIG_CHANGE_INTR(UDC_ICR1(pHWHead));

	// Setup default state info.
	UDC_STATE(pHWHead) = WAIT_FOR_SETUP;
	
	//RETAILMSG( 1, (TEXT("UDC_CR_A: %X\r\n"), ENDPOINT_A(pHWHead) ));
	//RETAILMSG( 1, (TEXT("UDC_CSR_A: %X\r\n"), UDC_CSR_A(pHWHead) ));
	//RETAILMSG( 1, (TEXT("UDC_CR_B: %X\r\n"), ENDPOINT_B(pHWHead) ));
	//RETAILMSG( 1, (TEXT("UDC_CSR_B: %X\r\n"), UDC_CSR_B(pHWHead) ));

	// Setup trace information.
#ifdef UDC_TRACE
	g_pTraceBuffer = VirtualAlloc( 0, PAGE_SIZE*PAGE_NUM, MEM_RESERVE, PAGE_NOACCESS );
	if( g_pTraceBuffer == NULL )
		return;
	
	if( ! VirtualCopy( (LPVOID) g_pTraceBuffer, (LPVOID) UDC_PHYSICAL_TRACE_BUFFER, PAGE_SIZE*PAGE_NUM, PAGE_READWRITE | PAGE_NOCACHE)) 
	{
		g_pTraceBuffer = NULL;
		return;
	}
	
	
	// Zero out the trace buffer.
	memset( g_pTraceBuffer, 0, PAGE_SIZE );
	g_pTraceBuffer[0] = 4;
#endif

	//Detect cable state is connected or not
//	if(pHWHead->pBCRReg->MISCRR1 & XLLP_BCR_MISCRR1_USB_CBL)
//	{
//	  pHWHead->UDC_Reset = 1;
//	  pHWHead->UDC_ResetTimeOut = 5000; //Configuring it to 5sec for now 
//	}

	//Enable UDC Soft Connect
//    pHWHead->pBCRReg->MISCWR2 &= ~XLLP_BCR_MISCWR2_NUSBC_SC;

    //NKDbgPrintfW(TEXT("-SA_USB_Init\r\n"));
	RETAILMSG(1, (TEXT("**************-SA_USB_Init\r\n")));
	DEBUGMSG( ZONE_FUNCTION,
		(TEXT("-SA_USB_Init\r\n")));
}

/*
 * SA_USB_DeInit
 *
 *
 */
void SA_USB_DeInit(
	PSER_INFO pHWHead
	)
{
    //Disable UDC clock
    //if (!(StopClock(CLK_USB,NOTINPOWERHANDLER)))
    //		 DEBUGMSG(ZONE_ERROR,(TEXT("HW_XSC1_Init: Unable to stop USB clock!\r\n")));
	
	//Disable UDC clock
	pHWHead->pCLKRegs->cken &= ~XLLP_CLKEN_USBCLIENT ;
}

/*----------------------------------------------------------------------------
 *	XmitEP0Data
 *
 *	Transmits data to EP0.  This makes sure that we don't have a premature
 *	status stage.
 *----------------------------------------------------------------------------*/
void XmitEP0Data( PSER_INFO pHWHead )
{
	int nXferCount, nIndex;
	BOOL bSetIPR = FALSE;
	PBYTE pData;
	unsigned int lastPacketLen = 0;
	unsigned int word_count, byte_count;
	unsigned long tx_word; //*pTxWord, 
	//unsigned char *pTxByte;
	volatile  BYTE  *pEP0FIFO = NULL;
    BYTE ch1, ch2, ch3;

	pEP0FIFO = (volatile  BYTE  *) &(UDC_DR_0( pHWHead ));

	// Check for premature status stage.
	if(UDC_CSR0( pHWHead) & XLLP_UDC_UDCCSR0_OPR && !(UDC_CSR0(pHWHead) & XLLP_UDC_UDCCSR0_SA)) {
		// Premature status stage.  Flush the xmit fifo and return back to
		// a wait for setup state.
		UDCTrace( pHWHead, UDCT_PRE_STATUS, UDC_CSR0( pHWHead ));

		// Clear the xmit fifo
		UDC_CSR0_MWRITE( UDC_CSR0(pHWHead), XLLP_UDC_UDCCSR0_FTF );

		// Clear the OPR bit
		UDC_CSR0_MWRITE( UDC_CSR0(pHWHead), XLLP_UDC_UDCCSR0_OPR );

		// Go back to waiting for setup.
		UDC_STATE( pHWHead ) = WAIT_FOR_SETUP;

		return;
	}

	// Is there a stall?
	if( UDC_CSR0( pHWHead ) & XLLP_UDC_UDCCSR0_SST ) {
		// Stall has been detected.  Clear the condition and go back to wait for setup.
		UDCTrace( pHWHead, UDCT_STALL, UDC_CSR0( pHWHead ));

		UDC_CSR0_MWRITE( UDC_CSR0(pHWHead), XLLP_UDC_UDCCSR0_SST );
		UDC_CSR0_MWRITE( UDC_CSR0(pHWHead), XLLP_UDC_UDCCSR0_FTF );

		UDC_STATE( pHWHead ) = WAIT_FOR_SETUP;

		return;
	}

	// NKDbgPrintfW(TEXT("Send data Req:%d Len:%d Index:%d UDC_state:%d\r\n"),
    //    pHWHead->nXmitReq, pHWHead->nXmitLength, pHWHead->nXmitIndex, UDC_STATE(pHWHead));

	// The ParseSetup has already setup the structure to determine how much
	// data to send.  Determine if this is the last data packet.
	

	if( pHWHead->nXmitLength < EP0Len ) {						

//		UDC_STATE( pHWHead ) = WAIT_FOR_OUT_STATUS;
		
		nXferCount = pHWHead->nXmitLength;

		// If transmitting less than maxpacket, set IPR.
		bSetIPR = TRUE;

		UDCTrace( pHWHead, UDCT_UDCCS0_STATE, UDC_CSR0( pHWHead ));

	} else {
		// More data to send 
		UDC_STATE( pHWHead ) = DATA_STATE_XMIT;
		nXferCount = EP0Len;
	}

	// Get the current index from the state structure and shove the data
	// into the FIFO's.  Adjust the remaining length
	nIndex = pHWHead->nXmitIndex;
	pData  = pHWHead->pXmitData;
	pHWHead->nXmitIndex = nIndex+nXferCount;
	pHWHead->nXmitLength -= nXferCount;

	UDCTrace( pHWHead, UDCT_SEND_DATA, nXferCount );
	
	//
	// Write to the FIFO directly to send the bytes.
	//
	lastPacketLen = nXferCount;
	word_count = lastPacketLen/4;
	byte_count = lastPacketLen%4;

	pData  = pHWHead->pXmitData + nIndex;
    
	nIndex = 0;	// bpc stuff. since pData already has nIndex added to it, reset nIndex back to 0.
				// bpc stuff. that way, the single byte transmissions start off at the right place,
				// bpc stuff. since the full word transmissions update nIndex as they go.

	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_0( pHWHead ) = tx_word;
	   pData +=4;
	   nIndex +=4;
	  }
	  pData = pHWHead->pXmitData;	
	}

	if(byte_count)
    {
	  if(byte_count==1)
	  {
		 ch1 = pData[nIndex++];//*pTxByte++;
		 *(pEP0FIFO) = ch1; 
	  }
	  else if (byte_count==2)
	  {
		 ch1 = pData[nIndex++]; //*pTxByte++;
		 ch2 = pData[nIndex++]; //*pTxByte++;
		 *(pEP0FIFO) = ch1; 
		 *(pEP0FIFO) = ch2;
	  }
	  else if (byte_count==3)
	  {
		 ch1 = pData[nIndex++]; //*pTxByte++;
		 ch2 = pData[nIndex++]; //*pTxByte++;
		 ch3 = pData[nIndex++]; //*pTxByte++;
		 *(pEP0FIFO) = ch1; 
		 *(pEP0FIFO) = ch2; 
		 *(pEP0FIFO) = ch3; 
	  }
	}

	// If we are transmitting less than maxpacket, IPR is set.
	if( bSetIPR ) {
		UDCTrace( pHWHead, UDCT_UDCCS0, XLLP_UDC_UDCCSR0_IPR );
		UDC_CSR0_MWRITE( UDC_CSR0(pHWHead), XLLP_UDC_UDCCSR0_IPR );
	}


// bpc:

	// switch states to OUT STATUS (or Handshake) WAIT
	// when the transmission is done.
	// the transmission is done when:
	//		the transmitted length equals the requested length, or
	//		there are no more bytes to send. (in this case, a 0 length
	//		packet would have just been transmitted.)
	if( pHWHead->nXmitIndex == pHWHead->nXmitReq )
	{

⌨️ 快捷键说明

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