一、概述
為了盡量給甲方降低成本,決定使用較低成本的PHY芯片RTL8201F-VB-CG芯片。移植官網(wǎng)的以太網(wǎng)demo程序,git上下載了一份很好看的rtl8201F的驅(qū)動程序,用來替換官方demo的lan8742程序。并沒有直接通,于是開始了調(diào)試之路。
二、平臺
芯片型號:stm32h753
官網(wǎng)例程文件名:STM32Cube_FW_H7_V1.10.0
三、原理圖
四、遇到的問題
使用官網(wǎng)lwip的demo,下載RTL8201F-VB-CG驅(qū)動程序并替換lan8742驅(qū)動芯片程序,使用PC機(jī)ping設(shè)備ping不通
五、調(diào)試過程
1.確定PHY驅(qū)動芯片的寄存器可以讀取和寫入。
通過函數(shù)接口HAL_ETH_ReadPHYRegister和HAL_ETH_WritePHYRegister進(jìn)行讀寫。這里我是可以直接正常讀寫的,所以并沒遇到太大阻力。但我還是請教了一下其他朋友,了解到PHY寄存器的讀寫依靠22,23引腳。22引腳為時(shí)鐘線,測量波形約2M左右,沒記錯(cuò)的話。
2.深入調(diào)試了STM32對于以太網(wǎng)的初始化程序
主要是HAL_ETH_Init函數(shù),先上代碼。
HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
{
uint32_t tickstart;
if (heth == NULL)
{
return HAL_ERROR;
}
if (heth->gState == HAL_ETH_STATE_RESET)
{
heth->gState = HAL_ETH_STATE_BUSY;
#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
ETH_InitCallbacksToDefault(heth);
if (heth->MspInitCallback == NULL)
{
heth->MspInitCallback = HAL_ETH_MspInit;
}
/* Init the low level hardware */
heth->MspInitCallback(heth);
#else
/* Init the low level hardware : GPIO, CLOCK, NVIC. */
HAL_ETH_MspInit(heth);
#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
}
__HAL_RCC_SYSCFG_CLK_ENABLE();
if (heth->Init.MediaInterface == HAL_ETH_MII_MODE)
{
HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_MII);
}
else
{
HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_RMII);
}
/* Dummy read to sync with ETH */
(void)SYSCFG->PMCR;
/* Ethernet Software reset */
/* Set the SWR bit: resets all MAC subsystem internal registers and logic */
/* After reset all the registers holds their respective reset values */
SET_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR);
/* Get tick */
tickstart = HAL_GetTick();
/* Wait for software reset */
while (READ_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR) > 0U)
{
if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT))
{
/* Set Error Code */
heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT;
/* Set State as Error */
heth->gState = HAL_ETH_STATE_ERROR;
/* Return Error */
return HAL_ERROR;
}
}
/*------------------ MDIO CSR Clock Range Configuration --------------------*/
HAL_ETH_SetMDIOClockRange(heth);
/*------------------ MAC LPI 1US Tic Counter Configuration --------------------*/
WRITE_REG(heth->Instance->MAC1USTCR, (((uint32_t)HAL_RCC_GetHCLKFreq() / ETH_MAC_US_TICK) - 1U));
/*------------------ MAC, MTL and DMA default Configuration ----------------*/
ETH_MACDMAConfig(heth);
/* SET DSL to 64 bit */
MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_DSL, ETH_DMACCR_DSL_64BIT);
/* Set Receive Buffers Length (must be a multiple of 4) */
if ((heth->Init.RxBuffLen % 0x4U) != 0x0U)
{
/* Set Error Code */
heth->ErrorCode = HAL_ETH_ERROR_PARAM;
/* Set State as Error */
heth->gState = HAL_ETH_STATE_ERROR;
/* Return Error */
return HAL_ERROR;
}
else
{
MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_RBSZ, ((heth->Init.RxBuffLen) << 1));
}
/*------------------ DMA Tx Descriptors Configuration ----------------------*/
ETH_DMATxDescListInit(heth);
/*------------------ DMA Rx Descriptors Configuration ----------------------*/
ETH_DMARxDescListInit(heth);
/*--------------------- ETHERNET MAC Address Configuration ------------------*/
/* Set MAC addr bits 32 to 47 */
heth->Instance->MACA0HR = (((uint32_t)(heth->Init.MACAddr[5]) << 8) | (uint32_t)heth->Init.MACAddr[4]);
/* Set MAC addr bits 0 to 31 */
heth->Instance->MACA0LR = (((uint32_t)(heth->Init.MACAddr[3]) << 24) | ((uint32_t)(heth->Init.MACAddr[2]) << 16) |
((uint32_t)(heth->Init.MACAddr[1]) << 8) | (uint32_t)heth->Init.MACAddr[0]);
heth->ErrorCode = HAL_ETH_ERROR_NONE;
heth->gState = HAL_ETH_STATE_READY;
return HAL_OK;
}
在該代碼的這一段發(fā)現(xiàn)程序返回了錯(cuò)誤。于是查找手冊對比這個(gè)bit位的作用
while (READ_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR) > 0U)
{
if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT))
{
/* Set Error Code */
heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT;
/* Set State as Error */
heth->gState = HAL_ETH_STATE_ERROR;
/* Return Error */
return HAL_ERROR;
}
}
3.獲取手冊上關(guān)于這個(gè)bit位的描述
手冊上關(guān)于這個(gè)bit位的描述如下,我的理解是,芯片需要檢查所有的時(shí)鐘,在檢測到時(shí)鐘的情況下,會自動復(fù)位完成。
4.測量PHY芯片各個(gè)時(shí)鐘線的狀態(tài)
通過向朋友的學(xué)習(xí),測量了PHY芯片15引腳的時(shí)序,因?yàn)槭褂肦MII模式,所以該時(shí)鐘引腳理論值約為50M。而我的這次調(diào)試,問題的根源也在這里。
在運(yùn)行程序時(shí),我測量了PHY芯片15引腳,發(fā)現(xiàn)該引腳有時(shí)鐘輸出,我就誤認(rèn)為這里的時(shí)鐘沒問題,后面總結(jié)過后,才發(fā)現(xiàn)是寄存器配置后,PHY芯片的時(shí)鐘才開始輸出。所以在測量時(shí),最好是打斷點(diǎn)進(jìn)行調(diào)試,斷點(diǎn)要打在HAL_ETH_Init初始化之前。
5.閱讀PHY芯片手冊,找到在HAL_ETH_Init初始化之前提供時(shí)鐘的辦法
通過查看PHY芯片的芯片手冊,關(guān)于該芯片12引腳的描述如下,在該引腳拉低或者浮空(芯片內(nèi)部默認(rèn)接地)的情況下,15引腳會默認(rèn)輸出時(shí)鐘信號
六、解決的辦法
將12引腳的上拉電阻去掉。stm32h7檢測到PHY芯片的時(shí)鐘信號后,以太網(wǎng)驅(qū)動的初始化會正常進(jìn)行。再ping設(shè)備,通了?。?!文章來源:http://www.zghlxwxcb.cn/news/detail-419152.html
七、總結(jié)
關(guān)于這個(gè)問題,也是請教朋友的過程中,意外學(xué)習(xí)到,一般來說以太網(wǎng)的時(shí)鐘信號應(yīng)該由控制芯片來提供,在這里也就是該由stm32h7芯片來提供時(shí)鐘。但是我在手冊上并沒有看到輸出時(shí)鐘的方法(或許我看漏了吧)。所以在初始化流程并沒有正常的進(jìn)行。
而原理圖的來源,是我們硬件工程師從一款海思的產(chǎn)品上copy下來的,所以他認(rèn)為沒什么問題??赡躍oc芯片都有以太網(wǎng)時(shí)鐘信號輸出的能力吧。
所以不同的平臺,驅(qū)動方式會略有差異,但問題終歸是解決了。文章來源地址http://www.zghlxwxcb.cn/news/detail-419152.html
到了這里,關(guān)于RTL8201 以太網(wǎng)PHY芯片 調(diào)試記錄的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!