Skip to content

Commit af6d50a

Browse files
author
Jamie Smith
authored
Teensy 4.1 port with Ethernet support (ARMmbed#144)
* Start porting to Teensy 4.1, also fix some compiler warnings in FSL HAL * Add hardware init for Teensy, refactor phy drivers, rework IMX EMAC autonegotiate code * Revert some testing changes * Fix incorrect phy address used outside of low_level_init_successful() * Ethernet operational! * Turn off DEBUG_IMX_EMAC * Style fixes * Style again * Bugfix: mbed_lib.json files in project source dir were not getting picked up * Bugfix: CLion debug configurations not generated properly due to variables going out of scope * Support Teensy OTP MAC address
1 parent bf5be9f commit af6d50a

File tree

31 files changed

+993
-244
lines changed

31 files changed

+993
-244
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ if(NOT MBED_IS_NATIVE_BUILD)
218218
# Load upload method if one is set up
219219
include(UploadMethodManager)
220220

221+
# Load debug config generator for IDEs
222+
include(mbed_ide_debug_cfg_generator)
221223
endif()
222224

223225
if(MBED_IS_NATIVE_BUILD)

connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
# SPDX-License-Identifier: Apache-2.0
33

44
if("MIMXRT1050_EVK" IN_LIST MBED_TARGET_LABELS OR "MIMXRT1060_EVK" IN_LIST MBED_TARGET_LABELS)
5-
add_subdirectory(TARGET_MIMXRT10x0_EVK)
5+
add_subdirectory(TARGET_MIMXRT105x_EVK)
6+
endif()
7+
if("TEENSY_41" IN_LIST MBED_TARGET_LABELS)
8+
add_subdirectory(TARGET_TEENSY_41)
69
endif()
710

811
target_include_directories(mbed-emac
@@ -13,4 +16,5 @@ target_include_directories(mbed-emac
1316
target_sources(mbed-emac
1417
PRIVATE
1518
imx_emac.cpp
19+
fsl_phy_common.c
1620
)

connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT10x0_EVK/CMakeLists.txt renamed to connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
target_sources(mbed-emac
55
PRIVATE
66
hardware_init.c
7+
fsl_phy_ksz8081rnb.c
78
)

targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/fsl_phy.c renamed to connectivity/drivers/emac/TARGET_NXP_EMAC/TARGET_IMX/TARGET_MIMXRT105x_EVK/fsl_phy_ksz8081rnb.c

Lines changed: 5 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
*/
88

99
#include "fsl_phy.h"
10+
#include "ksz8081rnb_regs.h"
11+
1012
/*******************************************************************************
1113
* Definitions
1214
******************************************************************************/
@@ -82,123 +84,17 @@ status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz)
8284
}
8385
#endif /* FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE */
8486
}
85-
return result;
86-
}
87-
88-
status_t PHY_AutoNegotiation(ENET_Type *base, uint32_t phyAddr)
89-
{
90-
status_t result = kStatus_Success;
91-
uint32_t bssReg;
92-
uint32_t counter = PHY_TIMEOUT_COUNT;
93-
uint32_t timeDelay;
94-
uint32_t ctlReg = 0;
9587

96-
/* Set the negotiation. */
97-
result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
88+
// Enable autonegotiation, allow negotiating for all ethernet types
89+
PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
9890
(PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
9991
PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U));
100-
if (result == kStatus_Success)
101-
{
102-
result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG,
103-
(PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
104-
if (result == kStatus_Success)
105-
{
106-
/* Check auto negotiation complete. */
107-
while (counter--)
108-
{
109-
result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg);
110-
if (result == kStatus_Success)
111-
{
112-
PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &ctlReg);
113-
if (((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0) && (ctlReg & PHY_LINK_READY_MASK))
114-
{
115-
/* Wait a moment for Phy status stable. */
116-
for (timeDelay = 0; timeDelay < PHY_TIMEOUT_COUNT; timeDelay++)
117-
{
118-
__ASM("nop");
119-
}
120-
break;
121-
}
122-
}
12392

124-
if (!counter)
125-
{
126-
return kStatus_PHY_AutoNegotiateFail;
127-
}
128-
}
129-
}
130-
}
93+
PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (PHY_BCTL_AUTONEG_MASK));
13194

13295
return result;
13396
}
13497

135-
status_t PHY_Write(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data)
136-
{
137-
uint32_t counter;
138-
139-
/* Clear the SMI interrupt event. */
140-
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
141-
142-
/* Starts a SMI write command. */
143-
ENET_StartSMIWrite(base, phyAddr, phyReg, kENET_MiiWriteValidFrame, data);
144-
145-
/* Wait for SMI complete. */
146-
for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--)
147-
{
148-
if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)
149-
{
150-
break;
151-
}
152-
}
153-
154-
/* Check for timeout. */
155-
if (!counter)
156-
{
157-
return kStatus_PHY_SMIVisitTimeout;
158-
}
159-
160-
/* Clear MII interrupt event. */
161-
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
162-
163-
return kStatus_Success;
164-
}
165-
166-
status_t PHY_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr)
167-
{
168-
assert(dataPtr);
169-
170-
uint32_t counter;
171-
172-
/* Clear the MII interrupt event. */
173-
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
174-
175-
/* Starts a SMI read command operation. */
176-
ENET_StartSMIRead(base, phyAddr, phyReg, kENET_MiiReadValidFrame);
177-
178-
/* Wait for MII complete. */
179-
for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--)
180-
{
181-
if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)
182-
{
183-
break;
184-
}
185-
}
186-
187-
/* Check for timeout. */
188-
if (!counter)
189-
{
190-
return kStatus_PHY_SMIVisitTimeout;
191-
}
192-
193-
/* Get data from MII register. */
194-
*dataPtr = ENET_ReadSMIData(base);
195-
196-
/* Clear MII interrupt event. */
197-
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
198-
199-
return kStatus_Success;
200-
}
201-
20298
status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, phy_speed_t speed, bool enable)
20399
{
204100
status_t result;
@@ -255,31 +151,6 @@ status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode,
255151
return result;
256152
}
257153

258-
status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status)
259-
{
260-
assert(status);
261-
262-
status_t result = kStatus_Success;
263-
uint32_t data;
264-
265-
/* Read the basic status register. */
266-
result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &data);
267-
if (result == kStatus_Success)
268-
{
269-
if (!(PHY_BSTATUS_LINKSTATUS_MASK & data))
270-
{
271-
/* link down. */
272-
*status = false;
273-
}
274-
else
275-
{
276-
/* link up. */
277-
*status = true;
278-
}
279-
}
280-
return result;
281-
}
282-
283154
status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex)
284155
{
285156
assert(duplex);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) 2015, Freescale Semiconductor, Inc.
3+
* Copyright 2016-2017 NXP
4+
* All rights reserved.
5+
*
6+
* SPDX-License-Identifier: BSD-3-Clause
7+
*/
8+
#ifndef _KSZ8081RNB_REGS_H_
9+
#define _KSZ8081RNB_REGS_H_
10+
11+
/*! @brief Defines the KSZ8081-specific PHY registers. */
12+
#define PHY_CONTROL1_REG 0x1EU /*!< The PHY control one register. */
13+
#define PHY_CONTROL2_REG 0x1FU /*!< The PHY control two register. */
14+
15+
#define PHY_CONTROL_ID1 0x22U /*!< The PHY ID1*/
16+
17+
/*!@brief Defines the mask flag of operation mode in control two register*/
18+
#define PHY_CTL2_REMOTELOOP_MASK 0x0004U /*!< The PHY remote loopback mask. */
19+
#define PHY_CTL2_REFCLK_SELECT_MASK 0x0080U /*!< The PHY RMII reference clock select. */
20+
#define PHY_CTL1_10HALFDUPLEX_MASK 0x0001U /*!< The PHY 10M half duplex mask. */
21+
#define PHY_CTL1_100HALFDUPLEX_MASK 0x0002U /*!< The PHY 100M half duplex mask. */
22+
#define PHY_CTL1_10FULLDUPLEX_MASK 0x0005U /*!< The PHY 10M full duplex mask. */
23+
#define PHY_CTL1_100FULLDUPLEX_MASK 0x0006U /*!< The PHY 100M full duplex mask. */
24+
#define PHY_CTL1_SPEEDUPLX_MASK 0x0007U /*!< The PHY speed and duplex mask. */
25+
#define PHY_CTL1_ENERGYDETECT_MASK 0x10U /*!< The PHY signal present on rx differential pair. */
26+
#define PHY_CTL1_LINKUP_MASK 0x100U /*!< The PHY link up. */
27+
#define PHY_LINK_READY_MASK (PHY_CTL1_ENERGYDETECT_MASK | PHY_CTL1_LINKUP_MASK)
28+
29+
#endif
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2020 ARM Limited. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
target_sources(mbed-emac
5+
PRIVATE
6+
hardware_init.cpp
7+
fsl_phy_dp83825.c
8+
)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) 2015, Freescale Semiconductor, Inc.
3+
* Copyright 2016-2017 NXP
4+
* All rights reserved.
5+
*
6+
* SPDX-License-Identifier: BSD-3-Clause
7+
*/
8+
#ifndef _DP83825_REGS_H_
9+
#define _DP83825_REGS_H_
10+
11+
/*! @brief Defines the DP83825-specific PHY registers. */
12+
#define PHY_PHYSTS_REG 0x10 ///< Phy Status Reg
13+
#define PHY_BISCR_REG 0x16 ///< Built-In Self Test Control Register
14+
#define PHY_RCSR_REG 0x17 ///< Receive Clock Select Register
15+
#define PHY_LEDCR_REG 0x18 ///< LED Control Register
16+
17+
#define PHY_CONTROL_ID1 0x2000U /*!< The PHY ID1*/
18+
19+
/*!@brief Defines the mask flag of operation mode in control two register*/
20+
#define PHY_CTL2_REMOTELOOP_MASK 0x0004U /*!< The PHY remote loopback mask. */
21+
#define PHY_CTL2_REFCLK_SELECT_MASK 0x0080U /*!< The PHY RMII reference clock select. */
22+
#define PHY_CTL1_10HALFDUPLEX_MASK 0x0001U /*!< The PHY 10M half duplex mask. */
23+
#define PHY_CTL1_100HALFDUPLEX_MASK 0x0002U /*!< The PHY 100M half duplex mask. */
24+
#define PHY_CTL1_10FULLDUPLEX_MASK 0x0005U /*!< The PHY 10M full duplex mask. */
25+
#define PHY_CTL1_100FULLDUPLEX_MASK 0x0006U /*!< The PHY 100M full duplex mask. */
26+
#define PHY_CTL1_SPEEDUPLX_MASK 0x0007U /*!< The PHY speed and duplex mask. */
27+
#define PHY_CTL1_ENERGYDETECT_MASK 0x10U /*!< The PHY signal present on rx differential pair. */
28+
#define PHY_CTL1_LINKUP_MASK 0x100U /*!< The PHY link up. */
29+
#define PHY_LINK_READY_MASK (PHY_CTL1_ENERGYDETECT_MASK | PHY_CTL1_LINKUP_MASK)
30+
31+
// Bits for PHYSTS register
32+
#define PHY_PHYSTS_DUPLEX_Msk (1 << 2)
33+
#define PHY_PHYSTS_SPEED_Msk (1 << 1)
34+
35+
// Bits for BISCR register
36+
#define PHY_BISCR_LOOPBACK_Msk (0b11111)
37+
#define PHY_BISCR_LOOPBACK_Pos 0
38+
#define PHY_BISCR_LOOPBACK_DIGITAL_LOOPBACK_10M_Val 0x1
39+
#define PHY_BISCR_LOOPBACK_DIGITAL_LOOPBACK_100M_Val 0x4
40+
#define PHY_BISCR_LOOPBACK_ANALOG_LOOPBACK_Val 0x8
41+
42+
// Bits for RCSR register
43+
#define PHY_RCSR_RX_ELASTICITY_Pos 0
44+
#define PHY_RCSR_RX_ELASTICITY_Msk 0b11
45+
#define PHY_RCSR_RMII_CLK_SEL_Msk (1 << 7)
46+
47+
// Bits for LEDCR register
48+
#define PHY_LEDCR_POLARITY_Msk (1 << 7)
49+
#define PHY_LEDCR_BLINK_RATE_Msk (0b11 << 9)
50+
#define PHY_LEDCR_BLINK_RATE_Pos 9
51+
52+
53+
#endif

0 commit comments

Comments
 (0)