From: Leandro Lucarella Date: Mon, 5 Dec 2005 02:25:25 +0000 (+0000) Subject: Finalmente arreglo problema de overflow de recepciĆ³n (gracias a los muchachos X-Git-Tag: 0.1-recibe-matriz-raw-por-udp~36 X-Git-Url: https://git.llucax.com/z.facultad/66.09/etherled.git/commitdiff_plain/674a29d498921fc9a07d0582ae69e674a069ab9d Finalmente arreglo problema de overflow de recepciĆ³n (gracias a los muchachos que hicieron el driver de la DP8390 para Linux =). --- diff --git a/pruebas/keil/red_test_anda/etherdev.c b/pruebas/keil/red_test_anda/etherdev.c index 141308f..2b265b8 100644 --- a/pruebas/keil/red_test_anda/etherdev.c +++ b/pruebas/keil/red_test_anda/etherdev.c @@ -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); - } } } diff --git a/pruebas/keil/red_test_anda/main.c b/pruebas/keil/red_test_anda/main.c index 43546b2..601f292 100644 --- a/pruebas/keil/red_test_anda/main.c +++ b/pruebas/keil/red_test_anda/main.c @@ -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