Powering down Ethernet PHY breaks debugging [LPC4088]

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Powering down Ethernet PHY breaks debugging [LPC4088]

Jump to solution
11,567 Views
bmcdonnell_ionx
Contributor III

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.

Problem Description

The problem goes like this:

  • Once phy_write(PHY_REG_BMCR, PHY_BMCR_PWR_DOWN); is called in main.cpp, and then after a reset or power-cycle, and after the code gets past the first for loop in ethernet_init(), you will no longer be able to debug. (i.e. The debugger can't halt the micro anymore, so you can't single step, "run to", or the like.)
    • This issue persists even after reset or power cycle. (Meaning you lose the ability to halt the micro once you pass that place inside ethernet_init().)
  • The only way I've found to fix the issue is as follows:
    • Power cycle the board so that you'll be able to halt the micro again (initially).
    • Erase the micro flash.
    • Power cycle the board again.
    • Now you'll be able to debug normally - until you pass that phy_write() call again.

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.)

Project Setup

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.

Labels (1)
1 Solution
10,525 Views
bmcdonnell_ionx
Contributor III

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".

View solution in original post

0 Kudos
Reply
29 Replies
2,586 Views
jeremyzhou
NXP Employee
NXP Employee

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!
-----------------------------------------------------------------------------------------------------------------------

2,586 Views
bmcdonnell_ionx
Contributor III

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,

  • ...
  • Powerdown_PHY();
  • NVIC_SystemReset();
  • MYSTERY_COMMAND();
  • Chip_ENET_Init();
  • ...

Obviously MYSTERY_COMMAND() would go before Chip_ENET_Init()

0 Kudos
Reply
2,586 Views
jeremyzhou
NXP Employee
NXP Employee

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.

pastedImage_2.png

Have a great day,
TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

10,526 Views
bmcdonnell_ionx
Contributor III

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".

0 Kudos
Reply
2,586 Views
gerhardk
Contributor II

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.

0 Kudos
Reply
2,586 Views
bmcdonnell_ionx
Contributor III

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.

0 Kudos
Reply
2,586 Views
bmcdonnell_ionx
Contributor III

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?

0 Kudos
Reply
2,586 Views
gerhardk
Contributor II

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!

0 Kudos
Reply
2,625 Views
gerhardk
Contributor II

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.

0 Kudos
Reply