dm9000.c
来自「该BSP是基于PXA270+WINCE的BSP」· C语言 代码 · 共 1,301 行 · 第 1/3 页
C
1,301 行
// issue EEPROM read command<2>
DeviceWritePort(DM9_EPCNTL,(1<<2));
// wait until status bit<0> cleared
// 80 uS, 5 times
if(!DevicePolling(DM9_EPCNTL,(1<<0),0x00,80,5))
return (U16)-1;
// stop command
DeviceWritePort(DM9_EPCNTL,0);
// retrive data
lowbyte = (U16)DeviceReadPort(DM9_EPLOW);
highbyte = (U16)DeviceReadPort(DM9_EPHIGH);
return ((highbyte<<8) | lowbyte);
}
typedef enum {
BYTE_MODE=1,
WORD_MODE=2,
DWORD_MODE=4,
} DEVICE_IO_MODE;
typedef enum {
NIC_HW_OK,
NIC_HW_TX_IDLE,
NIC_HW_TX_BUSY,
} NIC_HW_STATUS_TYPE;
#define REPORT(evt,val)
#define CHECK_SHUTDOWN()
/********************************************************************************
*
* EEPROM 93C46 Parameters
*
********************************************************************************/
#define BITS_PER_BYTE 8
#define EEPROM_93C46_BITS 1024
#define EEPROM_93C46_SIZE (EEPROM_93C46_BITS/BITS_PER_BYTE)
#define EEPROM_93C46_MAX_CYCLES 25
#define EEPROM_93C46_ADDRESS_BITS 6
#define EEPROM_93C46_DATA_BITS 16
#define EEPROM_93C46_DELAY 20
typedef unsigned short EEPROM_93C46_DATA_TYPE;
/********************************************************************************
*
* EEPROM Parameters
*
********************************************************************************/
#define EEPROM_SIZE EEPROM_93C46_SIZE
#define EEPROM_MAX_CYCLES EEPROM_93C46_MAX_CYCLES
#define EEPROM_DELAY EEPROM_93C46_DELAY
#define EEPROM_ADDRESS_BITS EEPROM_93C46_ADDRESS_BITS
#define EEPROM_DATA_BITS EEPROM_93C46_DATA_BITS
#define EEPROM_DATA_TYPE EEPROM_93C46_DATA_TYPE
/********************************************************************************
*
* PHY Parameters
*
********************************************************************************/
#define MII_INTERNAL_PHY_ADDR 1
#define MII_PHY_ADDR_LEN 5
#define MII_REG_ADDR_LEN 5
#define MII_DELAY 20
#define MII_PREAMBLES 32
#define MII_OFFSET_BMCR 0x00
#define MII_OFFSET_BMSR 0x01
#define MII_OFFSET_OUI_M 0x02
#define MII_OFFSET_OUI_L 0x03
#define MII_OFFSET_ANAR 0x04
#define MII_OFFSET_ALPAR 0x05
/********************************************************************************
*
* Configuration definitions
*
********************************************************************************/
#define CONNECTION_NONE 0x00000000
#define CONNECTION_AUTO 0x00000001
#define CONNECTION_10_HALF 0x00000002
#define CONNECTION_10_FULL 0x00000003
#define CONNECTION_100_HALF 0x00000004
#define CONNECTION_100_FULL 0x00000005
#define CONNECTION_1M8_HPNA 0x00000100
#define CONNECTION_10M8_HPNA 0x00000200
/********************************************************************************
*
* CRC32 Routine
*
* This routine calculates the CRC based on the following polynominal
* x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
*
* About the CRC value of one EEPROM
*
* eeprom<126-127> = CRC value = (U16)crc32(eeprom<0..125>);
*
*
*
*******************************************************************************/
U32 DeviceCalculateCRC32(
PU8 ptrBuffer,
int nLength,
BOOL bReverse)
{
U32 Crc, Carry;
int i, j;
U8 CurByte;
Crc = 0xffffffff;
for (i = 0; i < nLength; i++) {
CurByte = ptrBuffer[i];
for (j = 0; j < 8; j++) {
Carry = ((Crc & 0x80000000) ? 1 : 0) ^ (CurByte & 0x01);
Crc <<= 1;
CurByte >>= 1;
if (Carry) {
Crc = (Crc ^ 0x04c11db6) | Carry;
}
}
}
for (i=0, Carry=0x0L; i < 32 ; i++) {
Carry <<= 1;
if (Crc & 0x1) {
Carry |= 0x1L;
}
Crc >>= 1;
}
return bReverse?~Carry:Carry;
}
U16 DeviceWriteEeprom( U32 uWordAddress, U16 uValue);
void EDeviceLoadEeprom(void)
{
int n;
static U8 m_szEeprom[EEPROM_SIZE];
EEPROM_DATA_TYPE *pcurr=(EEPROM_DATA_TYPE*)&m_szEeprom[0];
for(n=0;n<(DIM(m_szEeprom)/sizeof(EEPROM_DATA_TYPE));n++,pcurr++)
{
*pcurr = DeviceReadEeprom(n);
} // of for offset n
DeviceCalculateCRC32(&m_szEeprom[0],DIM(m_szEeprom)-2,TRUE);
pcurr=(EEPROM_DATA_TYPE*)&m_szEeprom[0];
for(n=0;n<(DIM(m_szEeprom)/sizeof(EEPROM_DATA_TYPE));n++,pcurr++)
{
OALMSG("%X ",*pcurr);
if(((n+1)%8)==0)OALMSG("\n");
} // of for offset n
#if 0
for(n=0;n<(DIM(m_szEeprom)/sizeof(EEPROM_DATA_TYPE));n++)
{
OALMSG("%X ",DeviceWriteEeprom(n,n+5));
if(((n+1)%8)==0)OALMSG("\n");
} // of for offset n
pcurr=(EEPROM_DATA_TYPE*)&m_szEeprom[0];
for(n=0;n<(DIM(m_szEeprom)/sizeof(EEPROM_DATA_TYPE));n++,pcurr++)
{
*pcurr = DeviceReadEeprom(n);
} // of for offset n
DeviceCalculateCRC32(&m_szEeprom[0],DIM(m_szEeprom)-2,TRUE);
pcurr=(EEPROM_DATA_TYPE*)&m_szEeprom[0];
for(n=0;n<(DIM(m_szEeprom)/sizeof(EEPROM_DATA_TYPE));n++,pcurr++)
{
OALMSG("%X ",*pcurr);
if(((n+1)%8)==0)OALMSG("\n");
} // of for offset n
#endif
}
U16 DeviceWriteEeprom(
U32 uWordAddress,
U16 uValue)
{
// assign the register offset
DeviceWritePort(DM9_EPADDR,uWordAddress);
// put data
DeviceWritePort(DM9_EPLOW, LOW_BYTE(uValue));
DeviceWritePort(DM9_EPHIGH,HIGH_BYTE(uValue));
// issue EEPROM write enable<4> and write command<1>
DeviceWritePort(DM9_EPCNTL,MAKE_MASK2(4,1));
// wait until status bit<0> cleared
DevicePolling(DM9_EPCNTL,MAKE_MASK(0),0x00,20,-1);
// stop command
DeviceWritePort(DM9_EPCNTL,0);
return uValue;
}
void EDeviceInitialize(
int nResetCounts)
{
U32 val;
// reset member varialbes
m_uLastAddressPort = (U32)-1;
DeviceWritePort(0x1f, 0x00);
mWait(20);
// software reset the device
DeviceWritePort(DM9_NCR, 0x03);
mWait(20);
DeviceWritePort(DM9_NCR, 0x03);
mWait(20);
// read the io orgnization
// ISR<7:6> == x1, dword
// ISR<7:6> == 0x, word
// ISR<7:6> == 10, byte mode
val = DeviceReadPort(DM9_ISR);
if(val & MAKE_MASK(6))
{
m_nIoMode = DWORD_MODE;
m_nIoMaxPad = 3;
}
else if(!(val & MAKE_MASK(7)))
{
m_nIoMode = WORD_MODE;
m_nIoMaxPad = 1;
}
else
{
m_nIoMode = BYTE_MODE;
m_nIoMaxPad = 0;
}
// activate internal phy
// select GPIO 0<0>, set it to output
DeviceWritePort(DM9_GPCR, (1<<0));
mWait(20);
// output zero to activate internal phy
DeviceWritePort(DM9_GPR, 0x00);
mWait(20);
// Enable memory chain
DeviceWritePort(DM9_IMR, (1<<7));
mWait(20);
DeviceWritePort( DM9_TXCR, 0); /* TX Polling clear */
mWait(20);
DeviceWritePort( DM9_BACKTH, 0x3f); /* Less 3kb, 600us */
mWait(20);
DeviceWritePort( DM9_SMCR, 0); /* Special Mode */
mWait(20);
DeviceWritePort( DM9_NSR, 0x2c); /* clear TX status */
mWait(20);
DeviceWritePort( DM9_ISR, 0x0f); /* Clear interrupt status */
mWait(20);
OALMSG("val =%X, m_nIoMode:%X m_nIoMaxPad:%X\r\n",val,m_nIoMode,m_nIoMaxPad);
DeviceWritePort(DM9_PAR0+0,(U32)0xc000);
DeviceWritePort(DM9_PAR0+1,(U32)0x2826);
DeviceWritePort(DM9_PAR0+2,(U32)0x3096);
/* Activate DM9000A/DM9010 */
DeviceWritePort(DM9_RXCR, 0x30 | 1 | MAKE_MASK(1) ); /* RX enable */
// DeviceWritePort(DM9_RXCR, 1 | MAKE_MASK(1) ); /* RX enable */
DeviceWritePort(DM9_IMR, 0x80); // Enable TX/RX interrupt mask
}
//------------------------------------------------------------------------------
//
// Function: DM9000AInit
//
BOOL DM9000AInit(BYTE *pAddress, DWORD dwMultiplier, USHORT mac[3])
{
U32 val;
OALMSG("+DM9000AInit(0x%X, %B:%B:%B:%B:%B:%B)\r\n",pAddress, mac[0]&0xFF, mac[0]>>8, mac[1]&0xFF, mac[1]>>8,mac[2]&0xFF, mac[2]>>8);
// Save address
g_pDM9000 = (volatile DM9000_REGS*)pAddress;
g_pDM9000Frank = pAddress;
// DebugSegment7(0x08);
val = DeviceReadPort(0x2a);
val |= DeviceReadPort(0x2b) << 8;
val |= DeviceReadPort(0x28) << 16;
val |= DeviceReadPort(0x29) << 24;
OALMSG("[dm9: Chip signature is 0x%X\r\n", val);
if( ( DeviceReadPort(DM9_VIDL) != LOW_BYTE(DM9000_VID) ) ||
( DeviceReadPort(DM9_VIDH) != HIGH_BYTE(DM9000_VID) ) ||
( DeviceReadPort(DM9_PIDL) != LOW_BYTE(DM9000_PID) ) ||
( DeviceReadPort(DM9_PIDH) != HIGH_BYTE(DM9000_PID) ) )
{
OALMSG("Unknown device\n");
// DebugSegment7(0x09);
}
// DebugSegment7(0x0a);
// EDeviceLoadEeprom();
EDeviceInitialize(0);
return TRUE;
}
PU8 DeviceWriteString(PU8 ptrBuffer, int nLength)
{
#if 1
int count;
PU16 pcurr=(PU16)ptrBuffer;
// count = (nLength + m_nIoMaxPad) / m_nIoMode;
switch (m_nIoMode)
{
case BYTE_MODE:
break;
case WORD_MODE:
{
#if 0
int i;
OALMSG("Len is %X \n",nLength);
for(i=0;i<nLength;i++,pcurr++)
{
OALMSG("%X ", *pcurr);
}
OALMSG("\n");
#endif
count = (nLength+1)/2;
pcurr=(PU16)ptrBuffer;
*(U16*)(g_pDM9000Frank + DM9000_ADDR_OFFSET) =(U16)(DM9_MWCMD);
for(;count--;pcurr++)
{
*(U16*)(g_pDM9000Frank + DM9000_DATA_OFFSET) = *pcurr;
}
}
break;
case DWORD_MODE:
break;
default:
break;
} // of switch
#endif
return ptrBuffer;
}
//------------------------------------------------------------------------------
//
// Function: DM9000ASendFrame
//
UINT16 DM9000ASendFrame(BYTE *pData, DWORD length)
{
/* fill data */
DeviceWriteString(pData,length);
DeviceWritePort(DM9_TXLENH,HIGH_BYTE(length));
DeviceWritePort(DM9_TXLENL,LOW_BYTE(length));
// TXCR<0>, issue TX request
DeviceWritePort(DM9_TXCR, MAKE_MASK(0));
return 0;
}
U8 check_rx_ready(U8 rxbyte)
{
if (!(rxbyte & 0x01))
return 0;
return ((rxbyte >> 4) | 0x01);
}
#pragma pack(push, 1)
typedef struct _RX_DESC
{
U8 rxbyte;
U8 status;
U16 length;
}RX_DESC;
typedef union{
U8 buf[4];
RX_DESC desc;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?