在线时间717 小时
UID3127736
ST金币0
蝴蝶豆140
注册时间2015-5-15
论坛元老
- 最后登录
- 2020-12-3
|
a0a.1 32b0c
本帖最后由 黑皮男 于 2015-11-30 15:09 编辑
已经在论坛水了近一年了,兑换了两块开发板,但是一直没有发点有用的帖子,深感抱歉。现在深深的反省一下,把这几天调试DM9000的过程简单分享一下,希望对向我这样刚接触网卡芯片的新手作一个参考。已调通发包收包函数,并可以获取主机的MAC地址。光是模拟IO口接收就已经让我很是头疼了一阵。参考DM9000网卡芯片详细调试过程。这个在百度一搜就有,百度文库里有,这里仅仅介绍一下我自己所遇到的问题。附件直接拿来不能用,需要自己建工程然后添加进去
一、IO口模拟总线。
很多地方是用一个PORT(16bit)来模拟16位的数据总线,但是这样就不能随意配置IO口,这是我不喜欢的地方,于是参考了ST官方例程,把所需的IO口装在数组里,这样便于管理,移植起来也方便。当然,这样肯定会降低读写速度,但是对于我这样的新手来说,并不是很关心速度。
首先在头文件定义各个数据线:
#define BUS_BITS 16
#define BSP_IO15_PIN GPIO_PIN_9
#define BSP_IO15_PORT GPIOC
#define BSP_IO14_PIN GPIO_PIN_8
#define BSP_IO14_PORT GPIOB
#define BSP_IO13_PIN GPIO_PIN_9
#define BSP_IO13_PORT GPIOB
#define BSP_IO12_PIN GPIO_PIN_6
#define BSP_IO12_PORT GPIOA
#define BSP_IO11_PIN GPIO_PIN_7
#define BSP_IO11_PORT GPIOA
#define BSP_IO10_PIN GPIO_PIN_6
#define BSP_IO10_PORT GPIOB
#define BSP_IO9_PIN GPIO_PIN_7
#define BSP_IO9_PORT GPIOC
#define BSP_IO8_PIN GPIO_PIN_9
#define BSP_IO8_PORT GPIOA
#define BSP_IO7_PIN GPIO_PIN_8
#define BSP_IO7_PORT GPIOA
#define BSP_IO6_PIN GPIO_PIN_10
#define BSP_IO6_PORT GPIOB
#define BSP_IO5_PIN GPIO_PIN_4
#define BSP_IO5_PORT GPIOB
#define BSP_IO4_PIN GPIO_PIN_5
#define BSP_IO4_PORT GPIOB
#define BSP_IO3_PIN GPIO_PIN_11
#define BSP_IO3_PORT GPIOC
#define BSP_IO2_PIN GPIO_PIN_10
#define BSP_IO2_PORT GPIOA
#define BSP_IO1_PIN GPIO_PIN_2
#define BSP_IO1_PORT GPIOC
#define BSP_IO0_PIN GPIO_PIN_3
#define BSP_IO0_PORT GPIOC
在C文件中定义总线数组:
GPIO_TypeDef * BUS_PORT[BUS_BITS]={BSP_IO0_PORT, BSP_IO1_PORT, BSP_IO2_PORT, BSP_IO3_PORT, BSP_IO4_PORT, BSP_IO5_PORT, BSP_IO6_PORT, BSP_IO7_PORT, BSP_IO8_PORT, BSP_IO9_PORT, BSP_IO10_PORT, BSP_IO11_PORT, BSP_IO12_PORT, BSP_IO13_PORT, BSP_IO14_PORT, BSP_IO15_PORT};
const uint16_t BUS_PIN[BUS_BITS]={BSP_IO0_PIN, BSP_IO1_PIN, BSP_IO2_PIN, BSP_IO3_PIN, BSP_IO4_PIN, BSP_IO5_PIN, BSP_IO6_PIN, BSP_IO7_PIN, BSP_IO8_PIN, BSP_IO9_PIN, BSP_IO10_PIN, BSP_IO11_PIN, BSP_IO12_PIN, BSP_IO13_PIN, BSP_IO14_PIN, BSP_IO15_PIN};
IO初始化等略去,后面会附上源文件。
对总线写操作:
void BSP_BUS_Write16Bit(uint16_t data){
uint8_t i;
for(i = 16;i>0;i--){
if(data&0x8000)
SET_BIT(BUS_PORT[i-1]->ODR, BUS_PIN[i-1]);
else
CLEAR_BIT(BUS_PORT[i-1]->ODR, BUS_PIN[i-1]);
data=data<<1;
}
}
对总线读操作(此处有误,注意READ_BIT内对IO的读取时按数组脚标读的,论坛的编辑器吧变量i给漏掉了,添加不上):
uint16_t BSP_BUS_Read16Bit(void){
uint8_t i;
uint16_t res=0x00;
for(i=0;i<16;i++){
if(READ_BIT(BUS_PORT->IDR , BUS_PIN ))
res =res|(1<<i);
}
return res;
}
总线的读写操作就到此,还需要配置IO的输入输出模式,以便随时更改IO模式,使用了两个函数进行实现,请参考附件。
二、DM9000驱动程序(使用DM9000A)
以下关于DM9000的读写是按照时序来写的,开始的时候参照别人模拟时序,怎么都调不通, 后来仔细看了数据手册开发现读时序有问题。
DM9000 写命令:
uint16_t DM_ReadData(void)
{
uint16_t res;
DM9000_CMD_HIGH;
DM9000_CS_LOW;
DM9000_RD_LOW;
res = DM_READ_DATA(); //此句一定要放在DM9000_RD_HIGH之前
DM9000_RD_HIGH;
DM9000_CS_HIGH;
return res;
}
关于其他的读写函数请参照附件(时序都差不多)
收发包的过程函数,就请大家查看百度文库中有关的详细说明。
arp数据包结构的定义一定要按照顺序定义结构体中的每一个变量,并且要注意按照ARP数据帧结构定义每一个结构体中的变量(这涉及到数据类型对齐的问题),这个结构体会映射到一个收发缓冲数组中。
请注意arp数据包中op选项应该为: 1:arp request 2:: arp response 3:rarp request 4: rarp response
我看有人写的是0:arp request , 1: arp response.但是在TCP/IP详解卷I中是按 1:arp request 2: arp response 3:rarp request 4: rarp response定义的。
void BSP_Arp_Request(void)
{
arpbuf=(ARP_HDR *)Buffer;
memcpy(arpbuf->ethhdr.d_mac, host_mac_addr, 6);
memcpy(arpbuf->ethhdr.s_mac, mac_addr, 6);
arpbuf->ethhdr.type = HON(0x0806); //arp request/response type
arpbuf->hwtype = HON(1); //ethernet type
arpbuf->protocol = HON(0x0800);
arpbuf->hwlen = 6;
arpbuf->protolen = 4;
//arpbuf->opcode = HON(1);
arpbuf->opcode = HON(1); // 1:arp request 2:: arp response 3:rarp request 4: rarp response
memcpy(arpbuf->s_mac, mac_addr, 6);
memcpy(arpbuf->s_ipaddr, ip_addr, 4);
memcpy(arpbuf->d_ipaddr, host_ip_addr, 4);
packet_len = 42;
memcpy(TxBuffer, Buffer, 42);
DM_SendPacket(Buffer, packet_len);
}
|
-
-
22.82 KB, 下载次数: 55, 下载积分: ST金币 -1
评分
-
查看全部评分
|