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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值