天天看點

【學習筆記】DM9000裸機驅動(一)

1 總體介紹

DM9000是以太網MAC控制器。它有一個一般處理接口、一個10/100M自适應的PHY和4K DWORD值的SRAM。它的目的是在低功耗和高性能程序的3.3V與5V的支援寬帶。

DM9000還提供了媒體無關接口(MII)。該DM9000支援8位、16位和32位接口通路内部存儲器,以支援不同的處理器。DM9000的PHY接口完全支援10MBps下3類、4類、5類非屏蔽雙絞線和100MBps下5類非屏蔽雙絞線。它的自動協調功能将自動完成配置以最大限度地适合其線路帶寬。它還支援IEEE 802.3x全雙工流量控制。

2 準備知識

實體層的任務接受一個原始的位流,并試圖将它傳遞到目标機器。

PHY是實體層接口收發器,它實作實體層。包括MII(與媒體無關接口)子層、PCS(實體編碼子層)等其它子層。

PHY在發送資料的時候,接受MAC發過來的資料(對PHY來說,沒有幀的概念,對它來說一切都是原始的位流)。然後每4bit增加1bit的檢錯碼,然後把并行資料轉化為串行流資料,再按照實體層的編碼規則把資料編碼,再變為模拟信号把資料送出去。

隔離變壓器把PHY送出來的差分信号用差模耦合的線圈耦合濾波以增強信号,并通過電磁場的轉換耦合到連接配接網線的另一端。

MII(與媒體無關接口)。與媒體無關表明在不對MAC硬體重新設計或交換的情況下,任何類型的PHY裝置都可以正常工作。

MAC(媒體通路控制協定)主要負責控制與連接配接實體層的實體媒體,以實作無差錯傳輸。在發送資料的時候,MAC協定可以事先判斷是否可以發送資料,如果可以發送将給資料加上一些控制資訊,最終将資料以及控制資訊以規定的格式發送到實體層;在接收資料的時候,MAC協定首先判斷輸入的資訊是否有傳輸錯誤,如果沒有錯誤,則去掉控制資訊發送至LLC層。

3 DM9000原理

DM9000是Davicom公司的一款以太網控制晶片,在網絡中它可自動獲得同設定MAC位址一緻的IP包,完成IP包得收發,再用一個單片機來結合完成上層協定,就構成了一個完整的網絡終端。在單片機中嵌入了一個精簡TCP/IP協定棧。

3.1 DM9000結構框圖

【學習筆記】DM9000裸機驅動(一)

3.2 DM9000的PIN

【學習筆記】DM9000裸機驅動(一)

DM9000的管腳分為8大類。

第一類:MII Interface

    外部擴張接口,TQ2440沒用。

第二類:Processor Interface

處理器(ARM)與DM9000的接口,包括:片選、位址、資料、指令、狀态标志。

IO16:字指令标志,當内部存儲器的總線是16位或32位時。

INT:中斷請求。

第三類:EEPROM Interface

    控制EEPROM的接口,TQ2440沒有用。

第四類:Clock Interface

    25M時鐘接口。

第五類:LED Interface    

第六類:10/100M PHY/Fiber

與網線相連的。

第七類:Miscellaneous

    對TQ2440來說沒什麼用。

第八類:Power Pins

用在TQ2440上的管腳

管腳号 輸入輸出類型 管腳名稱 管腳功能
1 I IOR# 讀指令
2 I IOW# 寫指令
3 I AEN 位址使能
4 O IOWAIT L表示指令等待,正常情況下時H。使用上拉電阻進行上拉,增強信号。

6~13,

89~82

I/O SD0~15 資料總線
92 I CMD

指令類型:

H:資料;L:位址

100 O INT 中斷請求
以下為不重要的
14(硬體) I RST 複位(H)。被接地,故不能硬體複位。
93~98(硬體) I SA4~9

位址總線,選擇DM9000。

在TQ2440中,

SA9、SA8:H;

SA7、SA6、SA5、SA4:L;

80(硬體) I PW_RST# 低電平有效,用于上電複位。
67(硬體) I/O EECS

用于LED模式選擇引腳。

H:模式1(TQ2440)

L:模式0

62(LED燈) O LINK&ACT#

與LED相連

(1)在LED mode1表示連接配接和内部PHY的載波偵測信号的運作情況

(2)在LED mode2 表示内部PHY的載波偵測信号的運作情況

60(LED燈) O SPEED100#

L表示内部PHY運作在100Mbps;

H表示内部PHY運作在10Mbps

29 I RXI+ TP RX Input
30 I RXI- TP Rx Input
33 O TXO+ TP TX Output
34 O TXO- TP TX Output

3.3 DM9000的寄存器

 DM9000有許多的控制和狀态寄存器,我們可以通過主機控制它。這些控制和狀态寄存器(CSRs)是位元組對齊的。所有的CSRs被硬體被設定為它們預設的值,也可以被軟體設定為制定的值。

具體請參考DM9000的datasheet。

3.4 DM9000的初始化

(1)配置相關管腳

(2)進行ID測試

(3)配置寄存器

        a) 激活内部PHY

        b) 軟體複位

        c) 使能中斷

       d) 清除原網絡狀态和中斷狀态

       e) 對發射和接收進行新的控制

       f) 設定MAC位址

      g) 清除原網絡狀态和中斷狀态

      h) 使能中斷

注意将MMU的BANK4的權限設為NCNB。

MMU_SetMTT(0x20000000,0x27f00000,0x20000000,RW_NCNB);

DM9000初始化函數如下

//================================================================
//DM9000_Init()
//1.将相關的管腳配置好
//2.将相關的寄存器配置好

//初始化寄存器主要做的事情:
//1.複位
//2.清楚原先的狀态
//3.對發射、接收進行控制
//4.使能中斷
//在設定時,有些地方需要重複設定。
//================================================================
void DM9000_Init()
{
	U8 i;
	
	//1.配置管腳
	EINT_INIT( EINT7, Rising_edge);
	//2.進行ID測試
	Test_DM9000_ID();
	//3.配置寄存器
	//3.1.激活内部PHY
	DM9000_Write(GPCR,0x01);//設定GPCR bit[0]=1,使DM9000為GPIO0為輸出
	DM9000_Write(GPR,0x00);//GPR bit[0]=0,使GPIO0輸出低電平以激活内部PHY
	uDelay(5000);
	
	//3.2 軟體複位
	DM9000_Write(NCR,0x03);	//軟體複位,MAC内部循環回報(?)
	uDelay(3000);			//延時10us以上,等待軟體複位完成
	DM9000_Write(NCR,0x00);	//複位完成,設定正常工作模式
	DM9000_Write(NCR,0x03);	//第二次軟體複位。確定軟體複位完全成功
	uDelay(3000);			
	DM9000_Write(NCR,0x00);
	
	//3.3 使能中斷
	DM9000_Write(IMR,0x80);//使能指向SRAM的指針的自動傳回功能
	
	
	//3.4 清除原網絡和中斷狀态
	DM9000_Write(NSR,0x2c);	//清除各種狀态标志位
	DM9000_Write(ISR,0xbf);	//清除所有中斷标志位,8-bit
	
	//3.5 對發射和接收進行新的控制
	//    對中斷進行新的控制
	DM9000_Write(RXCR,0x39);//接收控制
	DM9000_Write(TXCR,0x00);//發送控制
	DM9000_Write(BPTR,0x3f);//設定RX的最低閥值,小于将産生擁塞
	DM9000_Write(FCTR,0x00);//接收FIFO門限3K,8K
	DM9000_Write(FCR,0xff);//啟動一些控制功能
	DM9000_Write(SMCR,0x00);//未啟動特殊模式
	
	//3.6  設定MAC位址 
	for(i=0; i<6; i++)
		DM9000_Write(PAR+i, mac_addr[i]);
	//3.7  清除原網絡狀态和中斷标志位
	DM9000_Write(NSR,0x2c);	//清除各種狀态标志位
	DM9000_Write(ISR,0x3f);	//清除所有中斷标志位,8-bit
	
	//3.8 使能中斷
	DM9000_Write(IMR,0x81);//使能指向SRAM的指針滿後自動傳回功能。
						   //使能資料包接收中斷
						   
	Uart_Printf("DM9000初始化結束");
	/MAC位址///
	Uart_Printf("\r\nMAC = %x",DM9000_Read(PAR)&0x00ff);
	Uart_Printf("  %x",DM9000_Read(PAR+1)&0x00ff);
	Uart_Printf("  %x",DM9000_Read(PAR+2)&0x00ff);
	Uart_Printf("  %x",DM9000_Read(PAR+3)&0x00ff);
	Uart_Printf("  %x",DM9000_Read(PAR+4)&0x00ff);
	Uart_Printf("  %x\r\n",DM9000_Read(PAR+5)&0x00ff);
}