OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2327|回复: 3

DM9000代码 几处疑惑,想询问下

[复制链接]

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2015-3-28
在线时间
4 小时
发表于 2019-1-7 21:35:10 | 显示全部楼层 |阅读模式
1金钱
1、u8 DM9000_Init(void)函数中有如下语句,想问下0x1FFFF7E8这个地址为什么是这个值,怎么来的??
temp=*(vu32*)(0x1FFFF7E8);                                //获取STM32的唯一ID的前24位作为MAC地址后三字节
        dm9000cfg.mode=DM9000_AUTO;       
        dm9000cfg.queue_packet_len=0;
        //DM9000的SRAM的发送和接收指针自动返回到开始地址,并且开启接收中断
        dm9000cfg.imr_all = IMR_PAR|IMR_PRI;


2、如下函数红色标注部分,我疑问是DM9000_ReadReg(DM9000_MRCMDX);//假读  假读后按照代码逻辑存储器地址为自动+1个字节,
所以再次调用rxbyte=(u8)DM9000->DATA;语句时应该读取值为dm9000 rsr寄存器值,可是实际情况不是这样的,为什么?
后面的语句         DM9000->REG=DM9000_MRCMD;
                       rx_status=DM9000->DATA;
                        rx_length=DM9000->DATA;    按代码逻辑就是这个意思,为什么在这里不是这样的,很困惑?
struct pbuf *DM9000_Receive_Packet(void)
{
        struct pbuf* p;
        struct pbuf* q;
    u32 rxbyte;
        vu16 rx_status, rx_length;
    u16* data;
        u16 dummy;
        int len;

        p=NULL;
__error_retry:       
        DM9000_ReadReg(DM9000_MRCMDX);                                        //假读
        rxbyte=(u8)DM9000->DATA;                                                //进行第二次读取
        if(rxbyte)                                                                                //接收到数据
        {
                if(rxbyte>1)                                                                //rxbyte大于1,接收到的数据错误,挂了               
                {
            printf("dm9000 rx: rx error, stop device\r\n");
                        DM9000_WriteReg(DM9000_RCR,0x00);
                        DM9000_WriteReg(DM9000_ISR,0x80);                 
                        return (struct pbuf*)p;
                }
                DM9000->REG=DM9000_MRCMD;
                rx_status=DM9000->DATA;
        rx_length=DM9000->DATA;
                //if(rx_length>512)printf("rxlen:%d\r\n",rx_length);
        p=pbuf_alloc(PBUF_RAW,rx_length,PBUF_POOL);        //pbufs内存池分配pbuf
                if(p!=NULL)                                                                        //内存申请成功
        {
            for(q=p;q!=NULL;q=q->next)
            {
                data=(u16*)q->payload;
                len=q->len;
                while(len>0)
                {
                                        *data=DM9000->DATA;
                    data++;
                    len-= 2;
                }
            }
        }else                                                                                //内存申请失败
                {
                        printf("pbuf内存申请失败:%d\r\n",rx_length);
            data=&dummy;
                        len=rx_length;
                        while(len)
                        {
                                *data=DM9000->DATA;
                                len-=2;
                        }
        }       
                //根据rx_status判断接收数据是否出现如下错误:FIFO溢出、CRC错误
                //对齐错误、物理层错误,如果有任何一个出现的话丢弃该数据帧,
                //当rx_length小于64或者大于最大数据长度的时候也丢弃该数据帧
                if((rx_status&0XBF00) || (rx_length < 0X40) || (rx_length > DM9000_PKT_MAX))
                {
                        printf("rx_status:%#x\r\n",rx_status);
                        if (rx_status & 0x100)printf("rx fifo error\r\n");
            if (rx_status & 0x200)printf("rx crc error\r\n");
            if (rx_status & 0x8000)printf("rx length error\r\n");
            if (rx_length>DM9000_PKT_MAX)
                        {
                                printf("rx length too big\r\n");
                                DM9000_WriteReg(DM9000_NCR, NCR_RST);         //复位DM9000
                                delay_ms(5);
                        }
                        if(p!=NULL)pbuf_free((struct pbuf*)p);                //释放内存
                        p=NULL;
                        goto __error_retry;
                }
        }else
    {
        DM9000_WriteReg(DM9000_ISR,ISR_PTS);                        //清除所有中断标志位
        dm9000cfg.imr_all=IMR_PAR|IMR_PRI;                                //重新接收中断
        DM9000_WriteReg(DM9000_IMR, dm9000cfg.imr_all);
    }
        return (struct pbuf*)p;
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2015-3-28
在线时间
4 小时
 楼主| 发表于 2019-1-7 21:47:08 | 显示全部楼层
另外还想问下,这个当rx_length小于64或者大于最大数据长度的时候也丢弃该数据帧,64字节是怎么来的

//当rx_length小于64或者大于最大数据长度的时候也丢弃该数据帧
                if((rx_status&0XBF00) || (rx_length < 0X40) || (rx_length > DM9000_PKT_MAX))
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2019-1-8 02:11:16 | 显示全部楼层
1,看STM32中文参考手册,唯一ID存放地址,找到这个你就知道为什么了。
2,得看DM9000数据手册,然后你按你的思路修改代码,看对不对。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

0

主题

168

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
286
金钱
286
注册时间
2018-12-31
在线时间
12 小时
发表于 2019-1-8 09:06:09 | 显示全部楼层
楼主可以的!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-23 01:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表