Forum: Mikrocontroller und Digitale Elektronik STM32F107 Ethernet Interface


von Gustav G. (gustavgggg)


Lesenswert?

Ich habe ein Board erstellt um mit dem STM32F107 die Ethernet 
Schnittstelle zu benutzen. Dazu nutze ich den DP83826 als PHY im Basic 
mode mit RMII. Der DP83826 wird außerdem im Master mode benutzt. Der 
bekommt also vom STM32 seine 25MHz über den MCO Pin an seinem XI pin. 
Der PHY ist per Strap so konfiguriert, dass er aus den 25MHz seine 50MHz 
für das RMII macht. Das habe ich gemessen und an der TXCLK liegen 50MHz 
an.

Leider startet aber keine automatische Link negotiation. Das verbinden 
eines Kabels mit einem PC führt nicht dazu, dass am PC der Link als 
aktiv angezeigt wird.

Ich nutze STM32 Cube und würde hier gerne fragen, ob ich noch auf etwas 
spezielles achten muss. Ich habe per debugger auch mal überprüft ob der 
controller über MDIO mit dem PHY kommunizieren kann. Das funktioniert 
einwandfrei, denn man mann das Register 0x02 auslesen und es liefert den 
erwarteten Wert.

Muss ich dem PHY oder dem lwip stack eventuell irgendwo sagen, dass er 
in regelmäßigen abständen neu prüfen soll, ob etwas angeschlossen ist?

von Wastl (hartundweichware)


Lesenswert?

Ich erinnere mich dass du das Problem in ähnlicher Weise schon
mal angesprochen hast. Hier:

Beitrag "STM32F107RBT6 Ethernet Clock"

Da kommt bei mir gleich die Frage auf ob du jetzt das Jitter-
Problem des PHY-Taktes angemessen berücksichtig hast. Dazu
finde ich in deinem jetzigen Bericht nichts dazu:

Gustav G. schrieb:
> Der DP83826 wird außerdem im Master mode benutzt. Der
> bekommt also vom STM32 seine 25MHz über den MCO Pin an seinem XI pin.

Wenn also der MCO Pin deines Controllers intern von der PLL
gespeist wird dann hast du etwas falsch gemacht bzw. schon
damals die Problematik nicht richtig verstanden.

von Gustav G. (gustavgggg)


Lesenswert?

Wastl schrieb:
> Wenn also der MCO Pin deines Controllers intern von der PLL
> gespeist wird dann hast du etwas falsch gemacht bzw. schon
> damals die Problematik nicht richtig verstanden.

Der MCO Pin wird direkt von HSE getrieben und nur die 25MHz 
durchgereicht. An der Stelle habe ich Unsinn geschrieben. Es ist keine 
PLL, die 25MHz generiert. An der Stelle habe ich mich an das Datenblatt 
gehalten und da wird diese Möglichkeit explizit genannt.

von Wastl (hartundweichware)


Lesenswert?

Gustav G. schrieb:
> Der MCO Pin wird direkt von HSE getrieben und nur die 25MHz
> durchgereicht.

Gustav G. schrieb:
> und da wird diese Möglichkeit explizit genannt.

Dagegen ist auch aus der Sicht der Jitter-Armut des Taktes für
den PHY nichts einzuwenden.

von Gustav G. (gustavgggg)


Lesenswert?

Wastl schrieb:
> Dagegen ist auch aus der Sicht der Jitter-Armut des Taktes für
> den PHY nichts einzuwenden.

Ich habe mich auch an Empfehlungen gehalten und folgenden Oszillator 
benutzt: ECS-2016MV-250-CN-TR

von Wastl (hartundweichware)


Lesenswert?

Jetzt kommt leider wieder die Salami-Thematik zu tragen ....
Wenn schon ein Schaltplan zu sehen wäre müsste man weniger
fragen ...

Aus den Datenblättern folgere ich dass die MAC-Einheit des
Controllers den 50MHz-Clock des PHY gespeist bekommen muss
(für den Fall der Konfiguration RMII). Der alternativ gespeiste
bzw. konfigurierte Pin heisst ETH_RMII_REF_CLK.

Hast du das berücksichtigt?

(soweit ich mich erinnere hatte ich das bei meiner Implementierung
für den F407 mehr oder weniger automatisch richtig gemacht
Beitrag "Re: STM32F107RBT6 Ethernet Clock")

von J. S. (jojos)


Lesenswert?

Gustav G. schrieb:
> Muss ich dem PHY oder dem lwip stack eventuell irgendwo sagen, dass er
> in regelmäßigen abständen neu prüfen soll, ob etwas angeschlossen ist?

das hängt davon ab ob man FreeRTOS eingebaut hat oder ohne OS arbeitet. 
In beiden Fällen wird Code generiert der den NIC Status abfragt und ein 
IF up/down auslöst. Ohne OS muss in der main loop das MX_LWIP_Process 
aufgerufen werden. Man kann einen Callback für die Statusänderung 
angeben. lwip hat Timer die z.B. auch die DHCP und ARP Anfragen 
auslösen.

von Joe J. (j_955)


Lesenswert?

Was auch wichtig ist - wie sieht die Initialisierung aus im Code?
Irgendwo musst du den PHY ja auch initialisieren.
Wir haben zb den KSZ 8081 und ich meine mich zu erinnern, das bestimmte 
Modi als default laufen. Kommst du denn durch die Init Routinen von ST 
durch?
Trag mal die ganzen Infos hier zusammen.
Viele Grüße

von Joe J. (j_955)


Lesenswert?

Meine Implementierung zb sieht vor, das der Status der Negotiation 
entsprechend auch zyklisch beim PHY abgefragt werden muss und so bringst 
du dann die Info entsrpechend in die Software ein - in Abhängigkeit von 
den Registern im PHY.
Post doch mal den Treiber für den PHY zb.
Du kannst doch bestimmt auch einfach mal die Register zyklish lesen und 
ausgeben auf einer UART oder so und Inhalte mit dem Datenblatt 
abgleichen.

: Bearbeitet durch User
von Gustav G. (gustavgggg)


Lesenswert?

Ich initialisiere da nichts besonderes, da ich bei der Cube IDE davon 
ausgehe, dass das alles gemacht wird. Ich habe auch nachgeschaut und 
MX_LWIP_Process wird aufgerufen. Ich nutze kein FreeRTOS. Allerdings ist 
mir aufgefallen, dass ich kein Interrupt Pin verbunden habe aber der 
Code davon ausgeht. Ich finde allerings im Falle eines Interrupts 
nirgendwo code, der auf den Link Status reagiert.

von J. S. (jojos)


Lesenswert?

Der Int wird nicht genutzt, dafür ist das MX_LWIP_Process, das erledigt 
alles per polling.
Im MW_LWIP_init wird auch der Phy Init auferufen, da kann man mit dem 
Debugger durchgehen.
Beim H7 habe ich das Problem das der zu schnell ist, der Phy init wird 
nach 3 ms aufgerufen, da hat der seine strapping bits noch nicht 
eingelesen und das Lesen des SR liefert -1 als Wert, aber keinen Fehler. 
In Folge läuft der Link mit 10 MBPS und half duplex, was dann keinen 
Datenaustausch erlaubt. Ist aber mit LAN8742. Es zeigt aber wie 
bescheiden der STM generierte Code an dieser Stelle ist. Weiteres 
Highlight ist, das der Phy init die Adressen 0...31 durchprobiert, 
obwohl der LAN8742 per strapping nur auf 0 oder 1 konfiguriert werden 
kann. Dann geht es weiter mit einer fixen Wartezeit von 2 s in der der 
Link ausgehandelt sein muss. Phy init liefert einen Fehlercode zurück, 
der wird aber einfach ignoriert.
Wenn man solche Sachen fixen möche, dann geht das nur indem man den 
Codegenerator abklemmt, der würde ja alles wieder überschreiben. Oder 
mühselig die Templates in der IDE Installation überschreiben...
Ich bin enttäuscht von dem Murks, hätte das für professioneller 
gehalten.
Und da haben wir noch nicht über das DMA/Cache Chaos geredet, das muss 
alles manuell konfiguriert werden.

nochmal zum Status:
in lwip.c wird der Callback
1
static void ethernet_link_status_updated(struct netif *netif)
angelegt, da darf man User Code reinschreiben. Diese Funktion muss 
aufgerufen werden wenn man das Netzwerkkabel zieht/steckt.
Diese wird für zusätzliche Aktionen aufgerufen, netif up/down behandelt 
lwip selber.

: Bearbeitet durch User
von Wastl (hartundweichware)


Lesenswert?

Gustav G. schrieb:
> Leider startet aber keine automatische Link negotiation.

Wastl schrieb:
> Hast du das berücksichtigt?

Ist das kein Thema mehr weil du das - ohne dich zu äussern -
bereits abgehandelt und für dich als nicht relevant betrachtet
hast? Oder hast du keine Lust dich mit potentiellen Problemen
bei der Hardware auseinanderzusetzen?

von Gustav G. (gustavgggg)


Lesenswert?

Wastl schrieb:
> Ist das kein Thema mehr weil du das - ohne dich zu äussern -
> bereits abgehandelt und für dich als nicht relevant betrachtet
> hast? Oder hast du keine Lust dich mit potentiellen Problemen
> bei der Hardware auseinanderzusetzen?

Ich habe etwas herumprobiert und nochmal geschaut was sein könnte. Es 
hat sich heruasgestellt, dass ich an dem RJ45 Verbinder mit integrierten 
Transformatoren den Shield nicht verbunden habe und den Center Tap mit 
einem Widerstand gegen 3.3V verbunden habe. Beides geändert und die Link 
Negotiation funktioniert. Leider kann ich aber noch keinen Ping zum 
Controller sende (ICMP ist aktiviert), da keine Pakete empfangen werden 
aber die Link up routine wird aufgerufen.

von Wastl (hartundweichware)


Lesenswert?

Gustav G. schrieb:
> Ich habe etwas herumprobiert .......

Das geht leider an meiner Fragestellung bzw. Problem-Vermutung
total vorbei.

von Gustav G. (gustavgggg)


Lesenswert?

Wastl schrieb:
> Das geht leider an meiner Fragestellung bzw. Problem-Vermutung
> total vorbei.

Das Problem mit der Link Negotiation war ein Hardwarefehler, der nun 
behoben wurde. Nun habe ich ein anderes Problem nämlich keine 
empfangenen Pakete.

von Wastl (hartundweichware)


Lesenswert?

Gustav G. schrieb:
> Nun habe ich ein anderes Problem nämlich keine
> empfangenen Pakete.

Wastl schrieb:
> Der alternativ gespeiste
> bzw. konfigurierte Pin heisst ETH_RMII_REF_CLK.

Wird dieser Eingang nun versorgt oder spielt das keine Rolle?
Habe ich in diesem Beitrag mein vermutetes Problem nicht
klar genug dargestellt?

von Gustav G. (gustavgggg)


Lesenswert?

Wastl schrieb:
> Wird dieser Eingang nun versorgt oder spielt das keine Rolle?
> Habe ich in diesem Beitrag mein vermutetes Problem nicht
> klar genug dargestellt?

Ja das habe ich eben gemessen dort liegen 50MHz an.

von J. S. (jojos)


Lesenswert?

in ethernetif.c in ethernet_link_check_state() wird der LinkState 
ausgewertet. Breakpoint setzen und gucken welche Linkspeed vom Phy 
gemeldet wird.

von Gustav G. (gustavgggg)


Lesenswert?

J. S. schrieb:
> Breakpoint setzen und gucken welche Linkspeed vom Phy
> gemeldet wird.

Habe ich gerade gemacht. Es wird Fullduplex und 100M Link speed 
ausgehandelt.

von J. S. (jojos)


Lesenswert?

IP Adresse ist fix oder per DHCP? Man kann in lwip eine Menge 
Debugausgaben aktivieren, geht auch über die CubeMX Konfiguration.
Diese kommen dann über stdout raus, d.h. man braucht eine Routine die 
printf() möglich macht. Also z.B. einen UART aktivieren und _write() 
definieren
1
int _write(int file, char *ptr, int len)
2
{
3
  HAL_UART_Transmit(&huart3, (uint8_t*) ptr, len, 10000);
4
        return len;
5
}

von Wastl (hartundweichware)


Lesenswert?

Gustav G. schrieb:
> Nun habe ich ein anderes Problem nämlich keine
> empfangenen Pakete.

Wie stellst du das fest (wie schaust du nach)?
Wo sollen Pakete herkommen?

Welche Art von Paketen erwartest du (Protokoll)? Und hast du
dafür korrekte IP Adressen konfiguriert? Muss ja auch in dein
Netz passen ....

: Bearbeitet durch User
von Gustav G. (gustavgggg)


Lesenswert?

Wastl schrieb:
> Wie stellst du das fest (wie schaust du nach)?

Im Debugger das Register anzeigen lassen und schauen ob die 
entpsrechenden Bits gesetzt sind (Das sind sie).

Wastl schrieb:
> Wo sollen Pakete herkommen?

Von meinem PC, der direkt mit dem Board verbunden ist.

Wastl schrieb:
> Welche Art von Paketen erwartest du (Protokoll)?

ICMP

Wastl schrieb:
> Und hast du
> dafür korrekte IP Adressen konfiguriert?

IP Adresse für Lwip ist statisch und auf dem Rechner auch.

von Wastl (hartundweichware)


Lesenswert?

Gustav G. schrieb:
> ICMP

ICMP stammt ja vermutlich vom Ping, und diese Pakete werden
ja vom LWIP intern verarbeitet, treten also gar nicht auf
User-Level in Erscheinung.

Um Pakete zu "sehen" wirst du wohl ein UDP oder TCP Protokoll
verwenden müssen.

von Gustav G. (gustavgggg)


Lesenswert?

Wastl schrieb:
> ICMP stammt ja vermutlich vom Ping, und diese Pakete werden
> ja vom LWIP intern verarbeitet, treten also gar nicht auf
> User-Level in Erscheinung.

Ich sollte aber auf einem Ping eine Antort erhalten und wenn ich mir in 
Wireshark anschaue was alles gesendet wird kommt nichts zurück. Allein 
schon die ARP Anfrage liefert keine Antwort, obwohl ARP aktiviert ist.

Auf low level ebene also in low_level_input() sollte ich sehr wohl alle 
einkommenden Pakete sehen

von J. S. (jojos)


Lesenswert?

Gustav G. schrieb:
> Auf low level ebene also in low_level_input() sollte ich sehr wohl alle
> einkommenden Pakete sehen

richtig, da muss was ankommen.

Problem mit Rx Leitungen am Phy? Rx Paar auch richtig im CubeMX 
ausgewählt? Steht im EthernetIf.c in HAL_ETH_MspInit() im Kommentar was 
verwendet wird.

: Bearbeitet durch User
von Gustav G. (gustavgggg)


Lesenswert?

J. S. schrieb:
> Problem mit Rx Leitungen am Phy? Rx Paar auch richtig im CubeMX
> ausgewählt? Steht im EthernetIf.c in HAL_ETH_MspInit() im Kommentar was
> verwendet wird.

Habe ich auch schon geprüft. Im MspInit steht

    PC1     ------> ETH_MDC
    PA1     ------> ETH_REF_CLK
    PA2     ------> ETH_MDIO
    PA7     ------> ETH_CRS_DV
    PC4     ------> ETH_RXD0
    PC5     ------> ETH_RXD1
    PB11     ------> ETH_TX_EN
    PB12     ------> ETH_TXD0
    PB13     ------> ETH_TXD1

und die sind auch so verbunden.

von Gustav G. (gustavgggg)


Lesenswert?

Ich habe noch etwas mit dem Debugger herumgespielt um überhaupt mal ARP 
Request zu sehen. Es scheint, dass die Funktion 
HAL_ETH_GetReceivedFrame() niemals in einer der if Bedingungen springt 
und immer HAL_ERROR zurückgibt. Es wird also tatsächlich nichts 
empfangen.

Es wundert mich an der Stelle, ob das ein generelles Problem ist, wo 
doch Link negotiation nun funktioniert. Muss bei der Link Negotiation 
auch etwas an Daten übertragen werden?

von J. S. (jojos)


Lesenswert?

was beim Link aushandeln genau passiert weiß ich auch nicht. Ist denn 
der gesendete ARP Request im Wireshark zu sehen? Wenn ja, sollte der Phy 
Clock ok sein.
Und es müsste am RXD0/1 liegen. Sind die PC4/5 vielleicht woanders in 
der Software wieder als GPIO definiert?
Software zeigen?

: Bearbeitet durch User
von Gustav G. (gustavgggg)


Lesenswert?

J. S. schrieb:
> Und es müsste am RXD0/1 liegen. Sind die PC4/5 vielleicht woanders in
> der Software wieder als GPIO definiert?

Habe ich schon geschaut PC 4 und PC 5 wird nirgendwo verwendet außer für 
ethernet. Welchen Teil des codes interessiert sich. Das ist bisher 
überwiegend generierter Code der STM32 IDE.

von J. S. (jojos)


Lesenswert?

ich habe auch mal ein Projekt mit F107 generiert, der ist ja um einiges 
einfacher als ein F4 oder gar H7. Es gibt nur einen Speicherbereich und 
keinen Cache, alles Dinge die den Start ganz schön schwer machen können. 
Wenn etwas mit den Speicherbereichen für die Deskriptoren oder lwipHeap 
nicht stimmt, dann sollte es Hard- oder Memoryfault geben (mit dem 
Debugger kontrolliert das er da nicht landet?).
Von daher würde ich immer noch auf die HW tippen. Ansonsten ist der 
relevante Teil ja im LWIP Verzeichniss des Projektes (5 Dateien), den 
könntest du zeigen. MX_LWIP_Process wird im generierten Code nicht in 
der main loop eingetragen, das muss man selber machen und hast du ja 
auch gemacht.

von Gustav G. (gustavgggg)


Lesenswert?

Nur mal ein kurzes Update. Es war am Ende kein Softwareproblem, sondern 
diverse Lötbrücken, die schwer zu erkennen waren und ein nicht 
geroutetes CRS_DV Signal. Nachdem ich das provisorisch behoben habe 
funktioniert nun der PHY und die Kommunikation seht gut und ich kann das 
Gerät mit ICMP anpingen.

Der benutze PHY funktioniert übrigens mit den Standardeinstellungen aus 
der Cube IDE.

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.