MDIO signaling problem

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

MDIO signaling problem

Jump to solution
11,957 Views
rothkarl
Contributor III

Dear Forumers!

I've started writing a communication stack, under FRDM-K64F board.

Currently I'am trying to complete the initialization sequence of the ENET peripheral. So at this point what I'am want to do is to exchange data between my onboard Micrel PHY chip and my controller. To do this I've done the followings:

MDIO init sequence:

/*port init*/

-Portb clock enable

-I have properly initialized the PTB0, and PTB1 to function as ALT4.

-I have turned on the pull-up resistors, because those are not populated on the board.

-At this point I dont know if it is neccessary, but I have turned on the Open drain output feature.

/*eth per init*/

-eth clock enable

-The datasheet says MDIO gets its clock by prescaling the internal bus clock. In my case that is 60 MHz by default, so I have choosen 11 as prescaler. (60/((11+1)*2))=2.5

-eth module enable

So far I have not initialized completely the eth peripheral, I just want to check first the MDIO functionality.

I have written a funtion that should exchange data between phy and my controller. The datasheet says that MII interrupt flag marks whenever an MDIO data exchange have been succeeded. In my function this works correctly,

before writing MMFR register this bit is 0, and after some time this bit turns to 1 marking the end of the proccess. But after reading from any phy and register addresses the returned result is always 0xffff data.

In my workspace I've checked the signals of the R55 and R56 pullup resistor pads, and I can clearly see that MDC and MDIO signals not altering at all, staying all the time steady.

I've read the other posts relating to this, but I didn't find solution, so I kindly ask some expert to help me discussing this question!

I think the problem can be related to clock distribution. I dont know if ENET peripheral uses RMII external 50 MHz reference clock.

Or do I have to configure ENET for RMII mode. At this point I think MDIO should be separated from MII, RMII functionality. I dont know.

Thank you for your help in advance!

Labels (1)
Tags (3)
1 Solution
7,722 Views
mjbcswitzerland
Specialist V

Roth

The MDIO changes correctly on the rising edge of the clock.

The MDC also always runs continuouly so there is no problems here - if you want to stpp the clock you can simply set MSCR = 0; and then set the speed again before you use it the next time.

I didn't look at the the signal details but basically the transfers are taking place so maybe you have a problem with the reading code - check for example that you have EIR  defined as a volatile register.

You can also do the followig:

- go to µTasker Kinetis FRDM-K64F support and load the binary called "uTaskerV1.4.8_FRDM-K64_LAN.bin" to your board

- On the OpenSDA virtual com port connect at 115200 Baud. Then hit the enter key to get the command line menu shell:

     Main menu
===================
1              Configure LAN interface
2              Configure serial interface
3              Go to I/O menu
4              Go to administration menu
5              Go to overview/statistics menu
6              Go to USB menu
7              Go to I2C menu
8              Go to utFAT disk interface
9              FTP/TELNET client commands
a              CAN commands
help           Display menu specific help
quit           Leave command mode

Enter 1 to get to the LAN menu:

LAN configuration
===================
up                  go to main menu
phy                 Dump PHY registers
set_phy             [reg] [val]
set_dhcp            [enable/disable] DHCP
set_ip_add          Set IPV4 address
set_ip_mask         Set IP subnet mask
set_ip_gway         Set default gateway
set_ip_dns          Set default DNS
set_eth_speed       Set LAN speed (10/100/AUTO)
show_config         Show network configuration
save                Save configuration to FLASH
ping                Ping test IP address
arp -a              Request ARP table
arp -d              Delete ARP table
help                Display menu specific help
quit                Leave command mode

Using the "phy" and "set_phy" commands you can dump the PHY registers and make changes to them. The PHY status is also being polled every 5s because this board has no interrupt line connected to the PHY and the SW needs to resynchronise the EMAC to the PHY setting each time the link state changes.

You can measure the signals and test that all is working correctly on your board and compare with your code's operation.

In the I/O menu (3):

 Input/Output menu
===================
up             go to main menu
md             Memory Display [address] [l|w|b] [num]
mm             Memory Modify [address] [l|w|b] [val]
mf             Memory Fill [address] [l|w|b] [val] [num]
sd             Storage Display {as md}
sm             Storage Modify {as mm}
sf             Storage Fill {as mf}
se             Storage Erase [address] [len-hex]
set_ddr        Set port type [1..4] [i|o]
get_ddr        Get data direction [1..4]
read_port      Read port input [1..4]
write_port     Set port output [1..4] [0/1]
save           Save port setting as default
help           Display menu specific help
quit           Leave command mode

there is also a memory debugger so that you look at the register contents and compare them with yours to see whether there is a difference that may explain something.

Note that I usually disable the MDC between usage but I let if run when the PHY commands are used (as in this SW).

Regards

Mark

Kinetis: µTasker Kinetis support

K64: µTasker Kinetis FRDM-K64F support / µTasker Kinetis TWR-K64F120M support

For the complete "out-of-the-box" Kinetis experience and faster time to market


View solution in original post

0 Kudos
Reply
16 Replies
7,722 Views
trilokjt
Contributor III

No, I'm getting some protocols I.e., ARP, Precesion time protocol(PRP), SSDP

Ive one doubt whether board is commected properly or not because on PC ethernet network is identified as Unidentified network. If enter to debug mode it will go off( On PC Shows- Identifying network...) again after few sec/min it again show it as unidentified networK. Can you tell me what's the problem? Is borad connected properly or not. I took TxN,TxP,RxP,RxN from board and connected to RJ 45.

0 Kudos
Reply
7,722 Views
mjbcswitzerland
Specialist V

Hi Roth

To initialise the MDIO on the FRDM-K64F you need:

#define SYSTEM_CLOCK 120000000

#define MII_MANAGEMENT_CLOCK_SPEED 2500000 // typ. 2.5MHz Speed

#define PHY_IDENTIFIER 0x00221560 // MICREL KSZ8081RNA identifier

#define PHY_MASK 0xfffffff0 // don't check the revision number

#define PHY_ADDRESS 0x00 // address of external PHY on board

#define PHY_REG_ID1 0x02 // PHY Identification Register 1

#define PHY_REG_ID2 0x03 // PHY Identification Register 2

{

    unsigned long ulPhyIdentifier;

    POWER_UP(2, SIM_SCGC2_ENET); // power up the Ethernet controller

    MPU_CESR = 0; // allow concurrent access to MPU controller

    _CONFIG_PERIPHERAL(B, 0, (PB_0_MII0_MDIO | PORT_PS_UP_ENABLE)); // MII0_MDIO on PB.0 (alt. function 4) with pullup enabled

    _CONFIG_PERIPHERAL(B, 1, PB_1_MII0_MDC); // MII0_MDC on PB.1 (alt. function 4)

    ECR = RESET_FEC; // EMAC software reset

    while (ECR & RESET_FEC) {} // short wait until reset is complete

    MSCR = (((SYSTEM_CLOCK/(2 * MII_MANAGEMENT_CLOCK_SPEED)) + 1) << 1); // generate the communication channel clock

    ulPhyIdentifier = fnMIIread(PHY_ADDRESS, PHY_REG_ID1); // check that the PHY is working correctly by reading its identifier - part 1

    ulPhyIdentifier <<= 16;

    ulPhyIdentifier |= fnMIIread(PHY_ADDRESS, PHY_REG_ID2); // check that the PHY is working correctly by reading its identifier - part 2

    if ((ulPhyIdentifier & PHY_MASK) != (PHY_IDENTIFIER & PHY_MASK)) {

        MSCR = 0; // disable clock

        POWER_DOWN(2, SIM_SCGC2_ENET);

        return -1; // if the identifier is incorrect the phy isn't responding correctly - return error

    }

    // else OK

}

// Function to read from the MII interface

//

static unsigned short fnMIIread(unsigned char _mpadr, unsigned char _mradr)

{

    MMFR = (MII_READ | (_mpadr << 23) | (_mradr << 18));

    while ((EIR & MII) == 0) {} // wait until the read has completed

    EIR = MII; // reset the interrupt event

    return (unsigned short)MMFR; // return the data read

}

Regards

Mark

P.S If you read 0xffff it usually means that you aren't addressing the PHY with its correct address (which is 0 on the FRDM-K64F)

Kinetis: µTasker Kinetis support

K64: µTasker Kinetis FRDM-K64F support / µTasker Kinetis TWR-K64F120M support

For the complete "out-of-the-box" Kinetis experience and faster time to market

7,722 Views
rothkarl
Contributor III

Hi,

Thank you for your reply. At the moment I can read back 0xffff0000, tomorrow I'll check the waveforms again!

I had to modify a littlebit, is this code correct?

eth_init is a funtion that i call when sw3 pressed. I need this to debug on scope.

#define SYSTEM_CLOCK 120000000

#define MII_MANAGEMENT_CLOCK_SPEED 2500000 // typ. 2.5MHz Speed

#define PHY_IDENTIFIER 0x00221560 // MICREL KSZ8081RNA identifier

#define PHY_MASK 0xfffffff0 // don't check the revision number

#define PHY_ADDRESS 0x00 // address of external PHY on board

#define PHY_REG_ID1 0x02 // PHY Identification Register 1

#define PHY_REG_ID2 0x03 // PHY Identification Register 2

static unsigned short fnMIIread(unsigned char _mpadr, unsigned char _mradr)

{

    ENET_MMFR = ((2 << 28) | (_mpadr << 23) | (_mradr << 18));

    while ((ENET_EIR & ENET_EIR_MII_MASK) == 0) {} // wait until the read has completed

    ENET_EIR = ENET_EIR_MII_MASK; // reset the interrupt event

    return (unsigned short)ENET_MMFR; // return the data read

}

void eth_init(void)

{

  /*Ethernet clock en*/

  asm( "NOP" );

  unsigned short usData;

  unsigned long ulPhyIdentifier;

  SIM_SCGC2 |= SIM_SCGC2_ENET_MASK;//eth clock en

  SIM_SCGC5|= SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTA_MASK;//portb es porta clock en

  PORTB_PCR0 |= PORT_PCR_MUX(4) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK;

  PORTB_PCR1 |= PORT_PCR_MUX(4);

  /*PORTA ALT4*/

  PORTA_PCR5 = PORT_PCR_MUX(4);//PTA5 ALT4 RMII0_RXER

  PORTA_PCR12 = PORT_PCR_MUX(4);//PTA12 ALT4 RMII0_RXD1

  PORTA_PCR13 = PORT_PCR_MUX(4);//PTA13 ALT4 RMII0_RXD0

  PORTA_PCR14 = PORT_PCR_MUX(4);//PTA14 ALT4 RMII0_CRS_DV

  PORTA_PCR15 = PORT_PCR_MUX(4);//PTA15 ALT4 RMII0_TXEN

  PORTA_PCR16 = PORT_PCR_MUX(4);//PTA16 ALT4 RMII0_TXD0

  PORTA_PCR17 = PORT_PCR_MUX(4);//PTA17 ALT4 RMII0_RXD1

  MPU_CESR = 0;

  ENET_ECR = ENET_ECR_RESET_MASK;

  for( usData = 0; usData < 10; usData++ )

  {

  asm( "NOP" );

  }

  ENET_MSCR = (((SYSTEM_CLOCK/(2 * MII_MANAGEMENT_CLOCK_SPEED)) + 1) << 1); // generate the communication channel clock

  ENET_ECR = ENET_ECR_ETHEREN_MASK;

  ulPhyIdentifier = fnMIIread(PHY_ADDRESS, PHY_REG_ID1); // check that the PHY is working correctly by reading its identifier - part 1

     ulPhyIdentifier <<= 16;

     ulPhyIdentifier |= fnMIIread(PHY_ADDRESS, PHY_REG_ID2); // check that the PHY is working correctly by reading its identifier - part 2

asm("nop");

  while(1);

0 Kudos
Reply
7,722 Views
mjbcswitzerland
Specialist V

Roth

Note that

#define MII_READ  (MII_TA | MII_ST | READ_OP)

is 0x60020000

and not (2 << 28)

Regards

Mark

Kinetis: µTasker Kinetis support

K64: µTasker Kinetis FRDM-K64F support / µTasker Kinetis TWR-K64F120M support

For the complete "out-of-the-box" Kinetis experience and faster time to market

0 Kudos
Reply
7,722 Views
rothkarl
Contributor III

Thanks! That was a miss.

But now I only get 0x20002000 as result.

0 Kudos
Reply
7,722 Views
rothkarl
Contributor III

Hi!

I've checked the waveforms!

First image:

201504211029.jpg

Maybe it's not easy to recognise, but it seems like there is some trouble with my code. When my cpu reseted both signals are high.

After I press SW3 button you can see my first mdio trigger point as a trailing edge. The problem is as i can see that the data on the mdio line

changes on the leading edge, but i think it should change on the trailing edge. Another problem is that after two read sequences completed,

the mdc line continues toggling.

Second image:

201504211030.jpg

Here you can see the two 1's. ST and OP fields...

Third image:

201504211031.jpg

Fourth image:

201504211032.jpg

Fifth image:

201504211033.jpg

On the pictures above you can see the consequtive bit sequences marked with the cursor.

After the MDIO does not changes (idling) the mdc continues toggling, but that is quite bad thing.

I hope this helps you!

0 Kudos
Reply
7,723 Views
mjbcswitzerland
Specialist V

Roth

The MDIO changes correctly on the rising edge of the clock.

The MDC also always runs continuouly so there is no problems here - if you want to stpp the clock you can simply set MSCR = 0; and then set the speed again before you use it the next time.

I didn't look at the the signal details but basically the transfers are taking place so maybe you have a problem with the reading code - check for example that you have EIR  defined as a volatile register.

You can also do the followig:

- go to µTasker Kinetis FRDM-K64F support and load the binary called "uTaskerV1.4.8_FRDM-K64_LAN.bin" to your board

- On the OpenSDA virtual com port connect at 115200 Baud. Then hit the enter key to get the command line menu shell:

     Main menu
===================
1              Configure LAN interface
2              Configure serial interface
3              Go to I/O menu
4              Go to administration menu
5              Go to overview/statistics menu
6              Go to USB menu
7              Go to I2C menu
8              Go to utFAT disk interface
9              FTP/TELNET client commands
a              CAN commands
help           Display menu specific help
quit           Leave command mode

Enter 1 to get to the LAN menu:

LAN configuration
===================
up                  go to main menu
phy                 Dump PHY registers
set_phy             [reg] [val]
set_dhcp            [enable/disable] DHCP
set_ip_add          Set IPV4 address
set_ip_mask         Set IP subnet mask
set_ip_gway         Set default gateway
set_ip_dns          Set default DNS
set_eth_speed       Set LAN speed (10/100/AUTO)
show_config         Show network configuration
save                Save configuration to FLASH
ping                Ping test IP address
arp -a              Request ARP table
arp -d              Delete ARP table
help                Display menu specific help
quit                Leave command mode

Using the "phy" and "set_phy" commands you can dump the PHY registers and make changes to them. The PHY status is also being polled every 5s because this board has no interrupt line connected to the PHY and the SW needs to resynchronise the EMAC to the PHY setting each time the link state changes.

You can measure the signals and test that all is working correctly on your board and compare with your code's operation.

In the I/O menu (3):

 Input/Output menu
===================
up             go to main menu
md             Memory Display [address] [l|w|b] [num]
mm             Memory Modify [address] [l|w|b] [val]
mf             Memory Fill [address] [l|w|b] [val] [num]
sd             Storage Display {as md}
sm             Storage Modify {as mm}
sf             Storage Fill {as mf}
se             Storage Erase [address] [len-hex]
set_ddr        Set port type [1..4] [i|o]
get_ddr        Get data direction [1..4]
read_port      Read port input [1..4]
write_port     Set port output [1..4] [0/1]
save           Save port setting as default
help           Display menu specific help
quit           Leave command mode

there is also a memory debugger so that you look at the register contents and compare them with yours to see whether there is a difference that may explain something.

Note that I usually disable the MDC between usage but I let if run when the PHY commands are used (as in this SW).

Regards

Mark

Kinetis: µTasker Kinetis support

K64: µTasker Kinetis FRDM-K64F support / µTasker Kinetis TWR-K64F120M support

For the complete "out-of-the-box" Kinetis experience and faster time to market


0 Kudos
Reply
7,722 Views
rogerchaplin
Contributor II

I've seen this very same waveform myself with the K64 I've chosen for my design, also trying to work through problems in bringing up the Ethernet using a Micrel KSZ8081 PHY. The scope trace very clearly shows the MAC is changing MDIO on the rising edge of MDC, but the IEEE 802.3 standard very clearly says that both the MAC (the standard calls it the STA) and the PHY are to sample MDIO on the rising edge of MDC. What gives?

0 Kudos
Reply
7,722 Views
rothkarl
Contributor III

Dear Roger!

I think the problems may occure are not in relationship with the rising/falling edge problem, but it can be with the lack of external pull-up resistance on MDIO line. I recommend to solder one 1.5 Kohm 0603 resistor on the board because it was not populated by default.

I also dont understand the waveforms, but this time i can confirm that the board config is just fine, however an external resistor should be added.

If you need some help just write to me. I have finished writing my tcp stack ad web/telnet application.

0 Kudos
Reply
7,722 Views
trilokjt
Contributor III

Hi Roth

I have similar problem, I'm getting around 4.1Mhz on the MDC pin (For MII speed  should be less than or equal to 2.5Mhz right?) according to the IEEE 802.2 standards. I given 50Mhz clock to PHY and mode of operation is RMII mode. What I'm looking for is - I'm sending some raw buffer from board and trying to analyze/capture on PC using Wireshark. But I couldn't able to read the frame/packet  which I have sent. 

Please help me out

Thank you

0 Kudos
Reply
7,722 Views
mjbcswitzerland
Specialist V

Hi

If the MII clock is higher than you want you can change the value in MSCR to reduce it. The following is the formula:

MSCR = (((ETHERNET_CONTROLLER_CLOCK/(2 * MII_MANAGEMENT_CLOCK_SPEED)) + 1) << 1);

But limit MSCR to 0x7e if needed.

The MII doesn't have anything to do with the Ethernet operation (sending and receiving frames) so if the PHY is defaulting to auto-neg (generally the case) whether the clock speed is too high or not will not affect your problem in any way. Note that the clock is often diabled too (to save power and reduce radiation) since it is only reqired when communicating with the PHY registers.

Regards

Mark

0 Kudos
Reply
7,722 Views
trilokjt
Contributor III

Okay, I have done that. I used wire shark to read raw ether frames sent from the board. But I couldn't able to find any packets/frames received from the board on PC(using wire shark). Please can you tell me what is the issue/problem :smileysad: I used interrupt to make sure frame has been transmitted, interrupt is occurring on both Tx and Rx frames. I enabled promiscuous mode(PHY device) to read/receive all data irrespective of particular type/address of device, sent from MAC. Can you help me out is there any other tool to view raw Ethernet frame?

0 Kudos
Reply
7,722 Views
mjbcswitzerland
Specialist V

Hi

Wireshark will see all Ethernet traffic so if you don't see anything from your board I think that it is not sending anything.

It may be best to start with a working solution - eg. If you use a standard development board you can load an image from http://www.utasker.com/kinetis.html and if you need to learn Ethernet and the controller's operation run the uTasker simulator to follow the internal behavior.

Regards

Mark

0 Kudos
Reply
7,722 Views
mjbcswitzerland
Specialist V

Hi

1.5k is a good value on the MDIO line since it ensures a fast rising edge.

I have however found that the FRDM-K64F (which has no pull-up mounted) is reliable at 2.5MHz MDIO clock as long as the MDIO0_MDIO input is configured with a pull-up enabled:

_CONFIG_PERIPHERAL(B, 0, (PB_0_MII0_MDIO | PORT_PS_UP_ENABLE));

Regards

Mark

0 Kudos
Reply
7,722 Views
rothkarl
Contributor III

Hello Mark!

Let me add some remarks for this. When I have started the development I have faced with some issues related to MDIO, and I have checked the waveforms on scope and I have figured out, that the integrated 10kohm internal pull_up resistor was now enough to achive fast enough slew rate on MDIO line.

The scope just showed some exponentional waveforms, but they were very slow, and the clock line dynamics was much more better, hence it uses push output. Since I have added one 1.5k resistor on MDIO line waveforms are pretty fine, and communication is stable!

I hope it help!

Regards,

Roth

0 Kudos
Reply
7,722 Views
rothkarl
Contributor III

Dear Mark!

It looks like I have mistyped one line in my code, and the example that you send me is working correctly!

Thank you very much for your help!

0 Kudos
Reply