Forum: Mikrocontroller und Digitale Elektronik ENC28J60 Tx funktioniert nicht


von Andy (Gast)


Lesenswert?

Hallo zusammen,
ich stehe momentan ziemlich auf dem Schlauch.
Habe einen ENC28J60 an einem LPC2129 sowie uIP als Stack. Momentan 
scheitere ich am Senden eines Paketes (getestet mit dem beliebten ping).
Die Anfrage wird korrekt empfangen und uIP generiert auch ein sinnvolles 
Antwort-Paket. Das kommt allerdings nie zum PC zurück.
Habe eine andere Implementierung des ENC28J60-Treibers ausprobiert und 
die funktioniert (ist nur ein wenig chaotisch geschrieben, über 
Geschmack läßt sich bekanntlich streiten). Nur bin ich irgendwie zu 
doof, den Unterschied zu meiner Implementierung zu finden.
Zumindest bin ich sicher, daß die Hardware und meine SPI-Routinen 
funktionieren.
Die Initialisierung sieht bei mir folgendermaßen aus:
1
void enc28j60_Init(unsigned char *MAC)
2
{
3
  // Chip-Select einrichten
4
  CS_DIR |= CS;
5
  ClearCS();
6
7
  // Reset
8
  ResetMacSW();
9
10
  // Speicher-Setup für Empfagspuffer
11
  BankSel(0);
12
  WriteCtrReg(ERXSTL,LOWBYTE(RXSTART_INIT));
13
  WriteCtrReg(ERXSTH,HIGHBYTE(RXSTART_INIT));
14
  WriteCtrReg(ERXNDL,LOWBYTE(RXSTOP_INIT));
15
  WriteCtrReg(ERXNDH,HIGHBYTE(RXSTOP_INIT));
16
17
  // Speicher-Setup für Sendepuffer
18
  WriteCtrReg(ETXSTL, LOWBYTE(TXSTART_INIT));
19
  WriteCtrReg(ETXSTH, HIGHBYTE(TXSTART_INIT));
20
21
  // Lese-Zeiger auf Anfang
22
  WriteCtrReg(ERXRDPTL, LOWBYTE(RXSTART_INIT));
23
  WriteCtrReg(ERXRDPTH, HIGHBYTE(RXSTART_INIT));
24
25
  // Empfagsfilter setzen
26
//  BankSel(1);
27
//  WriteCtrReg(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_BCEN);
28
29
  // MAC initialisieren
30
  BankSel(2);                             // select bank 2
31
  SetBitField(MACON1, MACON1_MARXEN|    // Enable reception of frames
32
            MACON1_TXPAUS|MACON1_RXPAUS);
33
//  WriteCtrReg(MACLCON2, 63);
34
  WriteCtrReg(MACON2, 0);
35
  SetBitField(MACON3, MACON3_FRMLNEN |    // Type / len field will be checked
36
                        MACON3_TXCRCEN |    // MAC will append valid CRC
37
                        MACON3_PADCFG0);    // All small packets will be padded
38
39
40
//  SetBitField(MACON4, MACON4_DEFER);
41
  WriteCtrReg(MAIPGL , 0x12);             // non back to back interpacket gap. set as per data sheet
42
  WriteCtrReg(MAIPGH , 0x0C);
43
  WriteCtrReg(MABBIPG, 0x12);             // back to back interpacket gap. set as per data sheet
44
  WriteCtrReg(MAMXFLL, LOWBYTE(MAXFRAMELEN));     // set max frame len
45
  WriteCtrReg(MAMXFLH, HIGHBYTE(MAXFRAMELEN));
46
47
  // MAC-Adresse schreiben
48
  BankSel(3);
49
  WriteCtrReg(MAADR6,*MAC++);
50
  WriteCtrReg(MAADR5,*MAC++);
51
  WriteCtrReg(MAADR4,*MAC++);
52
  WriteCtrReg(MAADR3,*MAC++);
53
  WriteCtrReg(MAADR2,*MAC++);
54
  WriteCtrReg(MAADR1,*MAC++);
55
56
  // PHY initialisieren
57
  WritePhyReg(PHCON2, PHCON2_HDLDIS);
58
  WritePhyReg(PHCON1, PHCON1_PDPXMD);
59
60
  // Interrupt ein
61
  BankSel(0);
62
  SetBitField(EIE, EIE_INTIE|EIE_PKTIE);
63
64
  // Empfang starten
65
  WriteCtrReg(ECON1, ECON1_RXEN);
66
}
Die Auskommentierten Zeilen stehen im funktionierenden Treiber nicht 
drin, haben aber keine Auswirkung auf die Anwesenheit meines Problems.

Die Sende-Routine schaut bei mir so aus:
1
/** MACRO for rev B5 fix.*/
2
#define ErrataFix()   SetBitField(ECON1, ECON1_TXRST);ClrBitField(ECON1, ECON1_TXRST);ClrBitField(EIR, EIR_TXERIF | EIR_TXIF)
3
4
void enc28j60_PacketSend(unsigned char *Buffer, unsigned short BufferLen)
5
{
6
  // Schreibzeiger auf Paketanfang
7
  BankSel(0);
8
  WriteCtrReg(EWRPTL, LOWBYTE(TXSTART_INIT));
9
  WriteCtrReg(EWRPTH, HIGHBYTE(TXSTART_INIT));
10
11
  // TxEnde auf Paket-Ende
12
  WriteCtrReg(ETXNDL, LOWBYTE(TXSTART_INIT+BufferLen));
13
  WriteCtrReg(ETXNDH, HIGHBYTE(TXSTART_INIT+BufferLen));
14
15
  // Control-Byte schreiben
16
  unsigned char ControlByte = 0;
17
  WriteMacBuffer(&ControlByte, 1);
18
19
  // Puffer schreiben
20
  WriteMacBuffer(Buffer, BufferLen);
21
22
  // Paket abschicken
23
  ErrataFix();
24
  SetBitField(ECON1, ECON1_TXRTS);
25
}
Schon mit und ohne ErrataFix() probiert, hat nichts geändert.
Der Puffer-Inhalt, der in die Routine übergeben wird, stimmt. Die 
Sub-Funktionen sollten auch in sich funktionieren, sonst käme ich mit 
dem Lesen der enc-Register und dem Empfang ja auch nicht klar.

Die Register haben bei mir vor & nach dem Senden den gleichen Inhalt 
(über 1min nach Senden getestet):
ESTAT  0x01
EIR    0x08
EIE    0xc0
ECON1  0x04
ECON2  0x80

Sieht jemand, woran es liegen könnte? Oder hat jemand einen Vorschlag, 
wie ich der Wurzel des Problems näher kommen könnte?

Grüzi
Andy

von Simon K. (simon) Benutzerseite


Lesenswert?

Ich kann dir leider nicht direkt helfen, aber in meinem uWebServer ist 
auch noch ein (von mir geschriebene) ENC28J60 Treiber drin:
Beitrag "ENC28J60 (Mikro-)Web-Server die Nächste"

Kannst du ja mal damit abgleichen.

von Andy (Gast)


Lesenswert?

Hallo Simon,
danke für den Link. Deine Speicheradressen im ENC sind anders als bei 
dem Treiber, der bei mir funktioniert.
Habe jetzt die Speicheradressen geändert und schreibe den Sendepuffer 
jetzt an einem Stück in den ENC (ohne zwischen Controll-Byte und Daten 
CS wegzunehmen).
Das Ergbnis ist interessant: ARP funktioniert, ICMP nicht.
Da ich an uIP nichts geändert habe, vermute ich noch einen Fehler im 
Puffer von Rx oder Tx.
Muß ich weitersuchen...

Danke!
Andy

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.