Estoy tratando de mostrar una PCB que usa un STM32F407 y LAN8720A Ethernet PHY, y parece que no puedo recibir ninguna trama de Ethernet, aunque no tengo problemas para transmitirlas.
Configuración de hardware
Tengo un cristal de 25 MHz en el STM32F4, impulsando un pin de salida de reloj de 25 MHz en el LAN8720A, que está en modo REF_CLK_OUT, y conduce un reloj de 50 MHz de regreso al STM32F4 como parte de la interfaz RMII.
El jack / magnetics son una parte genérica. Aquí está la hoja de datos:
Software
Estoy usando la última actualización de STM32CubeMX para generar un System Workbench para el proyecto STM32 que contiene FreeRTOS, lwIP, más los controladores periféricos ETH. Realmente no he tocado ninguno de los códigos generados, por lo que la pila lwIP se inicializa dentro de una pila FreeRTOS.
Los experimentos
Con el lwIP de mi placa configurado para una IP estática 10.0.0.2 y un dongle de USB a ethernet en mi computadora configurado para una IP estática 10.0.0.1, conecto los dos dispositivos directamente con un cable Ethernet, y mi placa intenta conectarse a un servicio en el puerto 80 de la computadora. Capturo la interacción entre mi placa y la computadora usando Wireshark (que se ejecuta en la computadora y enlazada al convertidor de USB a Ethernet).
Debido al problema de que no hay marcos recibidos, nunca superamos estas cosas ARP: Como puede ver, Stmicroe (mi placa) puede enviar paquetes ARP, escuchados por mi computadora, pero nunca parece escuchar la respuesta de mi computadora , ya que sigue lanzando paquetes ARP.
Ambos dispositivos están configurados con una máscara 255.255.255.0, y ambos están configurados con una dirección de puerta de enlace de 10.0.0.1 (la computadora). Escuché que las tablas ARP se arruinaron y que las computadoras ignoraron los paquetes ARP, pero no puedo imaginar que la placa ignore los paquetes ARP específicamente dirigidos a ella por mi computadora, en respuesta a las solicitudes que la placa hizo en primer lugar.
Entonces, me sumerjo en el archivo ethernetif.c de lwIP y noto que HAL_ETH_GetReceivedFrame_IT(&heth)
está devolviendo un error. Esa función devuelve un error porque (heth->RxDesc->Status & ETH_DMARXDESC_OWN)
== 0, en lugar de 1. Interpreto que significa que los búferes de DMA están actualmente armados para el periférico MAC y aún no han recibido nada.
Además, he verificado que nunca se llama al HAL_ETH_IRQHandler.
¿Un problema con el PHY?
En este punto, sospechaba que mi PHY tenía la culpa.
Para investigar más, conecté mi Saleae Logic Pro 16 a todas las señales relevantes y noté que hay mucho tráfico tanto en las líneas TX0 / TX1 como en las líneas RX0 / RX1. Aquí hay una captura de algo de tráfico RX con el reloj de entrada de 25 MHz:
RX_ERR está bajo todo el tiempo, a menos que intente capturar la salida de reloj de 50 MHz (lo que obviamente es un desafío con un dispositivo como el Saleae): en ese caso, RX_ERR se borra ocasionalmente para algunos paquetes (lo que en realidad es una buena señal - el pin parece estar funcionando).
Próximos pasos
He intentado habilitar manualmente las interrupciones ETH llamando HAL_NVIC_EnableIRQ(ETH_IRQn);
después de que tcpip_init()
se llama en la MX_LWIP_Init()
tarea, y eso no parece solucionar el problema. No estoy completamente seguro de que se suponga que se llame a la rutina de interrupción de Ethernet ; eso es lo desafiante con la presentación de un nuevo diseño; Estoy luchando por determinar cuál sería el comportamiento adecuado del sistema, por lo que puedo determinar cómo difiere mi configuración.
Si bien he usado las cosas STM32 / STM32CubeMX / FreeRTOS antes, nunca he usado el periférico Ethernet de STM32, y mi única experiencia con estas cosas es en sistemas Linux embebidos personalizados, que siempre parecían funcionar de manera inmediata. ¡Este es un territorio nuevo para mí!
Estoy seguro de que hay una estúpida casilla de verificación en alguna parte o una Ethernet_EnableReceive()
función mágica a la que me olvido de llamar, pero realmente no puedo encontrar ninguna documentación que sugiera la necesidad de habilitar explícitamente esas cosas, y las publicaciones que estoy viendo en Internet se deben a que no están relacionadas cuestiones.
Si alguien tiene alguna idea, ¡me encantaría recibir ayuda!
Anexo: Deshacerse de FreeRTOS
Solo para eliminar cosas, eliminé el componente del proyecto FreeRTOS, volviendo a un proyecto básico. En mi bucle principal, llamo MX_LWIP_Process()
. Este método debería eliminar la necesidad de interrupciones, pero no soluciona el problema; Todavía no puedo recibir marcos. Esto me hace pensar que hay algo en el código ETH HAL generado por STM32CubeMX.
Solución
En caso de que alguien se tope con esta pregunta en el futuro, el problema resultó ser voltear los pines RXD0 y RXD1. Es por eso que pude ver el tráfico en mi analizador lógico, pero mi MCU no lo decodificó.
Como alguien señaló, los imanes que utilicé son asimétricos y no deben usarse para auto-MDI-X. No he tenido ningún problema. Anticipo que está sucediendo una de dos cosas: - los imanes no funcionan realmente en la otra orientación, pero debido a que todo lo que tengo usa auto-MDI-X, mi placa esencialmente permanece fija en la configuración que funciona, mientras que el otro dispositivo está encendido el cable orienta sus señales para que coincidan. - el magnetismo proporciona una integridad de señal adecuada debido a las cortas ejecuciones de Ethernet, pero un análisis a largo plazo mostraría tasas más altas de caída de paquetes o problemas durante las ejecuciones más largas.
Honestamente, no está claro para mí por qué importaría en qué lado del transformador 1: 1 están instalados los filtros de línea, por lo que, fuera de las aplicaciones PoE, no estoy seguro de por qué sería importante un diseño simétrico frente a asimétrico.