X-Git-Url: https://git.llucax.com/z.facultad/66.09/etherled.git/blobdiff_plain/a963ad6157c406337b0d89323469296b5e865495..0052faf6d85ec776823a1a33efc8d911b4b4e2f6:/pruebas/keil/red_test_anda/etherdev.c diff --git a/pruebas/keil/red_test_anda/etherdev.c b/pruebas/keil/red_test_anda/etherdev.c index 4675026..93abcbf 100644 --- a/pruebas/keil/red_test_anda/etherdev.c +++ b/pruebas/keil/red_test_anda/etherdev.c @@ -1,11 +1,17 @@ // vim: set et sw=4 sts=4 : +#include "types.h" #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] = { @@ -17,17 +23,6 @@ unsigned char uip_buf[80] = 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 @@ -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_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_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) \ @@ -52,8 +45,6 @@ static unsigned int etherdev_poll(void); 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) { @@ -71,9 +62,6 @@ static void etherdev_reg_write(unsigned char reg, unsigned char wr_data) IOW = 1; NICE = 1; - // Set register data port as input again. - ETH_DATA_PORT = ETH_DATA_PORT_MASK; - 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; + // Set register data port as input. + ETH_DATA_PORT = ETH_DATA_PORT_MASK; + // 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() @@ -130,7 +100,7 @@ static void etherdev_timer0_isr(void) interrupt 1 using 1 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; @@ -156,7 +126,7 @@ bit etherdev_init(void) } // 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. @@ -170,16 +140,41 @@ bit etherdev_init(void) 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); + + // 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); @@ -194,54 +189,31 @@ bit etherdev_init(void) 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 - 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. - etherdev_reg_write(CR, RD2 | STP); + etherdev_reg_write(CR, ABORT | STP); // Restart RTL8019AS. - etherdev_reg_write(CR, RD2 | STA); + etherdev_reg_write(CR, ABORT | STA); // 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); - - // 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; } @@ -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. - 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; @@ -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(CR, RD1 | STA); + etherdev_reg_write(CR, WRITE | STA); // 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(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); @@ -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(CR, RD2 | TXP | STA); + etherdev_reg_write(CR, ABORT | TXP | STA); 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; @@ -347,7 +294,7 @@ static void etherdev_reset() // 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; @@ -368,10 +315,10 @@ static void etherdev_reset() } // Set transmit configuration register to loopback internally. - etherdev_reg_write(TCR, LB0); + etherdev_reg_write(TCR, MODE1); // 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); @@ -389,45 +336,49 @@ static void etherdev_reset() 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. - 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; - // Retardo mega-bizarro, si no lo pongo a veces leo basura del ISR - unsigned char j; - for (j = 0; j < 0xFF; ++j); // 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); - 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); - 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) @@ -472,7 +423,7 @@ static unsigned int etherdev_poll(void) 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); @@ -489,7 +440,7 @@ static unsigned int etherdev_poll(void) 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); @@ -523,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(CR, RD0 | STA); + etherdev_reg_write(CR, READ | STA); // Read packet data directly into uip_buf. uip_len = len; @@ -540,7 +491,7 @@ static unsigned int etherdev_poll(void) 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);