From af6d50aefe923349c32c8a1bd6dd0786ffe66fd7 Mon Sep 17 00:00:00 2001 From: Jamie Smith Date: Wed, 8 Mar 2023 20:18:33 -0800 Subject: [PATCH] Teensy 4.1 port with Ethernet support (#144) * Start porting to Teensy 4.1, also fix some compiler warnings in FSL HAL * Add hardware init for Teensy, refactor phy drivers, rework IMX EMAC autonegotiate code * Revert some testing changes * Fix incorrect phy address used outside of low_level_init_successful() * Ethernet operational! * Turn off DEBUG_IMX_EMAC * Style fixes * Style again * Bugfix: mbed_lib.json files in project source dir were not getting picked up * Bugfix: CLion debug configurations not generated properly due to variables going out of scope * Support Teensy OTP MAC address --- CMakeLists.txt | 2 + .../TARGET_NXP_EMAC/TARGET_IMX/CMakeLists.txt | 6 +- .../CMakeLists.txt | 1 + .../fsl_phy_ksz8081rnb.c | 139 +-------- .../hardware_init.c | 0 .../TARGET_MIMXRT105x_EVK/ksz8081rnb_regs.h | 29 ++ .../TARGET_TEENSY_41/CMakeLists.txt | 8 + .../TARGET_TEENSY_41/dp83825_regs.h | 53 ++++ .../TARGET_TEENSY_41/fsl_phy_dp83825.c | 202 +++++++++++++ .../TARGET_TEENSY_41/hardware_init.cpp | 148 ++++++++++ .../TARGET_NXP_EMAC/TARGET_IMX}/fsl_phy.h | 45 ++- .../TARGET_IMX/fsl_phy_common.c | 133 +++++++++ .../TARGET_NXP_EMAC/TARGET_IMX/imx_emac.cpp | 76 +++-- .../TARGET_NXP_EMAC/TARGET_IMX/imx_emac.h | 4 +- .../tests/TESTS/netsocket/udp/main.cpp | 5 + .../TARGET_IMX/pwmout_api.c | 1 + .../TARGET_EVK/CMakeLists.txt | 1 - .../TARGET_TEENSY_4X/CMakeLists.txt | 3 +- .../TARGET_TEENSY_40/PinNames.h | 2 +- .../TARGET_TEENSY_41/PinNames.h | 273 ++++++++++++++++++ .../TARGET_TEENSY_4X/device.h | 3 + .../TARGET_MIMXRT1050/drivers/fsl_dcp.c | 2 +- .../TARGET_MIMXRT1050/drivers/fsl_enet.c | 10 +- .../TARGET_MIMXRT1050/drivers/fsl_flexram.c | 2 +- .../TARGET_MIMXRT1050/drivers/fsl_flexspi.c | 10 +- .../TARGET_MIMXRT1050/drivers/fsl_sai.c | 20 +- .../TARGET_MIMXRT1050/mbed_overrides.c | 24 +- targets/targets.json | 18 ++ tools/cmake/app.cmake | 5 +- tools/cmake/mbed_generate_configuration.cmake | 1 + .../cmake/mbed_ide_debug_cfg_generator.cmake | 11 +- 31 files changed, 993 insertions(+), 244 deletions(-) rename connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/{TARGET_MIMXRT10x0_EVK => TARGET_MIMXRT105x_EVK}/CMakeLists.txt (87%) rename targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/fsl_phy.c => connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/fsl_phy_ksz8081rnb.c (61%) rename connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/{TARGET_MIMXRT10x0_EVK => TARGET_MIMXRT105x_EVK}/hardware_init.c (100%) create mode 100644 connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/ksz8081rnb_regs.h create mode 100644 connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_TEENSY_41/CMakeLists.txt create mode 100644 connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_TEENSY_41/dp83825_regs.h create mode 100644 connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_TEENSY_41/fsl_phy_dp83825.c create mode 100644 connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_TEENSY_41/hardware_init.cpp rename {targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK => connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX}/fsl_phy.h (83%) create mode 100644 connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/fsl_phy_common.c create mode 100644 targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_TEENSY_4X/TARGET_TEENSY_41/PinNames.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 52b0e070ebf..d93abbe5466 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -218,6 +218,8 @@ if(NOT MBED_IS_NATIVE_BUILD) # Load upload method if one is set up include(UploadMethodManager) + # Load debug config generator for IDEs + include(mbed_ide_debug_cfg_generator) endif() if(MBED_IS_NATIVE_BUILD) diff --git a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/CMakeLists.txt b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/CMakeLists.txt index 9d9ef330a0a..af73ac8b33a 100644 --- a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/CMakeLists.txt +++ b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/CMakeLists.txt @@ -2,7 +2,10 @@ # SPDX-License-Identifier: Apache-2.0 if("MIMXRT1050_EVK" IN_LIST MBED_TARGET_LABELS OR "MIMXRT1060_EVK" IN_LIST MBED_TARGET_LABELS) - add_subdirectory(TARGET_MIMXRT10x0_EVK) + add_subdirectory(TARGET_MIMXRT105x_EVK) +endif() +if("TEENSY_41" IN_LIST MBED_TARGET_LABELS) + add_subdirectory(TARGET_TEENSY_41) endif() target_include_directories(mbed-emac @@ -13,4 +16,5 @@ target_include_directories(mbed-emac target_sources(mbed-emac PRIVATE imx_emac.cpp + fsl_phy_common.c ) diff --git a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT10x0_EVK/CMakeLists.txt b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/CMakeLists.txt similarity index 87% rename from connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT10x0_EVK/CMakeLists.txt rename to connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/CMakeLists.txt index db07c9fa60d..a00d2fdc738 100644 --- a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT10x0_EVK/CMakeLists.txt +++ b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/CMakeLists.txt @@ -4,4 +4,5 @@ target_sources(mbed-emac PRIVATE hardware_init.c + fsl_phy_ksz8081rnb.c ) diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/fsl_phy.c b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/fsl_phy_ksz8081rnb.c similarity index 61% rename from targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/fsl_phy.c rename to connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/fsl_phy_ksz8081rnb.c index 3b09963b5a2..c107016ece2 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/fsl_phy.c +++ b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/fsl_phy_ksz8081rnb.c @@ -7,6 +7,8 @@ */ #include "fsl_phy.h" +#include "ksz8081rnb_regs.h" + /******************************************************************************* * Definitions ******************************************************************************/ @@ -82,123 +84,17 @@ status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz) } #endif /* FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE */ } - return result; -} - -status_t PHY_AutoNegotiation(ENET_Type *base, uint32_t phyAddr) -{ - status_t result = kStatus_Success; - uint32_t bssReg; - uint32_t counter = PHY_TIMEOUT_COUNT; - uint32_t timeDelay; - uint32_t ctlReg = 0; - /* Set the negotiation. */ - result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG, + // Enable autonegotiation, allow negotiating for all ethernet types + PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG, (PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK | PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U)); - if (result == kStatus_Success) - { - result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, - (PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK)); - if (result == kStatus_Success) - { - /* Check auto negotiation complete. */ - while (counter--) - { - result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg); - if (result == kStatus_Success) - { - PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &ctlReg); - if (((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0) && (ctlReg & PHY_LINK_READY_MASK)) - { - /* Wait a moment for Phy status stable. */ - for (timeDelay = 0; timeDelay < PHY_TIMEOUT_COUNT; timeDelay++) - { - __ASM("nop"); - } - break; - } - } - if (!counter) - { - return kStatus_PHY_AutoNegotiateFail; - } - } - } - } + PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (PHY_BCTL_AUTONEG_MASK)); return result; } -status_t PHY_Write(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data) -{ - uint32_t counter; - - /* Clear the SMI interrupt event. */ - ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); - - /* Starts a SMI write command. */ - ENET_StartSMIWrite(base, phyAddr, phyReg, kENET_MiiWriteValidFrame, data); - - /* Wait for SMI complete. */ - for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--) - { - if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) - { - break; - } - } - - /* Check for timeout. */ - if (!counter) - { - return kStatus_PHY_SMIVisitTimeout; - } - - /* Clear MII interrupt event. */ - ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); - - return kStatus_Success; -} - -status_t PHY_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr) -{ - assert(dataPtr); - - uint32_t counter; - - /* Clear the MII interrupt event. */ - ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); - - /* Starts a SMI read command operation. */ - ENET_StartSMIRead(base, phyAddr, phyReg, kENET_MiiReadValidFrame); - - /* Wait for MII complete. */ - for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--) - { - if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) - { - break; - } - } - - /* Check for timeout. */ - if (!counter) - { - return kStatus_PHY_SMIVisitTimeout; - } - - /* Get data from MII register. */ - *dataPtr = ENET_ReadSMIData(base); - - /* Clear MII interrupt event. */ - ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); - - return kStatus_Success; -} - status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, phy_speed_t speed, bool enable) { status_t result; @@ -255,31 +151,6 @@ status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, return result; } -status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status) -{ - assert(status); - - status_t result = kStatus_Success; - uint32_t data; - - /* Read the basic status register. */ - result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &data); - if (result == kStatus_Success) - { - if (!(PHY_BSTATUS_LINKSTATUS_MASK & data)) - { - /* link down. */ - *status = false; - } - else - { - /* link up. */ - *status = true; - } - } - return result; -} - status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex) { assert(duplex); diff --git a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT10x0_EVK/hardware_init.c b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/hardware_init.c similarity index 100% rename from connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT10x0_EVK/hardware_init.c rename to connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/hardware_init.c diff --git a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/ksz8081rnb_regs.h b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/ksz8081rnb_regs.h new file mode 100644 index 00000000000..0ddb42f0231 --- /dev/null +++ b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/ksz8081rnb_regs.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _KSZ8081RNB_REGS_H_ +#define _KSZ8081RNB_REGS_H_ + +/*! @brief Defines the KSZ8081-specific PHY registers. */ +#define PHY_CONTROL1_REG 0x1EU /*!< The PHY control one register. */ +#define PHY_CONTROL2_REG 0x1FU /*!< The PHY control two register. */ + +#define PHY_CONTROL_ID1 0x22U /*!< The PHY ID1*/ + +/*!@brief Defines the mask flag of operation mode in control two register*/ +#define PHY_CTL2_REMOTELOOP_MASK 0x0004U /*!< The PHY remote loopback mask. */ +#define PHY_CTL2_REFCLK_SELECT_MASK 0x0080U /*!< The PHY RMII reference clock select. */ +#define PHY_CTL1_10HALFDUPLEX_MASK 0x0001U /*!< The PHY 10M half duplex mask. */ +#define PHY_CTL1_100HALFDUPLEX_MASK 0x0002U /*!< The PHY 100M half duplex mask. */ +#define PHY_CTL1_10FULLDUPLEX_MASK 0x0005U /*!< The PHY 10M full duplex mask. */ +#define PHY_CTL1_100FULLDUPLEX_MASK 0x0006U /*!< The PHY 100M full duplex mask. */ +#define PHY_CTL1_SPEEDUPLX_MASK 0x0007U /*!< The PHY speed and duplex mask. */ +#define PHY_CTL1_ENERGYDETECT_MASK 0x10U /*!< The PHY signal present on rx differential pair. */ +#define PHY_CTL1_LINKUP_MASK 0x100U /*!< The PHY link up. */ +#define PHY_LINK_READY_MASK (PHY_CTL1_ENERGYDETECT_MASK | PHY_CTL1_LINKUP_MASK) + +#endif \ No newline at end of file diff --git a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_TEENSY_41/CMakeLists.txt b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_TEENSY_41/CMakeLists.txt new file mode 100644 index 00000000000..3687e9b3986 --- /dev/null +++ b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_TEENSY_41/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2020 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +target_sources(mbed-emac + PRIVATE + hardware_init.cpp + fsl_phy_dp83825.c +) diff --git a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_TEENSY_41/dp83825_regs.h b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_TEENSY_41/dp83825_regs.h new file mode 100644 index 00000000000..02a05ea6224 --- /dev/null +++ b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_TEENSY_41/dp83825_regs.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _DP83825_REGS_H_ +#define _DP83825_REGS_H_ + +/*! @brief Defines the DP83825-specific PHY registers. */ +#define PHY_PHYSTS_REG 0x10 ///< Phy Status Reg +#define PHY_BISCR_REG 0x16 ///< Built-In Self Test Control Register +#define PHY_RCSR_REG 0x17 ///< Receive Clock Select Register +#define PHY_LEDCR_REG 0x18 ///< LED Control Register + +#define PHY_CONTROL_ID1 0x2000U /*!< The PHY ID1*/ + +/*!@brief Defines the mask flag of operation mode in control two register*/ +#define PHY_CTL2_REMOTELOOP_MASK 0x0004U /*!< The PHY remote loopback mask. */ +#define PHY_CTL2_REFCLK_SELECT_MASK 0x0080U /*!< The PHY RMII reference clock select. */ +#define PHY_CTL1_10HALFDUPLEX_MASK 0x0001U /*!< The PHY 10M half duplex mask. */ +#define PHY_CTL1_100HALFDUPLEX_MASK 0x0002U /*!< The PHY 100M half duplex mask. */ +#define PHY_CTL1_10FULLDUPLEX_MASK 0x0005U /*!< The PHY 10M full duplex mask. */ +#define PHY_CTL1_100FULLDUPLEX_MASK 0x0006U /*!< The PHY 100M full duplex mask. */ +#define PHY_CTL1_SPEEDUPLX_MASK 0x0007U /*!< The PHY speed and duplex mask. */ +#define PHY_CTL1_ENERGYDETECT_MASK 0x10U /*!< The PHY signal present on rx differential pair. */ +#define PHY_CTL1_LINKUP_MASK 0x100U /*!< The PHY link up. */ +#define PHY_LINK_READY_MASK (PHY_CTL1_ENERGYDETECT_MASK | PHY_CTL1_LINKUP_MASK) + +// Bits for PHYSTS register +#define PHY_PHYSTS_DUPLEX_Msk (1 << 2) +#define PHY_PHYSTS_SPEED_Msk (1 << 1) + +// Bits for BISCR register +#define PHY_BISCR_LOOPBACK_Msk (0b11111) +#define PHY_BISCR_LOOPBACK_Pos 0 +#define PHY_BISCR_LOOPBACK_DIGITAL_LOOPBACK_10M_Val 0x1 +#define PHY_BISCR_LOOPBACK_DIGITAL_LOOPBACK_100M_Val 0x4 +#define PHY_BISCR_LOOPBACK_ANALOG_LOOPBACK_Val 0x8 + +// Bits for RCSR register +#define PHY_RCSR_RX_ELASTICITY_Pos 0 +#define PHY_RCSR_RX_ELASTICITY_Msk 0b11 +#define PHY_RCSR_RMII_CLK_SEL_Msk (1 << 7) + +// Bits for LEDCR register +#define PHY_LEDCR_POLARITY_Msk (1 << 7) +#define PHY_LEDCR_BLINK_RATE_Msk (0b11 << 9) +#define PHY_LEDCR_BLINK_RATE_Pos 9 + + +#endif \ No newline at end of file diff --git a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_TEENSY_41/fsl_phy_dp83825.c b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_TEENSY_41/fsl_phy_dp83825.c new file mode 100644 index 00000000000..17ac3a3add2 --- /dev/null +++ b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_TEENSY_41/fsl_phy_dp83825.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_phy.h" +#include "dp83825_regs.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Defines the timeout macro. */ +#define PHY_TIMEOUT_COUNT 100000 + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get the ENET instance from peripheral base address. + * + * @param base ENET peripheral base address. + * @return ENET instance. + */ +extern uint32_t ENET_GetInstance(ENET_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to enet clocks for each instance. */ +extern clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT]; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Code + ******************************************************************************/ + +status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz) +{ + uint32_t counter = PHY_TIMEOUT_COUNT; + uint32_t idReg = 0; + status_t result = kStatus_Success; + uint32_t instance = ENET_GetInstance(base); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Set SMI first. */ + CLOCK_EnableClock(s_enetClock[instance]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + ENET_SetSMI(base, srcClock_Hz, false); + + /* Initialization after PHY stars to work. */ + while ((idReg != PHY_CONTROL_ID1) && (counter != 0)) + { + PHY_Read(base, phyAddr, PHY_ID1_REG, &idReg); + counter--; + } + + if (!counter) + { + return kStatus_Fail; + } + + // Set up LED control for the teensy hardware. + // Reference here: https://github.com/ssilverman/QNEthernet/blob/master/src/lwip_t41.c#L265 + PHY_Write(base, phyAddr, PHY_LEDCR_REG, PHY_LEDCR_POLARITY_Msk | // LED to active high + (1 << PHY_LEDCR_BLINK_RATE_Pos)); // Blink period to 10Hz + + // Set up clock select register + PHY_Write(base, phyAddr, PHY_RCSR_REG, PHY_RCSR_RMII_CLK_SEL_Msk | // Select 50MHz RMII clock + (1 << PHY_RCSR_RX_ELASTICITY_Pos)); // Rx elasticity to 2 bits + + // Advertise support for all Ethernet modes + PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG, + (PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK | + PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U)); + + // Enable autonegotiation + PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG,PHY_BCTL_AUTONEG_MASK); + + + + return result; +} + +status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, phy_speed_t speed, bool enable) +{ + uint32_t data = 0; + + /* Set the loop mode. */ + if (enable) + { + if (mode == kPHY_LocalLoop) + { + if (speed == kPHY_Speed100M) + { + data = PHY_BCTL_SPEED_100M_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; + } + else + { + data = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; + } + PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, data); + + // Per datasheet, also need to set BISCR + uint32_t biscrVal; + PHY_Read(base, phyAddr, PHY_BISCR_REG, &biscrVal); + biscrVal &= ~PHY_BISCR_LOOPBACK_Msk; + biscrVal |= (speed == kPHY_Speed100M ? PHY_BISCR_LOOPBACK_DIGITAL_LOOPBACK_100M_Val : PHY_BISCR_LOOPBACK_DIGITAL_LOOPBACK_10M_Val); + PHY_Write(base, phyAddr, PHY_BISCR_REG, biscrVal); + } + else + { + // Set requested speed manually + if (speed == kPHY_Speed100M) + { + data = PHY_BCTL_SPEED_100M_MASK | PHY_BCTL_DUPLEX_MASK; + } + else + { + data = PHY_BCTL_DUPLEX_MASK; + } + PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, data); + + // Enable analog loopback in BISCR + uint32_t biscrVal; + PHY_Read(base, phyAddr, PHY_BISCR_REG, &biscrVal); + biscrVal &= ~PHY_BISCR_LOOPBACK_Msk; + biscrVal |= PHY_BISCR_LOOPBACK_ANALOG_LOOPBACK_Val; + PHY_Write(base, phyAddr, PHY_BISCR_REG, biscrVal); + } + } + else + { + /* Disable the loop mode. */ + if (mode == kPHY_LocalLoop) + { + // Reenable autonegotiation + PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &data); + data |= PHY_BCTL_RESTART_AUTONEG_MASK | PHY_BCTL_AUTONEG_MASK; + PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (data | PHY_BCTL_RESTART_AUTONEG_MASK)); + + // Also, disable loopback in BISCR + uint32_t biscrVal; + PHY_Read(base, phyAddr, PHY_BISCR_REG, &biscrVal); + biscrVal &= ~PHY_BISCR_LOOPBACK_Msk; + PHY_Write(base, phyAddr, PHY_BISCR_REG, biscrVal); + } + else + { + // Reenable autonegotiation + PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &data); + data |= PHY_BCTL_RESTART_AUTONEG_MASK | PHY_BCTL_AUTONEG_MASK; + PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (data | PHY_BCTL_RESTART_AUTONEG_MASK)); + + // Disable loopback in BISCR + uint32_t biscrVal; + PHY_Read(base, phyAddr, PHY_BISCR_REG, &biscrVal); + biscrVal &= ~PHY_BISCR_LOOPBACK_Msk; + PHY_Write(base, phyAddr, PHY_BISCR_REG, biscrVal); + } + } + return kStatus_Success; +} + +status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex) +{ + assert(duplex); + + status_t result = kStatus_Success; + uint32_t stsReg; + + /* Read status register. */ + result = PHY_Read(base, phyAddr, PHY_PHYSTS_REG, &stsReg); + if (result == kStatus_Success) + { + if(stsReg & PHY_PHYSTS_DUPLEX_Msk) + { + *duplex = kPHY_FullDuplex; + } + else + { + *duplex = kPHY_HalfDuplex; + } + + if(stsReg & PHY_PHYSTS_SPEED_Msk) + { + *speed = kPHY_Speed10M; + } + else + { + *speed = kPHY_Speed100M; + } + } + + return result; +} diff --git a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_TEENSY_41/hardware_init.cpp b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_TEENSY_41/hardware_init.cpp new file mode 100644 index 00000000000..509076c4f37 --- /dev/null +++ b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_TEENSY_41/hardware_init.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_gpio.h" +#include "fsl_iomuxc.h" +#include "fsl_clock.h" +#include "mbed_wait_api.h" + +#include "DigitalOut.h" + +/******************************************************************************* + * Code + ******************************************************************************/ +static void BOARD_InitModuleClock(void) +{ + const clock_enet_pll_config_t config = {true, false, 1}; + CLOCK_InitEnetPll(&config); +} + +extern "C" void kinetis_init_eth_hardware(void) +{ + CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */ + + // Power down pin (leave high for now, keeping the phy active) + static mbed::DigitalOut powerDown(GPIO_B0_15, 1); + + // Reset pin + static mbed::DigitalOut reset(GPIO_B0_14, 1); + + + // Use temporary digital outputs to set the strapping options. + // Note: Cannot use GPIO pullups/pulldowns as they are not strong enough to overcome the phy's + // 10k internal pulldowns + { + mbed::DigitalOut strapPhyAdd0(GPIO_B1_04, 1); + mbed::DigitalOut strapPhyAdd1(GPIO_B1_06, 0); + mbed::DigitalOut strapRMIIMode(GPIO_B1_05, 1); + + // Send reset pulse + reset.write(0); + wait_us(25); // DP83825 datasheet specifies >=25us reset pulse + reset.write(1); + wait_us(2000); // DP83825 datasheet specifies at least 2ms between reset and SMI access + } + + + // REF CLK (high speed output) + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_10_ENET_REF_CLK, 1); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_10_ENET_REF_CLK, + IOMUXC_SW_PAD_CTL_PAD_SRE_MASK | + IOMUXC_SW_PAD_CTL_PAD_DSE(5) | + IOMUXC_SW_PAD_CTL_PAD_SPEED(2)); + + // MDIO (bidirectional, open drain with 22k pullup) + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_15_ENET_MDIO, 0); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_15_ENET_MDIO, + IOMUXC_SW_PAD_CTL_PAD_SRE_MASK | + IOMUXC_SW_PAD_CTL_PAD_DSE(5) | + IOMUXC_SW_PAD_CTL_PAD_ODE_MASK | + IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | + IOMUXC_SW_PAD_CTL_PAD_PUE_MASK | + IOMUXC_SW_PAD_CTL_PAD_PUS(3)); + + // MDC (low speed output) + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_14_ENET_MDC, 0); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_10_ENET_REF_CLK, + IOMUXC_SW_PAD_CTL_PAD_SRE_MASK | + IOMUXC_SW_PAD_CTL_PAD_DSE(5)); + + // RXER (input) + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_11_ENET_RX_ER, 0); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_11_ENET_RX_ER, 0); + + // CRS_DV (input with 100k pulldown) + // Note: Constant is called "ENET_RX_EN" but this signal acts as CRS_DV in RMII mode + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_06_ENET_RX_EN, 0); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_06_ENET_RX_EN, + IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | + IOMUXC_SW_PAD_CTL_PAD_PUE_MASK | + IOMUXC_SW_PAD_CTL_PAD_PUS(0)); + + // TXEN (high speed output) + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_09_ENET_TX_EN, 0); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_09_ENET_TX_EN, + IOMUXC_SW_PAD_CTL_PAD_SRE_MASK | + IOMUXC_SW_PAD_CTL_PAD_DSE(5) | + IOMUXC_SW_PAD_CTL_PAD_SPEED(3)); + + // TXD0 (high speed output) + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_07_ENET_TX_DATA00, 0); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_07_ENET_TX_DATA00, + IOMUXC_SW_PAD_CTL_PAD_SRE_MASK | + IOMUXC_SW_PAD_CTL_PAD_DSE(5) | + IOMUXC_SW_PAD_CTL_PAD_SPEED(3)); + + // TXD1 (high speed output) + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_08_ENET_TX_DATA01, 0); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_08_ENET_TX_DATA01, + IOMUXC_SW_PAD_CTL_PAD_SRE_MASK | + IOMUXC_SW_PAD_CTL_PAD_DSE(5) | + IOMUXC_SW_PAD_CTL_PAD_SPEED(3)); + + // RXD0 (input ) + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0); + + // RXD1 (input) + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0); + + BOARD_InitModuleClock(); + + // Set up 50MHz clock output to the phy on GPIO_B1_10 + IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, true); +} + +/******************************************************************************* + * EOF + ******************************************************************************/ + + diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/fsl_phy.h b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/fsl_phy.h similarity index 83% rename from targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/fsl_phy.h rename to connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/fsl_phy.h index d4342bddb2d..aa5d0793c92 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/fsl_phy.h +++ b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/fsl_phy.h @@ -28,10 +28,6 @@ #define PHY_ID1_REG 0x02U /*!< The PHY ID one register. */ #define PHY_ID2_REG 0x03U /*!< The PHY ID two register. */ #define PHY_AUTONEG_ADVERTISE_REG 0x04U /*!< The PHY auto-negotiate advertise register. */ -#define PHY_CONTROL1_REG 0x1EU /*!< The PHY control one register. */ -#define PHY_CONTROL2_REG 0x1FU /*!< The PHY control two register. */ - -#define PHY_CONTROL_ID1 0x22U /*!< The PHY ID1*/ /*! @brief Defines the mask flag in basic control register. */ #define PHY_BCTL_DUPLEX_MASK 0x0100U /*!< The PHY duplex bit mask. */ @@ -42,18 +38,6 @@ #define PHY_BCTL_RESET_MASK 0x8000U /*!< The PHY reset bit mask. */ #define PHY_BCTL_SPEED_100M_MASK 0x2000U /*!< The PHY 100M speed mask. */ -/*!@brief Defines the mask flag of operation mode in control two register*/ -#define PHY_CTL2_REMOTELOOP_MASK 0x0004U /*!< The PHY remote loopback mask. */ -#define PHY_CTL2_REFCLK_SELECT_MASK 0x0080U /*!< The PHY RMII reference clock select. */ -#define PHY_CTL1_10HALFDUPLEX_MASK 0x0001U /*!< The PHY 10M half duplex mask. */ -#define PHY_CTL1_100HALFDUPLEX_MASK 0x0002U /*!< The PHY 100M half duplex mask. */ -#define PHY_CTL1_10FULLDUPLEX_MASK 0x0005U /*!< The PHY 10M full duplex mask. */ -#define PHY_CTL1_100FULLDUPLEX_MASK 0x0006U /*!< The PHY 100M full duplex mask. */ -#define PHY_CTL1_SPEEDUPLX_MASK 0x0007U /*!< The PHY speed and duplex mask. */ -#define PHY_CTL1_ENERGYDETECT_MASK 0x10U /*!< The PHY signal present on rx differential pair. */ -#define PHY_CTL1_LINKUP_MASK 0x100U /*!< The PHY link up. */ -#define PHY_LINK_READY_MASK (PHY_CTL1_ENERGYDETECT_MASK | PHY_CTL1_LINKUP_MASK) - /*! @brief Defines the mask flag in basic status register. */ #define PHY_BSTATUS_LINKSTATUS_MASK 0x0004U /*!< The PHY link status mask. */ #define PHY_BSTATUS_AUTONEGABLE_MASK 0x0008U /*!< The PHY auto-negotiation ability mask. */ @@ -123,16 +107,6 @@ extern "C" { */ status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz); -/*! - * @brief Initiates auto negotiation. - * - * @param base ENET peripheral base address. - * @param phyAddr The PHY address. - * @retval kStatus_Success PHY auto negotiation success - * @retval kStatus_PHY_AutoNegotiateFail PHY auto negotiate fail - */ -status_t PHY_AutoNegotiation(ENET_Type *base, uint32_t phyAddr); - /*! * @brief PHY Write function. This function write data over the SMI to * the specified PHY register. This function is called by all PHY interfaces. @@ -187,6 +161,25 @@ status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, */ status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status); +/*! + * @brief Gets the PHY autonegotiation status + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param[out] status Whether autonegotiation is done. + * @return Error code or success + */ +status_t PHY_GetAutonegotiationStatus(ENET_Type *base, uint32_t phyAddr, bool *status); + +/*! + * @brief Starts the autonegotiation process. Should be called after the link comes up. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @return Error code or success + */ +status_t PHY_StartAutonegotiation(ENET_Type *base, uint32_t phyAddr); + /*! * @brief Gets the PHY link speed and duplex. * diff --git a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/fsl_phy_common.c b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/fsl_phy_common.c new file mode 100644 index 00000000000..d7666af4948 --- /dev/null +++ b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/fsl_phy_common.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP + * All rights reserved. + * + * This file contains PHY functions which are common to all ethernet phys. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_phy.h" + +#include + +// Timeout for waiting for the processor to execute an SMI read/write operation +#define SMI_TIMEOUT_COUNT 100000 + +status_t PHY_Write(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data) +{ + uint32_t counter; + + /* Clear the SMI interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + /* Starts a SMI write command. */ + ENET_StartSMIWrite(base, phyAddr, phyReg, kENET_MiiWriteValidFrame, data); + + /* Wait for SMI complete. */ + for (counter = SMI_TIMEOUT_COUNT; counter > 0; counter--) + { + if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) + { + break; + } + } + + /* Check for timeout. */ + if (!counter) + { + return kStatus_PHY_SMIVisitTimeout; + } + + /* Clear MII interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + return kStatus_Success; +} + +status_t PHY_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr) +{ + assert(dataPtr); + + uint32_t counter; + + /* Clear the MII interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + /* Starts a SMI read command operation. */ + ENET_StartSMIRead(base, phyAddr, phyReg, kENET_MiiReadValidFrame); + + /* Wait for MII complete. */ + for (counter = SMI_TIMEOUT_COUNT; counter > 0; counter--) + { + if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) + { + break; + } + } + + /* Check for timeout. */ + if (!counter) + { + return kStatus_PHY_SMIVisitTimeout; + } + + /* Get data from MII register. */ + *dataPtr = ENET_ReadSMIData(base); + + /* Clear MII interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + return kStatus_Success; +} + +status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status) +{ + assert(status); + + status_t result = kStatus_Success; + uint32_t data; + + /* Read the basic status register. */ + result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &data); + if (result == kStatus_Success) + { + if (!(PHY_BSTATUS_LINKSTATUS_MASK & data)) + { + /* link down. */ + *status = false; + } + else + { + /* link up. */ + *status = true; + } + } + return result; +} + +status_t PHY_GetAutonegotiationStatus(ENET_Type *base, uint32_t phyAddr, bool *status) +{ + assert(status); + + status_t result = kStatus_Success; + uint32_t data; + + /* Read the basic status register. */ + result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &data); + if (result == kStatus_Success) + { + *status = data & PHY_BSTATUS_AUTONEGCOMP_MASK; + } + return result; +} + +status_t PHY_StartAutonegotiation(ENET_Type *base, uint32_t phyAddr) +{ + uint32_t bmcrVal; + status_t result = PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &bmcrVal); + bmcrVal |= PHY_BCTL_RESTART_AUTONEG_MASK; + result |= PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, bmcrVal); + return result; +} \ No newline at end of file diff --git a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/imx_emac.cpp b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/imx_emac.cpp index 8fba3340384..57ca6892c72 100644 --- a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/imx_emac.cpp +++ b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/imx_emac.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include "cmsis_os.h" @@ -43,6 +44,7 @@ #include "events/mbed_shared_queues.h" #include "fsl_phy.h" +#include "fsl_iomuxc.h" #include "imx_emac_config.h" #include "imx_emac.h" @@ -73,7 +75,10 @@ extern "C" void kinetis_init_eth_hardware(void); /** \brief Driver thread priority */ #define THREAD_PRIORITY (osPriorityNormal) -#define PHY_TASK_PERIOD 200ms +#define PHY_TASK_PERIOD 100ms + +// Change to 1 to get debug printfs from the emac +#define DEBUG_IMX_EMAC 0 Kinetis_EMAC::Kinetis_EMAC() : xTXDCountSem(ENET_TX_RING_LEN, ENET_TX_RING_LEN), hwaddr() { @@ -190,7 +195,6 @@ bool Kinetis_EMAC::low_level_init_successful() uint32_t sysClock; phy_speed_t phy_speed; phy_duplex_t phy_duplex; - uint32_t phyAddr = 0; enet_config_t config; AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rx_desc_start_addr[ENET_RX_RING_LEN], ENET_BUFF_ALIGNMENT); @@ -228,12 +232,14 @@ bool Kinetis_EMAC::low_level_init_successful() ENET_GetDefaultConfig(&config); - if (PHY_Init(ENET, phyAddr, sysClock) != kStatus_Success) { + if (PHY_Init(ENET, BOARD_ENET_PHY_ADDR, sysClock) != kStatus_Success) + { + printf("[IMX EMAC] Could not contact ethernet phy\n"); return false; } /* Get link information from PHY */ - PHY_GetLinkSpeedDuplex(ENET, phyAddr, &phy_speed, &phy_duplex); + PHY_GetLinkSpeedDuplex(ENET, BOARD_ENET_PHY_ADDR, &phy_speed, &phy_duplex); /* Change the MII speed and duplex for actual link status. */ config.miiSpeed = (enet_mii_speed_t)phy_speed; config.miiDuplex = (enet_mii_duplex_t)phy_duplex; @@ -246,7 +252,7 @@ bool Kinetis_EMAC::low_level_init_successful() ENET_SetCallback(&g_handle, &Kinetis_EMAC::ethernet_callback, this); ENET_ActiveRead(ENET); - + return true; } @@ -406,7 +412,7 @@ bool Kinetis_EMAC::link_out(emac_mem_buf_t *buf) SCB_CleanDCache_by_Addr(static_cast(memory_manager->get_ptr(buf)), memory_manager->get_len(buf)); /* Check if a descriptor is available for the transfer (wait 10ms before dropping the buffer) */ - if (!xTXDCountSem.try_acquire_for(10)) { + if (!xTXDCountSem.try_acquire_for(10ms)) { memory_manager->free(buf); return false; } @@ -448,44 +454,38 @@ bool Kinetis_EMAC::link_out(emac_mem_buf_t *buf) * PHY task: monitor link *******************************************************************************/ -#define STATE_UNKNOWN (-1) -#define STATE_LINK_DOWN (0) -#define STATE_LINK_UP (1) void Kinetis_EMAC::phy_task() { - uint32_t phyAddr = BOARD_ENET_PHY_ADDR; - // Get current status - PHY_STATE crt_state; - bool connection_status; - PHY_GetLinkStatus(ENET, phyAddr, &connection_status); - - if (connection_status) { - crt_state.connected = STATE_LINK_UP; - } else { - crt_state.connected = STATE_LINK_DOWN; - } - - if (crt_state.connected == STATE_LINK_UP) { - if (prev_state.connected != STATE_LINK_UP) { - PHY_AutoNegotiation(ENET, phyAddr); - } - - PHY_GetLinkSpeedDuplex(ENET, phyAddr, &crt_state.speed, &crt_state.duplex); + PHY_STATE currState{}; + PHY_GetLinkStatus(ENET, BOARD_ENET_PHY_ADDR, &currState.link_up); + + if(currState.link_up && !prev_state.link_up) + { + phy_speed_t speed; + phy_duplex_t duplex; + PHY_GetLinkSpeedDuplex(ENET, BOARD_ENET_PHY_ADDR, &speed, &duplex); + +#if DEBUG_IMX_EMAC + printf("[IMX EMAC] Link went up! Negotiated for speed %s, duplex %s\n", + speed == kPHY_Speed100M ? "100M" : "10M", + duplex == kPHY_FullDuplex ? "full" : "half"); +#endif + /* Poke the registers*/ + ENET_SetMII(ENET, (enet_mii_speed_t)speed, (enet_mii_duplex_t)duplex); - if (prev_state.connected != STATE_LINK_UP || crt_state.speed != prev_state.speed) { - /* Poke the registers*/ - ENET_SetMII(ENET, (enet_mii_speed_t)crt_state.speed, (enet_mii_duplex_t)crt_state.duplex); - } + emac_link_state_cb(currState.link_up); } - - // Compare with previous state - if (crt_state.connected != prev_state.connected && emac_link_state_cb) { - emac_link_state_cb(crt_state.connected); + else if(!currState.link_up && prev_state.link_up) + { +#if DEBUG_IMX_EMAC + printf("[IMX EMAC] Link went down!\n"); +#endif + emac_link_state_cb(currState.link_up); } - prev_state = crt_state; + prev_state = currState; } bool Kinetis_EMAC::power_up() @@ -505,9 +505,7 @@ bool Kinetis_EMAC::power_up() rx_isr(); /* PHY monitoring task */ - prev_state.connected = STATE_LINK_DOWN; - prev_state.speed = (phy_speed_t)STATE_UNKNOWN; - prev_state.duplex = (phy_duplex_t)STATE_UNKNOWN; + prev_state.link_up = false; mbed::mbed_event_queue()->call(mbed::callback(this, &Kinetis_EMAC::phy_task)); diff --git a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/imx_emac.h b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/imx_emac.h index 82b588b04fa..df5f7a6698a 100644 --- a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/imx_emac.h +++ b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/imx_emac.h @@ -171,9 +171,7 @@ class Kinetis_EMAC : public EMAC { EMACMemoryManager *memory_manager; /**< Memory manager */ int phy_task_handle; /**< Handle for phy task event */ struct PHY_STATE { - int connected; - phy_speed_t speed; - phy_duplex_t duplex; + bool link_up; }; PHY_STATE prev_state; uint8_t hwaddr[KINETIS_HWADDR_SIZE]; diff --git a/connectivity/netsocket/tests/TESTS/netsocket/udp/main.cpp b/connectivity/netsocket/tests/TESTS/netsocket/udp/main.cpp index 4b88b607b2a..c496c95d83f 100644 --- a/connectivity/netsocket/tests/TESTS/netsocket/udp/main.cpp +++ b/connectivity/netsocket/tests/TESTS/netsocket/udp/main.cpp @@ -64,6 +64,11 @@ static void _ifup() NetworkInterface *net = NetworkInterface::get_default_instance(); TEST_ASSERT_NOT_NULL_MESSAGE(net, "No NetworkInterface configured"); nsapi_error_t err = net->connect(); + + if (err != NSAPI_ERROR_OK) { + printf("Failed to initialize networking. Error: %d", err); + } + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err); SocketAddress address; net->get_ip_address(&address); diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/pwmout_api.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/pwmout_api.c index 641cc7d5143..9eaa0940716 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/pwmout_api.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/pwmout_api.c @@ -243,6 +243,7 @@ int pwmout_read_pulsewidth_us(pwmout_t *obj) { { count = (base->SM[module].VAL5) & PWM_VAL5_VAL5_MASK; } + return count; } const PinMap *pwmout_pinmap() diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/CMakeLists.txt b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/CMakeLists.txt index a1776d895bd..7080c3dcb6d 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/CMakeLists.txt +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/CMakeLists.txt @@ -11,7 +11,6 @@ target_include_directories(mbed-mimxrt1050-evk target_sources(mbed-mimxrt1050-evk INTERFACE - fsl_phy.c fsl_flexspi_nor_boot.c TARGET_1050_EVK/flash_api.c diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_TEENSY_4X/CMakeLists.txt b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_TEENSY_4X/CMakeLists.txt index 7d38d5d2219..367f3358f05 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_TEENSY_4X/CMakeLists.txt +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_TEENSY_4X/CMakeLists.txt @@ -16,4 +16,5 @@ target_include_directories(mbed-teensy-40 INTERFACE TARGET_TEENSY_40) # Target for Teensy 4.1 add_library(mbed-teensy-41 INTERFACE) target_link_libraries(mbed-teensy-41 INTERFACE - mbed-teensy-4x) \ No newline at end of file + mbed-teensy-4x) +target_include_directories(mbed-teensy-41 INTERFACE TARGET_TEENSY_41) \ No newline at end of file diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_TEENSY_4X/TARGET_TEENSY_40/PinNames.h b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_TEENSY_4X/TARGET_TEENSY_40/PinNames.h index c7c9d522407..dd323c6fc6c 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_TEENSY_4X/TARGET_TEENSY_40/PinNames.h +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_TEENSY_4X/TARGET_TEENSY_40/PinNames.h @@ -15,7 +15,7 @@ * limitations under the License. */ -/* MBED TARGET LIST: MIMXRT1050_EVK */ +/* MBED TARGET LIST: TEENSY_40 */ #ifndef MBED_PINNAMES_H #define MBED_PINNAMES_H diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_TEENSY_4X/TARGET_TEENSY_41/PinNames.h b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_TEENSY_4X/TARGET_TEENSY_41/PinNames.h new file mode 100644 index 00000000000..19acfeb0f80 --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_TEENSY_4X/TARGET_TEENSY_41/PinNames.h @@ -0,0 +1,273 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* MBED TARGET LIST: TEENSY_41 */ + +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define GPIO_PORT_SHIFT 12 +#define GPIO_MUX_PORT 5 + +typedef enum { + WAKEUP = ((5 << GPIO_PORT_SHIFT) | 0), + PMIC_ON_REQ = ((5 << GPIO_PORT_SHIFT) | 1), + PMIC_STBY_REQ = ((5 << GPIO_PORT_SHIFT) | 2), + + GPIO_EMC_00 = ((4 << GPIO_PORT_SHIFT) | 0), + GPIO_EMC_01 = ((4 << GPIO_PORT_SHIFT) | 1), + GPIO_EMC_02 = ((4 << GPIO_PORT_SHIFT) | 2), + GPIO_EMC_03 = ((4 << GPIO_PORT_SHIFT) | 3), + GPIO_EMC_04 = ((4 << GPIO_PORT_SHIFT) | 4), + GPIO_EMC_05 = ((4 << GPIO_PORT_SHIFT) | 5), + GPIO_EMC_06 = ((4 << GPIO_PORT_SHIFT) | 6), + GPIO_EMC_07 = ((4 << GPIO_PORT_SHIFT) | 7), + GPIO_EMC_08 = ((4 << GPIO_PORT_SHIFT) | 8), + GPIO_EMC_09 = ((4 << GPIO_PORT_SHIFT) | 9), + GPIO_EMC_10 = ((4 << GPIO_PORT_SHIFT) | 10), + GPIO_EMC_11 = ((4 << GPIO_PORT_SHIFT) | 11), + GPIO_EMC_12 = ((4 << GPIO_PORT_SHIFT) | 12), + GPIO_EMC_13 = ((4 << GPIO_PORT_SHIFT) | 13), + GPIO_EMC_14 = ((4 << GPIO_PORT_SHIFT) | 14), + GPIO_EMC_15 = ((4 << GPIO_PORT_SHIFT) | 15), + GPIO_EMC_16 = ((4 << GPIO_PORT_SHIFT) | 16), + GPIO_EMC_17 = ((4 << GPIO_PORT_SHIFT) | 17), + GPIO_EMC_18 = ((4 << GPIO_PORT_SHIFT) | 18), + GPIO_EMC_19 = ((4 << GPIO_PORT_SHIFT) | 19), + GPIO_EMC_20 = ((4 << GPIO_PORT_SHIFT) | 20), + GPIO_EMC_21 = ((4 << GPIO_PORT_SHIFT) | 21), + GPIO_EMC_22 = ((4 << GPIO_PORT_SHIFT) | 22), + GPIO_EMC_23 = ((4 << GPIO_PORT_SHIFT) | 23), + GPIO_EMC_24 = ((4 << GPIO_PORT_SHIFT) | 24), + GPIO_EMC_25 = ((4 << GPIO_PORT_SHIFT) | 25), + GPIO_EMC_26 = ((4 << GPIO_PORT_SHIFT) | 26), + GPIO_EMC_27 = ((4 << GPIO_PORT_SHIFT) | 27), + GPIO_EMC_28 = ((4 << GPIO_PORT_SHIFT) | 28), + GPIO_EMC_29 = ((4 << GPIO_PORT_SHIFT) | 29), + GPIO_EMC_30 = ((4 << GPIO_PORT_SHIFT) | 30), + GPIO_EMC_31 = ((4 << GPIO_PORT_SHIFT) | 31), + GPIO_EMC_32 = ((3 << GPIO_PORT_SHIFT) | 18), + GPIO_EMC_33 = ((3 << GPIO_PORT_SHIFT) | 19), + GPIO_EMC_34 = ((3 << GPIO_PORT_SHIFT) | 20), + GPIO_EMC_35 = ((3 << GPIO_PORT_SHIFT) | 21), + GPIO_EMC_36 = ((3 << GPIO_PORT_SHIFT) | 22), + GPIO_EMC_37 = ((3 << GPIO_PORT_SHIFT) | 23), + GPIO_EMC_38 = ((3 << GPIO_PORT_SHIFT) | 24), + GPIO_EMC_39 = ((3 << GPIO_PORT_SHIFT) | 25), + GPIO_EMC_40 = ((3 << GPIO_PORT_SHIFT) | 26), + GPIO_EMC_41 = ((3 << GPIO_PORT_SHIFT) | 27), + + GPIO_AD_B0_00 = ((1 << GPIO_PORT_SHIFT) | 0), + GPIO_AD_B0_01 = ((1 << GPIO_PORT_SHIFT) | 1), + GPIO_AD_B0_02 = ((1 << GPIO_PORT_SHIFT) | 2), + GPIO_AD_B0_03 = ((1 << GPIO_PORT_SHIFT) | 3), + GPIO_AD_B0_04 = ((1 << GPIO_PORT_SHIFT) | 4), + GPIO_AD_B0_05 = ((1 << GPIO_PORT_SHIFT) | 5), + GPIO_AD_B0_06 = ((1 << GPIO_PORT_SHIFT) | 6), + GPIO_AD_B0_07 = ((1 << GPIO_PORT_SHIFT) | 7), + GPIO_AD_B0_08 = ((1 << GPIO_PORT_SHIFT) | 8), + GPIO_AD_B0_09 = ((1 << GPIO_PORT_SHIFT) | 9), + GPIO_AD_B0_10 = ((1 << GPIO_PORT_SHIFT) | 10), + GPIO_AD_B0_11 = ((1 << GPIO_PORT_SHIFT) | 11), + GPIO_AD_B0_12 = ((1 << GPIO_PORT_SHIFT) | 12), + GPIO_AD_B0_13 = ((1 << GPIO_PORT_SHIFT) | 13), + GPIO_AD_B0_14 = ((1 << GPIO_PORT_SHIFT) | 14), + GPIO_AD_B0_15 = ((1 << GPIO_PORT_SHIFT) | 15), + + GPIO_AD_B1_00 = ((1 << GPIO_PORT_SHIFT) | 16), + GPIO_AD_B1_01 = ((1 << GPIO_PORT_SHIFT) | 17), + GPIO_AD_B1_02 = ((1 << GPIO_PORT_SHIFT) | 18), + GPIO_AD_B1_03 = ((1 << GPIO_PORT_SHIFT) | 19), + GPIO_AD_B1_04 = ((1 << GPIO_PORT_SHIFT) | 20), + GPIO_AD_B1_05 = ((1 << GPIO_PORT_SHIFT) | 21), + GPIO_AD_B1_06 = ((1 << GPIO_PORT_SHIFT) | 22), + GPIO_AD_B1_07 = ((1 << GPIO_PORT_SHIFT) | 23), + GPIO_AD_B1_08 = ((1 << GPIO_PORT_SHIFT) | 24), + GPIO_AD_B1_09 = ((1 << GPIO_PORT_SHIFT) | 25), + GPIO_AD_B1_10 = ((1 << GPIO_PORT_SHIFT) | 26), + GPIO_AD_B1_11 = ((1 << GPIO_PORT_SHIFT) | 27), + GPIO_AD_B1_12 = ((1 << GPIO_PORT_SHIFT) | 28), + GPIO_AD_B1_13 = ((1 << GPIO_PORT_SHIFT) | 29), + GPIO_AD_B1_14 = ((1 << GPIO_PORT_SHIFT) | 30), + GPIO_AD_B1_15 = ((1 << GPIO_PORT_SHIFT) | 31), + + GPIO_B0_00 = ((2 << GPIO_PORT_SHIFT) | 0), + GPIO_B0_01 = ((2 << GPIO_PORT_SHIFT) | 1), + GPIO_B0_02 = ((2 << GPIO_PORT_SHIFT) | 2), + GPIO_B0_03 = ((2 << GPIO_PORT_SHIFT) | 3), + GPIO_B0_04 = ((2 << GPIO_PORT_SHIFT) | 4), + GPIO_B0_05 = ((2 << GPIO_PORT_SHIFT) | 5), + GPIO_B0_06 = ((2 << GPIO_PORT_SHIFT) | 6), + GPIO_B0_07 = ((2 << GPIO_PORT_SHIFT) | 7), + GPIO_B0_08 = ((2 << GPIO_PORT_SHIFT) | 8), + GPIO_B0_09 = ((2 << GPIO_PORT_SHIFT) | 9), + GPIO_B0_10 = ((2 << GPIO_PORT_SHIFT) | 10), + GPIO_B0_11 = ((2 << GPIO_PORT_SHIFT) | 11), + GPIO_B0_12 = ((2 << GPIO_PORT_SHIFT) | 12), + GPIO_B0_13 = ((2 << GPIO_PORT_SHIFT) | 13), + GPIO_B0_14 = ((2 << GPIO_PORT_SHIFT) | 14), + GPIO_B0_15 = ((2 << GPIO_PORT_SHIFT) | 15), + + GPIO_B1_00 = ((2 << GPIO_PORT_SHIFT) | 16), + GPIO_B1_01 = ((2 << GPIO_PORT_SHIFT) | 17), + GPIO_B1_02 = ((2 << GPIO_PORT_SHIFT) | 18), + GPIO_B1_03 = ((2 << GPIO_PORT_SHIFT) | 19), + GPIO_B1_04 = ((2 << GPIO_PORT_SHIFT) | 20), + GPIO_B1_05 = ((2 << GPIO_PORT_SHIFT) | 21), + GPIO_B1_06 = ((2 << GPIO_PORT_SHIFT) | 22), + GPIO_B1_07 = ((2 << GPIO_PORT_SHIFT) | 23), + GPIO_B1_08 = ((2 << GPIO_PORT_SHIFT) | 24), + GPIO_B1_09 = ((2 << GPIO_PORT_SHIFT) | 25), + GPIO_B1_10 = ((2 << GPIO_PORT_SHIFT) | 26), + GPIO_B1_11 = ((2 << GPIO_PORT_SHIFT) | 27), + GPIO_B1_12 = ((2 << GPIO_PORT_SHIFT) | 28), + GPIO_B1_13 = ((2 << GPIO_PORT_SHIFT) | 29), + GPIO_B1_14 = ((2 << GPIO_PORT_SHIFT) | 30), + GPIO_B1_15 = ((2 << GPIO_PORT_SHIFT) | 31), + + GPIO_SD_B0_00 = ((3 << GPIO_PORT_SHIFT) | 12), + GPIO_SD_B0_01 = ((3 << GPIO_PORT_SHIFT) | 13), + GPIO_SD_B0_02 = ((3 << GPIO_PORT_SHIFT) | 14), + GPIO_SD_B0_03 = ((3 << GPIO_PORT_SHIFT) | 15), + GPIO_SD_B0_04 = ((3 << GPIO_PORT_SHIFT) | 16), + GPIO_SD_B0_05 = ((3 << GPIO_PORT_SHIFT) | 17), + + GPIO_SD_B1_00 = ((3 << GPIO_PORT_SHIFT) | 0), + GPIO_SD_B1_01 = ((3 << GPIO_PORT_SHIFT) | 1), + GPIO_SD_B1_02 = ((3 << GPIO_PORT_SHIFT) | 2), + GPIO_SD_B1_03 = ((3 << GPIO_PORT_SHIFT) | 3), + GPIO_SD_B1_04 = ((3 << GPIO_PORT_SHIFT) | 4), + GPIO_SD_B1_05 = ((3 << GPIO_PORT_SHIFT) | 5), + GPIO_SD_B1_06 = ((3 << GPIO_PORT_SHIFT) | 6), + GPIO_SD_B1_07 = ((3 << GPIO_PORT_SHIFT) | 7), + GPIO_SD_B1_08 = ((3 << GPIO_PORT_SHIFT) | 8), + GPIO_SD_B1_09 = ((3 << GPIO_PORT_SHIFT) | 9), + GPIO_SD_B1_10 = ((3 << GPIO_PORT_SHIFT) | 10), + GPIO_SD_B1_11 = ((3 << GPIO_PORT_SHIFT) | 11), + + // Teensy 4.1 pin names ------------------------------------- + // Digital + D0 = GPIO_AD_B0_03, + D1 = GPIO_AD_B0_02, + D2 = GPIO_EMC_04, + D3 = GPIO_EMC_05, + D4 = GPIO_EMC_06, + D5 = GPIO_EMC_08, + D6 = GPIO_B0_10, + D7 = GPIO_B1_01, + D8 = GPIO_B1_00, + D9 = GPIO_B0_11, + D10 = GPIO_B0_00, + D11 = GPIO_B0_02, + D12 = GPIO_B0_01, + D13 = GPIO_B0_03, + D14 = GPIO_AD_B1_02, + D15 = GPIO_AD_B1_03, + D16 = GPIO_AD_B1_07, + D17 = GPIO_AD_B1_06, + D18 = GPIO_AD_B1_01, + D19 = GPIO_AD_B1_00, + D20 = GPIO_AD_B1_10, + D21 = GPIO_AD_B1_11, + D22 = GPIO_AD_B1_08, + D23 = GPIO_AD_B1_09, + D24 = GPIO_AD_B0_12, + D25 = GPIO_AD_B0_13, + D26 = GPIO_AD_B1_14, + D27 = GPIO_AD_B1_15, + D28 = GPIO_EMC_32, + D29 = GPIO_EMC_31, + D30 = GPIO_EMC_37, + D31 = GPIO_EMC_36, + D32 = GPIO_B0_12, + D33 = GPIO_EMC_07, // note: All above here are the same as TEENSY4_0 + D34 = GPIO_B1_13, + D35 = GPIO_B1_12, + D36 = GPIO_B1_02, + D37 = GPIO_B1_07, + D38 = GPIO_AD_B1_12, + D39 = GPIO_AD_B1_13, + D40 = GPIO_AD_B1_04, + D41 = GPIO_AD_B1_05, + + // Analog + A0 = GPIO_AD_B1_02, + A1 = GPIO_AD_B1_03, + A2 = GPIO_AD_B1_07, + A3 = GPIO_AD_B1_06, + A4 = GPIO_AD_B1_01, + A5 = GPIO_AD_B1_00, + A6 = GPIO_AD_B1_10, + A7 = GPIO_AD_B1_11, + A8 = GPIO_AD_B1_08, + A9 = GPIO_AD_B1_09, + A10 = GPIO_AD_B0_12, + A11 = GPIO_AD_B0_13, + A12 = GPIO_AD_B1_14, + A13 = GPIO_AD_B1_15, + A14 = GPIO_AD_B1_12, + A15 = GPIO_AD_B1_13, + A16 = GPIO_AD_B1_04, + A17 = GPIO_AD_B1_05, + + // SD card pins + SD_CLK = GPIO_SD_B0_01, + SD_DAT0 = GPIO_SD_B0_02, + SD_DAT1 = GPIO_SD_B0_03, + SD_DAT2 = GPIO_SD_B0_04, + SD_DAT3 = GPIO_SD_B0_05, + + // Standard aliases ------------------------------------- + + // Even though the UART console is not used by default, we still provide mappings on the standard Arduino pins + CONSOLE_TX = D1, + CONSOLE_RX = D0, + + // Not connected + NC = (int)0xFFFFFFFF +} PinName; + +// Standardized LED and button names +#define LED1 D13 +#define USER_LED LED1 + +typedef enum { + PullNone = 0, + PullDown = 1, + PullUp_47K = 2, + PullUp_100K = 3, + PullUp_22K = 4, + PullDefault = PullUp_47K, + PullUp = PullUp_47K +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_TEENSY_4X/device.h b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_TEENSY_4X/device.h index 4dd30f8a11e..7bf7ace6675 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_TEENSY_4X/device.h +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_TEENSY_4X/device.h @@ -25,6 +25,9 @@ to be as vector table */ #undef __VECTOR_TABLE +// Set to 1 by MIMXRT pullups/pulldowns on CRS_DV and RXD0 +#define BOARD_ENET_PHY_ADDR 1 + #include "objects.h" #endif diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_dcp.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_dcp.c index b5d2dee619a..aaef2e40a17 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_dcp.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_dcp.c @@ -96,7 +96,7 @@ static dcp_context_t s_dcpContextSwitchingBuffer; static void dcp_reverse_and_copy(uint8_t *src, uint8_t *dest, size_t src_len) { - for (int i = 0; i < src_len; i++) + for (size_t i = 0; i < src_len; i++) { dest[i] = src[src_len - 1 - i]; } diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_enet.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_enet.c index 46a470b28d6..aa15ad92668 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_enet.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_enet.c @@ -762,7 +762,7 @@ static void ENET_SetTxBufferDescriptors(enet_handle_t *handle, /* Check the input parameters. */ for (ringNum = 0; ringNum < config->ringNum; ringNum++) { - if (buffCfg->txBdStartAddrAlign > 0) + if (buffCfg->txBdStartAddrAlign != 0) { volatile enet_tx_bd_struct_t *curBuffDescrip = buffCfg->txBdStartAddrAlign; txBuffSizeAlign = buffCfg->txBuffSizeAlign; @@ -780,7 +780,7 @@ static void ENET_SetTxBufferDescriptors(enet_handle_t *handle, /* Sets the crc. */ curBuffDescrip->control = ENET_BUFFDESCRIPTOR_TX_TRANMITCRC_MASK; /* Sets the last buffer descriptor with the wrap flag. */ - if (count == buffCfg->txBdNumber - 1) + if (count == (uint32_t)(buffCfg->txBdNumber - 1)) { curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_WRAP_MASK; } @@ -811,7 +811,7 @@ static void ENET_SetRxBufferDescriptors(enet_handle_t *handle, /* Default single ring is supported. */ uint8_t ringNum; uint32_t count; - uint32_t rxBuffSizeAlign; + uint32_t __attribute__((unused)) rxBuffSizeAlign; uint8_t *rxBuffer; const enet_buffer_config_t *buffCfg = bufferConfig; #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE @@ -835,7 +835,7 @@ static void ENET_SetRxBufferDescriptors(enet_handle_t *handle, #endif /* FSL_FEATURE_ENET_QUEUE > 1 */ #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - if ((buffCfg->rxBdStartAddrAlign > 0) && (buffCfg->rxBufferAlign > 0)) + if ((buffCfg->rxBdStartAddrAlign != 0) && (buffCfg->rxBufferAlign != 0)) { volatile enet_rx_bd_struct_t *curBuffDescrip = buffCfg->rxBdStartAddrAlign; rxBuffSizeAlign = buffCfg->rxBuffSizeAlign; @@ -859,7 +859,7 @@ static void ENET_SetRxBufferDescriptors(enet_handle_t *handle, /* Initializes the buffer descriptors with empty bit. */ curBuffDescrip->control = ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK; /* Sets the last buffer descriptor with the wrap flag. */ - if (count == buffCfg->rxBdNumber - 1) + if (count == (uint32_t)(buffCfg->rxBdNumber - 1)) { curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK; } diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_flexram.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_flexram.c index ee93440d94a..89313c350d6 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_flexram.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_flexram.c @@ -200,7 +200,7 @@ status_t FLEXRAM_AllocateRam(flexram_allocate_ram_t *config) continue; } - if (i < (dtcmBankNum + ocramBankNum + itcmBankNum)) + if (i < (uint32_t)(dtcmBankNum + ocramBankNum + itcmBankNum)) { bankCfg |= ((uint32_t)kFLEXRAM_BankITCM) << (i * 2); continue; diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_flexspi.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_flexspi.c index ec1e6382002..ffb00f57545 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_flexspi.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_flexspi.c @@ -97,11 +97,6 @@ static FLEXSPI_Type *const s_flexspiBases[] = FLEXSPI_BASE_PTRS; /*! @brief Pointers to flexspi IRQ number for each instance. */ static const IRQn_Type s_flexspiIrqs[] = FLEXSPI_IRQS; -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/* Clock name array */ -static const clock_ip_name_t s_flexspiClock[] = FLEXSPI_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - #if defined(FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ) && FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ /*! @brief Pointers to flexspi handles for each instance. */ static flexspi_handle_t *s_flexspiHandle[ARRAY_SIZE(s_flexspiBases)]; @@ -245,9 +240,8 @@ void FLEXSPI_Init(FLEXSPI_Type *base, const flexspi_config_t *config) uint8_t i = 0; #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable the flexspi clock */ - //CLOCK_EnableClock(s_flexspiClock[FLEXSPI_GetInstance(base)]); - /* Access the register directly to avoid warnings accessing non ran functions */ + /* Enable the flexspi clock. */ + /* Do this by accessing the register directly to avoid warnings accessing non-RAM functions */ CCM->CCGR6 |= CCM_CCGR6_CG5_MASK; #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_sai.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_sai.c index 9bf4c59ba2b..e702073e7d3 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_sai.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_sai.c @@ -1395,7 +1395,7 @@ void SAI_TxSetConfig(I2S_Type *base, sai_transceiver_t *config) config->channelMask = 1U << config->startChannel; } - for (i = 0U; i < FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++) + for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++) { if (((uint32_t)1 << i) & config->channelMask) { @@ -1408,7 +1408,7 @@ void SAI_TxSetConfig(I2S_Type *base, sai_transceiver_t *config) config->endChannel = i; } } - assert(channelNums <= FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); + assert(channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); config->channelNums = channelNums; #if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) /* make sure combine mode disabled while multipe channel is used */ @@ -1518,7 +1518,7 @@ void SAI_RxSetConfig(I2S_Type *base, sai_transceiver_t *config) config->channelMask = 1U << config->startChannel; } - for (i = 0U; i < FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++) + for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++) { if (((uint32_t)1 << i) & config->channelMask) { @@ -1531,7 +1531,7 @@ void SAI_RxSetConfig(I2S_Type *base, sai_transceiver_t *config) config->endChannel = i; } } - assert(channelNums <= FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); + assert(channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); config->channelNums = channelNums; #if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) /* make sure combine mode disabled while multipe channel is used */ @@ -1851,7 +1851,7 @@ void SAI_TxSetFormat(I2S_Type *base, } /* if channel nums is not set, calculate it here according to channelMask*/ - for (i = 0U; i < FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++) + for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++) { if (((uint32_t)1 << i) & format->channelMask) { @@ -1990,7 +1990,7 @@ void SAI_RxSetFormat(I2S_Type *base, } /* if channel nums is not set, calculate it here according to channelMask*/ - for (i = 0U; i < FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++) + for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++) { if (((uint32_t)1 << i) & format->channelMask) { @@ -2087,7 +2087,7 @@ void SAI_WriteMultiChannelBlocking( bytesPerWord = (size_t)((FSL_FEATURE_SAI_FIFO_COUNT - base->TCR1) * bytesPerWord); #endif - for (i = 0U; (i < FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); i++) + for (i = 0U; (i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); i++) { if ((1U << i) & (channelMask)) { @@ -2096,7 +2096,7 @@ void SAI_WriteMultiChannelBlocking( } } - assert(channelNums <= FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); + assert(channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); bytesPerWord *= channelNums; while (j < size) @@ -2140,7 +2140,7 @@ void SAI_ReadMultiChannelBlocking( #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) bytesPerWord = (size_t)(base->RCR1 * bytesPerWord); #endif - for (i = 0U; (i < FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); i++) + for (i = 0U; (i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); i++) { if ((1U << i) & (channelMask)) { @@ -2149,7 +2149,7 @@ void SAI_ReadMultiChannelBlocking( } } - assert(channelNums <= FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); + assert(channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); bytesPerWord *= channelNums; while (j < size) diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/mbed_overrides.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/mbed_overrides.c index 5f9e66a5d22..cc4841ee8d5 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/mbed_overrides.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/mbed_overrides.c @@ -289,6 +289,8 @@ void mbed_mac_address(char *mac) { } uint8_t mbed_otp_mac_address(char *mac) { + +#if TARGET_MIMXRT1050_EVK /* Check if a valid MAC address is programmed to the fuse bank */ if ((OCOTP->MAC0 != 0) && (OCOTP->MAC1 != 0) && @@ -308,10 +310,26 @@ uint8_t mbed_otp_mac_address(char *mac) { mac[3] = MAC[1]; mac[4] = MAC[2] >> 8; mac[5] = MAC[2]; - } else { - return 0; + + return 1; + } +#endif + +#if TARGET_TEENSY_4X + if(OCOTP->MAC0 != 0 || OCOTP->MAC1 != 0) + { + mac[0] = OCOTP->MAC1 >> 8; + mac[1] = OCOTP->MAC1 >> 0; + mac[2] = OCOTP->MAC0 >> 24; + mac[3] = OCOTP->MAC0 >> 16; + mac[4] = OCOTP->MAC0 >> 8; + mac[5] = OCOTP->MAC0 >> 0; + + return 1; } - return 1; +#endif + + return 0; } void mbed_default_mac_address(char *mac) { diff --git a/targets/targets.json b/targets/targets.json index 515709b508b..0617dfd0089 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -5195,6 +5195,24 @@ "EMAC" ] }, + "TEENSY_41": { + "inherits": [ + "MIMXRT105X" + ], + "extra_labels_add": [ + "TEENSY_4X", + "TEENSY_41" + ], + "macros_add": [ + "MIMXRT105X_BOARD_HAS_EXTERNAL_RAM=0", + "MBED_APP_SIZE=0x7C0000" + ], + "overrides": { + "console-usb": true, + "console-uart": false, + "network-default-interface-type": "ETHERNET" + } + }, "MIMXRT1170_EVK": { "supported_form_factors": [ "ARDUINO_UNO" diff --git a/tools/cmake/app.cmake b/tools/cmake/app.cmake index 47915aad885..7f8dfb5bf42 100644 --- a/tools/cmake/app.cmake +++ b/tools/cmake/app.cmake @@ -82,7 +82,4 @@ if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/../../${EXPECTED_MBED_UPLOAD_CFG_FILE_PATH}) else() message(STATUS "Mbed: Target does not have any upload method configuration. 'make flash-' commands will not be available unless configured by the upper-level project.") set(UPLOAD_METHOD_DEFAULT "NONE") -endif() - -# Load debug config generator for IDEs -include(mbed_ide_debug_cfg_generator) \ No newline at end of file +endif() \ No newline at end of file diff --git a/tools/cmake/mbed_generate_configuration.cmake b/tools/cmake/mbed_generate_configuration.cmake index 5b2080892ee..7e70b502e76 100644 --- a/tools/cmake/mbed_generate_configuration.cmake +++ b/tools/cmake/mbed_generate_configuration.cmake @@ -97,6 +97,7 @@ if(MBED_NEED_TO_RECONFIGURE) -m "${MBED_TARGET}" --mbed-os-path ${CMAKE_CURRENT_LIST_DIR}/../.. --output-dir ${CMAKE_CURRENT_BINARY_DIR} + --program-path ${CMAKE_SOURCE_DIR} ${APP_CONFIG_ARGUMENT} ${CUSTOM_TARGET_ARGUMENT}) diff --git a/tools/cmake/mbed_ide_debug_cfg_generator.cmake b/tools/cmake/mbed_ide_debug_cfg_generator.cmake index c095772e5dc..ab5022b9669 100644 --- a/tools/cmake/mbed_ide_debug_cfg_generator.cmake +++ b/tools/cmake/mbed_ide_debug_cfg_generator.cmake @@ -34,12 +34,12 @@ endif() if(MBED_GENERATE_CLION_DEBUG_CFGS) - # Find CLion run config dir - set(CLION_RUN_CONF_DIR ${CMAKE_SOURCE_DIR}/.idea/runConfigurations) - file(MAKE_DIRECTORY ${CLION_RUN_CONF_DIR}) - function(mbed_generate_ide_debug_configuration CMAKE_TARGET) + # Find CLion run config dir + set(CLION_RUN_CONF_DIR ${CMAKE_SOURCE_DIR}/.idea/runConfigurations) + file(MAKE_DIRECTORY ${CLION_RUN_CONF_DIR}) + # Create name (combine target name, Mbed target, and build type to generate a unique string) set(CONFIG_NAME "GDB ${CMAKE_TARGET} ${MBED_TARGET} ${CMAKE_BUILD_TYPE}") set(RUN_CONF_PATH "${CLION_RUN_CONF_DIR}/${CONFIG_NAME}.xml") @@ -95,8 +95,6 @@ if(MBED_GENERATE_CLION_DEBUG_CFGS) # ------------------------------------------------------------- elseif(MBED_GENERATE_VS_CODE_DEBUG_CFGS) - set(VSCODE_LAUNCH_JSON_PATH ${CMAKE_SOURCE_DIR}/.vscode/launch.json) - # Start building up json file. Needs to be a global property so we can append to it from anywhere. # Note: Cannot use a cache variable for this because cache variables aren't allowed to contain newlines. set_property(GLOBAL PROPERTY VSCODE_LAUNCH_JSON_CONTENT @@ -167,6 +165,7 @@ elseif(MBED_GENERATE_VS_CODE_DEBUG_CFGS) # Take all generated debug configurations and write them to launch.json. function(mbed_finalize_ide_debug_configurations) + set(VSCODE_LAUNCH_JSON_PATH ${CMAKE_SOURCE_DIR}/.vscode/launch.json) # Add footer set_property(GLOBAL APPEND_STRING PROPERTY VSCODE_LAUNCH_JSON_CONTENT "