Cheap shit-like ST-link 💩
In Debug Configuration please set 'Reset Mode' to value 'Software System Reset'
Generate code in CubeMX for PHY with RMII.
Override RMII config in section:
/* USER CODE BEGIN MACADDRESS */
heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_DISABLE;
heth.Init.Speed = ETH_SPEED_100M;
heth.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
heth.Init.PhyAddress = 0xFF;
/* USER CODE END MACADDRESS */
Disable PHY initialization inside HAL library (HAL_ETH_Init(&heth)
) by commenting out Phy
reset, autonegotation
HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
{
uint32_t tmpreg1 = 0U, phyreg = 0U;
uint32_t hclk = 60000000U;
uint32_t tickstart = 0U;
uint32_t err = ETH_SUCCESS;
/* Check the ETH peripheral state */
if(heth == NULL)
{
return HAL_ERROR;
}
/* Check parameters */
assert_param(IS_ETH_AUTONEGOTIATION(heth->Init.AutoNegotiation));
assert_param(IS_ETH_RX_MODE(heth->Init.RxMode));
assert_param(IS_ETH_CHECKSUM_MODE(heth->Init.ChecksumMode));
assert_param(IS_ETH_MEDIA_INTERFACE(heth->Init.MediaInterface));
if(heth->State == HAL_ETH_STATE_RESET)
{
/* Allocate lock resource and initialize it */
heth->Lock = HAL_UNLOCKED;
/* Init the low level hardware : GPIO, CLOCK, NVIC. */
HAL_ETH_MspInit(heth);
}
/* Select MII or RMII Mode*/
AFIO->MAPR &= ~(AFIO_MAPR_MII_RMII_SEL);
AFIO->MAPR |= (uint32_t)heth->Init.MediaInterface;
/* Ethernet Software reset */
/* Set the SWR bit: resets all MAC subsystem internal registers and logic */
/* After reset all the registers holds their respective reset values */
(heth->Instance)->DMABMR |= ETH_DMABMR_SR;
/* Get tick */
tickstart = HAL_GetTick();
/* Wait for software reset */
while (((heth->Instance)->DMABMR & ETH_DMABMR_SR) != (uint32_t)RESET)
{
/* Check for the Timeout */
if((HAL_GetTick() - tickstart ) > ETH_TIMEOUT_SWRESET)
{
heth->State= HAL_ETH_STATE_TIMEOUT;
/* Process Unlocked */
__HAL_UNLOCK(heth);
/* Note: The SWR is not performed if the ETH_RX_CLK or the ETH_TX_CLK are
not available, please check your external PHY or the IO configuration */
return HAL_TIMEOUT;
}
}
/*-------------------------------- MAC Initialization ----------------------*/
/* Get the ETHERNET MACMIIAR value */
tmpreg1 = (heth->Instance)->MACMIIAR;
/* Clear CSR Clock Range CR[2:0] bits */
tmpreg1 &= ETH_MACMIIAR_CR_MASK;
/* Get hclk frequency value */
hclk = HAL_RCC_GetHCLKFreq();
/* Set CR bits depending on hclk value */
if((hclk >= 20000000U)&&(hclk < 35000000U))
{
/* CSR Clock Range between 20-35 MHz */
tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV16;
}
else if((hclk >= 35000000U)&&(hclk < 60000000U))
{
/* CSR Clock Range between 35-60 MHz */
tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV26;
}
else
{
/* CSR Clock Range between 60-72 MHz */
tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV42;
}
/* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
(heth->Instance)->MACMIIAR = (uint32_t)tmpreg1;
/*-------------------- PHY initialization and configuration ----------------*/
/* Put the PHY in reset mode */
// if((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_RESET)) != HAL_OK)
// {
// /* In case of write timeout */
// err = ETH_ERROR;
//
// /* Config MAC and DMA */
// ETH_MACDMAConfig(heth, err);
//
// /* Set the ETH peripheral state to READY */
// heth->State = HAL_ETH_STATE_READY;
//
// /* Return HAL_ERROR */
// return HAL_ERROR;
// }
//
// /* Delay to assure PHY reset */
// HAL_Delay(PHY_RESET_DELAY);
//
// if((heth->Init).AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE)
// {
// /* Get tick */
// tickstart = HAL_GetTick();
//
// /* We wait for linked status */
// do
// {
// HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg);
//
// /* Check for the Timeout */
// if((HAL_GetTick() - tickstart ) > ETH_TIMEOUT_LINKED_STATE)
// {
// /* In case of write timeout */
// err = ETH_ERROR;
//
// /* Config MAC and DMA */
// ETH_MACDMAConfig(heth, err);
//
// heth->State= HAL_ETH_STATE_READY;
//
// /* Process Unlocked */
// __HAL_UNLOCK(heth);
//
// return HAL_TIMEOUT;
// }
// } while (((phyreg & PHY_LINKED_STATUS) != PHY_LINKED_STATUS));
//
//
// /* Enable Auto-Negotiation */
// if((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_AUTONEGOTIATION)) != HAL_OK)
// {
// /* In case of write timeout */
// err = ETH_ERROR;
//
// /* Config MAC and DMA */
// ETH_MACDMAConfig(heth, err);
//
// /* Set the ETH peripheral state to READY */
// heth->State = HAL_ETH_STATE_READY;
//
// /* Return HAL_ERROR */
// return HAL_ERROR;
// }
//
// /* Get tick */
// tickstart = HAL_GetTick();
//
// /* Wait until the auto-negotiation will be completed */
// do
// {
// HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg);
//
// /* Check for the Timeout */
// if((HAL_GetTick() - tickstart ) > ETH_TIMEOUT_AUTONEGO_COMPLETED)
// {
// /* In case of write timeout */
// err = ETH_ERROR;
//
// /* Config MAC and DMA */
// ETH_MACDMAConfig(heth, err);
//
// heth->State= HAL_ETH_STATE_READY;
//
// /* Process Unlocked */
// __HAL_UNLOCK(heth);
//
// return HAL_TIMEOUT;
// }
//
// } while (((phyreg & PHY_AUTONEGO_COMPLETE) != PHY_AUTONEGO_COMPLETE));
//
// /* Read the result of the auto-negotiation */
// if((HAL_ETH_ReadPHYRegister(heth, PHY_SR, &phyreg)) != HAL_OK)
// {
// /* In case of write timeout */
// err = ETH_ERROR;
//
// /* Config MAC and DMA */
// ETH_MACDMAConfig(heth, err);
//
// /* Set the ETH peripheral state to READY */
// heth->State = HAL_ETH_STATE_READY;
//
// /* Return HAL_ERROR */
// return HAL_ERROR;
// }
//
// /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
// if((phyreg & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
// {
// /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
// (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
// }
// else
// {
// /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
// (heth->Init).DuplexMode = ETH_MODE_HALFDUPLEX;
// }
// /* Configure the MAC with the speed fixed by the auto-negotiation process */
// if((phyreg & PHY_SPEED_STATUS) == PHY_SPEED_STATUS)
// {
// /* Set Ethernet speed to 10M following the auto-negotiation */
// (heth->Init).Speed = ETH_SPEED_10M;
// }
// else
// {
// /* Set Ethernet speed to 100M following the auto-negotiation */
// (heth->Init).Speed = ETH_SPEED_100M;
// }
// }
// else /* AutoNegotiation Disable */
// {
// /* Check parameters */
// assert_param(IS_ETH_SPEED(heth->Init.Speed));
// assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode));
//
// /* Set MAC Speed and Duplex Mode */
// if(HAL_ETH_WritePHYRegister(heth, PHY_BCR, ((uint16_t)((heth->Init).DuplexMode >> 3U) |
// (uint16_t)((heth->Init).Speed >> 1U))) != HAL_OK)
// {
// /* In case of write timeout */
// err = ETH_ERROR;
//
// /* Config MAC and DMA */
// ETH_MACDMAConfig(heth, err);
//
// /* Set the ETH peripheral state to READY */
// heth->State = HAL_ETH_STATE_READY;
//
// /* Return HAL_ERROR */
// return HAL_ERROR;
// }
//
// /* Delay to assure PHY configuration */
// HAL_Delay(PHY_CONFIG_DELAY);
// }
//
/* Config MAC and DMA */
ETH_MACDMAConfig(heth, err);
/* Set ETH HAL State to Ready */
heth->State= HAL_ETH_STATE_READY;
/* Return function status */
return HAL_OK;
}
Voila, should be able to ping board!