我們對(duì)g_ethercat_ssc_port0_ext_cfg這個(gè)全局變量深入追蹤,其成員變量 g_ether_PHY0,正好是一個(gè)PHY實(shí)例的詳細(xì)描述體。
/* Instance structure to use this module. */ const ether_PHY_instance_t g_ether_PHY0 = { .p_ctrl = &g_ether_PHY0_ctrl, .p_cfg = &g_ether_PHY0_cfg, .p_api = &g_ether_PHY_on_ether_PHY };
其中g(shù)_ether_PHY0_cfg是pyh實(shí)例的配置結(jié)構(gòu)體:
const ether_PHY_cfg_t g_ether_PHY0_cfg = { .channel = 0, .PHY_lsi_address = 0, .PHY_reset_wait_time = 0x00020000, .mii_bit_access_wait_time = 0, // Unused .flow_control = ETHER_PHY_FLOW_CONTROL_DISABLE, .mii_type = (ether_PHY_mii_type_t) 0, // Unused .p_context = NULL, .p_extend = &g_ether_PHY0_extend };
這里又通過p_extend 做了擴(kuò)展配置(其實(shí)可以合并在一起)如下所示:
const ether_PHY_extend_cfg_t g_ether_PHY0_extend = { .port_type = ETHER_PHY_PORT_TYPE_ETHER_CAT, .PHY_chip = (ether_PHY_chip_t) ETHER_PHY_CHIP_VSC8541, .mdio_type = ETHER_PHY_MDIO_GMAC, .bps = ETHER_PHY_SPEED_100, .duplex = ETHER_PHY_DUPLEX_FULL, .auto_negotiation = ETHER_PHY_AUTO_NEGOTIATION_ON, .PHY_reset_pin = BSP_IO_PORT_20_PIN_7, .PHY_reset_time = 15000, .p_selector_instance = (ether_selector_instance_t *)&g_ether_selector0, };
可以看到上面的擴(kuò)展配置當(dāng)中,PHY的具體硬件型號(hào)都已經(jīng)列出,如PHY_chip = (ether_PHY_chip_t) ETHER_PHY_CHIP_;
可以看到在示例代碼當(dāng)中已經(jīng)支持的PHY如下所示:
/** Identify PHY-LSI */ typedef enum e_ether_PHY_chip { ETHER_PHY_CHIP_VSC8541 = (1 << 0), ///< VSC8541 ? ?ETHER_PHY_CHIP_KSZ9131 = (1 << 1), ///< KSZ9131 ? ?ETHER_PHY_CHIP_KSZ9031 = (1 << 2), ///< KSZ9031 ? ?ETHER_PHY_CHIP_KSZ8081 = (1 << 3), ///< KSZ8081 ? ?ETHER_PHY_CHIP_KSZ8041 = (1 << 4) ?///< KSZ8041 } ether_PHY_chip_t;
這里具體看一下 g_ether_selector0 這個(gè) ether_selector_instance_t 類型的全局指針,指向 selector driver實(shí)例的成員變量:
typedef struct st_ether_selector_instance { ether_selector_ctrl_t * p_ctrl; ///< Pointer to the control structure for this instance ? ?ether_selector_cfg_t const * p_cfg; ?///< Pointer to the configuration structure for this instance ? ?ether_selector_api_t const * p_api; ?///< Pointer to the API structure for this instance } ether_selector_instance_t;
這又是一個(gè)類似的結(jié)構(gòu)體,通過三個(gè)指針來分別指向結(jié)構(gòu)本身,selector的具體配置,和配置selector過程中所需要用的的成員方法api.
看一下selector的具體配置信息:
typedef struct st_ether_selector_cfg { uint8_t port; ///< Port number ? ?ether_selector_PHYlink_polarity_t PHYlink; ///< PHY link signal polarity ? ?ether_selector_interface_t interface; ? ? ?///< Converter mode ? ?ether_selector_speed_t ? ? speed; ? ? ? ? ?///< Converter Speed ? ?ether_selector_duplex_t ? ?duplex; ? ? ? ? ///< Converter Duplex ? ?ether_selector_ref_clock_t ref_clock; ? ? ?///< Converter REF_CLK ? ?void const ? ? ? ? ? ? ? * p_extend; ? ? ? ///< Placeholder for user extension. } ether_selector_cfg_t;
可以看到selector 對(duì)應(yīng)的端口號(hào),PHY連接信號(hào)對(duì)應(yīng)的極性,接口模式,速率,全雙工,以及外部時(shí)鐘輸入。再看一下配置selector的過程中所需要用到的API函數(shù):
const ether_selector_api_t g_ether_selector_on_ether_selector = { .open = R_ETHER_SELECTOR_Open, .converterSet = R_ETHER_SELECTOR_ConverterSet, .close = R_ETHER_SELECTOR_Close, .versionGet = R_ETHER_SELECTOR_VersionGet };
其最主要的成員方法就是R_ETHER_SELECTOR_Open做了些什么:
先初始化ETHER_SELECTOR
/* One time initialization for all ETHER_SELECTOR instances. */ r_ether_selector_state_initialize(); /* Unlock write access protection for Ethernet subsystem registers */ r_ether_selector_reg_protection_disable(p_reg_ethss); /* Set the function of Ethernet ports. */ sw_mode = ETHER_SELECTOR_CFG_MODE; p_reg_ethss->MODCTRL_b.SW_MODE = sw_mode & ETHER_SELECTOR_MODCTRL_BIT_SWMODE_MASK; /* Set the MAC of all port for half-duplex. */ p_reg_ethss->SWDUPC_b.PHY_DUPLEX = 0; /* Set all Ethernet switch port to select not use 10Mbps. */ p_reg_ethss->SWCTRL_b.SET10 = 0;
根據(jù)端口號(hào)來選擇對(duì)應(yīng)控制寄存器
/* Set RGMII/RMII Converter configuration */ switch (port) { case 0: { p_reg_convctrl = (uint32_t *) &p_reg_ethss->CONVCTRL[0]; break; } case 1: { p_reg_convctrl = (uint32_t *) &p_reg_ethss->CONVCTRL[1]; break; } case 2: default: { p_reg_convctrl = (uint32_t *) &p_reg_ethss->CONVCTRL[2]; break; } }
根據(jù)指向selector的配置信息:
const ether_selector_cfg_t g_ether_selector0_cfg = { .port = 0, .PHYlink = ETHER_SELECTOR_PHYLINK_POLARITY_LOW, .interface = ETHER_SELECTOR_INTERFACE_RGMII, .speed = ETHER_SELECTOR_SPEED_100MBPS, .duplex = ETHER_SELECTOR_DUPLEX_FULL, .ref_clock = ETHER_SELECTOR_REF_CLOCK_INPUT, .p_extend = NULL, };
來對(duì)CONVCTRL[port_number]寄存器做相應(yīng)的配置
這里結(jié)合RZ/T2M的用戶手冊(cè),很容易理解其中的意思:
結(jié)合代碼來看,總體ETHER_SELECTOR 的驅(qū)動(dòng)的配置流程圖臺(tái)下所示:
在對(duì)ETHER_SELECTOR驅(qū)動(dòng)做完配置后,下面具體看一下對(duì)ETHER_PHY_CHIP這個(gè)PHY,代碼具體做了哪些操作:
首先是做初始化:
oid ether_PHY_targets_initialize_vsc8541 (ether_PHY_instance_ctrl_t * p_instance_ctrl) { /* Vendor Specific PHY Registers */ #define ETHER_PHY_REG_LED_MODE_SELECT (0x1D) #define ETHER_PHY_REG_LED_BEHAVIOR (0x1E) #define ETHER_PHY_REG_EXTEND_GPIO_PAGE (0x1F) ...
這個(gè)初始化函數(shù),并沒有對(duì)IEEE 標(biāo)準(zhǔn)規(guī)定的16個(gè)寄存器做讀寫操作,只對(duì)廠商自定義的寄存器做了配置。初始化完成之后,對(duì)是否打開自動(dòng)協(xié)商的功能對(duì)PHY進(jìn)行了讀寫:
這里可以看到對(duì)PHY芯生來說,需要配置的寄存器并不是很多,大多數(shù)情況下,把自動(dòng)協(xié)商寄存器配置好,就可以了。除此之后就是廠商自定義的寄存器的一些自定義的功能。這部分功能需要結(jié)合用戶手冊(cè)來理解和使用,大部分也是用來調(diào)試和指示的作用以及一些IEEE基本標(biāo)準(zhǔn)之外的特色功能,比如節(jié)能標(biāo)準(zhǔn)之類的。
對(duì)于用戶說來,搞清楚數(shù)據(jù)結(jié)構(gòu)之間的關(guān)聯(lián),剩下的就是驅(qū)動(dòng)代碼的執(zhí)行邏輯,考慮到執(zhí)行邏輯并不復(fù)雜,這里不展開來說。用戶可以參考錄屏材料進(jìn)一步深入了解。
其它
經(jīng)過驗(yàn)證的PHY芯片列表:
審核編輯:劉清
-
以太網(wǎng)
+關(guān)注
關(guān)注
40文章
5582瀏覽量
174767 -
寄存器
+關(guān)注
關(guān)注
31文章
5421瀏覽量
123306 -
PHY
+關(guān)注
關(guān)注
2文章
314瀏覽量
52483
原文標(biāo)題:工業(yè)以太網(wǎng)PHY驅(qū)動(dòng)適配參考文檔(完結(jié)篇)
文章出處:【微信號(hào):瑞薩MCU小百科,微信公眾號(hào):瑞薩MCU小百科】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
如何對(duì)以太網(wǎng)PHY芯片的rmii pin腳進(jìn)行配置
RK3288搭配以太網(wǎng)PHY芯片需要注意哪些
車載以太網(wǎng)MAC和PHY的問題詳解

EE-315:更改Blackfin?處理器的以太網(wǎng)驅(qū)動(dòng)程序中的PHY

車載以太網(wǎng)PHY標(biāo)準(zhǔn)分布
簡(jiǎn)化您的以太網(wǎng)設(shè)計(jì),第1部分:以太網(wǎng)PHY基礎(chǔ)知識(shí)和選擇過程

選擇以太網(wǎng)PHY時(shí)的重要因素

如何選擇適合的以太網(wǎng)PHY

還在為以太網(wǎng)PHY缺芯改版煩惱嗎?

適用于工業(yè)應(yīng)用的使用MDIO的以太網(wǎng)PHY配置

評(píng)論