00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "global.h"
00023 #include "timer.h"
00024 #include "rprintf.h"
00025
00026 #include "ax88796.h"
00027
00028
00029 #include "ax88796conf.h"
00030
00031
00032 static unsigned char NextPage;
00033 static unsigned int CurrentRetreiveAddress;
00034
00035
00036 void nicInit(void)
00037 {
00038 ax88796Init();
00039 }
00040
00041 void nicSend(unsigned int len, unsigned char* packet)
00042 {
00043 ax88796BeginPacketSend(len);
00044 ax88796SendPacketData(packet, len);
00045 ax88796EndPacketSend();
00046 }
00047
00048 unsigned int nicPoll(unsigned int maxlen, unsigned char* packet)
00049 {
00050 unsigned int packetLength;
00051
00052 packetLength = ax88796BeginPacketRetreive();
00053
00054
00055 if( !packetLength )
00056 return 0;
00057
00058
00059 if( packetLength > maxlen )
00060 {
00061 ax88796EndPacketRetreive();
00062 return 0;
00063 }
00064
00065
00066 ax88796RetreivePacketData( packet, packetLength );
00067 ax88796EndPacketRetreive();
00068
00069 return packetLength;
00070 }
00071
00072 void nicGetMacAddress(u08* macaddr)
00073 {
00074 u08 tempCR;
00075
00076 tempCR = ax88796Read(CR);
00077 ax88796Write(CR,tempCR|PS0);
00078
00079 *macaddr++ = ax88796Read(PAR0);
00080 *macaddr++ = ax88796Read(PAR1);
00081 *macaddr++ = ax88796Read(PAR2);
00082 *macaddr++ = ax88796Read(PAR3);
00083 *macaddr++ = ax88796Read(PAR4);
00084 *macaddr++ = ax88796Read(PAR5);
00085
00086 ax88796Write(CR,tempCR);
00087 }
00088
00089 void nicSetMacAddress(u08* macaddr)
00090 {
00091 u08 tempCR;
00092
00093 tempCR = ax88796Read(CR);
00094 ax88796Write(CR,tempCR|PS0);
00095
00096 ax88796Write(PAR0, *macaddr++);
00097 ax88796Write(PAR1, *macaddr++);
00098 ax88796Write(PAR2, *macaddr++);
00099 ax88796Write(PAR3, *macaddr++);
00100 ax88796Write(PAR4, *macaddr++);
00101 ax88796Write(PAR5, *macaddr++);
00102
00103 ax88796Write(CR,tempCR);
00104 }
00105
00106 void nicRegDump(void)
00107 {
00108 ax88796RegDump();
00109 }
00110
00111
00112 void ax88796SetupPorts(void)
00113 {
00114 #if NIC_CONNECTION == MEMORY_MAPPED
00115
00116 sbi(MCUCR, SRE);
00117
00118
00119
00120
00121 #else
00122
00123 AX88796_ADDRESS_DDR = AX88796_ADDRESS_MASK;
00124
00125
00126 AX88796_DATA_DDR = 0x00;
00127 AX88796_DATA_PORT = 0xFF;
00128
00129
00130 sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN );
00131 sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN );
00132
00133 sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_READPIN );
00134 sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_WRITEPIN );
00135 #endif
00136
00137 sbi( AX88796_RESET_DDR, AX88796_RESET_PIN );
00138 }
00139
00140
00141 #if NIC_CONNECTION == MEMORY_MAPPED
00142 inline void ax88796Write(u08 address, u08 data)
00143 {
00144 *(volatile u08*)(AX88796_MEMORY_MAPPED_OFFSET + address) = data;
00145 }
00146 #else
00147 void ax88796Write(u08 address, u08 data)
00148 {
00149
00150 AX88796_ADDRESS_PORT = address | (AX88796_ADDRESS_PORT&~AX88796_ADDRESS_MASK);
00151
00152
00153 AX88796_DATA_DDR = 0xFF;
00154 AX88796_DATA_PORT = data;
00155
00156
00157 cbi(AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN);
00158 nop();
00159 nop();
00160 sbi(AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN);
00161
00162
00163 AX88796_DATA_DDR = 0x00;
00164 AX88796_DATA_PORT = 0xFF;
00165 }
00166 #endif
00167
00168
00169 #if NIC_CONNECTION == MEMORY_MAPPED
00170 inline u08 ax88796Read(u08 address)
00171 {
00172 return *(volatile u08*)(AX88796_MEMORY_MAPPED_OFFSET + address);
00173 }
00174 #else
00175 u08 ax88796Read(u08 address)
00176 {
00177 u08 data;
00178
00179
00180 AX88796_ADDRESS_PORT = address | (AX88796_ADDRESS_PORT&~AX88796_ADDRESS_MASK);
00181
00182
00183 cbi(AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN);
00184 nop();
00185 nop();
00186
00187 data = AX88796_DATA_PIN;
00188
00189
00190 sbi(AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN);
00191
00192 return data;
00193 }
00194 #endif
00195
00196
00197 void ax88796Init(void)
00198 {
00199 unsigned char tcrFduFlag;
00200
00201
00202 ax88796SetupPorts();
00203
00204
00205 sbi(AX88796_RESET_PORT, AX88796_RESET_PIN);
00206 delay_ms(100);
00207 cbi(AX88796_RESET_PORT, AX88796_RESET_PIN);
00208
00209
00210 ax88796Write(ISR, ax88796Read(ISR));
00211 delay_ms(50);
00212
00213
00214 ax88796Read(RSTPORT);
00215 while(ax88796Read(TR) & RST_B);
00216
00217 ax88796WriteMii(0x10,0x00,0x0800);
00218 delay_ms(255);
00219 ax88796WriteMii(0x10,0x00,0x1200);
00220
00221 ax88796Write(CR,(RD2|STOP));
00222 delay_ms(5);
00223 ax88796Write(DCR,DCR_INIT);
00224 ax88796Write(RBCR0,0x00);
00225 ax88796Write(RBCR1,0x00);
00226 ax88796Write(IMR,0x00);
00227 ax88796Write(ISR,0xFF);
00228 ax88796Write(RCR,0x20);
00229 ax88796Write(BNRY,RXSTART_INIT);
00230 ax88796Write(PSTART,RXSTART_INIT);
00231 ax88796Write(PSTOP,RXSTOP_INIT);
00232
00233
00234 ax88796Write(CR,(PS0|RD2|STOP));
00235
00236 ax88796Write(PAR0+0, AX88796_MAC0);
00237 ax88796Write(PAR0+1, AX88796_MAC1);
00238 ax88796Write(PAR0+2, AX88796_MAC2);
00239 ax88796Write(PAR0+3, AX88796_MAC3);
00240 ax88796Write(PAR0+4, AX88796_MAC4);
00241 ax88796Write(PAR0+5, AX88796_MAC5);
00242
00243 ax88796Write(CURR,RXSTART_INIT+1);
00244
00245 ax88796Write(CR,(RD2|START));
00246 ax88796Write(RCR,RCR_INIT);
00247
00248 if(ax88796Read(GPI) & I_SPD)
00249 tcrFduFlag = FDU;
00250 else
00251 tcrFduFlag = 0;
00252
00253 ax88796Write(TCR,(tcrFduFlag|TCR_INIT));
00254
00255 ax88796Write(GPOC,MPSEL);
00256
00257 ax88796Write(TPSR,TXSTART_INIT);
00258
00259 ax88796Write(CR,(RD2|STOP));
00260 ax88796Write(DCR,DCR_INIT);
00261 ax88796Write(CR,(RD2|START));
00262 ax88796Write(ISR,0xFF);
00263 ax88796Write(IMR,IMR_INIT);
00264 ax88796Write(TCR,(tcrFduFlag|TCR_INIT));
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 }
00275
00276
00277 void ax88796BeginPacketSend(unsigned int packetLength)
00278 {
00279 unsigned int sendPacketLength;
00280 sendPacketLength = (packetLength>=ETHERNET_MIN_PACKET_LENGTH)?
00281 (packetLength):(ETHERNET_MIN_PACKET_LENGTH);
00282
00283
00284 ax88796Write(CR,(RD2|START));
00285
00286
00287 while( ax88796Read(CR) & TXP );
00288
00289
00290 ax88796Write(TPSR,TXSTART_INIT);
00291
00292
00293 ax88796Write(RSAR0,0x00);
00294 ax88796Write(RSAR1,0x40);
00295
00296
00297 ax88796Write(ISR, PTX);
00298
00299
00300 ax88796Write(RBCR0, (unsigned char)(packetLength));
00301 ax88796Write(RBCR1, (unsigned char)(packetLength>>8));
00302
00303 ax88796Write(TBCR0, (unsigned char)(sendPacketLength));
00304 ax88796Write(TBCR1, (unsigned char)((sendPacketLength)>>8));
00305
00306
00307 ax88796Write(CR,0x12);
00308 }
00309
00310
00311 void ax88796SendPacketData(unsigned char * localBuffer, unsigned int length)
00312 {
00313 unsigned int i;
00314
00315 for(i=0;i<length;i++)
00316 ax88796Write(RDMAPORT, localBuffer[i]);
00317 }
00318
00319
00320 void ax88796EndPacketSend(void)
00321 {
00322
00323 ax88796Write(CR,(RD2|TXP));
00324
00325
00326 ax88796Write(ISR, RDC);
00327 }
00328
00329
00330 unsigned int ax88796BeginPacketRetreive(void)
00331 {
00332 unsigned char writePagePtr;
00333 unsigned char readPagePtr;
00334 unsigned char bnryPagePtr;
00335 unsigned char i;
00336
00337 unsigned char pageheader[4];
00338 unsigned int rxlen;
00339
00340
00341 ax88796ProcessInterrupt();
00342
00343
00344 ax88796Write(CR,(PS0|RD2|START));
00345 writePagePtr = ax88796Read(CURR);
00346
00347 ax88796Write(CR,(RD2|START));
00348 bnryPagePtr = ax88796Read(BNRY);
00349
00350
00351 readPagePtr = bnryPagePtr+1;
00352 if(readPagePtr >= RXSTOP_INIT) readPagePtr = RXSTART_INIT;
00353
00354
00355 if( readPagePtr == writePagePtr )
00356 {
00357 return 0;
00358 }
00359
00360
00361 ax88796Write(ISR, PRX);
00362
00363
00364
00365 if( (bnryPagePtr < RXSTART_INIT) || (bnryPagePtr >= RXSTOP_INIT) )
00366 {
00367 ax88796Write(BNRY, RXSTART_INIT);
00368 ax88796Write(CR, (PS0|RD2|START));
00369 ax88796Write(CURR, RXSTART_INIT+1);
00370 ax88796Write(CR, (RD2|START));
00371
00372
00373 return 0;
00374 }
00375
00376
00377 ax88796Write(RBCR0, 4);
00378 ax88796Write(RBCR1, 0);
00379 ax88796Write(RSAR0, 0);
00380 ax88796Write(RSAR1, readPagePtr);
00381 ax88796Write(CR, (RD0|START));
00382 for(i=0;i<4;i++)
00383 pageheader[i] = ax88796Read(RDMAPORT);
00384
00385
00386 ax88796Write(CR, (RD2|START));
00387 for(i = 0; i <= 20; i++)
00388 if(ax88796Read(ISR) & RDC)
00389 break;
00390 ax88796Write(ISR, RDC);
00391
00392 rxlen = (pageheader[PKTHEADER_PKTLENH]<<8) + pageheader[PKTHEADER_PKTLENL];
00393 NextPage = pageheader[PKTHEADER_NEXTPAGE];
00394
00395 CurrentRetreiveAddress = (readPagePtr<<8) + 4;
00396
00397
00398 if( (NextPage >= RXSTOP_INIT) || (NextPage < RXSTART_INIT) )
00399 {
00400
00401
00402 return 0;
00403 }
00404
00405 return rxlen-4;
00406 }
00407
00408
00409 void ax88796RetreivePacketData(unsigned char * localBuffer, unsigned int length)
00410 {
00411 unsigned int i;
00412
00413
00414 ax88796Write(RBCR0, (unsigned char)length);
00415 ax88796Write(RBCR1, (unsigned char)(length>>8));
00416 ax88796Write(RSAR0, (unsigned char)CurrentRetreiveAddress);
00417 ax88796Write(RSAR1, (unsigned char)(CurrentRetreiveAddress>>8));
00418 ax88796Write(CR, (RD0|START));
00419 for(i=0;i<length;i++)
00420 localBuffer[i] = ax88796Read(RDMAPORT);
00421
00422
00423 ax88796Write(CR, (RD2|START));
00424 for(i = 0; i <= 20; i++)
00425 if(ax88796Read(ISR) & RDC)
00426 break;
00427 ax88796Write(ISR, RDC);
00428
00429 CurrentRetreiveAddress += length;
00430 if( CurrentRetreiveAddress >= 0x6000 )
00431 CurrentRetreiveAddress -= (0x6000-0x4600) ;
00432 }
00433
00434
00435 void ax88796EndPacketRetreive(void)
00436 {
00437 unsigned char i;
00438 unsigned char bnryPagePtr;
00439
00440
00441 ax88796Write(CR, (RD2|START));
00442 for(i = 0; i <= 20; i++)
00443 if(ax88796Read(ISR) & RDC)
00444 break;
00445 ax88796Write(ISR, RDC);
00446
00447
00448
00449 bnryPagePtr = NextPage-1;
00450 if(bnryPagePtr < RXSTART_INIT) bnryPagePtr = RXSTOP_INIT-1;
00451
00452 ax88796Write(BNRY, bnryPagePtr);
00453 }
00454
00455
00456 void ax88796ProcessInterrupt(void)
00457 {
00458 unsigned char intr = ax88796Read(ISR);
00459
00460
00461 if( intr & OVW )
00462 ax88796ReceiveOverflowRecover();
00463 }
00464
00465
00466 void ax88796ReceiveOverflowRecover(void)
00467 {
00468
00469
00470
00471 unsigned char cmdReg;
00472 unsigned char resend=0;
00473
00474
00475 cmdReg = ax88796Read(CR);
00476
00477 ax88796Write(CR, (RD2|STOP));
00478
00479 delay_ms(2);
00480
00481 ax88796Write(RBCR0, 0x00);
00482 ax88796Write(RBCR1, 0x00);
00483
00484
00485 if(cmdReg & TXP)
00486 {
00487
00488 cmdReg = ax88796Read(ISR);
00489 if((cmdReg & PTX) || (cmdReg & TXE))
00490 resend = 0;
00491 else
00492 resend = 1;
00493 }
00494
00495 ax88796Write(TCR, LB0);
00496
00497 ax88796Write(CR, (RD2|START));
00498
00499 ax88796Write(BNRY, RXSTART_INIT);
00500
00501 ax88796Write(CR, (PS0|RD2|START));
00502
00503 ax88796Write(CPR, RXSTART_INIT+1);
00504
00505 ax88796Write(CR, (RD2|START));
00506
00507 ax88796Write(ISR, OVW);
00508
00509 ax88796Write(TCR, TCR_INIT);
00510
00511
00512 if(resend)
00513 ax88796Write(CR, (RD2|TXP|START));
00514
00515
00516 }
00517
00518
00519 #define set_mdc ax88796Write(MEMR,ax88796Read(MEMR)|0x01);
00520 #define clr_mdc ax88796Write(MEMR,ax88796Read(MEMR)&0xFE);
00521
00522 #define mii_clk set_mdc; clr_mdc;
00523
00524 #define set_mdir ax88796Write(MEMR,ax88796Read(MEMR)|0x02);
00525 #define clr_mdir ax88796Write(MEMR,ax88796Read(MEMR)&0xFD);
00526
00527 #define set_mdo ax88796Write(MEMR,ax88796Read(MEMR)|0x08)
00528 #define clr_mdo ax88796Write(MEMR,ax88796Read(MEMR)&0xF7)
00529
00530 #define mii_write clr_mdo; mii_clk; \
00531 set_mdo; mii_clk; \
00532 clr_mdo; mii_clk; \
00533 set_mdo; mii_clk;
00534
00535 #define mii_read clr_mdo; mii_clk; \
00536 set_mdo; mii_clk; \
00537 set_mdo; mii_clk; \
00538 clr_mdo; mii_clk;
00539
00540 #define mii_r_ta mii_clk; \
00541
00542 #define mii_w_ta set_mdo; mii_clk; \
00543 clr_mdo; mii_clk;
00544
00545 void ax88796WriteMii(unsigned char phyad,unsigned char regad,unsigned int mii_data)
00546 {
00547 unsigned char mask8;
00548 unsigned int i,mask16;
00549
00550 mii_write;
00551
00552 mask8 = 0x10;
00553 for(i=0;i<5;++i)
00554 {
00555 if(mask8 & phyad)
00556 set_mdo;
00557 else
00558 clr_mdo;
00559 mii_clk;
00560 mask8 >>= 1;
00561 }
00562 mask8 = 0x10;
00563 for(i=0;i<5;++i)
00564 {
00565 if(mask8 & regad)
00566 set_mdo;
00567 else
00568 clr_mdo;
00569 mii_clk;
00570 mask8 >>= 1;
00571 }
00572 mii_w_ta;
00573
00574 mask16 = 0x8000;
00575 for(i=0;i<16;++i)
00576 {
00577 if(mask16 & mii_data)
00578 set_mdo;
00579 else
00580 clr_mdo;
00581 mii_clk;
00582 mask16 >>= 1;
00583 }
00584 }
00585
00586 unsigned int ax88796ReadMii(unsigned char phyad,unsigned char regad)
00587 {
00588 unsigned char mask8,i;
00589 unsigned int mask16,result16;
00590
00591 mii_read;
00592
00593 mask8 = 0x10;
00594 for(i=0;i<5;++i)
00595 {
00596 if(mask8 & phyad)
00597 set_mdo;
00598 else
00599 clr_mdo;
00600 mii_clk;
00601 mask8 >>= 1;
00602 }
00603 mask8 = 0x10;
00604 for(i=0;i<5;++i)
00605 {
00606 if(mask8 & regad)
00607 set_mdo;
00608 else
00609 clr_mdo;
00610 mii_clk;
00611 mask8 >>= 1;
00612 }
00613
00614 mii_r_ta;
00615
00616 mask16 = 0x8000;
00617 result16 = 0x0000;
00618 for(i=0;i<16;++i)
00619 {
00620 mii_clk;
00621 if(ax88796Read(MEMR) & 0x04)
00622 {
00623 result16 |= mask16;
00624 }
00625 else
00626 {
00627 asm volatile ("nop");
00628 break;
00629 }
00630 mask16 >>= 1;
00631 }
00632 return result16;
00633 }
00634
00635
00636 void ax88796RegDump(void)
00637 {
00638 unsigned char result;
00639 result = ax88796Read(TR);
00640
00641 rprintf("Media State: ");
00642 if(!(result & AUTOD))
00643 rprintf("Autonegotiation\r\n");
00644 else if(result & RST_B)
00645 rprintf("PHY in Reset \r\n");
00646 else if(!(result & RST_10B))
00647 rprintf("10BASE-T \r\n");
00648 else if(!(result & RST_TXB))
00649 rprintf("100BASE-T \r\n");
00650
00651
00652
00653
00654
00655 rprintfProgStrM("Page0: CR BNRY PSR PST ISR TSR RSR MMR TR GPI\r\n");
00656 rprintfProgStrM(" ");
00657 rprintfu08(ax88796Read(CR));
00658 rprintfProgStrM(" ");
00659 rprintfu08(ax88796Read(BNRY));
00660 rprintfProgStrM(" ");
00661 rprintfu08(ax88796Read(PSTART));
00662 rprintfProgStrM(" ");
00663 rprintfu08(ax88796Read(PSTOP));
00664 rprintfProgStrM(" ");
00665 rprintfu08(ax88796Read(ISR));
00666 rprintfProgStrM(" ");
00667 rprintfu08(ax88796Read(TSR));
00668 rprintfProgStrM(" ");
00669 rprintfu08(ax88796Read(RSR));
00670 rprintfProgStrM(" ");
00671 rprintfu08(ax88796Read(MEMR));
00672 rprintfProgStrM(" ");
00673 rprintfu08(ax88796Read(TR));
00674 rprintfProgStrM(" ");
00675 rprintfu08(ax88796Read(GPI));
00676 rprintfCRLF();
00677
00678 ax88796Write(CR,ax88796Read(CR)|PS0);
00679
00680 rprintf("Page1: CR PAR CPR\r\n");
00681 rprintfProgStrM(" ");
00682 rprintfu08(ax88796Read(CR));
00683 rprintfProgStrM(" ");
00684 rprintfChar(ax88796Read(PAR0));
00685 rprintfChar(ax88796Read(PAR1));
00686 rprintfChar(ax88796Read(PAR2));
00687 rprintfChar(ax88796Read(PAR3));
00688 rprintfChar(ax88796Read(PAR4));
00689 rprintfChar(ax88796Read(PAR5));
00690 rprintfProgStrM(" ");
00691 rprintfu08(ax88796Read(CPR));
00692
00693 ax88796Write(CR,ax88796Read(CR)&~PS0);
00694
00695 delay_ms(25);
00696 }
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716