2017-10-12 03: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 04: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 05: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 07: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 08: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 09: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 06: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.