Estou tentando abrir uma placa de circuito impresso que usa um PHY Ethernet STM32F407 e LAN8720A e não consigo receber nenhum quadro Ethernet - mesmo que eu não tenha problemas para transmitir quadros.
Configuração de hardware
Eu tenho um cristal de 25 MHz no STM32F4, direcionando um pino de saída de clock de 25 MHz para o LAN8720A, que está no modo REF_CLK_OUT - e direciona um relógio de 50 MHz de volta para o STM32F4 como parte da interface RMII.
O jack / magnetismo é uma parte genérica. Aqui está a folha de dados:
Programas
Estou usando a atualização mais recente do STM32CubeMX para gerar um projeto do System Workbench for STM32 que contém FreeRTOS, lwIP e os drivers periféricos ETH. Eu realmente não toquei nenhum código gerado - portanto, a pilha lwIP é inicializada dentro de uma pilha do FreeRTOS.
Experiências
Com o lwIP da minha placa configurado para um IP estático 10.0.0.2 e um dongle USB-ethernet no meu computador configurado para um IP estático 10.0.0.1, conecto os dois dispositivos diretamente com um cabo Ethernet, e minha placa tenta se conectar para um serviço na porta 80 do computador. Capto a interação entre minha placa e o computador usando o Wireshark (em execução no computador e vinculado ao conversor USB-Ethernet).
Devido ao problema de quadros não recebidos, nunca superamos esse material ARP: Como você pode ver, o Stmicroe (minha placa) pode enviar pacotes ARP - ouvidos pelo meu computador - mas nunca parece ouvir a resposta do meu computador , uma vez que continua lançando pacotes ARP.
Ambos os dispositivos são configurados com uma máscara 255.255.255.0 e os dois são configurados com um endereço de gateway 10.0.0.1 (o computador). Ouvi falar de tabelas ARP sendo estragadas e computadores ignorando pacotes ARP, mas não consigo imaginar que a placa ignore pacotes ARP especificamente endereçados a ela pelo meu computador - em resposta às solicitações feitas pela placa em primeiro lugar.
Então, eu mergulho no arquivo ethernetif.c do lwIP e percebo que HAL_ETH_GetReceivedFrame_IT(&heth)
está retornando um erro. Essa função retorna um erro porque (heth->RxDesc->Status & ETH_DMARXDESC_OWN)
== 0, em vez de 1. Eu interpreto isso como significando que os buffers DMA estão atualmente armados para o periférico MAC e ainda não receberam nada.
Além disso, verifiquei que o HAL_ETH_IRQHandler nunca é chamado.
Um problema com o PHY?
Nesse ponto, eu suspeitava que meu próprio PHY fosse o culpado.
Para investigar mais, anexei meu Saleae Logic Pro 16 a todos os sinais relevantes e notei que há muito tráfego nas linhas TX0 / TX1 e RX0 / RX1. Aqui está uma captura de algum tráfego RX com o relógio de entrada de 25 MHz:
O RX_ERR fica baixo o tempo todo, a menos que eu tente capturar a saída do clock de 50 MHz (o que é obviamente um desafio para um dispositivo como o Saleae): nesse caso, o RX_ERR é ocasionalmente alto para alguns pacotes (o que é realmente um bom sinal - o alfinete parece estar funcionando).
Próximos passos
Tentei ativar manualmente as interrupções do ETH chamando HAL_NVIC_EnableIRQ(ETH_IRQn);
depois de tcpip_init()
ser chamado na MX_LWIP_Init()
tarefa e isso não parece resolver o problema. Não tenho certeza absoluta de que a rotina de interrupção da Ethernet esteja sendo chamada - essa é a coisa desafiadora de criar um novo design; Estou lutando para determinar qual seria o comportamento adequado do sistema, para que eu possa determinar como minha configuração difere.
Embora eu tenha usado o material STM32 / STM32CubeMX / FreeRTOS antes, nunca usei o periférico Ethernet do STM32, e minha única experiência com esse material é em sistemas Linux embarcados personalizados, que sempre pareciam funcionar imediatamente. Este é um novo território para mim!
Tenho certeza de que há uma caixa de seleção estúpida em algum lugar ou Ethernet_EnableReceive()
função mágica que eu esqueço de chamar, mas não consigo encontrar nenhuma documentação que sugira a necessidade de ativar explicitamente essas coisas, e as postagens que estou vendo na internet são todas não relacionadas problemas.
Se alguém tiver alguma idéia, eu adoraria alguma ajuda!
Adendo: Como se livrar do FreeRTOS
Apenas para eliminar coisas, removi o componente do projeto FreeRTOS, voltando a um projeto bare-metal. No meu loop principal, eu ligo MX_LWIP_Process()
. Este método deve eliminar a necessidade de interrupções, mas não resolve o problema; Ainda não consigo receber quadros. Isso me faz pensar que há algo no código ETH HAL gerado pelo STM32CubeMX.
Solução
Caso alguém se depare com essa questão no futuro, o problema acabou sendo os pinos RXD0 e RXD1. Foi por isso que consegui ver o tráfego no meu analisador lógico, mas não foi decodificado pelo meu MCU.
Como alguém apontou, os magnéticos que usei são assimétricos e não devem ser usados para o auto-MDI-X. Eu não tive nenhum problema. Eu prevejo que uma das duas coisas está acontecendo: - as magnéticas não funcionam na outra orientação, mas como tudo o que tenho usa o MDI-X automático, minha placa permanece essencialmente fixa na configuração que funciona, enquanto o outro dispositivo está ligado. o cabo orienta seus sinais para que correspondam. - o magnetismo fornece integridade de sinal adequada, dadas as pequenas execuções Ethernet, mas uma análise a longo prazo mostra taxas mais altas de queda de pacotes ou problemas em execuções mais longas.
Honestamente, não está claro para mim por que isso importaria para qual lado do transformador 1: 1 os filtros de linha estão instalados; portanto, fora dos aplicativos PoE, não sei ao certo por que um projeto simétrico versus assimétrico importaria.