首先感謝上一篇轉載文章的作者給出的參考,下面是一些自己在調試過程中的一些步驟:
首先把代碼貼上來:
//--------------------------------------------------------------------------------------------
-
//DSP28377 利用EMIF控制網口DM9000芯片收發數據
//--------------------------------------------------------------------------------------------
-
#include "F28x_Project.h"
void Emif1Initialize(void);
//emif 映射地址
#define ASRAM_CS3_START_ADDR 0x37FFF0
#define ASRAM_CS3_SIZE 0x8000
extern void setup_emif1_pinmux_async_16bit(Uint16);
//地址指定;通過操作指針實現地址對應數據操作
Uint16 *ADDR_POINT
= (Uint16
*)(ASRAM_CS3_START_ADDR);
Uint16 *DATA_POINT
= (Uint16
*)(ASRAM_CS3_START_ADDR
+ 1);
#define EMIF1 0
//##########DM9000 SETING ######################
#define DM_NCR 0X00
#define DM_NSR 0X01
#define DM_TCR 0X02
#define DM_RCR 0X05
#define DM_BPTR 0X08
#define DM_FCTR 0X09
#define DM_RTFCR 0X0A
#define DM_EPCR 0X0B
#define DM_EPAR 0X0C
#define DM_EPDRL 0X0D
#define DM_EPDRH 0X0E
#define DM_PAB0 0X10
#define DM_PAB1 0X11
#define DM_PAB2 0X12
#define DM_PAB3 0X13
#define DM_PAB4 0X14
#define DM_PAB5 0X15
#define DM_GPCR 0X1E
#define DM_GPR 0X1F
#define DM_SMCR 0X2F
#define DM_MRCMDX 0XF0
#define DM_MRCMD 0XF2
#define DM_MWCMD 0XF8
#define DM_TXPLH 0XFD
#define DM_TXPLL 0XFC
#define DM_ISR 0XFE
#define DM_IMR 0XFF
#define PHY_BADDR 0X40
#define PHY_WCMD 0X0A
#define PHY_RCMD 0X0C
Uint16 NODE_ADDR[6] = {0X5A
, 0X5A
, 0X5A
, 0X5A
, 0X5A
, 0X5A};
Uint16 databuffer[540];
Uint16 buffersize =
520;
//---------------------------------------------------------------------
// 向DM9000內部寄存器寫值
void iow(Uint16 IOADDR
, Uint16 REGDARA){
*ADDR_POINT
= IOADDR;
DELAY_US(20);
*DATA_POINT
= REGDARA;
DELAY_US(20);
}
//---------------------------------------------------------------------
// 讀取DM9000內部寄存器的值
Uint16 ior(Uint16 IOADDR){
DELAY_US(20);
*ADDR_POINT
= IOADDR;
DELAY_US(20);
return(*DATA_POINT);
}
//---------------------------------------------------------------------
// 往固定地址寫值
void outw(Uint16 REGDATA
, Uint16 addr_data_type){
if(addr_data_type
== 1) *DATA_POINT
= REGDATA;
else if(addr_data_type
== 2) *ADDR_POINT
= REGDATA;
DELAY_US(50);
}
//---------------------------------------------------------------------
//讀取寄存器的值
Uint16 inw(){
return
*DATA_POINT;
}
//---------------------------------------------------------------------
//寫物理接口PHY寄存器的值
void phy_write(Uint16 offset
, Uint16 REGIN){
iow(DM_EPAR
, (offset
| PHY_BADDR));
iow(DM_EPDRH
, (REGIN >>
8) &
0x00ff);
iow(DM_EPDRL
, (REGIN &
0x00ff));
iow(DM_EPCR
, PHY_WCMD);
while((ior(DM_EPCR)
& 1));
DELAY_US(200);
iow(DM_EPCR
, 0x08);
}
//---------------------------------------------------------------------
//讀物理接口PHY寄存器的值
Uint16 phy_reaad(Uint16 offset
, Uint16 REGIN){
Uint16 returndata=0;
iow(DM_EPAR
, (offset
| PHY_BADDR));
iow(DM_EPCR
, PHY_RCMD);
while((ior(DM_EPCR)
& 1));
DELAY_US(200);
iow(DM_EPCR
, 0x08);
returndata
= ior(DM_EPDRH);
returndata
= (returndata <<
8) |
ior(DM_EPDRL);
return
returndata;
}
//---------------------------------------------------------------------
//DM9000 初始化
void DM9000_INIT(){
//開啓PHY
iow(DM_GPR
, 0X00);
//softerware reset and setting as normal mode(TWICE)
iow(DM_NCR
, 0X01);
DELAY_US(10000);
iow(DM_NCR
, 0X00);
iow(DM_NCR
, 0X01);
DELAY_US(10000);
iow(DM_NCR
, 0X00);
//clear the RX/TX flag
iow(DM_NSR,
0x2C);
iow(DM_ISR,
0x3F);
// //write the NODE_ADDR to physical register
iow(DM_PAB0
, NODE_ADDR[0]);
iow(DM_PAB1
, NODE_ADDR[1]);
iow(DM_PAB2
, NODE_ADDR[2]);
iow(DM_PAB3
, NODE_ADDR[3]);
iow(DM_PAB4
, NODE_ADDR[4]);
iow(DM_PAB5
, NODE_ADDR[5]);
//Eenable RX/TX function
iow(DM_RCR
, 0x31);//去掉混雜模式//iow(DM_RCR
, 0x31);
iow(DM_TCR
, 0x00);
//setting phy of dm9000
phy_write(0x00
, 0x8000);
DELAY_US(100000);
phy_write(0x04
, 0x01e1
| 0x0400);
DELAY_US(100000);
//set back presure threshold register
iow(DM_BPTR
, 0x3F);
iow(DM_FCTR
, 0x3A);
iow(DM_RTFCR
, 0xFF);
iow(DM_SMCR
, 0x00);
//clear all flags agin
iow(DM_NSR,
0x2C);
iow(DM_ISR,
0x3B);
//open the rx interrupt
iow(DM_IMR
, 0x81);
DELAY_US(1000);
}
//--------------------------------------------------------------------------------------
//發送網絡包
void PACKE_SEND(Uint16
*datain ,
Uint16 datalen){
Uint16 i
= 0;
Uint16 len=0;
//關閉RX中斷
iow(DM_IMR
, 0x80);
//write length to internal sram
//將包的長度寫入到寄存器中;
len =
datalen *
2;
iow(DM_TXPLH
, ((len&0xff00)>>8));
iow(DM_TXPLL
, len&0x00ff);
//DM_MWCMD is pointer to internal TX sdram address
outw(DM_MWCMD
, 2);
//write data int internal sram
for(i
= 0;
i < datalen
; i++)
outw(datain[i] ,
1);
//start transmit
iow(DM_TCR
, 0X01);
// wait transmit complit
while((ior(DM_NSR)
& 0x0c) ==
0);
DELAY_US(20);
//clear the tx flag
iow(DM_NSR
, 0X2C);
//oprn rx intterupt
iow(DM_IMR
, 0x81);
}
//----------------------------------------------------------------------------------------
//接受網絡包
//在調試的過程中;通過一片DSP發送1040個數據(8bit);並設置發送長度爲1040;但對於接受的網絡包
而言;不僅僅會在接收到的網絡包前包含4個
//信息byte;分別是接受準備;接受狀態位;幀長度(2byte);後面跟隨1040個數據(byte);後面還會
跟隨4個byte位;作用不知;同時接受到的
//幀長度爲1044個;所以在讀取數據是必須讀取完成整個1044個數據;rx指針纔會自動跳轉到SRAM的首地址
等待下一次觸發
void PACKE_RECIVE(Uint16
*datain ,
Uint16 datalen){
Uint16 i
= 0;
Uint16 rx_length
= 0;
Uint16 rx_status
= 0;
Uint16 state
= 0;
Uint16 ready
= 0;
//獲取中斷標識
state
= ior(DM_ISR);
if(state
& 0x01){
//清除中斷標誌
iow(DM_ISR
, 0x01);
//將rx指針指向SRAM(此指針的指向方式爲讀取數據後指針不會自動增加)
ready
= ior(DM_MRCMDX);
DELAY_US(200);
//在讀取一次狀態寄存器
ready
= ior(DM_MRCMDX);
//取狀態寄存器的低8位
ready
= ready &
0X00FF;
if(ready
== 0x01){
//將rx指針指向SRAM(此指針的指向方式爲讀取數據後指針會自動增加)
outw(DM_MRCMD
, 2);
//讀取狀態信息
rx_status
= inw();
//讀取幀字節數
rx_length
= inw();
//獲取數據
if((rx_length
% 2) ==
1)
rx_length =
rx_length + 1;
for(i=0;i<rx_length/2;i++){
*(datain
+ i) =
inw();
}
ESTOP0;
}
else if(ready
== 0x00)
{
/*iow(DM_IMR , 0x80);
iow(DM_ISR , 0x0F);
iow(DM_RCR , 0x00);
iow(DM_NCR , 0x01);
DELAY_US(20);
iow(DM_NSR, 0x2C);
iow(DM_ISR, 0x80);
iow(DM_RCR, 0x39);*/
ESTOP0;
}
}
iow(DM_ISR
, 0x01);
iow(DM_IMR
, 0x81);
}
void main(void)
{
Uint16 i
= 0;
Uint16 datalen
= 0;
InitSysCtrl();
DINT;
InitPieCtrl();
EALLOW;
IER =
0x0000;
IFR =
0x0000;
EDIS;
InitPieVectTable();
Emif1Initialize();
EALLOW;
ClkCfgRegs.PERCLKDIVSEL.bit.EMIF1CLKDIV
= 0x1;
EDIS;
EALLOW;
Emif1ConfigRegs.EMIF1MSEL.all
= 0x93A5CE71;
Emif1ConfigRegs.EMIF1ACCPROT0.all
= 0x0;
if
(Emif1ConfigRegs.EMIF1ACCPROT0.all
!= 0x0)
{
while(1);
}
Emif1ConfigRegs.EMIF1COMMIT.all
= 0x1;
if(Emif1ConfigRegs.EMIF1COMMIT.all
!= 0x1)
{
while(1);
}
// Lock the configuration so that EMIF1COMMIT register can't be changed any more.
Emif1ConfigRegs.EMIF1LOCK.all
= 0x1;
if
(Emif1ConfigRegs.EMIF1LOCK.all
!= 1)
{
while(1);
}
EDIS;
setup_emif1_pinmux_async_16bit(0);
Emif1Regs.ASYNC_CS3_CR.all
= ( EMIF_ASYNC_ASIZE_16
| // 16Bit Memory Interface
EMIF_ASYNC_TA_3
| // Turn Around time of 2 EmifClock
EMIF_ASYNC_RHOLD_1
| // Read Hold time of 1 EmifClock
EMIF_ASYNC_RSTROBE_5
| // Read Strobe time of 4 EmifClock
EMIF_ASYNC_RSETUP_1
| // Read Setup time of 1 EmifClock
EMIF_ASYNC_WHOLD_1
| // Write Hold time of 1 EmifClock
EMIF_ASYNC_WSTROBE_2
| // Write Strobe time of 1 EmifClock
EMIF_ASYNC_WSETUP_1
| // Write Setup time of 1 EmifClock
EMIF_ASYNC_EW_DISABLE
| // Extended Wait Disable.
EMIF_ASYNC_SS_DISABLE
// Strobe Select Mode Disable.
);
DELAY_US(500000);
DM9000_INIT();
DELAY_US(500000);
//********************************************************************
//接受數據測試段代碼
//******************************************************************
// for(i=0;i<520;i++){
// databuffer[i] = 0;
// }
//
// while(1){
// PACKE_RECIVE(&databuffer[0] , 520);
//
// if(datalen > 10) ESTOP0;
// }
//*************************************************************************
//發送數據測試段代碼
//*************************************************************************
databuffer[0] =
0xFFFF;
databuffer[1] =
0xFFFF;
databuffer[2] =
0xFFFF;
databuffer[3] =
0x285B;
databuffer[4] =
0xC92D;
databuffer[5] =
0x587D;
databuffer[6] =
0X00;databuffer[7]=0X00;
for(i
= 0
; i<
512 ;
i++){
databuffer[i+8] =
i;
}
while(1){
PACKE_SEND(&databuffer[0] ,
buffersize);
DELAY_US(1000);
}
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------
一下調試過程中的需要注意一下的地方
1、初始化過程中不要搞錯寄存器了,在第一次調試的時候,發現對PHY上電到網口的指示燈亮每次的都要2s的時間,這表徵着給PHY上電需要2s的時間,後來發現是配置寄存器配置錯了。代碼中 DM9000_INIT()函數的第一個配置;
2、DM9000只要兩個寄存器的直接操作權在我們手裏,就是我們可以認爲的去讀寫的兩個,一個是0x00;另外一個是0x04;所以在調試的過程中,可以先把寄存器的值寫入在讀出來,看是否正確;
3、在接收數據調試的時候,由於數據發送端是pc;還會有很多數據通過網口輸送出來被DSP檢測到,這樣就不利於數據的傳輸;可以將DM9000設置爲通用模式,只接受自己設置的目的地址的數據;該設置在DM9000_INIT()函數中的 :iow(DM_RCR , 0x31);//去掉混雜模試