您的位置:首页 > 其它

dsp控制DM9000实现802.3数据收发第三篇,调试过程程序第三版;采用外部引脚中断方式获取中断,优化掉帧现象

2016-11-23 17:43 746 查看
//--------------------------------------------------------------------------------------------

-

//DSP28377 利用EMIF控制网口DM9000芯片收发数据
//--------------------------------------------------------------------------------------------

-
#include "F28x_Project.h"

#include "string.h"
void Emif1Initialize(void);
//emif 映射地址
#define ASRAM_CS3_START_ADDR 0x37FFF0

#define ASRAM_CS3_SIZE 0x8000
interrupt void
xint1_isr(void);
extern void setup_emif1_pinmux_async_16bit(Uint16);
#pragma DATA_SECTION(datafrompc , "RAMGS0");

Uint16 datafrompc[12288];

//地址指定;通过操作指针实现地址对应数据操作
Uint16 *ADDR_POINT
= (Uint16
*)(ASRAM_CS3_START_ADDR);

Uint16 *DATA_POINT
= (Uint16
*)(ASRAM_CS3_START_ADDR
+ 1);

//##########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 PHYIntFlag =
0;
Uint16 RxReady =
0;
Uint16 SweepMode =
0;
Uint16 Index[24] = {0
, 512
, 1024
, 1536
, 2048
, 2560
, 3072
, 3584
, 4096
, 4608
, 5120
,
5632 ,
6144 ,
6656 ,
7168 ,
7680 ,
8192 ,
8704 ,
9216 ,
9728 ,
10240 ,
10752 ,

11264 ,11776};

//----------------------------------------------------------------------------------

//检测到PHY中断信号并触发中断
---------------------------------------------------------------
interrupt void
xint1_isr(void)

{
GpioDataRegs.GPBCLEAR.all
= 0x4;
// GPIO34 is low

// Acknowledge this interrupt to get more from group 1
PieCtrlRegs.PIEACK.all
= PIEACK_GROUP1;
PHYIntFlag =
1;

}

//---------------------------------------------------------------------

// 向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);

}

//---------------------------------------------------------------------

//读取DM9000当前地址值
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的首地址

等待下一次触发
//数据包后面还跟随了2个word的校验位
void PACKE_RECIVE(Uint16
*datain ,
Uint16 *data_ready
, Uint16 *Type_mode){
Uint16 i =
0;
Uint16 rx_length =
0;
Uint16 state =
0;
Uint16 ready =
0;
Uint16 phy_addr[6];
Uint16 mode_typ =
0;
Uint16 cnt =
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_length =
inw();
//读取帧字节数
rx_length =
inw();
phy_addr[0] =
inw();phy_addr[1] =
inw();phy_addr[2] =
inw();
phy_addr[3] =
inw();phy_addr[4] =
inw();phy_addr[5] =
inw();
mode_typ =
inw();
cnt = inw();
rx_length = (rx_length
- 16)/2;
for(i=0;i<rx_length;i++){

*(datain +
i + Index[cnt]) =
inw();

}
if(cnt
== 23){

*data_ready =
1;

*Type_mode =
mode_typ;

}

}
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);

}

}
iow(DM_ISR
, 0x01);
iow(DM_IMR
, 0x81);

}

//--------------------------------------------------------------------------

//emif 设置
void emifsetting()

{
Emif1Initialize();
//Configure to run EMIF1 on full Rate (EMIF1CLK = CPU1SYSCLK)
EALLOW;
ClkCfgRegs.PERCLKDIVSEL.bit.EMIF1CLKDIV
= 0x1;
EDIS;
EALLOW;
//Grab EMIF1 For CPU1
Emif1ConfigRegs.EMIF1MSEL.all
= 0x93A5CE71;
//Disable Access Protection (CPU_FETCH/CPU_WR/DMA_WR)
Emif1ConfigRegs.EMIF1ACCPROT0.all
= 0x0;
if (Emif1ConfigRegs.EMIF1ACCPROT0.all
!= 0x0)

{
while(1);

}
// Commit the configuration related to protection. Till this bit remains set

// content of EMIF1ACCPROT0 register can't be changed.
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;
//

// //Configure GPIO pins for EMIF1
setup_emif1_pinmux_async_16bit(0);
//

// //Configure the access timing for CS2 space

//net
Emif1Regs.ASYNC_CS3_CR.all
= ( EMIF_ASYNC_ASIZE_16
| // 16Bit Memory Interface
EMIF_ASYNC_TA_3 |
EMIF_ASYNC_RHOLD_1 |
EMIF_ASYNC_RSTROBE_5 |

EMIF_ASYNC_RSETUP_1 |

EMIF_ASYNC_WHOLD_1 |
EMIF_ASYNC_WSTROBE_2 |

EMIF_ASYNC_WSETUP_1 |

EMIF_ASYNC_EW_DISABLE |

EMIF_ASYNC_SS_DISABLE
);

}

//--------------------------------------------------------------------------

//GPIO中断触发设置
void GPIOINTsetting(){
//设置中断触发组1
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.XINT1_INT
= &xint1_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
PieCtrlRegs.PIECTRL.bit.ENPIE
= 1;
// Enable the PIE block
PieCtrlRegs.PIEIER1.bit.INTx4
= 1;
// Enable PIE Group 1 INT4
PieCtrlRegs.PIEIER1.bit.INTx5
= 1;
// Enable PIE Group 1 INT5
IER |= M_INT1;
// Enable CPU INT1
EINT;
//出发源为外部引脚GPIO55,此引脚链接至DM9000的中断引脚
EALLOW;
GpioCtrlRegs.GPBMUX2.bit.GPIO55
= 0;
// GPIO
GpioCtrlRegs.GPBDIR.bit.GPIO55
= 0;
// input
GpioCtrlRegs.GPBQSEL2.bit.GPIO55
= 0;
EDIS;
GPIO_SetupXINT1Gpio(55);
//设置引脚上升沿出发中断
XintRegs.XINT1CR.bit.POLARITY
= 1;
// Falling edge interrupt
XintRegs.XINT1CR.bit.ENABLE
= 1;
// Enable XINT1

}

//-------------------------------------------------------------------

// 主函数
void main(void)

{
Uint16 i =
0;
InitSysCtrl();
DINT;
InitPieCtrl();
EALLOW;
IER = 0x0000;
IFR = 0x0000;
EDIS;
InitPieVectTable();
GPIOINTsetting();
emifsetting();
DM9000_INIT();
DELAY_US(500000);
//********************************************************************

//接受数据测试段代码
//******************************************************************
while(1){
if(PHYIntFlag
== 1){
PHYIntFlag =
0;
PACKE_RECIVE(&datafrompc[0] , &RxReady
, &SweepMode);
if(RxReady
== 1){
RxReady =
0;
//过程处理
ESTOP0;
memset(&datafrompc[0] ,
0 ,
12288);

}

}

}
//*************************************************************************

//发送数据测试段代码
//*************************************************************************

// 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);

// }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐