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.
Respostas:
Você tem o wireshark instalado no PC e, como diz, usa o adaptador USB-para-LAN. Não sei em que ponto físico o Wireshark captura pacotes em sua instalação e, portanto, é uma boa pergunta se os pacotes de saída realmente aparecem na rede física . Eu recomendo que você conecte outro PC à interface de rede e verifique se esses computadores podem se comunicar comparando a saída do Wiresharks neles.
Sua saída do wireshark não mostra nenhum problema, o PC anuncia três vezes que está na rede local e possui o endereço IP 10.0.0.1 (se receber resposta a qualquer uma dessas 3 solicitações de ARP, o sistema operacional aparecerá com conflito de endereço IP).
Então, sua diretoria pergunta constantemente Quem tem 10.0.0.1? Diga 10.0.0.2 e PC respostas com 10.0.0.1 está em ... . A questão é por que isso acontece em loop:
Portanto, como próxima etapa de solução de problemas, pegue outro PC com interface Ethernet "normal", instale o Wireshark nele, configure sua rede da mesma maneira que você fez para a placa e tente
telnet 10.0.0.1 80
ver se ele aparece no Wiresharks nas duas máquinas. Dessa forma, você garantiria que o PC com seu adaptador USB-Ethernet funcione corretamente.Seus próximos passos dependerão do que você vê nesses Wiresharks.
Atualizar:
Incorreto. Você quer pensar que sua placa recebe pacotes. Você vê que há alguma alteração no nível dos sinais de entrada PHY, mas eles não representam necessariamente pacotes válidos. O fato de RX_ERR não alternar imediatamente não me convence de que PHY está funcionando corretamente nos eventos recebidos, ou que as informações que chegam formam pacotes adequados.
De qualquer forma, depende de você, minha teoria da solução de problemas é simples - você deve garantir em um nível superior onde encontra o problema e depois pesquisar na parte respectiva do design. Cavar em todas as partes e suspeitar de tudo é inútil. Seria uma grande sorte se você encontrar um problema em espalhar o foco; você já está tentando simplificar o software; se não der certo, provavelmente começará a substituir os chips.
Não acho que minha etapa de solução de problemas seja tão complicada para garantir que outro PC possa se comunicar com o dongle e me provar que estou certo ou errado e, assim, garanto que você está certo em cavar profundas suspeitas de PHY, MAC e software da placa trabalhando em eles.
fonte
Desculpe ressuscitar este tópico. Eu não poderia passar sem mencionar minha experiência.
Eu usei este HR911105A (RJ45 com ímã) em um dos meus projetos.
HR911105A: De relance, uma coisa chamou minha atenção: a conexão entre o LAN8720 e o RJ45, conforme o seu esquema.
Desde que eu vejo que a conexão parece crossover. Embora os sistemas conectados usem principalmente o MDI-X e, portanto, detectem pares de recebimento / transmissão, seria bom fornecer uma conexão menos confusa assim:
Pin #4 and Pin #5
(portanto, os resistores pull-up 49.9R) seriam bons se conectados3V3_AN
no seu esquema, enquanto o outro lado deveria ser acoplado ao GND por meio de um capacitor (0,1uF ou 0,022uF).fonte