]> git.llucax.com Git - z.facultad/66.09/etherled.git/blobdiff - pruebas/keil/red_test_anda/etherdev.c
Implementa el protocolo ELP sobre UDP. Tiene problemas cuando los leds estan
[z.facultad/66.09/etherled.git] / pruebas / keil / red_test_anda / etherdev.c
index ce600004d6f509c5e0da44042158f7f91dc17ff0..93abcbf4198b9e38999ad673d520a5094296c521 100644 (file)
@@ -1,11 +1,17 @@
 // vim: set et sw=4 sts=4 :    
 
 // vim: set et sw=4 sts=4 :    
 
+#include "types.h"
 #include "etherdev.h"
 
 void sleep(unsigned char);
 
 #include "etherdev.h"
 
 void sleep(unsigned char);
 
-static xdata leds1 _at_ 0x0080;
-static xdata leds2 _at_ 0x00c0;
+#ifdef SDCC
+static xdata at 0x0080 byte leds1;
+static xdata at 0x00c0 byte leds2;
+#else
+static byte xdata leds1 _at_ 0x0080;
+static byte xdata leds2 _at_ 0x00c0;
+#endif
 
 unsigned char uip_buf[80] =
 {
 
 unsigned char uip_buf[80] =
 {
@@ -17,17 +23,6 @@ unsigned char uip_buf[80] =
 
 unsigned int uip_len = 14;
 
 
 unsigned int uip_len = 14;
 
-#define ETH_CPU_CLOCK      ETH_CPU_XTAL / 12    // 8051 clock rate (X1 mode)
-
-// Delay routine timing parameters
-#define ETH_DELAY_CONST    9.114584e-5          // Delay routine constant
-#define ETH_DELAY_MULTPLR  (unsigned char)(ETH_DELAY_CONST * ETH_CPU_CLOCK)
-
-// X1 CPU mode timing parameters
-#define ETH_T0_CLOCK             ETH_CPU_XTAL / 12 // Timer 0 mode 1 clock rate
-#define ETH_T0_INT_RATE          24                // Timer 0 intrupt rate (Hz)
-#define ETH_T0_RELOAD            65536 - (ETH_T0_CLOCK / ETH_T0_INT_RATE)
-
 // Packet transmit & receive buffer configuration
 #define ETH_TX_PAGE_START  0x40    // 0x4000 Tx buffer is  6 * 256 = 1536 bytes
 #define ETH_RX_PAGE_START  0x46    // 0x4600 Rx buffer is 26 * 256 = 6656 bytes
 // Packet transmit & receive buffer configuration
 #define ETH_TX_PAGE_START  0x40    // 0x4000 Tx buffer is  6 * 256 = 1536 bytes
 #define ETH_RX_PAGE_START  0x46    // 0x4600 Rx buffer is 26 * 256 = 6656 bytes
@@ -36,13 +31,11 @@ unsigned int uip_len = 14;
 #define ETH_ADDR_PORT_MASK 0x1F                 // 00011111y
 #define ETH_DATA_PORT_MASK 0xFF                 // 11111111y
 
 #define ETH_ADDR_PORT_MASK 0x1F                 // 00011111y
 #define ETH_DATA_PORT_MASK 0xFF                 // 11111111y
 
-#define ETH_MIN_PACKET_LEN 0x3C
+#define ETH_MIN_PACKET_LEN 0x3C                 // 60 bytes
 
 
 static void etherdev_reg_write(unsigned char reg, unsigned char wr_data);
 static unsigned char etherdev_reg_read(unsigned char reg);
 
 
 static void etherdev_reg_write(unsigned char reg, unsigned char wr_data);
 static unsigned char etherdev_reg_read(unsigned char reg);
-static void etherdev_delay_ms(unsigned int count);
-static unsigned int etherdev_poll(void);
 
 // Manipulate PS1 & PS0 in CR to select RTL8019AS register page. 
 #define ETHERDEV_SELECT_REG_PAGE(page)                                      \
 
 // Manipulate PS1 & PS0 in CR to select RTL8019AS register page. 
 #define ETHERDEV_SELECT_REG_PAGE(page)                                      \
@@ -52,8 +45,6 @@ static unsigned int etherdev_poll(void);
               etherdev_reg_write(CR, etherdev_reg_read(CR) | (page << 6));  \
           } while(0)
 
               etherdev_reg_write(CR, etherdev_reg_read(CR) | (page << 6));  \
           } while(0)
 
-static unsigned char tick_count = 0;
-
 
 static void etherdev_reg_write(unsigned char reg, unsigned char wr_data)
 {
 
 static void etherdev_reg_write(unsigned char reg, unsigned char wr_data)
 {
@@ -71,9 +62,6 @@ static void etherdev_reg_write(unsigned char reg, unsigned char wr_data)
     IOW = 1;
     NICE = 1;
 
     IOW = 1;
     NICE = 1;
 
-    // Set register data port as input again.
-    ETH_DATA_PORT = ETH_DATA_PORT_MASK;
-
     return;
 } 
 
     return;
 } 
 
@@ -86,6 +74,9 @@ static unsigned char etherdev_reg_read(unsigned char reg)
     ETH_ADDR_PORT &= ~ETH_ADDR_PORT_MASK;
     ETH_ADDR_PORT |= reg;
 
     ETH_ADDR_PORT &= ~ETH_ADDR_PORT_MASK;
     ETH_ADDR_PORT |= reg;
 
+    // Set register data port as input.
+    ETH_DATA_PORT = ETH_DATA_PORT_MASK;
+
     // Enable register data output from RTL8019AS.
     NICE = 0;
     IOR = 0;
     // Enable register data output from RTL8019AS.
     NICE = 0;
     IOR = 0;
@@ -101,27 +92,6 @@ static unsigned char etherdev_reg_read(unsigned char reg)
 } 
 
 
 } 
 
 
-/* 
-                                                                     
-                           etherdev_timer0_isr()                     
-                                                                     
- This function is invoked each 1/24th of a second and updates a      
- 1/24th of a second tick counter.                                    
-                                                                     
- */
-static void etherdev_timer0_isr(void) interrupt 1 using 1
-{
-    // Reload timer/ counter 0 for 24Hz periodic interrupt.   
-    TH0 = ETH_T0_RELOAD >> 8;
-    TL0 = ETH_T0_RELOAD;
-
-    // Increment 24ths of a second counter.
-    tick_count++;
-
-    return;
-}
-
-
 /*
                                                                      
                             etherdev_init()                          
 /*
                                                                      
                             etherdev_init()                          
@@ -130,7 +100,7 @@ static void etherdev_timer0_isr(void) interrupt 1 using 1
   Refer to National Semiconductor DP8390 App Note 874, July 1993.    
                                                                      
  */
   Refer to National Semiconductor DP8390 App Note 874, July 1993.    
                                                                      
  */
-bit etherdev_init(void)
+bool etherdev_init(void)
 {
     // Set IOR & IOW as they're active low.
     IOR = 1;
 {
     // Set IOR & IOW as they're active low.
     IOR = 1;
@@ -156,7 +126,7 @@ bit etherdev_init(void)
     }
 
     // Stop RTL8019AS, select page 0 and abort DMA operation.
     }
 
     // Stop RTL8019AS, select page 0 and abort DMA operation.
-    etherdev_reg_write(CR, RD2 | STP);
+    etherdev_reg_write(CR, ABORT | STP);
 
     // Initialise data configuration register. 
     // FIFO threshold 8 bytes, no loopback, don't use auto send packet.
 
     // Initialise data configuration register. 
     // FIFO threshold 8 bytes, no loopback, don't use auto send packet.
@@ -170,16 +140,41 @@ bit etherdev_init(void)
     etherdev_reg_write(RCR, MON);
 
     // Initialise transmit configuration register to loopback internally.
     etherdev_reg_write(RCR, MON);
 
     // Initialise transmit configuration register to loopback internally.
-    etherdev_reg_write(TCR, LB0);
+    etherdev_reg_write(TCR, MODE1);
 
     // Clear interrupt status register bits by writing 1 to each.
     etherdev_reg_write(ISR, 0xFF);
 
     // Mask all interrupts in mask register.
     etherdev_reg_write(IMR, 0x00);
 
     // Clear interrupt status register bits by writing 1 to each.
     etherdev_reg_write(ISR, 0xFF);
 
     // Mask all interrupts in mask register.
     etherdev_reg_write(IMR, 0x00);
+    
+    // Obtengo MAC de la placa
+    etherdev_reg_write(RBCR0, 0x0c); // Vamos a leer 12 bytes (2 x 6)
+    etherdev_reg_write(RBCR1, 0x00); 
+    etherdev_reg_write(RSAR0, 0x00); // En la dirección 0x0000
+    etherdev_reg_write(RSAR1, 0x00);
+    etherdev_reg_write(CR, READ | STA); // Comienza lectura
+    uip_buf[6] = etherdev_reg_read(RDMA);
+    etherdev_reg_read(RDMA); // Ignoramos porque viene como un word
+    uip_buf[7] = etherdev_reg_read(RDMA);
+    etherdev_reg_read(RDMA); // Ignoramos porque viene como un word
+    uip_buf[8] = etherdev_reg_read(RDMA);
+    etherdev_reg_read(RDMA); // Ignoramos porque viene como un word
+    uip_buf[9] = etherdev_reg_read(RDMA);
+    etherdev_reg_read(RDMA); // Ignoramos porque viene como un word
+    uip_buf[10] = etherdev_reg_read(RDMA);
+    etherdev_reg_read(RDMA); // Ignoramos porque viene como un word
+    uip_buf[11] = etherdev_reg_read(RDMA);
+    etherdev_reg_read(RDMA); // Ignoramos porque viene como un word
+
+    // Wait until remote DMA operation completes.
+    while(!(etherdev_reg_read(ISR) & RDC)) continue;
 
 
-    // TODO Obtengo MAC de la placa
-    //etherdev_reg_write(CR, 0x21);
+    // Abort/ complete DMA operation.
+    etherdev_reg_write(CR, ABORT | STP);
+
+    // Limpia ISR
+    etherdev_reg_write(ISR, RDC);
 
     // Set transmit page start.
     etherdev_reg_write(TPSR, ETH_TX_PAGE_START);
 
     // Set transmit page start.
     etherdev_reg_write(TPSR, ETH_TX_PAGE_START);
@@ -194,54 +189,31 @@ bit etherdev_init(void)
     etherdev_reg_write(PSTOP, ETH_RX_PAGE_STOP);
 
     // Select RTL8019AS register page 1.
     etherdev_reg_write(PSTOP, ETH_RX_PAGE_STOP);
 
     // Select RTL8019AS register page 1.
-    etherdev_reg_write(CR, RD2 | PS0 | STP);
+    etherdev_reg_write(CR, ABORT | PAGE1 | STP);
 
     // Initialise current packet receive buffer page pointer
     etherdev_reg_write(CURR, ETH_RX_PAGE_START + 1);
 
     // Set physical address
 
     // Initialise current packet receive buffer page pointer
     etherdev_reg_write(CURR, ETH_RX_PAGE_START + 1);
 
     // Set physical address
-    etherdev_reg_write(PAR0, 0x00);
-    etherdev_reg_write(PAR1, 0x0c);
-    etherdev_reg_write(PAR2, 0x6e);
-    etherdev_reg_write(PAR3, 0x37);
-    etherdev_reg_write(PAR4, 0x19);
-    etherdev_reg_write(PAR5, 0xbe);
+    etherdev_reg_write(PAR0, uip_buf[6]);
+    etherdev_reg_write(PAR1, uip_buf[7]);
+    etherdev_reg_write(PAR2, uip_buf[8]);
+    etherdev_reg_write(PAR3, uip_buf[9]);
+    etherdev_reg_write(PAR4, uip_buf[10]);
+    etherdev_reg_write(PAR5, uip_buf[11]);
 
     // Select RTL8019AS register page 0 and abort DMA operation.
 
     // Select RTL8019AS register page 0 and abort DMA operation.
-    etherdev_reg_write(CR, RD2 | STP);
+    etherdev_reg_write(CR, ABORT | STP);
 
     // Restart RTL8019AS. 
 
     // Restart RTL8019AS. 
-    etherdev_reg_write(CR, RD2 | STA);
+    etherdev_reg_write(CR, ABORT | STA);
 
     // Initialise transmit configuration register for normal operation.
 
     // Initialise transmit configuration register for normal operation.
-    etherdev_reg_write(TCR, 0x00);
+    etherdev_reg_write(TCR, MODE0);
 
     // Receive configuration register to accept broadcast packets.
     etherdev_reg_write(RCR, AB);
 
 
     // Receive configuration register to accept broadcast packets.
     etherdev_reg_write(RCR, AB);
 
-
-    // Initialize Timer 0 to generate a periodic 24Hz interrupt. 
-
-    // Stop timer/ counter 0.                                         
-    TR0  = 0;          
-
-    // Set timer/ counter 0 as mode 1 16 bit timer.      
-    TMOD &= 0xF0;
-    TMOD |= 0x01;
-
-    // Preload for 24Hz periodic interrupt.    
-    TH0 = ETH_T0_RELOAD >> 8; 
-    TL0 = ETH_T0_RELOAD;
-
-    // Restart timer/ counter 0 running.
-    TR0 = 1;
-
-    // Enable timer/ counter 0 overflow interrupt.            
-    ET0 = 1;
-
-    // Enable global interrupt.
-    EA = 1;
-
     return 1;
 }
 
     return 1;
 }
 
@@ -261,7 +233,7 @@ void etherdev_send(void)
     // Setup for DMA transfer from uip_buf & uip_appdata buffers to RTL8019AS.
 
     // Select RTL8019AS register page 0 and abort DMA operation.
     // Setup for DMA transfer from uip_buf & uip_appdata buffers to RTL8019AS.
 
     // Select RTL8019AS register page 0 and abort DMA operation.
-    etherdev_reg_write(CR, RD2 | STA);
+    etherdev_reg_write(CR, ABORT | STA);
 
     // Wait until pending transmit operation completes.
     while(etherdev_reg_read(CR) & TXP) continue;
 
     // Wait until pending transmit operation completes.
     while(etherdev_reg_read(CR) & TXP) continue;
@@ -275,7 +247,7 @@ void etherdev_send(void)
     etherdev_reg_write(RBCR1, (unsigned char)(uip_len >> 8));
 
     // Initiate DMA transfer of uip_buf & uip_appdata buffers to RTL8019AS.
     etherdev_reg_write(RBCR1, (unsigned char)(uip_len >> 8));
 
     // Initiate DMA transfer of uip_buf & uip_appdata buffers to RTL8019AS.
-    etherdev_reg_write(CR, RD1 | STA);
+    etherdev_reg_write(CR, WRITE | STA);
 
     // DMA transfer packet from uip_buf & uip_appdata to RTL8019AS local
     // transmit buffer memory.
 
     // DMA transfer packet from uip_buf & uip_appdata to RTL8019AS local
     // transmit buffer memory.
@@ -291,7 +263,7 @@ void etherdev_send(void)
     etherdev_reg_write(ISR, RDC);
 
     // Abort/ complete DMA operation.
     etherdev_reg_write(ISR, RDC);
 
     // Abort/ complete DMA operation.
-    etherdev_reg_write(CR, RD2 | STA);
+    etherdev_reg_write(CR, ABORT | STA);
 
     // Set transmit page start to indicate packet start.
     etherdev_reg_write(TPSR, ETH_TX_PAGE_START);
 
     // Set transmit page start to indicate packet start.
     etherdev_reg_write(TPSR, ETH_TX_PAGE_START);
@@ -307,37 +279,12 @@ void etherdev_send(void)
     etherdev_reg_write(TBCR1, (unsigned char)(uip_len >> 8));
 
     // Issue command for RTL8019AS to transmit packet from it's local buffer.
     etherdev_reg_write(TBCR1, (unsigned char)(uip_len >> 8));
 
     // Issue command for RTL8019AS to transmit packet from it's local buffer.
-    etherdev_reg_write(CR, RD2 | TXP | STA);
+    etherdev_reg_write(CR, ABORT | TXP | STA);
 
     return;
 }
 
 
 
     return;
 }
 
 
-/*
-                                                                     
-                           etherdev_read()                           
-                                                                     
- This function will read an entire IP packet into the uip_buf.       
- If it must wait for more than 0.5 seconds, it will return with      
- the return value 0. Otherwise, when a full packet has been read     
- into the uip_buf buffer, the length of the packet is returned.      
-                                                                     
- */
-unsigned int etherdev_read(void)
-{    
-    unsigned int bytes_read;
-
-    /* tick_count threshold should be 12 for 0.5 sec bail-out
-       One second (24) worked better for me, but socket recycling
-       is then slower. I set UIP_TIME_WAIT_TIMEOUT 60 in uipopt.h
-       to counter this. Retransmission timing etc. is affected also. */
-    while ((!(bytes_read = etherdev_poll())) && (tick_count < 12)) continue;
-
-    tick_count = 0;
-
-    return bytes_read;
-}
-
 static void etherdev_reset()
 {
     bit retransmit = etherdev_reg_read(CR) & TXP;
 static void etherdev_reset()
 {
     bit retransmit = etherdev_reg_read(CR) & TXP;
@@ -347,7 +294,7 @@ static void etherdev_reset()
     // data it contains is uncorrupted, or will cause us grief.
 
     // Stop RTL8019AS and abort DMA operation.
     // data it contains is uncorrupted, or will cause us grief.
 
     // Stop RTL8019AS and abort DMA operation.
-    etherdev_reg_write(CR, RD2 | STP);
+    etherdev_reg_write(CR, ABORT | STP);
 
     // Wait for controller to halt after any current tx completes.
     while(!(etherdev_reg_read(ISR) & RST)) continue;
 
     // Wait for controller to halt after any current tx completes.
     while(!(etherdev_reg_read(ISR) & RST)) continue;
@@ -368,10 +315,10 @@ static void etherdev_reset()
     }
 
     // Set transmit configuration register to loopback internally.
     }
 
     // Set transmit configuration register to loopback internally.
-    etherdev_reg_write(TCR, LB0);
+    etherdev_reg_write(TCR, MODE1);
 
     // Restart the RTL8019AS.
 
     // Restart the RTL8019AS.
-    etherdev_reg_write(CR, RD2 | STA);
+    etherdev_reg_write(CR, ABORT | STA);
 
     // Re-initialise last receive buffer read pointer.
     etherdev_reg_write(BNRY, ETH_RX_PAGE_START);
 
     // Re-initialise last receive buffer read pointer.
     etherdev_reg_write(BNRY, ETH_RX_PAGE_START);
@@ -389,42 +336,49 @@ static void etherdev_reset()
     etherdev_reg_write(ISR, PRX | OVW);
 
     // Re-itialise transmit configuration reg for normal operation.
     etherdev_reg_write(ISR, PRX | OVW);
 
     // Re-itialise transmit configuration reg for normal operation.
-    etherdev_reg_write(TCR, 0x00);
+    etherdev_reg_write(TCR, MODE0);
 
     if(retransmit)
     {
         // Retransmit packet in RTL8019AS local tx buffer.
 
     if(retransmit)
     {
         // Retransmit packet in RTL8019AS local tx buffer.
-        etherdev_reg_write(CR, RD2 | TXP | STA);
+        etherdev_reg_write(CR, ABORT | TXP | STA);
     }
 }
 
     }
 }
 
-/*
-                                                                     
-                           etherdev_poll()                           
-                                                                     
- Poll the RTL8019AS ethernet device for an available packet.         
-                                                                     
- */
-static unsigned int etherdev_poll(void)
-{
+
+unsigned int etherdev_read(void)
+{    
     unsigned int len = 0;
 
     // Check if the rx buffer has overflowed.
     if (etherdev_reg_read(ISR) & OVW)
     {
     unsigned int len = 0;
 
     // Check if the rx buffer has overflowed.
     if (etherdev_reg_read(ISR) & OVW)
     {
-        leds1 = ~0x01;
-        leds2 = ~etherdev_reg_read(ISR);
-        sleep(5);
-        leds1 = ~0x02;
-        leds2 = ~etherdev_reg_read(BNRY);
-        sleep(5);
-        leds1 = ~0x04;
+        unsigned char current;
+
+        // Select RTL8019AS register page 1.
         ETHERDEV_SELECT_REG_PAGE(1);
         ETHERDEV_SELECT_REG_PAGE(1);
-        leds2 = ~etherdev_reg_read(CURR);
+
+        // Retrieve current receive buffer page
+        current = etherdev_reg_read(CURR);
+
+        // Select RTL8019AS register page 1.
         ETHERDEV_SELECT_REG_PAGE(0);
         ETHERDEV_SELECT_REG_PAGE(0);
-        sleep(5);
-        etherdev_reset();
-        len = 0;
+
+        if (etherdev_reg_read(BNRY) == current)
+        {
+
+            leds1 = ~0x01;
+            leds2 = ~etherdev_reg_read(ISR);
+            sleep(5);
+            leds1 = ~0x02;
+            leds2 = ~etherdev_reg_read(BNRY);
+            sleep(5);
+            leds1 = ~0x04;
+            leds2 = ~current;
+            sleep(5);
+
+            etherdev_reset();
+        }
     }
     // Check if there is a packet in the rx buffer.
     else if (etherdev_reg_read(ISR) & PRX)
     }
     // Check if there is a packet in the rx buffer.
     else if (etherdev_reg_read(ISR) & PRX)
@@ -469,7 +423,7 @@ static unsigned int etherdev_poll(void)
         etherdev_reg_write(ISR, RDC);
 
         // Initiate DMA transfer of packet header.
         etherdev_reg_write(ISR, RDC);
 
         // Initiate DMA transfer of packet header.
-        etherdev_reg_write(CR, RD0 | STA);
+        etherdev_reg_write(CR, READ | STA);
 
         // Packet status.
         status = etherdev_reg_read(RDMA);
 
         // Packet status.
         status = etherdev_reg_read(RDMA);
@@ -486,7 +440,7 @@ static unsigned int etherdev_poll(void)
         while(!(etherdev_reg_read(ISR) & RDC)) continue;
 
         // Abort/ complete DMA operation.
         while(!(etherdev_reg_read(ISR) & RDC)) continue;
 
         // Abort/ complete DMA operation.
-        etherdev_reg_write(CR, RD2 | STA);
+        etherdev_reg_write(CR, ABORT | STA);
 
         // Limpia ISR
         etherdev_reg_write(ISR, RDC);
 
         // Limpia ISR
         etherdev_reg_write(ISR, RDC);
@@ -520,7 +474,7 @@ static unsigned int etherdev_poll(void)
             etherdev_reg_write(RBCR1, (unsigned char)(len >> 8));
 
             // Initiate DMA transfer of packet data.
             etherdev_reg_write(RBCR1, (unsigned char)(len >> 8));
 
             // Initiate DMA transfer of packet data.
-            etherdev_reg_write(CR, RD0 | STA);
+            etherdev_reg_write(CR, READ | STA);
 
             // Read packet data directly into uip_buf.
             uip_len = len;
 
             // Read packet data directly into uip_buf.
             uip_len = len;
@@ -537,7 +491,7 @@ static unsigned int etherdev_poll(void)
             while(!(etherdev_reg_read(ISR) & RDC)) continue;
 
             // Abort/ complete DMA operation.
             while(!(etherdev_reg_read(ISR) & RDC)) continue;
 
             // Abort/ complete DMA operation.
-            etherdev_reg_write(CR, RD2 | STA);
+            etherdev_reg_write(CR, ABORT | STA);
 
             // Clear remote DMA complete interrupt status register bit.
             etherdev_reg_write(ISR, RDC);
 
             // Clear remote DMA complete interrupt status register bit.
             etherdev_reg_write(ISR, RDC);