📄 rtl8019as.c
字号:
WORD MACGetFreeRxSize(void)
{
BYTE NICWritePtr;
BYTE temp;
WORD_VAL tempVal;
NICPut(CMDR, 0x60);
NICWritePtr = NICGet(CURRP);
NICPut(CMDR, 0x20);
if ( NICWritePtr < NICCurrentRdPtr )
temp = (RXSTOP - NICCurrentRdPtr) + NICWritePtr;
else
temp = NICWritePtr - NICCurrentRdPtr;
temp = RXPAGES - temp;
tempVal.v[1] = temp;
tempVal.v[0] = 0;
return tempVal.Val;
}
BOOL MACIsLinked(void)
{
BYTE_VAL temp;
// Select Page 3
NICPut(CMDR, 0xe0);
// Read CONFIG0.
temp.Val = NICGet(0x03);
// Reset to page 0.
NICPut(CMDR, 0x20);
// Bit 2 "BNC" will be '0' if LINK is established.
return (temp.bits.b2 == 0);
}
BOOL MACGetHeader(MAC_ADDR *remote, BYTE* type)
{
NE_PREAMBLE header;
BYTE NICWritePtr;
WORD_VAL temp;
*type = MAC_UNKNOWN;
// Reset NIC if overrun has occured.
if ( NICGet(ISR) & 0x10 )
{
#if 1
NICPut(CMDR, 0x21);
{
BYTE i;
for(i = 0; i < 10; i++)
{
DelayMs(20);
}
}
NICPut(RBCR0, 0);
NICPut(RBCR1, 0);
NICPut(TCR, 0x02);
NICPut(CMDR, 0x20);
MACDiscardRx();
NICPut(ISR, 0xff);
NICPut(TCR, 0x00);
return FALSE;
#else
MACInit();
return FALSE;
#endif
}
NICPut(CMDR, 0x60);
NICWritePtr = NICGet(CURRP);
NICPut(CMDR, 0x20);
if ( NICWritePtr != NICReadPtr )
{
temp.v[1] = NICReadPtr;
temp.v[0] = 0;
NICSetAddr(temp.Val);
MACGetArray((BYTE*)&header, sizeof(header));
// Validate packet length and status.
if ( header.Status.PRX && (header.ReceivedBytes >= MINFRAMEC) && (header.ReceivedBytes <= MAXFRAMEC) )
{
header.Type.Val = swaps(header.Type.Val);
memcpy((void*)remote->v, (void*)header.SourceMACAddr.v, sizeof(*remote));
if ( (header.Type.v[1] == 0x08) && ((header.Type.v[0] == ETHER_IP) || (header.Type.v[0] == ETHER_ARP)) )
*type = header.Type.v[0];
}
NICCurrentRdPtr = NICReadPtr;
NICReadPtr = header.NextPacketPointer;
return TRUE;
}
return FALSE;
}
void MACPutHeader(MAC_ADDR *remote,
BYTE type,
WORD dataLen)
{
WORD_VAL mytemp;
BYTE etherType;
NICPut(ISR, 0x0a);
mytemp.v[1] = TxBuffers[NICCurrentTxBuffer].Index;
mytemp.v[0] = 0;
NICSetAddr(mytemp.Val);
MACPutArray((BYTE*)remote, sizeof(*remote));
MACPut(AppConfig.MyMACAddr.v[0]);
MACPut(AppConfig.MyMACAddr.v[1]);
MACPut(AppConfig.MyMACAddr.v[2]);
MACPut(AppConfig.MyMACAddr.v[3]);
MACPut(AppConfig.MyMACAddr.v[4]);
MACPut(AppConfig.MyMACAddr.v[5]);
if ( type == MAC_IP )
etherType = ETHER_IP;
else
etherType = ETHER_ARP;
MACPut(0x08);
MACPut(etherType);
dataLen += (WORD)sizeof(ETHER_HEADER);
if ( dataLen < MINFRAME ) // 64 ) // NKR 4/23/02
dataLen = 64; // MINFRAME;
mytemp.Val = dataLen;
NICPut(TBCR0, mytemp.v[0]);
NICPut(TBCR1, mytemp.v[1]);
}
void MACFlush(void)
{
BYTE i;
NICPut(TPSR, TxBuffers[NICCurrentTxBuffer].Index);
NICPut(CMDR, 0x24);
// After every transmission, adjust transmit pointer to
// next free transmit buffer.
for ( i = 0; i < MAX_DATA_BUFFERS; i++ )
{
if ( TxBuffers[i].bFree )
{
NICCurrentTxBuffer = i;
return;
}
}
}
static void NICReset(void)
{
NIC_DATA_TRIS = 0;
NIC_ADDR_LATCH_TRIS = 0;
// Write address 0x00
NIC_ADDR_IO = 0;
NIC_ADDR_TRIS = 0x00;
NIC_ADDR_LATCH_IO = 1;
Nop();
NIC_ADDR_LATCH_IO = 0;
NIC_ADDR_LATCH_IO = 1;
#if defined(PICDEMNET)
INTCON2bits.RBPU = 0;
#endif
#if defined(C30)
// Set control pins as digital
NIC_RESET_ADPCFG = 1; // Ensure RSTDRV is digital
NIC_IOW_ADPCFG = 1; // Ensure IOWR is digital
NIC_IOR_ADPCFG = 1; // Ensure IORD is digital
#if defined(DSPICDEMNET1) || defined(DSPICDEMNET2)
NIC_ADDR_LATCH_ADPCFG = 1; // Ensure ALE is digital
#endif
#endif
NIC_IOW_IO = 1;
NIC_IOR_IO = 1;
NIC_RESET_IO = 1;
NIC_IOW_TRIS = 0;
NIC_IOR_TRIS = 0;
NIC_RESET_TRIS = 0;
// Reset pulse must be at least 800 ns.
Delay10us(1);
NIC_RESET_IO = 0;
}
// -----------------------------------------------------------------------------
// Subroutine: Realtek Control Register Selection and Data Write
// -----------------------------------------------------------------------------
static void NICPut(BYTE reg, WORD data)
{
// Set the proper address
NIC_ADDR_TRIS = 0x00;
NIC_ADDR_LATCH_IO = 1;
NIC_ADDR_IO = reg;
Nop();
NIC_ADDR_LATCH_IO = 0;
// Send the data
NIC_DATA_TRIS = 0x0000;
NIC_DATA_IO = data;
NIC_IOW_IO = 0;
#if INSTR_FREQ > 5000000
Nop();
Nop();
#endif
#if INSTR_FREQ > 10000000
Nop();
Nop();
#endif
#if INSTR_FREQ > 15000000
Nop();
Nop();
#endif
#if INSTR_FREQ > 20000000
Nop();
Nop();
#endif
#if INSTR_FREQ > 25000000
Nop();
Nop();
#endif
#if INSTR_FREQ > 30000000
Nop();
Nop();
#endif
#if INSTR_FREQ > 35000000
Nop();
Nop();
#endif
NIC_ADDR_LATCH_IO = 1;
NIC_IOW_IO = 1;
NIC_DATA_TRIS = 0xFFFF;
}
// -----------------------------------------------------------------------------
// Subroutine: Realtek Control Register Selection and Data Read
// -----------------------------------------------------------------------------
static BYTE NICGet(BYTE reg)
{
BYTE val;
// Set the read address
NIC_ADDR_TRIS = 0x00;
NIC_ADDR_LATCH_IO = 1;
NIC_ADDR_IO = reg;
Nop();
NIC_ADDR_LATCH_IO = 0;
// Perform the read
NIC_DATA_TRIS = 0xFFFF;
NIC_IOR_IO = 0;
#if INSTR_FREQ > 5000000
Nop();
Nop();
#endif
#if INSTR_FREQ > 10000000
Nop();
Nop();
#endif
#if INSTR_FREQ > 15000000
Nop();
Nop();
#endif
#if INSTR_FREQ > 20000000
Nop();
Nop();
#endif
#if INSTR_FREQ > 25000000
Nop();
Nop();
#endif
#if INSTR_FREQ > 30000000
Nop();
Nop();
#endif
#if INSTR_FREQ > 35000000
Nop();
Nop();
#endif
val = NIC_DATA_IO;
NIC_ADDR_LATCH_IO = 1;
NIC_IOR_IO = 1;
return val;
}
static void NICSetAddr(WORD addr)
{
WORD_VAL t;
t.Val = addr;
NICPut(ISR, 0x40);
NICPut(RSAR0, t.v[0]);
NICPut(RSAR1, t.v[1]);
}
void MACSetRxBuffer(WORD offset)
{
WORD_VAL t;
t.v[1] = NICCurrentRdPtr;
t.v[0] = sizeof(NE_PREAMBLE);
t.Val += offset;
NICSetAddr(t.Val);
}
void MACSetTxBuffer(BUFFER buffer, WORD offset)
{
WORD_VAL t;
NICCurrentTxBuffer = buffer;
t.v[1] = TxBuffers[NICCurrentTxBuffer].Index;
t.v[0] = sizeof(ETHER_HEADER);
t.Val += offset;
NICSetAddr(t.Val);
}
WORD MACGetOffset(void)
{
WORD_VAL t;
t.v[1] = NICGet(RSAR1);
t.v[0] = NICGet(RSAR0);
return t.Val;
}
#endif //#if defined(NIC_IOW_IO)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -