dsp28377控制DM9000收发数据——第三版程序,通过外部引脚触发来实现中断接受数据,优化掉帧现象
//--------------------------------------------------------------------------------------------
-
//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:\Users\havi\Desktop\DM9000_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:\Users\havi\Desktop\DM9000_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);
// }
}
dsp28377控制DM9000收发数据——第三版程序,通过外部引脚触发来实现中断接受数据,优化掉帧现象的更多相关文章
- dsp28377控制DM9000收发数据——第二版程序,能够实现手术功能,但是容易掉帧;使用读取中断寄存器的方式判断中断
G:\controlSUITE\device_support\F2837xD\v180\F2837xD_examples_Cpu1\emif1_16bit_asram\cpu01\emif1_16bi ...
- dsp28377控制DM9000收发数据
首先感谢上一篇转载文章的作者给出的参考,下面是一些自己在调试过程中的一些步骤: 首先把代码贴上来: //------------------------------------------------ ...
- STM3的Uart中断接受数据和非中断接受数据!
//非中断方式接受数据if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET) //接收数据寄存器非空标志位{ str = USART_Recei ...
- 评CSDN上一篇讲述数据迁移的文章“程序员 12 小时惊魂记:凌晨迁移数据出大事故!”
原文地址:https://blog.csdn.net/csdnnews/article/details/98476886 我的评论:热数据迁移,本不该搞突击,这样一旦出现问题后果不堪设想,多少DBA和 ...
- Linux就这个范儿 第15章 七种武器 linux 同步IO: sync、fsync与fdatasync Linux中的内存大页面huge page/large page David Cutler Linux读写内存数据的三种方式
Linux就这个范儿 第15章 七种武器 linux 同步IO: sync.fsync与fdatasync Linux中的内存大页面huge page/large page David Cut ...
- 微软发布 Windows Server 2016 预览版第三版,开发者要重点关注Nano Server
微软已经发布 Windows Server 2016 和 System Center 2016 第三个技术预览版,已经提供下载.Windows Server 2016 技术预览版第三版也是首个包括了容 ...
- JavaScript高级程序设计(第三版)学习笔记20、21、23章
第20章,JSON JSON(JavaScript Object Notation,JavaScript对象表示法),是JavaScript的一个严格的子集. JSON可表示一下三种类型值: 简单值: ...
- SLAM+语音机器人DIY系列:(三)感知与大脑——2.带自校准九轴数据融合IMU惯性传感器
摘要 在我的想象中机器人首先应该能自由的走来走去,然后应该能流利的与主人对话.朝着这个理想,我准备设计一个能自由行走,并且可以与人语音对话的机器人.实现的关键是让机器人能通过传感器感知周围环境,并通过 ...
- 《Effective Java 第三版》目录汇总
经过反复不断的拖延和坚持,所有条目已经翻译完成,供大家分享学习.时间有限,个别地方翻译得比较仓促,希望有疑虑的地方指出批评改正. 第一章简介 忽略 第二章 创建和销毁对象 1. 考虑使用静态工厂方法替 ...
随机推荐
- 使用DiskFileItemFactory 实现文件上传 ,设定缓冲区大小和存放临时文件目录。
DiskFileItemFactory有两个方法 :setSizeThreshold和.setRepository 1. setRepository方法用于设置当上传文件尺寸大于setSizeThre ...
- Leetcode: Valid Word Square
Given a sequence of words, check whether it forms a valid word square. A sequence of words forms a v ...
- C++之路进阶——P2022
P2022 有趣的数 让我们来考虑1到N的正整数集合.让我们把集合中的元素按照字典序排列,例如当N=11时,其顺序应该为:1,10,11,2,3,4,5,6,7,8,9. 定义K在N个数中的位置为Q( ...
- iOS原生APP与H5+JS交互////////////////////zzzz
原生代码中直接加载页面 1. 具体案例 加载本地/网络HTML5作为功能介绍页 2. 代码示例 //本地 -(void)loadLocalPage:(UIWebView*)webView ...
- 使用git 更新线上代码
先本地代码合并://1合并分支git branch//2查看taggit tag //3添加tagcloud_crm]$ git tag -a v1.0.2 -m "0902"// ...
- getRemoteAddr()和getRemoteHost() 区别
System.out.println("request.getRemoteAddr(): " + request.getRemoteAddr()); System.out.prin ...
- Node.js Express 框架 GET方法
GET 方法 以下实例演示了在表单中通过 GET 方法提交两个参数,我们可以使用 server.js 文件内的 process_get 路由器来处理输入: index.htm 文件代码如下: < ...
- yii2得到的数据对象转化成数组
yii2得到的数据对象转化成数组需要用到asArray().1.Customer::find(['id' => $id])->asArray()->one();2.$model = ...
- Java8-Function使用及Groovy闭包的代码示例
导航 定位 概述 代码示例 Java-Function Groovy闭包 定位 本文适用于想要了解Java8 Function接口编程及闭包表达式的筒鞋. 概述 在实际开发中,常常遇到使用模板模式的场 ...
- python 实现简单 http 代理
有台 openwrt 路由器,16M flash存储 + 64M 内存 ,可以装 python .因为没有自带 url 网站访问记录,想手写一个. 原理: http 1.1 也就是 tcp 连接,有 ...