dec21140.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 1,694 行 · 第 1/4 页

C
1,694
字号
	volatile PTX_DESCRIPTOR_FORMAT	pRememberingTheVeryFirstDescriptor;


	pFirstTxDescriptor  = (PTX_DESCRIPTOR_FORMAT) NULL;	

	//printf ("DEC21140SendFrame()::: Sending %d bytes \r\n", dwLength);        

	//	localDEBUGMSG ("DEC21140SendFrame()::: Sending : %d bytes\r\n", dwLength);
	
	//	Need time out...   When all TX process of dec21140 STALL !!!
	while (dwTotalSent < dwLength)
	{	
		if (pCurrentTxDesc->TDES0.dwReg & ~DESC_OWNED_BY_HOST)
		{			
			//	Do something here to make sure the TX process get rid of all these packets...
			//	Then back to top of loop...		
			
			continue;
		}

		if (pCurrentTxDesc == pFirstTxDescriptor)
		{
			//	This should NEVER happen if we have plenty of descriptors...
			//	We'll get into this loop only if we keep getting the descriptor in this while...

			//	localDEBUGMSG ("DEC21140SendFrame()::: Error Tx Loop Back...\r\n");

			//	Just forget about the whole sending and reset current descriptor to the first one...
			pCurrentTxDesc = pFirstTxDescriptor;
			return	DEC21140_ERROR_TX_LOOPBACK;
		}


		// Remember the first descriptor...
		if (pFirstTxDescriptor == (PTX_DESCRIPTOR_FORMAT) NULL)				
			pFirstTxDescriptor = pCurrentTxDesc;
		
		dwNumberOfDescriptorUsed++;		

		if ((dwLength - dwTotalSent) > MAX_BUFFER_SIZE)
			dwToSend = MAX_BUFFER_SIZE;
		else
			dwToSend = dwLength - dwTotalSent;

		
		//localDEBUGMSG ("DEC21140SendFrame()::: Obtained descriptor %d - Filling: %d bytes.\r\n",
		//	(pCurrentTxDesc - pTxDesc), dwToSend);	

		memcpy ((PVOID)TO_VIRT(pCurrentTxDesc->TDES2), pbData + dwTotalSent, dwToSend);		

		pCurrentTxDesc->TDES1.Buffer1Size = dwToSend;

		dwTotalSent += dwToSend;
		
		// Advance to next descriptor...
		pCurrentTxDesc = (PTX_DESCRIPTOR_FORMAT) TO_VIRT(pCurrentTxDesc->TDES3);
	}

	//printf ("NumberOfDescriptorUsed = %d\r\n", dwNumberOfDescriptorUsed);

	//	Now, let's update the descriptors...
	while (i++ < dwNumberOfDescriptorUsed)
	{
		//	If it is first segment, mark it, otherwise unmarked it.   
		//	This descriptor may have been used in previous sending...
		if (i == 1)			
			pFirstTxDescriptor->TDES1.FirstSegment = 1;
		else
			pFirstTxDescriptor->TDES1.FirstSegment = 0;
		
		//	Ditto for last segment.
		if (i == dwNumberOfDescriptorUsed)		
			pFirstTxDescriptor->TDES1.LastSegment = 1;
		else
			pFirstTxDescriptor->TDES1.LastSegment = 0;


		//	Let 21140 owns it now...   It will reset this when the buffer has been 
		//	successfully sent...
		if (i == 1)
		{
			//	Don't release the descriptor yet until the complete frame is done.
			pRememberingTheVeryFirstDescriptor = pFirstTxDescriptor;			
		}		
		else
			pFirstTxDescriptor->TDES0.dwReg |= ~DESC_OWNED_BY_HOST;						
		
		// Advance to next descriptor...
		pFirstTxDescriptor = (PTX_DESCRIPTOR_FORMAT) TO_VIRT(pFirstTxDescriptor->TDES3);		
	}


	//	Rock n Roll time... 
	pRememberingTheVeryFirstDescriptor->TDES0.dwReg |= ~DESC_OWNED_BY_HOST;
    CSR6.dwReg = READ_PORT_ULONG(CSR6_REG);
    CSR6.StartTransmit = 1;	
    WRITE_PORT_ULONG(CSR6_REG, CSR6.dwReg);
	WRITE_PORT_ULONG(CSR1_REG, 0xffffffff);


	/*
	for (;;)
	{
		int	i = 1000000;
		
		printf ("TDES0 = 0x%x \r\n", pRememberingTheVeryFirstDescriptor->TDES0.dwReg);
		while (i--)
			;


	}
	*/
		

	return 0x00;
} 



/////////////////////////////////////////////////////////////////////////////////
//	DEC21140QueryBufferSize() & DEC21140QueryDescriptorSize()
//	Caller can use these functions to figure out how many descriptors and buffer 
//	that can fit into its budget.
//	DEC21140QueryBufferSize() simply returns the constant used by this libary in 
//	determining the size of each buffer.
//	DEC21140QueryDescriptorSize() will return size of TX_DESCRIPTOR_FORMAT.
//	These two dimensions can change, and caller should make sure that it uses these 
//	functions in determining the number of descriptor that the library can use.
//

DWORD	DEC21140QueryBufferSize (void)
{
	return MAX_BUFFER_SIZE;
}	// DEC21140QueryBufferSize()



DWORD	DEC21140QueryDescriptorSize (void)
{
	return	sizeof(TX_DESCRIPTOR_FORMAT);
}	// DEC21140QueryDescriptorSize()




/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//	Misc Utility functions:
//	DumpTxDescriptor()
//	DumpRxDescriptor()
//	DumpMemory()
//

/////////////////////////////////////////////////////////////////////////////////
//	DumpTxDescriptor()
//
#ifdef  __DEC21140_DUMP_TX_DESCRIPTOR__
static void	DumpTxDescriptor (PTX_DESCRIPTOR_FORMAT pTxHead)
{
	PTX_DESCRIPTOR_FORMAT	pTxDesc;
	int						dwCount = 0;

	pTxDesc = pTxHead;


	localDEBUGMSG ("+--------  Dumping TX descriptor  --------+\r\n");
	localDEBUGMSG ("pTxHead = 0x%x \r\n", pTxHead);

	while (1)
	{		
		localDEBUGMSG ("%d ---> ", dwCount++);
		localDEBUGMSG ("Addr = 0x%x | ", pTxDesc);
		localDEBUGMSG ("T0 = 0x%x |", pTxDesc->TDES0.dwReg);
		localDEBUGMSG ("T1 = 0x%x |", pTxDesc->TDES1.dwReg);	
		localDEBUGMSG ("T2 = 0x%x |", pTxDesc->TDES2);		
		localDEBUGMSG ("T3 = 0x%x \r\n", pTxDesc->TDES3);		

		if (TO_VIRT(pTxDesc->TDES3) == (DWORD) pTxHead)
		{
			//	This must be the last descriptor before we loop back...
			break;
		}
		else
			pTxDesc = (PTX_DESCRIPTOR_FORMAT) TO_VIRT(pTxDesc->TDES3);



	}
}
#endif // __DEC21140_DUMP_TX_DESCRIPTOR__



/////////////////////////////////////////////////////////////////////////////////
//	DumpRxDescriptor()
//
#ifdef  __DEC21140_DUMP_RX_DESCRIPTOR__
static void	DumpRxDescriptor (PRX_DESCRIPTOR_FORMAT pRxHead)
{
	PRX_DESCRIPTOR_FORMAT	pRxDesc;
	int						dwCount = 0;

	pRxDesc = pRxHead;


	localDEBUGMSG ("+--------  Dumping RX descriptor  --------+\r\n");
	localDEBUGMSG ("pRxHead = 0x%x \r\n", pRxHead);

	while (1)
	{		
		localDEBUGMSG ("%d ---> ", dwCount++);
		localDEBUGMSG ("Addr = 0x%x | ", pRxDesc);
		localDEBUGMSG ("R0 = 0x%x |", pRxDesc->RDES0.dwReg);
		localDEBUGMSG ("R1 = 0x%x |", pRxDesc->RDES1.dwReg);		
		localDEBUGMSG ("R2 = 0x%x |", pRxDesc->RDES2);		
		localDEBUGMSG ("R3 = 0x%x \r\n", pRxDesc->RDES3);		

		if (TO_VIRT(pRxDesc->RDES3) == (DWORD) pRxHead)
		{
			//	This must be the last descriptor before we loop back...
			break;
		}
		else
			pRxDesc = (PRX_DESCRIPTOR_FORMAT) TO_VIRT(pRxDesc->RDES3);
	}
}	// DumpRxDescriptor()
#endif	//	__DEC21140_DUMP_RX_DEXCRIPTOR__


/////////////////////////////////////////////////////////////////////////////////
//	DumpMemory()
//
#ifdef  __DEC21140_DUMP_MEMORY__

//localDEBUGMSG ("0x%x\t", *pSource++);	

void DisplayHex (BYTE data)
{
	localDEBUGMSG ("0x");
	if (data < 0x10)
		localDEBUGMSG ("0");
	localDEBUGMSG ("%x ", data);
}	// DisplayHex()


void DumpMemory (PBYTE	pSource, DWORD	dwLength)
{
	int		i = 0;


	localDEBUGMSG ("+---- MEM DUMP ----+\r\n");
	localDEBUGMSG ("0x%x: ", pSource);
	while (dwLength--)
	{	
		DisplayHex (*pSource++);
		if (++i == 16)
		{
			i = 0;		
			localDEBUGMSG ("\r\n0x%x: ", pSource);
		}
		
	}
	localDEBUGMSG ("\r\n\r\n");
}	// DumpMemory()
#endif	//	__DEC21140_DUMP_MEMORY__


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
WORD 
EEPROMReadWord( BYTE bAddress ) 
{
    UCHAR nCnt = 0;
    CSR9_21140 localCSR9;
    USHORT nVal = 0;

    localCSR9.dwReg = 0;

    WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);	// Clear.
    Delay(100);
   
    localCSR9.SerialRomSelect = 1;			// Read from SROM.
    localCSR9.ReadOperation   = 1; 
    localCSR9.MiiManagementOperationMode = 1;

    localCSR9.BootRomDataOrSerialRomCtrl = 0x001;	// Setup.
    WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
    Delay(100);

    localCSR9.BootRomDataOrSerialRomCtrl = 0x011; 
    WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
    Delay(1000);
    
    localCSR9.BootRomDataOrSerialRomCtrl = 0x001; 
    WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
    Delay(1000);
   
    localCSR9.BootRomDataOrSerialRomCtrl = 0x101; 	// Command phase.
    WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
    Delay(1000);
     
    localCSR9.BootRomDataOrSerialRomCtrl = 0x111;
    WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
    Delay(1000);

    localCSR9.BootRomDataOrSerialRomCtrl = 0x101;
    WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
    Delay(1000);

    localCSR9.BootRomDataOrSerialRomCtrl = 0x111;
    WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
    Delay(1000);
    
    localCSR9.BootRomDataOrSerialRomCtrl = 0x101;
    WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
    Delay(1000);

    localCSR9.BootRomDataOrSerialRomCtrl = 0x001;
    WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
    Delay(1000);

    localCSR9.BootRomDataOrSerialRomCtrl = 0x011;
    WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
    Delay(1000);

    localCSR9.BootRomDataOrSerialRomCtrl = 0x001;
    WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
    Delay(1000);

    // Address phase.
    for (nCnt = 0 ; nCnt < 8 ; nCnt++)	// Assume a 2Kb - 4Kb SROM part (8 bits)
    {
        nVal = (USHORT)(((bAddress << nCnt) & 0x80) >> 5);


        localCSR9.BootRomDataOrSerialRomCtrl = (0x001 | nVal);
        WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
        Delay(1000);

        localCSR9.BootRomDataOrSerialRomCtrl = (0x011 | nVal);
        WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
        Delay(1000);

        localCSR9.BootRomDataOrSerialRomCtrl = (0x001 | nVal);
        WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
        Delay(1000);
    }


    Delay(1000);

    // Data phase.
    for (nCnt = 0, nVal = 0 ; nCnt < 16 ; nCnt++)  // Data is 16-bits wide.
    {
        
        localCSR9.BootRomDataOrSerialRomCtrl = 0x011;
        WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
        Delay(1000);

        nVal |= ((READ_PORT_ULONG(CSR9_REG) & 0x00000008) >> 3);
        if (nCnt < (16 - 1))
            nVal = nVal << 1;
        Delay(1000);

        localCSR9.BootRomDataOrSerialRomCtrl = 0x001;
        WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
        Delay(1000);
    }

    localCSR9.BootRomDataOrSerialRomCtrl = 0x000;  // Complete transaction.
    WRITE_PORT_ULONG(CSR9_REG, localCSR9.dwReg);
    Delay(1000);

localDEBUGMSG("EEPROMReadWord: Address=0x%x  Data=0x%x\r\n", bAddress, nVal);

    return(nVal);
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL 
EEPROMReadMAC(WORD *wMAC)
{

    int i = 0;

    for (i = 0; i < 3; i++)
    {
        wMAC[i] = EEPROMReadWord((BYTE)(i + 10));  // MAC address is 20 bytes
                                                   // (10 words) into SROM.
    }

    return(TRUE);
}


BOOL
DEC21140SetMACAddress(PUSHORT pMacAddr)
{
    int n = 0;
    PBYTE pDst = NULL;
    PBYTE pSrc = NULL;

    // Make a copy of the MAC address...
    pSrc = (PBYTE)pMacAddr;
    pDst = pbEthernetAddr;	
    for (n = 6; n ; n--) 
    {
        *pDst++ = *pSrc++;		
    }

        localDEBUGMSG ("INFO: Set DEC21140 MAC to %x-%x-%x", pbEthernetAddr[0], pbEthernetAddr[1], pbEthernetAddr[2]);
        localDEBUGMSG ("-%x-%x-%x\r\n",  pbEthernetAddr[3], pbEthernetAddr[4], pbEthernetAddr[5]);

    return(TRUE);
}


⌨️ 快捷键说明

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