smsc100.c

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

C
1,011
字号
		//
		// Re-enable TXENA
		//
		WriteWord (TCR, ReadWord (TCR) | TCR_ENABLE);
		SelectBank (BANK2);
		//
		// Release the buffer memory for the Frame that failed to transmit.
		//
		WriteWord (MMU_CMD, MC_FREEPKT);
		//
		// Wait for the MMU Release to complete.
		//
		dwStartTime = OEMEthGetSecs ();
		while (ReadWord (MMU_CMD) & MC_BUSY)
			{
			if (OEMEthGetSecs () - dwStartTime > 2)
				{
				EdbgOutputDebugString ("!Smsc100FdSendFrame: Timed out waiting for MMU command to complete.\r\n");
				break;
				}
			}
		return (wCompletionCode);
		}
	else
		{
		//
		// Successful transmission, clear the collision count.
		//
		SelectBank (BANK0);
		ReadWord (COUNTER);
//		EdbgOutputDebugString ("-Smsc100FdSendFrame: Success\r\n");
		return (0);
		}
	}

#ifdef SMSC_DUMP_FRAMES
static void
DumpEtherFrame (BYTE *pFrame, WORD cwFrameLength)
	{
	int i,j;

	EdbgOutputDebugString ("Frame Buffer Address: 0x%X\r\n", pFrame);
	EdbgOutputDebugString ("To: %B:%B:%B:%B:%B:%B  From: %B:%B:%B:%B:%B:%B  Type: 0x%H  Length: %u\r\n", pFrame[0], pFrame[1], pFrame[2], pFrame[3], pFrame[4], pFrame[5], pFrame[6], pFrame[7], pFrame[8], pFrame[9], pFrame[10], pFrame[11], ntohs (*((UINT16 *)(pFrame + 12))), cwFrameLength);
	for (i = 0; i < cwFrameLength / 16; i++)
		{
		for (j = 0; j < 16; j++)
			EdbgOutputDebugString (" %B", pFrame[i*16 + j]);
		EdbgOutputDebugString ("\r\n");
		}
	for (j = 0; j < cwFrameLength % 16; j++)
		EdbgOutputDebugString (" %B", pFrame[i*16 + j]);
	EdbgOutputDebugString ("\r\n");
	}
#endif

//
// The read and write EEPROM routines access the 64 word by 16-bit EEPROM that is attached to the
// SMSC91C100FD.  There are locations within the EEPROM that the chip does not need and can be used to
// store other important information.
//
BOOL
Smsc100FdReadEEPROM (UINT16 usAddress, UINT16 *pusData)
	{
	DWORD dwTimeout;

//	EdbgOutputDebugString ("+Smsc100FdReadEEPROM: Address 0x%x.\n", usAddress);
	SelectBank (BANK2);
	WriteWord (POINTER, (usAddress & 0x003F) | PTR_AUTOINC | PTR_READ);
	SelectBank (BANK1);
	WriteWord (CONTROL, ReadWord (CONTROL) | CTL_EEPROM | CTL_RELOAD);

	for (dwTimeout = 0x000fffff; dwTimeout; dwTimeout--)
		{
		if (!(ReadWord (CONTROL) & (CTL_STORE | CTL_RELOAD)))
			break;
		}
	*pusData = ReadWord (GENERAL);
	WriteWord (CONTROL, ReadWord (CONTROL) & ~(CTL_EEPROM | CTL_RELOAD | CTL_STORE));
	if (!dwTimeout)
		{
		EdbgOutputDebugString ("!Smsc100FdReadEEPROM: Read timed out.\n");
		EdbgOutputDebugString ("-Smsc100FdReadEEPROM: Failed Address 0x%x.\n", usAddress);
		return (FALSE);
		}
//	EdbgOutputDebugString ("-Smsc100FdReadEEPROM: Address 0x%x = 0x%x.\n", usAddress, *pusData);
	return (TRUE);
	}

BOOL
Smsc100FdWriteEEPROM (UINT16 usAddress, UINT16 usData)
	{
	DWORD dwTimeout;

//	EdbgOutputDebugString ("+Smsc100FdWriteEEPROM: Address 0x%x.\n", usAddress);
	SelectBank (BANK2);
	WriteWord (POINTER, (usAddress & 0x003F) | PTR_AUTOINC | PTR_READ);
	SelectBank (BANK1);
	WriteWord (GENERAL, usData);
	WriteWord (CONTROL, ReadWord (CONTROL) | CTL_EEPROM | CTL_STORE);

	// Loop until EEPROM data is written
	for (dwTimeout = 0x00ffffff; dwTimeout; dwTimeout--)
		{
		if (!(ReadWord (CONTROL) & (CTL_STORE | CTL_RELOAD)))
			break;
		}
	WriteWord (CONTROL, ReadWord (CONTROL) & ~(CTL_EEPROM | CTL_RELOAD | CTL_STORE));
	if (!dwTimeout)
		{
		EdbgOutputDebugString ("!Smsc100FdWriteEEPROM Write timed out.\n");
		EdbgOutputDebugString ("-Smsc100FdWriteEEPROM: Failed Address 0x%x.\n", usAddress);
		return (FALSE);
		}
//	EdbgOutputDebugString ("-Smsc100FdWriteEEPROM: Address 0x%x = 0x%x.\n", usAddress, usData);
	return (TRUE);
	}

BOOL
Smsc100FdReloadEEPROM ()
	{
//	EdbgOutputDebugString ("+Smsc100FdReloadEEPROM: Address 0x%x.\n", usAddress);
	SelectBank (BANK1);
	WriteWord (CONTROL, ReadWord (CONTROL) | CTL_RELOAD);

//	EdbgOutputDebugString ("-Smsc100FdReloadEEPROM: Address 0x%x = 0x%x.\n", usAddress, usData);
	return (TRUE);
	}

/*
 * Description:
 *	Write registers in the PHY.
 *
 * Arguments:
 *	uiPhyRegister - The address of the register within the PHY
 *	usPhyData - The data to write.
 *
 * Return Value:
 *	None.
 */
VOID
Smsc100FdWritePhy (USHORT usPhyRegister, USHORT usPhyData)
	{
	USHORT usControl;
	UINT uiBitCount;
	//
	// Build the 64 bits of data to clock out to the PHY.
	//
	ULONGLONG ullCommand = usPhyRegister;
	ullCommand <<= MIIREG_INDEX_BIT;
	ullCommand &= MIIREG_INDEX_MASK;
	ullCommand &= ~MIIREG_PHYADDR_MASK;
	ullCommand |= (((ULONGLONG)PHY_ADDRESS) << MIIREG_PHYADDR_BIT);
	ullCommand |= (ULONGLONG)usPhyData; 
	ullCommand |= MIIREG_WRITE;
	//
	// Select the proper bank.
	//
	SelectBank (BANK3);
	//
	// Pre-read the MGMT port to preserve unused bits.
	//
	usControl = ReadWord (MGMT);
	//
	// Set the Clock low and the DataOut enabled and high.
	//
	usControl &= ~(MGMT_MCLK | MGMT_MDO | MGMT_MDOE);
	WriteWord (MGMT, usControl);
	//
	// Send out the 32 synchronization preamble bits.
	//
	for (uiBitCount = 0; uiBitCount < 32; uiBitCount++)
		{
		UCHAR ucDataBit = (UCHAR)((ullCommand & MIIREG_NEXTBIT_MASK) >> MIIREG_NEXTBIT_BIT);
		ullCommand <<= 1;
		WriteWord (MGMT, usControl | ucDataBit | MGMT_MDOE);				// Clock low, DataOut enabled
		WriteWord (MGMT, usControl | ucDataBit | MGMT_MDOE | MGMT_MCLK);	// Clock high, DataOut enabled
		}
	//
	// Send out the 2 start bits, the 2 opcode bits, the 5 device address bits, the 5 register address bits, and the 2 turn around bits.
	//
	for (uiBitCount = 0; uiBitCount < 16; uiBitCount++)
		{
		UCHAR ucDataBit = (UCHAR)((ullCommand & MIIREG_NEXTBIT_MASK) >> MIIREG_NEXTBIT_BIT);
		ullCommand <<= 1;
		WriteWord (MGMT, usControl | ucDataBit | MGMT_MDOE);				// Clock low, DataOut enabled
		WriteWord (MGMT, usControl | ucDataBit | MGMT_MDOE | MGMT_MCLK);	// Clock high, DataOut enabled
		}
	//
	// Send out the 16 data bits.
	//
	for (uiBitCount = 0; uiBitCount < 16; uiBitCount++)
		{
		UCHAR ucDataBit = (UCHAR)((ullCommand & MIIREG_NEXTBIT_MASK) >> MIIREG_NEXTBIT_BIT);
		ullCommand <<= 1;
		WriteWord (MGMT, usControl | ucDataBit | MGMT_MDOE);				// Clock low, DataOut enabled
		WriteWord (MGMT, usControl | ucDataBit | MGMT_MDOE | MGMT_MCLK);	// Clock high, DataOut enabled
		}
	}

/*
 * Description:
 *	Read register from the PHY.
 *
 * Arguments:
 *	uiPhyRegister - The address of the register within the PHY
 *
 * Return Value:
 *	The data read.
 */
USHORT
Smsc100FdReadPhy (USHORT usPhyRegister)
	{
	USHORT usPhyData;
	USHORT usControl;
	UINT uiBitCount;
	//
	// Build the 64 bits of data to clock out to the PHY.
	//
	ULONGLONG ullCommand = usPhyRegister;
	ullCommand <<= MIIREG_INDEX_BIT;
	ullCommand &= MIIREG_INDEX_MASK;
	ullCommand &= ~MIIREG_PHYADDR_MASK;
	ullCommand |= (((ULONGLONG)PHY_ADDRESS) << MIIREG_PHYADDR_BIT);
	ullCommand |= MIIREG_READ;
	//
	// Select the proper bank.
	//
	SelectBank (BANK3);
	//
	// Pre-read the MGMT port to preserve unused bits.
	//
	usControl = ReadWord (MGMT);
	//
	// Set the Clock low and the DataOut enabled and high.
	//
	usControl &= ~(MGMT_MCLK | MGMT_MDO | MGMT_MDOE);
	WriteWord (MGMT, usControl);
	//
	// Send out the 32 synchronization preamble bits.
	//
	for (uiBitCount = 0; uiBitCount < 32; uiBitCount++)
		{
		UCHAR ucDataBit = (UCHAR)((ullCommand & MIIREG_NEXTBIT_MASK) >> MIIREG_NEXTBIT_BIT);
		ullCommand <<= 1;
		WriteWord (MGMT, usControl | ucDataBit | MGMT_MDOE);				// Clock low, DataOut enabled
		WriteWord (MGMT, usControl | ucDataBit | MGMT_MDOE | MGMT_MCLK);	// Clock high, DataOut enabled
		}
	//
	// Send out the 2 start bits, the 2 opcode bits, the 5 device address bits, and the 5 register address bits.
	//
	for (uiBitCount = 0; uiBitCount < 14; uiBitCount++)
		{
		UCHAR ucDataBit = (UCHAR)((ullCommand & MIIREG_NEXTBIT_MASK) >> MIIREG_NEXTBIT_BIT);
		ullCommand <<= 1;
		WriteWord (MGMT, usControl | ucDataBit | MGMT_MDOE);				// Clock low, DataOut enabled
		WriteWord (MGMT, usControl | ucDataBit | MGMT_MDOE | MGMT_MCLK);	// Clock high, DataOut enabled
		}
	//
	// Send out the 2 turn around bits.
	//
	for (uiBitCount = 0; uiBitCount < 2; uiBitCount++)
		{
		WriteWord (MGMT, usControl);				// Clock low, DataOut disabled
		WriteWord (MGMT, usControl | MGMT_MCLK);	// Clock high, DataOut disabled
		}
	//
	// Read the 16 data bits.
	//
	for (uiBitCount = 0, usPhyData = 0; uiBitCount < 16; uiBitCount++)
		{
		UCHAR ucDataBit = (ReadWord (MGMT) & MGMT_MDI) >> 1;
		usPhyData <<= 1;
		usPhyData |= ucDataBit;
		WriteWord (MGMT, usControl);				// Clock low, DataOut disabled
		WriteWord (MGMT, usControl | MGMT_MCLK);	// Clock high, DataOut disabled
		}
	return (usPhyData);
	}

/*
 * Description:
 *	Read the revision register of the SMSC91C100FD.
 *
 * Return Value:
 *	The contents of the revision register.
 */
USHORT
Smsc100FdGetRevision (void)
	{
	//
	// Select the proper bank.
	//
	SelectBank (BANK3);
	//
	// Read the Revision register.
	//
	return (ReadWord (REVISION));
	}


BOOL Smsc100ReadIPFromEEPROMData(DWORD *pdwIP, DWORD *pdwSubnetMask)	{
	USHORT usIPAddressHigh, usIPAddressLow, usSubnetMaskHigh, usSubnetMaskLow;
	PSMSC100FDEEPROM pSmsc100FdEEProm = (PSMSC100FDEEPROM)0;

	if (!Smsc100FdReadEEPROM ((UINT16)&pSmsc100FdEEProm->ucIp[0]/*0x23*/, &usIPAddressLow) || !Smsc100FdReadEEPROM ((UINT16)&pSmsc100FdEEProm->ucIp[1], &usIPAddressHigh) || !Smsc100FdReadEEPROM ((UINT16)&pSmsc100FdEEProm->ucSubnetMask[0], &usSubnetMaskLow) || !Smsc100FdReadEEPROM ((UINT16)&pSmsc100FdEEProm->ucSubnetMask[0], &usSubnetMaskHigh))
		return (FALSE);

	*pdwIP = ((ULONG)usIPAddressHigh << 16) | usIPAddressLow;
	*pdwSubnetMask = ((ULONG)usSubnetMaskHigh << 16) | usSubnetMaskLow;
	return (TRUE);
}

BOOL Smsc100UpdateEEPROMIPData (DWORD dwIP, DWORD dwSubnetMask)
{
	DWORD dwPrevIP, dwPrevSubnetMask;
	PSMSC100FDEEPROM pSmsc100FdEEProm = (PSMSC100FDEEPROM)0;

	if (!Smsc100ReadIPFromEEPROMData(&dwPrevIP, &dwPrevSubnetMask))
		return (FALSE);
	if (dwPrevIP != dwIP)
		{
		if (!Smsc100FdWriteEEPROM ((UINT16)&pSmsc100FdEEProm->ucIp[0], (WORD)(dwIP)))
			return (FALSE);
		if (!Smsc100FdWriteEEPROM ((UINT16)&pSmsc100FdEEProm->ucIp[1], (WORD)(dwIP >> 16)))
			return (FALSE);
		}

	if (dwPrevSubnetMask != dwSubnetMask)
		{
		if (!Smsc100FdWriteEEPROM ((UINT16)&pSmsc100FdEEProm->ucSubnetMask[0], (WORD)(dwSubnetMask)))
			return (FALSE);
		if (!Smsc100FdWriteEEPROM ((UINT16)&pSmsc100FdEEProm->ucSubnetMask[1], (WORD)(dwSubnetMask >> 16)))
			return (FALSE);
		}
	return (TRUE);
}

⌨️ 快捷键说明

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