diff options
-rw-r--r-- | ports/mimxrt/Makefile | 1 | ||||
-rw-r--r-- | ports/mimxrt/eth.c | 11 | ||||
-rw-r--r-- | ports/mimxrt/eth.h | 8 | ||||
-rw-r--r-- | ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.c | 12 | ||||
-rw-r--r-- | ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.c | 254 | ||||
-rw-r--r-- | ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.h | 163 | ||||
-rw-r--r-- | ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.c | 8 | ||||
-rw-r--r-- | ports/mimxrt/network_lan.c | 17 |
8 files changed, 454 insertions, 20 deletions
diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index eeab29ddc3..574aebb4cd 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -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 \ diff --git a/ports/mimxrt/eth.c b/ports/mimxrt/eth.c index 9c036cd056..1a8210cb11 100644 --- a/ports/mimxrt/eth.c +++ b/ports/mimxrt/eth.c @@ -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. diff --git a/ports/mimxrt/eth.h b/ports/mimxrt/eth.h index 962b6c88cb..b225d00492 100644 --- a/ports/mimxrt/eth.h +++ b/ports/mimxrt/eth.h @@ -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 diff --git a/ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.c b/ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.c index 2aca609a05..309755f860 100644 --- a/ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.c +++ b/ports/mimxrt/hal/phy/device/phydp83825/fsl_phydp83825.c @@ -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 diff --git a/ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.c b/ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.c new file mode 100644 index 0000000000..0ef618d421 --- /dev/null +++ b/ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.c @@ -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, ®Value); + 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, ®Value); + 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, ®Value); + 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, ®Value); + 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, ®Value); + 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, ®Value); + 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, ®Value); + 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, ®Value); + 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; +} diff --git a/ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.h b/ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.h new file mode 100644 index 0000000000..7ccc260f7b --- /dev/null +++ b/ports/mimxrt/hal/phy/device/phydp83848/fsl_phydp83848.h @@ -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_ */ diff --git a/ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.c b/ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.c index b7435c2d05..e141ebd513 100644 --- a/ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.c +++ b/ports/mimxrt/hal/phy/device/phylan8720/fsl_phylan8720.c @@ -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 diff --git a/ports/mimxrt/network_lan.c b/ports/mimxrt/network_lan.c index 7b725276a1..5517b54bd0 100644 --- a/ports/mimxrt/network_lan.c +++ b/ports/mimxrt/network_lan.c @@ -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); |