Author Topic: LAN8720 PHY IC requires delay after reset?  (Read 1630 times)

0 Members and 1 Guest are viewing this topic.

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
LAN8720 PHY IC requires delay after reset?
« on: June 21, 2022, 04:50:29 pm »
Hi I am currently working on a project where I have to implement an Ethernet Driver for STM32F429ZI Nucleo board with LAN8720 PHY IC. Below is my code.

Code: [Select]

#include "main.h"

#define ETH_EXTPHY_ADDRESS 0

#define ETH_EXTPHY_BCR 0
#define ETH_EXTPHY_BSR 1
#define ETH_EXTPHY_ANAR 4
#define ETH_EXTPHY_ANLPAR 5
#define ETH_EXTPHY_ANER 6
#define ETH_EXTPHY_PHYSCSR 31

#define ETH_RXBUFNUM 4
#define ETH_TXBUFNUM 2
#define ETH_RXBUFFSIZE 1524
#define ETH_TXBUFFSIZE 1524

uint8_t ETH_TxBuffer[ETH_TXBUFFSIZE];//[ETH_TXBUFNUM][ETH_TXBUFFSIZE];
uint8_t ETH_RxBuffer[ETH_RXBUFNUM][ETH_RXBUFFSIZE];

typedef struct{
uint32_t Status;
uint32_t ControlBufferSize;
uint32_t Buffer1Address;
uint32_t NextDescriptorAddress;
}ETH_Descriptor;

ETH_Descriptor RxDescriptorTable[ETH_RXBUFNUM];
ETH_Descriptor TxDescriptorTable;

void SystemClock_Config(void);

uint16_t ETH_ReadPHYRegister(uint8_t PHYRegAddr)
{
//read data from external PHY register
uint32_t tempReg = 0x0;

while(ETH->MACMIIAR & ETH_MACMIIAR_MB); //Wait until all operations to finish
tempReg |= (ETH_EXTPHY_ADDRESS<<ETH_MACMIIAR_PA_Pos) | (PHYRegAddr<<ETH_MACMIIAR_MR_Pos) | (0b100<<ETH_MACMIIAR_CR_Pos) | ETH_MACMIIAR_MB;
ETH->MACMIIAR = tempReg;

while(ETH->MACMIIAR & ETH_MACMIIAR_MB); //Wait until Data is received
return (ETH->MACMIIDR & 0xFFFF);
}

void ETH_WritePHYRegister(uint8_t PHYRegAddr, uint16_t RegValue)
{
//write data to external PHY register
uint32_t tempReg = 0x0;

while(ETH->MACMIIAR & ETH_MACMIIAR_MB); //Wait until all operations to finish
ETH->MACMIIDR = RegValue; //Load Data to Register
tempReg |= (ETH_EXTPHY_ADDRESS<<ETH_MACMIIAR_PA_Pos) | (PHYRegAddr<<ETH_MACMIIAR_MR_Pos) | (0b100<<ETH_MACMIIAR_CR_Pos) | ETH_MACMIIAR_MW | ETH_MACMIIAR_MB;
ETH->MACMIIAR = tempReg;
}

void Initialization()
{
//----------------GPIO Configuration----------------//
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN; //Enable Clocks

GPIOA->MODER |= (0b10<<GPIO_MODER_MODE1_Pos) | (0b10<<GPIO_MODER_MODE2_Pos) | (0b10<<GPIO_MODER_MODE7_Pos); //Set Pins as Alternate Function pins
GPIOA->OSPEEDR |= (0b11<<GPIO_OSPEEDR_OSPEED1_Pos) | (0b11<<GPIO_OSPEEDR_OSPEED2_Pos) | (0b11<<GPIO_OSPEEDR_OSPEED7_Pos); //Set Pins as Very High Speed
GPIOA->AFR[0] |= (11<<GPIO_AFRL_AFSEL1_Pos) | (11<<GPIO_AFRL_AFSEL2_Pos) | (11<<GPIO_AFRL_AFSEL7_Pos); //Set pins Alternative Functions

GPIOB->MODER |= (0b10<<GPIO_MODER_MODE11_Pos) | (0b10<<GPIO_MODER_MODE12_Pos) | (0b10<<GPIO_MODER_MODE13_Pos); //Set Pins as Alternate Function pins
GPIOB->OSPEEDR |= (0b11<<GPIO_OSPEEDR_OSPEED11_Pos) | (0b11<<GPIO_OSPEEDR_OSPEED12_Pos) | (0b11<<GPIO_OSPEEDR_OSPEED13_Pos); //Set Pins as Very High Speed
GPIOB->AFR[1] |= (11<<GPIO_AFRH_AFSEL11_Pos) | (11<<GPIO_AFRH_AFSEL12_Pos) | (11<<GPIO_AFRH_AFSEL13_Pos); //Set pins Alternative Functions

GPIOC->MODER |= (0b10<<GPIO_MODER_MODE1_Pos) | (0b10<<GPIO_MODER_MODE4_Pos) | (0b10<<GPIO_MODER_MODE5_Pos); //Set Pins as Alternate Function pins
GPIOC->OSPEEDR |= (0b11<<GPIO_OSPEEDR_OSPEED1_Pos) | (0b11<<GPIO_OSPEEDR_OSPEED4_Pos) | (0b11<<GPIO_OSPEEDR_OSPEED5_Pos); //Set Pins as Very High Speed
GPIOC->AFR[0] |= (11<<GPIO_AFRL_AFSEL1_Pos) | (11<<GPIO_AFRL_AFSEL4_Pos) | (11<<GPIO_AFRL_AFSEL5_Pos); //Set pins Alternative Functions

//----------------SYSCFG Configuration----------------//
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; //Enable Clocks

SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL; //Select RMII

//----------------Ethernet Configuration----------------//
RCC->AHB1ENR |= RCC_AHB1ENR_ETHMACEN | RCC_AHB1ENR_ETHMACTXEN | RCC_AHB1ENR_ETHMACRXEN; //Enable Clocks

ETH->DMABMR |= ETH_DMABMR_SR; //Resets Ethernet Core
while(ETH->DMABMR & ETH_DMABMR_SR); //Wait until reset completes

//--------PHY Configuration--------//
uint16_t tempRegister;

//Soft Reset PHY
ETH_WritePHYRegister(ETH_EXTPHY_BCR, 0x8000);
while(ETH_ReadPHYRegister(ETH_EXTPHY_BCR) & 0x8000); //Wait until reset completes

//Wait for Linked status
while(!(ETH_ReadPHYRegister(ETH_EXTPHY_BSR) & 0x4)); //Wait until link is up

//Auto negotiation is enabled by hardware.
tempRegister = ETH_ReadPHYRegister(ETH_EXTPHY_BCR);
tempRegister |= (0b1<<9);
ETH_WritePHYRegister(ETH_EXTPHY_BCR, tempRegister); //Restart auto-negotiation.
while(!(ETH_ReadPHYRegister(ETH_EXTPHY_BSR) & (0b1<<5))); //Wait until auto-negotiation completes

//Auto negotiation result
tempRegister = ETH_ReadPHYRegister(ETH_EXTPHY_PHYSCSR);

//--------MAC Configuration--------//
if(((tempRegister>>2) & 0b111) == 0b110) //100BASE-TX Full-duplex
{
ETH->MACCR |= ETH_MACCR_FES | ETH_MACCR_DM;
}
else if(((tempRegister>>2) & 0b111) == 0b010) //100BASE-TX Half-duplex
{
ETH->MACCR |= ETH_MACCR_FES;
}
else if(((tempRegister>>2) & 0b111) == 0b101) //10BASE-T Full-duplex
{
ETH->MACCR |= ETH_MACCR_DM;
}
else  //10BASE-T Half-duplex
{
ETH->MACCR &= ~(ETH_MACCR_FES | ETH_MACCR_DM);
}
ETH->MACCR |= ETH_MACCR_IPCO; //Enable IPv4 Off-load
ETH->MACIMR |= ETH_MACIMR_TSTIM | ETH_MACIMR_PMTIM; //Disable interrupt generation due to time stamp trigger and PMT.

//MAC Address is set here
ETH->MACA0HR &= ~(ETH_MACA0HR_MACA0H); //Clear MAC Address
ETH->MACA0HR |= (0xMACADDRESS<<ETH_MACA0HR_MACA0H_Pos);
ETH->MACA0LR &= ~(ETH_MACA0LR_MACA0L); //Clear MAC Address
ETH->MACA0LR |= (0xMACADDRESS<<ETH_MACA0LR_MACA0L_Pos);

//--------MMC Configuration--------//
//Mask Statistic Interrupts
ETH->MMCRIMR |= ETH_MMCRIMR_RGUFM | ETH_MMCRIMR_RFAEM | ETH_MMCRIMR_RFCEM;
ETH->MMCTIMR |= ETH_MMCTIMR_TGFM | ETH_MMCTIMR_TGFMSCM | ETH_MMCTIMR_TGFSCM;

//--------DMA Configuration--------//

ETH->DMARDLAR = (uint32_t) &RxDescriptorTable[0];
ETH->DMATDLAR = (uint32_t) &TxDescriptorTable;

ETH->DMAOMR |= ETH_DMAOMR_RSF | ETH_DMAOMR_TSF; //Forward Mode

ETH->DMAIER |= ETH_DMAIER_NISE | ETH_DMAIER_RIE; //Enable Rx interrupt

//----------------NVIC Configuration----------------//
NVIC_EnableIRQ(ETH_IRQn);

//--------ETH Start--------//

ETH->MACCR |= ETH_MACCR_TE;
ETH->MACCR |= ETH_MACCR_RE;
ETH->DMAOMR |= ETH_DMAOMR_FTF; // Transmit fifo flush
while(ETH->DMAOMR & ETH_DMAOMR_FTF); // Wait until fifo flushes
ETH->DMAOMR |= ETH_DMAOMR_ST;
ETH->DMAOMR |= ETH_DMAOMR_SR;




}



void ETH_IRQHandler()
{

}

int main(void)
{

  HAL_Init();
  SystemClock_Config();
  Initialization();

  TxDescriptorTable.Status = ETH_DMATXDESC_TCH;
  TxDescriptorTable.ControlBufferSize = 0x0;
  TxDescriptorTable.Buffer1Address = (uint32_t)(&ETH_TxBuffer[0]);
  TxDescriptorTable.NextDescriptorAddress = (uint32_t) &TxDescriptorTable;

  TxDescriptorTable.Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;


  ETH_TxBuffer[0] = 0xff;
  ETH_TxBuffer[1] = 0xff;
  ETH_TxBuffer[2] = 0xff;
  ETH_TxBuffer[3] = 0xff;
  ETH_TxBuffer[4] = 0xff;
  ETH_TxBuffer[5] = 0xff;

  ETH_TxBuffer[6] = 0xMAC1;
  ETH_TxBuffer[7] = 0xMAC2;
  ETH_TxBuffer[8] = 0xMAC3;
  ETH_TxBuffer[9] = 0xMAC4;
  ETH_TxBuffer[10] = 0xMAC5;
  ETH_TxBuffer[11] = 0xMAC6;

  ETH_TxBuffer[12] = 0x08;
  ETH_TxBuffer[13] = 0x06;

  ETH_TxBuffer[14] = 0x00;
  ETH_TxBuffer[15] = 0x01;

  ETH_TxBuffer[16] = 0x08;
  ETH_TxBuffer[17] = 0x00;

  ETH_TxBuffer[18] = 0x06;

  ETH_TxBuffer[19] = 0x04;

  ETH_TxBuffer[20] = 0x00;
  ETH_TxBuffer[21] = 0x01;

  ETH_TxBuffer[22] = 0xMAC1;
  ETH_TxBuffer[23] = 0xMAC2;
  ETH_TxBuffer[24] = 0xMAC3;
  ETH_TxBuffer[25] = 0xMAC4;
  ETH_TxBuffer[26] = 0xMAC5;
  ETH_TxBuffer[27] = 0xMAC6;


  ETH_TxBuffer[28] = 0xc0;
  ETH_TxBuffer[29] = 0xa8;
  ETH_TxBuffer[30] = 0x00;
  ETH_TxBuffer[31] = 0x16;

  ETH_TxBuffer[32] = 0x00;
  ETH_TxBuffer[33] = 0x00;
  ETH_TxBuffer[34] = 0x00;
  ETH_TxBuffer[35] = 0x00;
  ETH_TxBuffer[36] = 0x00;
  ETH_TxBuffer[37] = 0x00;

  ETH_TxBuffer[38] = 0xc0;
  ETH_TxBuffer[39] = 0xa8;
  ETH_TxBuffer[40] = 0x00;
  ETH_TxBuffer[41] = 0x05;



  while(TxDescriptorTable.Status & ETH_DMATXDESC_OWN); //wait until DMA release Descriptor

  TxDescriptorTable.Status |=ETH_DMATXDESC_FS|ETH_DMATXDESC_LS|ETH_DMATXDESC_TER;
  TxDescriptorTable.ControlBufferSize = 42;
  TxDescriptorTable.Status |= ETH_DMATXDESC_OWN;

if (ETH->DMASR & ETH_DMASR_TBUS)
{
ETH->DMASR = ETH_DMASR_TBUS;
ETH->DMATPDR = 0;
}





  while (1)
  {

  }

}


void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 180;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {

  }
  /** Activate the Over-Drive mode
  */
  if (HAL_PWREx_EnableOverDrive() != HAL_OK)
  {

  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {

  }
  SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk);
}





Code works fine if I am debugging but when I flash the code and reset the microcontroller it doesnt seem to send the ARP requests.
If I add a delay after link status check for approximately 270ms the code works fine . So I believe I have to wait for the chip to wake up after reset or something? I counldn't find anything in datasheet. I was expecting a register bit that I can poll to make sure the IC is ready to handle the data. Normally I only check Link status and Auto negotiation result to continue the code.
 

Offline spostma

  • Regular Contributor
  • *
  • Posts: 118
  • Country: nl
Re: LAN8720 PHY IC requires delay after reset?
« Reply #1 on: June 21, 2022, 06:07:59 pm »
 

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
Re: LAN8720 PHY IC requires delay after reset?
« Reply #2 on: June 21, 2022, 06:50:55 pm »
Thanks for reply but I understand that this guys problem is, not being able to use clock pin and boot pin for MCU at same time. Since boot pin has to low and clock pin has to high for initial startup for both MCU and PHY. So he uses custom "reset" supervisor IC.
In article also in datasheet it is stated that reset must be released after stable clock is applied to the PHY .On my board IC has its own crystal with 25MHz always so it shouldn't have a problem about reset being released when no clock is available.
 

Offline ajb

  • Super Contributor
  • ***
  • Posts: 2596
  • Country: us
Re: LAN8720 PHY IC requires delay after reset?
« Reply #3 on: June 21, 2022, 07:48:10 pm »
From the datasheet (emphasis mine)
Quote
3.8.5.2 Software Reset
A Software reset is activated by setting the Soft Reset bit of the Basic Control Register to “1”. All registers bits, except those indicated as “NASR” in the register definitions, are cleared by a Software reset. The Soft Reset bit is self-clearing.
 Per the IEEE 802.3u standard, clause 22 (22.2.4.1.1) the reset process will be completed within 0.5s from the setting of this bit.

So the reset bit is itself the bit that will tell you when the reset is complete, and 270ms is well within the quoted time for the reset to be completed. It's possible that the link management section of the PHY complete the reset process before other parts do, and attempting to interact with the PHY before those other parts are fully reset causes some sort of invalid internal state. Regardless, it's generally a risky idea to interact with a complicated part like this during a reset as behavior can be difficult to predict.
 

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
Re: LAN8720 PHY IC requires delay after reset?
« Reply #4 on: June 22, 2022, 06:29:23 am »
Basic Control register has soft reset bit when you trigger it will issue a soft reset then you can check the bit if the process is finish by polling this bit. However, I need a bit that can tell me if IC is ready after Hardware reset. It seems like there is no such bit. I have to put dummy delays at the beginning of the code.

Also I tried to Soft reset after startup and polled the bit but behavior didn't changed.
 

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
Re: LAN8720 PHY IC requires delay after reset?
« Reply #5 on: June 22, 2022, 07:57:45 am »
I scoped RST pin and MDC pin. I also removed the delay. It seems like it is  waiting for approximately 1.5s for the link go up. I don't understand why this configuration doesn't work. Blue is RST pin, yellow is MDC. MDIO and MDC constantly checks for link status thats why its seems like oscillating.
« Last Edit: June 22, 2022, 08:42:50 am by syntax333 »
 

Offline ajb

  • Super Contributor
  • ***
  • Posts: 2596
  • Country: us
Re: LAN8720 PHY IC requires delay after reset?
« Reply #6 on: June 22, 2022, 07:32:39 pm »
Your code doesn't show the MCU issuing a hard reset, but it DOES show it issuing a soft reset. 

Is that the reset line on the PHY you're probing, or the MCU?  How is the PHY reset line connected?  Either way it looks like you are waiting for the reset status bit to clear after the reset, so that part should be fine.  What happens when it doesn't transmit?  Are you seeing any data on the RMII lines?  Is the Eth DMAC releasing the descriptor? 
 

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
Re: LAN8720 PHY IC requires delay after reset?
« Reply #7 on: June 23, 2022, 04:46:05 am »
I am pressing reset button on nucleo board to reset both MCU and ETH PHY.  Reset line connected both MCU and ETH PHY in nucleo board. The screen shot I sent shows MDC so after reset I am constantly checking Link status. I didn't checked other RMII lines. I am waiting for DMA to release the descriptor ((" while(TxDescriptorTable.Status & ETH_DMATXDESC_OWN); //wait until DMA release Descriptor" )).

Also I realised that If I flash the code it runs fine. However, If I issue a reset or plug out/in the power after flashing code it won't run. That is the main problem I think.
« Last Edit: June 23, 2022, 04:51:03 am by syntax333 »
 

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
Re: LAN8720 PHY IC requires delay after reset?
« Reply #8 on: June 23, 2022, 07:52:54 am »
I realised my laptop sends arp requests to line after 4-5seconds after link is up. I am using wireshark. If I add 4 second delay to my code it works fine. So is this something about wireshark not being able to see things?   
 

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
Re: LAN8720 PHY IC requires delay after reset?
« Reply #9 on: June 23, 2022, 02:10:32 pm »
So I found the IC requires 4-5 seconds to power up. While powering up it is unresponsive. After 4-5 seconds it operates as it should. However, It is interesting to me that nowhere in datasheet says anything about powering up -> being able to accept data timing. Has anyone worked with this IC before? Encountered same problem?
 

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
Re: LAN8720 PHY IC requires delay after reset?
« Reply #10 on: June 23, 2022, 03:44:10 pm »
I added schematic of PHY IC on board.
 

Offline bson

  • Supporter
  • ****
  • Posts: 2269
  • Country: us
Re: LAN8720 PHY IC requires delay after reset?
« Reply #11 on: June 25, 2022, 07:53:48 pm »
With the boot pins = 111 you have auto-negotiation enabled.  Maybe this just takes a few seconds in your particular setup.  (Patch cable directly to your laptop?)

I think I would watch the basic status register, or similar, and timestamp and decode/log it to the console whenever it changes.  This would give a clue as to what's going on, watching what it's doing, and at which stage it's working again.  My wild guess is when you hit reset it also up ends up seeing a spurious link fault - or something.  (Or the other end does.)  It's probably not the best to reset the PHY while the cable is plugged in anyway.
« Last Edit: June 25, 2022, 08:12:06 pm by bson »
 

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
Re: LAN8720 PHY IC requires delay after reset?
« Reply #12 on: June 25, 2022, 09:17:43 pm »
Ethernet cable was directly connected to my PC. I found a work around by replacing
Code: [Select]
while(!(ETH_ReadPHYRegister(ETH_EXTPHY_BSR) & 0x4));

with

Code: [Select]
uint16_t tempReg;
do
{
DummyDelay(250); //250ms delay
tempReg = ETH_ReadPHYRegister(ETH_EXTPHY_BSR);
}
while(!(tempReg  & 0x4));

Which basically checks the link status every 250ms instead continuously. This resulted in connection time of approximately 2 seconds instead of 4-5. I still don't know what I am doing wrong and inner workings of the IC.

I tried logging Basic status register, but everything seems fine before and after the link status check and autonegotiation complete check.
 

Offline ajb

  • Super Contributor
  • ***
  • Posts: 2596
  • Country: us
Re: LAN8720 PHY IC requires delay after reset?
« Reply #13 on: June 28, 2022, 05:37:32 pm »
I am pressing reset button on nucleo board to reset both MCU and ETH PHY.  Reset line connected both MCU and ETH PHY in nucleo board.

[...]

Also I realised that If I flash the code it runs fine. However, If I issue a reset or plug out/in the power after flashing code it won't run. That is the main problem I think.

That makes sense if your toolchain and programming interface are configured to soft reset the MCU after programming, since it won't cause a hardware reset to the PHY.  So the PHY will still be up and running from the last reset unless/until you issue a soft reset.

Speaking which, it's hard to offer advice when you aren't clear and consistent in your description of the problem.  You started off asking about hard reset, but then the code you posted shows the MCU issuing a soft reset, which confuses what's going on and makes it harder to help you.  If you're making changes to the code as you troubleshoot that's fine, but please be clear about which changes to the code or your programming/reset process have what effects on the system behavior. 

Quote
The screen shot I sent shows MDC so after reset I am constantly checking Link status. I didn't checked other RMII lines. I am waiting for DMA to release the descriptor ((" while(TxDescriptorTable.Status & ETH_DMATXDESC_OWN); //wait until DMA release Descriptor" )).

Sure, your code is waiting for the descriptor to be released, but is that actually happening?  Without information like this it's harder to tell where the problem is. 

All that aside, if the link comes up faster when you reduce the polling rate, then my guess is that servicing an SMI transaction is keeping the PHY's internal logic from getting the link worked out or performing whatever other reset housekeeping it needs to do.  I don't know how PHYs are designed internally but given how much work they do I could believe there's something like a little general purpose processor core in there that handles a lot of the configuration and housekeeping necessary to manage the link hardware, and it probably wasn't designed to service SMI continuously at the rate that something like an STM32F4 can poll it during otherwise normal operation.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf