RT1050_FreeRTOS_Hello/component/phy/mdio/enet/fsl_enet_mdio.c

134 lines
4.2 KiB
C

/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_enet_mdio.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
static void ENET_MDIO_Init(mdio_handle_t *handle);
static status_t ENET_MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data);
static status_t ENET_MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr);
/*******************************************************************************
* Variables
******************************************************************************/
const mdio_operations_t enet_ops = {.mdioInit = ENET_MDIO_Init,
.mdioWrite = ENET_MDIO_Write,
.mdioRead = ENET_MDIO_Read,
.mdioWriteExt = NULL,
.mdioReadExt = NULL};
/*******************************************************************************
* Code
******************************************************************************/
static void ENET_MDIO_Init(mdio_handle_t *handle)
{
mdio_resource_t *resource = (mdio_resource_t *)&handle->resource;
ENET_Type *base = (ENET_Type *)resource->base;
uint32_t instance = ENET_GetInstance(base);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Set SMI first. */
(void)CLOCK_EnableClock(s_enetClock[instance]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
ENET_SetSMI(base, resource->csrClock_Hz, false);
}
static status_t ENET_MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data)
{
mdio_resource_t *resource = (mdio_resource_t *)&handle->resource;
ENET_Type *base = (ENET_Type *)resource->base;
status_t result = kStatus_Success;
#ifdef MDIO_TIMEOUT_COUNT
uint32_t counter;
#endif
/* Clear the SMI interrupt event. */
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
/* Starts a SMI write command. */
ENET_StartSMIWrite(base, phyAddr, devAddr, kENET_MiiWriteValidFrame, data);
/* Wait for SMI complete. */
#ifdef MDIO_TIMEOUT_COUNT
for (counter = MDIO_TIMEOUT_COUNT; counter > 0U; counter--)
{
if (ENET_EIR_MII_MASK == (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK))
{
break;
}
}
/* Check for timeout. */
if (0U == counter)
{
result = kStatus_PHY_SMIVisitTimeout;
}
#else
while (ENET_EIR_MII_MASK != (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK))
{
}
#endif
/* Clear SMI interrupt event. */
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
return result;
}
static status_t ENET_MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr)
{
assert(dataPtr);
mdio_resource_t *resource = (mdio_resource_t *)&handle->resource;
ENET_Type *base = (ENET_Type *)resource->base;
#ifdef MDIO_TIMEOUT_COUNT
uint32_t counter;
#endif
/* Clear the SMI interrupt event. */
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
/* Starts a SMI read command operation. */
ENET_StartSMIRead(base, phyAddr, devAddr, kENET_MiiReadValidFrame);
/* Wait for SMI complete. */
#ifdef MDIO_TIMEOUT_COUNT
for (counter = MDIO_TIMEOUT_COUNT; counter > 0U; counter--)
{
if (ENET_EIR_MII_MASK == (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK))
{
break;
}
}
/* Check for timeout. */
if (0U == counter)
{
return kStatus_PHY_SMIVisitTimeout;
}
#else
while (ENET_EIR_MII_MASK != (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK))
{
}
#endif
/* Get data from SMI register. */
*dataPtr = ENET_ReadSMIData(base);
/* Clear SMI interrupt event. */
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
return kStatus_Success;
}