Bring up a PCB that uses an STM32F407 and LAN8720A Ethernet PHY
STM32F407LAN8720A
Hardware setup
~~![](<URL url=)https://i.stack.imgur.com/cQUW3.png
I have a 25 MHz crystal on the STM32F4, driving a 25 MHz clock output pin into the LAN8720A, which is in REFCLKOUT mode — and drives a 50 MHz clock back to the STM32F4 as part of the RMII interface.
The jack/magnetics are a generic part. Here's the datasheet:
~~![](<URL url=)https://i.stack.imgur.com/tWDWT.png
Software
I'm using the latest-update STM32CubeMX to generate a System Workbench for STM32 project that contains FreeRTOS, lwIP, plus the ETH peripheral drivers. I haven't really touched any of the generated code — so the lwIP stack gets initialized inside a FreeRTOS stack.
Experiments
With my board's lwIP configured for a 10.0.0.2 static IP, and a USB-to-ethernet dongle on my computer configured for a 10.0.0.1 static IP, I connect the two devices directly with an Ethernet cable, and my board attempts to connect to a service on port 80 of the computer. I capture the interaction between my board and the computer using Wireshark (running on the computer, and bound to the USB-to-Ethernet converter).
Because of the no-received-frames problem, we never get past this ARP stuff:
~~![](<URL url=)https://i.stack.imgur.com/TENLQ.png
As you can see, the Stmicroe (my board) can send ARP packets — heard by my computer — but it never seems to hear the response from my computer, as it keeps blasting out ARP packets.
Both devices are configured with a 255.255.255.0 mask, and both are configured with a gateway address of 10.0.0.1 (the computer). I've heard of ARP tables getting screwed up and computers ignoring ARP packets, but I can't imagine the board would ignore ARP packets specifically addressed to it by my computer — in response to the requests the board made in the first place.
So, I dive into lwIP's ethernetif.c file and notice that HALETHGetReceivedFrameIT(&heth) is returning an error. That function returns an error because (heth->RxDesc->Status & ETHDMARXDESC_OWN) == 0, instead of 1. I interpret that to mean that the DMA buffers are currently armed for the MAC peripheral, and haven't received anything yet.
Furthermore, I've verified that the HALETHIRQHandler never gets called.
A problem with the PHY?
At this point, I suspected my PHY itself was to blame.
To investigate further, I attached my Saleae Logic Pro 16 to all the relevant signals, and noticed there's plenty of traffic on both the TX0/TX1, as well as the RX0/RX1 lines. Here's a capture of some RX traffic with the 25 MHz input clock:
~~![](<URL url=)https://i.stack.imgur.com/Jb0vQ.png
RXERR is low the entire time, unless I attempt to capture the 50 MHz clock output (which is obviously challenging with a device like the Saleae): in that case, RXERR is ocassionally blipped high for a few packets (which is actually a good sign — the pin appears to be functioning).
Next steps
I've tried manually enabling ETH interrupts by calling HALNVICEnableIRQ(ETHIRQn); after tcpipinit() is called in the MXLWIPInit() task, and that doesn't seem to fix the problem. I'm not entirely sure the Ethernet interrupt routine is even supposed to be getting called — that's the challenging thing with bringing up a brand new design; I'm struggling to determine what the proper behavior of the system would be, so I can then determine how my setup differs.
While I've used the STM32/STM32CubeMX/FreeRTOS stuff before, I've never used the STM32's Ethernet peripheral, and my only experience with this stuff is on custom embedded Linux systems, which always seemed to just work out of the box. This is new territory for me!
I'm sure there's a stupid checkbox somewhere or magical Ethernet_EnableReceive() function I forget to call, but I can't really find any documentation that suggests needing to explicitly enable that stuff, and the posts I'm seeing on the internet are all due to unrelated issues.
If anyone has any ideas, I'd love some help!
Addendum: Getting rid of FreeRTOS
Just to eliminate stuff, I've removed the FreeRTOS project component, going back to a bare-metal project. In my main loop, I call MXLWIPProcess(). This method should eliminate the need for interrupts, but it doesn't fix the problem; I'm still unable to receive frames. This makes me think there's something in the ETH HAL code generated by STM32CubeMX.~~~~
2 Replies
Custom Logo DesignLogo Design Services Dubai
RMII clock, PHY, HAL, interrupts, pin mapping: Check these for Ethernet issue.
thanks and regards
revida marcos
https://www.multispanindia.com