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!
解決済! 解決策の投稿を見る。
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
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.
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
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);
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
Thanks! That was a miss.
But now I only get 0x20002000 as result.
Hi!
I've checked the waveforms!
First image:
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:
Here you can see the two 1's. ST and OP fields...
Third image:
Fourth image:
Fifth image:
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!
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
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?
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.
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
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
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?
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
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
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
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!