//-------------------------------------------------------------------------------------------- - //DSP28377 利用EMIF控制网口DM9000芯片收发数据 //-------------------------------------------------------------------------------------------- - #include "F28x_Project.h" // Device Headerfile and Examples Include File #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]); -3-C:UsershaviDesktopDM9000_CTR.c 2016年11月23日 17:10 //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 | // Turn Around time of 2 Emif Clock EMIF_ASYNC_RHOLD_1 | // Read Hold time of 1 Emif Clock EMIF_ASYNC_RSTROBE_5 | // Read Strobe time of 4 Emif Clock EMIF_ASYNC_RSETUP_1 | // Read Setup time of 1 Emif Clock EMIF_ASYNC_WHOLD_1 | // Write Hold time of 1 Emif Clock EMIF_ASYNC_WSTROBE_2 | // Write Strobe time of 1 Emif Clock EMIF_ASYNC_WSETUP_1 | // Write Setup time of 1 Emif -6-C:UsershaviDesktopDM9000_CTR.c 2016年11月23日 17:10 Clock EMIF_ASYNC_EW_DISABLE | // Extended Wait Disable. EMIF_ASYNC_SS_DISABLE // Strobe Select Mode 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); // } }