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 + -
显示快捷键?