?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 6

Line No. Rev Author Line
1 6 kaklik /*! \file rtl8019.c \brief Realtek RTL8019AS Ethernet Interface Driver. */
2 //*****************************************************************************
3 //
4 // File Name : 'rtl8019.c'
5 // Title : Realtek RTL8019AS Ethernet Interface Driver
6 // Author : Pascal Stang
7 // Created : 7/6/2004
8 // Revised : 10/1/2005
9 // Version : 0.1
10 // Target MCU : Atmel AVR series
11 // Editor Tabs : 4
12 //
13 // Based in part on code by Louis Beaudoin (www.embedded-creations.com).
14 // Thanks to Adam Dunkels and Louis Beaudoin for providing the initial
15 // structure in which to write this driver.
16 //*****************************************************************************
17  
18 #include "global.h"
19 #include "timer.h"
20 #include "rprintf.h"
21  
22 #include "rtl8019.h"
23  
24 // include configuration
25 #include "rtl8019conf.h"
26  
27 // pointers to locations in the RTL8019 receive buffer
28 static unsigned char NextPage; // page pointer to next Rx packet
29 static unsigned int CurrentRetreiveAddress; // DMA address for read Rx packet location
30  
31  
32 void nicInit(void)
33 {
34 rtl8019Init();
35 }
36  
37 void nicSend(unsigned int len, unsigned char* packet)
38 {
39 rtl8019BeginPacketSend(len);
40 rtl8019SendPacketData(packet, len);
41 rtl8019EndPacketSend();
42 }
43  
44 unsigned int nicPoll(unsigned int maxlen, unsigned char* packet)
45 {
46 unsigned int packetLength;
47  
48 packetLength = rtl8019BeginPacketRetreive();
49  
50 // if there's no packet or an error - exit without ending the operation
51 if( !packetLength )
52 return 0;
53  
54 // drop anything too big for the buffer
55 if( packetLength > maxlen )
56 {
57 rtl8019EndPacketRetreive();
58 return 0;
59 }
60  
61 // copy the packet data into the packet buffer
62 rtl8019RetreivePacketData( packet, packetLength );
63 rtl8019EndPacketRetreive();
64  
65 return packetLength;
66 }
67  
68 void nicGetMacAddress(u08* macaddr)
69 {
70 u08 tempCR;
71 // switch register pages
72 tempCR = rtl8019Read(CR);
73 rtl8019Write(CR,tempCR|PS0);
74 // read MAC address registers
75 *macaddr++ = rtl8019Read(PAR0);
76 *macaddr++ = rtl8019Read(PAR1);
77 *macaddr++ = rtl8019Read(PAR2);
78 *macaddr++ = rtl8019Read(PAR3);
79 *macaddr++ = rtl8019Read(PAR4);
80 *macaddr++ = rtl8019Read(PAR5);
81 // switch register pages back
82 rtl8019Write(CR,tempCR);
83 }
84  
85 void nicSetMacAddress(u08* macaddr)
86 {
87 u08 tempCR;
88 // switch register pages
89 tempCR = rtl8019Read(CR);
90 rtl8019Write(CR,tempCR|PS0);
91 // write MAC address registers
92 rtl8019Write(PAR0, *macaddr++);
93 rtl8019Write(PAR1, *macaddr++);
94 rtl8019Write(PAR2, *macaddr++);
95 rtl8019Write(PAR3, *macaddr++);
96 rtl8019Write(PAR4, *macaddr++);
97 rtl8019Write(PAR5, *macaddr++);
98 // switch register pages back
99 rtl8019Write(CR,tempCR);
100 }
101  
102 void nicRegDump(void)
103 {
104 rtl8019RegDump();
105 }
106  
107  
108 void rtl8019SetupPorts(void)
109 {
110 #if NIC_CONNECTION == MEMORY_MAPPED
111 // enable external SRAM interface - no wait states
112 sbi(MCUCR, SRE);
113 // sbi(MCUCR, SRW10);
114 // sbi(XMCRA, SRW00);
115 // sbi(XMCRA, SRW01);
116 // sbi(XMCRA, SRW11);
117 #else
118 // make the address port output
119 RTL8019_ADDRESS_DDR |= RTL8019_ADDRESS_MASK;
120 // make the data port input with pull-ups
121 RTL8019_DATA_PORT = 0xFF;
122  
123 // initialize the control port read and write pins to de-asserted
124 RTL8019_CONTROL_DDR |= (1<<RTL8019_CONTROL_READPIN);
125 RTL8019_CONTROL_DDR |= (1<<RTL8019_CONTROL_WRITEPIN);
126 // set the read and write pins to output
127 RTL8019_CONTROL_PORT |= (1<<RTL8019_CONTROL_READPIN);
128 RTL8019_CONTROL_PORT |= (1<<RTL8019_CONTROL_WRITEPIN);
129 #endif
130 // set reset pin to output
131 sbi(RTL8019_RESET_DDR, RTL8019_RESET_PIN);
132 }
133  
134  
135 #if NIC_CONNECTION == MEMORY_MAPPED
136 inline void rtl8019Write(u08 address, u08 data)
137 {
138 *(volatile u08*)(RTL8019_MEMORY_MAPPED_OFFSET + address) = data;
139 }
140 #else
141 void rtl8019Write(unsigned char address, unsigned char data)
142 {
143 // assert the address
144 RTL8019_ADDRESS_PORT = address | (RTL8019_ADDRESS_PORT&~RTL8019_ADDRESS_MASK);
145 // set data bus as output and place data on bus
146 RTL8019_DATA_DDR = 0xFF;
147 RTL8019_DATA_PORT = data;
148 // clock write pin
149 cbi(RTL8019_CONTROL_PORT, RTL8019_CONTROL_WRITEPIN);
150 nop();
151 nop();
152 sbi(RTL8019_CONTROL_PORT, RTL8019_CONTROL_WRITEPIN);
153 // set data port back to input with pullups enabled
154 RTL8019_DATA_DDR = 0x00;
155 RTL8019_DATA_PORT = 0xFF;
156 }
157 #endif
158  
159  
160 #if NIC_CONNECTION == MEMORY_MAPPED
161 inline u08 ax88796Read(u08 address)
162 {
163 return *(volatile u08*)(RTL8019_MEMORY_MAPPED_OFFSET + address);
164 }
165 #else
166 unsigned char rtl8019Read(unsigned char address)
167 {
168 unsigned char data;
169  
170 // assert the address
171 RTL8019_ADDRESS_PORT = address | (RTL8019_ADDRESS_PORT&~RTL8019_ADDRESS_MASK);
172 // assert read
173 cbi(RTL8019_CONTROL_PORT, RTL8019_CONTROL_READPIN);
174 nop();
175 nop();
176 // read in the data
177 data = RTL8019_DATA_PIN;
178 // negate read
179 sbi(RTL8019_CONTROL_PORT, RTL8019_CONTROL_READPIN);
180 // return data
181 return data;
182 }
183 #endif
184  
185  
186 void rtl8019Init(void)
187 {
188 // setup I/O ports
189 rtl8019SetupPorts();
190  
191 // do a hard reset
192 sbi(RTL8019_RESET_PORT, RTL8019_RESET_PIN);
193 delay_ms(10);
194 cbi(RTL8019_RESET_PORT, RTL8019_RESET_PIN);
195  
196 // clear interrupt state
197 rtl8019Write( ISR, rtl8019Read(ISR) );
198 delay_ms(50);
199  
200 // switch to page 3 to load config registers
201 rtl8019Write(CR, (PS0|PS1|RD2|STOP));
202  
203 // disable EEPROM write protect of config registers
204 rtl8019Write(RTL_EECR, (EEM1|EEM0));
205  
206 // set network type to 10 Base-T link test
207 rtl8019Write(CONFIG2, 0x20);
208  
209 // disable powerdown and sleep
210 rtl8019Write(CONFIG3, 0);
211 delay_ms(255);
212  
213 // reenable EEPROM write protect
214 rtl8019Write(RTL_EECR, 0);
215  
216 // go back to page 0, stop NIC, abort DMA
217 rtl8019Write(CR, (RD2|STOP));
218 delay_ms(2); // wait for traffic to complete
219 rtl8019Write(DCR, DCR_INIT);
220 rtl8019Write(RBCR0,0x00);
221 rtl8019Write(RBCR1,0x00);
222 rtl8019Write(RCR, AB);
223 rtl8019Write(TPSR, TXSTART_INIT);
224 rtl8019Write(TCR, LB0);
225 rtl8019Write(PSTART, RXSTART_INIT);
226 rtl8019Write(BNRY, RXSTART_INIT);
227 rtl8019Write(PSTOP, RXSTOP_INIT);
228 rtl8019Write(CR, (PS0|RD2|STOP)); // switch to page 1
229 delay_ms(2);
230 rtl8019Write(CPR, RXSTART_INIT);
231  
232 // set MAC address
233 rtl8019Write(PAR0, RTL8019_MAC0);
234 rtl8019Write(PAR1, RTL8019_MAC1);
235 rtl8019Write(PAR2, RTL8019_MAC2);
236 rtl8019Write(PAR3, RTL8019_MAC3);
237 rtl8019Write(PAR4, RTL8019_MAC4);
238 rtl8019Write(PAR5, RTL8019_MAC5);
239  
240 // initialize sequence per NE2000 spec
241 rtl8019Write(CR, (RD2|STOP));
242 rtl8019Write(DCR, DCR_INIT);
243 rtl8019Write(CR, (RD2|START));
244 rtl8019Write(ISR,0xFF); // clear all interrupts
245 rtl8019Write(IMR, IMR_INIT);
246 rtl8019Write(TCR, TCR_INIT);
247  
248 rtl8019Write(CR, (RD2|START)); // start the NIC
249 }
250  
251  
252 void rtl8019BeginPacketSend(unsigned int packetLength)
253 {
254 unsigned int sendPacketLength;
255 sendPacketLength = (packetLength>=ETHERNET_MIN_PACKET_LENGTH)?
256 (packetLength):ETHERNET_MIN_PACKET_LENGTH;
257  
258 //start the NIC
259 rtl8019Write(CR, (RD2|START));
260  
261 // still transmitting a packet - wait for it to finish
262 while( rtl8019Read(CR) & TXP );
263  
264 // load beginning page for transmit buffer
265 rtl8019Write(TPSR,TXSTART_INIT);
266  
267 // set start address for remote DMA operation
268 rtl8019Write(RSAR0,0x00);
269 rtl8019Write(RSAR1,0x40);
270  
271 // clear the packet stored interrupt
272 rtl8019Write(ISR,PTX);
273  
274 // load data byte count for remote DMA
275 rtl8019Write(RBCR0, (unsigned char)(packetLength));
276 rtl8019Write(RBCR1, (unsigned char)(packetLength>>8));
277  
278 rtl8019Write(TBCR0, (unsigned char)(sendPacketLength));
279 rtl8019Write(TBCR1, (unsigned char)((sendPacketLength)>>8));
280  
281 // do remote write operation
282 rtl8019Write(CR,(RD1|START));
283 }
284  
285  
286 void rtl8019SendPacketData(unsigned char *localBuffer, unsigned int length)
287 {
288 unsigned int i;
289  
290 // write data to DMA port
291 for(i=0;i<length;i++)
292 rtl8019Write(RDMAPORT, localBuffer[i]);
293 }
294  
295  
296 void rtl8019EndPacketSend(void)
297 {
298 //send the contents of the transmit buffer onto the network
299 rtl8019Write(CR,(RD2|TXP));
300 // clear the remote DMA interrupt
301 rtl8019Write(ISR, RDC);
302 }
303  
304  
305 unsigned int rtl8019BeginPacketRetreive(void)
306 {
307 unsigned char i;
308 unsigned char bnry;
309  
310 unsigned char pageheader[4];
311 unsigned int rxlen;
312  
313 // check for and handle an overflow
314 rtl8019ProcessInterrupt();
315  
316 // read CPR from page 1
317 rtl8019Write(CR,(PS0|RD2|START));
318 i = rtl8019Read(CPR);
319  
320 // return to page 0
321 rtl8019Write(CR,(RD2|START));
322  
323 // read the boundary register - pointing to the beginning of the packet
324 bnry = rtl8019Read(BNRY) ;
325  
326 // return if there is no packet in the buffer
327 if( bnry == i )
328 return 0;
329  
330 // clear the packet received interrupt flag
331 rtl8019Write(ISR, PRX);
332  
333 // if boundary pointer is invalid
334 if( (bnry >= RXSTOP_INIT) || (bnry < RXSTART_INIT) )
335 {
336 // reset the contents of the buffer and exit
337 rtl8019Write(BNRY, RXSTART_INIT);
338 rtl8019Write(CR, (PS0|RD2|START));
339 rtl8019Write(CPR, RXSTART_INIT);
340 rtl8019Write(CR, (RD2|START));
341 return 0;
342 }
343  
344 // initiate DMA to transfer the RTL8019 packet header
345 rtl8019Write(RBCR0, 4);
346 rtl8019Write(RBCR1, 0);
347 rtl8019Write(RSAR0, 0);
348 rtl8019Write(RSAR1, bnry);
349 rtl8019Write(CR, (RD0|START));
350 // transfer packet header
351 for(i=0;i<4;i++)
352 pageheader[i] = rtl8019Read(RDMAPORT);
353 // end the DMA operation
354 rtl8019Write(CR, (RD2|START));
355 // wait for remote DMA complete
356 for(i = 0; i < 20; i++)
357 if(rtl8019Read(ISR) & RDC)
358 break;
359 rtl8019Write(ISR, RDC);
360  
361 rxlen = (pageheader[PKTHEADER_PKTLENH]<<8) + pageheader[PKTHEADER_PKTLENL];
362 NextPage = pageheader[PKTHEADER_NEXTPAGE];
363  
364 CurrentRetreiveAddress = (bnry<<8) + 4;
365  
366 // if the NextPage pointer is invalid, the packet is not ready yet - exit
367 if( (NextPage >= RXSTOP_INIT) || (NextPage < RXSTART_INIT) )
368 return 0;
369  
370 return rxlen-4;
371 }
372  
373  
374 void rtl8019RetreivePacketData(unsigned char * localBuffer, unsigned int length)
375 {
376 unsigned int i;
377  
378 // initiate DMA to transfer the data
379 rtl8019Write(RBCR0, (unsigned char)length);
380 rtl8019Write(RBCR1, (unsigned char)(length>>8));
381 rtl8019Write(RSAR0, (unsigned char)CurrentRetreiveAddress);
382 rtl8019Write(RSAR1, (unsigned char)(CurrentRetreiveAddress>>8));
383 rtl8019Write(CR, (RD0|START));
384 // transfer packet data
385 for(i=0;i<length;i++)
386 localBuffer[i] = rtl8019Read(RDMAPORT);
387 // end the DMA operation
388 rtl8019Write(CR, (RD2|START));
389 // wait for remote DMA complete
390 for(i=0; i<20; i++)
391 if(rtl8019Read(ISR) & RDC)
392 break;
393 rtl8019Write(ISR, RDC);
394 // keep track of current address
395 CurrentRetreiveAddress += length;
396 if( CurrentRetreiveAddress >= 0x6000 )
397 CurrentRetreiveAddress = CurrentRetreiveAddress - (0x6000-0x4600) ;
398 }
399  
400  
401 void rtl8019EndPacketRetreive(void)
402 {
403 unsigned char i;
404  
405 // end the DMA operation
406 rtl8019Write(CR, (RD2|START));
407 // wait for remote DMA complete
408 for(i=0; i<20; i++)
409 if(rtl8019Read(ISR) & RDC)
410 break;
411 rtl8019Write(ISR, RDC);
412  
413 // set the boundary register to point to the start of the next packet
414 rtl8019Write(BNRY, NextPage);
415 }
416  
417  
418 void rtl8019ProcessInterrupt(void)
419 {
420 unsigned char byte = rtl8019Read(ISR);
421  
422 if( byte & OVW )
423 rtl8019ReceiveOverflowRecover();
424 }
425  
426 void rtl8019ReceiveOverflowRecover(void)
427 {
428 unsigned char data_L, resend;
429  
430 data_L = rtl8019Read(CR);
431 rtl8019Write(CR, 0x21);
432 delay_ms(2);
433 rtl8019Write(RBCR0, 0x00);
434 rtl8019Write(RBCR1, 0x00);
435 if(!(data_L & 0x04))
436 resend = 0;
437 else if(data_L & 0x04)
438 {
439 data_L = rtl8019Read(ISR);
440 if((data_L & 0x02) || (data_L & 0x08))
441 resend = 0;
442 else
443 resend = 1;
444 }
445  
446 rtl8019Write(TCR, 0x02);
447 rtl8019Write(CR, 0x22);
448 rtl8019Write(BNRY, RXSTART_INIT);
449 rtl8019Write(CR, 0x62);
450 rtl8019Write(CPR, RXSTART_INIT);
451 rtl8019Write(CR, 0x22);
452 rtl8019Write(ISR, 0x10);
453 rtl8019Write(TCR, TCR_INIT);
454  
455 if(resend)
456 rtl8019Write(CR, 0x26);
457  
458 rtl8019Write(ISR, 0xFF);
459 }
460  
461  
462 void rtl8019RegDump(void)
463 {
464 // unsigned char result;
465 // result = rtl8019Read(TR);
466  
467 // rprintf("Media State: ");
468 // if(!(result & AUTOD))
469 // rprintf("Autonegotiation\r\n");
470 // else if(result & RST_B)
471 // rprintf("PHY in Reset \r\n");
472 // else if(!(result & RST_10B))
473 // rprintf("10BASE-T \r\n");
474 // else if(!(result & RST_TXB))
475 // rprintf("100BASE-T \r\n");
476  
477 //rprintf("TR regsiter : %x\r\n",result);
478 //result = read_mii(0x10,0);
479 //rprintf("MII regsiter 0x10: %x\r\n",result);
480  
481 rprintf("Page0: CR BNRY PSR PST ISR TSR RSR MMR TR GPI\r\n");
482 rprintfProgStrM(" ");
483 rprintfu08(rtl8019Read(CR));
484 rprintfProgStrM(" ");
485 rprintfu08(rtl8019Read(BNRY));
486 rprintfProgStrM(" ");
487 rprintfu08(rtl8019Read(PSTART));
488 rprintfProgStrM(" ");
489 rprintfu08(rtl8019Read(PSTOP));
490 rprintfProgStrM(" ");
491 rprintfu08(rtl8019Read(ISR));
492 rprintfProgStrM(" ");
493 rprintfu08(rtl8019Read(TSR));
494 rprintfProgStrM(" ");
495 rprintfu08(rtl8019Read(RSR));
496 rprintfProgStrM(" ");
497 // rprintfu08(rtl8019Read(MEMR));
498 rprintfProgStrM(" ");
499 // rprintfu08(rtl8019Read(TR));
500 rprintfProgStrM(" ");
501 // rprintfu08(rtl8019Read(GPI));
502 rprintfCRLF();
503  
504 rtl8019Write(CR,rtl8019Read(CR)|PS0);
505  
506 rprintf("Page1: CR PAR CPR\r\n");
507 rprintfProgStrM(" ");
508 rprintfu08(rtl8019Read(CR));
509 rprintfProgStrM(" ");
510 rprintfChar(rtl8019Read(PAR0));
511 rprintfChar(rtl8019Read(PAR1));
512 rprintfChar(rtl8019Read(PAR2));
513 rprintfChar(rtl8019Read(PAR3));
514 rprintfChar(rtl8019Read(PAR4));
515 rprintfChar(rtl8019Read(PAR5));
516 rprintfProgStrM(" ");
517 rprintfu08(rtl8019Read(CPR));
518  
519 rtl8019Write(CR,rtl8019Read(CR)&~PS0);
520  
521 delay_ms(25);
522 }
523  
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3