2416開發板上網卡芯片lan9220的時序配置問題

 2416開發板上網卡芯片lan9220的時序配置問題

最近在學習某品牌的2416(不好評論)開發板,其他都還好,就這個網卡把我折磨得夠嗆。lan9220這款網卡芯片功能極其強大,能耗控制,遠程喚醒,高度集成PHY與MAC, 10Mbps/100Mbps等,但是建議各位在非極端情況下不要採用此款芯片,至少在與2416搭配時不要採用此芯片。

發現的硬傷(2416與lan9220搭配時),未在其他開發板上測試,僅供參考:

現象1:lan9220觸發的中斷信號使用2416的GPG7,外部中斷15,當我們採用下降沿進行觸發時,會出現抖動,造成觸發2次中斷,2次中斷還特別怪異,第一次外部中斷狀態置1,內部中斷PND與SRC都置1,當我們清除後,第二次進入中斷,只有內部中斷PND與SRC置1,外部中斷狀態全0.(這個與朋友討論結論:有可能是2416的電源沒有保護好,不管了,反正我們搞軟件的)。(注:此時我們僅開通了內部中斷5管理的外部中斷15,其他的8到14全部關閉狀態中。

現象2:當使能發送時(TX_EN),如果再次使能接受使能(RX_EN)TX_EN的使能會被錯誤的關閉。

現象3HBI層的寄存器能正常訪問,MAC層的寄存器組,對MAC_CSR_CMD的寫必須使用busy mode(使用說明沒提到),PHY層的寄存器組反應速度比較慢,這也是我今天要說明的東西。

首先在lan9220的手冊上提到的一些時序問題,我們就不再這裏討論了,我們來說說他漏掉的一些時序問題。

因爲lan9220mac層與phy層的寄存器是不能直接被訪問的,都是逐級調用寄存器來進行來訪問的,但我對mac進行按照說明書上的步驟進行訪問時出現一個現象是:

 

本來phy_id1的默認值是7  id2默認值是c0c3的,但是他們都被錯誤的讀取了。我的程序如下:

static unsigned long HBI_read(unsigned char offset)

{

return __REG(LAN9220_BASEADDR | (offset & 0xFF));

}

static void HBI_write(unsigned char offset, unsigned long value)

{

__REG(LAN9220_BASEADDR | (offset & 0xFF)) = (RAW_U32)value;

}

static unsigned long mac_read(unsigned int index)

{

unsigned long reg = 0;

while (HBI_read(MAC_CSR_CMD) & (0x1 << 31)) {

delay(1);

}

HBI_write(MAC_CSR_CMD, (0x1 << 31) | (0x1 << 30) | (index & 0xFF));

reg = HBI_read(MAC_CSR_DATA);

while (HBI_read(MAC_CSR_CMD) & (0x1 << 31)) {

delay(1);

}

return reg;

}

static void mac_write(unsigned int index, unsigned long value)

{

while (HBI_read(MAC_CSR_CMD) & (0x1 << 31)) {

delay(1);

}

HBI_write(MAC_CSR_DATA, value);

HBI_write(MAC_CSR_CMD, (0x1 << 31) | (index & 0xFF));

while (HBI_read(MAC_CSR_CMD) & (0x1 << 31)) {

delay(1);

}

}

static unsigned long phy_read(unsigned int index)

{

unsigned short reg = 0;

while (mac_read(MII_ACC) & 0x1);

mac_write(MII_ACC, (0x1) | (index << 6) | (0x01 << 11));

reg = mac_read(MII_DATA) & 0xFFFF;

while (mac_read(MII_ACC) & 0x1);

return reg;

}

static void phy_write(unsigned int index, unsigned short value)

{

while (mac_read(MII_ACC) & 0x1);

mac_write(MII_DATA, (unsigned long)(value & 0xFFFF));

mac_write(MII_ACC, (0x1) | (0x1 << 1) | (index << 6) | (0x01 << 11));

while (mac_read(MII_ACC) & 0x1);

}

static void delay(int cnt)

{

while (cnt--)

{

HBI_read(BYTE_TEST);

}

}

但我對mac_read/mac_write進行debug時,添加打印信息,缺又偶然的得到了正確的反饋信息,說明對phy層寄存器的操作需要添加一定延時,來滿足寄存器相應。大概流程如下:

DATA---delay--->cmd--->wait for complete

寫操作

Cmd--->delay----->data---->delay---->wait for complete

讀操作

注意,在這2組操作之間也需要一定的延時來插入。

大概就這樣吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章