diff --git a/CMakeLists.txt b/CMakeLists.txt index 52b0e07..d93abbe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -218,6 +218,8 @@ # 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 9d9ef33..af73ac8 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_sources(mbed-emac PRIVATE imx_emac.cpp + fsl_phy_common.c ) diff --git a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/CMakeLists.txt b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/CMakeLists.txt new file mode 100644 index 0000000..a00d2fd --- /dev/null +++ b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/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.c + fsl_phy_ksz8081rnb.c +) diff --git a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/fsl_phy_ksz8081rnb.c b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/fsl_phy_ksz8081rnb.c new file mode 100644 index 0000000..c107016 --- /dev/null +++ b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/fsl_phy_ksz8081rnb.c @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_phy.h" +#include "ksz8081rnb_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; + } + + /* Reset PHY. */ + result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK); + if (result == kStatus_Success) + { +#if defined(FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE) + uint32_t data = 0; + result = PHY_Read(base, phyAddr, PHY_CONTROL2_REG, &data); + if (result != kStatus_Success) + { + return result; + } + result = PHY_Write(base, phyAddr, PHY_CONTROL2_REG, (data | PHY_CTL2_REFCLK_SELECT_MASK)); + if (result != kStatus_Success) + { + return result; + } +#endif /* FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE */ + } + + // 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)); + + 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) +{ + status_t result; + 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; + } + return PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, data); + } + else + { + /* First read the current status in control register. */ + result = PHY_Read(base, phyAddr, PHY_CONTROL2_REG, &data); + if (result == kStatus_Success) + { + return PHY_Write(base, phyAddr, PHY_CONTROL2_REG, (data | PHY_CTL2_REMOTELOOP_MASK)); + } + } + } + else + { + /* Disable the loop mode. */ + if (mode == kPHY_LocalLoop) + { + /* First read the current status in control register. */ + result = PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &data); + if (result == kStatus_Success) + { + data &= ~PHY_BCTL_LOOP_MASK; + return PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (data | PHY_BCTL_RESTART_AUTONEG_MASK)); + } + } + else + { + /* First read the current status in control one register. */ + result = PHY_Read(base, phyAddr, PHY_CONTROL2_REG, &data); + if (result == kStatus_Success) + { + return PHY_Write(base, phyAddr, PHY_CONTROL2_REG, (data & ~PHY_CTL2_REMOTELOOP_MASK)); + } + } + } + return result; +} + +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 data, ctlReg; + + /* Read the control two register. */ + result = PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &ctlReg); + if (result == kStatus_Success) + { + data = ctlReg & PHY_CTL1_SPEEDUPLX_MASK; + if ((PHY_CTL1_10FULLDUPLEX_MASK == data) || (PHY_CTL1_100FULLDUPLEX_MASK == data)) + { + /* Full duplex. */ + *duplex = kPHY_FullDuplex; + } + else + { + /* Half duplex. */ + *duplex = kPHY_HalfDuplex; + } + + data = ctlReg & PHY_CTL1_SPEEDUPLX_MASK; + if ((PHY_CTL1_100HALFDUPLEX_MASK == data) || (PHY_CTL1_100FULLDUPLEX_MASK == data)) + { + /* 100M speed. */ + *speed = kPHY_Speed100M; + } + else + { /* 10M speed. */ + *speed = kPHY_Speed10M; + } + } + + return result; +} diff --git a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/hardware_init.c b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/hardware_init.c new file mode 100644 index 0000000..2f6e27f --- /dev/null +++ b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/hardware_init.c @@ -0,0 +1,226 @@ +/* + * 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" + +/******************************************************************************* + * Code + ******************************************************************************/ +static void BOARD_InitModuleClock(void) +{ + const clock_enet_pll_config_t config = {true, false, 1}; + CLOCK_InitEnetPll(&config); +} + +void kinetis_init_eth_hardware(void) +{ + gpio_pin_config_t gpio_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode}; + + CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */ + + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, /* GPIO_AD_B0_09 is configured as GPIO1_IO09 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B0_10_GPIO1_IO10, /* GPIO_AD_B0_10 is configured as GPIO1_IO10 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_04_ENET_RX_DATA00, /* GPIO_B1_04 is configured as ENET_RX_DATA00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_05_ENET_RX_DATA01, /* GPIO_B1_05 is configured as ENET_RX_DATA01 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_06_ENET_RX_EN, /* GPIO_B1_06 is configured as ENET_RX_EN */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_07_ENET_TX_DATA00, /* GPIO_B1_07 is configured as ENET_TX_DATA00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_08_ENET_TX_DATA01, /* GPIO_B1_08 is configured as ENET_TX_DATA01 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_09_ENET_TX_EN, /* GPIO_B1_09 is configured as ENET_TX_EN */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_10_ENET_REF_CLK, /* GPIO_B1_10 is configured as ENET_REF_CLK */ + 1U); /* Software Input On Field: Force input path of pad GPIO_B1_10 */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_11_ENET_RX_ER, /* GPIO_B1_11 is configured as ENET_RX_ER */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_40_ENET_MDC, /* GPIO_EMC_40 is configured as ENET_MDC */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_41_ENET_MDIO, /* GPIO_EMC_41 is configured as ENET_MDIO */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, /* GPIO_AD_B0_09 PAD functional properties : */ + 0xB0A9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/5 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Disabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_B0_10_GPIO1_IO10, /* GPIO_AD_B0_10 PAD functional properties : */ + 0xB0A9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/5 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Disabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_04_ENET_RX_DATA00, /* GPIO_B1_04 PAD functional properties : */ + 0xB0E9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/5 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Disabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_05_ENET_RX_DATA01, /* GPIO_B1_05 PAD functional properties : */ + 0xB0E9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/5 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Disabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_06_ENET_RX_EN, /* GPIO_B1_06 PAD functional properties : */ + 0xB0E9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/5 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Disabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_07_ENET_TX_DATA00, /* GPIO_B1_07 PAD functional properties : */ + 0xB0E9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/5 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Disabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_08_ENET_TX_DATA01, /* GPIO_B1_08 PAD functional properties : */ + 0xB0E9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/5 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Disabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_09_ENET_TX_EN, /* GPIO_B1_09 PAD functional properties : */ + 0xB0E9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/5 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Disabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_10_ENET_REF_CLK, /* GPIO_B1_10 PAD functional properties : */ + 0x31u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/6 + Speed Field: low(50MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Disabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Disabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_11_ENET_RX_ER, /* GPIO_B1_11 PAD functional properties : */ + 0xB0E9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/5 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Disabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_40_ENET_MDC, /* GPIO_EMC_40 PAD functional properties : */ + 0xB0E9u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/5 + Speed Field: max(200MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Disabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_41_ENET_MDIO, /* GPIO_EMC_41 PAD functional properties : */ + 0xB829u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/5 + Speed Field: low(50MHz) + Open Drain Enable Field: Open Drain Enabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Disabled */ + + + BOARD_InitModuleClock(); + + IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, true); + + GPIO_PinInit(GPIO1, 9, &gpio_config); + GPIO_PinInit(GPIO1, 10, &gpio_config); + /* pull up the ENET_INT before RESET. */ + GPIO_WritePinOutput(GPIO1, 10, 1); + GPIO_WritePinOutput(GPIO1, 9, 0); + wait_us(1 * 1000); + GPIO_WritePinOutput(GPIO1, 9, 1); +} + +/******************************************************************************* + * EOF + ******************************************************************************/ + + 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 0000000..0ddb42f --- /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_MIMXRT10x0_EVK/CMakeLists.txt b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT10x0_EVK/CMakeLists.txt deleted file mode 100644 index db07c9f..0000000 --- a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT10x0_EVK/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2020 ARM Limited. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 - -target_sources(mbed-emac - PRIVATE - hardware_init.c -) 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_MIMXRT10x0_EVK/hardware_init.c deleted file mode 100644 index 2f6e27f..0000000 --- a/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT10x0_EVK/hardware_init.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * 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" - -/******************************************************************************* - * Code - ******************************************************************************/ -static void BOARD_InitModuleClock(void) -{ - const clock_enet_pll_config_t config = {true, false, 1}; - CLOCK_InitEnetPll(&config); -} - -void kinetis_init_eth_hardware(void) -{ - gpio_pin_config_t gpio_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode}; - - CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */ - - IOMUXC_SetPinMux( - IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, /* GPIO_AD_B0_09 is configured as GPIO1_IO09 */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_AD_B0_10_GPIO1_IO10, /* GPIO_AD_B0_10 is configured as GPIO1_IO10 */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_B1_04_ENET_RX_DATA00, /* GPIO_B1_04 is configured as ENET_RX_DATA00 */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_B1_05_ENET_RX_DATA01, /* GPIO_B1_05 is configured as ENET_RX_DATA01 */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_B1_06_ENET_RX_EN, /* GPIO_B1_06 is configured as ENET_RX_EN */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_B1_07_ENET_TX_DATA00, /* GPIO_B1_07 is configured as ENET_TX_DATA00 */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_B1_08_ENET_TX_DATA01, /* GPIO_B1_08 is configured as ENET_TX_DATA01 */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_B1_09_ENET_TX_EN, /* GPIO_B1_09 is configured as ENET_TX_EN */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_B1_10_ENET_REF_CLK, /* GPIO_B1_10 is configured as ENET_REF_CLK */ - 1U); /* Software Input On Field: Force input path of pad GPIO_B1_10 */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_B1_11_ENET_RX_ER, /* GPIO_B1_11 is configured as ENET_RX_ER */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_EMC_40_ENET_MDC, /* GPIO_EMC_40 is configured as ENET_MDC */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_EMC_41_ENET_MDIO, /* GPIO_EMC_41 is configured as ENET_MDIO */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, /* GPIO_AD_B0_09 PAD functional properties : */ - 0xB0A9u); /* Slew Rate Field: Fast Slew Rate - Drive Strength Field: R0/5 - Speed Field: medium(100MHz) - Open Drain Enable Field: Open Drain Disabled - Pull / Keep Enable Field: Pull/Keeper Enabled - Pull / Keep Select Field: Pull - Pull Up / Down Config. Field: 100K Ohm Pull Up - Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_AD_B0_10_GPIO1_IO10, /* GPIO_AD_B0_10 PAD functional properties : */ - 0xB0A9u); /* Slew Rate Field: Fast Slew Rate - Drive Strength Field: R0/5 - Speed Field: medium(100MHz) - Open Drain Enable Field: Open Drain Disabled - Pull / Keep Enable Field: Pull/Keeper Enabled - Pull / Keep Select Field: Pull - Pull Up / Down Config. Field: 100K Ohm Pull Up - Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_B1_04_ENET_RX_DATA00, /* GPIO_B1_04 PAD functional properties : */ - 0xB0E9u); /* Slew Rate Field: Fast Slew Rate - Drive Strength Field: R0/5 - Speed Field: max(200MHz) - Open Drain Enable Field: Open Drain Disabled - Pull / Keep Enable Field: Pull/Keeper Enabled - Pull / Keep Select Field: Pull - Pull Up / Down Config. Field: 100K Ohm Pull Up - Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_B1_05_ENET_RX_DATA01, /* GPIO_B1_05 PAD functional properties : */ - 0xB0E9u); /* Slew Rate Field: Fast Slew Rate - Drive Strength Field: R0/5 - Speed Field: max(200MHz) - Open Drain Enable Field: Open Drain Disabled - Pull / Keep Enable Field: Pull/Keeper Enabled - Pull / Keep Select Field: Pull - Pull Up / Down Config. Field: 100K Ohm Pull Up - Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_B1_06_ENET_RX_EN, /* GPIO_B1_06 PAD functional properties : */ - 0xB0E9u); /* Slew Rate Field: Fast Slew Rate - Drive Strength Field: R0/5 - Speed Field: max(200MHz) - Open Drain Enable Field: Open Drain Disabled - Pull / Keep Enable Field: Pull/Keeper Enabled - Pull / Keep Select Field: Pull - Pull Up / Down Config. Field: 100K Ohm Pull Up - Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_B1_07_ENET_TX_DATA00, /* GPIO_B1_07 PAD functional properties : */ - 0xB0E9u); /* Slew Rate Field: Fast Slew Rate - Drive Strength Field: R0/5 - Speed Field: max(200MHz) - Open Drain Enable Field: Open Drain Disabled - Pull / Keep Enable Field: Pull/Keeper Enabled - Pull / Keep Select Field: Pull - Pull Up / Down Config. Field: 100K Ohm Pull Up - Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_B1_08_ENET_TX_DATA01, /* GPIO_B1_08 PAD functional properties : */ - 0xB0E9u); /* Slew Rate Field: Fast Slew Rate - Drive Strength Field: R0/5 - Speed Field: max(200MHz) - Open Drain Enable Field: Open Drain Disabled - Pull / Keep Enable Field: Pull/Keeper Enabled - Pull / Keep Select Field: Pull - Pull Up / Down Config. Field: 100K Ohm Pull Up - Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_B1_09_ENET_TX_EN, /* GPIO_B1_09 PAD functional properties : */ - 0xB0E9u); /* Slew Rate Field: Fast Slew Rate - Drive Strength Field: R0/5 - Speed Field: max(200MHz) - Open Drain Enable Field: Open Drain Disabled - Pull / Keep Enable Field: Pull/Keeper Enabled - Pull / Keep Select Field: Pull - Pull Up / Down Config. Field: 100K Ohm Pull Up - Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_B1_10_ENET_REF_CLK, /* GPIO_B1_10 PAD functional properties : */ - 0x31u); /* Slew Rate Field: Fast Slew Rate - Drive Strength Field: R0/6 - Speed Field: low(50MHz) - Open Drain Enable Field: Open Drain Disabled - Pull / Keep Enable Field: Pull/Keeper Disabled - Pull / Keep Select Field: Keeper - Pull Up / Down Config. Field: 100K Ohm Pull Down - Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_B1_11_ENET_RX_ER, /* GPIO_B1_11 PAD functional properties : */ - 0xB0E9u); /* Slew Rate Field: Fast Slew Rate - Drive Strength Field: R0/5 - Speed Field: max(200MHz) - Open Drain Enable Field: Open Drain Disabled - Pull / Keep Enable Field: Pull/Keeper Enabled - Pull / Keep Select Field: Pull - Pull Up / Down Config. Field: 100K Ohm Pull Up - Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_EMC_40_ENET_MDC, /* GPIO_EMC_40 PAD functional properties : */ - 0xB0E9u); /* Slew Rate Field: Fast Slew Rate - Drive Strength Field: R0/5 - Speed Field: max(200MHz) - Open Drain Enable Field: Open Drain Disabled - Pull / Keep Enable Field: Pull/Keeper Enabled - Pull / Keep Select Field: Pull - Pull Up / Down Config. Field: 100K Ohm Pull Up - Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_EMC_41_ENET_MDIO, /* GPIO_EMC_41 PAD functional properties : */ - 0xB829u); /* Slew Rate Field: Fast Slew Rate - Drive Strength Field: R0/5 - Speed Field: low(50MHz) - Open Drain Enable Field: Open Drain Enabled - Pull / Keep Enable Field: Pull/Keeper Enabled - Pull / Keep Select Field: Pull - Pull Up / Down Config. Field: 100K Ohm Pull Up - Hyst. Enable Field: Hysteresis Disabled */ - - - BOARD_InitModuleClock(); - - IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, true); - - GPIO_PinInit(GPIO1, 9, &gpio_config); - GPIO_PinInit(GPIO1, 10, &gpio_config); - /* pull up the ENET_INT before RESET. */ - GPIO_WritePinOutput(GPIO1, 10, 1); - GPIO_WritePinOutput(GPIO1, 9, 0); - wait_us(1 * 1000); - GPIO_WritePinOutput(GPIO1, 9, 1); -} - -/******************************************************************************* - * EOF - ******************************************************************************/ - - 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 0000000..3687e9b --- /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 0000000..02a05ea --- /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 0000000..17ac3a3 --- /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 0000000..509076c --- /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/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/fsl_phy.h b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/fsl_phy.h new file mode 100644 index 0000000..aa5d079 --- /dev/null +++ b/connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/fsl_phy.h @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _FSL_PHY_H_ +#define _FSL_PHY_H_ + +#include "fsl_enet.h" + +/*! + * @addtogroup phy_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief PHY driver version */ +#define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ + +/*! @brief Defines the PHY registers. */ +#define PHY_BASICCONTROL_REG 0x00U /*!< The PHY basic control register. */ +#define PHY_BASICSTATUS_REG 0x01U /*!< The PHY basic status register. */ +#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. */ + +/*! @brief Defines the mask flag in basic control register. */ +#define PHY_BCTL_DUPLEX_MASK 0x0100U /*!< The PHY duplex bit mask. */ +#define PHY_BCTL_RESTART_AUTONEG_MASK 0x0200U /*!< The PHY restart auto negotiation mask. */ +#define PHY_BCTL_AUTONEG_MASK 0x1000U /*!< The PHY auto negotiation bit mask. */ +#define PHY_BCTL_SPEED_MASK 0x2000U /*!< The PHY speed bit mask. */ +#define PHY_BCTL_LOOP_MASK 0x4000U /*!< The PHY loop bit mask. */ +#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 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. */ +#define PHY_BSTATUS_AUTONEGCOMP_MASK 0x0020U /*!< The PHY auto-negotiation complete mask. */ + +/*! @brief Defines the mask flag in PHY auto-negotiation advertise register. */ +#define PHY_100BaseT4_ABILITY_MASK 0x200U /*!< The PHY have the T4 ability. */ +#define PHY_100BASETX_FULLDUPLEX_MASK 0x100U /*!< The PHY has the 100M full duplex ability.*/ +#define PHY_100BASETX_HALFDUPLEX_MASK 0x080U /*!< The PHY has the 100M full duplex ability.*/ +#define PHY_10BASETX_FULLDUPLEX_MASK 0x040U /*!< The PHY has the 10M full duplex ability.*/ +#define PHY_10BASETX_HALFDUPLEX_MASK 0x020U /*!< The PHY has the 10M full duplex ability.*/ + +/*! @brief Defines the PHY status. */ +enum _phy_status +{ + kStatus_PHY_SMIVisitTimeout = MAKE_STATUS(kStatusGroup_PHY, 1), /*!< ENET PHY SMI visit timeout. */ + kStatus_PHY_AutoNegotiateFail = MAKE_STATUS(kStatusGroup_PHY, 2) /*!< ENET PHY AutoNegotiate Fail. */ +}; + +/*! @brief Defines the PHY link speed. This is align with the speed for ENET MAC. */ +typedef enum _phy_speed +{ + kPHY_Speed10M = 0U, /*!< ENET PHY 10M speed. */ + kPHY_Speed100M /*!< ENET PHY 100M speed. */ +} phy_speed_t; + +/*! @brief Defines the PHY link duplex. */ +typedef enum _phy_duplex +{ + kPHY_HalfDuplex = 0U, /*!< ENET PHY half duplex. */ + kPHY_FullDuplex /*!< ENET PHY full duplex. */ +} phy_duplex_t; + +/*! @brief Defines the PHY loopback mode. */ +typedef enum _phy_loop +{ + kPHY_LocalLoop = 0U, /*!< ENET PHY local loopback. */ + kPHY_RemoteLoop /*!< ENET PHY remote loopback. */ +} phy_loop_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name PHY Driver + * @{ + */ + +/*! + * @brief Initializes PHY. + * + * This function initialize the SMI interface and initialize PHY. + * The SMI is the MII management interface between PHY and MAC, which should be + * firstly initialized before any other operation for PHY. The PHY initialize with auto-negotiation. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param srcClock_Hz The module clock frequency - system clock for MII management interface - SMI. + * @retval kStatus_Success PHY initialize success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + * @retval kStatus_PHY_AutoNegotiateFail PHY auto negotiate fail + */ +status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz); + +/*! + * @brief PHY Write function. This function write data over the SMI to + * the specified PHY register. This function is called by all PHY interfaces. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @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_Write(ENET_Type *base, uint32_t phyAddr, 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 base ENET peripheral base address. + * @param phyAddr The PHY address. + * @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_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr); + +/*! + * @brief Enables/disables PHY loopback. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param mode The loopback mode to be enabled, please see "phy_loop_t". + * the two loopback mode should not be both set. when one loopback mode is set + * the other one 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_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, phy_speed_t speed, bool enable); + +/*! + * @brief Gets the PHY link status. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @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 get link status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +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. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param speed The address of PHY link speed. + * @param duplex The link duplex of PHY. + * @retval kStatus_Success PHY get link speed and duplex success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_PHY_H_ */ 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 0000000..d7666af --- /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 8fba334..57ca689 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 @@ /** \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 @@ 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 @@ 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 @@ ENET_SetCallback(&g_handle, &Kinetis_EMAC::ethernet_callback, this); ENET_ActiveRead(ENET); - + return true; } @@ -406,7 +412,7 @@ 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 @@ * 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); + PHY_STATE currState{}; + PHY_GetLinkStatus(ENET, BOARD_ENET_PHY_ADDR, &currState.link_up); - if (connection_status) { - crt_state.connected = STATE_LINK_UP; - } else { - crt_state.connected = STATE_LINK_DOWN; + 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); + + emac_link_state_cb(currState.link_up); + } + 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); } - 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); - - 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); - } - } - - // Compare with previous state - if (crt_state.connected != prev_state.connected && emac_link_state_cb) { - emac_link_state_cb(crt_state.connected); - } - - prev_state = crt_state; + prev_state = currState; } bool Kinetis_EMAC::power_up() @@ -505,9 +505,7 @@ 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 82b588b..df5f7a6 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 @@ 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 4b88b60..c496c95 100644 --- a/connectivity/netsocket/tests/TESTS/netsocket/udp/main.cpp +++ b/connectivity/netsocket/tests/TESTS/netsocket/udp/main.cpp @@ -64,6 +64,11 @@ 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 641cc7d..9eaa094 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 @@ { 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 a1776d8..7080c3d 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_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_EVK/fsl_phy.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/fsl_phy.c deleted file mode 100644 index 3b09963..0000000 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/fsl_phy.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2018 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_phy.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; - } - - /* Reset PHY. */ - result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK); - if (result == kStatus_Success) - { -#if defined(FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE) - uint32_t data = 0; - result = PHY_Read(base, phyAddr, PHY_CONTROL2_REG, &data); - if (result != kStatus_Success) - { - return result; - } - result = PHY_Write(base, phyAddr, PHY_CONTROL2_REG, (data | PHY_CTL2_REFCLK_SELECT_MASK)); - if (result != kStatus_Success) - { - return result; - } -#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, - (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; - } - } - } - } - - 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; - 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; - } - return PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, data); - } - else - { - /* First read the current status in control register. */ - result = PHY_Read(base, phyAddr, PHY_CONTROL2_REG, &data); - if (result == kStatus_Success) - { - return PHY_Write(base, phyAddr, PHY_CONTROL2_REG, (data | PHY_CTL2_REMOTELOOP_MASK)); - } - } - } - else - { - /* Disable the loop mode. */ - if (mode == kPHY_LocalLoop) - { - /* First read the current status in control register. */ - result = PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &data); - if (result == kStatus_Success) - { - data &= ~PHY_BCTL_LOOP_MASK; - return PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (data | PHY_BCTL_RESTART_AUTONEG_MASK)); - } - } - else - { - /* First read the current status in control one register. */ - result = PHY_Read(base, phyAddr, PHY_CONTROL2_REG, &data); - if (result == kStatus_Success) - { - return PHY_Write(base, phyAddr, PHY_CONTROL2_REG, (data & ~PHY_CTL2_REMOTELOOP_MASK)); - } - } - } - 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); - - status_t result = kStatus_Success; - uint32_t data, ctlReg; - - /* Read the control two register. */ - result = PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &ctlReg); - if (result == kStatus_Success) - { - data = ctlReg & PHY_CTL1_SPEEDUPLX_MASK; - if ((PHY_CTL1_10FULLDUPLEX_MASK == data) || (PHY_CTL1_100FULLDUPLEX_MASK == data)) - { - /* Full duplex. */ - *duplex = kPHY_FullDuplex; - } - else - { - /* Half duplex. */ - *duplex = kPHY_HalfDuplex; - } - - data = ctlReg & PHY_CTL1_SPEEDUPLX_MASK; - if ((PHY_CTL1_100HALFDUPLEX_MASK == data) || (PHY_CTL1_100FULLDUPLEX_MASK == data)) - { - /* 100M speed. */ - *speed = kPHY_Speed100M; - } - else - { /* 10M speed. */ - *speed = kPHY_Speed10M; - } - } - - return result; -} diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/fsl_phy.h b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/fsl_phy.h deleted file mode 100644 index d4342bd..0000000 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/fsl_phy.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#ifndef _FSL_PHY_H_ -#define _FSL_PHY_H_ - -#include "fsl_enet.h" - -/*! - * @addtogroup phy_driver - * @{ - */ - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/*! @brief PHY driver version */ -#define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ - -/*! @brief Defines the PHY registers. */ -#define PHY_BASICCONTROL_REG 0x00U /*!< The PHY basic control register. */ -#define PHY_BASICSTATUS_REG 0x01U /*!< The PHY basic status register. */ -#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. */ -#define PHY_BCTL_RESTART_AUTONEG_MASK 0x0200U /*!< The PHY restart auto negotiation mask. */ -#define PHY_BCTL_AUTONEG_MASK 0x1000U /*!< The PHY auto negotiation bit mask. */ -#define PHY_BCTL_SPEED_MASK 0x2000U /*!< The PHY speed bit mask. */ -#define PHY_BCTL_LOOP_MASK 0x4000U /*!< The PHY loop bit mask. */ -#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. */ -#define PHY_BSTATUS_AUTONEGCOMP_MASK 0x0020U /*!< The PHY auto-negotiation complete mask. */ - -/*! @brief Defines the mask flag in PHY auto-negotiation advertise register. */ -#define PHY_100BaseT4_ABILITY_MASK 0x200U /*!< The PHY have the T4 ability. */ -#define PHY_100BASETX_FULLDUPLEX_MASK 0x100U /*!< The PHY has the 100M full duplex ability.*/ -#define PHY_100BASETX_HALFDUPLEX_MASK 0x080U /*!< The PHY has the 100M full duplex ability.*/ -#define PHY_10BASETX_FULLDUPLEX_MASK 0x040U /*!< The PHY has the 10M full duplex ability.*/ -#define PHY_10BASETX_HALFDUPLEX_MASK 0x020U /*!< The PHY has the 10M full duplex ability.*/ - -/*! @brief Defines the PHY status. */ -enum _phy_status -{ - kStatus_PHY_SMIVisitTimeout = MAKE_STATUS(kStatusGroup_PHY, 1), /*!< ENET PHY SMI visit timeout. */ - kStatus_PHY_AutoNegotiateFail = MAKE_STATUS(kStatusGroup_PHY, 2) /*!< ENET PHY AutoNegotiate Fail. */ -}; - -/*! @brief Defines the PHY link speed. This is align with the speed for ENET MAC. */ -typedef enum _phy_speed -{ - kPHY_Speed10M = 0U, /*!< ENET PHY 10M speed. */ - kPHY_Speed100M /*!< ENET PHY 100M speed. */ -} phy_speed_t; - -/*! @brief Defines the PHY link duplex. */ -typedef enum _phy_duplex -{ - kPHY_HalfDuplex = 0U, /*!< ENET PHY half duplex. */ - kPHY_FullDuplex /*!< ENET PHY full duplex. */ -} phy_duplex_t; - -/*! @brief Defines the PHY loopback mode. */ -typedef enum _phy_loop -{ - kPHY_LocalLoop = 0U, /*!< ENET PHY local loopback. */ - kPHY_RemoteLoop /*!< ENET PHY remote loopback. */ -} phy_loop_t; - -/******************************************************************************* - * API - ******************************************************************************/ - -#if defined(__cplusplus) -extern "C" { -#endif - -/*! - * @name PHY Driver - * @{ - */ - -/*! - * @brief Initializes PHY. - * - * This function initialize the SMI interface and initialize PHY. - * The SMI is the MII management interface between PHY and MAC, which should be - * firstly initialized before any other operation for PHY. The PHY initialize with auto-negotiation. - * - * @param base ENET peripheral base address. - * @param phyAddr The PHY address. - * @param srcClock_Hz The module clock frequency - system clock for MII management interface - SMI. - * @retval kStatus_Success PHY initialize success - * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out - * @retval kStatus_PHY_AutoNegotiateFail PHY auto negotiate fail - */ -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. - * - * @param base ENET peripheral base address. - * @param phyAddr The PHY address. - * @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_Write(ENET_Type *base, uint32_t phyAddr, 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 base ENET peripheral base address. - * @param phyAddr The PHY address. - * @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_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr); - -/*! - * @brief Enables/disables PHY loopback. - * - * @param base ENET peripheral base address. - * @param phyAddr The PHY address. - * @param mode The loopback mode to be enabled, please see "phy_loop_t". - * the two loopback mode should not be both set. when one loopback mode is set - * the other one 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_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, phy_speed_t speed, bool enable); - -/*! - * @brief Gets the PHY link status. - * - * @param base ENET peripheral base address. - * @param phyAddr The PHY address. - * @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 get link status success - * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out - */ -status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status); - -/*! - * @brief Gets the PHY link speed and duplex. - * - * @param base ENET peripheral base address. - * @param phyAddr The PHY address. - * @param speed The address of PHY link speed. - * @param duplex The link duplex of PHY. - * @retval kStatus_Success PHY get link speed and duplex success - * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out - */ -status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex); - -/* @} */ - -#if defined(__cplusplus) -} -#endif - -/*! @}*/ - -#endif /* _FSL_PHY_H_ */ 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 7d38d5d..367f335 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 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 c7c9d52..dd323c6 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 0000000..19acfeb --- /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 4dd30f8..7bf7ace 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 b5d2dee..aaef2e4 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 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 46a470b..aa15ad9 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 @@ /* 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 @@ /* 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 @@ /* 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 @@ #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 @@ /* 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 ee93440..89313c3 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 @@ 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 ec1e638..ffb00f5 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 @@ /*! @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 @@ 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 9bf4c59..e702073 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } /* 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 @@ } /* 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 @@ 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 @@ } } - 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 @@ #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 @@ } } - 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 5f9e66a..cc4841e 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 @@ } 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 @@ mac[3] = MAC[1]; mac[4] = MAC[2] >> 8; mac[5] = MAC[2]; - } else { - return 0; + + return 1; } - 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; + } +#endif + + return 0; } void mbed_default_mac_address(char *mac) { diff --git a/targets/targets.json b/targets/targets.json index 515709b..0617dfd 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 47915aa..7f8dfb5 100644 --- a/tools/cmake/app.cmake +++ b/tools/cmake/app.cmake @@ -82,7 +82,4 @@ 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 5b20808..7e70b50 100644 --- a/tools/cmake/mbed_generate_configuration.cmake +++ b/tools/cmake/mbed_generate_configuration.cmake @@ -97,6 +97,7 @@ -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 c095772..ab5022b 100644 --- a/tools/cmake/mbed_ide_debug_cfg_generator.cmake +++ b/tools/cmake/mbed_ide_debug_cfg_generator.cmake @@ -34,12 +34,12 @@ 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 @@ # ------------------------------------------------------------- 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 @@ # 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 "