当前位置: 首页 > news >正文

PHY——LAN8720A 寄存器读写 (二)

文章目录

  • PHY——LAN8720A 寄存器读写 (二)
    • 工程配置
    • 引脚初始化代码
    • 以太网初始化代码
    • PHY 接口实现
    • LAN8720 接口实现
    • PHY 接口测试

PHY——LAN8720A 寄存器读写 (二)

工程配置

这里以野火电子的 F429 开发板为例,配置以太网外设
在这里插入图片描述
这里有一点需要注意原理图 RMII_TXD0, RMII_TXD1 使用的分别是 PG13, PG14,如下图

在这里插入图片描述
但是当 CubeMx 使能 ETH 外设的 RMII 时候,默认使用的引脚是 PB12 和 PB13
在这里插入图片描述
这里需要手动修改
在这里插入图片描述
这样 RMII 的引脚和以太网相关时钟就配置好了,这里我们只借助 CubeMx 配置这两个,PHY的驱动自己来实现

引脚初始化代码

void HAL_ETH_MspInit(ETH_HandleTypeDef* ethHandle)
{GPIO_InitTypeDef GPIO_InitStruct = {0};if(ethHandle->Instance==ETH){/* USER CODE BEGIN ETH_MspInit 0 *//* USER CODE END ETH_MspInit 0 *//* ETH clock enable */__HAL_RCC_ETH_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOG_CLK_ENABLE();/**ETH GPIO ConfigurationPC1     ------> ETH_MDCPA1     ------> ETH_REF_CLKPA2     ------> ETH_MDIOPA7     ------> ETH_CRS_DVPC4     ------> ETH_RXD0PC5     ------> ETH_RXD1PB11     ------> ETH_TX_ENPG13     ------> ETH_TXD0PG14     ------> ETH_TXD1*/GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF11_ETH;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF11_ETH;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_11;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF11_ETH;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF11_ETH;HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);/* USER CODE BEGIN ETH_MspInit 1 *//* USER CODE END ETH_MspInit 1 */}
}

以太网初始化代码

void MX_ETH_Init(void)
{/* USER CODE BEGIN ETH_Init 0 *//* USER CODE END ETH_Init 0 */static uint8_t MACAddr[6];/* USER CODE BEGIN ETH_Init 1 *//* USER CODE END ETH_Init 1 */heth.Instance = ETH;MACAddr[0] = 0x00;MACAddr[1] = 0x80;MACAddr[2] = 0xE1;MACAddr[3] = 0x00;MACAddr[4] = 0x00;MACAddr[5] = 0x00;heth.Init.MACAddr = &MACAddr[0];heth.Init.MediaInterface = HAL_ETH_RMII_MODE;heth.Init.TxDesc = DMATxDscrTab;heth.Init.RxDesc = DMARxDscrTab;heth.Init.RxBuffLen = 1524;/* USER CODE BEGIN MACADDRESS *//* USER CODE END MACADDRESS */if (HAL_ETH_Init(&heth) != HAL_OK){Error_Handler();}memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig));TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT;/* USER CODE BEGIN ETH_Init 2 *//* USER CODE END ETH_Init 2 */}

PHY 接口实现

ethernetif.c
这个文件其实主要实现了两个接口 ETH_PHY_IO_ReadRegETH_PHY_IO_WriteReg

/* USER CODE BEGIN Header */
/********************************************************************************* File Name          : ethernetif.c* Description        : This file provides code for the configuration*                      of the ethernetif.c MiddleWare.******************************************************************************* @attention** Copyright (c) 2025 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.********************************************************************************/
/* USER CODE END Header *//* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "ethernetif.h"
#include "lan8720.h"
#include <string.h>/* USER CODE BEGIN 0 *//* USER CODE END 0 *//* USER CODE BEGIN 1 *//* USER CODE END 1 *//* Private function prototypes -----------------------------------------------*/
int32_t ETH_PHY_IO_Init(void);
int32_t ETH_PHY_IO_DeInit (void);
int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal);
int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal);
int32_t ETH_PHY_IO_GetTick(void);lan8720_Object_t LAN8720;
lan8720_IOCtx_t  LAN8720_IOCtx = {ETH_PHY_IO_Init,ETH_PHY_IO_DeInit,ETH_PHY_IO_WriteReg,ETH_PHY_IO_ReadReg,ETH_PHY_IO_GetTick};/* USER CODE BEGIN 3 *//* USER CODE END 3 *//* USER CODE BEGIN 4 *//* USER CODE END 4 *//* USER CODE END 6 *//*******************************************************************************PHI IO Functions
*******************************************************************************/
/*** @brief  Initializes the MDIO interface GPIO and clocks.* @param  None* @retval 0 if OK, -1 if ERROR*/
int32_t ETH_PHY_IO_Init(void)
{/* We assume that MDIO GPIO configuration is already donein the ETH_MspInit() else it should be done here*//* Configure the MDIO Clock */HAL_ETH_SetMDIOClockRange(&heth);return 0;
}/*** @brief  De-Initializes the MDIO interface .* @param  None* @retval 0 if OK, -1 if ERROR*/
int32_t ETH_PHY_IO_DeInit (void)
{return 0;
}/*** @brief  Read a PHY register through the MDIO interface.* @param  DevAddr: PHY port address* @param  RegAddr: PHY register address* @param  pRegVal: pointer to hold the register value* @retval 0 if OK -1 if Error*/
int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal)
{if(HAL_ETH_ReadPHYRegister(&heth, DevAddr, RegAddr, pRegVal) != HAL_OK){return -1;}return 0;
}/*** @brief  Write a value to a PHY register through the MDIO interface.* @param  DevAddr: PHY port address* @param  RegAddr: PHY register address* @param  RegVal: Value to be written* @retval 0 if OK -1 if Error*/
int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal)
{if(HAL_ETH_WritePHYRegister(&heth, DevAddr, RegAddr, RegVal) != HAL_OK){return -1;}return 0;
}/*** @brief  Get the time in millisecons used for internal PHY driver process.* @retval Time value*/
int32_t ETH_PHY_IO_GetTick(void)
{return HAL_GetTick();
}
/* USER CODE BEGIN 8 *//* USER CODE END 8 */

ethernetif.h 文件

/* USER CODE BEGIN Header */
/********************************************************************************* File Name          : ethernetif.h* Description        : This file provides initialization code for LWIP*                      middleWare.******************************************************************************* @attention** Copyright (c) 2025 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.********************************************************************************/
/* USER CODE END Header */#ifndef __ETHERNETIF_H__
#define __ETHERNETIF_H__/* USER CODE BEGIN 0 */
#include "main.h"
#include "lan8720.h"
extern ETH_HandleTypeDef heth;
extern lan8720_Object_t LAN8720;
extern lan8720_IOCtx_t  LAN8720_IOCtx;
/* USER CODE END 0 *//* USER CODE BEGIN 1 *//* USER CODE END 1 */
#endif

LAN8720 接口实现

lan8720.c

/********************************************************************************* @file    lan8720.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 "lan8720.h"/** @addtogroup BSP* @{*//** @addtogroup Component* @{*//** @defgroup LAN8720 LAN8720* @{*//* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/** @defgroup LAN8720_Private_Defines LAN8720 Private Defines* @{*/
#define LAN8720_MAX_DEV_ADDR   ((uint32_t)31U)
/*** @}*//* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup LAN8720_Private_Functions LAN8720 Private Functions* @{*//*** @brief  Register IO functions to component object* @param  pObj: device object  of LAN8720_Object_t.* @param  ioctx: holds device IO functions.* @retval LAN8720_STATUS_OK  if OK*         LAN8720_STATUS_ERROR if missing mandatory function*/
int32_t  LAN8720_RegisterBusIO(lan8720_Object_t *pObj, lan8720_IOCtx_t *ioctx)
{if(!pObj || !ioctx->ReadReg || !ioctx->WriteReg || !ioctx->GetTick){return LAN8720_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 LAN8720_STATUS_OK;
}/*** @brief  Initialize the lan8720 and configure the needed hardware resources* @param  pObj: device object LAN8720_Object_t.* @retval LAN8720_STATUS_OK  if OK*         LAN8720_STATUS_ADDRESS_ERROR if cannot find device address*         LAN8720_STATUS_READ_ERROR if cannot read register*/int32_t LAN8720_Init(lan8720_Object_t *pObj){uint32_t regvalue = 0, addr = 0;int32_t status = LAN8720_STATUS_OK;if(pObj->Is_Initialized == 0){if(pObj->IO.Init != 0){/* GPIO and Clocks initialization */pObj->IO.Init();}/* for later check */pObj->DevAddr = LAN8720_MAX_DEV_ADDR + 1;/* Get the device address from special mode register */for(addr = 0; addr <= LAN8720_MAX_DEV_ADDR; addr ++){if(pObj->IO.ReadReg(addr, LAN8720_SMR, &regvalue) < 0){status = LAN8720_STATUS_READ_ERROR;/* Can't read from this device addresscontinue with next address */continue;}if((regvalue & LAN8720_SMR_PHY_ADDR) == addr){pObj->DevAddr = addr;status = LAN8720_STATUS_OK;break;}}if(pObj->DevAddr > LAN8720_MAX_DEV_ADDR){status = LAN8720_STATUS_ADDRESS_ERROR;}/* if device address is matched */if(status == LAN8720_STATUS_OK){pObj->Is_Initialized = 1;}}return status;}/*** @brief  De-Initialize the lan8720 and it's hardware resources* @param  pObj: device object LAN8720_Object_t.* @retval None*/
int32_t LAN8720_DeInit(lan8720_Object_t *pObj)
{if(pObj->Is_Initialized){if(pObj->IO.DeInit != 0){if(pObj->IO.DeInit() < 0){return LAN8720_STATUS_ERROR;}}pObj->Is_Initialized = 0;}return LAN8720_STATUS_OK;
}/*** @brief  Disable the LAN8720 power down mode.* @param  pObj: device object LAN8720_Object_t.* @retval LAN8720_STATUS_OK  if OK*         LAN8720_STATUS_READ_ERROR if cannot read register*         LAN8720_STATUS_WRITE_ERROR if cannot write to register*/
int32_t LAN8720_DisablePowerDownMode(lan8720_Object_t *pObj)
{uint32_t readval = 0;int32_t status = LAN8720_STATUS_OK;if(pObj->IO.ReadReg(pObj->DevAddr, LAN8720_BCR, &readval) >= 0){readval &= ~LAN8720_BCR_POWER_DOWN;/* Apply configuration */if(pObj->IO.WriteReg(pObj->DevAddr, LAN8720_BCR, readval) < 0){status =  LAN8720_STATUS_WRITE_ERROR;}}else{status = LAN8720_STATUS_READ_ERROR;}return status;
}/*** @brief  Enable the LAN8720 power down mode.* @param  pObj: device object LAN8720_Object_t.* @retval LAN8720_STATUS_OK  if OK*         LAN8720_STATUS_READ_ERROR if cannot read register*         LAN8720_STATUS_WRITE_ERROR if cannot write to register*/
int32_t LAN8720_EnablePowerDownMode(lan8720_Object_t *pObj)
{uint32_t readval = 0;int32_t status = LAN8720_STATUS_OK;if(pObj->IO.ReadReg(pObj->DevAddr, LAN8720_BCR, &readval) >= 0){readval |= LAN8720_BCR_POWER_DOWN;/* Apply configuration */if(pObj->IO.WriteReg(pObj->DevAddr, LAN8720_BCR, readval) < 0){status =  LAN8720_STATUS_WRITE_ERROR;}}else{status = LAN8720_STATUS_READ_ERROR;}return status;
}/*** @brief  Start the auto negotiation process.* @param  pObj: device object LAN8720_Object_t.* @retval LAN8720_STATUS_OK  if OK*         LAN8720_STATUS_READ_ERROR if cannot read register*         LAN8720_STATUS_WRITE_ERROR if cannot write to register*/
int32_t LAN8720_StartAutoNego(lan8720_Object_t *pObj)
{uint32_t readval = 0;int32_t status = LAN8720_STATUS_OK;if(pObj->IO.ReadReg(pObj->DevAddr, LAN8720_BCR, &readval) >= 0){readval |= LAN8720_BCR_AUTONEGO_EN;/* Apply configuration */if(pObj->IO.WriteReg(pObj->DevAddr, LAN8720_BCR, readval) < 0){status =  LAN8720_STATUS_WRITE_ERROR;}}else{status = LAN8720_STATUS_READ_ERROR;}return status;
}/*** @brief  Get the link state of LAN8720 device.* @param  pObj: Pointer to device object.* @param  pLinkState: Pointer to link state* @retval LAN8720_STATUS_LINK_DOWN  if link is down*         LAN8720_STATUS_AUTONEGO_NOTDONE if Auto nego not completed*         LAN8720_STATUS_100MBITS_FULLDUPLEX if 100Mb/s FD*         LAN8720_STATUS_100MBITS_HALFDUPLEX if 100Mb/s HD*         LAN8720_STATUS_10MBITS_FULLDUPLEX  if 10Mb/s FD*         LAN8720_STATUS_10MBITS_HALFDUPLEX  if 10Mb/s HD*         LAN8720_STATUS_READ_ERROR if cannot read register*         LAN8720_STATUS_WRITE_ERROR if cannot write to register*/
int32_t LAN8720_GetLinkState(lan8720_Object_t *pObj)
{uint32_t readval = 0;/* Read Status register  */if(pObj->IO.ReadReg(pObj->DevAddr, LAN8720_BSR, &readval) < 0){return LAN8720_STATUS_READ_ERROR;}/* Read Status register again */if(pObj->IO.ReadReg(pObj->DevAddr, LAN8720_BSR, &readval) < 0){return LAN8720_STATUS_READ_ERROR;}if((readval & LAN8720_BSR_LINK_STATUS) == 0){/* Return Link Down status */return LAN8720_STATUS_LINK_DOWN;}/* Check Auto negotiation */if(pObj->IO.ReadReg(pObj->DevAddr, LAN8720_BCR, &readval) < 0){return LAN8720_STATUS_READ_ERROR;}if((readval & LAN8720_BCR_AUTONEGO_EN) != LAN8720_BCR_AUTONEGO_EN){if(((readval & LAN8720_BCR_SPEED_SELECT) == LAN8720_BCR_SPEED_SELECT) && ((readval & LAN8720_BCR_DUPLEX_MODE) == LAN8720_BCR_DUPLEX_MODE)){return LAN8720_STATUS_100MBITS_FULLDUPLEX;}else if ((readval & LAN8720_BCR_SPEED_SELECT) == LAN8720_BCR_SPEED_SELECT){return LAN8720_STATUS_100MBITS_HALFDUPLEX;}else if ((readval & LAN8720_BCR_DUPLEX_MODE) == LAN8720_BCR_DUPLEX_MODE){return LAN8720_STATUS_10MBITS_FULLDUPLEX;}else{return LAN8720_STATUS_10MBITS_HALFDUPLEX;}}else /* Auto Nego enabled */{if(pObj->IO.ReadReg(pObj->DevAddr, LAN8720_PHYSCSR, &readval) < 0){return LAN8720_STATUS_READ_ERROR;}/* Check if auto nego not done */if((readval & LAN8720_PHYSCSR_AUTONEGO_DONE) == 0){return LAN8720_STATUS_AUTONEGO_NOTDONE;}if((readval & LAN8720_PHYSCSR_HCDSPEEDMASK) == LAN8720_PHYSCSR_100BTX_FD){return LAN8720_STATUS_100MBITS_FULLDUPLEX;}else if ((readval & LAN8720_PHYSCSR_HCDSPEEDMASK) == LAN8720_PHYSCSR_100BTX_HD){return LAN8720_STATUS_100MBITS_HALFDUPLEX;}else if ((readval & LAN8720_PHYSCSR_HCDSPEEDMASK) == LAN8720_PHYSCSR_10BT_FD){return LAN8720_STATUS_10MBITS_FULLDUPLEX;}else{return LAN8720_STATUS_10MBITS_HALFDUPLEX;}}
}/*** @brief  Set the link state of LAN8720 device.* @param  pObj: Pointer to device object.* @param  pLinkState: link state can be one of the following*         LAN8720_STATUS_100MBITS_FULLDUPLEX if 100Mb/s FD*         LAN8720_STATUS_100MBITS_HALFDUPLEX if 100Mb/s HD*         LAN8720_STATUS_10MBITS_FULLDUPLEX  if 10Mb/s FD*         LAN8720_STATUS_10MBITS_HALFDUPLEX  if 10Mb/s HD* @retval LAN8720_STATUS_OK  if OK*         LAN8720_STATUS_ERROR  if parameter error*         LAN8720_STATUS_READ_ERROR if cannot read register*         LAN8720_STATUS_WRITE_ERROR if cannot write to register*/
int32_t LAN8720_SetLinkState(lan8720_Object_t *pObj, uint32_t LinkState)
{uint32_t bcrvalue = 0;int32_t status = LAN8720_STATUS_OK;if(pObj->IO.ReadReg(pObj->DevAddr, LAN8720_BCR, &bcrvalue) >= 0){/* Disable link config (Auto nego, speed and duplex) */bcrvalue &= ~(LAN8720_BCR_AUTONEGO_EN | LAN8720_BCR_SPEED_SELECT | LAN8720_BCR_DUPLEX_MODE);if(LinkState == LAN8720_STATUS_100MBITS_FULLDUPLEX){bcrvalue |= (LAN8720_BCR_SPEED_SELECT | LAN8720_BCR_DUPLEX_MODE);}else if (LinkState == LAN8720_STATUS_100MBITS_HALFDUPLEX){bcrvalue |= LAN8720_BCR_SPEED_SELECT;}else if (LinkState == LAN8720_STATUS_10MBITS_FULLDUPLEX){bcrvalue |= LAN8720_BCR_DUPLEX_MODE;}else{/* Wrong link status parameter */status = LAN8720_STATUS_ERROR;}}else{status = LAN8720_STATUS_READ_ERROR;}if(status == LAN8720_STATUS_OK){/* Apply configuration */if(pObj->IO.WriteReg(pObj->DevAddr, LAN8720_BCR, bcrvalue) < 0){status = LAN8720_STATUS_WRITE_ERROR;}}return status;
}/*** @brief  Enable loopback mode.* @param  pObj: Pointer to device object.* @retval LAN8720_STATUS_OK  if OK*         LAN8720_STATUS_READ_ERROR if cannot read register*         LAN8720_STATUS_WRITE_ERROR if cannot write to register*/
int32_t LAN8720_EnableLoopbackMode(lan8720_Object_t *pObj)
{uint32_t readval = 0;int32_t status = LAN8720_STATUS_OK;if(pObj->IO.ReadReg(pObj->DevAddr, LAN8720_BCR, &readval) >= 0){readval |= LAN8720_BCR_LOOPBACK;/* Apply configuration */if(pObj->IO.WriteReg(pObj->DevAddr, LAN8720_BCR, readval) < 0){status = LAN8720_STATUS_WRITE_ERROR;}}else{status = LAN8720_STATUS_READ_ERROR;}return status;
}/*** @brief  Disable loopback mode.* @param  pObj: Pointer to device object.* @retval LAN8720_STATUS_OK  if OK*         LAN8720_STATUS_READ_ERROR if cannot read register*         LAN8720_STATUS_WRITE_ERROR if cannot write to register*/
int32_t LAN8720_DisableLoopbackMode(lan8720_Object_t *pObj)
{uint32_t readval = 0;int32_t status = LAN8720_STATUS_OK;if(pObj->IO.ReadReg(pObj->DevAddr, LAN8720_BCR, &readval) >= 0){readval &= ~LAN8720_BCR_LOOPBACK;/* Apply configuration */if(pObj->IO.WriteReg(pObj->DevAddr, LAN8720_BCR, readval) < 0){status =  LAN8720_STATUS_WRITE_ERROR;}}else{status = LAN8720_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:*         LAN8720_WOL_IT*         LAN8720_ENERGYON_IT*         LAN8720_AUTONEGO_COMPLETE_IT*         LAN8720_REMOTE_FAULT_IT*         LAN8720_LINK_DOWN_IT*         LAN8720_AUTONEGO_LP_ACK_IT*         LAN8720_PARALLEL_DETECTION_FAULT_IT*         LAN8720_AUTONEGO_PAGE_RECEIVED_IT* @retval LAN8720_STATUS_OK  if OK*         LAN8720_STATUS_READ_ERROR if cannot read register*         LAN8720_STATUS_WRITE_ERROR if cannot write to register*/
int32_t LAN8720_EnableIT(lan8720_Object_t *pObj, uint32_t Interrupt)
{uint32_t readval = 0;int32_t status = LAN8720_STATUS_OK;if(pObj->IO.ReadReg(pObj->DevAddr, LAN8720_IMR, &readval) >= 0){readval |= Interrupt;/* Apply configuration */if(pObj->IO.WriteReg(pObj->DevAddr, LAN8720_IMR, readval) < 0){status =  LAN8720_STATUS_WRITE_ERROR;}}else{status = LAN8720_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:*         LAN8720_WOL_IT*         LAN8720_ENERGYON_IT*         LAN8720_AUTONEGO_COMPLETE_IT*         LAN8720_REMOTE_FAULT_IT*         LAN8720_LINK_DOWN_IT*         LAN8720_AUTONEGO_LP_ACK_IT*         LAN8720_PARALLEL_DETECTION_FAULT_IT*         LAN8720_AUTONEGO_PAGE_RECEIVED_IT* @retval LAN8720_STATUS_OK  if OK*         LAN8720_STATUS_READ_ERROR if cannot read register*         LAN8720_STATUS_WRITE_ERROR if cannot write to register*/
int32_t LAN8720_DisableIT(lan8720_Object_t *pObj, uint32_t Interrupt)
{uint32_t readval = 0;int32_t status = LAN8720_STATUS_OK;if(pObj->IO.ReadReg(pObj->DevAddr, LAN8720_IMR, &readval) >= 0){readval &= ~Interrupt;/* Apply configuration */if(pObj->IO.WriteReg(pObj->DevAddr, LAN8720_IMR, readval) < 0){status = LAN8720_STATUS_WRITE_ERROR;}}else{status = LAN8720_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:*         LAN8720_WOL_IT*         LAN8720_ENERGYON_IT*         LAN8720_AUTONEGO_COMPLETE_IT*         LAN8720_REMOTE_FAULT_IT*         LAN8720_LINK_DOWN_IT*         LAN8720_AUTONEGO_LP_ACK_IT*         LAN8720_PARALLEL_DETECTION_FAULT_IT*         LAN8720_AUTONEGO_PAGE_RECEIVED_IT* @retval LAN8720_STATUS_OK  if OK*         LAN8720_STATUS_READ_ERROR if cannot read register*/
int32_t  LAN8720_ClearIT(lan8720_Object_t *pObj, uint32_t Interrupt)
{uint32_t readval = 0;int32_t status = LAN8720_STATUS_OK;if(pObj->IO.ReadReg(pObj->DevAddr, LAN8720_ISFR, &readval) < 0){status =  LAN8720_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:*         LAN8720_WOL_IT*         LAN8720_ENERGYON_IT*         LAN8720_AUTONEGO_COMPLETE_IT*         LAN8720_REMOTE_FAULT_IT*         LAN8720_LINK_DOWN_IT*         LAN8720_AUTONEGO_LP_ACK_IT*         LAN8720_PARALLEL_DETECTION_FAULT_IT*         LAN8720_AUTONEGO_PAGE_RECEIVED_IT* @retval 1 IT flag is SET*         0 IT flag is RESET*         LAN8720_STATUS_READ_ERROR if cannot read register*/
int32_t LAN8720_GetITStatus(lan8720_Object_t *pObj, uint32_t Interrupt)
{uint32_t readval = 0;int32_t status = 0;if(pObj->IO.ReadReg(pObj->DevAddr, LAN8720_ISFR, &readval) >= 0){status = ((readval & Interrupt) == Interrupt);}else{status = LAN8720_STATUS_READ_ERROR;}return status;
}/*** @}*//*** @}*//*** @}*//*** @}*/

lan8720.h
这个文件主要定义 PHY 的相关寄存器以及各个 bit,例如 LAN8720_BCRLAN8720_BSRLAN8720_BCR_SOFT_RESET

/********************************************************************************* @file    lan8720.h* @author  MCD Application Team* @brief   This file contains all the functions prototypes for the*          lan8720.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 LAN8720_H
#define LAN8720_H#ifdef __cplusplusextern "C" {
#endif   /* Includes ------------------------------------------------------------------*/
#include <stdint.h>/** @addtogroup BSP* @{*/ /** @addtogroup Component* @{*//** @defgroup LAN8720* @{*/    
/* Exported constants --------------------------------------------------------*/
/** @defgroup LAN8720_Exported_Constants LAN8720 Exported Constants* @{*/ /** @defgroup LAN8720_Registers_Mapping LAN8720 Registers Mapping* @{*/ 
#define LAN8720_BCR      ((uint16_t)0x0000U)
#define LAN8720_BSR      ((uint16_t)0x0001U)
#define LAN8720_PHYI1R   ((uint16_t)0x0002U)
#define LAN8720_PHYI2R   ((uint16_t)0x0003U)
#define LAN8720_ANAR     ((uint16_t)0x0004U)
#define LAN8720_ANLPAR   ((uint16_t)0x0005U)
#define LAN8720_ANER     ((uint16_t)0x0006U)
#define LAN8720_ANNPTR   ((uint16_t)0x0007U)
#define LAN8720_ANNPRR   ((uint16_t)0x0008U)
#define LAN8720_MMDACR   ((uint16_t)0x000DU)
#define LAN8720_MMDAADR  ((uint16_t)0x000EU)
#define LAN8720_ENCTR    ((uint16_t)0x0010U)
#define LAN8720_MCSR     ((uint16_t)0x0011U)
#define LAN8720_SMR      ((uint16_t)0x0012U)
#define LAN8720_TPDCR    ((uint16_t)0x0018U)
#define LAN8720_TCSR     ((uint16_t)0x0019U)
#define LAN8720_SECR     ((uint16_t)0x001AU)
#define LAN8720_SCSIR    ((uint16_t)0x001BU)
#define LAN8720_CLR      ((uint16_t)0x001CU)
#define LAN8720_ISFR     ((uint16_t)0x001DU)
#define LAN8720_IMR      ((uint16_t)0x001EU)
#define LAN8720_PHYSCSR  ((uint16_t)0x001FU)
/*** @}*//** @defgroup LAN8720_BCR_Bit_Definition LAN8720 BCR Bit Definition* @{*/    
#define LAN8720_BCR_SOFT_RESET         ((uint16_t)0x8000U)
#define LAN8720_BCR_LOOPBACK           ((uint16_t)0x4000U)
#define LAN8720_BCR_SPEED_SELECT       ((uint16_t)0x2000U)
#define LAN8720_BCR_AUTONEGO_EN        ((uint16_t)0x1000U)
#define LAN8720_BCR_POWER_DOWN         ((uint16_t)0x0800U)
#define LAN8720_BCR_ISOLATE            ((uint16_t)0x0400U)
#define LAN8720_BCR_RESTART_AUTONEGO   ((uint16_t)0x0200U)
#define LAN8720_BCR_DUPLEX_MODE        ((uint16_t)0x0100U) 
/*** @}*//** @defgroup LAN8720_BSR_Bit_Definition LAN8720 BSR Bit Definition* @{*/   
#define LAN8720_BSR_100BASE_T4       ((uint16_t)0x8000U)
#define LAN8720_BSR_100BASE_TX_FD    ((uint16_t)0x4000U)
#define LAN8720_BSR_100BASE_TX_HD    ((uint16_t)0x2000U)
#define LAN8720_BSR_10BASE_T_FD      ((uint16_t)0x1000U)
#define LAN8720_BSR_10BASE_T_HD      ((uint16_t)0x0800U)
#define LAN8720_BSR_100BASE_T2_FD    ((uint16_t)0x0400U)
#define LAN8720_BSR_100BASE_T2_HD    ((uint16_t)0x0200U)
#define LAN8720_BSR_EXTENDED_STATUS  ((uint16_t)0x0100U)
#define LAN8720_BSR_AUTONEGO_CPLT    ((uint16_t)0x0020U)
#define LAN8720_BSR_REMOTE_FAULT     ((uint16_t)0x0010U)
#define LAN8720_BSR_AUTONEGO_ABILITY ((uint16_t)0x0008U)
#define LAN8720_BSR_LINK_STATUS      ((uint16_t)0x0004U)
#define LAN8720_BSR_JABBER_DETECT    ((uint16_t)0x0002U)
#define LAN8720_BSR_EXTENDED_CAP     ((uint16_t)0x0001U)
/*** @}*//** @defgroup LAN8720_PHYI1R_Bit_Definition LAN8720 PHYI1R Bit Definition* @{*/
#define LAN8720_PHYI1R_OUI_3_18           ((uint16_t)0xFFFFU)
/*** @}*//** @defgroup LAN8720_PHYI2R_Bit_Definition LAN8720 PHYI2R Bit Definition* @{*/
#define LAN8720_PHYI2R_OUI_19_24          ((uint16_t)0xFC00U)
#define LAN8720_PHYI2R_MODEL_NBR          ((uint16_t)0x03F0U)
#define LAN8720_PHYI2R_REVISION_NBR       ((uint16_t)0x000FU)
/*** @}*//** @defgroup LAN8720_ANAR_Bit_Definition LAN8720 ANAR Bit Definition* @{*/
#define LAN8720_ANAR_NEXT_PAGE               ((uint16_t)0x8000U)
#define LAN8720_ANAR_REMOTE_FAULT            ((uint16_t)0x2000U)
#define LAN8720_ANAR_PAUSE_OPERATION         ((uint16_t)0x0C00U)
#define LAN8720_ANAR_PO_NOPAUSE              ((uint16_t)0x0000U)
#define LAN8720_ANAR_PO_SYMMETRIC_PAUSE      ((uint16_t)0x0400U)
#define LAN8720_ANAR_PO_ASYMMETRIC_PAUSE     ((uint16_t)0x0800U)
#define LAN8720_ANAR_PO_ADVERTISE_SUPPORT    ((uint16_t)0x0C00U)
#define LAN8720_ANAR_100BASE_TX_FD           ((uint16_t)0x0100U)
#define LAN8720_ANAR_100BASE_TX              ((uint16_t)0x0080U)
#define LAN8720_ANAR_10BASE_T_FD             ((uint16_t)0x0040U)
#define LAN8720_ANAR_10BASE_T                ((uint16_t)0x0020U)
#define LAN8720_ANAR_SELECTOR_FIELD          ((uint16_t)0x000FU)
/*** @}*//** @defgroup LAN8720_ANLPAR_Bit_Definition LAN8720 ANLPAR Bit Definition* @{*/
#define LAN8720_ANLPAR_NEXT_PAGE            ((uint16_t)0x8000U)
#define LAN8720_ANLPAR_REMOTE_FAULT         ((uint16_t)0x2000U)
#define LAN8720_ANLPAR_PAUSE_OPERATION      ((uint16_t)0x0C00U)
#define LAN8720_ANLPAR_PO_NOPAUSE           ((uint16_t)0x0000U)
#define LAN8720_ANLPAR_PO_SYMMETRIC_PAUSE   ((uint16_t)0x0400U)
#define LAN8720_ANLPAR_PO_ASYMMETRIC_PAUSE  ((uint16_t)0x0800U)
#define LAN8720_ANLPAR_PO_ADVERTISE_SUPPORT ((uint16_t)0x0C00U)
#define LAN8720_ANLPAR_100BASE_TX_FD        ((uint16_t)0x0100U)
#define LAN8720_ANLPAR_100BASE_TX           ((uint16_t)0x0080U)
#define LAN8720_ANLPAR_10BASE_T_FD          ((uint16_t)0x0040U)
#define LAN8720_ANLPAR_10BASE_T             ((uint16_t)0x0020U)
#define LAN8720_ANLPAR_SELECTOR_FIELD       ((uint16_t)0x000FU)
/*** @}*//** @defgroup LAN8720_ANER_Bit_Definition LAN8720 ANER Bit Definition* @{*/
#define LAN8720_ANER_RX_NP_LOCATION_ABLE    ((uint16_t)0x0040U)
#define LAN8720_ANER_RX_NP_STORAGE_LOCATION ((uint16_t)0x0020U)
#define LAN8720_ANER_PARALLEL_DETECT_FAULT  ((uint16_t)0x0010U)
#define LAN8720_ANER_LP_NP_ABLE             ((uint16_t)0x0008U)
#define LAN8720_ANER_NP_ABLE                ((uint16_t)0x0004U)
#define LAN8720_ANER_PAGE_RECEIVED          ((uint16_t)0x0002U)
#define LAN8720_ANER_LP_AUTONEG_ABLE        ((uint16_t)0x0001U)
/*** @}*//** @defgroup LAN8720_ANNPTR_Bit_Definition LAN8720 ANNPTR Bit Definition* @{*/
#define LAN8720_ANNPTR_NEXT_PAGE         ((uint16_t)0x8000U)
#define LAN8720_ANNPTR_MESSAGE_PAGE      ((uint16_t)0x2000U)
#define LAN8720_ANNPTR_ACK2              ((uint16_t)0x1000U)
#define LAN8720_ANNPTR_TOGGLE            ((uint16_t)0x0800U)
#define LAN8720_ANNPTR_MESSAGGE_CODE     ((uint16_t)0x07FFU)
/*** @}*//** @defgroup LAN8720_ANNPRR_Bit_Definition LAN8720 ANNPRR Bit Definition* @{*/
#define LAN8720_ANNPTR_NEXT_PAGE         ((uint16_t)0x8000U)
#define LAN8720_ANNPRR_ACK               ((uint16_t)0x4000U)
#define LAN8720_ANNPRR_MESSAGE_PAGE      ((uint16_t)0x2000U)
#define LAN8720_ANNPRR_ACK2              ((uint16_t)0x1000U)
#define LAN8720_ANNPRR_TOGGLE            ((uint16_t)0x0800U)
#define LAN8720_ANNPRR_MESSAGGE_CODE     ((uint16_t)0x07FFU)
/*** @}*//** @defgroup LAN8720_MMDACR_Bit_Definition LAN8720 MMDACR Bit Definition* @{*/
#define LAN8720_MMDACR_MMD_FUNCTION       ((uint16_t)0xC000U) 
#define LAN8720_MMDACR_MMD_FUNCTION_ADDR  ((uint16_t)0x0000U)
#define LAN8720_MMDACR_MMD_FUNCTION_DATA  ((uint16_t)0x4000U)
#define LAN8720_MMDACR_MMD_DEV_ADDR       ((uint16_t)0x001FU)
/*** @}*//** @defgroup LAN8720_ENCTR_Bit_Definition LAN8720 ENCTR Bit Definition* @{*/
#define LAN8720_ENCTR_TX_ENABLE             ((uint16_t)0x8000U)
#define LAN8720_ENCTR_TX_TIMER              ((uint16_t)0x6000U)
#define LAN8720_ENCTR_TX_TIMER_1S           ((uint16_t)0x0000U)
#define LAN8720_ENCTR_TX_TIMER_768MS        ((uint16_t)0x2000U)
#define LAN8720_ENCTR_TX_TIMER_512MS        ((uint16_t)0x4000U)
#define LAN8720_ENCTR_TX_TIMER_265MS        ((uint16_t)0x6000U)
#define LAN8720_ENCTR_RX_ENABLE             ((uint16_t)0x1000U)
#define LAN8720_ENCTR_RX_MAX_INTERVAL       ((uint16_t)0x0C00U)
#define LAN8720_ENCTR_RX_MAX_INTERVAL_64MS  ((uint16_t)0x0000U)
#define LAN8720_ENCTR_RX_MAX_INTERVAL_256MS ((uint16_t)0x0400U)
#define LAN8720_ENCTR_RX_MAX_INTERVAL_512MS ((uint16_t)0x0800U)
#define LAN8720_ENCTR_RX_MAX_INTERVAL_1S    ((uint16_t)0x0C00U)
#define LAN8720_ENCTR_EX_CROSS_OVER         ((uint16_t)0x0002U)
#define LAN8720_ENCTR_EX_MANUAL_CROSS_OVER  ((uint16_t)0x0001U)
/*** @}*//** @defgroup LAN8720_MCSR_Bit_Definition LAN8720 MCSR Bit Definition* @{*/
#define LAN8720_MCSR_EDPWRDOWN        ((uint16_t)0x2000U)
#define LAN8720_MCSR_FARLOOPBACK      ((uint16_t)0x0200U)
#define LAN8720_MCSR_ALTINT           ((uint16_t)0x0040U)
#define LAN8720_MCSR_ENERGYON         ((uint16_t)0x0002U)
/*** @}*//** @defgroup LAN8720_SMR_Bit_Definition LAN8720 SMR Bit Definition* @{*/
#define LAN8720_SMR_MODE       ((uint16_t)0x00E0U)
#define LAN8720_SMR_PHY_ADDR   ((uint16_t)0x001FU)
/*** @}*//** @defgroup LAN8720_TPDCR_Bit_Definition LAN8720 TPDCR Bit Definition* @{*/
#define LAN8720_TPDCR_DELAY_IN                 ((uint16_t)0x8000U)
#define LAN8720_TPDCR_LINE_BREAK_COUNTER       ((uint16_t)0x7000U)
#define LAN8720_TPDCR_PATTERN_HIGH             ((uint16_t)0x0FC0U)
#define LAN8720_TPDCR_PATTERN_LOW              ((uint16_t)0x003FU)
/*** @}*//** @defgroup LAN8720_TCSR_Bit_Definition LAN8720 TCSR Bit Definition* @{*/
#define LAN8720_TCSR_TDR_ENABLE           ((uint16_t)0x8000U)
#define LAN8720_TCSR_TDR_AD_FILTER_ENABLE ((uint16_t)0x4000U)
#define LAN8720_TCSR_TDR_CH_CABLE_TYPE    ((uint16_t)0x0600U)
#define LAN8720_TCSR_TDR_CH_CABLE_DEFAULT ((uint16_t)0x0000U)
#define LAN8720_TCSR_TDR_CH_CABLE_SHORTED ((uint16_t)0x0200U)
#define LAN8720_TCSR_TDR_CH_CABLE_OPEN    ((uint16_t)0x0400U)
#define LAN8720_TCSR_TDR_CH_CABLE_MATCH   ((uint16_t)0x0600U)
#define LAN8720_TCSR_TDR_CH_STATUS        ((uint16_t)0x0100U)
#define LAN8720_TCSR_TDR_CH_LENGTH        ((uint16_t)0x00FFU)
/*** @}*//** @defgroup LAN8720_SCSIR_Bit_Definition LAN8720 SCSIR Bit Definition* @{*/
#define LAN8720_SCSIR_AUTO_MDIX_ENABLE    ((uint16_t)0x8000U)
#define LAN8720_SCSIR_CHANNEL_SELECT      ((uint16_t)0x2000U)
#define LAN8720_SCSIR_SQE_DISABLE         ((uint16_t)0x0800U)
#define LAN8720_SCSIR_XPOLALITY           ((uint16_t)0x0010U)
/*** @}*//** @defgroup LAN8720_CLR_Bit_Definition LAN8720 CLR Bit Definition* @{*/
#define LAN8720_CLR_CABLE_LENGTH       ((uint16_t)0xF000U)
/*** @}*//** @defgroup LAN8720_IMR_ISFR_Bit_Definition LAN8720 IMR ISFR Bit Definition* @{*/
#define LAN8720_INT_8       ((uint16_t)0x0100U)
#define LAN8720_INT_7       ((uint16_t)0x0080U)
#define LAN8720_INT_6       ((uint16_t)0x0040U)
#define LAN8720_INT_5       ((uint16_t)0x0020U)
#define LAN8720_INT_4       ((uint16_t)0x0010U)
#define LAN8720_INT_3       ((uint16_t)0x0008U)
#define LAN8720_INT_2       ((uint16_t)0x0004U)
#define LAN8720_INT_1       ((uint16_t)0x0002U)
/*** @}*//** @defgroup LAN8720_PHYSCSR_Bit_Definition LAN8720 PHYSCSR Bit Definition* @{*/
#define LAN8720_PHYSCSR_AUTONEGO_DONE   ((uint16_t)0x1000U)
#define LAN8720_PHYSCSR_HCDSPEEDMASK    ((uint16_t)0x001CU)
#define LAN8720_PHYSCSR_10BT_HD         ((uint16_t)0x0004U)
#define LAN8720_PHYSCSR_10BT_FD         ((uint16_t)0x0014U)
#define LAN8720_PHYSCSR_100BTX_HD       ((uint16_t)0x0008U)
#define LAN8720_PHYSCSR_100BTX_FD       ((uint16_t)0x0018U) 
/*** @}*//** @defgroup LAN8720_Status LAN8720 Status* @{*/    #define  LAN8720_STATUS_READ_ERROR            ((int32_t)-5)
#define  LAN8720_STATUS_WRITE_ERROR           ((int32_t)-4)
#define  LAN8720_STATUS_ADDRESS_ERROR         ((int32_t)-3)
#define  LAN8720_STATUS_RESET_TIMEOUT         ((int32_t)-2)
#define  LAN8720_STATUS_ERROR                 ((int32_t)-1)
#define  LAN8720_STATUS_OK                    ((int32_t) 0)
#define  LAN8720_STATUS_LINK_DOWN             ((int32_t) 1)
#define  LAN8720_STATUS_100MBITS_FULLDUPLEX   ((int32_t) 2)
#define  LAN8720_STATUS_100MBITS_HALFDUPLEX   ((int32_t) 3)
#define  LAN8720_STATUS_10MBITS_FULLDUPLEX    ((int32_t) 4)
#define  LAN8720_STATUS_10MBITS_HALFDUPLEX    ((int32_t) 5)
#define  LAN8720_STATUS_AUTONEGO_NOTDONE      ((int32_t) 6)
/*** @}*//** @defgroup LAN8720_IT_Flags LAN8720 IT Flags* @{*/     
#define  LAN8720_WOL_IT                        LAN8720_INT_8
#define  LAN8720_ENERGYON_IT                   LAN8720_INT_7
#define  LAN8720_AUTONEGO_COMPLETE_IT          LAN8720_INT_6
#define  LAN8720_REMOTE_FAULT_IT               LAN8720_INT_5
#define  LAN8720_LINK_DOWN_IT                  LAN8720_INT_4
#define  LAN8720_AUTONEGO_LP_ACK_IT            LAN8720_INT_3
#define  LAN8720_PARALLEL_DETECTION_FAULT_IT   LAN8720_INT_2
#define  LAN8720_AUTONEGO_PAGE_RECEIVED_IT     LAN8720_INT_1
/*** @}*//*** @}*//* Exported types ------------------------------------------------------------*/ 
/** @defgroup LAN8720_Exported_Types LAN8720 Exported Types* @{*/
typedef int32_t  (*lan8720_Init_Func) (void); 
typedef int32_t  (*lan8720_DeInit_Func) (void);
typedef int32_t  (*lan8720_ReadReg_Func)   (uint32_t, uint32_t, uint32_t *);
typedef int32_t  (*lan8720_WriteReg_Func)  (uint32_t, uint32_t, uint32_t);
typedef int32_t  (*lan8720_GetTick_Func)  (void);typedef struct 
{                   lan8720_Init_Func      Init; lan8720_DeInit_Func    DeInit;lan8720_WriteReg_Func  WriteReg;lan8720_ReadReg_Func   ReadReg; lan8720_GetTick_Func   GetTick;   
} lan8720_IOCtx_t;  typedef struct 
{uint32_t            DevAddr;uint32_t            Is_Initialized;lan8720_IOCtx_t     IO;void               *pData;
}lan8720_Object_t;
/*** @}*/ /* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup LAN8720_Exported_Functions LAN8720 Exported Functions* @{*/
int32_t LAN8720_RegisterBusIO(lan8720_Object_t *pObj, lan8720_IOCtx_t *ioctx);
int32_t LAN8720_Init(lan8720_Object_t *pObj);
int32_t LAN8720_DeInit(lan8720_Object_t *pObj);
int32_t LAN8720_DisablePowerDownMode(lan8720_Object_t *pObj);
int32_t LAN8720_EnablePowerDownMode(lan8720_Object_t *pObj);
int32_t LAN8720_StartAutoNego(lan8720_Object_t *pObj);
int32_t LAN8720_GetLinkState(lan8720_Object_t *pObj);
int32_t LAN8720_SetLinkState(lan8720_Object_t *pObj, uint32_t LinkState);
int32_t LAN8720_EnableLoopbackMode(lan8720_Object_t *pObj);
int32_t LAN8720_DisableLoopbackMode(lan8720_Object_t *pObj);
int32_t LAN8720_EnableIT(lan8720_Object_t *pObj, uint32_t Interrupt);
int32_t LAN8720_DisableIT(lan8720_Object_t *pObj, uint32_t Interrupt);
int32_t LAN8720_ClearIT(lan8720_Object_t *pObj, uint32_t Interrupt);
int32_t LAN8720_GetITStatus(lan8720_Object_t *pObj, uint32_t Interrupt);
/*** @}*/ #ifdef __cplusplus
}
#endif
#endif /* LAN8720_H *//*** @}*/ /*** @}*//*** @}*/ /*** @}*/       

PHY 接口测试

前面分别实现了 PHY 的读写接口,以及 LAN8720 相关的接口,这里简单测试一下,LAN8720 寄存器的读写功能

/* USER CODE BEGIN 0 */
static void print_binary(int value, int bits)
{for (int i = bits - 1; i >= 0; i--){printf("%d", (value >> i) & 1);}printf("b\r\n");
}static void MY_PHY_LAN8720_INIT(void)
{/* Set PHY IO functions */LAN8720_RegisterBusIO(&LAN8720, &LAN8720_IOCtx);/* Initialize the LAN8742 ETH PHY */if(LAN8720_Init(&LAN8720) != LAN8720_STATUS_OK){printf("init lan8720 error\r\n");while(1);}printf("my phy addr = %d\r\n", LAN8720.DevAddr);uint32_t readval = 0;if(LAN8720_IOCtx.ReadReg(LAN8720.DevAddr, LAN8720_PHYI1R, &readval) < 0){printf("read lan8720 error\r\n");while(1);}printf("LAN8720_PHYI1R PHY ID Number = %d\r\n", readval);readval = 0;if(LAN8720_IOCtx.ReadReg(LAN8720.DevAddr, LAN8720_PHYI2R, &readval) < 0){printf("read lan8720 error\r\n");while(1);}uint32_t bits_15_10 = (readval >> 10) & 0x3F; // 提取 bit15:10printf("LAN8720_PHYI2R PHY ID Number = ");print_binary(bits_15_10, 6); // bit15:10 共 6 位uint32_t bits_9_4 = (readval >> 4) & 0x3F; // 提取 bit9:4 (6 位)printf("LAN8720_PHYI2R Model Number  = ");print_binary(bits_9_4, 6); // bit15:10 共 6 位readval = 0;if(LAN8720_IOCtx.ReadReg(LAN8720.DevAddr, LAN8720_BCR, &readval) < 0){printf("read lan8720 error\r\n");while(1);}printf("before write: %d\r\n", readval);readval |= LAN8720_BCR_LOOPBACK;if(LAN8720_IOCtx.WriteReg(LAN8720.DevAddr, LAN8720_BCR, readval) < 0){printf("write lan8720 error\r\n");while(1);}readval = 0;if(LAN8720_IOCtx.ReadReg(LAN8720.DevAddr, LAN8720_BCR, &readval) < 0){printf("read lan8720 error\r\n");while(1);}printf("after bit14 set = ");print_binary(readval, 16); // 共 16 位
}
/* USER CODE END 0 */
  /* USER CODE BEGIN 2 */MY_PHY_LAN8720_INIT();printf("this is eht example\r\n");/* USER CODE END 2 */
  • 代码中先读取了 PHY 的地址
  • 读取 LAN8720_PHYI1R 寄存器获取 PHY ID Number
  • 读取 LAN8720_PHYI2R 寄存器获取 PHY ID NumberModel Number
  • 最后对 LAN8720_BCRbit14 进行了读写

部分地址的描述如下
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

效果如下

my phy addr = 0
PHY ID Number = 110000b
Model Number  = 001111b
before write: 0
after bit14 set = 0100000000000000b
this is eht example

相关文章:

PHY——LAN8720A 寄存器读写 (二)

文章目录 PHY——LAN8720A 寄存器读写 (二)工程配置引脚初始化代码以太网初始化代码PHY 接口实现LAN8720 接口实现PHY 接口测试 PHY——LAN8720A 寄存器读写 (二) 工程配置 这里以野火电子的 F429 开发板为例&#xff0c;配置以太网外设 这里有一点需要注意原理图 RMII_TXD0…...

HTML5和CSS3的一些特性

HTML5 和 CSS3 是现代网页设计的基础技术&#xff0c;它们引入了许多新特性和功能&#xff0c;极大地丰富了网页的表现力和交互能力。 HTML5 的一些重要特性包括&#xff1a; 新的语义化标签: HTML5 引入了一些重要的语义化标签如 <header>, <footer>, <articl…...

sass报错,忽略 Sass 弃用警告,降级版本

最有效的方法是创建一个 .sassrc.json 文件来配置 Sass 编译器。告诉 Sass 编译器忽略来自依赖项的警告消息。 解决方案&#xff1a; 1. 在项目根目录创建 .sassrc.json 文件&#xff1a; {"quietDeps": true }这个配置会让 Sass 编译器忽略所有来自依赖项&#x…...

DeepSeek+Kimi:PPT制作的效率革命

摘要&#xff1a;传统PPT制作面临模板选择困难、内容逻辑混乱、设计排版能力有限以及反复修改等问题。DeepSeek和Kimi两款AI工具的组合为PPT制作提供了全新的解决方案。DeepSeek擅长内容生成与逻辑推理&#xff0c;能够快速生成高质量的PPT大纲和内容&#xff1b;Kimi则专注于长…...

transformers中学习率warmup策略具体如何设置

在使用 get_linear_schedule_with_warmup&#xff08;如 Hugging Face Transformers 库中的学习率调度器&#xff09;时&#xff0c;参数的合理设置需要结合 数据量&#xff08;dataset size&#xff09;、批次大小&#xff08;batch size&#xff09; 和 训练轮数&#xff08;…...

linux实现rsync+sersync实时数据备份

1.概述 rsync(Remote Sync) 是一个Unix/linux系统下的文件同步和传输工具 2.端口和运行模式 tcp/873 采用C/S模式&#xff08;客户端/服务器模式&#xff09; 3.特点 可以镜像保存整个目录和文件第一次全量备份(备份全部的文件),之后是增量备份(只备份变化的文件) 4. 数…...

CTF类题目复现总结-[MRCTF2020]ezmisc 1

一、题目地址 https://buuoj.cn/challenges#[MRCTF2020]ezmisc二、复现步骤 1、下载附件&#xff0c;得到一张图片&#xff1b; 2、利用010 Editor打开图片&#xff0c;提示CRC值校验错误&#xff0c;flag.png应该是宽和高被修改了&#xff0c;导致flag被隐藏掉&#xff1b;…...

『Linux』 第十一章 线程同步与互斥

1. 线程互斥 1.1 进程线程间的互斥相关背景概念 临界资源&#xff1a;多线程执行流共享的资源就叫做临界资源临界区&#xff1a;每个线程内部&#xff0c;访问临界资源的代码&#xff0c;就叫做临界区互斥&#xff1a;任何时刻&#xff0c;互斥保证有且只有一个执行流进入临界…...

【数据结构】队列

目录 一、队列1、概念与结构2、队列的实现3、队列的初始化4、打印队列数据5、入队6、销毁队列7、队列判空8、出队9、取队头、队尾数据10、队列中有效元素个数 二、源码 个人主页&#xff0c;点击这里~ 数据结构专栏&#xff0c;点击这里~ 一、队列 1、概念与结构 概念&#x…...

【导航定位】GNSS数据协议-RINEX OBS

RINEX协议 RINEX(Receiver INdependent EXchange format,与接收机无关的交换格式)是一种在GPS测量应用中普遍采用的标准数据格式,该格式采用文本文件形式&#xff08;ASCII码&#xff09;存储数据数据记录格式与接收机的制造厂商和具体型号无关。目前RINEX版本已经发布到了4.x…...

Qt中的事件循环

Qt的事件循环是其核心机制之一&#xff0c;它是一种消息处理机制&#xff0c;负责处理各种事件(如用户输入、定时器、网络请求等)的分发和处理。Qt中的事件循环是一个持续运行的循环&#xff0c;负责接收事件并将它们分发给相应的对象进行处理。当没有事件需要处理时&#xff0…...

Android并发编程:线程池与协程的核心区别与最佳实践指南

1. 基本概念对比 特性 线程池 (ThreadPool) 协程 (Coroutine) 本质 Java线程管理机制 Kotlin轻量级并发框架 最小执行单元 线程(Thread) 协程(Coroutine) 创建开销 较高(需分配系统线程资源) 极低(用户态调度) 并发模型 基于线程的抢占式调度 基于协程的协作式调度 2. 核心差异…...

吴恩达深度学习复盘(2)神经网络的基本原理轮廓

笔者注 这两节课主要介绍了神经网络的大的轮廓。而神经网络基本上是在模拟人类大脑的工作模式&#xff0c;有些仿生学的意味。为了便于理解&#xff0c;搜集了一些脑神经的资料&#xff0c;这部分是课程中没有讲到的。 首先要了解一下大脑神经元之间结构。 细胞体&#xff1…...

【redis】集群 数据分片算法:哈希求余、一致性哈希、哈希槽分区算法

文章目录 什么是集群数据分片算法哈希求余分片搬运 一致性哈希扩容 哈希槽分区算法扩容相关问题 什么是集群 广义的集群&#xff0c;只要你是多个机器&#xff0c;构成了分布式系统&#xff0c;都可以称为是一个“集群” 前面的“主从结构”和“哨兵模式”可以称为是“广义的…...

计算机组成原理笔记(六)——2.2机器数的定点表示和浮点表示

计算机在进行算术运算时&#xff0c;需要指出小数点的位置&#xff0c;根据小数点的位置是否固定&#xff0c;在计算机中有两种数据格式:定点表示和浮点表示。 2.2.1定点表示法 一、基本概念 定点表示法是一种小数点的位置固定不变的数据表示方式&#xff0c;用于表示整数或…...

将树莓派5当做Ollama服务器,C#调用generate的API的示例

其实完全没这个必要&#xff0c;性能用脚后跟想都会很差。但基于上一篇文章的成果&#xff0c;来都来了就先简单试试吧。 先来看看这个拼夕夕上五百多块钱能达到的效果&#xff1a; 只要对速度没要求&#xff0c;那感觉就还行。 Ollama默认只在本地回环&#xff08;127.0.0…...

MYSQL数据库(一)

一.数据库的操作 1.显示数据库 show databases; 2.创建数据库 create database 数据库名; 3.使用数据库 use 数据库名; 4.删除数据库 drop database 数据库名; drop database if exists 数据库名; 二.表的操作 1.显示所有表 show tables; 2.查看表结构 des…...

Python Cookbook-4.15 字典的一键多值

任务 需要一个字典&#xff0c;能够将每个键映射到多个值上。 解决方案 正常情况下&#xff0c;字典是一对一映射的&#xff0c;但要实现一对多映射也不难&#xff0c;换句话说&#xff0c;即一个键对应多个值。你有两个可选方案&#xff0c;但具体要看你怎么看待键的多个对…...

IDEA 终端 vs CMD:为什么 java -version 显示的 JDK 版本不一致?

前言&#xff1a;离谱的 JDK 版本问题 今天遇到了一个让人抓狂的现象&#xff1a;在 Windows 的 CMD 里输入 java -version 和在 IntelliJ IDEA 终端输入 java -version&#xff0c;居然显示了不同的 JDK 版本&#xff01; 本以为是环境变量、缓存或者 IDEA 设置的问题&#x…...

Flask登录页面后点击按钮在远程CentOS上自动执行一条命令

templates文件夹和app.py在同一目录下。 templates文件夹下包括2个文件&#xff1a;index.html login.html app.py代码如下&#xff1a; import os import time from flask import Flask, render_template, request, redirect, session, make_response import mysql.con…...

深度解析:文件夹变白色文件的数据恢复之道

在数字化时代&#xff0c;数据的重要性不言而喻。然而&#xff0c;当我们在使用计算机时&#xff0c;偶尔会遇到一些棘手的问题&#xff0c;其中“文件夹变白色文件”便是一个令人困惑且亟待解决的难题。这一现象不仅影响了文件的正常访问&#xff0c;更可能隐藏着数据丢失的风…...

【Matlab】-- 基于MATLAB的飞蛾扑火算法与反向传播算法的混凝土强度预测

文章目录 文章目录 01 内容概要02 MFO-BP模型03 部分代码04 运行结果05 参考文献06 代码下载 01 内容概要 本资料介绍了一种基于飞蛾扑火算法&#xff08;Moth Flame Optimization, MFO&#xff09;与反向传播算法&#xff08;Backpropagation, BP&#xff09;的混凝土强度预…...

【Python实例学习笔记】图像相似度计算--哈希算法

【Python实例学习笔记】图像相似度计算--哈希算法 一、哈希算法的实现步骤&#xff1a;二、对每一步都进行注解的代码 一、哈希算法的实现步骤&#xff1a; 1、缩小尺寸&#xff1a; 将图像缩小到8*8的尺寸&#xff0c;总共64个像素。这一步的作用是去除图像的细节&#xff0c…...

2025DevSecOps标杆案例|智能制造国际领导厂商敏捷安全工具链实践

某智能制造国际领导厂商是涵盖智能家居、楼宇科技&#xff0c;工业技术、机器人与自动化和数字化创新业务五大业务板块为一体的全球化科技集团&#xff0c;连续入选《财富》世界500强&#xff0c;每年为全球超过4亿用户、各领域的重要客户与战略合作伙伴提供产品和服务。 数智化…...

【YOLOv11】目标检测任务-实操过程

目录 一、torch环境安装1.1 创建虚拟环境1.2 启动虚拟环境1.3 安装pytorch1.4 验证cuda是否可用 二、yolo模型推理2.1 下载yolo模型2.2 创建模型推理文件2.3 推理结果保存路径 三、labelimg数据标注3.1 安装labelimg3.2 解决浮点数报错3.3 labelimg UI界面介绍3.4 数据标注案例…...

第十七章:Python数据可视化工工具-Pyecharts库

一、Pyecharts简介 资源绑定附上完整资源供读者参考学习&#xff01; Pyecharts是一个基于百度开源可视化库ECharts的Python数据可视化工具&#xff0c;支持生成交互式的HTML格式图表。相较于Matplotlib等静态图表库&#xff0c;Pyecharts具有以下优势&#xff1a; 丰富的图表…...

解决【vite-plugin-top-level-await】 插件导致的 Bindings Not Found 错误

解决【vite-plugin-top-level-await】 插件导致的 Bindings Not Found 错误 环境设置 操作系统: macOS硬件平台: M1 Pro前端框架: Vue 3Node.js 版本: 20 在使用 Vue 项目时&#xff0c;我们尝试集成 vite-plugin-top-level-await 插件以支持顶层 await 语法。然而&#xff…...

《八大排序算法》

相关概念 排序&#xff1a;使一串记录&#xff0c;按照其中某个或某些关键字的大小&#xff0c;递增或递减的排列起来。稳定性&#xff1a;它描述了在排序过程中&#xff0c;相等元素的相对顺序是否保持不变。假设在待排序的序列中&#xff0c;有两个元素a和b&#xff0c;它们…...

六十天前端强化训练之第三十七天之Docker 容器化部署实战指南(大师级详解)

欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗&#xff0c;谢谢大佬&#xff01; 目录 一、Docker 核心知识体系 1.1 容器革命&#xff1a;改变开发方式的技术 1.2 Docker 三剑客 1.3 Docker 生命周期管理 1.4 关键命令详解 二、前端容器化实战案例&#xff…...

RabbitMQ--延迟队列事务消息分发

目录 1.延迟队列 1.1应用场景 1.2利用TTL死信队列模拟延迟队列存在的问题 1.3延迟队列插件 1.4常见面试题 2.事务 2.1配置事务管理器 3.消息分发 3.1概念 3.2应用场景 3.2.1限流 3.2.2负载均衡 1.延迟队列 延迟队列(Delayed Queue)&#xff0c;即消息被发送以后, 并…...

列表,元组,字典,集合,之间的嵌套关系

在 Python 中&#xff0c;列表、元组、字典和集合的嵌套关系需要遵循各自的特性&#xff08;如可变性、可哈希性&#xff09;。以下是它们之间的嵌套规则、示例和典型应用场景的详细梳理&#xff1a; 1. 列表&#xff08;List&#xff09;的嵌套 特性&#xff1a; 可变、有序…...

【行驶证识别】批量咕嘎OCR识别行驶证照片复印件图片里的文字信息保存表格或改名字,基于QT和腾讯云api_ocr的实现方式

项目背景 在许多业务场景中,如物流管理、车辆租赁、保险理赔等,常常需要处理大量的行驶证照片复印件。手动录入行驶证上的文字信息,像车主姓名、车辆型号、车牌号码等,不仅效率低下,还容易出现人为错误。借助 OCR(光学字符识别)技术,能够自动识别行驶证图片中的文字信…...

鸿蒙HarmonyOS NEXT设备升级应用数据迁移流程

数据迁移是什么 什么是数据迁移&#xff0c;对用户来讲就是本地数据的迁移&#xff0c;终端设备从HarmonyOS 3.1 Release API 9及之前版本&#xff08;单框架&#xff09;迁移到HarmonyOS NEXT&#xff08;双框架&#xff09;后保证本地数据不丢失。例如&#xff0c;我在某APP…...

MCP从零开始

MCP简介 MCP&#xff0c;全称是Model Context Protocol&#xff0c;模型上下文协议&#xff0c;由Claude母公司Anthropic于去年11月正式提出。MCP解决的最大痛点就是Agent开发中调用外部工具的技术门槛过高的问题。 能调用外部工具&#xff0c;是大模型进化为智能体Agent的关…...

Three.js 快速入门教程【十九】CSS2DRenderer(CSS2D渲染器)介绍,实现场景中物体或设备标注标签信息

系列文章目录 Three.js 快速入门教程【一】开启你的 3D Web 开发之旅 Three.js 快速入门教程【二】透视投影相机 Three.js 快速入门教程【三】渲染器 Three.js 快速入门教程【四】三维坐标系 Three.js 快速入门教程【五】动画渲染循环 Three.js 快速入门教程【六】相机控件 Or…...

横扫SQL面试——连续性登录问题

横扫SQL面试 &#x1f4cc; 连续性登录问题 在互联网公司的SQL面试中&#xff0c;连续性问题堪称“必考之王”。&#x1f4bb;&#x1f50d; 用户连续登录7天送优惠券&#x1f31f;&#xff0c;服务器连续报警3次触发熔断⚠️&#xff0c;图书馆连续3天人流破百开启限流⚡” …...

爱因斯坦求和 torch

目录 向量点积 矩阵乘法 矩阵转置 向量转换相机坐标系 在 Python 的科学计算库&#xff08;如 NumPy&#xff09;中&#xff0c;einsum 是一个强大的函数&#xff0c;它可以简洁地表示各种张量运算。下面是几个不同类型的使用示例&#xff1a; 向量点积 向量点积是两个向量…...

Spring Initializr搭建spring boot项目

介绍 Spring Initializr 是一个用于快速生成 Spring Boot 项目结构的工具。它为开发者提供了一种便捷的方式&#xff0c;可以从预先定义的模板中创建一个新的 Spring Boot 应用程序&#xff0c;从而节省了从头开始设置项目的大量时间。 使用 Spring Initializr&#xff0c;你…...

【实战】渗透测试下的文件操作

目录 Linux查找文件 Windows查找文件 查找可写目录 windows Linux 创建 Windows Linux 压缩 解压 远程解压文件 Linux查找文件 >find / -name index.php 查找木马文件 >find . -name *.php | xargs grep -n eval( >find . -name *.php | xargs grep -n ass…...

MATLAB 控制系统设计与仿真 - 30

用极点配置设计伺服系统 方法2-反馈修正 如果我们想只用前馈校正输入&#xff0c;从而达到伺服控制的效果&#xff0c;我们需要很精确的知道系统的参数模型&#xff0c;否则系统输出仍然具有较大的静态误差。 但是如果我们在误差比较器和系统的前馈通道之间插入一个积分器&a…...

P1091 [NOIP 2004 提高组] 合唱队形

题目链接&#xff1a; 思路&#xff1a; 题目意思&#xff0c;找出最少的同学出列&#xff0c;保证学生 1-t 上升&#xff0c; t-n 下降。我们只要求出每个点的最长上升子序列和最长不上升子序列&#xff0c;然后总人数-最长上升子序列和最长不上升子序列1&#xff0c;就是最少…...

小林coding-12道Spring面试题

1.说一下你对 Spring 的理解?spring的核心思想说说你的理解&#xff1f; 2.Spring IoC和AOP 介绍一下?Spring的aop介绍一下?IOC和AOP是通过什么机制来实现的?怎么理解SpringIoc&#xff1f;依赖倒置&#xff0c;依赖注入&#xff0c;控制反转分别是什么&#xff1f;依赖注…...

通过Spring Boot集成WebSocket进行消息通信

文章目录 通过Spring Boot集成WebSocket进行消息通信1. 创建 Spring Boot 项目2. 添加 WebSocket 依赖3. 配置 WebSocket4. 创建 WebSocket 处理器5. 创建控制器&#xff08;可选&#xff09;6. 前端页面测试7. 运行项目注意事项 通过Spring Boot集成WebSocket进行消息通信 1.…...

ComfyUI发展全景:从AI绘画新星到多功能创意平台的崛起

在人工智能技术迅猛发展的浪潮中&#xff0c;ComfyUI作为基于Stable Diffusion的开源工具&#xff0c;已经从最初的AI绘画辅助软件成长为支持多模态创作的强大平台。本文将全面梳理ComfyUI的发展历程、技术特点、应用场景及其在AIGC生态中的独特地位&#xff0c;同时展望这一工…...

11-项目涉及设备的问题

我们部门在开发一些项目时&#xff0c;确实需要借用设备&#xff0c;但每次开发新需求时都要从硬件部门借设备&#xff0c;开发完成后又要归还。这种频繁的借还流程不仅增加了沟通成本&#xff0c;还导致项目负责人和开发人员对设备的功能和应用场景缺乏直观的了解。有时甚至连…...

将 Markdown 表格结构转换为Excel 文件

在数据管理和文档编写过程中&#xff0c;我们经常使用 Markdown 来记录表格数据。然而&#xff0c;Markdown 格式的表格在实际应用中不如 Excel 方便&#xff0c;特别是需要进一步处理数据时。因此&#xff0c;我们开发了一个使用 wxPython 的 GUI 工具&#xff0c;将 Markdown…...

C++学习之Linux文件编译、调试及库制作

目录 1.rwx对于文件和目录的区别 2.gcc编译过程 3.数据段合并和地址回填说明 4.gcc编译其他参数 5.函数库简介 6.静态库的使用 7.动态库的简介 8.动态库制作基本流程 9.启动APP错误解决方案12 10.启动APP错误解决方案34 11.makefile一组规则 12.makefile的两个函数 …...

neo4j中导入csv格式的三元组数据

csv数据格式&#xff1a; head_entity,relation,tail_entity 02.02类以外的脂肪乳化制品&#xff0c;包括混合的和&#xff08;或&#xff09;调味的脂肪乳化制品,允许添加,β-胡萝卜素 02.02类以外的脂肪乳化制品&#xff0c;包括混合的和&#xff08;或&#xff09;调味的脂…...

高项第十六章——项目采购管理

什么是采购管理&#xff1f;项目采购管理包括从项目团队外部采购或获取所需产品、服务或成果的各个过程。 项目采购管理包括编制和管理协议所需的管理和控制过程。 16_1 管理基础 什么是协议&#xff1f;协议是用于明确项目初步意向的任何文件或沟通结果&#xff0c;协议的范…...

架构师面试(二十二):TCP 协议

问题 今天我们聊一个非常常见的面试题目&#xff0c;不管前端还是后端&#xff0c;也不管做的是上层业务还是底层框架&#xff0c;更不管技术方向是运维还是架构&#xff0c;都可以思考和参与一下哈&#xff01; TCP协议无处不在&#xff0c;我们知道 TCP 是基于连接的端到端…...