DM9000网卡芯片 8bit 模式时接收数据长度错误.
本帖最后由 绿茶山人 于 2014-7-22 19:23 编辑项目需要用 51 来连接 DM9000. 所以用的是 8bit 模式.
但是写好了驱动程序, 发现发送没有问题, 接收的数据长度, 读上来的 length 一直是 96(60h) 字节. 偶尔出现 114(72h) 字节的情况,
看了下程序没有发现问题, 难道 DM9000 8bit 模式有 bug??? 或者是有假货?
谢谢大侠指点.
// DM9000 底层接收函数
uu16 dm9000a_1_prcv(uu8 *eth_head, uu8 *pdata_buf)
{
uu16i;
uu8 Rx_Byte;
uu16 Rx_Status;
uu16Rx_Len = 0;
uu8 * data_ptr;
/* Rx-ISR bit must be set. */
if (!(dm9000a_ior(DM9000A_ISR) & 0x01)) {
return 0;
}
// dm9000a_iow(DM9000A_ISR, 0x01);/* clear PR status latched in bit 0 */
dm9000a_iow(DM9000A_IMR, 0x80); // 关闭网卡中断
/*****************************************************************************************
* DM9000从网络中接到一个数据包后,会在数据包前面加上 4 个字节,分别为 “01H”、
* “status”(同RSR寄存器的值)、“LENL”(数据包长度低 8 位)、“LENH”(数据包长度高 8 位)。
* 所以首先要读取这 4 个字节来确定数据包的状态,第一个字节 “01H” 表示接下来的是有效数据包,
* 若为“00H”则表示没有数据包,若为其它值则表示网卡没有正确初始化,需要从新初始化。
* 如果接收到的数据包长度小于 60 字节,则 DM9000 会自动为不足的字节补上 0,使其达到 60 字节。
* 同时,在接收到的数据包后 DM9000 还会自动添加 4 个 CRC 校验字节。可以不予处理。
* 于是,接收到的数据包的最小长度也会是 64 字节。
******************************************************************************************/
/* Get most updated data, only look at bits 0:1, See application notes DM9000 */
dm9000a_ior(DM9000A_MRCMDX); // 第一次读取一般都是 0x00
Rx_Byte = IORD(DM9000A_DAT_ADDR_1) & 0x03; // 第二次总能读到数据
/* Status check: this byte must be 0 or 1 */
if(Rx_Byte > DM9000A_PKT_RDY) {
dm9000a_iow(DM9000A_RXCR, 0x00); /* Stop Device */
dm9000a_iow(DM9000A_ISR, 0x80);/* Stop INT request */
return 0;
}
if (Rx_Byte != DM9000A_PKT_RDY)
return 0; /* No packet received, ignore */
/* A packet ready now& Get status/length */
IOWR(DM9000A_CMD_ADDR_1, DM9000A_MRCMD); // 将 memory write cmd 写入 addr 上
Rx_Byte = IORD(DM9000A_DAT_ADDR_1);
Rx_Status = IORD(DM9000A_DAT_ADDR_1) + (IORD(DM9000A_DAT_ADDR_1) << 8);
// Rx_Len = IORD(DM9000A_DAT_ADDR_1) + (IORD(DM9000A_DAT_ADDR_1) << 8);
Rx_Len = IORD(DM9000A_DAT_ADDR_1);
Rx_Len |= (uu16)(IORD(DM9000A_DAT_ADDR_1) << 8);
data_ptr = (uu8 *)eth_head;
for (i = 0; i < sizeof(ETH_HEADER); i++) {
*data_ptr++ = IORD(DM9000A_DAT_ADDR_1);
}
/* Move data from DM9000 Read received packet from RX SRAM */
data_ptr = (uu8 *)pdata_buf;
for (i = 14; i < Rx_Len; i++) {
*data_ptr++ = IORD(DM9000A_DAT_ADDR_1);
}
dm9000a_iow(DM9000A_ISR, 0x01);/* clear PR status latched in bit 0 */
dm9000a_iow(DM9000A_IMR, 0x81); // 重新开启网卡中断接收
return Rx_Len;
}
//==============================================================================================
// 网卡初始化
static void dm9000a_init(void)
{
uu8 i = 0;
uu8 IO_Mode = 0; // IO 口 模式 8/16bit
uu32dm9000a_ID = 0; // 低 16 位: vendor ID高 16 位: product ID
uu32dm9000aphy_ID = 0;
u8 link;
u8 speed;
u8 duplex;
gio_clr(DM9000A_RST_ADDR_1);
delay_ms(5);
gio_set(DM9000A_RST_ADDR_1);
delay_ms(5);
dm9000a_iow(DM9000A_GPR, 0); // 激活内部PHY
delay_ms(20); // 延时
dm9000a_iow(DM9000A_NCR, 0x03); // 软复位第一次,mac lookback on
delay_ms(20);
dm9000aphy_iow(DM9000APHY_BMCR, 0x8000);//PHY复位
i = 0;
do {
delay_ms (1);
} while ( (i++ < 200) && !( dm9000a_ior(DM9000A_NSR) & 0x40) );
dm9000aphy_iow(DM9000APHY_ANAR, 0x01E1 | 0x0400);/* operating PHY media mode with H/W Flow-control */
dm9000aphy_iow(DM9000APHY_BMCR, 0x1200); //PHY复位
i = 0;
do {
delay_ms (1);
} while ( (i++ < 200) && !( dm9000a_ior(DM9000A_NSR) & 0x40) );
delay_ms (5);
/* set other registers depending on applications */
dm9000a_iow(DM9000A_IMR, 0x80); /* IMR enable only Pointer Auto Return for RX/TX FIFO SRAM */
dm9000a_iow(DM9000A_BPTR, 0x3f); /* BPTR REG.08(if necessary) High Water Overflow 3KB, 600us */
dm9000a_iow(DM9000A_FCTR, 0x5A); /* FCTR REG.09 (if necessary) High/ Low Threshold 5KB/ 10KB */
dm9000a_iow(DM9000A_RXTXFCR, 0x29); /* FCR REG.0AH enable TXPEN, BKPM (for TX_half), FLCE (RX) */
//dm9000a_addrset(ether_addrress); ////设置MAC地址
for (i = 0; i < 6; i++) {
dm9000a_iow(DM9000A_PAR + i, ether_addrress);
}
dm9000a_addrfilterset((uu8 *)&multimac_mcastFilter); // 设置组播模式
dm9000a_iow(DM9000A_NCR, 0); /* enable chip functions and disable loopback back to normal*/
/* clear any pending interrupt */
dm9000a_iow(DM9000A_NSR, 0x2c); /* clear NSR 3bits status: TX1END, TX2END, WAKEST by RW/C1 */
dm9000a_iow(DM9000A_ISR, 0x3F); /* clear ISR status: PR,PT, ROS,ROO, UDRUN, LNKCHG by RW/C1 */
/* enable interrupts ~go */
dm9000a_iow(DM9000A_IMR, 0x81); /* IMR REG. FFH enable PAR+ PTI+PRI+ROI+ROOI+UDRUNI+LNKCHGI */
/* enable RX Broadcast/ ALL MULTICAST to activate DM9000A ~go */
dm9000a_iow(DM9000A_RXCR, 0x31);
/* initialize the driver variables or the user passed arguments */
IO_Mode = dm9000a_ior(DM9000A_ISR); //最高位 1: 8bit0: 16bit
dm9000a_ID = dm9000a_Info(); //
// printf("DM9000A-1 Vendor ID and Product ID: %x", dm9000a_vendor_ID);
dm9000aphy_ID = dm9000aphy_Info();
// printf("DM9000A-1 PHY ID Identifier: %x", dm9000aphy_ID)
link= (dm9000a_ior(DM9000A_NSR) & 0x40) ? 1 : 0; // bit.6 = 1: link ok
speed = (dm9000a_ior(DM9000A_NSR) & 0x80) ? 10 : 100; // bit.7 = 0: 100Mbps
duplex = (dm9000a_ior(DM9000A_NCR) & 0x8) ? 1 : 0; // bit.3 = 1: Full Duplex mode
delay_ms(1);
}
发送函数没有问题, 也一并贴了吧. 大家一起学习.
//==============================================================================================
// 描述: DM9000 底层发送函数
uu8 dm9000a_1_ptran(uu8 *head, uu16 buflen, uu8 *pbuf)
{
uu32i;
uu16tx_len;
uu8 * data_ptr;
// P3 = 0x00; // 测试发送时间,大约 5ms/1500 字节
// dm9000a_iow(DM9000A_ISR, 0x02); /* Clear Tx bit in ISR */
dm9000a_iow(DM9000A_IMR, 0x80); // 关闭网卡中断
/* Move data to DM9000 TX RAM */
IOWR(DM9000A_CMD_ADDR_1, DM9000A_MWCMD); /* Prepare for TX-data */
data_ptr = (uu8 *)head;
for (i = 0; i < sizeof(ETH_HEADER); i++) {
IOWR(DM9000A_DAT_ADDR_1, *data_ptr++);
}
data_ptr = (uu8 *)pbuf;
for (i = 0; i < buflen; i++) {
IOWR(DM9000A_DAT_ADDR_1, *data_ptr++);
}
tx_len = buflen + 14;
dm9000a_iow(DM9000A_TXPLL, (tx_len) & 0xff);
dm9000a_iow(DM9000A_TXPLH, tx_len >> 8);
dm9000a_iow(DM9000A_TXCR, 1 | DM9000A_TXCR_INIT_VAL);
while((dm9000a_ior(DM9000A_NSR) & 0x0c) == 0);
dm9000a_iow(DM9000A_NSR, 0x2c);
dm9000a_iow(DM9000A_IMR, 0x81); // 重新开启网卡中断接收
// P3 = 0xFF; // 测试发送时间
return 0;
} 64应该是很正常的,如果我没记错,DM9000如果收到小于64字节的数据包,会自动填充到64字节。 javenreal 发表于 2014-7-22 16:47
64应该是很正常的,如果我没记错,DM9000如果收到小于64字节的数据包,会自动填充到64字节。 ...
关键是, ping 的时候指定了 50/100/300/500 字节后, 长度还是 96(60H, 题目描述错误了, 不好意思), 偶尔出现 114 (72H) .
搞不明白了.我晕.
页:
[1]