mimxrt: Add a driver for the DP83848 PHY device.

Just another choice for the PHY interface.

Added: Keyword option phy_clock=LAN.IN or LAN.OUT
to define the source of the 50MHZ clock for the PHY
interface. The RMII clock is not enabled if it
is generated by a PYH board. Constants:

LAN.IN  The clock is provided by the PHY board.
LAN.OUT The clock is provided by the MCU board.

The default is LAN.OUT or the value set in mpconfigboard.h, which
is currently set to IN only for the SEEED ARCH MIX board. Usage etc:

lan = LAN(phy_type=LAN.PHY_DP83848, phy_clock=LAN.IN)
This commit is contained in:
robert-hh 2021-11-30 15:22:42 +01:00
parent 5d8941ec85
commit 1e9eaa7af5
8 changed files with 454 additions and 20 deletions

View File

@ -145,6 +145,7 @@ SRC_MOD := $(filter-out %/mbedtls/library/error.c, $(SRC_MOD))
SRC_ETH_C += \
hal/phy/mdio/enet/fsl_enet_mdio.c \
hal/phy/device/phydp83825/fsl_phydp83825.c \
hal/phy/device/phydp83848/fsl_phydp83848.c \
hal/phy/device/phyksz8081/fsl_phyksz8081.c \
hal/phy/device/phylan8720/fsl_phylan8720.c \
lib/mbedtls_errors/mp_mbedtls_errors.c \

View File

@ -113,9 +113,6 @@ static const iomux_table_t iomux_table_enet[] = {
};
#define IOTE (iomux_table_enet[i])
#ifndef ENET_TX_CLK_OUTPUT
#define ENET_TX_CLK_OUTPUT true
#endif
#define TRACE_ASYNC_EV (0x0001)
#define TRACE_ETH_TX (0x0002)
@ -182,7 +179,7 @@ void eth_irq_handler(ENET_Type *base, enet_handle_t *handle, enet_event_t event,
}
// eth_init: Set up GPIO and the transceiver
void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy_addr) {
void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy_addr, bool phy_clock) {
self->netif.num = mac_idx; // Set the interface number
@ -222,12 +219,12 @@ void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy
}
const clock_enet_pll_config_t config = {
.enableClkOutput = true, .enableClkOutput25M = false, .loopDivider = 1
.enableClkOutput = phy_clock, .enableClkOutput25M = false, .loopDivider = 1
};
CLOCK_InitEnetPll(&config);
IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1RefClkMode, false); // Drive ENET_REF_CLK from PAD
IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, ENET_TX_CLK_OUTPUT); // Enable output driver
IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1RefClkMode, false); // Do not use the 25 MHz MII clock
IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, phy_clock); // Set the clock pad direction
// Reset transceiver
// pull up the ENET_INT before RESET.

View File

@ -30,7 +30,7 @@
typedef struct _eth_t eth_t;
extern eth_t eth_instance;
void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy_addr);
void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy_addr, bool phy_clock);
void eth_set_trace(eth_t *self, uint32_t value);
struct netif *eth_netif(eth_t *self);
int eth_link_status(eth_t *self);
@ -41,7 +41,13 @@ void eth_low_power_mode(eth_t *self, bool enable);
enum {
PHY_KSZ8081 = 0,
PHY_DP83825,
PHY_DP83848,
PHY_LAN8720,
};
enum {
PHY_TX_CLK_IN = false,
PHY_TX_CLK_OUT = true,
};
#endif // MICROPY_INCLUDED_MIMXRT_ETH_H

View File

@ -12,9 +12,9 @@
******************************************************************************/
/*! @brief Defines the PHY PD83825 vendor defined registers. */
#define PHY_PHYSTS_REG 0x10U // Phy status register
#define PHY_BISCR_REG 0x16U // RMII Config register.
#define PHY_RCSR_REG 0x17U // RMII Config register.
#define PHY_PHYSTS_REG 0x10U /* Phy status register */
#define PHY_BISCR_REG 0x16U /* RMII Config register. */
#define PHY_RCSR_REG 0x17U /* RMII Config register. */
#define PHY_CONTROL2_REG 0x1FU /*!< The PHY control register 2. */
/*! @brief Defines the PHY DP82825 ID number. */
@ -26,9 +26,9 @@
#define PHY_PHYSTS_100M_MASK 0x0002U /*!< The PHY 100M mask. */
#define PHY_PHYSTS_LINK_MASK 0x0001U /*!< The PHY link up mask. */
#define PYH_RMII_CLOCK_SELECT 0x80 // Select 50MHz clock
#define PHY_BISCR_REMOTELOOP_MASK 0x1FU // !< The PHY remote loopback mask.
#define PHY_BISCR_REMOTELOOP_MODE 0x08U // !< The PHY remote loopback mode.
#define PYH_RMII_CLOCK_SELECT 0x80 /* Select 50MHz clock */
#define PHY_BISCR_REMOTELOOP_MASK 0x1FU /* !< The PHY remote loopback mask. */
#define PHY_BISCR_REMOTELOOP_MODE 0x08U /* !< The PHY remote loopback mode. */
/*! @brief Defines the timeout macro. */
#define PHY_READID_TIMEOUT_COUNT 1000U

View File

@ -0,0 +1,254 @@
/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_phydp83848.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Defines the PHY PD83848 vendor defined registers. */
#define PHY_PHYSTS_REG 0x10U /* Phy status register */
#define PHY_RBR_REG 0x17U /* RMII Config register. */
/*! @brief Defines the PHY DP82825 ID number. */
#define PHY_CONTROL_ID1 0x2000U /*!< The PHY ID1 */
/*! @brief Defines the mask flag of operation mode in control registers */
#define PHY_PHYSTS_100FULLDUPLEX_MASK 0x0006U /*!< The PHY 100M full duplex mask. */
#define PHY_PHYSTS_DUPLEX_MASK 0x0004U /*!< The PHY full duplex mask. */
#define PHY_PHYSTS_100M_MASK 0x0002U /*!< The PHY 100M mask. */
#define PHY_PHYSTS_LINK_MASK 0x0001U /*!< The PHY link up mask. */
#define PHY_RMII_MODE 0x20
#define PHY_RMII_REV1_0 0x10
/*! @brief Defines the timeout macro. */
#define PHY_READID_TIMEOUT_COUNT 1000U
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
const phy_operations_t phydp83848_ops = {.phyInit = PHY_DP83848_Init,
.phyWrite = PHY_DP83848_Write,
.phyRead = PHY_DP83848_Read,
.getAutoNegoStatus = PHY_DP83848_GetAutoNegotiationStatus,
.getLinkStatus = PHY_DP83848_GetLinkStatus,
.getLinkSpeedDuplex = PHY_DP83848_GetLinkSpeedDuplex,
.setLinkSpeedDuplex = PHY_DP83848_SetLinkSpeedDuplex,
.enableLoopback = PHY_DP83848_EnableLoopback};
/*******************************************************************************
* Code
******************************************************************************/
status_t PHY_DP83848_Init(phy_handle_t *handle, const phy_config_t *config) {
uint32_t counter = PHY_READID_TIMEOUT_COUNT;
status_t result = kStatus_Success;
uint32_t regValue = 0;
/* Init MDIO interface. */
MDIO_Init(handle->mdioHandle);
/* Assign phy address. */
handle->phyAddr = config->phyAddr;
/* Check PHY ID. */
do
{
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_ID1_REG, &regValue);
if (result != kStatus_Success) {
return result;
}
counter--;
} while ((regValue != PHY_CONTROL_ID1) && (counter != 0U));
if (counter == 0U) {
return kStatus_Fail;
}
/* Reset PHY. */
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
if (result == kStatus_Success) {
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_RBR_REG, &regValue);
if (result != kStatus_Success) {
return result;
}
result =
MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_RBR_REG, (regValue | PHY_RMII_MODE | PHY_RMII_REV1_0));
if (result != kStatus_Success) {
return result;
}
if (config->autoNeg) {
/* Set the auto-negotiation then start it. */
result =
MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_AUTONEG_ADVERTISE_REG,
(PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | PHY_IEEE802_3_SELECTOR_MASK));
if (result == kStatus_Success) {
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG,
(PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
}
} else {
/* This PHY only supports 10/100M speed. */
assert(config->speed <= kPHY_Speed100M);
/* Disable isolate mode */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
if (result != kStatus_Success) {
return result;
}
regValue &= ~PHY_BCTL_ISOLATE_MASK;
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
if (result != kStatus_Success) {
return result;
}
/* Disable the auto-negotiation and set user-defined speed/duplex configuration. */
result = PHY_DP83848_SetLinkSpeedDuplex(handle, config->speed, config->duplex);
}
}
return result;
}
status_t PHY_DP83848_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data) {
return MDIO_Write(handle->mdioHandle, handle->phyAddr, phyReg, data);
}
status_t PHY_DP83848_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr) {
return MDIO_Read(handle->mdioHandle, handle->phyAddr, phyReg, dataPtr);
}
status_t PHY_DP83848_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status) {
assert(status);
status_t result;
uint32_t regValue;
*status = false;
/* Check auto negotiation complete. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, &regValue);
if (result == kStatus_Success) {
if ((regValue & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0U) {
*status = true;
}
}
return result;
}
status_t PHY_DP83848_GetLinkStatus(phy_handle_t *handle, bool *status) {
assert(status);
status_t result;
uint32_t regValue;
/* Read the basic status register. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, &regValue);
if (result == kStatus_Success) {
if ((PHY_BSTATUS_LINKSTATUS_MASK & regValue) != 0U) {
/* Link up. */
*status = true;
} else {
/* Link down. */
*status = false;
}
}
return result;
}
status_t PHY_DP83848_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex) {
assert(!((speed == NULL) && (duplex == NULL)));
status_t result;
uint32_t regValue;
uint32_t flag;
/* Read the control register. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_PHYSTS_REG, &regValue);
if (result == kStatus_Success) {
if (speed != NULL) {
flag = regValue & PHY_PHYSTS_100M_MASK;
if (flag) {
*speed = kPHY_Speed10M;
} else {
*speed = kPHY_Speed100M;
}
}
if (duplex != NULL) {
flag = regValue & PHY_PHYSTS_DUPLEX_MASK;
if (flag) {
*duplex = kPHY_FullDuplex;
} else {
*duplex = kPHY_HalfDuplex;
}
}
}
return result;
}
status_t PHY_DP83848_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex) {
/* This PHY only supports 10/100M speed. */
assert(speed <= kPHY_Speed100M);
status_t result;
uint32_t regValue;
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
if (result == kStatus_Success) {
/* Disable the auto-negotiation and set according to user-defined configuration. */
regValue &= ~PHY_BCTL_AUTONEG_MASK;
if (speed == kPHY_Speed100M) {
regValue |= PHY_BCTL_SPEED0_MASK;
} else {
regValue &= ~PHY_BCTL_SPEED0_MASK;
}
if (duplex == kPHY_FullDuplex) {
regValue |= PHY_BCTL_DUPLEX_MASK;
} else {
regValue &= ~PHY_BCTL_DUPLEX_MASK;
}
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
}
return result;
}
status_t PHY_DP83848_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable) {
/* This PHY only supports local/remote loopback and 10/100M speed. */
assert(mode <= kPHY_RemoteLoop);
assert(speed <= kPHY_Speed100M);
status_t result = kStatus_Success;
uint32_t regValue;
/* Set the loop mode. */
if (enable) {
if (mode == kPHY_LocalLoop) {
if (speed == kPHY_Speed100M) {
regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
} else {
regValue = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
}
return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
}
} else {
/* First read the current status in control register. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
if (result == kStatus_Success) {
regValue &= ~PHY_BCTL_LOOP_MASK;
return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG,
(regValue | PHY_BCTL_RESTART_AUTONEG_MASK));
}
}
return result;
}

View File

@ -0,0 +1,163 @@
/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*****************************************************************************
* PHY DP83848 driver change log
*****************************************************************************/
/*!
@page driver_log Driver Change Log
@section phyksz8081 PHYDP83848
The current PHYDP83848 driver version is 2.0.0.
- 2.0.0
- Initial version.
*/
#ifndef _FSL_DP83848_H_
#define _FSL_DP83848_H_
#include "fsl_phy.h"
/*!
* @addtogroup phy_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief PHY driver version */
#define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*! @brief PHY operations structure. */
extern const phy_operations_t phydp83848_ops;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name PHY Driver
* @{
*/
/*!
* @brief Initializes PHY.
*
* This function initialize PHY.
*
* @param handle PHY device handle.
* @param config Pointer to structure of phy_config_t.
* @retval kStatus_Success PHY initialization succeeds
* @retval kStatus_Fail PHY initialization fails
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_DP83848_Init(phy_handle_t *handle, const phy_config_t *config);
/*!
* @brief PHY Write function. This function writes data over the SMI to
* the specified PHY register. This function is called by all PHY interfaces.
*
* @param handle PHY device handle.
* @param phyReg The PHY register.
* @param data The data written to the PHY register.
* @retval kStatus_Success PHY write success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_DP83848_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data);
/*!
* @brief PHY Read function. This interface read data over the SMI from the
* specified PHY register. This function is called by all PHY interfaces.
*
* @param handle PHY device handle.
* @param phyReg The PHY register.
* @param dataPtr The address to store the data read from the PHY register.
* @retval kStatus_Success PHY read success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_DP83848_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr);
/*!
* @brief Gets the PHY auto-negotiation status.
*
* @param handle PHY device handle.
* @param status The auto-negotiation status of the PHY.
* - true the auto-negotiation is over.
* - false the auto-negotiation is on-going or not started.
* @retval kStatus_Success PHY gets status success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_DP83848_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status);
/*!
* @brief Gets the PHY link status.
*
* @param handle PHY device handle.
* @param status The link up or down status of the PHY.
* - true the link is up.
* - false the link is down.
* @retval kStatus_Success PHY gets link status success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_DP83848_GetLinkStatus(phy_handle_t *handle, bool *status);
/*!
* @brief Gets the PHY link speed and duplex.
*
* @brief This function gets the speed and duplex mode of PHY. User can give one of speed
* and duplex address paramter and set the other as NULL if only wants to get one of them.
*
* @param handle PHY device handle.
* @param speed The address of PHY link speed.
* @param duplex The link duplex of PHY.
* @retval kStatus_Success PHY gets link speed and duplex success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_DP83848_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex);
/*!
* @brief Sets the PHY link speed and duplex.
*
* @param handle PHY device handle.
* @param speed Specified PHY link speed.
* @param duplex Specified PHY link duplex.
* @retval kStatus_Success PHY gets status success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_DP83848_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex);
/*!
* @brief Enables/disables PHY loopback.
*
* @param handle PHY device handle.
* @param mode The loopback mode to be enabled, please see "phy_loop_t".
* All loopback modes should not be set together, when one loopback mode is set
* another should be disabled.
* @param speed PHY speed for loopback mode.
* @param enable True to enable, false to disable.
* @retval kStatus_Success PHY loopback success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_DP83848_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable);
/* @} */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_DP83848_H_ */

View File

@ -12,8 +12,8 @@
******************************************************************************/
/*! @brief Defines the PHY LAN8720 vendor defined registers. */
#define PHY_PHYSTS_REG 0x1FU // Phy status register
#define PHY_MCSR_REG 0x11U // Mode Control/Status Register for loopback
#define PHY_PHYSTS_REG 0x1FU /* Phy status register */
#define PHY_MCSR_REG 0x11U /* Mode Control/Status Register for loopback */
/*! @brief Defines the PHY LAN8720 ID number. */
#define PHY_CONTROL_ID1 0x07U /*!< The PHY ID1 */
@ -25,8 +25,8 @@
#define PHY_PHYSTS_100M_FLAG 0x0008U /*!< The PHY 100M flag. */
#define PHY_PHYSTS_LINK_MASK 0x0001U /*!< The PHY link up mask. */
#define PHY_MCSR_REMOTELOOP_MASK 0x100U // !< The PHY remote loopback mask.
#define PHY_MCSR_REMOTELOOP_MODE 0x100U // !< The PHY remote loopback mode.
#define PHY_MCSR_REMOTELOOP_MASK 0x100U /* !< The PHY remote loopback mask. */
#define PHY_MCSR_REMOTELOOP_MODE 0x100U /* !< The PHY remote loopback mode. */
/*! @brief Defines the timeout macro. */
#define PHY_READID_TIMEOUT_COUNT 1000U

View File

@ -34,10 +34,15 @@
#include "eth.h"
#include "hal/phy/device/phyksz8081/fsl_phyksz8081.h"
#include "hal/phy/device/phydp83825/fsl_phydp83825.h"
#include "hal/phy/device/phydp83848/fsl_phydp83848.h"
#include "hal/phy/device/phylan8720/fsl_phylan8720.h"
#include "lwip/netif.h"
#ifndef ENET_TX_CLK_OUTPUT
#define ENET_TX_CLK_OUTPUT true
#endif
typedef struct _network_lan_obj_t {
mp_obj_base_t base;
eth_t *eth;
@ -59,11 +64,12 @@ STATIC void network_lan_print(const mp_print_t *print, mp_obj_t self_in, mp_prin
}
STATIC mp_obj_t network_lan_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
enum { ARG_id, ARG_phy_type, ARG_phy_addr};
enum { ARG_id, ARG_phy_type, ARG_phy_addr, ARG_phy_clock};
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_phy_type, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
{ MP_QSTR_phy_addr, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = ENET_PHY_ADDRESS} },
{ MP_QSTR_phy_clock, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = ENET_TX_CLK_OUTPUT} },
};
// Parse args.
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@ -78,6 +84,8 @@ STATIC mp_obj_t network_lan_make_new(const mp_obj_type_t *type, size_t n_args, s
phy_ops = &phyksz8081_ops;
} else if (phy_type == PHY_DP83825) {
phy_ops = &phydp83825_ops;
} else if (phy_type == PHY_DP83848) {
phy_ops = &phydp83848_ops;
} else if (phy_type == PHY_LAN8720) {
phy_ops = &phylan8720_ops;
} else {
@ -86,6 +94,8 @@ STATIC mp_obj_t network_lan_make_new(const mp_obj_type_t *type, size_t n_args, s
}
int phy_addr = args[ARG_phy_addr].u_int;
bool phy_clock = args[ARG_phy_clock].u_int;
// Prepare for two ETH interfaces.
const network_lan_obj_t *self;
int mac_id = args[ARG_id].u_int;
@ -99,7 +109,7 @@ STATIC mp_obj_t network_lan_make_new(const mp_obj_type_t *type, size_t n_args, s
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid LAN interface %d"), mac_id);
}
eth_init(self->eth, mac_id, phy_ops, phy_addr);
eth_init(self->eth, mac_id, phy_ops, phy_addr, phy_clock);
// register with network module
mod_network_register_nic((mp_obj_t *)self);
return MP_OBJ_FROM_PTR(self);
@ -203,7 +213,10 @@ STATIC const mp_rom_map_elem_t network_lan_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_PHY_KSZ8081), MP_ROM_INT(PHY_KSZ8081) },
{ MP_ROM_QSTR(MP_QSTR_PHY_DP83825), MP_ROM_INT(PHY_DP83825) },
{ MP_ROM_QSTR(MP_QSTR_PHY_DP83848), MP_ROM_INT(PHY_DP83848) },
{ MP_ROM_QSTR(MP_QSTR_PHY_LAN8720), MP_ROM_INT(PHY_LAN8720) },
{ MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(PHY_TX_CLK_IN) },
{ MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(PHY_TX_CLK_OUT) },
};
STATIC MP_DEFINE_CONST_DICT(network_lan_locals_dict, network_lan_locals_dict_table);