📄 drv_8019.c
字号:
void ei_rx_overrun( void )
{
byte was_txing, must_resend = 0;
//print_int("OVER");
/* Record whether a Tx was in progress
and then issue the stop command. */
was_txing = EN_CMD & EN_TRANS;
EN_CMD = EN_NODMA + EN_PAGE0 + EN_STOP;
delay_1ms(2); /* I don't know exactly time yet.. at least 2ms */
/** Reset RBCR[01] back to zero as per magic incantation. */
EN0_RCNTLO = 0x00;
EN0_RCNTHI = 0x00;
/* See if any Tx was interrupted or not. According to NS, this
step is vital, and skipping it will cause no end of havoc. */
if (was_txing) {
if (!(EN0_ISR & (ENISR_TX + ENISR_TX_ERR))) must_resend = 1;
}
/* Have to enter loopback mode and then restart the NIC before
you are allowed to slurp packets up off the ring. */
EN0_TXCR = E8390_TXOFF;
EN_CMD = EN_NODMA + EN_PAGE0 + EN_START;
/* Clear the Rx ring of all the debris(颇祈), and ack the interrupt. */
ei_receive();
EN0_ISR = ENISR_OVER;
/* Leave loopback mode, and resend any packet that got stopped. */
EN0_TXCR = E8390_TXCONFIG;
if (must_resend) EN_CMD = EN_NODMA + EN_PAGE0 + EN_START + EN_TRANS;
}
void ethernet_packet_tx_test(void)
{
byte i,temp;
word test_packet1_size,test_packet3_size;
code byte test_packet1[] = {0x00, 0x10, 0x4b, 0x18, 0xd8, 0x30, 0x00, 0x10,\
0x4b, 0x18, 0xd8, 0x31, 0x08, 0x00, 0x45, 0x00,\
0x00, 0x30, 0x05, 0x11, 0x40, 0x00, 0x80, 0x06,\
0x00, 0x00, 0xca, 0x1e, 0x14, 0xac, 0xca, 0x1e,\
0x14, 0xaa, 0x00, 0x50, 0x04, 0x47, 0xb2, 0x0e,\
0x02, 0x66, 0x4c, 0xb8, 0xec, 0x0a, 0x70, 0x12,\
0x44, 0x70, 0x8f, 0x3d, 0x00, 0x00, 0x02, 0x04,\
0x05, 0xb4, 0x01, 0x01, 0x04, 0x02};
code byte test_packet3[] = {0x00, 0x10, 0x4b, 0x18, 0xd8, 0x30, 0x00, 0x10,\
0x4b, 0x18, 0xd8, 0x31, 0x08, 0x00, 0x45, 0x00,\
0x00, 0x28, 0x04, 0xc6, 0x40, 0x00, 0x80, 0x06,\
0x38, 0x77, 0xca, 0x1e, 0x14, 0xac, 0xca, 0x1e,\
0x14, 0xaa, 0x04, 0x47, 0x00, 0x50, 0x91, 0xf1,\
0xa8, 0x98, 0xc3, 0x14, 0xe1, 0xcb, 0x50, 0x10,\
0x44, 0x70, 0xc9, 0xcf, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00 };
EN0_IMR = 0x00; /* 价脚吝俊绰 牢磐反飘啊 救吧府霸 阜酒 初绰促. */
test_packet1_size = sizeof(test_packet1);
test_packet3_size = sizeof(test_packet3);
/* 'code' is important.. other command is of no use for example static.. remember this situation */
/* content express that client tried to connect http web server i.e. one of three way handshaking */
for (i=0;i<1;i++){ /* if you transmit packets above 3, this chip was out of order.. */
while ((temp=EN_CMD) & EN_TRANS);
DMA_write(test_packet1, 0x4000, test_packet1_size);
EN0_TPSR = NE_START_PG; /* Transmit starting page */
EN0_TCNTLO = test_packet1_size; /* Low byte of tx byte count */
EN0_TCNTHI = 0; /* High byte of tx byte count Transmit byte count register */
EN_CMD = EN_PAGE0 + EN_NODMA + EN_TRANS + EN_START; /* Transmit a frame */
while(EN_CMD & EN_TRANS){
print("\n\rTransmit Status Reg. : ");
temp = EN0_TSR;
putb_ser(temp);
}
print("\n\rTransmit Status Reg. : ");
temp = EN0_TSR;
putb_ser(temp);
DMA_read(0x4000,test_packet1_size);
delay(100);
print("\n\r");
DMA_write(test_packet3, 0x4000, test_packet3_size);
EN0_TPSR = NE_START_PG; /* Transmit starting page */
EN0_TCNTLO = test_packet3_size; /* Low byte of tx byte count */
EN0_TCNTHI = 0; /* High byte of tx byte count Transmit byte count register */
EN_CMD = EN_PAGE0 + EN_NODMA + EN_TRANS + EN_START; /* Transmit a frame */
while(EN_CMD & EN_TRANS){
print("\n\rTransmit Status Reg. : ");
temp = EN0_TSR;
putb_ser(temp);
//print("."); /* this message was sent on transmission */
}
print("\n\rTransmit Status Reg. : ");
temp = EN0_TSR;
putb_ser(temp);
DMA_read(0x4000,test_packet3_size);
}
EN0_IMR = ENISR_ALL; /* INTerrupt mask reg */
}
void ethernet_register_test(void) /* All Register test */
{
byte i,read,write;
print("\n\r------------------------------------------------------------------------");
print("\n\rAddr Page0 Page1 Page2 Page3");
print("\n\r Write/Read Write/Read Write/Read Write/Read");
print("\n\r------------------------------------------------------------------------");
for (i=0; i < 16; i++) {
/* Page0 select */
EN_CMD = EN_PAGE0 + EN_NODMA + EN_START;
print("\n\r"); putb_ser(i);print(" ");
write = EN_PAGE0 + EN_NODMA + EN_START;
/* outportb(i,write); */
putb_ser(write);
print(" "); read = inportb(i);
putb_ser(read); print(" ");
/* Page1 select */
EN_CMD = EN_PAGE1 + EN_NODMA + EN_START;
write = EN_PAGE1 + EN_NODMA + EN_START;
/* outportb(i,write); */
putb_ser(write); print(" ");
read = inportb(i);
putb_ser(read); print(" ");
/* Page2 select */
EN_CMD = EN_PAGE2 + EN_NODMA + EN_START;
print("x ");
read = inportb(i);
putb_ser(read); print(" ");
/* Page3 select */
EN_CMD = EN_PAGE3 + EN_NODMA + EN_START;
write = EN_PAGE3 + EN_NODMA + EN_START;
/* outportb(i,write); */
putb_ser(write);
print(" ");
read = inportb(i);
putb_ser(read); print(" ");
}
print("\n\r------------------------------------------------------------------------\n\r");
}
/*****************************************************************************/
/* D M A Write */
/*****************************************************************************/
void DMA_write(byte *buffer, word StartAddr, word Count)
{
word loop;
//print("\n\rDMA write : ");
EN_CMD = EN_PAGE0 + EN_NODMA + EN_START; /* Remote DMA, Start the chip, clear reset */
EN0_RCNTLO = (byte)(Count & 0xff); /* LSB Remote byte count reg */
EN0_RCNTHI = (byte)(Count >> 8); /* MSB Remote byte count reg */
EN0_RSARLO = (byte)(StartAddr & 0xff); /* LSB Remote start address reg */
EN0_RSARHI = (byte)(StartAddr >> 8); /* MSB Remote start address reg */
EN_CMD = EN_PAGE0 + EN_RWRITE + EN_START; /* Remote Write, Start the chip, clear reset */
for(loop=0;loop < Count;loop++){
EN_DATA = *buffer++;
//putb_ser(*buffer++);
}
}
/*****************************************************************************/
/* D M A Read */
/*****************************************************************************/
#ifndef WARNING
void DMA_read(word StartAddr, word Count)
{
byte temp;
word loop;
//print("\n\rDMA read : ");
EN_CMD = EN_PAGE0 + EN_RREAD + EN_STOP;
/* Set Remote byte count */
EN0_RCNTLO = (byte)(Count & 0xff); /* Low byte of tx byte count */
EN0_RCNTHI = (byte)(Count >> 8); /* High byte of tx byte count Transmit byte count register */
/* Set Remote Start Address */
EN0_RSARLO = (byte)(StartAddr & 0xff); /*LSB Remote start address reg */
EN0_RSARHI = (byte)(StartAddr >> 8); /* MSB Remote start address reg */
EN_CMD = EN_PAGE0 + EN_RREAD + EN_START; /* Remote Read, Start the chip, clear reset */
for(loop=0;loop < Count;loop++){
temp = EN_DATA;
putb_ser(temp);
}
}
#endif
void ethernet_test(void)
{
byte temp1,temp2;
print("\n\n\r/*****************************************************************/\n\r");
print("/* RTL8019AS TEST ROUTINE 0.5.2 */\n\r");
print("/* If you see 0x50 and 0x70 or 'P' and 'p', it operate well */\n\r");
print("/*****************************************************************/\n\r");
temp1 = inportb(0x000a); /* EN0_8019ID0 */
temp2 = inportb(0x000b); /* EN0_8019ID1 */
putb_ser(temp1);
putb_ser(temp2);
if ((temp1 != 0x50)|(temp2 != 0x70)) {
print(" Circuit have H/W problem.\n\r");
}
print(" Circuit OK!\n\r");
#ifdef STRING_TEST
test = 0x1234;
printf("\n\n\r%x %d ",test,test);
putb_ser(test);
test1 = (byte)test;
printf("\n\n\r%x %d ",test1,test1);
#endif
}
/*****************************************************************************/
/* RTL8019AS Initialize */
/*****************************************************************************/
void ethernet_init(void)
{
word i;
#ifdef RTL8019AS_ID_CHECK
ethernet_test();
#endif
HW_RESET = 1; /* Hardware RESET. when EN_RESET = 0; is Software */
for (i=0;i<DELAY;i++); /* 府悸饶 2ms 瘤楷. 救登搁 窍靛傀绢 府悸阑 port 1栏肺 秦具窃 */
HW_RESET = 0;
//EN_RESET = 0x00; /* very important !!!!! */
for (i=0;i<DELAY;i++);
EN_CMD = EN_PAGE0 + EN_NODMA + EN_STOP; /* 00001010B: PS1 PS0 RD2 RD1 RD0 TXP STA STP */
EN0_DCFG = ENDCFG_FT10 + ENDCFG_BMS + ENDCFG_BOS; /* ?FIFO treshold 8byte !!,normal operation, byte transfer mode selection */
/* Clear the remote byte count registers. */
EN0_RCNTHI = 0x00; /* MSB remote byte count reg */
EN0_RCNTLO = 0x00; /* LSB remote byte count reg */
EN0_RXCR = E8390_RXOFF; /* RX configuration reg Monitor mode (no packet receive) */
EN0_TXCR = E8390_TXOFF; /* TX configuration reg set internal loopback mode */
EN0_TPSR = NE_START_PG;
EN0_STARTPG = RX_START_PG ; /* 菩哦 荐脚矫俊 肺拿 DMA啊 荐脚窍绰 其捞瘤甫 瘤沥茄促. 46h */
/* Starting page of ring buffer. First page of Rx ring buffer 46h*/
EN0_BOUNDARY = RX_START_PG; /* Boundary page of ring buffer */
EN0_STOPPG = NE_STOP_PG; /* Ending page +1 of ring buffer */
EN_CMD = EN_PAGE1 + EN_NODMA + EN_STOP;
EN1_CURR = RX_START_PG + 1; /* RX_CURR_PG; Current memory page = RX_CURR_PG ? */
current_page = RX_START_PG + 1; /* assert boundary+1 */
next_pkt = RX_START_PG + 1;
EN_CMD = EN_PAGE0 + EN_NODMA + EN_STOP;
EN0_ISR = 0xff; /* INTerrupt stauts reg */
/* Host绰 牢磐反飘甫 老栏虐绰 巴阑 茫酒郴扁困秦 佬绰促.
阿 厚飘绰 包访等 bit俊 1阑 结 持澜栏肺辑 努府绢 等促.
弊巴篮 颇况诀 饶俊 馆靛矫 努府绢 登绢具茄促.(must) */
EN0_IMR = 0; /* INTerrupt mask reg = Disable all Interrupt */
EN_CMD = EN_NODMA + EN_PAGE1 + EN_STOP; /* Select page 1, remote DMA */
EN1_PAR0 = 0x12;
EN1_PAR1 = 0x34;
EN1_PAR2 = 0x56;
EN1_PAR3 = 0x78;
EN1_PAR4 = 0x9A;
EN1_PAR5 = 0xBC;
/* Initialize the multicast list to accept-all. If we enable multicast
the higher levels can do the filtering. multicast filter mask array (8 bytes) */
EN1_MAR0 = 0xff;
EN1_MAR1 = 0xff;
EN1_MAR2 = 0xff;
EN1_MAR3 = 0xff;
EN1_MAR4 = 0xff;
EN1_MAR5 = 0xff;
EN1_MAR6 = 0xff;
EN1_MAR7 = 0xff;
EN_CMD = EN_PAGE0 + EN_NODMA + EN_STOP; /* 00001010B: PS1 PS0 RD2 RD1 RD0 TXP STA STP */
EN0_ISR = 0xff; /* Individual bits are cleared by writing a "1" into it. */
/* It must be cleared after power up. */
EN0_IMR = ENISR_ALL; /* INTerrupt mask reg */
EN_CMD = EN_PAGE0 + EN_NODMA + EN_START;
EN0_TXCR = ENTXCR_TXCONFIG; /* xmit on. */
/* 3c503 TechMan says rxconfig only after the NIC is started. */
EN0_RXCR = ENRXCR_RXCONFIG; /* rx on(broadcasts, no multicast,errors */
EN0_RXCR = 0; /* rx on(broadcasts, no multicast,errors */
CONFIG1 = 0x90; /* IRQ enable + INT0:IRQ2/9(pin 4) + I/O BASE(300H) */
CONFIG2 = 0x00;
CONFIG3 = 0xf0;
CONFIG4 = 0x00;
EthRxBufRdPtr = 0;
EthRxBufWrPtr = EthRxBufRdPtr + 1;
EN_CMD = EN_PAGE0 + EN_NODMA + EN_START;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -