|
本帖最后由 绿茶山人 于 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)
- {
- uu16 i;
- uu8 Rx_Byte;
- uu16 Rx_Status;
- uu16 Rx_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
- uu32 dm9000a_ID = 0; // 低 16 位: vendor ID 高 16 位: product ID
- uu32 dm9000aphy_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[i]);
- }
- dm9000a_addrfilterset((uu8 *)&multimac_mcastFilter[0]); // 设置组播模式
-
- 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: 8bit 0: 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)
- {
- uu32 i;
- uu16 tx_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;
- }
复制代码 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|