3 void sleep(unsigned char);
5 static xdata leds1 _at_ 0x0080;
6 static xdata leds2 _at_ 0x00c0;
8 unsigned char uip_buf[64] =
10 //0x00, 0x0c, 0x6e, 0x37, 0x19, 0xbf, // MAC destino
11 0x00, 0x80, 0xc7, 0x42, 0x8d, 0x27, // MAC destino
12 0x00, 0x0c, 0x6e, 0x37, 0x19, 0xbe, // MAC fuente
16 unsigned int uip_len = 14;
18 /* ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
20 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ */
21 #define ETH_CPU_CLOCK ETH_CPU_XTAL / 12 // 8051 clock rate (X1 mode)
23 // Delay routine timing parameters
24 #define ETH_DELAY_CONST 9.114584e-5 // Delay routine constant
25 #define ETH_DELAY_MULTPLR (unsigned char)(ETH_DELAY_CONST * ETH_CPU_CLOCK)
27 // X1 CPU mode timing parameters
28 #define ETH_T0_CLOCK ETH_CPU_XTAL / 12 // Timer 0 mode 1 clock rate
29 #define ETH_T0_INT_RATE 24 // Timer 0 intrupt rate (Hz)
30 #define ETH_T0_RELOAD 65536 - (ETH_T0_CLOCK / ETH_T0_INT_RATE)
32 // Packet transmit & receive buffer configuration
33 #define ETH_TX_PAGE_START 0x40 // 0x4000 Tx buffer is 6 * 256 = 1536 bytes
34 #define ETH_RX_PAGE_START 0x46 // 0x4600 Rx buffer is 26 * 256 = 6656 bytes
35 #define ETH_RX_PAGE_STOP 0x60 // 0x6000
37 #define ETH_ADDR_PORT_MASK 0x1F // 00011111y
38 #define ETH_DATA_PORT_MASK 0xFF // 11111111y
40 #define ETH_MIN_PACKET_LEN 0x3C
43 /* ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
44 º Private Function Prototypes º
45 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ */
46 static void etherdev_reg_write(unsigned char reg, unsigned char wr_data);
47 static unsigned char etherdev_reg_read(unsigned char reg);
48 static void etherdev_delay_ms(unsigned int count);
49 static unsigned int etherdev_poll(void);
50 //static void etherdev_timer0_isr(void) interrupt 1 using 1;
53 /* ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
54 º Private Macro Defines º
55 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ */
56 // Manipulate PS1 & PS0 in CR to select RTL8019AS register page.
57 #define ETHERDEV_SELECT_REG_PAGE(page) \
60 etherdev_reg_write(CR, etherdev_reg_read(CR) & ~(PS1 | PS0)); \
61 etherdev_reg_write(CR, etherdev_reg_read(CR) | (page << 6)); \
65 /* ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
67 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ */
68 static unsigned char tick_count = 0;
71 /* ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
72 º Private Function Implementation º
73 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ */
75 /* ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
77 º etherdev_reg_write() º
80 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ */
81 static void etherdev_reg_write(unsigned char reg, unsigned char wr_data)
83 // Select register address.
84 ETH_ADDR_PORT &= ~ETH_ADDR_PORT_MASK;
87 // Output register data to port.
88 ETH_DATA_PORT = wr_data;
90 // Clock register data into RTL8019AS.
91 // IOR & IOW are both active low.
97 // Set register data port as input again.
98 ETH_DATA_PORT = ETH_DATA_PORT_MASK;
104 /* ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
106 º etherdev_reg_read() º
109 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ */
110 static unsigned char etherdev_reg_read(unsigned char reg)
112 unsigned char rd_data;
114 // Select register address.
115 ETH_ADDR_PORT &= ~ETH_ADDR_PORT_MASK;
116 ETH_ADDR_PORT |= reg;
118 // Enable register data output from RTL8019AS.
122 // Read register data from port.
123 rd_data = ETH_DATA_PORT;
125 // Disable register data output from RTL8019AS.
133 /* ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
135 º etherdev_delay_ms() º
137 º 1 to 255+ ms delay. º
139 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ */
140 static void etherdev_delay_ms(unsigned int count)
143 for(count *= ETH_DELAY_MULTPLR; count > 0; count--) continue;
149 /* ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
151 º etherdev_timer0_isr() º
153 º This function is invoked each 1/24th of a second and updates a º
154 º 1/24th of a second tick counter. º
156 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ */
157 static void etherdev_timer0_isr(void) interrupt 1 using 1
159 // Reload timer/ counter 0 for 24Hz periodic interrupt.
160 TH0 = ETH_T0_RELOAD >> 8;
163 // Increment 24ths of a second counter.
170 /* ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
171 º Public Function Implementation º
172 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ */
174 /* ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
178 º Returns: 1 on success, 0 on failure. º
179 º Refer to National Semiconductor DP8390 App Note 874, July 1993. º
181 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ */
182 bit etherdev_init(void)
184 // Set IOR & IOW as they're active low.
189 // Set register data port as input.
190 ETH_DATA_PORT = ETH_DATA_PORT_MASK;
194 #endif /* ETH_DEBUG */
196 // Configure RTL8019AS ethernet controller.
198 // Keil startup code takes 4ms to execute (18.432MHz, X1 mode).
199 // That leaves plenty of time for the RTL8019AS to read it's
200 // configuration in from the 9346 EEPROM before we get here.
202 // Select RTL8019AS register page 0.
203 ETHERDEV_SELECT_REG_PAGE(0);
205 // Check if RTL8019AS fully reset.
206 if(!(etherdev_reg_read(ISR) & RST))
214 // Select RTL8019AS register page 3.
215 ETHERDEV_SELECT_REG_PAGE(3);
217 // Temporarily disable config register write protection.
218 etherdev_reg_write(_9346CR, EEM1 | EEM0);
220 // Disable boot ROM & select 10BaseT with TP/CX auto-detect.
221 etherdev_reg_write(CONFIG2, BSELB);
223 // Select half-duplex, awake, power-up & LED_TX/ LED_RX/ LED_LNK behaviour.
224 etherdev_reg_write(CONFIG3, LEDS0);
226 // Re-enable config register write protection.
227 etherdev_reg_write(_9346CR, 0x00);
229 // Select RTL8019AS register page 0.
230 ETHERDEV_SELECT_REG_PAGE(0);
232 // Stop RTL8019AS, select page 0 and abort DMA operation.
233 etherdev_reg_write(CR, RD2 | STP);
235 // Initialise data configuration register.
236 // FIFO threshold 8 bytes, no loopback, don't use auto send packet.
237 etherdev_reg_write(DCR, FT1 | LS);
239 // Reset remote byte count registers.
240 etherdev_reg_write(RBCR0, 0x00);
241 etherdev_reg_write(RBCR1, 0x00);
243 // Receive configuration register to monitor mode.
244 etherdev_reg_write(RCR, MON);
246 // Initialise transmit configuration register to loopback internally.
247 etherdev_reg_write(TCR, LB0);
249 // Clear interrupt status register bits by writing 1 to each.
250 etherdev_reg_write(ISR, 0xFF);
252 // Mask all interrupts in mask register.
253 etherdev_reg_write(IMR, 0x00);
255 // Obtengo MAC de la placa
256 //etherdev_reg_write(CR, 0x21);
259 // Set transmit page start.
260 etherdev_reg_write(TPSR, ETH_TX_PAGE_START);
262 // Set receive buffer page start.
263 etherdev_reg_write(PSTART, ETH_RX_PAGE_START);
265 // Initialise last receive buffer read pointer.
266 etherdev_reg_write(BNRY, ETH_RX_PAGE_START);
268 // Set receive buffer page stop.
269 etherdev_reg_write(PSTOP, ETH_RX_PAGE_STOP);
271 // Select RTL8019AS register page 1.
272 etherdev_reg_write(CR, RD2 | PS0 | STP);
274 // Initialise current packet receive buffer page pointer
275 etherdev_reg_write(CURR, ETH_RX_PAGE_START);
277 // Set physical address
278 etherdev_reg_write(PAR0, 0x00);
279 etherdev_reg_write(PAR1, 0x0c);
280 etherdev_reg_write(PAR2, 0x6e);
281 etherdev_reg_write(PAR3, 0x37);
282 etherdev_reg_write(PAR4, 0x19);
283 etherdev_reg_write(PAR5, 0xbe);
285 // Select RTL8019AS register page 0 and abort DMA operation.
286 etherdev_reg_write(CR, RD2 | STP);
288 // Restart RTL8019AS.
289 etherdev_reg_write(CR, RD2 | STA);
291 // Initialise transmit configuration register for normal operation.
292 etherdev_reg_write(TCR, 0x00);
294 // Receive configuration register to accept broadcast packets.
295 etherdev_reg_write(RCR, AB);
298 // Initialize Timer 0 to generate a periodic 24Hz interrupt.
300 // Stop timer/ counter 0.
303 // Set timer/ counter 0 as mode 1 16 bit timer.
307 // Preload for 24Hz periodic interrupt.
308 TH0 = ETH_T0_RELOAD >> 8;
311 // Restart timer/ counter 0 running.
314 // Enable timer/ counter 0 overflow interrupt.
317 // Enable global interrupt.
324 /* ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
328 º Send the packet in the uip_buf and uip_appdata buffers using the º
329 º RTL8019AS ethernet card. º
331 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ */
332 void etherdev_send(void)
339 // Setup for DMA transfer from uip_buf & uip_appdata buffers to RTL8019AS.
341 // Select RTL8019AS register page 0 and abort DMA operation.
342 etherdev_reg_write(CR, RD2 | STA);
345 i = etherdev_reg_read(CR);
347 // Wait until pending transmit operation completes.
348 while(etherdev_reg_read(CR) & TXP) continue;
350 // Clear remote DMA complete interrupt status register bit.
351 etherdev_reg_write(ISR, RDC);
353 // Set remote DMA start address registers to indicate where to load packet.
354 etherdev_reg_write(RSAR0, 0x00);
355 etherdev_reg_write(RSAR1, ETH_TX_PAGE_START);
357 // Set remote DMA byte count registers to indicate length of packet load.
358 etherdev_reg_write(RBCR0, (unsigned char)(uip_len & 0xFF));
359 etherdev_reg_write(RBCR1, (unsigned char)(uip_len >> 8));
361 // Initiate DMA transfer of uip_buf & uip_appdata buffers to RTL8019AS.
362 etherdev_reg_write(CR, RD1 | STA);
364 // DMA transfer packet from uip_buf & uip_appdata to RTL8019AS local
365 // transmit buffer memory.
366 for(i = 0; i < uip_len; i++)
368 etherdev_reg_write(RDMA, *ptr++);
371 // Wait until remote DMA operation complete.
373 leds2 = ~etherdev_reg_read(ISR);
374 while(!(etherdev_reg_read(ISR) & RDC)) continue;
376 // Abort/ complete DMA operation.
377 etherdev_reg_write(CR, RD2 | STA);
379 // Set transmit page start to indicate packet start.
380 etherdev_reg_write(TPSR, ETH_TX_PAGE_START);
382 // Ethernet packets must be > 60 bytes, otherwise are rejected as runts.
383 if(uip_len < ETH_MIN_PACKET_LEN)
385 uip_len = ETH_MIN_PACKET_LEN;
388 // Set transmit byte count registers to indicate packet length.
389 etherdev_reg_write(TBCR0, (unsigned char)(uip_len & 0xFF));
390 etherdev_reg_write(TBCR1, (unsigned char)(uip_len >> 8));
392 // Issue command for RTL8019AS to transmit packet from it's local buffer.
393 etherdev_reg_write(CR, RD2 | TXP | STA);
399 /* ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
403 º This function will read an entire IP packet into the uip_buf. º
404 º If it must wait for more than 0.5 seconds, it will return with º
405 º the return value 0. Otherwise, when a full packet has been read º
406 º into the uip_buf buffer, the length of the packet is returned. º
408 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ */
409 unsigned int etherdev_read(void)
411 unsigned int bytes_read;
413 /* tick_count threshold should be 12 for 0.5 sec bail-out
414 One second (24) worked better for me, but socket recycling
415 is then slower. I set UIP_TIME_WAIT_TIMEOUT 60 in uipopt.h
416 to counter this. Retransmission timing etc. is affected also. */
417 while ((!(bytes_read = etherdev_poll())) && (tick_count < 12)) continue;
425 /* ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
429 º Poll the RTL8019AS ethernet device for an available packet. º
431 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ */
432 static unsigned int etherdev_poll(void)
434 unsigned int len = 0;
436 // Check if there is a packet in the rx buffer.
437 if(etherdev_reg_read(ISR) & PRX)
439 // Check if the rx buffer has overflowed.
440 if(etherdev_reg_read(ISR) & OVW)
444 // If the receive buffer ring has overflowed we dump the whole
445 // thing and start over. There is no way of knowing whether the
446 // data it contains is uncorrupted, or will cause us grief.
448 // Stop RTL8019AS and abort DMA operation.
449 etherdev_reg_write(CR, RD2 | STP);
451 // Reset remote byte count registers.
452 etherdev_reg_write(RBCR0, 0x00);
453 etherdev_reg_write(RBCR1, 0x00);
455 // Wait for controller to halt after any current tx completes.
456 while(!(etherdev_reg_read(ISR) & RST)) continue;
458 // Check whether currently transmitting a packet.
459 if(etherdev_reg_read(CR) & TXP)
461 // If neither a successful transmission nor a tx abort error
462 // has occured, then flag current tx packet for resend.
463 if(!((etherdev_reg_read(ISR) & PTX)
464 || (etherdev_reg_read(ISR) & TXE)))
470 // Set transmit configuration register to loopback internally.
471 etherdev_reg_write(TCR, LB0);
473 // Restart the RTL8019AS.
474 etherdev_reg_write(CR, RD2 | STA);
476 // Re-initialise last receive buffer read pointer.
477 etherdev_reg_write(BNRY, ETH_RX_PAGE_START);
479 // Select RTL8019AS register page 1.
480 ETHERDEV_SELECT_REG_PAGE(1);
482 // Re-initialise current packet receive buffer page pointer.
483 etherdev_reg_write(CURR, ETH_RX_PAGE_START);
485 // Select RTL8019AS register page 0.
486 ETHERDEV_SELECT_REG_PAGE(0);
488 // Clear rx buffer overflow & packet received interrupt flags.
489 etherdev_reg_write(ISR, PRX | OVW);
491 // Re-itialise transmit configuration reg for normal operation.
492 etherdev_reg_write(TCR, 0x00);
496 // Retransmit packet in RTL8019AS local tx buffer.
497 etherdev_reg_write(CR, RD2 | TXP | STA);
500 else // Rx buffer has not overflowed, so read a packet into uip_buf.
503 unsigned char next_rx_packet;
504 unsigned char current;
506 // Retrieve packet header. (status, next_ptr, length_l, length_h)
508 // Clear remote DMA complete interrupt status register bit.
509 etherdev_reg_write(ISR, RDC);
511 // Set remote DMA start address registers to packet header.
512 etherdev_reg_write(RSAR0, 0x00);
513 etherdev_reg_write(RSAR1, etherdev_reg_read(BNRY));
515 // Set remote DMA byte count registers to packet header length.
516 etherdev_reg_write(RBCR0, 0x04);
517 etherdev_reg_write(RBCR1, 0x00);
519 // Initiate DMA transfer of packet header.
520 etherdev_reg_write(CR, RD0 | STA);
522 // Drop packet status. We don't use it.
523 etherdev_reg_read(RDMA);
525 // Save next packet pointer.
526 next_rx_packet = etherdev_reg_read(RDMA);
528 // Retrieve packet data length and subtract CRC bytes.
529 len = etherdev_reg_read(RDMA);
530 len += etherdev_reg_read(RDMA) << 8;
533 // Wait until remote DMA operation completes.
534 while(!(etherdev_reg_read(ISR) & RDC)) continue;
536 // Abort/ complete DMA operation.
537 etherdev_reg_write(CR, RD2 | STA);
540 // Retrieve packet data.
542 // Check if incoming packet will fit into rx buffer.
543 if(len <= sizeof(uip_buf))
545 // Clear remote DMA complete interrupt status register bit.
546 etherdev_reg_write(ISR, RDC);
548 // Set remote DMA start address registers to packet data.
549 etherdev_reg_write(RSAR0, 0x04);
550 etherdev_reg_write(RSAR1, etherdev_reg_read(BNRY));
552 // Set remote DMA byte count registers to packet data length.
553 etherdev_reg_write(RBCR0, (unsigned char)(len & 0xFF));
554 etherdev_reg_write(RBCR1, (unsigned char)(len >> 8));
556 // Initiate DMA transfer of packet data.
557 etherdev_reg_write(CR, RD0 | STA);
559 // Read packet data directly into uip_buf.
560 for(i = 0; i < len; i++)
562 *(uip_buf + i) = etherdev_reg_read(RDMA);
565 // Wait until remote DMA operation complete.
566 while(!(etherdev_reg_read(ISR) & RDC)) continue;
568 // Abort/ complete DMA operation.
569 etherdev_reg_write(CR, RD2 | STA);
574 // Incoming packet too big, so dump it.
578 // Advance boundary pointer to next packet start.
579 etherdev_reg_write(BNRY, next_rx_packet);
581 // Select RTL8019AS register page 1.
582 ETHERDEV_SELECT_REG_PAGE(1);
584 // Retrieve current receive buffer page
585 current = etherdev_reg_read(CURR);
587 // Select RTL8019AS register page 0.
588 ETHERDEV_SELECT_REG_PAGE(0);
590 // Check if last packet has been removed from rx buffer.
591 if(next_rx_packet == current)
593 // Clear packet received interrupt flag.
594 etherdev_reg_write(ISR, PRX);