/* * Copyright 2020-2022 NXP * All rights reserved. * */ #include "S32K39.h" #include "Platform.h" #include "device.h" #include "Mcal.h" #include "Mcu.h" #include "Port.h" #include "OsIf.h" #include "Eth_43_GMAC.h" #include "Dio.h" #ifndef USING_OS_FREERTOS #include "Gpt.h" #endif #include "Gmac_Ip.h" #include "Gmac_Ip_Hw_Access.h" #include "Gmac_Ip_TrustedFunctions.h" #define ETHERNET_RMII // #define ETHERNET_MII #define ETHERNET_MASTER #define ETHERNET_AUTONOMOUS // Autonomous,Polarity correct(default) #define CFG_PHY_CTRL_IDX (0U) #define BIT(n) (1UL << (n)) /* PHY ID definitions (Section 7.1 CL22 register overview) */ #define TJA1103_PHY_ID1 0x001B // PHY Identifier 1 (Reg 2) #define TJA1103_PHY_ID2 0xB013 // PHY Identifier 2 (Reg 3) /* MMD30 - Device status register */ #define TJA1103_DEVICE_CONTROL (0x0040U) #define TJA1103_DEVICE_CONTROL_GLOBAL_CFG_EN BIT(14) #define TJA1103_DEVICE_CONTROL_SUPER_CFG_EN BIT(13) /* Shared - PHY control register */ #define TJA1103_PHY_CONTROL (0x8100U) #define TJA1103_PHY_CONTROL_CFG_EN BIT(14) /* Shared - PHY status register */ #define TJA1103_PHY_STATUS (0x8102U) #define TJA1103_PHY_STATUS_LINK_STAT BIT(2) #define TJA1103_PORT_CONTROL (0x8040U) #define PORT_CONTROL_CFG_EN BIT(14) #define TJA1103_PORT_INFRA_CONTROL (0xAC00U) #define PORT_INFRA_CONTROL_CFG_EN BIT(14) #define TJA1103_PHY_CONFIG (0x8108U) #define BMCR_RESET 0x8000 // Soft reset control bit #define BMSR_LINK_STATUS 0x0004 // Link status bit /* XMII_MODE */ #define MII_BASIC_CONFIG (0xAFC6U) #define MII_MODE 4U #define RMII_MODE 5U #define CL45_ACCESS_CONTROL 0x0D /* PHY address */ #define PHY_ADDRESS 27 // PHYAD is 27 /* MMD30 device address */ #define MMD30_DEVAD 30 // DEVAD corresponding to MMD30 /* MDIO Manageable Device addresses */ #define MDIO_MMD_PMAPMD 0x01U #define MDIO_MMD_PCS 0x03U #define MDIO_MMD_VENDOR_SPECIFIC1 0x1EU /* BASE-T1 PMA/PMD control register */ /* BASE-T1 PMA/PMD control register */ /** BASE-T1 master/slave configuration */ #define BASE_T1_PMA_CONTROL 0x0834U #define MDIO_PMA_PMD_BT1_CTRL_CFG_MST BIT(14) #define PMA_CONTROL1 0U /* PHY initialization function */ static void Eth_T_InitPhys(void) { uint16_t phy_reg_val0, phy_reg_val1; uint16_t phy_addr = PHY_ADDRESS; uint16_t PHY_ID_Found_flag = 0; /* 1. Enable MDIO */ Gmac_Ip_EnableMDIO(CFG_PHY_CTRL_IDX, FALSE, 48000000U); /* 2. PHY detection (Clause 22) */ Gmac_Ip_MDIORead(CFG_PHY_CTRL_IDX, phy_addr, 2U, &phy_reg_val0, 1U); Gmac_Ip_MDIORead(CFG_PHY_CTRL_IDX, phy_addr, 3U, &phy_reg_val1, 1U); if ((phy_reg_val0 == TJA1103_PHY_ID1) && (phy_reg_val1 == TJA1103_PHY_ID2)) { PHY_ID_Found_flag = 1; } else { // Error handling return; } /* 3. Reset PHY */ Gmac_Ip_MDIOWriteMMD(CFG_PHY_CTRL_IDX, phy_addr, MDIO_MMD_VENDOR_SPECIFIC1, TJA1103_DEVICE_CONTROL, BMCR_RESET, 1U); while (Gmac_Ip_MDIOReadMMD(CFG_PHY_CTRL_IDX, phy_addr, MDIO_MMD_VENDOR_SPECIFIC1, TJA1103_DEVICE_CONTROL, &phy_reg_val0, 1U) & BMCR_RESET) ; /* 4. Enable register configuration */ Gmac_Ip_MDIOWriteMMD(CFG_PHY_CTRL_IDX, phy_addr, MDIO_MMD_VENDOR_SPECIFIC1, TJA1103_DEVICE_CONTROL, TJA1103_DEVICE_CONTROL_GLOBAL_CFG_EN | TJA1103_DEVICE_CONTROL_SUPER_CFG_EN, 1U); Gmac_Ip_MDIOWriteMMD(CFG_PHY_CTRL_IDX, phy_addr, MDIO_MMD_VENDOR_SPECIFIC1, TJA1103_PORT_CONTROL, PORT_CONTROL_CFG_EN, 1U); Gmac_Ip_MDIOWriteMMD(CFG_PHY_CTRL_IDX, phy_addr, MDIO_MMD_VENDOR_SPECIFIC1, TJA1103_PHY_CONTROL, TJA1103_PHY_CONTROL_CFG_EN, 1U); Gmac_Ip_MDIOWriteMMD(CFG_PHY_CTRL_IDX, phy_addr, MDIO_MMD_VENDOR_SPECIFIC1, TJA1103_PORT_INFRA_CONTROL, PORT_INFRA_CONTROL_CFG_EN, 1U); /* 5. Configure Master/Slave */ Gmac_Ip_MDIOReadMMD(CFG_PHY_CTRL_IDX, phy_addr, MDIO_MMD_PMAPMD, BASE_T1_PMA_CONTROL, &phy_reg_val0, 1U); /* Change master/slave mode if need */ #ifdef ETHERNET_MASTER phy_reg_val0 |= MDIO_PMA_PMD_BT1_CTRL_CFG_MST; #else phy_reg_val0 &= ~MDIO_PMA_PMD_BT1_CTRL_CFG_MST; #endif Gmac_Ip_MDIOWriteMMD(CFG_PHY_CTRL_IDX, phy_addr, MDIO_MMD_PMAPMD, BASE_T1_PMA_CONTROL, phy_reg_val0, 1U); Gmac_Ip_MDIOReadMMD(CFG_PHY_CTRL_IDX, phy_addr, MDIO_MMD_PMAPMD, BASE_T1_PMA_CONTROL, &phy_reg_val0, 1U); /* 6. Configure XMII_mode: MII, RMII... (1U<<4)-'reverse' role mode enabled */ #ifdef ETHERNET_RMII phy_reg_val0 = RMII_MODE | (1U << 4); #else phy_reg_val0 = MII_MODE; #endif Gmac_Ip_MDIOWriteMMD(CFG_PHY_CTRL_IDX, phy_addr, MDIO_MMD_VENDOR_SPECIFIC1, MII_BASIC_CONFIG, phy_reg_val0, 1U); Gmac_Ip_MDIOReadMMD(CFG_PHY_CTRL_IDX, phy_addr, MDIO_MMD_VENDOR_SPECIFIC1, MII_BASIC_CONFIG, &phy_reg_val0, 1U); /* 7.a: POLARITY_CORRECT_DISABLE bit2 reset 0 no need to rewrite b: AUTO_OPERATION reset 0 needs to be set to 1 bit0 */ Gmac_Ip_MDIOReadMMD(CFG_PHY_CTRL_IDX, phy_addr, MDIO_MMD_VENDOR_SPECIFIC1, TJA1103_PHY_CONFIG, &phy_reg_val0, 1U); /* Autonomous,Polarity correct */ #ifdef ETHERNET_AUTONOMOUS phy_reg_val0 = 1U; #else phy_reg_val0 = 0U; #endif Gmac_Ip_MDIOWriteMMD(CFG_PHY_CTRL_IDX, phy_addr, MDIO_MMD_VENDOR_SPECIFIC1, TJA1103_PHY_CONFIG, phy_reg_val0, 1U); Gmac_Ip_MDIOReadMMD(CFG_PHY_CTRL_IDX, phy_addr, MDIO_MMD_VENDOR_SPECIFIC1, TJA1103_PHY_CONFIG, &phy_reg_val0, 1U); /* START_OPERATION */ /* 8. Wait for link establishment */ uint32_t timeout = 1000000U; do { Gmac_Ip_MDIOReadMMD(CFG_PHY_CTRL_IDX, phy_addr, MDIO_MMD_VENDOR_SPECIFIC1, TJA1103_PHY_STATUS, &phy_reg_val0, 1U); if (--timeout == 0U) { // 添加超时处理,例如记录日志 break; } } while ((phy_reg_val0 & BMSR_LINK_STATUS) == 0); /* 9. Disable register configuration and start device */ Gmac_Ip_MDIOWriteMMD(CFG_PHY_CTRL_IDX, phy_addr, MDIO_MMD_VENDOR_SPECIFIC1, TJA1103_DEVICE_CONTROL, 0x001U, 1U); /* Link establishment post-configuration */ if (phy_reg_val0 & BMSR_LINK_STATUS) { // Read SQI register (assuming address is MMD30:0x0010) // Enable PTP (MMD30:0x0011) } } void TestDelay(uint32 delay) { static volatile uint32 DelayTimer = 0; while (DelayTimer < delay) { DelayTimer++; } DelayTimer = 0; } void device_init(void) { /* Set RMII configuration for EMAC in DCM module */ IP_DCM_GPR->DCMRWF1 = (IP_DCM_GPR->DCMRWF1 & ~DCM_GPR_DCMRWF1_MAC_CONF_SEL_MASK) | DCM_GPR_DCMRWF1_MAC_CONF_SEL(2U); // 0->MII,2->RMII /* Initialize code */ /* Reset PHY */ Dio_WriteChannel(DioConf_DioChannel_ENET0_nRST, STD_LOW); TestDelay(500000); Dio_WriteChannel(DioConf_DioChannel_ENET0_nRST, STD_HIGH); /* Config PHY */ Eth_T_InitPhys(); /* Initialize and enable the GMAC module */ Eth_43_GMAC_Init(NULL_PTR); }