mirror of https://github.com/ARMmbed/mbed-os.git
Teensy 4.1 port with Ethernet support (#144)
* Start porting to Teensy 4.1, also fix some compiler warnings in FSL HAL * Add hardware init for Teensy, refactor phy drivers, rework IMX EMAC autonegotiate code * Revert some testing changes * Fix incorrect phy address used outside of low_level_init_successful() * Ethernet operational! * Turn off DEBUG_IMX_EMAC * Style fixes * Style again * Bugfix: mbed_lib.json files in project source dir were not getting picked up * Bugfix: CLion debug configurations not generated properly due to variables going out of scope * Support Teensy OTP MAC addresspull/15437/head
parent
bf5be9f630
commit
af6d50aefe
|
|
@ -218,6 +218,8 @@ if(NOT MBED_IS_NATIVE_BUILD)
|
|||
# Load upload method if one is set up
|
||||
include(UploadMethodManager)
|
||||
|
||||
# Load debug config generator for IDEs
|
||||
include(mbed_ide_debug_cfg_generator)
|
||||
endif()
|
||||
|
||||
if(MBED_IS_NATIVE_BUILD)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
if("MIMXRT1050_EVK" IN_LIST MBED_TARGET_LABELS OR "MIMXRT1060_EVK" IN_LIST MBED_TARGET_LABELS)
|
||||
add_subdirectory(TARGET_MIMXRT10x0_EVK)
|
||||
add_subdirectory(TARGET_MIMXRT105x_EVK)
|
||||
endif()
|
||||
if("TEENSY_41" IN_LIST MBED_TARGET_LABELS)
|
||||
add_subdirectory(TARGET_TEENSY_41)
|
||||
endif()
|
||||
|
||||
target_include_directories(mbed-emac
|
||||
|
|
@ -13,4 +16,5 @@ target_include_directories(mbed-emac
|
|||
target_sources(mbed-emac
|
||||
PRIVATE
|
||||
imx_emac.cpp
|
||||
fsl_phy_common.c
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4,4 +4,5 @@
|
|||
target_sources(mbed-emac
|
||||
PRIVATE
|
||||
hardware_init.c
|
||||
fsl_phy_ksz8081rnb.c
|
||||
)
|
||||
|
|
@ -7,6 +7,8 @@
|
|||
*/
|
||||
|
||||
#include "fsl_phy.h"
|
||||
#include "ksz8081rnb_regs.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
|
@ -82,123 +84,17 @@ status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz)
|
|||
}
|
||||
#endif /* FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE */
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t PHY_AutoNegotiation(ENET_Type *base, uint32_t phyAddr)
|
||||
{
|
||||
status_t result = kStatus_Success;
|
||||
uint32_t bssReg;
|
||||
uint32_t counter = PHY_TIMEOUT_COUNT;
|
||||
uint32_t timeDelay;
|
||||
uint32_t ctlReg = 0;
|
||||
|
||||
/* Set the negotiation. */
|
||||
result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
|
||||
// Enable autonegotiation, allow negotiating for all ethernet types
|
||||
PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
|
||||
(PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
|
||||
PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U));
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG,
|
||||
(PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
/* Check auto negotiation complete. */
|
||||
while (counter--)
|
||||
{
|
||||
result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg);
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &ctlReg);
|
||||
if (((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0) && (ctlReg & PHY_LINK_READY_MASK))
|
||||
{
|
||||
/* Wait a moment for Phy status stable. */
|
||||
for (timeDelay = 0; timeDelay < PHY_TIMEOUT_COUNT; timeDelay++)
|
||||
{
|
||||
__ASM("nop");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!counter)
|
||||
{
|
||||
return kStatus_PHY_AutoNegotiateFail;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (PHY_BCTL_AUTONEG_MASK));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t PHY_Write(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data)
|
||||
{
|
||||
uint32_t counter;
|
||||
|
||||
/* Clear the SMI interrupt event. */
|
||||
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
|
||||
|
||||
/* Starts a SMI write command. */
|
||||
ENET_StartSMIWrite(base, phyAddr, phyReg, kENET_MiiWriteValidFrame, data);
|
||||
|
||||
/* Wait for SMI complete. */
|
||||
for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--)
|
||||
{
|
||||
if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for timeout. */
|
||||
if (!counter)
|
||||
{
|
||||
return kStatus_PHY_SMIVisitTimeout;
|
||||
}
|
||||
|
||||
/* Clear MII interrupt event. */
|
||||
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t PHY_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr)
|
||||
{
|
||||
assert(dataPtr);
|
||||
|
||||
uint32_t counter;
|
||||
|
||||
/* Clear the MII interrupt event. */
|
||||
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
|
||||
|
||||
/* Starts a SMI read command operation. */
|
||||
ENET_StartSMIRead(base, phyAddr, phyReg, kENET_MiiReadValidFrame);
|
||||
|
||||
/* Wait for MII complete. */
|
||||
for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--)
|
||||
{
|
||||
if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for timeout. */
|
||||
if (!counter)
|
||||
{
|
||||
return kStatus_PHY_SMIVisitTimeout;
|
||||
}
|
||||
|
||||
/* Get data from MII register. */
|
||||
*dataPtr = ENET_ReadSMIData(base);
|
||||
|
||||
/* Clear MII interrupt event. */
|
||||
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, phy_speed_t speed, bool enable)
|
||||
{
|
||||
status_t result;
|
||||
|
|
@ -255,31 +151,6 @@ status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode,
|
|||
return result;
|
||||
}
|
||||
|
||||
status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status)
|
||||
{
|
||||
assert(status);
|
||||
|
||||
status_t result = kStatus_Success;
|
||||
uint32_t data;
|
||||
|
||||
/* Read the basic status register. */
|
||||
result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &data);
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
if (!(PHY_BSTATUS_LINKSTATUS_MASK & data))
|
||||
{
|
||||
/* link down. */
|
||||
*status = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* link up. */
|
||||
*status = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex)
|
||||
{
|
||||
assert(duplex);
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
)
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
|
|
@ -28,10 +28,6 @@
|
|||
#define PHY_ID1_REG 0x02U /*!< The PHY ID one register. */
|
||||
#define PHY_ID2_REG 0x03U /*!< The PHY ID two register. */
|
||||
#define PHY_AUTONEG_ADVERTISE_REG 0x04U /*!< The PHY auto-negotiate advertise register. */
|
||||
#define PHY_CONTROL1_REG 0x1EU /*!< The PHY control one register. */
|
||||
#define PHY_CONTROL2_REG 0x1FU /*!< The PHY control two register. */
|
||||
|
||||
#define PHY_CONTROL_ID1 0x22U /*!< The PHY ID1*/
|
||||
|
||||
/*! @brief Defines the mask flag in basic control register. */
|
||||
#define PHY_BCTL_DUPLEX_MASK 0x0100U /*!< The PHY duplex bit mask. */
|
||||
|
|
@ -42,18 +38,6 @@
|
|||
#define PHY_BCTL_RESET_MASK 0x8000U /*!< The PHY reset bit mask. */
|
||||
#define PHY_BCTL_SPEED_100M_MASK 0x2000U /*!< The PHY 100M speed mask. */
|
||||
|
||||
/*!@brief Defines the mask flag of operation mode in control two register*/
|
||||
#define PHY_CTL2_REMOTELOOP_MASK 0x0004U /*!< The PHY remote loopback mask. */
|
||||
#define PHY_CTL2_REFCLK_SELECT_MASK 0x0080U /*!< The PHY RMII reference clock select. */
|
||||
#define PHY_CTL1_10HALFDUPLEX_MASK 0x0001U /*!< The PHY 10M half duplex mask. */
|
||||
#define PHY_CTL1_100HALFDUPLEX_MASK 0x0002U /*!< The PHY 100M half duplex mask. */
|
||||
#define PHY_CTL1_10FULLDUPLEX_MASK 0x0005U /*!< The PHY 10M full duplex mask. */
|
||||
#define PHY_CTL1_100FULLDUPLEX_MASK 0x0006U /*!< The PHY 100M full duplex mask. */
|
||||
#define PHY_CTL1_SPEEDUPLX_MASK 0x0007U /*!< The PHY speed and duplex mask. */
|
||||
#define PHY_CTL1_ENERGYDETECT_MASK 0x10U /*!< The PHY signal present on rx differential pair. */
|
||||
#define PHY_CTL1_LINKUP_MASK 0x100U /*!< The PHY link up. */
|
||||
#define PHY_LINK_READY_MASK (PHY_CTL1_ENERGYDETECT_MASK | PHY_CTL1_LINKUP_MASK)
|
||||
|
||||
/*! @brief Defines the mask flag in basic status register. */
|
||||
#define PHY_BSTATUS_LINKSTATUS_MASK 0x0004U /*!< The PHY link status mask. */
|
||||
#define PHY_BSTATUS_AUTONEGABLE_MASK 0x0008U /*!< The PHY auto-negotiation ability mask. */
|
||||
|
|
@ -123,16 +107,6 @@ extern "C" {
|
|||
*/
|
||||
status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz);
|
||||
|
||||
/*!
|
||||
* @brief Initiates auto negotiation.
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @param phyAddr The PHY address.
|
||||
* @retval kStatus_Success PHY auto negotiation success
|
||||
* @retval kStatus_PHY_AutoNegotiateFail PHY auto negotiate fail
|
||||
*/
|
||||
status_t PHY_AutoNegotiation(ENET_Type *base, uint32_t phyAddr);
|
||||
|
||||
/*!
|
||||
* @brief PHY Write function. This function write data over the SMI to
|
||||
* the specified PHY register. This function is called by all PHY interfaces.
|
||||
|
|
@ -187,6 +161,25 @@ status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode,
|
|||
*/
|
||||
status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status);
|
||||
|
||||
/*!
|
||||
* @brief Gets the PHY autonegotiation status
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @param phyAddr The PHY address.
|
||||
* @param[out] status Whether autonegotiation is done.
|
||||
* @return Error code or success
|
||||
*/
|
||||
status_t PHY_GetAutonegotiationStatus(ENET_Type *base, uint32_t phyAddr, bool *status);
|
||||
|
||||
/*!
|
||||
* @brief Starts the autonegotiation process. Should be called after the link comes up.
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @param phyAddr The PHY address.
|
||||
* @return Error code or success
|
||||
*/
|
||||
status_t PHY_StartAutonegotiation(ENET_Type *base, uint32_t phyAddr);
|
||||
|
||||
/*!
|
||||
* @brief Gets the PHY link speed and duplex.
|
||||
*
|
||||
|
|
@ -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 <stdio.h>
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cmsis_os.h"
|
||||
|
||||
|
|
@ -43,6 +44,7 @@
|
|||
#include "events/mbed_shared_queues.h"
|
||||
|
||||
#include "fsl_phy.h"
|
||||
#include "fsl_iomuxc.h"
|
||||
|
||||
#include "imx_emac_config.h"
|
||||
#include "imx_emac.h"
|
||||
|
|
@ -73,7 +75,10 @@ extern "C" void kinetis_init_eth_hardware(void);
|
|||
/** \brief Driver thread priority */
|
||||
#define THREAD_PRIORITY (osPriorityNormal)
|
||||
|
||||
#define PHY_TASK_PERIOD 200ms
|
||||
#define PHY_TASK_PERIOD 100ms
|
||||
|
||||
// Change to 1 to get debug printfs from the emac
|
||||
#define DEBUG_IMX_EMAC 0
|
||||
|
||||
Kinetis_EMAC::Kinetis_EMAC() : xTXDCountSem(ENET_TX_RING_LEN, ENET_TX_RING_LEN), hwaddr()
|
||||
{
|
||||
|
|
@ -190,7 +195,6 @@ bool Kinetis_EMAC::low_level_init_successful()
|
|||
uint32_t sysClock;
|
||||
phy_speed_t phy_speed;
|
||||
phy_duplex_t phy_duplex;
|
||||
uint32_t phyAddr = 0;
|
||||
enet_config_t config;
|
||||
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rx_desc_start_addr[ENET_RX_RING_LEN], ENET_BUFF_ALIGNMENT);
|
||||
|
|
@ -228,12 +232,14 @@ bool Kinetis_EMAC::low_level_init_successful()
|
|||
|
||||
ENET_GetDefaultConfig(&config);
|
||||
|
||||
if (PHY_Init(ENET, phyAddr, sysClock) != kStatus_Success) {
|
||||
if (PHY_Init(ENET, BOARD_ENET_PHY_ADDR, sysClock) != kStatus_Success)
|
||||
{
|
||||
printf("[IMX EMAC] Could not contact ethernet phy\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get link information from PHY */
|
||||
PHY_GetLinkSpeedDuplex(ENET, phyAddr, &phy_speed, &phy_duplex);
|
||||
PHY_GetLinkSpeedDuplex(ENET, BOARD_ENET_PHY_ADDR, &phy_speed, &phy_duplex);
|
||||
/* Change the MII speed and duplex for actual link status. */
|
||||
config.miiSpeed = (enet_mii_speed_t)phy_speed;
|
||||
config.miiDuplex = (enet_mii_duplex_t)phy_duplex;
|
||||
|
|
@ -246,7 +252,7 @@ bool Kinetis_EMAC::low_level_init_successful()
|
|||
|
||||
ENET_SetCallback(&g_handle, &Kinetis_EMAC::ethernet_callback, this);
|
||||
ENET_ActiveRead(ENET);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -406,7 +412,7 @@ bool Kinetis_EMAC::link_out(emac_mem_buf_t *buf)
|
|||
SCB_CleanDCache_by_Addr(static_cast<uint32_t *>(memory_manager->get_ptr(buf)), memory_manager->get_len(buf));
|
||||
|
||||
/* Check if a descriptor is available for the transfer (wait 10ms before dropping the buffer) */
|
||||
if (!xTXDCountSem.try_acquire_for(10)) {
|
||||
if (!xTXDCountSem.try_acquire_for(10ms)) {
|
||||
memory_manager->free(buf);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -448,44 +454,38 @@ bool Kinetis_EMAC::link_out(emac_mem_buf_t *buf)
|
|||
* PHY task: monitor link
|
||||
*******************************************************************************/
|
||||
|
||||
#define STATE_UNKNOWN (-1)
|
||||
#define STATE_LINK_DOWN (0)
|
||||
#define STATE_LINK_UP (1)
|
||||
|
||||
void Kinetis_EMAC::phy_task()
|
||||
{
|
||||
uint32_t phyAddr = BOARD_ENET_PHY_ADDR;
|
||||
|
||||
// Get current status
|
||||
PHY_STATE crt_state;
|
||||
bool connection_status;
|
||||
PHY_GetLinkStatus(ENET, phyAddr, &connection_status);
|
||||
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 @@ bool Kinetis_EMAC::power_up()
|
|||
rx_isr();
|
||||
|
||||
/* PHY monitoring task */
|
||||
prev_state.connected = STATE_LINK_DOWN;
|
||||
prev_state.speed = (phy_speed_t)STATE_UNKNOWN;
|
||||
prev_state.duplex = (phy_duplex_t)STATE_UNKNOWN;
|
||||
prev_state.link_up = false;
|
||||
|
||||
mbed::mbed_event_queue()->call(mbed::callback(this, &Kinetis_EMAC::phy_task));
|
||||
|
||||
|
|
|
|||
|
|
@ -171,9 +171,7 @@ private:
|
|||
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];
|
||||
|
|
|
|||
|
|
@ -64,6 +64,11 @@ static void _ifup()
|
|||
NetworkInterface *net = NetworkInterface::get_default_instance();
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(net, "No NetworkInterface configured");
|
||||
nsapi_error_t err = net->connect();
|
||||
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
printf("Failed to initialize networking. Error: %d", err);
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);
|
||||
SocketAddress address;
|
||||
net->get_ip_address(&address);
|
||||
|
|
|
|||
|
|
@ -243,6 +243,7 @@ int pwmout_read_pulsewidth_us(pwmout_t *obj) {
|
|||
{
|
||||
count = (base->SM[module].VAL5) & PWM_VAL5_VAL5_MASK;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ target_include_directories(mbed-mimxrt1050-evk
|
|||
|
||||
target_sources(mbed-mimxrt1050-evk
|
||||
INTERFACE
|
||||
fsl_phy.c
|
||||
fsl_flexspi_nor_boot.c
|
||||
|
||||
TARGET_1050_EVK/flash_api.c
|
||||
|
|
|
|||
|
|
@ -16,4 +16,5 @@ target_include_directories(mbed-teensy-40 INTERFACE TARGET_TEENSY_40)
|
|||
# Target for Teensy 4.1
|
||||
add_library(mbed-teensy-41 INTERFACE)
|
||||
target_link_libraries(mbed-teensy-41 INTERFACE
|
||||
mbed-teensy-4x)
|
||||
mbed-teensy-4x)
|
||||
target_include_directories(mbed-teensy-41 INTERFACE TARGET_TEENSY_41)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ static dcp_context_t s_dcpContextSwitchingBuffer;
|
|||
|
||||
static void dcp_reverse_and_copy(uint8_t *src, uint8_t *dest, size_t src_len)
|
||||
{
|
||||
for (int i = 0; i < src_len; i++)
|
||||
for (size_t i = 0; i < src_len; i++)
|
||||
{
|
||||
dest[i] = src[src_len - 1 - i];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -762,7 +762,7 @@ static void ENET_SetTxBufferDescriptors(enet_handle_t *handle,
|
|||
/* Check the input parameters. */
|
||||
for (ringNum = 0; ringNum < config->ringNum; ringNum++)
|
||||
{
|
||||
if (buffCfg->txBdStartAddrAlign > 0)
|
||||
if (buffCfg->txBdStartAddrAlign != 0)
|
||||
{
|
||||
volatile enet_tx_bd_struct_t *curBuffDescrip = buffCfg->txBdStartAddrAlign;
|
||||
txBuffSizeAlign = buffCfg->txBuffSizeAlign;
|
||||
|
|
@ -780,7 +780,7 @@ static void ENET_SetTxBufferDescriptors(enet_handle_t *handle,
|
|||
/* Sets the crc. */
|
||||
curBuffDescrip->control = ENET_BUFFDESCRIPTOR_TX_TRANMITCRC_MASK;
|
||||
/* Sets the last buffer descriptor with the wrap flag. */
|
||||
if (count == buffCfg->txBdNumber - 1)
|
||||
if (count == (uint32_t)(buffCfg->txBdNumber - 1))
|
||||
{
|
||||
curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_WRAP_MASK;
|
||||
}
|
||||
|
|
@ -811,7 +811,7 @@ static void ENET_SetRxBufferDescriptors(enet_handle_t *handle,
|
|||
/* Default single ring is supported. */
|
||||
uint8_t ringNum;
|
||||
uint32_t count;
|
||||
uint32_t rxBuffSizeAlign;
|
||||
uint32_t __attribute__((unused)) rxBuffSizeAlign;
|
||||
uint8_t *rxBuffer;
|
||||
const enet_buffer_config_t *buffCfg = bufferConfig;
|
||||
#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
|
||||
|
|
@ -835,7 +835,7 @@ static void ENET_SetRxBufferDescriptors(enet_handle_t *handle,
|
|||
#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
|
||||
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
|
||||
|
||||
if ((buffCfg->rxBdStartAddrAlign > 0) && (buffCfg->rxBufferAlign > 0))
|
||||
if ((buffCfg->rxBdStartAddrAlign != 0) && (buffCfg->rxBufferAlign != 0))
|
||||
{
|
||||
volatile enet_rx_bd_struct_t *curBuffDescrip = buffCfg->rxBdStartAddrAlign;
|
||||
rxBuffSizeAlign = buffCfg->rxBuffSizeAlign;
|
||||
|
|
@ -859,7 +859,7 @@ static void ENET_SetRxBufferDescriptors(enet_handle_t *handle,
|
|||
/* Initializes the buffer descriptors with empty bit. */
|
||||
curBuffDescrip->control = ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
|
||||
/* Sets the last buffer descriptor with the wrap flag. */
|
||||
if (count == buffCfg->rxBdNumber - 1)
|
||||
if (count == (uint32_t)(buffCfg->rxBdNumber - 1))
|
||||
{
|
||||
curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ status_t FLEXRAM_AllocateRam(flexram_allocate_ram_t *config)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (i < (dtcmBankNum + ocramBankNum + itcmBankNum))
|
||||
if (i < (uint32_t)(dtcmBankNum + ocramBankNum + itcmBankNum))
|
||||
{
|
||||
bankCfg |= ((uint32_t)kFLEXRAM_BankITCM) << (i * 2);
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -97,11 +97,6 @@ static FLEXSPI_Type *const s_flexspiBases[] = FLEXSPI_BASE_PTRS;
|
|||
/*! @brief Pointers to flexspi IRQ number for each instance. */
|
||||
static const IRQn_Type s_flexspiIrqs[] = FLEXSPI_IRQS;
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/* Clock name array */
|
||||
static const clock_ip_name_t s_flexspiClock[] = FLEXSPI_CLOCKS;
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
#if defined(FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ) && FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ
|
||||
/*! @brief Pointers to flexspi handles for each instance. */
|
||||
static flexspi_handle_t *s_flexspiHandle[ARRAY_SIZE(s_flexspiBases)];
|
||||
|
|
@ -245,9 +240,8 @@ void FLEXSPI_Init(FLEXSPI_Type *base, const flexspi_config_t *config)
|
|||
uint8_t i = 0;
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/* Enable the flexspi clock */
|
||||
//CLOCK_EnableClock(s_flexspiClock[FLEXSPI_GetInstance(base)]);
|
||||
/* Access the register directly to avoid warnings accessing non ran functions */
|
||||
/* Enable the flexspi clock. */
|
||||
/* Do this by accessing the register directly to avoid warnings accessing non-RAM functions */
|
||||
CCM->CCGR6 |= CCM_CCGR6_CG5_MASK;
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
|
|
|
|||
|
|
@ -1395,7 +1395,7 @@ void SAI_TxSetConfig(I2S_Type *base, sai_transceiver_t *config)
|
|||
config->channelMask = 1U << config->startChannel;
|
||||
}
|
||||
|
||||
for (i = 0U; i < FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
|
||||
for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
|
||||
{
|
||||
if (((uint32_t)1 << i) & config->channelMask)
|
||||
{
|
||||
|
|
@ -1408,7 +1408,7 @@ void SAI_TxSetConfig(I2S_Type *base, sai_transceiver_t *config)
|
|||
config->endChannel = i;
|
||||
}
|
||||
}
|
||||
assert(channelNums <= FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
|
||||
assert(channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
|
||||
config->channelNums = channelNums;
|
||||
#if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE)
|
||||
/* make sure combine mode disabled while multipe channel is used */
|
||||
|
|
@ -1518,7 +1518,7 @@ void SAI_RxSetConfig(I2S_Type *base, sai_transceiver_t *config)
|
|||
config->channelMask = 1U << config->startChannel;
|
||||
}
|
||||
|
||||
for (i = 0U; i < FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
|
||||
for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
|
||||
{
|
||||
if (((uint32_t)1 << i) & config->channelMask)
|
||||
{
|
||||
|
|
@ -1531,7 +1531,7 @@ void SAI_RxSetConfig(I2S_Type *base, sai_transceiver_t *config)
|
|||
config->endChannel = i;
|
||||
}
|
||||
}
|
||||
assert(channelNums <= FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
|
||||
assert(channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
|
||||
config->channelNums = channelNums;
|
||||
#if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE)
|
||||
/* make sure combine mode disabled while multipe channel is used */
|
||||
|
|
@ -1851,7 +1851,7 @@ void SAI_TxSetFormat(I2S_Type *base,
|
|||
}
|
||||
|
||||
/* if channel nums is not set, calculate it here according to channelMask*/
|
||||
for (i = 0U; i < FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
|
||||
for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
|
||||
{
|
||||
if (((uint32_t)1 << i) & format->channelMask)
|
||||
{
|
||||
|
|
@ -1990,7 +1990,7 @@ void SAI_RxSetFormat(I2S_Type *base,
|
|||
}
|
||||
|
||||
/* if channel nums is not set, calculate it here according to channelMask*/
|
||||
for (i = 0U; i < FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
|
||||
for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
|
||||
{
|
||||
if (((uint32_t)1 << i) & format->channelMask)
|
||||
{
|
||||
|
|
@ -2087,7 +2087,7 @@ void SAI_WriteMultiChannelBlocking(
|
|||
bytesPerWord = (size_t)((FSL_FEATURE_SAI_FIFO_COUNT - base->TCR1) * bytesPerWord);
|
||||
#endif
|
||||
|
||||
for (i = 0U; (i < FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); i++)
|
||||
for (i = 0U; (i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); i++)
|
||||
{
|
||||
if ((1U << i) & (channelMask))
|
||||
{
|
||||
|
|
@ -2096,7 +2096,7 @@ void SAI_WriteMultiChannelBlocking(
|
|||
}
|
||||
}
|
||||
|
||||
assert(channelNums <= FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
|
||||
assert(channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
|
||||
bytesPerWord *= channelNums;
|
||||
|
||||
while (j < size)
|
||||
|
|
@ -2140,7 +2140,7 @@ void SAI_ReadMultiChannelBlocking(
|
|||
#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
|
||||
bytesPerWord = (size_t)(base->RCR1 * bytesPerWord);
|
||||
#endif
|
||||
for (i = 0U; (i < FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); i++)
|
||||
for (i = 0U; (i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); i++)
|
||||
{
|
||||
if ((1U << i) & (channelMask))
|
||||
{
|
||||
|
|
@ -2149,7 +2149,7 @@ void SAI_ReadMultiChannelBlocking(
|
|||
}
|
||||
}
|
||||
|
||||
assert(channelNums <= FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
|
||||
assert(channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
|
||||
bytesPerWord *= channelNums;
|
||||
|
||||
while (j < size)
|
||||
|
|
|
|||
|
|
@ -289,6 +289,8 @@ void mbed_mac_address(char *mac) {
|
|||
}
|
||||
|
||||
uint8_t mbed_otp_mac_address(char *mac) {
|
||||
|
||||
#if TARGET_MIMXRT1050_EVK
|
||||
/* Check if a valid MAC address is programmed to the fuse bank */
|
||||
if ((OCOTP->MAC0 != 0) &&
|
||||
(OCOTP->MAC1 != 0) &&
|
||||
|
|
@ -308,10 +310,26 @@ uint8_t mbed_otp_mac_address(char *mac) {
|
|||
mac[3] = MAC[1];
|
||||
mac[4] = MAC[2] >> 8;
|
||||
mac[5] = MAC[2];
|
||||
} else {
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -82,7 +82,4 @@ if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/../../${EXPECTED_MBED_UPLOAD_CFG_FILE_PATH})
|
|||
else()
|
||||
message(STATUS "Mbed: Target does not have any upload method configuration. 'make flash-' commands will not be available unless configured by the upper-level project.")
|
||||
set(UPLOAD_METHOD_DEFAULT "NONE")
|
||||
endif()
|
||||
|
||||
# Load debug config generator for IDEs
|
||||
include(mbed_ide_debug_cfg_generator)
|
||||
endif()
|
||||
|
|
@ -97,6 +97,7 @@ if(MBED_NEED_TO_RECONFIGURE)
|
|||
-m "${MBED_TARGET}"
|
||||
--mbed-os-path ${CMAKE_CURRENT_LIST_DIR}/../..
|
||||
--output-dir ${CMAKE_CURRENT_BINARY_DIR}
|
||||
--program-path ${CMAKE_SOURCE_DIR}
|
||||
${APP_CONFIG_ARGUMENT}
|
||||
${CUSTOM_TARGET_ARGUMENT})
|
||||
|
||||
|
|
|
|||
|
|
@ -34,12 +34,12 @@ endif()
|
|||
|
||||
if(MBED_GENERATE_CLION_DEBUG_CFGS)
|
||||
|
||||
# Find CLion run config dir
|
||||
set(CLION_RUN_CONF_DIR ${CMAKE_SOURCE_DIR}/.idea/runConfigurations)
|
||||
file(MAKE_DIRECTORY ${CLION_RUN_CONF_DIR})
|
||||
|
||||
function(mbed_generate_ide_debug_configuration CMAKE_TARGET)
|
||||
|
||||
# Find CLion run config dir
|
||||
set(CLION_RUN_CONF_DIR ${CMAKE_SOURCE_DIR}/.idea/runConfigurations)
|
||||
file(MAKE_DIRECTORY ${CLION_RUN_CONF_DIR})
|
||||
|
||||
# Create name (combine target name, Mbed target, and build type to generate a unique string)
|
||||
set(CONFIG_NAME "GDB ${CMAKE_TARGET} ${MBED_TARGET} ${CMAKE_BUILD_TYPE}")
|
||||
set(RUN_CONF_PATH "${CLION_RUN_CONF_DIR}/${CONFIG_NAME}.xml")
|
||||
|
|
@ -95,8 +95,6 @@ if(MBED_GENERATE_CLION_DEBUG_CFGS)
|
|||
# -------------------------------------------------------------
|
||||
elseif(MBED_GENERATE_VS_CODE_DEBUG_CFGS)
|
||||
|
||||
set(VSCODE_LAUNCH_JSON_PATH ${CMAKE_SOURCE_DIR}/.vscode/launch.json)
|
||||
|
||||
# Start building up json file. Needs to be a global property so we can append to it from anywhere.
|
||||
# Note: Cannot use a cache variable for this because cache variables aren't allowed to contain newlines.
|
||||
set_property(GLOBAL PROPERTY VSCODE_LAUNCH_JSON_CONTENT
|
||||
|
|
@ -167,6 +165,7 @@ elseif(MBED_GENERATE_VS_CODE_DEBUG_CFGS)
|
|||
# Take all generated debug configurations and write them to launch.json.
|
||||
function(mbed_finalize_ide_debug_configurations)
|
||||
|
||||
set(VSCODE_LAUNCH_JSON_PATH ${CMAKE_SOURCE_DIR}/.vscode/launch.json)
|
||||
|
||||
# Add footer
|
||||
set_property(GLOBAL APPEND_STRING PROPERTY VSCODE_LAUNCH_JSON_CONTENT "
|
||||
|
|
|
|||
Loading…
Reference in New Issue