工程提交

This commit is contained in:
2026-03-31 15:46:04 +08:00
parent 75f512a5b4
commit da4e944bca
2841 changed files with 4822938 additions and 1 deletions

View File

@@ -0,0 +1,6 @@
This software component is provided to you as part of a software package and
applicable license terms are in the Package_license file. If you received this
software component outside of a package or without applicable license terms,
the terms of the BSD-3-Clause license shall apply.
You may obtain a copy of the BSD-3-Clause at:
https://opensource.org/licenses/BSD-3-Clause

View File

@@ -0,0 +1,613 @@
/**
******************************************************************************
* @file lan8742.c
* @author MCD Application Team
* @brief This file provides a set of functions needed to manage the LAN742
* PHY devices.
******************************************************************************
* @attention
*
* Copyright (c) 2017 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "lan8742.h"
/** @addtogroup BSP
* @{
*/
/** @addtogroup Component
* @{
*/
/** @defgroup LAN8742 LAN8742
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/** @defgroup LAN8742_Private_Defines LAN8742 Private Defines
* @{
*/
#define LAN8742_MAX_DEV_ADDR ((uint32_t)31U)
/**
* @}
*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup LAN8742_Private_Functions LAN8742 Private Functions
* @{
*/
/**
* @brief Register IO functions to component object
* @param pObj: device object of LAN8742_Object_t.
* @param ioctx: holds device IO functions.
* @retval LAN8742_STATUS_OK if OK
* LAN8742_STATUS_ERROR if missing mandatory function
*/
int32_t LAN8742_RegisterBusIO(lan8742_Object_t *pObj, lan8742_IOCtx_t *ioctx)
{
if(!pObj || !ioctx->ReadReg || !ioctx->WriteReg || !ioctx->GetTick)
{
return LAN8742_STATUS_ERROR;
}
pObj->IO.Init = ioctx->Init;
pObj->IO.DeInit = ioctx->DeInit;
pObj->IO.ReadReg = ioctx->ReadReg;
pObj->IO.WriteReg = ioctx->WriteReg;
pObj->IO.GetTick = ioctx->GetTick;
return LAN8742_STATUS_OK;
}
/**
* @brief Initialize the lan8742 and configure the needed hardware resources
* @param pObj: device object LAN8742_Object_t.
* @retval LAN8742_STATUS_OK if OK
* LAN8742_STATUS_ADDRESS_ERROR if cannot find device address
* LAN8742_STATUS_READ_ERROR if cannot read register
*/
int32_t LAN8742_Init(lan8742_Object_t *pObj)
{
uint32_t regvalue = 0, addr = 0;
int32_t status = LAN8742_STATUS_OK;
if(pObj->Is_Initialized == 0)
{
if(pObj->IO.Init != 0)
{
/* GPIO and Clocks initialization */
pObj->IO.Init();
}
/* for later check */
pObj->DevAddr = LAN8742_MAX_DEV_ADDR + 1;
/* Get the device address from special mode register */
for(addr = 0; addr <= LAN8742_MAX_DEV_ADDR; addr ++)
{
if(pObj->IO.ReadReg(addr, LAN8742_SMR, &regvalue) < 0)
{
status = LAN8742_STATUS_READ_ERROR;
/* Can't read from this device address
continue with next address */
continue;
}
if((regvalue & LAN8742_SMR_PHY_ADDR) == addr)
{
pObj->DevAddr = addr;
status = LAN8742_STATUS_OK;
break;
}
}
if(pObj->DevAddr > LAN8742_MAX_DEV_ADDR)
{
status = LAN8742_STATUS_ADDRESS_ERROR;
}
/* if device address is matched */
if(status == LAN8742_STATUS_OK)
{
pObj->Is_Initialized = 1;
}
}
return status;
}
/**
* @brief De-Initialize the lan8742 and it's hardware resources
* @param pObj: device object LAN8742_Object_t.
* @retval None
*/
int32_t LAN8742_DeInit(lan8742_Object_t *pObj)
{
if(pObj->Is_Initialized)
{
if(pObj->IO.DeInit != 0)
{
if(pObj->IO.DeInit() < 0)
{
return LAN8742_STATUS_ERROR;
}
}
pObj->Is_Initialized = 0;
}
return LAN8742_STATUS_OK;
}
/**
* @brief Disable the LAN8742 power down mode.
* @param pObj: device object LAN8742_Object_t.
* @retval LAN8742_STATUS_OK if OK
* LAN8742_STATUS_READ_ERROR if cannot read register
* LAN8742_STATUS_WRITE_ERROR if cannot write to register
*/
int32_t LAN8742_DisablePowerDownMode(lan8742_Object_t *pObj)
{
uint32_t readval = 0;
int32_t status = LAN8742_STATUS_OK;
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) >= 0)
{
readval &= ~LAN8742_BCR_POWER_DOWN;
/* Apply configuration */
if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, readval) < 0)
{
status = LAN8742_STATUS_WRITE_ERROR;
}
}
else
{
status = LAN8742_STATUS_READ_ERROR;
}
return status;
}
/**
* @brief Enable the LAN8742 power down mode.
* @param pObj: device object LAN8742_Object_t.
* @retval LAN8742_STATUS_OK if OK
* LAN8742_STATUS_READ_ERROR if cannot read register
* LAN8742_STATUS_WRITE_ERROR if cannot write to register
*/
int32_t LAN8742_EnablePowerDownMode(lan8742_Object_t *pObj)
{
uint32_t readval = 0;
int32_t status = LAN8742_STATUS_OK;
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) >= 0)
{
readval |= LAN8742_BCR_POWER_DOWN;
/* Apply configuration */
if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, readval) < 0)
{
status = LAN8742_STATUS_WRITE_ERROR;
}
}
else
{
status = LAN8742_STATUS_READ_ERROR;
}
return status;
}
/**
* @brief Start the auto negotiation process.
* @param pObj: device object LAN8742_Object_t.
* @retval LAN8742_STATUS_OK if OK
* LAN8742_STATUS_READ_ERROR if cannot read register
* LAN8742_STATUS_WRITE_ERROR if cannot write to register
*/
int32_t LAN8742_StartAutoNego(lan8742_Object_t *pObj)
{
uint32_t readval = 0;
int32_t status = LAN8742_STATUS_OK;
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) >= 0)
{
readval |= LAN8742_BCR_AUTONEGO_EN;
/* Apply configuration */
if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, readval) < 0)
{
status = LAN8742_STATUS_WRITE_ERROR;
}
}
else
{
status = LAN8742_STATUS_READ_ERROR;
}
return status;
}
/**
* @brief Get the link state of LAN8742 device.
* @param pObj: Pointer to device object.
* @param pLinkState: Pointer to link state
* @retval LAN8742_STATUS_LINK_DOWN if link is down
* LAN8742_STATUS_AUTONEGO_NOTDONE if Auto nego not completed
* LAN8742_STATUS_100MBITS_FULLDUPLEX if 100Mb/s FD
* LAN8742_STATUS_100MBITS_HALFDUPLEX if 100Mb/s HD
* LAN8742_STATUS_10MBITS_FULLDUPLEX if 10Mb/s FD
* LAN8742_STATUS_10MBITS_HALFDUPLEX if 10Mb/s HD
* LAN8742_STATUS_READ_ERROR if cannot read register
* LAN8742_STATUS_WRITE_ERROR if cannot write to register
*/
int32_t LAN8742_GetLinkState(lan8742_Object_t *pObj)
{
uint32_t readval = 0;
/* Read Status register */
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval) < 0)
{
return LAN8742_STATUS_READ_ERROR;
}
/* Read Status register again */
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval) < 0)
{
return LAN8742_STATUS_READ_ERROR;
}
if((readval & LAN8742_BSR_LINK_STATUS) == 0)
{
/* Return Link Down status */
return LAN8742_STATUS_LINK_DOWN;
}
/* Check Auto negotiation */
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) < 0)
{
return LAN8742_STATUS_READ_ERROR;
}
if((readval & LAN8742_BCR_AUTONEGO_EN) != LAN8742_BCR_AUTONEGO_EN)
{
if(((readval & LAN8742_BCR_SPEED_SELECT) == LAN8742_BCR_SPEED_SELECT) && ((readval & LAN8742_BCR_DUPLEX_MODE) == LAN8742_BCR_DUPLEX_MODE))
{
return LAN8742_STATUS_100MBITS_FULLDUPLEX;
}
else if ((readval & LAN8742_BCR_SPEED_SELECT) == LAN8742_BCR_SPEED_SELECT)
{
return LAN8742_STATUS_100MBITS_HALFDUPLEX;
}
else if ((readval & LAN8742_BCR_DUPLEX_MODE) == LAN8742_BCR_DUPLEX_MODE)
{
return LAN8742_STATUS_10MBITS_FULLDUPLEX;
}
else
{
return LAN8742_STATUS_10MBITS_HALFDUPLEX;
}
}
else /* Auto Nego enabled */
{
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_PHYSCSR, &readval) < 0)
{
return LAN8742_STATUS_READ_ERROR;
}
/* Check if auto nego not done */
if((readval & LAN8742_PHYSCSR_AUTONEGO_DONE) == 0)
{
return LAN8742_STATUS_AUTONEGO_NOTDONE;
}
if((readval & LAN8742_PHYSCSR_HCDSPEEDMASK) == LAN8742_PHYSCSR_100BTX_FD)
{
return LAN8742_STATUS_100MBITS_FULLDUPLEX;
}
else if ((readval & LAN8742_PHYSCSR_HCDSPEEDMASK) == LAN8742_PHYSCSR_100BTX_HD)
{
return LAN8742_STATUS_100MBITS_HALFDUPLEX;
}
else if ((readval & LAN8742_PHYSCSR_HCDSPEEDMASK) == LAN8742_PHYSCSR_10BT_FD)
{
return LAN8742_STATUS_10MBITS_FULLDUPLEX;
}
else
{
return LAN8742_STATUS_10MBITS_HALFDUPLEX;
}
}
}
/**
* @brief Set the link state of LAN8742 device.
* @param pObj: Pointer to device object.
* @param pLinkState: link state can be one of the following
* LAN8742_STATUS_100MBITS_FULLDUPLEX if 100Mb/s FD
* LAN8742_STATUS_100MBITS_HALFDUPLEX if 100Mb/s HD
* LAN8742_STATUS_10MBITS_FULLDUPLEX if 10Mb/s FD
* LAN8742_STATUS_10MBITS_HALFDUPLEX if 10Mb/s HD
* @retval LAN8742_STATUS_OK if OK
* LAN8742_STATUS_ERROR if parameter error
* LAN8742_STATUS_READ_ERROR if cannot read register
* LAN8742_STATUS_WRITE_ERROR if cannot write to register
*/
int32_t LAN8742_SetLinkState(lan8742_Object_t *pObj, uint32_t LinkState)
{
uint32_t bcrvalue = 0;
int32_t status = LAN8742_STATUS_OK;
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &bcrvalue) >= 0)
{
/* Disable link config (Auto nego, speed and duplex) */
bcrvalue &= ~(LAN8742_BCR_AUTONEGO_EN | LAN8742_BCR_SPEED_SELECT | LAN8742_BCR_DUPLEX_MODE);
if(LinkState == LAN8742_STATUS_100MBITS_FULLDUPLEX)
{
bcrvalue |= (LAN8742_BCR_SPEED_SELECT | LAN8742_BCR_DUPLEX_MODE);
}
else if (LinkState == LAN8742_STATUS_100MBITS_HALFDUPLEX)
{
bcrvalue |= LAN8742_BCR_SPEED_SELECT;
}
else if (LinkState == LAN8742_STATUS_10MBITS_FULLDUPLEX)
{
bcrvalue |= LAN8742_BCR_DUPLEX_MODE;
}
else
{
/* Wrong link status parameter */
status = LAN8742_STATUS_ERROR;
}
}
else
{
status = LAN8742_STATUS_READ_ERROR;
}
if(status == LAN8742_STATUS_OK)
{
/* Apply configuration */
if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, bcrvalue) < 0)
{
status = LAN8742_STATUS_WRITE_ERROR;
}
}
return status;
}
/**
* @brief Enable loopback mode.
* @param pObj: Pointer to device object.
* @retval LAN8742_STATUS_OK if OK
* LAN8742_STATUS_READ_ERROR if cannot read register
* LAN8742_STATUS_WRITE_ERROR if cannot write to register
*/
int32_t LAN8742_EnableLoopbackMode(lan8742_Object_t *pObj)
{
uint32_t readval = 0;
int32_t status = LAN8742_STATUS_OK;
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) >= 0)
{
readval |= LAN8742_BCR_LOOPBACK;
/* Apply configuration */
if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, readval) < 0)
{
status = LAN8742_STATUS_WRITE_ERROR;
}
}
else
{
status = LAN8742_STATUS_READ_ERROR;
}
return status;
}
/**
* @brief Disable loopback mode.
* @param pObj: Pointer to device object.
* @retval LAN8742_STATUS_OK if OK
* LAN8742_STATUS_READ_ERROR if cannot read register
* LAN8742_STATUS_WRITE_ERROR if cannot write to register
*/
int32_t LAN8742_DisableLoopbackMode(lan8742_Object_t *pObj)
{
uint32_t readval = 0;
int32_t status = LAN8742_STATUS_OK;
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) >= 0)
{
readval &= ~LAN8742_BCR_LOOPBACK;
/* Apply configuration */
if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, readval) < 0)
{
status = LAN8742_STATUS_WRITE_ERROR;
}
}
else
{
status = LAN8742_STATUS_READ_ERROR;
}
return status;
}
/**
* @brief Enable IT source.
* @param pObj: Pointer to device object.
* @param Interrupt: IT source to be enabled
* should be a value or a combination of the following:
* LAN8742_WOL_IT
* LAN8742_ENERGYON_IT
* LAN8742_AUTONEGO_COMPLETE_IT
* LAN8742_REMOTE_FAULT_IT
* LAN8742_LINK_DOWN_IT
* LAN8742_AUTONEGO_LP_ACK_IT
* LAN8742_PARALLEL_DETECTION_FAULT_IT
* LAN8742_AUTONEGO_PAGE_RECEIVED_IT
* @retval LAN8742_STATUS_OK if OK
* LAN8742_STATUS_READ_ERROR if cannot read register
* LAN8742_STATUS_WRITE_ERROR if cannot write to register
*/
int32_t LAN8742_EnableIT(lan8742_Object_t *pObj, uint32_t Interrupt)
{
uint32_t readval = 0;
int32_t status = LAN8742_STATUS_OK;
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_IMR, &readval) >= 0)
{
readval |= Interrupt;
/* Apply configuration */
if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_IMR, readval) < 0)
{
status = LAN8742_STATUS_WRITE_ERROR;
}
}
else
{
status = LAN8742_STATUS_READ_ERROR;
}
return status;
}
/**
* @brief Disable IT source.
* @param pObj: Pointer to device object.
* @param Interrupt: IT source to be disabled
* should be a value or a combination of the following:
* LAN8742_WOL_IT
* LAN8742_ENERGYON_IT
* LAN8742_AUTONEGO_COMPLETE_IT
* LAN8742_REMOTE_FAULT_IT
* LAN8742_LINK_DOWN_IT
* LAN8742_AUTONEGO_LP_ACK_IT
* LAN8742_PARALLEL_DETECTION_FAULT_IT
* LAN8742_AUTONEGO_PAGE_RECEIVED_IT
* @retval LAN8742_STATUS_OK if OK
* LAN8742_STATUS_READ_ERROR if cannot read register
* LAN8742_STATUS_WRITE_ERROR if cannot write to register
*/
int32_t LAN8742_DisableIT(lan8742_Object_t *pObj, uint32_t Interrupt)
{
uint32_t readval = 0;
int32_t status = LAN8742_STATUS_OK;
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_IMR, &readval) >= 0)
{
readval &= ~Interrupt;
/* Apply configuration */
if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_IMR, readval) < 0)
{
status = LAN8742_STATUS_WRITE_ERROR;
}
}
else
{
status = LAN8742_STATUS_READ_ERROR;
}
return status;
}
/**
* @brief Clear IT flag.
* @param pObj: Pointer to device object.
* @param Interrupt: IT flag to be cleared
* should be a value or a combination of the following:
* LAN8742_WOL_IT
* LAN8742_ENERGYON_IT
* LAN8742_AUTONEGO_COMPLETE_IT
* LAN8742_REMOTE_FAULT_IT
* LAN8742_LINK_DOWN_IT
* LAN8742_AUTONEGO_LP_ACK_IT
* LAN8742_PARALLEL_DETECTION_FAULT_IT
* LAN8742_AUTONEGO_PAGE_RECEIVED_IT
* @retval LAN8742_STATUS_OK if OK
* LAN8742_STATUS_READ_ERROR if cannot read register
*/
int32_t LAN8742_ClearIT(lan8742_Object_t *pObj, uint32_t Interrupt)
{
uint32_t readval = 0;
int32_t status = LAN8742_STATUS_OK;
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_ISFR, &readval) < 0)
{
status = LAN8742_STATUS_READ_ERROR;
}
return status;
}
/**
* @brief Get IT Flag status.
* @param pObj: Pointer to device object.
* @param Interrupt: IT Flag to be checked,
* should be a value or a combination of the following:
* LAN8742_WOL_IT
* LAN8742_ENERGYON_IT
* LAN8742_AUTONEGO_COMPLETE_IT
* LAN8742_REMOTE_FAULT_IT
* LAN8742_LINK_DOWN_IT
* LAN8742_AUTONEGO_LP_ACK_IT
* LAN8742_PARALLEL_DETECTION_FAULT_IT
* LAN8742_AUTONEGO_PAGE_RECEIVED_IT
* @retval 1 IT flag is SET
* 0 IT flag is RESET
* LAN8742_STATUS_READ_ERROR if cannot read register
*/
int32_t LAN8742_GetITStatus(lan8742_Object_t *pObj, uint32_t Interrupt)
{
uint32_t readval = 0;
int32_t status = 0;
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_ISFR, &readval) >= 0)
{
status = ((readval & Interrupt) == Interrupt);
}
else
{
status = LAN8742_STATUS_READ_ERROR;
}
return status;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,446 @@
/**
******************************************************************************
* @file lan8742.h
* @author MCD Application Team
* @brief This file contains all the functions prototypes for the
* lan8742.c PHY driver.
******************************************************************************
* @attention
*
* Copyright (c) 2017 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef LAN8742_H
#define LAN8742_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
/** @addtogroup BSP
* @{
*/
/** @addtogroup Component
* @{
*/
/** @defgroup LAN8742
* @{
*/
/* Exported constants --------------------------------------------------------*/
/** @defgroup LAN8742_Exported_Constants LAN8742 Exported Constants
* @{
*/
/** @defgroup LAN8742_Registers_Mapping LAN8742 Registers Mapping
* @{
*/
#define LAN8742_BCR ((uint16_t)0x0000U)
#define LAN8742_BSR ((uint16_t)0x0001U)
#define LAN8742_PHYI1R ((uint16_t)0x0002U)
#define LAN8742_PHYI2R ((uint16_t)0x0003U)
#define LAN8742_ANAR ((uint16_t)0x0004U)
#define LAN8742_ANLPAR ((uint16_t)0x0005U)
#define LAN8742_ANER ((uint16_t)0x0006U)
#define LAN8742_ANNPTR ((uint16_t)0x0007U)
#define LAN8742_ANNPRR ((uint16_t)0x0008U)
#define LAN8742_MMDACR ((uint16_t)0x000DU)
#define LAN8742_MMDAADR ((uint16_t)0x000EU)
#define LAN8742_ENCTR ((uint16_t)0x0010U)
#define LAN8742_MCSR ((uint16_t)0x0011U)
#define LAN8742_SMR ((uint16_t)0x0012U)
#define LAN8742_TPDCR ((uint16_t)0x0018U)
#define LAN8742_TCSR ((uint16_t)0x0019U)
#define LAN8742_SECR ((uint16_t)0x001AU)
#define LAN8742_SCSIR ((uint16_t)0x001BU)
#define LAN8742_CLR ((uint16_t)0x001CU)
#define LAN8742_ISFR ((uint16_t)0x001DU)
#define LAN8742_IMR ((uint16_t)0x001EU)
#define LAN8742_PHYSCSR ((uint16_t)0x001FU)
/**
* @}
*/
/** @defgroup LAN8742_BCR_Bit_Definition LAN8742 BCR Bit Definition
* @{
*/
#define LAN8742_BCR_SOFT_RESET ((uint16_t)0x8000U)
#define LAN8742_BCR_LOOPBACK ((uint16_t)0x4000U)
#define LAN8742_BCR_SPEED_SELECT ((uint16_t)0x2000U)
#define LAN8742_BCR_AUTONEGO_EN ((uint16_t)0x1000U)
#define LAN8742_BCR_POWER_DOWN ((uint16_t)0x0800U)
#define LAN8742_BCR_ISOLATE ((uint16_t)0x0400U)
#define LAN8742_BCR_RESTART_AUTONEGO ((uint16_t)0x0200U)
#define LAN8742_BCR_DUPLEX_MODE ((uint16_t)0x0100U)
/**
* @}
*/
/** @defgroup LAN8742_BSR_Bit_Definition LAN8742 BSR Bit Definition
* @{
*/
#define LAN8742_BSR_100BASE_T4 ((uint16_t)0x8000U)
#define LAN8742_BSR_100BASE_TX_FD ((uint16_t)0x4000U)
#define LAN8742_BSR_100BASE_TX_HD ((uint16_t)0x2000U)
#define LAN8742_BSR_10BASE_T_FD ((uint16_t)0x1000U)
#define LAN8742_BSR_10BASE_T_HD ((uint16_t)0x0800U)
#define LAN8742_BSR_100BASE_T2_FD ((uint16_t)0x0400U)
#define LAN8742_BSR_100BASE_T2_HD ((uint16_t)0x0200U)
#define LAN8742_BSR_EXTENDED_STATUS ((uint16_t)0x0100U)
#define LAN8742_BSR_AUTONEGO_CPLT ((uint16_t)0x0020U)
#define LAN8742_BSR_REMOTE_FAULT ((uint16_t)0x0010U)
#define LAN8742_BSR_AUTONEGO_ABILITY ((uint16_t)0x0008U)
#define LAN8742_BSR_LINK_STATUS ((uint16_t)0x0004U)
#define LAN8742_BSR_JABBER_DETECT ((uint16_t)0x0002U)
#define LAN8742_BSR_EXTENDED_CAP ((uint16_t)0x0001U)
/**
* @}
*/
/** @defgroup LAN8742_PHYI1R_Bit_Definition LAN8742 PHYI1R Bit Definition
* @{
*/
#define LAN8742_PHYI1R_OUI_3_18 ((uint16_t)0xFFFFU)
/**
* @}
*/
/** @defgroup LAN8742_PHYI2R_Bit_Definition LAN8742 PHYI2R Bit Definition
* @{
*/
#define LAN8742_PHYI2R_OUI_19_24 ((uint16_t)0xFC00U)
#define LAN8742_PHYI2R_MODEL_NBR ((uint16_t)0x03F0U)
#define LAN8742_PHYI2R_REVISION_NBR ((uint16_t)0x000FU)
/**
* @}
*/
/** @defgroup LAN8742_ANAR_Bit_Definition LAN8742 ANAR Bit Definition
* @{
*/
#define LAN8742_ANAR_NEXT_PAGE ((uint16_t)0x8000U)
#define LAN8742_ANAR_REMOTE_FAULT ((uint16_t)0x2000U)
#define LAN8742_ANAR_PAUSE_OPERATION ((uint16_t)0x0C00U)
#define LAN8742_ANAR_PO_NOPAUSE ((uint16_t)0x0000U)
#define LAN8742_ANAR_PO_SYMMETRIC_PAUSE ((uint16_t)0x0400U)
#define LAN8742_ANAR_PO_ASYMMETRIC_PAUSE ((uint16_t)0x0800U)
#define LAN8742_ANAR_PO_ADVERTISE_SUPPORT ((uint16_t)0x0C00U)
#define LAN8742_ANAR_100BASE_TX_FD ((uint16_t)0x0100U)
#define LAN8742_ANAR_100BASE_TX ((uint16_t)0x0080U)
#define LAN8742_ANAR_10BASE_T_FD ((uint16_t)0x0040U)
#define LAN8742_ANAR_10BASE_T ((uint16_t)0x0020U)
#define LAN8742_ANAR_SELECTOR_FIELD ((uint16_t)0x000FU)
/**
* @}
*/
/** @defgroup LAN8742_ANLPAR_Bit_Definition LAN8742 ANLPAR Bit Definition
* @{
*/
#define LAN8742_ANLPAR_NEXT_PAGE ((uint16_t)0x8000U)
#define LAN8742_ANLPAR_REMOTE_FAULT ((uint16_t)0x2000U)
#define LAN8742_ANLPAR_PAUSE_OPERATION ((uint16_t)0x0C00U)
#define LAN8742_ANLPAR_PO_NOPAUSE ((uint16_t)0x0000U)
#define LAN8742_ANLPAR_PO_SYMMETRIC_PAUSE ((uint16_t)0x0400U)
#define LAN8742_ANLPAR_PO_ASYMMETRIC_PAUSE ((uint16_t)0x0800U)
#define LAN8742_ANLPAR_PO_ADVERTISE_SUPPORT ((uint16_t)0x0C00U)
#define LAN8742_ANLPAR_100BASE_TX_FD ((uint16_t)0x0100U)
#define LAN8742_ANLPAR_100BASE_TX ((uint16_t)0x0080U)
#define LAN8742_ANLPAR_10BASE_T_FD ((uint16_t)0x0040U)
#define LAN8742_ANLPAR_10BASE_T ((uint16_t)0x0020U)
#define LAN8742_ANLPAR_SELECTOR_FIELD ((uint16_t)0x000FU)
/**
* @}
*/
/** @defgroup LAN8742_ANER_Bit_Definition LAN8742 ANER Bit Definition
* @{
*/
#define LAN8742_ANER_RX_NP_LOCATION_ABLE ((uint16_t)0x0040U)
#define LAN8742_ANER_RX_NP_STORAGE_LOCATION ((uint16_t)0x0020U)
#define LAN8742_ANER_PARALLEL_DETECT_FAULT ((uint16_t)0x0010U)
#define LAN8742_ANER_LP_NP_ABLE ((uint16_t)0x0008U)
#define LAN8742_ANER_NP_ABLE ((uint16_t)0x0004U)
#define LAN8742_ANER_PAGE_RECEIVED ((uint16_t)0x0002U)
#define LAN8742_ANER_LP_AUTONEG_ABLE ((uint16_t)0x0001U)
/**
* @}
*/
/** @defgroup LAN8742_ANNPTR_Bit_Definition LAN8742 ANNPTR Bit Definition
* @{
*/
#define LAN8742_ANNPTR_NEXT_PAGE ((uint16_t)0x8000U)
#define LAN8742_ANNPTR_MESSAGE_PAGE ((uint16_t)0x2000U)
#define LAN8742_ANNPTR_ACK2 ((uint16_t)0x1000U)
#define LAN8742_ANNPTR_TOGGLE ((uint16_t)0x0800U)
#define LAN8742_ANNPTR_MESSAGGE_CODE ((uint16_t)0x07FFU)
/**
* @}
*/
/** @defgroup LAN8742_ANNPRR_Bit_Definition LAN8742 ANNPRR Bit Definition
* @{
*/
#define LAN8742_ANNPTR_NEXT_PAGE ((uint16_t)0x8000U)
#define LAN8742_ANNPRR_ACK ((uint16_t)0x4000U)
#define LAN8742_ANNPRR_MESSAGE_PAGE ((uint16_t)0x2000U)
#define LAN8742_ANNPRR_ACK2 ((uint16_t)0x1000U)
#define LAN8742_ANNPRR_TOGGLE ((uint16_t)0x0800U)
#define LAN8742_ANNPRR_MESSAGGE_CODE ((uint16_t)0x07FFU)
/**
* @}
*/
/** @defgroup LAN8742_MMDACR_Bit_Definition LAN8742 MMDACR Bit Definition
* @{
*/
#define LAN8742_MMDACR_MMD_FUNCTION ((uint16_t)0xC000U)
#define LAN8742_MMDACR_MMD_FUNCTION_ADDR ((uint16_t)0x0000U)
#define LAN8742_MMDACR_MMD_FUNCTION_DATA ((uint16_t)0x4000U)
#define LAN8742_MMDACR_MMD_DEV_ADDR ((uint16_t)0x001FU)
/**
* @}
*/
/** @defgroup LAN8742_ENCTR_Bit_Definition LAN8742 ENCTR Bit Definition
* @{
*/
#define LAN8742_ENCTR_TX_ENABLE ((uint16_t)0x8000U)
#define LAN8742_ENCTR_TX_TIMER ((uint16_t)0x6000U)
#define LAN8742_ENCTR_TX_TIMER_1S ((uint16_t)0x0000U)
#define LAN8742_ENCTR_TX_TIMER_768MS ((uint16_t)0x2000U)
#define LAN8742_ENCTR_TX_TIMER_512MS ((uint16_t)0x4000U)
#define LAN8742_ENCTR_TX_TIMER_265MS ((uint16_t)0x6000U)
#define LAN8742_ENCTR_RX_ENABLE ((uint16_t)0x1000U)
#define LAN8742_ENCTR_RX_MAX_INTERVAL ((uint16_t)0x0C00U)
#define LAN8742_ENCTR_RX_MAX_INTERVAL_64MS ((uint16_t)0x0000U)
#define LAN8742_ENCTR_RX_MAX_INTERVAL_256MS ((uint16_t)0x0400U)
#define LAN8742_ENCTR_RX_MAX_INTERVAL_512MS ((uint16_t)0x0800U)
#define LAN8742_ENCTR_RX_MAX_INTERVAL_1S ((uint16_t)0x0C00U)
#define LAN8742_ENCTR_EX_CROSS_OVER ((uint16_t)0x0002U)
#define LAN8742_ENCTR_EX_MANUAL_CROSS_OVER ((uint16_t)0x0001U)
/**
* @}
*/
/** @defgroup LAN8742_MCSR_Bit_Definition LAN8742 MCSR Bit Definition
* @{
*/
#define LAN8742_MCSR_EDPWRDOWN ((uint16_t)0x2000U)
#define LAN8742_MCSR_FARLOOPBACK ((uint16_t)0x0200U)
#define LAN8742_MCSR_ALTINT ((uint16_t)0x0040U)
#define LAN8742_MCSR_ENERGYON ((uint16_t)0x0002U)
/**
* @}
*/
/** @defgroup LAN8742_SMR_Bit_Definition LAN8742 SMR Bit Definition
* @{
*/
#define LAN8742_SMR_MODE ((uint16_t)0x00E0U)
#define LAN8742_SMR_PHY_ADDR ((uint16_t)0x001FU)
/**
* @}
*/
/** @defgroup LAN8742_TPDCR_Bit_Definition LAN8742 TPDCR Bit Definition
* @{
*/
#define LAN8742_TPDCR_DELAY_IN ((uint16_t)0x8000U)
#define LAN8742_TPDCR_LINE_BREAK_COUNTER ((uint16_t)0x7000U)
#define LAN8742_TPDCR_PATTERN_HIGH ((uint16_t)0x0FC0U)
#define LAN8742_TPDCR_PATTERN_LOW ((uint16_t)0x003FU)
/**
* @}
*/
/** @defgroup LAN8742_TCSR_Bit_Definition LAN8742 TCSR Bit Definition
* @{
*/
#define LAN8742_TCSR_TDR_ENABLE ((uint16_t)0x8000U)
#define LAN8742_TCSR_TDR_AD_FILTER_ENABLE ((uint16_t)0x4000U)
#define LAN8742_TCSR_TDR_CH_CABLE_TYPE ((uint16_t)0x0600U)
#define LAN8742_TCSR_TDR_CH_CABLE_DEFAULT ((uint16_t)0x0000U)
#define LAN8742_TCSR_TDR_CH_CABLE_SHORTED ((uint16_t)0x0200U)
#define LAN8742_TCSR_TDR_CH_CABLE_OPEN ((uint16_t)0x0400U)
#define LAN8742_TCSR_TDR_CH_CABLE_MATCH ((uint16_t)0x0600U)
#define LAN8742_TCSR_TDR_CH_STATUS ((uint16_t)0x0100U)
#define LAN8742_TCSR_TDR_CH_LENGTH ((uint16_t)0x00FFU)
/**
* @}
*/
/** @defgroup LAN8742_SCSIR_Bit_Definition LAN8742 SCSIR Bit Definition
* @{
*/
#define LAN8742_SCSIR_AUTO_MDIX_ENABLE ((uint16_t)0x8000U)
#define LAN8742_SCSIR_CHANNEL_SELECT ((uint16_t)0x2000U)
#define LAN8742_SCSIR_SQE_DISABLE ((uint16_t)0x0800U)
#define LAN8742_SCSIR_XPOLALITY ((uint16_t)0x0010U)
/**
* @}
*/
/** @defgroup LAN8742_CLR_Bit_Definition LAN8742 CLR Bit Definition
* @{
*/
#define LAN8742_CLR_CABLE_LENGTH ((uint16_t)0xF000U)
/**
* @}
*/
/** @defgroup LAN8742_IMR_ISFR_Bit_Definition LAN8742 IMR ISFR Bit Definition
* @{
*/
#define LAN8742_INT_8 ((uint16_t)0x0100U)
#define LAN8742_INT_7 ((uint16_t)0x0080U)
#define LAN8742_INT_6 ((uint16_t)0x0040U)
#define LAN8742_INT_5 ((uint16_t)0x0020U)
#define LAN8742_INT_4 ((uint16_t)0x0010U)
#define LAN8742_INT_3 ((uint16_t)0x0008U)
#define LAN8742_INT_2 ((uint16_t)0x0004U)
#define LAN8742_INT_1 ((uint16_t)0x0002U)
/**
* @}
*/
/** @defgroup LAN8742_PHYSCSR_Bit_Definition LAN8742 PHYSCSR Bit Definition
* @{
*/
#define LAN8742_PHYSCSR_AUTONEGO_DONE ((uint16_t)0x1000U)
#define LAN8742_PHYSCSR_HCDSPEEDMASK ((uint16_t)0x001CU)
#define LAN8742_PHYSCSR_10BT_HD ((uint16_t)0x0004U)
#define LAN8742_PHYSCSR_10BT_FD ((uint16_t)0x0014U)
#define LAN8742_PHYSCSR_100BTX_HD ((uint16_t)0x0008U)
#define LAN8742_PHYSCSR_100BTX_FD ((uint16_t)0x0018U)
/**
* @}
*/
/** @defgroup LAN8742_Status LAN8742 Status
* @{
*/
#define LAN8742_STATUS_READ_ERROR ((int32_t)-5)
#define LAN8742_STATUS_WRITE_ERROR ((int32_t)-4)
#define LAN8742_STATUS_ADDRESS_ERROR ((int32_t)-3)
#define LAN8742_STATUS_RESET_TIMEOUT ((int32_t)-2)
#define LAN8742_STATUS_ERROR ((int32_t)-1)
#define LAN8742_STATUS_OK ((int32_t) 0)
#define LAN8742_STATUS_LINK_DOWN ((int32_t) 1)
#define LAN8742_STATUS_100MBITS_FULLDUPLEX ((int32_t) 2)
#define LAN8742_STATUS_100MBITS_HALFDUPLEX ((int32_t) 3)
#define LAN8742_STATUS_10MBITS_FULLDUPLEX ((int32_t) 4)
#define LAN8742_STATUS_10MBITS_HALFDUPLEX ((int32_t) 5)
#define LAN8742_STATUS_AUTONEGO_NOTDONE ((int32_t) 6)
/**
* @}
*/
/** @defgroup LAN8742_IT_Flags LAN8742 IT Flags
* @{
*/
#define LAN8742_WOL_IT LAN8742_INT_8
#define LAN8742_ENERGYON_IT LAN8742_INT_7
#define LAN8742_AUTONEGO_COMPLETE_IT LAN8742_INT_6
#define LAN8742_REMOTE_FAULT_IT LAN8742_INT_5
#define LAN8742_LINK_DOWN_IT LAN8742_INT_4
#define LAN8742_AUTONEGO_LP_ACK_IT LAN8742_INT_3
#define LAN8742_PARALLEL_DETECTION_FAULT_IT LAN8742_INT_2
#define LAN8742_AUTONEGO_PAGE_RECEIVED_IT LAN8742_INT_1
/**
* @}
*/
/**
* @}
*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup LAN8742_Exported_Types LAN8742 Exported Types
* @{
*/
typedef int32_t (*lan8742_Init_Func) (void);
typedef int32_t (*lan8742_DeInit_Func) (void);
typedef int32_t (*lan8742_ReadReg_Func) (uint32_t, uint32_t, uint32_t *);
typedef int32_t (*lan8742_WriteReg_Func) (uint32_t, uint32_t, uint32_t);
typedef int32_t (*lan8742_GetTick_Func) (void);
typedef struct
{
lan8742_Init_Func Init;
lan8742_DeInit_Func DeInit;
lan8742_WriteReg_Func WriteReg;
lan8742_ReadReg_Func ReadReg;
lan8742_GetTick_Func GetTick;
} lan8742_IOCtx_t;
typedef struct
{
uint32_t DevAddr;
uint32_t Is_Initialized;
lan8742_IOCtx_t IO;
void *pData;
}lan8742_Object_t;
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup LAN8742_Exported_Functions LAN8742 Exported Functions
* @{
*/
int32_t LAN8742_RegisterBusIO(lan8742_Object_t *pObj, lan8742_IOCtx_t *ioctx);
int32_t LAN8742_Init(lan8742_Object_t *pObj);
int32_t LAN8742_DeInit(lan8742_Object_t *pObj);
int32_t LAN8742_DisablePowerDownMode(lan8742_Object_t *pObj);
int32_t LAN8742_EnablePowerDownMode(lan8742_Object_t *pObj);
int32_t LAN8742_StartAutoNego(lan8742_Object_t *pObj);
int32_t LAN8742_GetLinkState(lan8742_Object_t *pObj);
int32_t LAN8742_SetLinkState(lan8742_Object_t *pObj, uint32_t LinkState);
int32_t LAN8742_EnableLoopbackMode(lan8742_Object_t *pObj);
int32_t LAN8742_DisableLoopbackMode(lan8742_Object_t *pObj);
int32_t LAN8742_EnableIT(lan8742_Object_t *pObj, uint32_t Interrupt);
int32_t LAN8742_DisableIT(lan8742_Object_t *pObj, uint32_t Interrupt);
int32_t LAN8742_ClearIT(lan8742_Object_t *pObj, uint32_t Interrupt);
int32_t LAN8742_GetITStatus(lan8742_Object_t *pObj, uint32_t Interrupt);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* LAN8742_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,418 @@
/* Includes ------------------------------------------------------------------*/
#include "yt8512c.h"
#define YT8512C_SW_RESET_TO ((uint32_t)500U) /* 软件复位等待时间 */
#define YT8512C_INIT_TO ((uint32_t)2000U) /* 初始化等待时间 */
#define YT8512C_MAX_DEV_ADDR ((uint32_t)31U) /* PHY地址的最大值 */
#define YT8512C_AND_RTL8201BL_PHYREGISTER2 0x0000
/**
* @brief 将IO函数注册到组件对象
* @param pobj设备对象
* @param ioctx保存设备IO功能
* @retval YT8512C_STATUS_OKOK
* YT8512C_STATUS_ERROR缺少功能
*/
int32_t yt8512c_regster_bus_io(yt8512c_object_t *pobj, yt8512c_ioc_tx_t *ioctx)
{
if (!pobj || !ioctx->readreg || !ioctx->writereg || !ioctx->gettick)
{
return YT8512C_STATUS_ERROR;
}
pobj->io.init = ioctx->init;
pobj->io.deinit = ioctx->deinit;
pobj->io.readreg = ioctx->readreg;
pobj->io.writereg = ioctx->writereg;
pobj->io.gettick = ioctx->gettick;
return YT8512C_STATUS_OK;
}
/**
* @brief 初始化YT8512C并配置所需的硬件资源
* @param pobj: 设备对象
* @retval YT8512C_STATUS_OK初始化YT8512C并配置所需的硬件资源成功
YT8512C_STATUS_ADDRESS_ERROR找不到设备地址
YT8512C_STATUS_READ_ERROR不能读取寄存器
YT8512C_STATUS_WRITE_ERROR不能写入寄存器
YT8512C_STATUS_RESET_TIMEOUT无法执行软件复位
*/
int32_t yt8512c_init(yt8512c_object_t *pobj)
{
uint32_t tickstart = 0, regvalue = 0, addr = 0;
int32_t status = YT8512C_STATUS_OK;
if (pobj->is_initialized == 0)
{
if (pobj->io.init != 0)
{
/* MDC时钟 */
pobj->io.init();
}
/* 设置PHY地址为32 */
pobj->devaddr = YT8512C_MAX_DEV_ADDR + 1;
/* 主要为了查找PHY地址 */
for (addr = 0; addr <= YT8512C_MAX_DEV_ADDR; addr ++)
{
if (pobj->io.readreg(addr, YT8512C_PHYSCSR, &regvalue) < 0)
{
status = YT8512C_STATUS_READ_ERROR;
/* 无法读取这个设备地址继续下一个地址 */
continue;
}
/* 已经找到PHY地址了 */
if ((regvalue & YT8512C_PHY_COUNT) == addr)
{
pobj->devaddr = addr;
status = YT8512C_STATUS_OK;
break;
}
}
/* 判断这个PHY地址是否大于322^5*/
if (pobj->devaddr > YT8512C_MAX_DEV_ADDR)
{
status = YT8512C_STATUS_ADDRESS_ERROR;
}
/* 如果PHY地址有效 */
if (status == YT8512C_STATUS_OK)
{
/* 设置软件复位 */
if (pobj->io.writereg(pobj->devaddr, YT8512C_BCR, YT8512C_BCR_SOFT_RESET) >= 0)
{
/* 获取软件重置状态 */
if (pobj->io.readreg(pobj->devaddr, YT8512C_BCR, &regvalue) >= 0)
{
tickstart = pobj->io.gettick();
/* 等待软件复位完成或超时 */
while (regvalue & YT8512C_BCR_SOFT_RESET)
{
if ((pobj->io.gettick() - tickstart) <= YT8512C_SW_RESET_TO)
{
if (pobj->io.readreg(pobj->devaddr, YT8512C_BCR, &regvalue) < 0)
{
status = YT8512C_STATUS_READ_ERROR;
break;
}
}
else
{
status = YT8512C_STATUS_RESET_TIMEOUT;
break;
}
}
}
else
{
status = YT8512C_STATUS_READ_ERROR;
}
}
else
{
status = YT8512C_STATUS_WRITE_ERROR;
}
}
}
/* 到了这里,初始化完成!!! */
if (status == YT8512C_STATUS_OK)
{
tickstart = pobj->io.gettick();
/* 等待2s进行初始化 */
while ((pobj->io.gettick() - tickstart) <= YT8512C_INIT_TO)
{
}
pobj->is_initialized = 1;
}
return status;
}
/**
* @brief 反初始化YT8512C及其硬件资源
* @param pobj: 设备对象
* @retval YT8512C_STATUS_OK反初始化失败成功
YT8512C_STATUS_ERROR反初始化失败
*/
int32_t yt8512c_deinit(yt8512c_object_t *pobj)
{
if (pobj->is_initialized)
{
if (pobj->io.deinit != 0)
{
if (pobj->io.deinit() < 0)
{
return YT8512C_STATUS_ERROR;
}
}
pobj->is_initialized = 0;
}
return YT8512C_STATUS_OK;
}
/**
* @brief 关闭YT8512C的下电模式
* @param pobj: 设备对象
* @retval YT8512C_STATUS_OK关闭成功
YT8512C_STATUS_READ_ERROR不能读取寄存器
YT8512C_STATUS_WRITE_ERROR不能写寄存器
*/
int32_t yt8512c_disable_power_down_mode(yt8512c_object_t *pobj)
{
uint32_t readval = 0;
int32_t status = YT8512C_STATUS_OK;
if (pobj->io.readreg(pobj->devaddr, YT8512C_BCR, &readval) >= 0)
{
readval &= ~YT8512C_BCR_POWER_DOWN;
/* 清除下电模式 */
if (pobj->io.writereg(pobj->devaddr, YT8512C_BCR, readval) < 0)
{
status = YT8512C_STATUS_WRITE_ERROR;
}
}
else
{
status = YT8512C_STATUS_READ_ERROR;
}
return status;
}
/**
* @brief 使能YT8512C的下电模式
* @param pobj: 设备对象
* @retval YT8512C_STATUS_OK关闭成功
YT8512C_STATUS_READ_ERROR不能读取寄存器
YT8512C_STATUS_WRITE_ERROR不能写寄存器
*/
int32_t yt8512c_enable_power_down_mode(yt8512c_object_t *pobj)
{
uint32_t readval = 0;
int32_t status = YT8512C_STATUS_OK;
if (pobj->io.readreg(pobj->devaddr, YT8512C_BCR, &readval) >= 0)
{
readval |= YT8512C_BCR_POWER_DOWN;
/* 使能下电模式 */
if (pobj->io.writereg(pobj->devaddr, YT8512C_BCR, readval) < 0)
{
status = YT8512C_STATUS_WRITE_ERROR;
}
}
else
{
status = YT8512C_STATUS_READ_ERROR;
}
return status;
}
/**
* @brief 启动自动协商过程
* @param pobj: 设备对象
* @retval YT8512C_STATUS_OK关闭成功
YT8512C_STATUS_READ_ERROR不能读取寄存器
YT8512C_STATUS_WRITE_ERROR不能写寄存器
*/
int32_t yt8512c_start_auto_nego(yt8512c_object_t *pobj)
{
uint32_t readval = 0;
int32_t status = YT8512C_STATUS_OK;
if (pobj->io.readreg(pobj->devaddr, YT8512C_BCR, &readval) >= 0)
{
readval |= YT8512C_BCR_AUTONEGO_EN;
/* 启动自动协商 */
if (pobj->io.writereg(pobj->devaddr, YT8512C_BCR, readval) < 0)
{
status = YT8512C_STATUS_WRITE_ERROR;
}
}
else
{
status = YT8512C_STATUS_READ_ERROR;
}
return status;
}
/**
* @brief 获取YT8512C设备的链路状态
* @param pobj: 设备对象
* @param pLinkState: 指向链路状态的指针
* @retval YT8512C_STATUS_100MBITS_FULLDUPLEX100M全双工
YT8512C_STATUS_100MBITS_HALFDUPLEX 100M半双工
YT8512C_STATUS_10MBITS_FULLDUPLEX10M全双工
YT8512C_STATUS_10MBITS_HALFDUPLEX 10M半双工
YT8512C_STATUS_READ_ERROR不能读取寄存器
*/
int32_t yt8512c_get_link_state(yt8512c_object_t *pobj)
{
uint32_t readval = 0;
/* 检测特殊功能寄存器链接值 */
if (pobj->io.readreg(pobj->devaddr, YT8512C_PHYSCSR, &readval) < 0)
{
return YT8512C_STATUS_READ_ERROR;
}
if (((readval & YT8512C_SPEED_STATUS) != YT8512C_SPEED_STATUS) && ((readval & YT8512C_DUPLEX_STATUS) != 0))
{
return YT8512C_STATUS_100MBITS_FULLDUPLEX;
}
else if (((readval & YT8512C_SPEED_STATUS) != YT8512C_SPEED_STATUS))
{
return YT8512C_STATUS_100MBITS_HALFDUPLEX;
}
else if (((readval & YT8512C_BCR_DUPLEX_MODE) != YT8512C_BCR_DUPLEX_MODE))
{
return YT8512C_STATUS_10MBITS_FULLDUPLEX;
}
else
{
return YT8512C_STATUS_10MBITS_HALFDUPLEX;
}
}
/**
* @brief 设置YT8512C设备的链路状态
* @param pobj: 设备对象
* @param pLinkState: 指向链路状态的指针
* @retval YT8512C_STATUS_OK设置成功
YT8512C_STATUS_ERROR :设置失败
YT8512C_STATUS_READ_ERROR不能读取寄存器
YT8512C_STATUS_WRITE_ERROR :不能写入寄存器
*/
int32_t yt8512c_set_link_state(yt8512c_object_t *pobj, uint32_t linkstate)
{
uint32_t bcrvalue = 0;
int32_t status = YT8512C_STATUS_OK;
if (pobj->io.readreg(pobj->devaddr, YT8512C_BCR, &bcrvalue) >= 0)
{
/* 禁用链路配置(自动协商,速度和双工) */
bcrvalue &= ~(YT8512C_BCR_AUTONEGO_EN | YT8512C_BCR_SPEED_SELECT | YT8512C_BCR_DUPLEX_MODE);
if (linkstate == YT8512C_STATUS_100MBITS_FULLDUPLEX)
{
bcrvalue |= (YT8512C_BCR_SPEED_SELECT | YT8512C_BCR_DUPLEX_MODE);
}
else if (linkstate == YT8512C_STATUS_100MBITS_HALFDUPLEX)
{
bcrvalue |= YT8512C_BCR_SPEED_SELECT;
}
else if (linkstate == YT8512C_STATUS_10MBITS_FULLDUPLEX)
{
bcrvalue |= YT8512C_BCR_DUPLEX_MODE;
}
else
{
/* 错误的链路状态参数 */
status = YT8512C_STATUS_ERROR;
}
}
else
{
status = YT8512C_STATUS_READ_ERROR;
}
if(status == YT8512C_STATUS_OK)
{
/* 写入链路状态 */
if(pobj->io.writereg(pobj->devaddr, YT8512C_BCR, bcrvalue) < 0)
{
status = YT8512C_STATUS_WRITE_ERROR;
}
}
return status;
}
/**
* @brief 启用环回模式
* @param pobj: 设备对象
* @param pLinkState: 指向链路状态的指针
* @retval YT8512C_STATUS_OK设置成功
YT8512C_STATUS_READ_ERROR不能读取寄存器
YT8512C_STATUS_WRITE_ERROR :不能写入寄存器
*/
int32_t yt8512c_enable_loop_back_mode(yt8512c_object_t *pobj)
{
uint32_t readval = 0;
int32_t status = YT8512C_STATUS_OK;
if (pobj->io.readreg(pobj->devaddr, YT8512C_BCR, &readval) >= 0)
{
readval |= YT8512C_BCR_LOOPBACK;
/* 启用环回模式 */
if (pobj->io.writereg(pobj->devaddr, YT8512C_BCR, readval) < 0)
{
status = YT8512C_STATUS_WRITE_ERROR;
}
}
else
{
status = YT8512C_STATUS_READ_ERROR;
}
return status;
}
/**
* @brief 禁用环回模式
* @param pobj: 设备对象
* @param pLinkState: 指向链路状态的指针
* @retval YT8512C_STATUS_OK设置成功
YT8512C_STATUS_READ_ERROR不能读取寄存器
YT8512C_STATUS_WRITE_ERROR :不能写入寄存器
*/
int32_t yt8512c_disable_loop_back_mode(yt8512c_object_t *pobj)
{
uint32_t readval = 0;
int32_t status = YT8512C_STATUS_OK;
if (pobj->io.readreg(pobj->devaddr, YT8512C_BCR, &readval) >= 0)
{
readval &= ~YT8512C_BCR_LOOPBACK;
/* 禁用环回模式 */
if (pobj->io.writereg(pobj->devaddr, YT8512C_BCR, readval) < 0)
{
status = YT8512C_STATUS_WRITE_ERROR;
}
}
else
{
status = YT8512C_STATUS_READ_ERROR;
}
return status;
}

View File

@@ -0,0 +1,111 @@
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef YT8512C_H
#define YT8512C_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include "global.h"
/* PHY芯片寄存器映射表 */
#define YT8512C_BCR ((uint16_t)0x0000U)
#define YT8512C_BSR ((uint16_t)0x0001U)
#define PHY_REGISTER2 ((uint16_t)0x0002U)
#define PHY_REGISTER3 ((uint16_t)0x0003U)
/* 操作SCR寄存器的值一般不需要修改 */
#define YT8512C_BCR_SOFT_RESET ((uint16_t)0x8000U)
#define YT8512C_BCR_LOOPBACK ((uint16_t)0x4000U)
#define YT8512C_BCR_SPEED_SELECT ((uint16_t)0x2000U)
#define YT8512C_BCR_AUTONEGO_EN ((uint16_t)0x1000U)
#define YT8512C_BCR_POWER_DOWN ((uint16_t)0x0800U)
#define YT8512C_BCR_ISOLATE ((uint16_t)0x0400U)
#define YT8512C_BCR_RESTART_AUTONEGO ((uint16_t)0x0200U)
#define YT8512C_BCR_DUPLEX_MODE ((uint16_t)0x0100U)
/* 操作BSR寄存器的值一般不需要修改 */
#define YT8512C_BSR_100BASE_T4 ((uint16_t)0x8000U)
#define YT8512C_BSR_100BASE_TX_FD ((uint16_t)0x4000U)
#define YT8512C_BSR_100BASE_TX_HD ((uint16_t)0x2000U)
#define YT8512C_BSR_10BASE_T_FD ((uint16_t)0x1000U)
#define YT8512C_BSR_10BASE_T_HD ((uint16_t)0x0800U)
#define YT8512C_BSR_100BASE_T2_FD ((uint16_t)0x0400U)
#define YT8512C_BSR_100BASE_T2_HD ((uint16_t)0x0200U)
#define YT8512C_BSR_EXTENDED_STATUS ((uint16_t)0x0100U)
#define YT8512C_BSR_AUTONEGO_CPLT ((uint16_t)0x0020U)
#define YT8512C_BSR_REMOTE_FAULT ((uint16_t)0x0010U)
#define YT8512C_BSR_AUTONEGO_ABILITY ((uint16_t)0x0008U)
#define YT8512C_BSR_LINK_STATUS ((uint16_t)0x0004U)
#define YT8512C_BSR_JABBER_DETECT ((uint16_t)0x0002U)
#define YT8512C_BSR_EXTENDED_CAP ((uint16_t)0x0001U)
/* PHY芯片进程状态 */
#define YT8512C_STATUS_READ_ERROR ((int32_t)-5)
#define YT8512C_STATUS_WRITE_ERROR ((int32_t)-4)
#define YT8512C_STATUS_ADDRESS_ERROR ((int32_t)-3)
#define YT8512C_STATUS_RESET_TIMEOUT ((int32_t)-2)
#define YT8512C_STATUS_ERROR ((int32_t)-1)
#define YT8512C_STATUS_OK ((int32_t) 0)
#define YT8512C_STATUS_LINK_DOWN ((int32_t) 1)
#define YT8512C_STATUS_100MBITS_FULLDUPLEX ((int32_t) 2)
#define YT8512C_STATUS_100MBITS_HALFDUPLEX ((int32_t) 3)
#define YT8512C_STATUS_10MBITS_FULLDUPLEX ((int32_t) 4)
#define YT8512C_STATUS_10MBITS_HALFDUPLEX ((int32_t) 5)
#define YT8512C_STATUS_AUTONEGO_NOTDONE ((int32_t) 6)
/* PHY地址 ---- 由用户设置 */
#define YT8512C_ADDR ((uint16_t)0x0000U)
/* PHY寄存器的数量 */
#define YT8512C_PHY_COUNT ((uint16_t)0x001FU)
#define YT8512C_PHYSCSR ((uint16_t)0x11) /*!< tranceiver status register */
#define YT8512C_SPEED_STATUS ((uint16_t)0x4010) /*!< configured information of speed: 100Mbit/s */
#define YT8512C_DUPLEX_STATUS ((uint16_t)0x2000) /*!< configured information of duplex: full-duplex */
/* 定义函数指针 */
typedef int32_t (*yt8512c_init_func) (void);
typedef int32_t (*yt8512c_deinit_func) (void);
typedef int32_t (*yt8512c_readreg_func) (uint32_t, uint32_t, uint32_t *);
typedef int32_t (*yt8512c_writereg_func) (uint32_t, uint32_t, uint32_t);
typedef int32_t (*yt8512c_gettick_func) (void);
/* PHY共用函数结构体 */
typedef struct
{
yt8512c_init_func init; /* 指向PHY初始化函数 */
yt8512c_deinit_func deinit; /* 指向PHY反初始化函数 */
yt8512c_writereg_func writereg; /* 指向PHY写寄存器函数 */
yt8512c_readreg_func readreg; /* 指向PHY读寄存器函数 */
yt8512c_gettick_func gettick; /* 指向节拍函数 */
} yt8512c_ioc_tx_t;
/* 注册到组件对象结构体 */
typedef struct
{
uint32_t devaddr; /* PHY地址 */
uint32_t is_initialized; /* 描述该设备是否初始化 */
yt8512c_ioc_tx_t io; /* 设备调用的函数入口 */
void *pdata; /* 传入的形参 */
}yt8512c_object_t;
int32_t yt8512c_regster_bus_io(yt8512c_object_t *pobj, yt8512c_ioc_tx_t *ioctx); /* 将IO函数注册到组件对象 */
int32_t yt8512c_init(yt8512c_object_t *pobj); /* 初始化YT8512C并配置所需的硬件资源 */
int32_t yt8512c_deinit(yt8512c_object_t *pobj); /* 反初始化YT8512C及其硬件资源 */
int32_t yt8512c_disable_power_down_mode(yt8512c_object_t *pobj); /* 关闭YT8512C的下电模式 */
int32_t yt8512c_enable_power_down_mode(yt8512c_object_t *pobj); /* 使能YT8512C的下电模式 */
int32_t yt8512c_start_auto_nego(yt8512c_object_t *pobj); /* 启动自动协商过程 */
int32_t yt8512c_get_link_state(yt8512c_object_t *pobj); /* 获取YT8512C设备的链路状态 */
int32_t yt8512c_set_link_state(yt8512c_object_t *pobj, uint32_t linkstate); /* 设置YT8512C设备的链路状态 */
int32_t yt8512c_enable_loop_back_mode(yt8512c_object_t *pobj); /* 启用环回模式 */
int32_t yt8512c_disable_loop_back_mode(yt8512c_object_t *pobj); /* 禁用环回模式 */
#ifdef __cplusplus
}
#endif
#endif /* YT8512C_H */