CC=sdcc
-
LD=sdcc
+CFLAGS=-DDEBUG
all: el.hex
--- /dev/null
+// vim: set et sw=4 sts=4 :
+
+#ifndef _DEBUG_H_
+#define _DEBUG_H_
+
+#ifdef DEBUG
+
+#include "types.h"
+#include "leds.h"
+
+#define sleep(t) \
+ do \
+ { \
+ uint16 i; \
+ byte j; \
+ for (i = 0; i < 0xffff; ++i) \
+ for (j = 0; j < t; ++j); \
+ } \
+ while (0)
+
+#define print(w) \
+ do \
+ { \
+ leds(w); \
+ sleep(8); \
+ } \
+ while (0)
+
+#define printb(bh, bl) print(WORD(bh, bl))
+
+#else // NO DEBUG
+
+#define sleep(t) ;
+#define print(w) ;
+#define printb(b1, b2) ;
+
+#endif // DEBUG
+
+#endif // _DEBUG_H_
// vim: set et sw=4 sts=4 :
+#include "debug.h"
#include "eth.h"
#include "dp8390.h"
-#ifdef DEBUG
-void sleep(unsigned char);
-#ifdef SDCC
-static xdata at 0x0080 byte leds0;
-static xdata at 0x00c0 byte leds1;
-#else
-static byte xdata leds0 _at_ 0x0080;
-static byte xdata leds1 _at_ 0x00c0;
-#endif
-#endif
-
/// Datos persistentes del módulo
-static union
+static union // Unión porque nunca se usan ambos juntos
{
byte send_len; ///> Tamaño del frame que será enviado
byte next_pkt; ///> Próximo frame a obtener
write_reg(RBCR1, 0u);
// Initiate DMA transfer of uip_buf & uip_appdata buffers to RTL8019AS.
- write_reg(CR, WRITE | STA);
+ write_reg(CR, WRITE);
}
/** Escribe un byte al buffer de la placa de red para ser enviado
* @return Cantidad de bytes del frame leído
*/
byte netdev_recv_start()
-{
+{
+ // Indicamos que no se leyó el paquete
+ persistent.next_pkt = 0;
+
// Check if the rx buffer has overflowed.
if (read_reg(ISR) & OVW)
{
if (read_reg(BNRY) == current)
{
-#ifdef DEBUG
- leds1 = ~0x01;
- leds2 = ~read_reg(ISR);
- sleep(5);
- leds1 = ~0x02;
- leds2 = ~read_reg(BNRY);
- sleep(5);
- leds1 = ~0x04;
- leds2 = ~current;
- sleep(5);
-#endif
+ printb(read_reg(ISR), 0x01);
+ printb(read_reg(BNRY), 0x02);
+ printb(current, 0x04);
reset();
}
return 0u;
// Check if last packet has been removed from rx buffer.
if(bnry == current)
{
+ print(0x0000);
// Clear packet received interrupt flag.
write_reg(ISR, PRX | RXE);
return 0u;
// Set remote DMA byte count registers to packet header length.
write_reg(RBCR0, sizeof(struct buf_hdr_t));
- write_reg(RBCR1, 0u);
+ write_reg(RBCR1, 0x00);
// Clear remote DMA complete interrupt status register bit.
write_reg(ISR, RDC);
buf_hdr.status = read_reg(RDMA);
// Save next packet pointer.
- buf_hdr.next = persistent.next_pkt = read_reg(RDMA);
+ buf_hdr.next = read_reg(RDMA);
+
+ // Indicamos cual es el próximo paquete para cuando termine
+ persistent.next_pkt = buf_hdr.next - 1;
+
+ printb(bnry, 0x03);
+ printb(current, 0x07);
+ printb(buf_hdr.next, 0x0f);
// Retrieve packet data length and subtract CRC bytes.
buf_hdr.len = read_reg(RDMA) - sizeof(struct buf_hdr_t);
// Si es muy grande, muy chico o hubo error, lo descartamos
if ((buf_hdr.len < MIN_PACKET_LEN) || (buf_hdr.len > MAX_PACKET_LEN)
|| ((buf_hdr.status & 0x0F) != RXSOK)
- || read_reg(RDMA)) // Parte alta del tamaño
+ || (current = read_reg(RDMA))) // Parte alta del tamaño
{
- ABORT_DMA(START); // Termina DMA
- write_reg(BNRY, buf_hdr.next - 1); // Pasa al próximo frame
+ printb(buf_hdr.next, 0x1f);
+ printb(buf_hdr.status, 0x3f);
+ printb(buf_hdr.len, 0x7f);
+ printb(current, 0xff);
return 0;
}
void netdev_recv_end()
{
// Abort/ complete DMA operation.
- ABORT_DMA(START);
+ ABORT_DMA(STOP);
// Advance boundary pointer to next packet start.
- write_reg(BNRY, persistent.next_pkt - 1);
+ if (persistent.next_pkt)
+ write_reg(BNRY, persistent.next_pkt);
}
#define ADDR_PORT_MASK 0x1F // Máscara de direcciones (para no cambiar
// bits que no se usan)
#ifdef SDCC
-sbit at 0xB2 IOW; // ISA slot pin B13, RTL8019AS pin 30, active low
+sbit at 0xB4 IOW; // ISA slot pin B13, RTL8019AS pin 30, active low
sbit at 0xB5 IOR; // ISA slot pin B14, RTL8019AS pin 29, active low
sbit at 0xB2 NICE; // A7, usado para activar placa de red
#else
#define STP 0x01 // Stop bit transceiver ctrl
// Shortcuts
#define PAGE0 0x00 // Page 0
- #define PAGE1 0x40 // Page 1
- #define PAGE2 0x80 // Page 2
- #define PAGE3 0xC0 // Page 3 (Reserved!)
- #define ABORT 0x20 // Abort/Complete DMA
- #define READ 0x0A // Remote Read (RD0 | STA)
- #define WRITE 0x12 // Remote Write (RD1 | STA)
- #define SENDPKT 0x1A // Send Packet (RD0 | RD1 | STA)
- #define STOP 0x21 // STP | ABORT
- #define START 0x22 // STA | ABORT
+ #define PAGE1 PS0 // Page 1
+ #define PAGE2 PS1 // Page 2
+ #define PAGE3 (PS0 | PS1) // Page 3 (Reserved!)
+ #define ABORT RD2 // Abort/Complete DMA
+ #define READ (RD0 | STA) // Remote Read
+ #define WRITE (RD1 | STA) // Remote Write
+ #define SENDPKT (RD0 | RD1 | STA) // Send Packet
+ #define STOP (ABORT | STP) // Para la placa de red
+ #define START (ABORT | STA) // Inicia la placa de red
#define RDMA 0x10 // Remote DMA port
#define RESET 0x18 // Reset port
#define CRC 0x01 // CRC generation inhibit bit
// Shortcuts
#define MODE0 0x00 // Loopback mode 0
- #define MODE1 0x02 // Loopback mode 1
- #define MODE2 0x04 // Loopback mode 2
- #define MODE3 0x06 // Loopback mode 3
+ #define MODE1 LB0 // Loopback mode 1
+ #define MODE2 LB1 // Loopback mode 2
+ #define MODE3 (LB0 | LB1) // Loopback mode 3
#define DCR REG_BASE + 0x0E // Data configuration register
// Data configuration register bits (write in page 0, read in page 2)
#define FT1 0x40 // FIFO threshold select bit 1
// vim: set et sw=4 sts=4 :
+#include "debug.h"
#include "netdev.h"
#include "eth.h"
--- /dev/null
+// vim: set et sw=4 sts=4 :
+
+#ifndef _LEDS_H_
+#define _LEDS_H_
+
+#include "types.h"
+
+#ifdef SDCC
+static xdata at 0x0080 byte leds0;
+static xdata at 0x00c0 byte leds1;
+#else
+static byte xdata leds0 _at_ 0x0080;
+static byte xdata leds1 _at_ 0x00c0;
+#endif
+
+#define leds(word) \
+ do \
+ { \
+ leds0 = ~LOW(word); \
+ leds1 = ~HIGH(word); \
+ } \
+ while (0)
+
+#endif // _LEDS_H_
// vim: set et sw=4 sts=4 :
+#include "debug.h"
+#include "leds.h"
#include "netdev.h"
#include "eth.h"
#include "ip.h"
#include "udp.h"
-#ifdef SDCC
-static xdata at 0x0080 byte leds0;
-static xdata at 0x00c0 byte leds1;
-#else
-static byte xdata leds0 _at_ 0x0080;
-static byte xdata leds1 _at_ 0x00c0;
-#endif
-
-#define leds(word) \
- do \
- { \
- leds0 = ~LOW(word); \
- leds1 = ~HIGH(word); \
- } \
- while (0)
-
-
-void sleep(unsigned char times)
-{
- unsigned int i;
- unsigned char j;
- for (i = 0; i < 0xffff; ++i)
- for (j = 0; j < times; ++j);
-}
-
void main(void)
{
// Apagamos todos los leds
- leds(0x0000);
+ leds(0);
// Inicializamos dispositivo de red
if (!netdev_init())
{
- leds(0xffff);
+ leds(0xFFFF);
while(1); // Si falla init nos quedamos bobos
}
while (1) // Forever
{
uint16 len = netdev_recv_start();
+ printb(len, 0x1);
if (!len) // no recibimos nada
- {
- netdev_recv_end();
- continue; // vamos de nuevo!
- }
+ goto drop; // Tiramos el paquete
+
+ // Tenemos algo!
+ //print(0x2);
// Parseamos cabecera ethernet
if (!eth_read_frame_header()) // No es un buen header
- {
- // Tenemos algo!
- netdev_recv_end(); // Tiramos el paquete
- continue; // Vamos de nuevo!
- }
+ goto drop; // Tiramos el paquete
+ //print(0x4);
// Vemos que protocolo transporta
switch (eth_proto)
{
case ETH_ARP: // FIXME, implementar ARP!
- netdev_recv_end(); // Tiramos el paquete
- continue; // Vamos de nuevo!
+ goto drop; // Tiramos el paquete
case ETH_IP:
+ //print(0x8);
// Parseamos cabecera IP
if (!ip_read_packet_header()) // No es un buen header
- {
- netdev_recv_end(); // Tiramos el paquete
- continue; // Vamos de nuevo!
- }
+ goto drop; // Tiramos el paquete
+ //print(0x10);
// Vemos que protocolo transporta
switch (ip_proto)
{
case IP_ICMP: // FIXME, implementar ICMP!
- netdev_recv_end(); // Tiramos el paquete
- continue; // Vamos de nuevo!
+ goto drop; // Tiramos el paquete
case IP_UDP:
+ //print(0x20);
// Parseamos cabecera UDP
if (!udp_read_dgram_header()) // No es un buen header
- {
- netdev_recv_end(); // Tiramos el paquete
- continue; // Vamos de nuevo!
- }
+ goto drop; // Tiramos el paquete
+ printb(udp_dgram_len, 0x40);
// TODO
// Nuestro protocolo, por ahora un simple echo!
for (len = 8; len < udp_dgram_len; len += 2) // 8 por la cabecera UDP
{
- leds(netdev_recv_word());
- sleep(5);
+ print(netdev_recv_word());
}
+drop:
+ netdev_recv_end();
}
}
}
if (netdev_recv_byte()) /* no soportamos más de 255 bytes */
return false; /* drop */
udp_dgram_len = netdev_recv_byte();
+ if (udp_dgram_len < 8) /* no puede ser más chico que sus cabeceras */
+ return false; /* drop */
/* agregamos tamaño al checksum */
sum(udp_dgram_len);
/* agregamos checksum al checksum */