ADI Blackfin DSP处理器-BF533的开发详解19:LAN的网口设计(含源代码)

news2024/12/24 21:25:10

硬件准备

ADSP-EDU-BF533:BF533开发板
AD-HP530ICE:ADI DSP仿真器

软件准备

Visual DSP++软件

硬件链接

在这里插入图片描述

功能介绍

BF533说实话用来做LAN的应用有些许勉强,因为他自己不带网口,要做的话,需要在总线上挂,那么真实来讲,我何不直接用一个自带网口的DSP呢?比如BF537?BF548?BF609?因为我在做BF533的项目的时候,其他的DSP都还没有推出,ADI没有什么带网口的DSP,所以强行用533+一个DM9000来实现的,当下如果让我再去做这个方案的设计,芯片选型会有更多的选择。

20年前那会,我们真的是没条件也得创造条件。。。

这个程序只是打通了底层的硬件链路,并没有去写怎么移植TCP/IP协议的,后面有时间我再单独开一章,好好说一说怎么在嵌入式DSP上去移植TCP/IP协议。

ADSP-EDU-BF533开发板上的网卡模块采用 DM9000EP 实现, DM9000EP 为 DAVICOM 公司生产的网络芯片,它集成了网卡的 MAC 和 PHY,支持 10M/100M 速度。支持 16Bit/32Bit 总线访问带宽。

ADSP-BF533 通过 EBIU 总线采用 16Bit 总线方式与 DM9000EP 连接,其映射地址为 ADSP-BF53x 的 BANK2地址,其映射寄存器如下:

DM9000_PPTR 寄存器(写唯一):
DM9000_PPTRT 寄存器地址:0x20200000
DM9000_PPTR 寄存器是 DM9000EP 的指令寄存器,用于为 DM9000EP 写入指令。
DM9000_PDATA 寄存器(读写):
DM9000_PDATA 寄存器地址:0x20200020
DM9000_PDATA 寄存器是 DM9000EP 的数据寄存器,通过该寄存器读取和发送数据包。

硬件连接示意图

在这里插入图片描述

代码实现功能

代码实现了通过网络接口发送数据包的功能,没有包含任何网络协议。通过网线与计算机连接,使用计算机上的抓包工具,抓取数据包可以查看数据包的数据内容。

调试步骤

  1. 将仿真器(ICE)与 ADSP-EDU-BF53x 开发板和计算机连接好。
  2. 先给 ADSP-EDU-BF53x 开发板上电,再为仿真器(ICE)上电。
  3. 将交叉网线连接于计算机网口和开发板网口。
  4. 运行 VisualDSP++ 5.0 软件,选择合适的 BF533 的 session 将仿真器与软件连接。
  5. 加载 VisualDSP++ 5.0 工程文件 BF53x_LAN.dpj,编译并全速运行。
  6. 运行抓包软件 Commview.exe,通过软件抓取网卡发送的数据包。

通过抓包软件 Commview.exe 的 Pack 窗口可以看到抓取的数据包的数据信息。

在这里插入图片描述

计算机端打印的网卡信息

在这里插入图片描述

使用 COMMVIEW 软件抓取的数据包信息。

程序源码

#include <cdefbf533.h>
#include “dm9000e.h”

#define CONFIG_DRIVER_DM9000
#define CONFIG_COMMANDS 1
#define CFG_CMD_NET 1
#ifdef CONFIG_DRIVER_DM9000
#if (CONFIG_COMMANDS & CFG_CMD_NET)
#define PKTALIGN 32
#define PKTSIZE_ALIGN 1536
#define CFG_HZ 1000

#define DM9000_VID_L 0x28
#define DM9000_VID_H 0x29
#define DM9000_PID_L 0x2A
#define DM9000_PID_H 0x2B
#define DM9000_ID 0x90000A46
#define DM9000_int32_MII 0x00
#define DM9000_10MHD 0x1
#define DM9000_10MFD 0x2
#define DM9000_100MHD 0x3
#define DM9000_100MFD 0x4
#define LOOP_MAC 0x1
#define LOOP_PHY100M 0x2

unsigned short NetRxPackets[PKTSIZE_ALIGN+PKTALIGN];
unsigned char env_enetaddr[6];

#define DM9000_PPTR *(volatile unsigned short *)(0x20200000)
#define DM9000_PDATA *(volatile unsigned short *)(0x20200020)

/****************************************************************************

  • 名称 : GetDM9000ID

  • 功能 : 读取DM9000E ID并打印

  • 入口参数 :无

  • 出口参数 :id_val ID值
    ****************************************************************************/
    unsigned int GetDM9000ID(void)
    {
    unsigned int id_val;

    id_val = ior(DM9000_PID_H);
    printf(“DM9000E ID is %x”,id_val);
    id_val = ior(DM9000_PID_L);
    printf(“%x”,id_val);
    id_val = ior(DM9000_VID_H);
    printf(“%x”,id_val);
    id_val = ior(DM9000_VID_L);
    printf(" %x\n\r",id_val);
    return id_val;
    }
    /****************************************************************************

  • 名称 : iow

  • 功能 : 将值写入指定的寄存器

  • 入口参数 :reg,value

  • 出口参数 :无
    /
    static void iow(int reg, unsigned char value)
    {
    DM9000_PPTR = reg;
    asm(“ssync;”);
    asm(“ssync;”);
    asm(“ssync;”);
    DM9000_PDATA = value & 0xff;
    asm(“ssync;”);
    asm(“ssync;”);
    asm(“ssync;”);
    }
    /

  • 名称 : ior

  • 功能 : 送入要读取的寄存器地址返回当前寄存器值

  • 入口参数 :reg

  • 出口参数 :DM9000_PDATA & 0xff
    /
    static unsigned char ior(int reg)
    {
    DM9000_PPTR = reg;
    asm(“ssync;”);
    asm(“ssync;”);
    asm(“ssync;”);
    return DM9000_PDATA & 0xff;
    }
    /

  • 名称 : eth_reset

  • 功能 : 复位,初始化dm9000E并打印相关设置

  • 入口参数 :无

  • 出口参数 :无
    ****************************************************************************/
    void eth_reset (void)
    {
    int IoMode;
    unsigned char tmp;

    iow(0, 1); // 复位
    delay(50); // delay 100us
    IoMode = ior(0xfe) >> 6; //读取io模式
    if(!IoMode)
    printf(“DM9000 work in 16 bus width\r\n”);
    else if(IoMode == 2)
    printf(“DM9000 work in 8 bus width\r\n”);
    else if(IoMode == 1)
    printf(“DM9000 work in 32 bus width\r\n”);
    else
    printf(“DM9000 work in wrong bus width, error\r\n”);
    iow(0x1e, 0x01);
    iow(0x1f, 0x00); // 使能 PHY
    iow(0xff, 0x80);
    iow(0x01, 0xc); // 清除 TX 状态
    iow(0x5, 0x33); // 使能 RX
    ior(0x6);
    iow(0x2, 1); // 使能TX
    delay(100);
    IoMode = ior(0x01);
    if(IoMode & 0x40)
    printf(“Link on ethernet at:%d Mbps\r\n”, (IoMode & 0x80) ? 10:100);

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

  • 名称 : eth_rx

  • 功能 : 读取网络传输数据

  • 入口参数 :addr

  • 出口参数 :rxlen
    ****************************************************************************/
    int eth_rx (unsigned short *addr)
    {
    int i;
    unsigned short rxlen;
    unsigned short status;
    unsigned char RxRead;
    unsigned char *tmp;

    RxRead = ior(0xf0);
    RxRead = (DM9000_PDATA) & 0xff;
    RxRead = (DM9000_PDATA) & 0xff;
    if (RxRead != 1)
    return 0;
    status = ior(0xf2);//获得状态
    rxlen = DM9000_PDATA; //获得长度
    asm(“ssync;”);
    if (rxlen > PKTSIZE_ALIGN + PKTALIGN)
    printf (“packet too big! %d %d\r\n”, rxlen, PKTSIZE_ALIGN + PKTALIGN);
    for ( i =0; i<rxlen/2;i++)
    addr[i] = DM9000_PDATA;
    asm(“ssync;”);
    return rxlen;
    }

unsigned char txCmd;
/****************************************************************************

  • 名称 : eth_send

  • 功能 : 向网络发送数据包

  • 入口参数 :packet,length

  • 出口参数 :0
    ****************************************************************************/
    void eth_send (volatile void *packet, int length)
    {
    int i;
    volatile unsigned short *addr;
    int tmo;
    unsigned char TxStatus;
    int length1 = length>>1;
    int IoMode;

    TxStatus = ior(0x01);
    TxStatus = TxStatus & 0xc;

    DM9000_PPTR = 0xf8;
    for(i=0;i<2;i++) //延时匹配时序。
    asm(“ssync;”);

    for (addr = packet; length1 > 0; length1 --)
    {
    DM9000_PDATA = *addr++;
    for(i=0;i<3;i++) //延时匹配84nS延时时序。
    asm(“ssync;”);

    }
    iow(0xfd, (length >> 8) & 0xff); //set transmit leng
    iow(0xfc, length & 0xff);
    /* start transmit */
    iow(0x02, txCmd|0x1);

    return 0;
    }

/****************************************************************************

  • 名称 : phy_read

  • 功能 : 读取DM9000E物理寄存器

  • 入口参数 :reg

  • 出口参数 :( ior( 0xe) << 8 ) | ior( 0xd)
    /
    static unsigned short phy_read(int reg)
    {
    iow( 0xc, DM9000_PHY | reg);
    iow( 0xb, 0xc);
    delay(100);
    iow(0xb, 0x0);
    return ( ior( 0xe) << 8 ) | ior( 0xd);
    }
    /

  • 名称 : phy_write

  • 功能 : 写DM9000E物理寄存器

  • 入口参数 :reg,value

  • 出口参数 :无
    /
    static void phy_write( int reg, unsigned short value)
    {
    iow( 0xc, DM9000_PHY | reg);
    iow( 0xd, (value & 0xff));
    iow(0xe, ( (value >> 8) & 0xff));
    iow(0xb, 0xa);
    delay(100);
    iow(0xb, 0x0);
    }
    /

  • 名称 : set_PHY_mode

  • 功能 : 设置网卡工作模式 10M:100M

  • 入口参数 :op_mode

  • 出口参数 :无
    ****************************************************************************/
    static void set_PHY_mode(op_mode)
    {
    int phy_reg4,phy_reg0;
    switch(op_mode)
    {
    case DM9000_10MHD:
    phy_reg4 = 0x21;
    asm(“ssync;”);
    phy_reg0 = 0x0000;
    asm(“ssync;”);
    break;
    case DM9000_10MFD:
    phy_reg4 = 0x41;
    asm(“ssync;”);
    phy_reg0 = 0x1100;
    asm(“ssync;”);
    break;
    case DM9000_100MHD:
    phy_reg4 = 0x81;
    asm(“ssync;”);
    phy_reg0 = 0x2000;
    asm(“ssync;”);
    break;
    case DM9000_100MFD:
    phy_reg4 = 0x101;
    asm(“ssync;”);
    phy_reg0 = 0x3100;
    asm(“ssync;”);
    break;
    } // end of switch
    phy_write( 0, phy_reg0);

    phy_write( 4, 0x0400|phy_reg4);
    }
    /****************************************************************************

  • 名称 : loopback

  • 功能 : 网卡环路测试,设置网卡工作于何种环路测试模式

  • 入口参数 :mode

  • 出口参数 :无
    ****************************************************************************/
    void loopback(int mode)
    {
    switch(mode)
    {
    case LOOP_MAC:
    iow(DM9000_NCR, 0x02);
    phy_write( 0, 0x40);
    break;
    case LOOP_PHY100M:
    iow(DM9000_NCR, 0x04);
    phy_write( 0, 0x40);
    break;
    }
    }

#endif
#endif

unsigned short pack[1024];
unsigned short packLen=0;

void main()
{
int i;

Set_PLL(16,4);	
Init_EBIU();
Init_SDRAM(); 
GetDM9000ID();		
set_PHY_mode(DM9000_100MHD);
eth_reset();
delay(100);   
for(i=0;i<1024;i++)
	pack[i] = i;
while(1)
{  
	for(i=0;i<1000000;i++)
	{
		packLen = 512; 	
		eth_send(pack,packLen);
	} 	
	eth_rx(NetRxPackets);      	    	  	
}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/77731.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3D视觉PnP问题

文章目录背景和定义方法分类典型方法P3P(角锥法&#xff09;DLT单应性矩阵分解迭代法EPnP其他延伸总结背景和定义 目前常用的pnp方法有很多&#xff0c;但是本人学习和查阅后发现比较零散&#xff0c;因此&#xff0c;在这里将所学习的方法按照理解分类和总结&#xff0c;并且…

体验了一下火爆全球的 ChatGPT,我惊呆了

这几天&#xff0c;要说编程圈最热的话题&#xff0c;莫过于OpenAI的ChatGPT&#xff0c;写小说&#xff0c;写代码&#xff0c;找BUG&#xff0c;写论文&#xff0c;画漫画&#xff0c;谱曲……简直没有它干不了的事。 趁着下班时间&#xff0c;我也光速注册体验了一下&#…

深度整理总结MySQL——事务专辑

事务前言什么是事务事务的特性事务的状态事务会引发什么问题&#xff1f;解决事物引发的问题手段事务日志Undo Log 日志简单介绍具体实现Buffer PoolBuffer Pool缓存什么&#xff1f;Redo Log日志为什么需要Redo Log?什么是 redo log&#xff1f;redo log要写入磁盘&#xff0…

保姆级教程:手把手教你使用 Keras 搭建神经网络

大家好&#xff0c;本文从0到1详细讲解两种基于Keras的建模方法&#xff1a; 基于Sequential的建模&#xff1b;快速方便&#xff0c;易上手 基于函数式API的建模&#xff1b;易于扩展&#xff0c;灵活性强 文章目录你会学到什么&#xff1f;技术提升导入内置数据集数据缩放和…

【GRU回归预测】基于卷积神经网络结合门控循环单元CNN-GRU实现数据多维输入单输出预测附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

ChatGPT强悍的编程能力,让我吓出一身冷汗!

最近有好几个人给我安利ChatGPT&#xff0c;说老刘快你去看看吧&#xff0c;这货实在太强了&#xff0c;搞不好我们程序员都失业了。刚开始我都是微微一笑&#xff0c;怎么可能&#xff1f;我之前的观点一直都是在我的有生之年&#xff0c;AI绝对不可能干掉程序员。但是安利的人…

一篇文章让你懂 io流

文件&#xff1a;就是保存数据的地方。文件流&#xff1a;文件在程序中是以流的形式来操作的。流&#xff1a;数据在数据源&#xff08;文件&#xff09;和程序&#xff08;内存&#xff09;之间经历的路径。输入流&#xff1a;数据从文件&#xff08;磁盘&#xff09;到Java程…

Spring-Cloud-Admin-06

前言 admin是用来监控各个服务的状况的&#xff0c;通过前台页面&#xff0c;可以查看我们各个服务的一个状态&#xff0c;是否在线&#xff0c;服务状况的一个框架。 服务端项目使用 admin有服务端和客户端&#xff0c;我们不需要每个服务都导入admin的客户端依赖&#xff0c;…

以太网 网络高可用性(链路聚合、LACP模式、静态手动模式)

2.9.0 以太网 网络高可用性&#xff08;链路聚合、LACP模式、静态手动模式&#xff09; 网络高可用性2.9.0 以太网 网络高可用性&#xff08;链路聚合、LACP模式、静态手动模式&#xff09;一、简介&#xff1a;1、单板可靠性&#xff1a;1.1、实现机柜式的可靠性提升&#xff…

Java#35(多线程扩展)

目录 一.定时器 定时器是一种控制任务延时调用, 或者周期调用的技术 1.Timer定时器(不推荐) 2.ScheduledExecutorService定时器(推荐) 二.并发与并行 三.线程状态 一.定时器 定时器是一种控制任务延时调用, 或者周期调用的技术 1.Timer定时器(不推荐) 代码示范: import …

Microsoft Store无法打开的解决办法【成功解决】

Microsoft Store无法打开解决办法我自己的解决办法其他Bug导致Microsoft Store无法打开的解决办法vpn代理问题使用TLS 1.2其他BUG解决方案成功解决之前我就有安装wsl的想法&#xff0c;但是他要求打开Microsoft Store&#xff0c;我尝试了各种办法&#xff0c;都不行。今天终于…

SpringCloud-全面详解(学习总结---从入门到深化)

​​​​​​​ 微服务架构进化论 单体应用阶段 (夫妻摊位) 在互联网发展的初期&#xff0c;用户数量少&#xff0c;一般网站的流量也很少&#xff0c;但硬 件成本较高。因此&#xff0c;一般的企业会将所有的功能都集成在一起开发 一个单体应用&#xff0c;然后将该单体应用…

Python代码加速100倍,针对Excel自动化处理的加速实战!

并发 vs 并行 说到并发编程&#xff0c;我们先来澄清一下并发 (Concurrency) 和 并行 ( Parallelism)这两个概念&#xff0c;因为这个两个概念的含义是不同的。 并行&#xff08;Parallelism&#xff09;指的就是在同一时刻&#xff0c;有两个或两个以上的任务的代码在处理器…

Spring Cloud Ribbon(负载均衡器)介绍及使用

目前主流的负载方案分为以下两种&#xff1a; 集中式负载均衡&#xff0c;在消费者和服务提供方中间使用独立的代理方式进行负载&#xff0c;有硬件的&#xff08;比如 F5&#xff09;&#xff0c;也有软件的&#xff08;比如 Nginx&#xff09;。客户端自己做负载均衡&#x…

[附源码]Python计算机毕业设计SSM基于框架的秧苗以及农产品交易网站(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

命令设计模式

一、命令模式 1、定义 命令模式&#xff08;Command Pattern&#xff09;是对命令的封装&#xff0c;每一个命令都是一个操作&#xff0c;请求方发出请求要求执行一个操作&#xff0c;接收方收到请求并执行操作。属于行为型设计模式。 命令模式通过在请求与实现之间引入一个抽…

Spring注解开发

1、Spring注解开发 1 注解开发定义Bean对象【重点】 目的&#xff1a;xml配置Bean对象有些繁琐&#xff0c;使用注解简化Bean对象的定义 问题导入 问题1&#xff1a;使用什么标签进行Spring注解包扫描&#xff1f; 问题2&#xff1a;Component注解和Controller、Service、Re…

【指纹识别】指纹识别【含GUI Matlab源码 029期】

⛄一、指纹识别简介 指纹识别技术主要分三个步骤&#xff1a;指纹预处理、特征提取、指纹分类与匹配。 无论是指纹分类还是指纹匹配,都需要提取指纹的有效特征,而特征提取的性能很大程度上要依赖于指纹图像的质量。在实际应用中,由于采集条件和采集设备的因素,采集到的指纹图像…

IBRNet:基于IBR的NeRF

IBRNet: Learning Multi-View Image-Based Rendering 针对问题&#xff1a;使NeRF具有泛化能力 如何做&#xff1a;主要还是针对颜色和密度的预测进行改进&#xff08;三维重建部分&#xff09;&#xff0c;和NeRF一样&#xff0c;使用的是volume rendering&#xff08;渲染部…

Vulkan下多线程渲染设计

1 Vulkan 视角下的多线程渲染 首先我们需要从vulkan api的顶层框架上来看一下&#xff0c;它在哪些地方可以让我们并行。 Vulkan API的基本框架 Vulkan不同于Gles只有一个&#xff08;不被API暴露出来的&#xff09;单一链条的cmdbuffer处理&#xff0c;它最大的特点是允许多…