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?
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.
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.
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.
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
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")
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.
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
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
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.
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
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?
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.
Gustav G. schrieb: > Ich habe etwas herumprobiert ....... Das geht leider an meiner Fragestellung bzw. Problem-Vermutung total vorbei.
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.
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?
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.
in ethernetif.c in ethernet_link_check_state() wird der LinkState ausgewertet. Breakpoint setzen und gucken welche Linkspeed vom Phy gemeldet wird.
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.
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 | }
|
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
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.
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.
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
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
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.
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?
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
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.