]> git.llucax.com Git - z.facultad/66.09/etherled.git/commitdiff
Finalmente arreglo problema de overflow de recepciĆ³n (gracias a los muchachos
authorLeandro Lucarella <llucax@gmail.com>
Mon, 5 Dec 2005 02:25:25 +0000 (02:25 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Mon, 5 Dec 2005 02:25:25 +0000 (02:25 +0000)
que hicieron el driver de la DP8390 para Linux =).

pruebas/keil/red_test_anda/etherdev.c
pruebas/keil/red_test_anda/main.c

index 141308f83af504afcdc85f957313717c29502e71..2b265b82d366a8bdb22cd27d3aa231657c77b0f1 100644 (file)
@@ -200,7 +200,7 @@ bit etherdev_init(void)
     etherdev_reg_write(CR, RD2 | PS0 | STP);
 
     // Initialise current packet receive buffer page pointer
-    etherdev_reg_write(CURR, ETH_RX_PAGE_START);
+    etherdev_reg_write(CURR, ETH_RX_PAGE_START+1);
 
     // Set physical address
     etherdev_reg_write(PAR0, 0x00);
@@ -269,9 +269,6 @@ void etherdev_send(void)
     // Wait until pending transmit operation completes.
     while(etherdev_reg_read(CR) & TXP) continue;
 
-    // Clear remote DMA complete interrupt status register bit.
-    etherdev_reg_write(ISR, RDC);
-
     // Set remote DMA start address registers to indicate where to load packet.
     etherdev_reg_write(RSAR0, 0x00);
     etherdev_reg_write(RSAR1, ETH_TX_PAGE_START);
@@ -293,6 +290,9 @@ void etherdev_send(void)
     // Wait until remote DMA operation complete.
     while(!(etherdev_reg_read(ISR) & RDC)) continue;
 
+    // Clear remote DMA complete interrupt status register bit.
+    etherdev_reg_write(ISR, RDC);
+
     // Abort/ complete DMA operation.
     etherdev_reg_write(CR, RD2 | STA);
 
@@ -353,6 +353,20 @@ static unsigned int etherdev_poll(void)
 {
     unsigned int len = 0;
 
+    leds1 = ~0x01;
+    leds2 = ~etherdev_reg_read(ISR);
+    sleep(0);
+
+    if(etherdev_reg_read(ISR) & OVW)
+    {
+        leds1 = ~0x02;
+        leds2 = ~etherdev_reg_read(BNRY);
+        sleep(5);
+        leds1 = ~0x04;
+        leds2 = ~etherdev_reg_read(CURR);
+        sleep(5);
+    }
+
     // Check if there is a packet in the rx buffer.
     if(etherdev_reg_read(ISR) & PRX)
     {
@@ -400,7 +414,7 @@ static unsigned int etherdev_poll(void)
             ETHERDEV_SELECT_REG_PAGE(1);
 
             // Re-initialise current packet receive buffer page pointer.
-            etherdev_reg_write(CURR, ETH_RX_PAGE_START);
+            etherdev_reg_write(CURR, ETH_RX_PAGE_START+1);
 
             // Select RTL8019AS register page 0.
             ETHERDEV_SELECT_REG_PAGE(0);
@@ -422,25 +436,47 @@ static unsigned int etherdev_poll(void)
             unsigned int i;
             unsigned char next_rx_packet;
             unsigned char current;
+            unsigned char bnry;
+            unsigned char status;
 
             // Retrieve packet header. (status, next_ptr, length_l, length_h)
 
-            // Clear remote DMA complete interrupt status register bit.
-            etherdev_reg_write(ISR, RDC);
-
             // Set remote DMA start address registers to packet header.
+            bnry = etherdev_reg_read(BNRY) + 1;
+            if (bnry >= ETH_RX_PAGE_STOP)
+                bnry = ETH_RX_PAGE_START;
             etherdev_reg_write(RSAR0, 0x00);
-            etherdev_reg_write(RSAR1, etherdev_reg_read(BNRY));
+            etherdev_reg_write(RSAR1, bnry);
+
+            // Select RTL8019AS register page 1.
+            ETHERDEV_SELECT_REG_PAGE(1);
+
+            // Retrieve current receive buffer page
+            current = etherdev_reg_read(CURR);
+
+            // Select RTL8019AS register page 1.
+            ETHERDEV_SELECT_REG_PAGE(0);
+
+            // Check if last packet has been removed from rx buffer.
+            if(bnry == current)
+            {
+                // Clear packet received interrupt flag.
+                etherdev_reg_write(ISR, PRX);
+                return 0;
+            }
 
             // Set remote DMA byte count registers to packet header length.
             etherdev_reg_write(RBCR0, 0x04);
             etherdev_reg_write(RBCR1, 0x00);
 
+            // Clear remote DMA complete interrupt status register bit.
+            etherdev_reg_write(ISR, RDC);
+
             // Initiate DMA transfer of packet header.
             etherdev_reg_write(CR, RD0 | STA);
 
-            // Drop packet status. We don't use it.
-            etherdev_reg_read(RDMA);
+            // Packet status.
+            status = etherdev_reg_read(RDMA);
 
             // Save next packet pointer.
             next_rx_packet = etherdev_reg_read(RDMA);
@@ -456,18 +492,32 @@ static unsigned int etherdev_poll(void)
             // Abort/ complete DMA operation.
             etherdev_reg_write(CR, RD2 | STA);
 
+            // Limpia ISR
+            etherdev_reg_write(ISR, RDC);
+
+            if (len < 60 || len > 1518) // XXX DROP!!!
+            {
+                leds1 = ~0xff;
+                leds2 = ~0x01;
+                while(1);
+            }
+
+            if ((status & 0x0F) != RXSOK) // XXX DROP!!!
+            {
+                leds1 = ~0xff;
+                leds2 = ~0x02;
+                while(1);
+            }
 
             // Retrieve packet data.
 
             // Check if incoming packet will fit into rx buffer.
             if(len <= sizeof(uip_buf))
             {
-                // Clear remote DMA complete interrupt status register bit.
-                etherdev_reg_write(ISR, RDC);
 
                 // Set remote DMA start address registers to packet data.
                 etherdev_reg_write(RSAR0, 0x04);
-                etherdev_reg_write(RSAR1, etherdev_reg_read(BNRY));
+                etherdev_reg_write(RSAR1, bnry);
 
                 // Set remote DMA byte count registers to packet data length.
                 etherdev_reg_write(RBCR0, (unsigned char)(len & 0xFF));
@@ -477,9 +527,14 @@ static unsigned int etherdev_poll(void)
                 etherdev_reg_write(CR, RD0 | STA);
 
                 // Read packet data directly into uip_buf.
-                for(i = 0; i < len; i++)
+                uip_len = len;
+                for(i = 0; i < 14; i++)
                 {
-                    *(uip_buf + i) = etherdev_reg_read(RDMA);
+                    etherdev_reg_read(RDMA); // XXX descarto cabecera eth
+                }
+                for(i = 14; i < len; i++)
+                {
+                    uip_buf[i] = etherdev_reg_read(RDMA); // XXX copio el resto
                 }
 
                 // Wait until remote DMA operation complete.
@@ -488,6 +543,9 @@ static unsigned int etherdev_poll(void)
                 // Abort/ complete DMA operation.
                 etherdev_reg_write(CR, RD2 | STA);
 
+                // Clear remote DMA complete interrupt status register bit.
+                etherdev_reg_write(ISR, RDC);
+
             }
             else
             {
@@ -496,23 +554,10 @@ static unsigned int etherdev_poll(void)
             }
 
             // Advance boundary pointer to next packet start.
-            etherdev_reg_write(BNRY, next_rx_packet);
-
-            // Select RTL8019AS register page 1.
-            ETHERDEV_SELECT_REG_PAGE(1);
-
-            // Retrieve current receive buffer page
-            current = etherdev_reg_read(CURR);
+            etherdev_reg_write(BNRY, next_rx_packet - 1);
 
             // Select RTL8019AS register page 0.
             ETHERDEV_SELECT_REG_PAGE(0);
-
-            // Check if last packet has been removed from rx buffer.
-            if(next_rx_packet == current)
-            {
-                // Clear packet received interrupt flag.
-                etherdev_reg_write(ISR, PRX);
-            }
         }
     }
 
index 43546b2e70efd114d8d390d0a7cec497d0d83e7e..601f292b411ba7603e5457d840b4e6ed1dfaa32a 100644 (file)
@@ -15,6 +15,7 @@ void sleep(unsigned char times)
 
 void main(void)
 {
+    unsigned char count = 1;
     unsigned int len;
     leds1 = ~0xff;
     leds2 = ~0xff;
@@ -31,25 +32,34 @@ void main(void)
     // leemos
     do
     {
+
+    for (len = 14; len < sizeof(uip_buf); ++len)
+        uip_buf[len] = 0;
+
         len = etherdev_read();
         if (len)
         {
             leds1 = ~0x55;
-            leds2 = len;
-            sleep(2);
+            leds2 = ~len;
+            sleep(0);
+            /*
             for (len = 0; len < uip_len; ++len)
             {
                 leds1 = ~(1 << (len % 8));
                 leds2 = ~uip_buf[len];
                 sleep(5);
             }
-            leds1 = ~0x55;
-            leds2 = ~0x55;
+            */
+            //leds1 = ~0x33;
+            //leds2 = ~uip_buf[42];
+            //sleep(5);
+            uip_buf[13] = count++;
+            etherdev_send();
         }
         else
         {
-            leds1 = ~0xff;
-            leds2 = ~0xff;
+            leds1 = ~0x00;
+            leds2 = ~0x00;
         }
     }
     while (1); // Quedamos paveando forever