cancel
Showing results for 
Search instead for 
Did you mean: 

stm32h5xx Ethernet MDIO clause 45

shonz
Associate

Hi,

I working with nucleo-h563zi.
I try to use MDIO as Clause 45, copy HAL_ETH_WritePHYRegister, HAL_ETH_ReadPHYRegister and change it's to fit for Clause 45.

#define ETH_MACMDIOAR_MOC_ADD_Pos                     (2U)
#define ETH_MACMDIOAR_MOC_ADD_Msk                     (0x0UL << ETH_MACMDIOAR_MOC_ADD_Pos) /*!< 0x00000000 */
#define ETH_MACMDIOAR_MOC_ADD                         ETH_MACMDIOAR_MOC_ADD_Msk /* Write */
#define ETH_MACMDIOAR_MOC_WR_Pos                      (2U)
#define ETH_MACMDIOAR_MOC_WR_Msk                      (0x1UL << ETH_MACMDIOAR_MOC_WR_Pos) /*!< 0x00000004 */
#define ETH_MACMDIOAR_MOC_WR                          ETH_MACMDIOAR_MOC_WR_Msk /* Write */
#define ETH_MACMDIOAR_MOC_RD_ADD_Pos                  (2U)
#define ETH_MACMDIOAR_MOC_RD_ADD_Msk                  (0x2UL << ETH_MACMDIOAR_MOC_RD_ADD_Pos) /*!< 0x00000008 */
#define ETH_MACMDIOAR_MOC_RD_ADD                      ETH_MACMDIOAR_MOC_RD_ADD_Msk /* read + addres */
#define ETH_MACMDIOAR_MOC_RD_Pos                      (2U)
#define ETH_MACMDIOAR_MOC_RD_Msk                      (0x3UL << ETH_MACMDIOAR_MOC_RD_Pos) /*!< 0x0000000C */
#define ETH_MACMDIOAR_MOC_RD                          ETH_MACMDIOAR_MOC_RD_Msk /* Read */

/**
 * @brief  Reads a PHY register using Clause-45 MDIO.
 * @PAram  heth:       pointer to ETH handle
 * @PAram  PHYAddr:    PHY port address (0-31)
 * @PAram  PHYReg:     combined device/register address (devad in [20:16], reg in [15:0])
 * @PAram  pRegValue:  pointer to store the 16-bit read value
 * @retval HAL status
 */
HAL_StatusTypeDef HAL_ETH_ReadPHYRegister_Clause45(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
		uint32_t *pRegValue)
{
    uint32_t tickstart;
    uint32_t tmpreg;

    if (pRegValue == NULL || heth == NULL) {
        return HAL_ERROR;
    }

    uint32_t devaddr = (PHYReg >> 16U) & 0x1FU;  /* device address (DEVAD) */
    uint32_t regaddr = PHYReg & 0xFFFFU;          /* register address       */

    /* Check for the Busy flag */
    if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET)
    {
        return HAL_ERROR;
    }

    /* Write register address into MACMDIODR RA field for Clause-45 */
    WRITE_REG(heth->Instance->MACMDIODR, (regaddr << 16U));

    /* Get the MACMDIOAR value */
    WRITE_REG(tmpreg, heth->Instance->MACMDIOAR);

    /* Prepare the MDIO Address Register value
       - Set the PHY device address
       - Set the device type (RDA field = devaddr for C45)
       - Set the read mode
       - Set C45E bit
       - Set the MII Busy bit */
    MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21));
    MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (devaddr << 16));
    MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_RD_ADD);
    SET_BIT(tmpreg, ETH_MACMDIOAR_C45E);
    SET_BIT(tmpreg, ETH_MACMDIOAR_MB);

    /* Write the result value into the MDIO Address register */
    WRITE_REG(heth->Instance->MACMDIOAR, tmpreg);

    tickstart = HAL_GetTick();

    /* Wait for the Busy flag */
    while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U)
    {
        if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT))
        {
            return HAL_ERROR;
        }
    }

    /* Get MACMDIODR value */
    WRITE_REG(*pRegValue, heth->Instance->MACMDIODR);
    printf("HAL_ETH_ReadPHYRegister_Clause45: val=0x%08lX\n\r", *pRegValue);

    return HAL_OK;
}

/**
 * @brief  Writes a PHY register using Clause-45 MDIO.
 * @PAram  heth:      pointer to ETH handle
 * @PAram  PHYAddr:   PHY port address (0-31)
 * @PAram  PHYReg:    combined device/register address (devad in [20:16], reg in [15:0])
 * @PAram  RegValue:  16-bit value to write
 * @retval HAL status
 */
HAL_StatusTypeDef HAL_ETH_WritePHYRegister_Clause45(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
		uint32_t RegValue)
{
    uint32_t tickstart;
    uint32_t tmpreg;

    if (heth == NULL) {
        return HAL_ERROR;
    }

    uint32_t devaddr = (PHYReg >> 16U) & 0x1FU;  /* device address */
    uint32_t regaddr = PHYReg & 0xFFFFU;          /* register address */

    /* Check for the Busy flag */
    if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET)
    {
        return HAL_ERROR;
    }

    /* Get the MACMDIOAR value */
    WRITE_REG(tmpreg, heth->Instance->MACMDIOAR);

    /* Prepare the MDIO Address Register value */
    MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21));
    MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (devaddr << 16));
    MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_WR);
    SET_BIT(tmpreg, ETH_MACMDIOAR_C45E);
    SET_BIT(tmpreg, ETH_MACMDIOAR_MB);

    /* Give the value to the MII data register (RA + MD for C45) */
    WRITE_REG(heth->Instance->MACMDIODR, (regaddr << 16U) | (uint16_t)RegValue);

    /* Write the result value into the MII Address register */
    WRITE_REG(heth->Instance->MACMDIOAR, tmpreg);

    tickstart = HAL_GetTick();

    /* Wait for the Busy flag */
    while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U)
    {
        if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT))
        {
            return HAL_ERROR;
        }
    }

    return HAL_OK;
}

 Write function working well, but read function don't get any data in heth->Instance->MACMDIODR.
This is the print that i get "HAL_ETH_ReadPHYRegister_Clause45: val=0x00070000" ,
but its need to be "HAL_ETH_ReadPHYRegister_Clause45: val=0x00070100"
Can see in the photo below

shonz_0-1780394520247.png

This photo is from logic that connected in PA2(MDIO),PC1(MDC)



0 REPLIES 0
Announcement

We’re moving the ST Community to a new platform to give you a better and more reliable community experience.