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