I need to power down the Ethernet PHY on my Embedded Artists' LPC4088QSB (QuickStart Board), in order to reduce the current draw. I've got some code which seems to do it, and reduces the current draw by (very) roughly 40 mA. But executing this code breaks debugging in a very strange way.
I'm using Mbed OS 5.7.5 in MCUXpresso. I describe further below how to check out and setup the project. But first I detail the issue.
Here is my test code where I demonstrate the issue:
GitHub - bmcdonnell-ionx/eth-dbg-issue
Is this the right way to power down the PHY? Why is it breaking debugging, and how can I fix it? Details follow.
The problem goes like this:
I tried debugging with the on-board debugger, and with a separate LPC-Link2; results were the same.
The issue presents itself in all three of the commits in the repository now. (If you use the most recent, you may need to change the place to "Stop on startup" in Run -> Debug Configurations... -> Debugger tab.)
Prerequisites:
At the command prompt:
mbed import https://github.com/bmcdonnell-ionx/eth-dbg-issue.git
cd eth-dbg-issue
mbed export -m LPC4088 -i mcuxpresso
Alternatively,
git clone https://github.com/bmcdonnell-ionx/eth-dbg-issue.git
cd eth-dbg-issue
mbed deploy
mbed export -m LPC4088 -i mcuxpresso
Then in MCUXpresso, import the project from the filesystem.
Solved! Go to Solution.
Jeremy,
Thanks for the info. That should work.
There are couple posts in this thread with parts of the answer to my situation. Marking just one of them as the answer could potentially mislead future readers, so I "liked" and marked them as "helpful".
Hi Brendan McDonnell,
Good news, I've figured out the way of resetting the PHY which enable the PHY to be reinitialized with any hardware modifications.
It's very simple, just calling the Reset_PHY(); prior to executing the NVIC_SystemReset();.
/* LAN8720 BCR register definitions */
#define LAN8_RESET (1 << 15) /*!< 1= S/W Reset */
void Reset_PHY(void)
{
lpc_mii_write(LAN8_BCR_REG, LAN8_RESET);
}
I test it with LPC4088 OEM board, and it works.
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
jeremyzhou wrote:
...the way of resetting the PHY which enable the PHY to be reinitialized with any hardware modifications.
It's very simple, just calling the Reset_PHY(); prior to executing the NVIC_SystemReset();./* LAN8720 BCR register definitions */ #define LAN8_RESET (1 << 15) /*!< 1= S/W Reset */ void Reset_PHY(void) { lpc_mii_write(LAN8_BCR_REG, LAN8_RESET); }
That did work, thanks.
Is there also a way to safely initialize after a reset, without having done this "safe shutdown" sequence? That is,
Obviously MYSTERY_COMMAND() would go before Chip_ENET_Init()
Hi McDonnell,
It's available to detect the reset source by checking the RSID register(Reset Source Identification register), so you can skip the "safe shutdown" sequence to execute the MYSTERY_COMMAND(); when a software reset is identified.
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Jeremy,
Thanks for the info. That should work.
There are couple posts in this thread with parts of the answer to my situation. Marking just one of them as the answer could potentially mislead future readers, so I "liked" and marked them as "helpful".
I assume your problem is the missing 50mhz reference clock. It gets disabled when you power down the PHY. This is still the case after a NVIC sysreset of the CPU.
Without the 50mhz clock an access to any one register in the Ethernet MAC 'Control registers' or 'RX filter registers' group blocks/crashes the CPU!
The first for loop in ethernet_init() follows an access to LPC_EMAC->Command which is in the 'Control registers' group. That is where the system crashes.
Solution: Begin your initialization with sending an instruction to the PHY to take it out of power down and switch the 50mhz back on. For that you need: 1) MDIO/MDC pins 2) ENET peripheral clock on 3) Ethernet MAC not in reset (MAC1=0) 4) MIIM clock divider configured 5) phy_write(...) to enable the PHY. If the 50mhz is up, you can do the normal initialization sequence.
Bottom line: Access to the PHY through MIIM is always possible. Avoid the critical registers in the Ethernet block before the 50mhz are stable at the ENET_REFCLK pin.
Gerhard Knorr wrote:
...Solution: Begin your initialization with sending an instruction to the PHY to take it out of power down and switch the 50mhz back on....
Bottom line: Access to the PHY through MIIM is always possible. Avoid the critical registers in the Ethernet block before the 50mhz are stable at the ENET_REFCLK pin.
Is the instruction you're referring to the Reset_PHY() function that Jeremy shared?
Please have a look at my latest comment. Is there a way to safely initialize the PHY and Ethernet module without knowing whether the PHY has been powered down or not? That would obviate the need for the "safe shutdown" sequence.
Gerhard,
Thanks for your input.
Gerhard Knorr wrote:
I assume your problem is the missing 50mhz reference clock. It gets disabled when you power down the PHY. This is still the case after a NVIC sysreset of the CPU.
Without the 50mhz clock an access to any one register in the Ethernet MAC 'Control registers' or 'RX filter registers' group blocks/crashes the CPU!
Do you mean the P1.15-RMII_CLK signal pictured in the LPC4088QSB schematic excerpt I showed above?
The first for loop in ethernet_init() follows an access to LPC_EMAC->Command which is in the 'Control registers' group. That is where the system crashes.
Indeed.
Solution: Begin your initialization with sending an instruction to the PHY to take it out of power down and switch the 50mhz back on. For that you need: 1) MDIO/MDC pins 2) ENET peripheral clock on 3) Ethernet MAC not in reset (MAC1=0) 4) MIIM clock divider configured 5) phy_write(...) to enable the PHY. If the 50mhz is up, you can do the normal initialization sequence.
Bottom line: Access to the PHY through MIIM is always possible. Avoid the critical registers in the Ethernet block before the 50mhz are stable at the ENET_REFCLK pin.
"Access to the PHY through MIIM is always possible" - except when it's not? Per your #2. Or are you referring to a clock signal internal to the MCU?
Do you mean the P1.15-RMII_CLK signal pictured in the LPC4088QSB schematic excerpt I showed above?
Yes, that is the critical signal.
"Access to the PHY through MIIM is always possible" - except when it's not? Per your #2. Or are you referring to a clock signal internal to the MCU?
I was somewhat vague here, sorry! #2 simply refers to the internal clock which is controlled by PCONP.
So I believe you have everything in place to talk to the PHY and bring the 50mhz back on-line.
PS:
In our own design there was an external oscillator for the 50mhz. We switched it off with a GPIO to save power, only to learn that the Ethernet MAC became partly inaccessible. Imagine the clock fails because of a broken component or a bad solder joint, you're not gonna learn about this failure mode before your CPU dies in an Ethernet register access. That is the reason why we have never used LPC devices for Ethernet applications again. For non-Ethernet they remain our preferred solution!
It may not be related, but this reminds me of a problem we had with our first LPC2468 design (long ago!).
The LPC2468 could be a beast when it dîdn't get the Ethernet clock. The debugger session crashed on the first attempt to access the Ethernet registers when the 50mhz clock was off. Perhaps your powering down the Phy also switches this clock off? But I must say this was with the Keil debugger, not mbed.