From: Leandro Lucarella Date: Mon, 5 Dec 2005 06:22:49 +0000 (+0000) Subject: Más limpieza de código y corrección de algunos errores raros. X-Git-Tag: 0.1-recibe-matriz-raw-por-udp~35 X-Git-Url: https://git.llucax.com/z.facultad/66.09/etherled.git/commitdiff_plain/a6042244f620fab815a3d899480dd7a9b4665707 Más limpieza de código y corrección de algunos errores raros. --- diff --git a/pruebas/keil/red_test_anda/etherdev.c b/pruebas/keil/red_test_anda/etherdev.c index 2b265b8..ce60000 100644 --- a/pruebas/keil/red_test_anda/etherdev.c +++ b/pruebas/keil/red_test_anda/etherdev.c @@ -87,7 +87,7 @@ static unsigned char etherdev_reg_read(unsigned char reg) ETH_ADDR_PORT |= reg; // Enable register data output from RTL8019AS. - NICE = 0; + NICE = 0; IOR = 0; // Read register data from port. @@ -95,7 +95,7 @@ static unsigned char etherdev_reg_read(unsigned char reg) // Disable register data output from RTL8019AS. IOR = 1; - NICE = 1; + NICE = 1; return rd_data; } @@ -155,9 +155,6 @@ bit etherdev_init(void) return 0; } - // Select RTL8019AS register page 0. - ETHERDEV_SELECT_REG_PAGE(0); - // Stop RTL8019AS, select page 0 and abort DMA operation. etherdev_reg_write(CR, RD2 | STP); @@ -200,7 +197,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+1); + etherdev_reg_write(CURR, ETH_RX_PAGE_START + 1); // Set physical address etherdev_reg_write(PAR0, 0x00); @@ -341,6 +338,65 @@ unsigned int etherdev_read(void) return bytes_read; } +static void etherdev_reset() +{ + bit retransmit = etherdev_reg_read(CR) & TXP; + + // If the receive buffer ring has overflowed we dump the whole + // thing and start over. There is no way of knowing whether the + // data it contains is uncorrupted, or will cause us grief. + + // Stop RTL8019AS and abort DMA operation. + etherdev_reg_write(CR, RD2 | STP); + + // Wait for controller to halt after any current tx completes. + while(!(etherdev_reg_read(ISR) & RST)) continue; + + // Reset remote byte count registers. + etherdev_reg_write(RBCR0, 0x00); + etherdev_reg_write(RBCR1, 0x00); + + // Check whether currently transmitting a packet. + if(retransmit) + { + // If neither a successful transmission nor a tx abort error + // has occured, then flag current tx packet for resend. + if(etherdev_reg_read(ISR) & (PTX | TXE)) + { + retransmit = 0; + } + } + + // Set transmit configuration register to loopback internally. + etherdev_reg_write(TCR, LB0); + + // Restart the RTL8019AS. + etherdev_reg_write(CR, RD2 | STA); + + // Re-initialise last receive buffer read pointer. + etherdev_reg_write(BNRY, ETH_RX_PAGE_START); + + // Select RTL8019AS register page 1. + ETHERDEV_SELECT_REG_PAGE(1); + + // Re-initialise current packet receive buffer page pointer. + etherdev_reg_write(CURR, ETH_RX_PAGE_START + 1); + + // Select RTL8019AS register page 0. + ETHERDEV_SELECT_REG_PAGE(0); + + // Clear rx buffer overflow & packet received interrupt flags. + etherdev_reg_write(ISR, PRX | OVW); + + // Re-itialise transmit configuration reg for normal operation. + etherdev_reg_write(TCR, 0x00); + + if(retransmit) + { + // Retransmit packet in RTL8019AS local tx buffer. + etherdev_reg_write(CR, RD2 | TXP | STA); + } +} /* @@ -353,212 +409,150 @@ 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) + // 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; + ETHERDEV_SELECT_REG_PAGE(1); leds2 = ~etherdev_reg_read(CURR); + ETHERDEV_SELECT_REG_PAGE(0); sleep(5); + etherdev_reset(); + len = 0; } - // Check if there is a packet in the rx buffer. - if(etherdev_reg_read(ISR) & PRX) + else if (etherdev_reg_read(ISR) & PRX) { - // Check if the rx buffer has overflowed. - if(etherdev_reg_read(ISR) & OVW) - { - bit retransmit = 0; + unsigned int i; + unsigned char next_rx_packet; + unsigned char current; + unsigned char bnry; + unsigned char status; - // If the receive buffer ring has overflowed we dump the whole - // thing and start over. There is no way of knowing whether the - // data it contains is uncorrupted, or will cause us grief. + // Retrieve packet header. (status, next_ptr, length_l, length_h) - // Stop RTL8019AS and abort DMA operation. - etherdev_reg_write(CR, RD2 | STP); + // 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, bnry); - // Reset remote byte count registers. - etherdev_reg_write(RBCR0, 0x00); - etherdev_reg_write(RBCR1, 0x00); + // Select RTL8019AS register page 1. + ETHERDEV_SELECT_REG_PAGE(1); - // Wait for controller to halt after any current tx completes. - while(!(etherdev_reg_read(ISR) & RST)) continue; + // Retrieve current receive buffer page + current = etherdev_reg_read(CURR); - // Check whether currently transmitting a packet. - if(etherdev_reg_read(CR) & TXP) - { - // If neither a successful transmission nor a tx abort error - // has occured, then flag current tx packet for resend. - if(!((etherdev_reg_read(ISR) & PTX) - || (etherdev_reg_read(ISR) & TXE))) - { - retransmit = 1; - } - } - - // Set transmit configuration register to loopback internally. - etherdev_reg_write(TCR, LB0); - - // Restart the RTL8019AS. - etherdev_reg_write(CR, RD2 | STA); + // Select RTL8019AS register page 1. + ETHERDEV_SELECT_REG_PAGE(0); - // Re-initialise last receive buffer read pointer. - etherdev_reg_write(BNRY, ETH_RX_PAGE_START); - - // Select RTL8019AS register page 1. - ETHERDEV_SELECT_REG_PAGE(1); + // Check if last packet has been removed from rx buffer. + if(bnry == current) + { + // Clear packet received interrupt flag. + etherdev_reg_write(ISR, PRX | RXE); + return 0; + } - // Re-initialise current packet receive buffer page pointer. - etherdev_reg_write(CURR, ETH_RX_PAGE_START+1); + // Set remote DMA byte count registers to packet header length. + etherdev_reg_write(RBCR0, 0x04); + etherdev_reg_write(RBCR1, 0x00); - // Select RTL8019AS register page 0. - ETHERDEV_SELECT_REG_PAGE(0); + // Clear remote DMA complete interrupt status register bit. + etherdev_reg_write(ISR, RDC); - // Clear rx buffer overflow & packet received interrupt flags. - etherdev_reg_write(ISR, PRX | OVW); + // Initiate DMA transfer of packet header. + etherdev_reg_write(CR, RD0 | STA); - // Re-itialise transmit configuration reg for normal operation. - etherdev_reg_write(TCR, 0x00); - - if(retransmit) - { - // Retransmit packet in RTL8019AS local tx buffer. - etherdev_reg_write(CR, RD2 | TXP | STA); - } - } - else // Rx buffer has not overflowed, so read a packet into uip_buf. - { - 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) - - // 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, bnry); + // Packet status. + status = etherdev_reg_read(RDMA); - // Select RTL8019AS register page 1. - ETHERDEV_SELECT_REG_PAGE(1); + // Save next packet pointer. + next_rx_packet = etherdev_reg_read(RDMA); - // Retrieve current receive buffer page - current = etherdev_reg_read(CURR); + // Retrieve packet data length and subtract CRC bytes. + len = etherdev_reg_read(RDMA); + len += etherdev_reg_read(RDMA) << 8; + len -= 4; - // Select RTL8019AS register page 1. - ETHERDEV_SELECT_REG_PAGE(0); + // Wait until remote DMA operation completes. + while(!(etherdev_reg_read(ISR) & RDC)) continue; - // 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; - } + // Abort/ complete DMA operation. + etherdev_reg_write(CR, RD2 | STA); - // Set remote DMA byte count registers to packet header length. - etherdev_reg_write(RBCR0, 0x04); - etherdev_reg_write(RBCR1, 0x00); + // Limpia ISR + etherdev_reg_write(ISR, RDC); - // 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); + // Si es un paquete inválido, lo dropeamos + if (len < 60 || len > 1518) + { + len = 0; + goto drop; + } - // Packet status. - status = etherdev_reg_read(RDMA); + // Si hubo un error, también lo dropeamos + if ((status & 0x0F) != RXSOK) + { + len = 0; + goto drop; + } - // Save next packet pointer. - next_rx_packet = etherdev_reg_read(RDMA); + // Retrieve packet data. - // Retrieve packet data length and subtract CRC bytes. - len = etherdev_reg_read(RDMA); - len += etherdev_reg_read(RDMA) << 8; - len -= 4; + // Check if incoming packet will fit into rx buffer. + if(len <= sizeof(uip_buf)) + { - // Wait until remote DMA operation completes. - while(!(etherdev_reg_read(ISR) & RDC)) continue; + // Set remote DMA start address registers to packet data. + etherdev_reg_write(RSAR0, 0x04); + etherdev_reg_write(RSAR1, bnry); - // Abort/ complete DMA operation. - etherdev_reg_write(CR, RD2 | STA); + // Set remote DMA byte count registers to packet data length. + etherdev_reg_write(RBCR0, (unsigned char)(len & 0xFF)); + etherdev_reg_write(RBCR1, (unsigned char)(len >> 8)); - // Limpia ISR - etherdev_reg_write(ISR, RDC); + // Initiate DMA transfer of packet data. + etherdev_reg_write(CR, RD0 | STA); - if (len < 60 || len > 1518) // XXX DROP!!! + // Read packet data directly into uip_buf. + uip_len = len; + for(i = 0; i < 14; i++) { - leds1 = ~0xff; - leds2 = ~0x01; - while(1); + etherdev_reg_read(RDMA); // XXX descarto cabecera eth } - - if ((status & 0x0F) != RXSOK) // XXX DROP!!! + for(i = 14; i < len; i++) { - leds1 = ~0xff; - leds2 = ~0x02; - while(1); + uip_buf[i] = etherdev_reg_read(RDMA); // XXX copio el resto } - // Retrieve packet data. - - // Check if incoming packet will fit into rx buffer. - if(len <= sizeof(uip_buf)) - { - - // Set remote DMA start address registers to packet data. - etherdev_reg_write(RSAR0, 0x04); - etherdev_reg_write(RSAR1, bnry); - - // Set remote DMA byte count registers to packet data length. - etherdev_reg_write(RBCR0, (unsigned char)(len & 0xFF)); - etherdev_reg_write(RBCR1, (unsigned char)(len >> 8)); - - // Initiate DMA transfer of packet data. - etherdev_reg_write(CR, RD0 | STA); - - // Read packet data directly into uip_buf. - uip_len = len; - for(i = 0; i < 14; i++) - { - 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. - while(!(etherdev_reg_read(ISR) & RDC)) continue; + // Wait until remote DMA operation complete. + while(!(etherdev_reg_read(ISR) & RDC)) continue; - // Abort/ complete DMA operation. - etherdev_reg_write(CR, RD2 | STA); + // Abort/ complete DMA operation. + etherdev_reg_write(CR, RD2 | 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); - } - else - { - // Incoming packet too big, so dump it. - len = 0; - } + } + else + { + // Incoming packet too big, so dump it. + len = 0; + } - // Advance boundary pointer to next packet start. - etherdev_reg_write(BNRY, next_rx_packet - 1); +drop: + // Advance boundary pointer to next packet start. + etherdev_reg_write(BNRY, next_rx_packet - 1); - // Select RTL8019AS register page 0. - ETHERDEV_SELECT_REG_PAGE(0); - } } return len; diff --git a/pruebas/keil/red_test_anda/main.c b/pruebas/keil/red_test_anda/main.c index 601f292..90be817 100644 --- a/pruebas/keil/red_test_anda/main.c +++ b/pruebas/keil/red_test_anda/main.c @@ -39,9 +39,9 @@ void main(void) len = etherdev_read(); if (len) { - leds1 = ~0x55; - leds2 = ~len; - sleep(0); + //leds1 = ~0x55; + //leds2 = ~len; + //sleep(0); /* for (len = 0; len < uip_len; ++len) {