Sto cercando di visualizzare un PCB che utilizza un PHY Ethernet STM32F407 e LAN8720A e non riesco a ricevere alcun frame Ethernet, anche se non ho problemi a trasmettere i frame.
Configurazione dell'hardware
Ho un cristallo a 25 MHz su STM32F4, che guida un pin di uscita di clock a 25 MHz su LAN8720A, che è in modalità REF_CLK_OUT - e riporta un clock di 50 MHz su STM32F4 come parte dell'interfaccia RMII.
Il jack / magnetici sono una parte generica. Ecco la scheda tecnica:
Software
Sto utilizzando l'ultimo aggiornamento STM32CubeMX per generare un progetto System Workbench per STM32 che contiene FreeRTOS, lwIP e i driver di periferica ETH. Non ho davvero toccato nessuno dei codici generati, quindi lo stack lwIP viene inizializzato all'interno di uno stack FreeRTOS.
esperimenti
Con l'IPIP della mia scheda configurato per un IP statico 10.0.0.2 e una chiave hardware da USB a Ethernet sul mio computer configurata per un IP statico 10.0.0.1, collego i due dispositivi direttamente con un cavo Ethernet e la mia scheda tenta di connettersi a un servizio sulla porta 80 del computer. Catturo l'interazione tra la mia scheda e il computer utilizzando Wireshark (in esecuzione sul computer e associato al convertitore da USB a Ethernet).
A causa del problema dei frame non ricevuti, non superiamo mai questa roba ARP: come puoi vedere, la Stmicroe (la mia scheda) può inviare pacchetti ARP - ascoltati dal mio computer - ma non sembra mai sentire la risposta dal mio computer , poiché continua a mandare fuori pacchetti ARP.
Entrambi i dispositivi sono configurati con una maschera 255.255.255.0 ed entrambi sono configurati con un indirizzo gateway 10.0.0.1 (il computer). Ho sentito parlare delle tabelle ARP che vengono rovinate e dei computer che ignorano i pacchetti ARP, ma non riesco a immaginare che la scheda ignorerebbe i pacchetti ARP specificamente indirizzati dal mio computer, in risposta alle richieste che la scheda ha fatto in primo luogo.
Quindi, mi tuffo nel file ethernetif.c di lwIP e noto che HAL_ETH_GetReceivedFrame_IT(&heth)
sta restituendo un errore. Quella funzione restituisce un errore perché (heth->RxDesc->Status & ETH_DMARXDESC_OWN)
== 0, invece di 1. Lo interpreto nel senso che i buffer DMA sono attualmente armati per la periferica MAC e non hanno ancora ricevuto nulla.
Inoltre, ho verificato che HAL_ETH_IRQHandler non viene mai chiamato.
Un problema con il PHY?
A questo punto, sospettavo che la colpa fosse del mio PHY stesso.
Per indagare ulteriormente, ho collegato la mia Saleae Logic Pro 16 a tutti i segnali pertinenti e ho notato che c'è molto traffico su entrambe le linee TX0 / TX1 e RX0 / RX1. Ecco un'acquisizione di un po 'di traffico RX con l'orologio di ingresso a 25 MHz:
RX_ERR è basso per tutto il tempo, a meno che non tenti di catturare l'uscita di clock a 50 MHz (il che è ovviamente impegnativo con un dispositivo come il Saleae): in tal caso, RX_ERR viene picchiato in modo ocassionale per alcuni pacchetti (che in realtà è un buon segno - il perno sembra funzionare).
Prossimi passi
Ho provato ad abilitare manualmente gli interrupt ETH chiamando HAL_NVIC_EnableIRQ(ETH_IRQn);
dopo aver tcpip_init()
chiamato nell'attività MX_LWIP_Init()
e questo non sembra risolvere il problema. Non sono del tutto sicuro che la routine di interruzione Ethernet debba nemmeno essere chiamata - questa è la cosa difficile con la creazione di un nuovo design; Sto lottando per determinare quale sarebbe il comportamento corretto del sistema, quindi posso quindi determinare in che modo differisce la mia configurazione.
Mentre ho usato le cose STM32 / STM32CubeMX / FreeRTOS prima, non ho mai usato la periferica Ethernet dell'STM32 e la mia unica esperienza con questa roba è su sistemi Linux integrati personalizzati, che sembravano sempre funzionare immediatamente. Questo è un nuovo territorio per me!
Sono sicuro che c'è una casella di controllo stupida da qualche parte o una Ethernet_EnableReceive()
funzione magica che dimentico di chiamare, ma non riesco davvero a trovare alcuna documentazione che suggerisca la necessità di abilitare esplicitamente quella roba, e i post che vedo su Internet sono tutti dovuti a non correlati problemi.
Se qualcuno ha qualche idea, mi piacerebbe un po 'di aiuto!
Addendum: sbarazzarsi di FreeRTOS
Solo per eliminare le cose, ho rimosso il componente del progetto FreeRTOS, tornando a un progetto bare metal. Nel mio ciclo principale, chiamo MX_LWIP_Process()
. Questo metodo dovrebbe eliminare la necessità di interruzioni, ma non risolve il problema; Non riesco ancora a ricevere i frame. Questo mi fa pensare che ci sia qualcosa nel codice ETH HAL generato da STM32CubeMX.
Soluzione
Nel caso in cui qualcuno si imbattesse in questa domanda in futuro, il problema si è rivelato essere capovolto pin RXD0 e RXD1. Questo è il motivo per cui sono stato in grado di vedere il traffico sul mio analizzatore logico, ma non è stato decodificato dal mio MCU.
Come qualcuno ha sottolineato, i magnetici che ho usato sono asimmetrici e non dovrebbero essere usati per l'auto-MDI-X. Non ho avuto problemi. Prevedo che sta accadendo una di queste due cose: - i magnetici in realtà non funzionano nell'altro orientamento, ma poiché tutto ciò che ho utilizza auto-MDI-X, la mia scheda rimane sostanzialmente fissa nella configurazione che funziona, mentre l'altro dispositivo è acceso il cavo orienta i suoi segnali in modo che corrispondano. - i magnetici forniscono un'adeguata integrità del segnale date le brevi corse Ethernet, ma un'analisi a lungo termine mostrerebbe tassi più alti di caduta dei pacchetti o problemi su lunghe tirature.
Onestamente, non mi è chiaro perché sia importante su quale lato del trasformatore 1: 1 sono installati i filtri di linea, quindi al di fuori delle applicazioni PoE, non sono sicuro del motivo per cui un design simmetrico vs asimmetrico sarebbe importante.