2017-10-12 3:21 AM
Hi
I am trying to probe data going between the STM32F407 MAC and LAN8720A. I have a 50MHz clock from MCO1 to the PHY and seems to be working as the LED's are recognizing the network. I believe the clock signal is idle until there is data transfer between them but when I do a write (or read) I do not see and signal on the MDIO or MDC lines. As I am only interestes in the SMI at the moment I have configured the alternate function (ETH) 0b1011 for PA2 and PC1 as follows:
GPIOA->MODER |= (1 << 5); // Set PA2 as alternate function - MDIO
GPIOC->MODER |= (1 << 3); // Set PC1 as alternate function - MDC GPIOA->AFR[0] |= (0xB << 8); // AF11 - 0b1011 = 0xB GPIOC->AFR[0] |= (0xB << 4);The write is as follows:
uint32_t ETH_WritePHYRegister(uint16_t PHYAddress, uint16_t PHYReg, uint16_t PHYValue)
{ volatile uint32_t tmpreg = 0; uint32_t tmpDataReg = 0; __IO uint32_t timeout = 0; tmpreg = ETH_MACMIIAR; // keeps previous clock setting /* Keep only the CSR Clock Range CR[2:4] bits value */ tmpreg &= 0b00000000000000000000000000011100;/* Prepare the MII register address value */
tmpreg |=(((uint32_t)PHYAddress<<11) & ETH_MACMIIAR_PA); /* Set the PHY device address */ // ETH_MACMIIAR_PA = 0x0000F800 tmpreg |=(((uint32_t)PHYReg<<6) & ETH_MACMIIAR_MR); /* Set the PHY register address */ tmpreg |= ETH_MACMIIAR_MW; /* Set the write mode */ // ETH_MACMIIAR_MW = 0x2 tmpreg |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */ // ETH_MACMIIAR_MB = 0x1 /* Give the value to the MII data register */ ETH_MACMIIDR = PHYValue; /* Write the result value into the MII Address register */ ETH_MACMIIAR = tmpreg; /* Check for the Busy flag */ do { timeout++; tmpreg = ETH_MACMIIAR; } while (timeout < 5); //} while ((tmpreg = 0b10011) && (timeout < (uint32_t)PHY_WRITE_TO)); /* Return ERROR in case of timeout */ if(timeout == PHY_WRITE_TO) // PHY_WRITE_TO = 0x0000FFFFU {return ETH_ERROR; // 1
}/* Return SUCCESS */
return ETH_SUCCESS; // 0
}I expect when I get to '
ETH_MACMIIAR = tmpreg;' that I would see some activity on the MDC and MDIO lines but there is nothing happening. Is there something additional required to initiate a write??
Thanks.
2017-10-12 4:15 AM
You need to have clock present on the MAC clock input, enabled in RCC (all 3 bits), and the RMII mode set in SYSCFG.
JW
2017-10-12 5:49 AM
I have added the following MAC clock enable:
RCC->AHB1ENR |= (1 << 25); // Ethernet MAC clock enable
RCC->AHB1ENR |= (1 << 26); // Ethernet Transmission clock enable RCC->AHB1ENR |= (1 << 27); // Ethernet Reception clock enableAs I am using a MII, SYSCFG_PMC defaults to zero so I have not set it. Still nothing appearing. Do certain registers perhaps need to be reset after?
2017-10-12 7:30 AM
Its a SMSC LAN8720A.
I just checked the connections and the clock is not present on PC1 so this is RMII. The data sheet states: This configuration must be done while the MAC is under reset and before enabling the MAC clocks. So I run the config function first which includes setting this bit. When this is done I then enable the clocks. Still no joy.
void main (void) {
SMI_Init();
clockEnable(); MCO1Enable();}
void SMI_Init(void)
{ SYSCFG_PMC |= (1 << 23); // RMII interface is selected GPIOA->MODER |= (1 << 3); // Set PA1 as alternate function GPIOA->MODER |= (1 << 5); // Set PA2 as alternate function GPIOA->MODER |= (1 << 15); // Set PA7 as alternate function GPIOC->MODER |= (1 << 7); // Set PC3 as alternate function GPIOC->MODER |= (1 << 9); // Set PC4 as alternate function GPIOC->MODER |= (1 << 11); // Set PC5 as alternate function GPIOA->AFR[0] |= (0xB << 4); // AF11 on PA1 GPIOA->AFR[0] |= (0xB << 8); // AF11 on PA2 GPIOA->AFR[0] |= (0xB << 28); // AF11 on PA7 GPIOC->AFR[0] |= (0xB << 12); // AF11 on PC3 GPIOC->AFR[0] |= (0xB << 16); // AF11 on PC4 GPIOC->AFR[0] |= (0xB << 20); // AF11 on PC5}void clockEnable(void)
{ RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; // enable the clock to GPIOA RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; // enable the clock to GPIOC RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; // enable the clock to GPIOD RCC->APB2ENR |= (1 << 14); // Enable clock for SYSCFG RCC->AHB1ENR |= (1 << 25); // Ethernet MAC clock enable RCC->AHB1ENR |= (1 << 26); // Ethernet Transmission clock enable RCC->AHB1ENR |= (1 << 27); // Ethernet Reception clock enable}void MCO1Enable(void)
{ // Enable MCO1 clock on PA8 GPIOA->MODER |= (1 << 17); // same as *GPIOAMODER = (1 << 17); GPIOA->OSPEEDR = 0x30000; // very high speed. OSPEEDR8 GPIOA->PUPDR = 0x0; // No pull-up, pull-down GPIOA->AFR[0] = 0x0; // AF0 GPIOA->AFR[1] = 0x0; // AF0 RCC->CFGR = 0b11111101011000001001010000001010;}2017-10-12 8:04 AM
50MHz sounded like RMII. I don't know the PHY you are using.
Do you have the input clock present on the TX_CLK and RX_CLK pins (PA1/PC3), and those pins configured as AF/ETH?
JW
2017-10-12 9:06 AM
That was jest a redefined but works the same. So I changed enabled the
APB2ENR register before SYSCFG is enabled like the following.
RCC->APB2ENR |= (1 << 14);
SYSCFG->PMC |= (1 << 23);The settings seem to be ok but still not working.
2017-10-12 10:29 AM
Verify in debugger if all those registers are set as you want them.
(I am aiming at whether all modules' clock are enabled in RCC, namely SYSCFG)
JW
PS.
SYSCFG_PMC
Why not SYSCFG->PMC?
2017-10-17 6:15 AM
It turns out that some settings were getting reset further on in the code. The resets were removed and everything is working as it should now.
We’re moving the ST Community to a new platform to give you a better and more reliable community experience.