ENC28J60 link detection

Da sich meine Standard ENC28J60 Library gerne mal aufhängt, wenn ich ein Paket versende und es keine Physikalische Verbindung gibt, war klar: eine Link-Detection muss her.

Erster Ansatzpunkt ist das Datenblatt[1] vom ENC28J60.

Auf Seite 26 findet sich ein interessantes Register: PHSTAT2.
Im 10. Bit (LSTAT) findet sich der Status wieder.
0 = Link down / 1 = Link up

Das klingt zwar einfach, aber man muss einigen Aufwand betreiben, um an das Register heran zu kommen.

(Kleine Anmerkung: Ich fange in diesem Artikel immer bei 0 an zu zählen und nicht bei 1 =) )

Zuerst werfen wir einen Blick auf das SPI-Interface.

Das erste zu sendende Byte ist speziell aufgebaut.
Die 3 höchsten Bits (Bit 7 – 5) geben den Opcode an; also was wir machen wollen.
Für uns relevant sind: (4.2 – SPI Instruction Set; Seite 28)

0 0 0 = Read Control Register (Wert aus einem Register lesen)
0 1 0 = Write Control Register (Wert in ein Register schreiben)
1 0 0 = Bit Field Set (Maskierte XOR Operation auf ein Register durchführen)
1 0 1 = Bit Field Clear (Maskierte NOTAND Operation auf ein Register durchführen)

Die übrigen 5 Bits (Bit 4 – 0) geben die Adresse an, die unsere Operation betrifft.

Da das PHSTAT2 Register sehr tief im Chip hängt, muss jetzt einiges getan werden.

Die relevanten Register sind: (3.1 – Control Registers; Seite 14 – 16)

0x11 = PHSTAT2
0x12 = MICMD
0x14 = MIREGADR
0x18 = MIRDL
0x19 = MIRDH
0x1F = ECON1
0x0A = MISTAT

Noch kurz Vorweg: Die Register des ENC’s sind in 4 „Bänke“ aufgeteilt. Das heißt, dass unter Adresse X sich mehrere Register befinden, die man durch ein Global verfügbares Register (ECON1) auswählt.
Die 2 niedrigsten Bits (Bit 1 – 0) geben die Bank an. 0b00 = 0; 0b01 = 1; 0b10 = 2; 0b11 = 3;

Da das PHSTAT2 Register zur Kategorie PHY-Register gehört, müssen wir die Adresse des PHY-Registers nach MIREGADR schreiben.
MIREGADR liegt in Bank 2. Also muss vorher in ECON1 die Bank gesetzt werden; und das geht so:

1. ECON1 holen und in einer Variablen sichern. (Opcode 0x00 OR Register 0x1F => 0x1F senden; lesen)
2. Geholte Variable modifizieren. ((var AND 0b11111100) OR 0x02) [Bit 1 und 0 werden auf 1 und 0 gesetzt]
3. Modifizierte Variable senden. (Opcode 0x40 OR Register 0x1F => 0x5F senden; var senden)

Und schon ist man in der 2. Bank.

Jetzt kann man die Adresse des PHSTAT2 Registers nach MIREGADR schreiben und das MIIRD Bit in MICMD setzen.

4. PHSTAT2 nach MIREGADR schreiben. (Opcode 0x40 OR Register 0x14 => 0x54 senden; Register 0x11 senden)
5. Bit 0 in MICMD setzen. (Opcode 0x80 OR Register 0x12 => 0x92 senden; Maske 0b00000001 bzw. 0x01 senden)
Achtung! Laut Datenblatt müsste man jetzt ca. 11 µSekunden warten und ein Status-Bit prüfen – ich will es aber nicht verkomplizieren. 20 µSekunden sollten auf jeden Fall reichen.
6. 20 µSekunden warten (muss reichen – wenn nicht: Datenblatt selber lesen =) ).
7. Bit 0 in MICMD löschen. (Opcode 0xA0 OR Register 0x12 => 0xB2 senden; Maske 0b00000001 bzw. 0x01 senden)

Nun sollte in den Registern MIRDL und MIRDH das ergebnis stehen. Die Reihenfolge, wie man diese zwei Bytes lesen muss ist egal. (z.B. nicht wie beim Atmel)

8. MIRDL holen. (Opcode 0x00 OR Register 0x18 => 0x18 senden; lesen)
9. MIRDH holen. (Opcode 0x00 OR Register 0x19 => 0x19 senden; lesen)

Nun hat man endlich den gewünschten Wert aus dem SPI abgeholt.

Wenn ihr eine fremde Library benutzt und der ENC28J60 danach nicht mehr wie gewohnt arbeiten will, muss eventuell der alte Wert aus ECON1 wieder nach ECON1 geschrieben werden.

Die gesamte Kommunikation (in Bits) sieht so aus:

1. 00011111 senden
2. 01100000 wird gelesen (Beispiel!)
3. 01011111 01100010 senden
4. 01010100 00010001 senden
5. 10010010 00000001 senden
6. 20 µSekunden warten
7. 10110010 00000001 senden
8. 00011000 senden
9. 00000000 wird gelesen (Beispiel!)
10. 00011001 senden
11. 00000100 wird gelesen (Beispiel! – das High-Bit (‚1‘) ist das gesuchte LSTAT Bit)

Und so weiß die Software, ob ein Kabel richtig angeschlossen ist – oder eben nicht.

Links:
[1] ENC28J60 Datenblatt: http://ww1.microchip.com/downloads/en/devicedoc/39662b.pdf

Schreibe einen Kommentar