DM9006 在Lwip 下带FreeRTOS驱动

最近调试了DM9006的驱动,发现网上参考的代码较少,在F4平台上费了很久时间总是调试通了,这里贴上适合FreeRTOS加lwip的代码,为后来人提供方便,这个芯片是接FSMC几口驱动的,我也是用FSMC驱动的,当然可以特定拿出单片机的16个IO口出来,当作数据传输线进行驱动。

bsp_dm9006.c

   1 #include "bsp_dm9006.h"
   2 
   3 #include "systick.h"
   4 #include "global.h"
   5 #include "netconf.h"
   6 
   7 #include "FreeRTOS.h"
   8 #include "task.h"
   9 
  10 #ifdef UIP
  11 
  12 /* DM9006A 接收函数设置宏 */
  13 //#define Rx_Int_enable
  14 #define Max_Int_Count                    1
  15 #define Max_Broadcast_Lenth        500
  16 #define Broadcast_Jump
  17 
  18 /* DM9006A 传送函数设置宏 */
  19 #define Max_Send_Pack                    2
  20 #define Fix_Note_Address
  21 
  22 #endif
  23 
  24 /**********************************************************************************************************
  25 *                                           全局变量参数细分
  26 **********************************************************************************************************/
  27 
  28 uint8_t SendPackOk = 0;
  29 uint8_t s_FSMC_Init_Ok = 0;    // 用于指示FSMC是否初始化
  30 
  31 /*
  32 *    函数名: dm9k_udelay
  33 *    参  数: time : 延迟时间,不精确,us级别
  34 *    返  回: 无
  35 *    功  能: 延迟函数
  36 */
  37 void dm9k_udelay(uint16_t time)
  38 {
  39     CPU_TS_Tmr_Delay_US(time);
  40 }
  41 
  42 /*
  43 *    函数名: ior
  44 *    参  数: reg :寄存器地址
  45 *    返  回: 无
  46 *    功  能: 读出寄存器的值
  47 */
  48 uint8_t DM9k_ior(uint8_t reg)
  49 {
  50     NET_REG_ADDR = reg;
  51     return (NET_REG_DATA);
  52 }
  53 
  54 /*
  55 *    函数名: iow
  56 *    参  数: reg :寄存器地址
  57 *                writedata : 写入的数据
  58 *    返  回: 无
  59 *    功  能: 写DM9006AE寄存器的值
  60 */
  61 void DM9k_iow(uint8_t reg, uint8_t writedata)
  62 {
  63     NET_REG_ADDR = reg;
  64     NET_REG_DATA = writedata;
  65 }
  66 
  67 /*
  68 *    函数名: DM9k_WaitBitClear
  69 *    参  数: reg :寄存器地址
  70 *                    bit : 数据位
  71 *    返  回: 无
  72 *    功  能: 等待写寄存器完成
  73 */
  74 void DM9k_WaitBitClear(uint8_t reg, uint8_t bit)
  75 {
  76     uint32_t timeout = 10000;
  77 
  78     while (timeout--)
  79     {
  80         if (!DM9k_ior(reg) & (1 << bit))
  81             break;
  82     }
  83 }
  84 
  85 /*
  86 *    函数名: DM9k_WaitBitClear
  87 *    参  数: phy_id PHY ID
  88 *                    reg :寄存器地址
  89 *                    bit : 数据位
  90 *    返  回: 无
  91 *    功  能: 等待PHY寄存器清除完成
  92 */
  93 void DM9k_WaitPhyBitClear(uint8_t phy_id, uint8_t reg, uint8_t bit)
  94 {
  95     uint32_t timeout = 10000;
  96     
  97     while (timeout--)
  98     {
  99         if (!(dm9k_phy_read(reg, phy_id) & (1 << bit)))
 100             break;
 101     }
 102 }
 103 
 104 /*
 105 *    函数名: dm9k_hash_table
 106 *    参  数: 无
 107 *    返  回: 无
 108 *    功  能: 设置 DM9006A MAC 、 广播 、 多播 寄存器
 109 */
 110 void dm9k_hash_table(uint8_t *MacAdd)
 111 {
 112     uint8_t i;
 113 
 114 //    printf(">>DM9006A write mac:");
 115     // 设置 网卡 MAC 位置,来自於 MyHardware
 116     for(i = 0; i < 6; i++)
 117     {
 118         DM9k_iow(DM9006_REG_PAR + i, MacAdd[i]);
 119 //        printf("0x%X ",MacAdd[i]);
 120     }
 121 //    printf("\r\n");
 122     // 清除 网卡多播设置
 123     for(i = 0; i < 8; i++)                                 
 124         DM9k_iow(DM9006_REG_MAR + i, 0xff);
 125 }
 126 
 127 /*
 128 *    函数名: dm9k_reset
 129 *    参  数: 无
 130 *    返  回: 无
 131 *    功  能: 对DM9006AE进行软件复位
 132 */
 133 void dm9k_reset(void)
 134 {
 135     uint8_t data = NET_REG_ADDR; // 暂存所使用的位置 
 136     
 137     dm9k_init();
 138 
 139     NET_REG_ADDR = data; // 恢复所使用的位置
 140 
 141     SendPackOk = 0;
 142 }
 143 
 144 /*
 145 *    函数名: dm9k_phy_write
 146 *    参  数: phy_reg : 寄存器地址
 147 *                    writedata : 写入的数据
 148 *                 port : 端口编号
 149 *    返  回: 无
 150 *    功  能: 写DM9006A PHY 寄存器
 151 */
 152 void dm9k_phy_write(uint8_t phy_reg, uint16_t writedata,uint8_t port)
 153 {
 154     
 155     // 设置写入 PHY 寄存器的位置
 156     DM9k_iow(DM9006_REG_EPAR, ( phy_reg | (port << 6)) );
 157 
 158     // 设置写入 PHY 寄存器的值
 159     DM9k_iow(DM9006_REG_EPDRH, (writedata >> 8) & 0xff);
 160     DM9k_iow(DM9006_REG_EPDRL, writedata & 0xff);
 161 
 162     DM9k_iow(DM9006_REG_EPCR, 0x08);     // Clear phyxcer write command 
 163     DM9k_iow(DM9006_REG_EPCR, 0x0A);  // 将资料写入 PHY 寄存器
 164     DM9k_iow(DM9006_REG_EPCR, 0x08);  // Clear phyxcer write command
 165 
 166     // 查寻是否执行结束
 167     do {
 168         if (!(DM9k_ior(DM9006_REG_EPCR) & 0x01))
 169             break;
 170     }while(1);
 171 
 172 }
 173 
 174 /*
 175 *    函数名: dm9k_phy_read
 176 *    参  数: phy_reg : 寄存器地址
 177 *         port : 端口编号
 178 *    返  回: 无
 179 *    功  能: 读DM9006A PHY 寄存器
 180 */
 181 uint16_t dm9k_phy_read(uint8_t phy_reg,uint8_t port)
 182 {
 183     uint16_t temp;
 184     
 185     // 设置写入 PHY 寄存器的位置
 186     DM9k_iow(DM9006_REG_EPAR, ( phy_reg | (port << 6))); //  Fill the phyxcer register into REG_0C
 187 
 188     // 设置写入 PHY 寄存器的值
 189     DM9k_iow(DM9006_REG_EPCR, 0x08);  //Clear phyxcer read command 
 190     DM9k_iow(DM9006_REG_EPCR, 0x0C);  //选中PHY,发送读命令
 191     DM9k_iow(DM9006_REG_EPCR, 0x08);  //Clear phyxcer read command 
 192 
 193     while(DM9k_ior(DM9006_REG_EPCR) & 0x01);    // 查寻是否执行结束
 194 
 195     temp = (DM9k_ior(DM9006_REG_EPDRH) << 8) | (DM9k_ior(DM9006_REG_EPDRL));
 196 
 197     return temp;
 198 }
 199 
 200 /*
 201 *    函数名: DM9006_LinkStat
 202 *    参  数: 无
 203 *    返  回: 0,未连接
 204 *                1,已连接
 205 *    功  能: 获取DM9006的连接状态
 206 */
 207 uint8_t DM9006_LinkStat(void)
 208 {
 209     static uint8_t timer = 0;
 210     uint8_t linkchanged = 0;
 211     
 212     // Link Change Status.This bit is set after port 0 or 1 link changed. This bit is cleared by write 1
 213 //    linkchanged = (DM9k_ior(DM9006_REG_NSR) >> 5) & 0x01;
 214 //    printf(">>DM9006_REG_NSR  0x%X\r\n",DM9k_ior(DM9006_REG_NSR));
 215 //    printf(">>DM9006_REG_ISR  0x%X\r\n",DM9k_ior(DM9006_REG_ISR));
 216     
 217 //    printf(">>DM9006_REG_WAR  0x%X\r\n",DM9k_ior(DM9006_REG_WAR));
 218     linkchanged =(DM9k_ior(DM9006_REG_WAR) >> 2) & 0x01;
 219     if(linkchanged)
 220     {
 221         timer ++;
 222         // 清除链接查询标志位
 223         DM9k_iow(DM9006_REG_NSR, 0x20); 
 224     }
 225     // DM9006 只能记录链接状态的标志位,不能记录各个端口的连接状态
 226     if( timer % 2)
 227     {
 228         return 1;
 229     }else
 230     {
 231         return 1;
 232     }
 233     
 234 }
 235 
 236 /*
 237 *    函数名: DM9006_Set_PHYMode
 238 *    参  数: mode 模式设置
 239 *    返  回: void
 240 *    功  能: 设置DM9006的连接模式
 241 */
 242 void DM9006_Set_PHYMode(uint8_t mode)
 243 {
 244     uint16_t BMCR_Val, ANAR_Val;
 245     
 246     /* 连接模式设置
 247       0x0000 : 固定10M半双工    ANAR_Value:0x21
 248       0x0100 : 固定10M全双工    ANAR_Value:0x41
 249       0x2000 : 固定100M半双工    ANAR_Value:0x81
 250       0x2100 : 固定100M全双工    ANAR_Value:0x0101
 251       0x1000 : 自适应模式        ANAR_Value:0x01E1
 252      */
 253     switch (mode)
 254     {
 255         case DM9006_10MHD:
 256             BMCR_Val = 0x0000;
 257             ANAR_Val = 0x21;
 258             break;
 259         case DM9006_10MFD:
 260             BMCR_Val = 0x0100;
 261             ANAR_Val = 0x41;
 262             break;
 263         
 264         case DM9006_100MHD:
 265             BMCR_Val = 0x2000;
 266             ANAR_Val = 0x81;
 267             break;
 268         
 269         case DM9006_100MFD:
 270             BMCR_Val = 0x2100;
 271             ANAR_Val = 0x101;
 272             break;
 273         
 274         case DM9006_AUTO:
 275             BMCR_Val = 0x1000;
 276             ANAR_Val = 0x01E1;
 277             break;
 278     }
 279     DM9k_iow(DM9006_PHY_BMCR, BMCR_Val);
 280     DM9k_iow(DM9006_PHY_ANAR, ANAR_Val);
 281 }
 282 
 283 /*
 284 *    函数名: DM9006_Get_SpeedAndDuplex
 285 *    参  数: 无
 286 *    返  回: 0,100M半双工
 287 *                1,100M全双工
 288 *                2,10M半双工
 289 *                3,10M全双工
 290 *                  0XFF,连接失败!
 291 *    功  能: 获取DM9006的连接速度和双工模式
 292 */
 293 uint8_t DM9006_Get_SpeedAndDuplex(void)
 294 {
 295     uint8_t temp;
 296     uint8_t i = 0;
 297     
 298     //等待自动协商完成
 299     while( !(dm9k_phy_read(DM9006_PHY_BMSR & 0x0020, 0)) )
 300     {
 301         HAL_Delay(100);
 302         i++;
 303 
 304         if(i > 100)
 305             return 0xFF;                    //自动协商失败
 306     }
 307 
 308     //这里查询数据手册发现读取这两个寄存器只适合DM9000
 309     //获取DM9006的连接速度 0:100M 1:10M
 310     temp = ((DM9k_ior(DM9006_REG_NSR) >> 6) & 0x02);
 311     //获取DM9006的双工状态
 312     temp |= ((DM9k_ior(DM9006_REG_NCR) >> 3) & 0x01);
 313     
 314     //这里查询数据手册发现读取这两个寄存器只适合DM9006
 315 //    printf(">>DM9006_REG_P_INDEX  0x%X\r\n",DM9k_ior(DM9006_REG_P_INDEX));
 316 //    
 317 //    DM9k_iow(DM9006_REG_P_INDEX, 0x00); // 0 号端口
 318 //    
 319 //    printf(">>DM9006_REG_P_INDEX  0x%X\r\n",DM9k_ior(DM9006_REG_P_INDEX));
 320 //    
 321 //    DM9k_iow(DM9006_REG_P_CTRL, 0x00); // 0 号端口
 322 //    
 323 //    temp = ((DM9k_ior(DM9006_REG_P_STUS) >> 1) & 0x03);
 324 //    
 325 //    printf(">>DM9006_REG_P_STUS  0x%X\r\n",temp);
 326     
 327     return temp;
 328 }
 329 
 330 /*
 331 *    函数名: dm9k_init
 332 *    参  数: 无
 333 *    返  回: 无
 334 *    功  能: 初始化DM9006AE
 335 */
 336 void dm9k_init(void)
 337 {
 338     uint8_t temp = 0;
 339     
 340     // switch reset 
 341     DM9k_iow(DM9006_REG_SWITCHCR, 0x40); // Reset Switch Core and auto clear after 10us
 342     DM9k_WaitBitClear(DM9006_REG_SWITCHCR,6);
 343     
 344     // software reset
 345     DM9k_iow(DM9006_REG_NCR, 1);    //Software reset and auto clear after 10us.
 346     DM9k_WaitBitClear(DM9006_REG_NCR,0);
 347     
 348     /* 连接模式设置
 349       0x0000 : 固定10M半双工    ANAR_Value:0x21
 350       0x0100 : 固定10M全双工    ANAR_Value:0x41
 351       0x2000 : 固定100M半双工    ANAR_Value:0x81
 352       0x2100 : 固定100M全双工    ANAR_Value:0x0101
 353       0x1000 : 自适应模式        ANAR_Value:0x01E1
 354     */
 355     // reset & wait for PHY ready
 356     for (temp = 0; temp < 2; temp ++)
 357     {
 358         // reset & wait for PHY ready 重置 PHY 的寄存器
 359         dm9k_phy_write(DM9006_PHY_BMCR, 0x8000, temp);        //    PHY软件复位
 360         DM9k_WaitPhyBitClear(temp, DM9006_PHY_BMCR, 15);    //    等待位清除完成
 361         dm9k_phy_write(DM9006_PHY_SCR, 0x0C80, temp);       //    (Specified config)Reg 10BAST-T mode,Enable Transmit power sacing in 10BASR-T mode,MDIX mode
 362         // 设置 基本连接模式
 363         dm9k_phy_write(DM9006_PHY_BMCR, 0x1200, temp);        //    Auto-negotiation, Restart auto-negotiation
 364 //        dm9k_phy_write(DM9006_PHY_ANAR, 0x01E1, temp);        //  设置 自适应模式相容表 
 365     }
 366     
 367     // Program operating register 
 368     DM9k_iow(DM9006_REG_NCR, 0x20);     // reg.01 cleared by write 1 
 369     DM9k_iow(DM9006_REG_FCR, 0x20);     // RX Flow Control Enable 
 370 //    DM9k_iow(DM9006_REG_NCR, 0x60);     // reg.01 cleared by write 1 
 371 //    DM9k_iow(DM9006_REG_WAR, 0x20);     // Link Change Event Enable
 372 //    DM9k_iow(DM9006_REG_FCR, 0x20);     // RX Flow Control Enable 
 373 
 374 #if CHECKSUM
 375     DM9k_iow(DM9006_REG_TCSCR, 0x07);            /* TX checksum enable */
 376     DM9k_iow(DM9006_REG_RCSCSR, 0x02);            /* RX checksum enable */
 377 #if 0
 378     /* switch config */
 379     /* If using EEPROM sets switch functions,  
 380        don't execute dm9013_switch_config() function */
 381     if (db->HasEEPROM)
 382         DM9k_iow(db, DM9013_EPCR, (1<<5));/* reload EEPROM */
 383     else
 384         dm9013_switch_config(db);
 385 #endif
 386 #endif
 387     
 388 #if ENABLE_VLAN
 389     /* reset VLAN mapping table */
 390     for (i=0xB0; i<=0xBF; i++)
 391         DM9k_iow(i, 0x0F);
 392     /* reset Per-Port VID*/
 393     for(i = 0; i < 4; i++)
 394     {
 395         DM9k_iow(0x60, i);
 396         DM9k_iow(0x6E, 1);
 397     }
 398     /* reset VLAN control */
 399     DM9k_iow (VLANCR, 0);
 400     /* reset Per-Port switch control */
 401     for(i=0; i<4; i++)
 402     {
 403         DM9k_iow(0x60, i);
 404         DM9k_iow(0x61, 0);
 405         DM9k_iow(0x66, 0);
 406         DM9k_iow(0x67, 0);
 407         DM9k_iow(0x6D, 0);
 408         DM9k_iow(0x6F, 0);
 409     }
 410 #endif
 411     
 412     // Set Physical Address 
 413     dm9k_hash_table(lwipdev.mac);    // 设置 DM9006A MAC 及 多播
 414     
 415     // 基本记存器相关设置 
 416     DM9k_iow(DM9006_REG_RCR, 0x09);    //Filter all address in Hash Table. RX Enable
 417     // 开启内存自环模式,设置中断
 418     DM9k_iow(DM9006_REG_IMR, 0x83);    //(Interrupt mask reg) Enable the SRAM read/write pointer used as transmit/receive address. Enable Packet Rx/Tx Interrupt
 419 //    DM9k_iow(DM9006_REG_IMR, 0xA3);
 420     
 421 }
 422 
 423 
 424 /*
 425 *    函数名: dm9k_initnic
 426 *    参  数: 无
 427 *    返  回: 无
 428 *    功  能: 初始化DM9006AE
 429 */
 430 void dm9k_initnic(void)
 431 {
 432     uint8_t temp;
 433     
 434     //读厂商ID,产品ID,版本信息
 435     if(DM9006A_ID != dm9k_ReadID())                    /* 进行 设备ID读取判断 */
 436     {
 437         printf(">>DM9006A_ID fault 0x%X\r\n",dm9k_ReadID());
 438         return;
 439     }else
 440     {
 441         //模块检测正常, 初始化模块
 442         printf(">>DM9006A_ID true 0x%X\r\n",DM9006A_ID);
 443         dm9k_init();
 444         
 445         //读取MAC地址
 446 //        printf(">>DM9006A read DM9006_REG_PAR mac:");
 447 //        for (temp = 0; temp < 6; temp++)
 448 //        {
 449 //            lwipdev.mac[temp] = DM9k_ior(DM9006_REG_PAR + temp); //DM9006_REG_PAR
 450 //        }
 451 //        for (temp = 0; temp < 6; temp++)
 452 //        {
 453 //            printf("0x%X ",lwipdev.mac[temp]);
 454 //        }
 455 //        printf("\r\n");
 456         
 457 //        //读取内部MAC地址
 458 //        DM9k_iow(DM9006_REG_P_INDEX, 0x00);
 459 //        printf(">>DM9006A read DM9006_REG_EAD0 mac:");
 460 //        for (temp = 0; temp < 6; temp++)
 461 //        {
 462 //            lwipdev.mac[temp] = DM9k_ior(DM9006_REG_EAD0 + temp); //DM9006_REG_PAR
 463 //        }
 464 //        for (temp = 0; temp < 6; temp++)
 465 //        {
 466 //            printf("0x%X ",lwipdev.mac[temp]);
 467 //        }
 468 //        printf("\r\n");
 469     
 470     }
 471 
 472     temp = DM9006_Get_SpeedAndDuplex();    // 获取DM9006的连接速度和双工状态 
 473     if(temp != 0xFF) // 连接成功,通过串口显示连接速度和双工状态 
 474     {
 475         printf(">>DM9006 Speed:%dMbps,Duplex:%s duplex mode\r\n", (temp & 0x02) ? 10 : 100, (temp & 0x01) ? "Full" : "Half");
 476     }else
 477     {
 478         printf(">>DM9006 Establish Link Failed!\r\n");
 479     }
 480     
 481     bsp_exti_init(DM9006_INTPORT, DM9006_INTPIN, GPIO_Mode_IN, 8, 0);
 482     
 483     SendPackOk = 0;
 484 }
 485 
 486 /*
 487 *    函 数 名: bsp_exti_init
 488 *    功能说明: 使能 EXTI
 489 *    形    参: GPIOx:端口 pin 脚
 490 *    返 回 值: 无
 491 */
 492 void bsp_exti_init(GPIO_TypeDef *_GPIOx, uint32_t _pin, uint32_t _mode, uint8_t _Priority, uint8_t _SubPriority)
 493 {
 494     EXTI_InitTypeDef   EXTI_InitStructure;
 495     GPIO_InitTypeDef   GPIO_InitStructure;
 496     NVIC_InitTypeDef   NVIC_InitStructure;
 497     
 498     /* Enable GPIOG clock */
 499   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);
 500   /* Enable SYSCFG clock */
 501   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
 502     
 503       /* Configure PD1 pin as input floating */
 504   GPIO_InitStructure.GPIO_Mode = _mode;
 505   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
 506   GPIO_InitStructure.GPIO_Pin = _pin;
 507   GPIO_Init(_GPIOx, &GPIO_InitStructure);
 508     
 509     /* Connect EXTI Line0 to PG13 pin */
 510   SYSCFG_EXTILineConfig(ETH_EXTI_PORT_SOURCE, ETH_EXTI_PIN_SOURCE);
 511     
 512     /* Configure EXTI Line13 */
 513   EXTI_InitStructure.EXTI_Line = ETH_EXTI_LINE;
 514   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
 515   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // EXTI_Trigger_Rising 上升沿中断,EXTI_Trigger_Falling,下降沿沿触发
 516   EXTI_InitStructure.EXTI_LineCmd = ENABLE;
 517   EXTI_Init(&EXTI_InitStructure);
 518 
 519   /* Enable and set EXTI Line0 Interrupt to the lowest priority */
 520   NVIC_InitStructure.NVIC_IRQChannel = ETH_EXTI_IRQn;
 521   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = _Priority;
 522   NVIC_InitStructure.NVIC_IRQChannelSubPriority = _SubPriority;
 523   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 524   NVIC_Init(&NVIC_InitStructure);
 525     
 526 }
 527 
 528 /*
 529 *    函数名: ETH_NRST_PIN_LOW
 530 *    参  数: 无
 531 *    返  回: 无
 532 *    功  能:  初始化DM9006AE 复位引脚
 533 */
 534 void ETH_NRST_PIN_LOW(void)
 535 {
 536     GPIO_ResetBits(DM9006_NRSTPORT, DM9006_NRSTPIN);
 537 }
 538 
 539 /*
 540 *    函数名: ETH_NRST_PIN_HIGH
 541 *    参  数: 无
 542 *    返  回: 无
 543 *    功  能: 初始化DM9006AE 复位引脚
 544 */
 545 void ETH_NRST_PIN_HIGH(void)
 546 {
 547     GPIO_SetBits(DM9006_NRSTPORT, DM9006_NRSTPIN);
 548 }
 549 
 550 /*
 551 *    函数名: DM9006_Receive_Packet
 552 *    参  数: void
 553 *    返  回: pbuf格式的接收到的数据包
 554 *    功  能: DM9006 接收数据包
 555                     接收到的数据包存放在 DM9006 的RX FIFO中,地址为0X0C00~0X3FFF
 556                     接收到的数据包的前四个字节并不是真实的数据,而是有特定含义的
 557                     byte1:表明是否接收到数据,为0x00或者0X01,如果两个都不是的话一定要软件复位 DM9006
 558                             0x01,接收到数据
 559                             0x00,未接收到数据
 560                     byte2:第二个字节表示一些状态信息,和 DM9006 的RSR(0X06)寄存器一致的
 561                     byte3:本帧数据长度的低字节 
 562                     byte4:本帧数据长度的高字节
 563 */
 564 struct pbuf *DM9006_Receive_Packet(void)
 565 {
 566     struct pbuf* p;
 567     struct pbuf* q;
 568     u32 rxbyte;
 569     vu16 rx_status, rx_length;
 570     u16* data;
 571     u16 dummy; 
 572     int len;
 573 //    u8 err;
 574     
 575     p = NULL; 
 576     
 577 //    OSMutexPend(dm9000lock,0,&err);                 //请求互斥信号量,锁定DM9000
 578 
 579 //    DM9k_ior(DM9006_REG_MRRH);
 580 //    DM9k_ior(DM9006_REG_MRRL);
 581     
 582 __error_retry:    
 583 
 584     // 假读,读取内存数据,地址不增加
 585     DM9k_ior( DM9006_REG_MRCMDX );
 586   // 进行第二次读取
 587     //    rxbyte = NET_REG_DATA;    
 588     rxbyte = (uint8_t) DM9k_ior(DM9006_REG_MRCMDX); // 这里只识别低8位
 589     
 590     if( rxbyte == DM9006_PKT_RDY ) // 接收到数据
 591     {        
 592 //      templength = DM9k_ior(DM9006_REG_RXPLHR) << 8 | DM9k_ior(DM9006_REG_RXPLLR);
 593         // A packet ready now  & Get status/length
 594         NET_REG_ADDR = DM9006_REG_MRCMD;
 595         rx_status = NET_REG_DATA; // 只有高八位有效 &0xFF00
 596     rx_length = NET_REG_DATA;
 597         
 598 //        //if(rx_length>512)printf("rxlen:%d\r\n",rx_length);
 599     p = pbuf_alloc(PBUF_RAW,rx_length,PBUF_POOL);    //pbufs内存池分配pbuf
 600         if(p != NULL) //内存申请成功
 601      {
 602                 for(q = p;q != NULL;q = q->next)
 603                 {
 604                         data = (u16*)q->payload;
 605                         len = q->len;
 606                         while( len > 0 )
 607                         {
 608                             *data = NET_REG_DATA;
 609                             data ++;
 610                             len -= 2;
 611                         }
 612                 }
 613       }else    //内存申请失败
 614             {
 615                     printf(">>pbuf内存申请失败:%d\r\n",rx_length);
 616                     data =& dummy;
 617                     len = rx_length;
 618                     while(len)
 619                     {
 620                         *data = NET_REG_DATA;
 621                         len-=2;
 622                     }
 623        }    
 624             //根据rx_status判断接收数据是否出现如下错误:FIFO溢出、CRC错误
 625             //对齐错误、物理层错误,如果有任何一个出现的话丢弃该数据帧,
 626             //当rx_length小于64或者大于最大数据长度的时候也丢弃该数据帧
 627             if( (rx_length < 0x40) || (rx_length > Max_Ethernet_Lenth)) // (rx_status & 0XBF00) || 
 628             {
 629                 printf(">>dm9006 rx_status:%#x\r\n",rx_status);
 630                 if (rx_status & 0x100)
 631                     printf(">>dm9006 rx fifo error\r\n");
 632                 if (rx_status & 0x200)
 633                     printf(">>dm9006 rx crc error\r\n");
 634                 if (rx_status & 0x8000)
 635                     printf(">>dm9006 rx length error\r\n");
 636                 
 637                 if (rx_length > Max_Ethernet_Lenth)
 638                 {
 639                     printf(">>dm9006 rx length too big\r\n");
 640                     DM9k_iow(DM9006_REG_NCR, NCR_RST);     //复位DM9006
 641                     HAL_Delay(5);
 642                 }
 643                 if(p != NULL)
 644                     pbuf_free((struct pbuf*)p);        //释放内存
 645                 p = NULL;
 646                 goto __error_retry;
 647             }    
 648      }else
 649    {
 650          if( rxbyte > 1 )// rxbyte大于1,接收到的数据错误,挂了        
 651             {
 652                 printf(">>dm9006 rx: rx error, stop device 0x%X\r\n",rxbyte);
 653                 
 654                 DM9k_iow(DM9006_REG_RCR,0x00);
 655                 DM9k_iow(DM9006_REG_ISR,0x80);         
 656     //            DM9k_iow(DM9006_REG_RCR,0x09);
 657     //            DM9k_iow(DM9006_REG_ISR,0x83);         
 658                 
 659                 return (struct pbuf*)p;
 660             }
 661          if(rxbyte == DM9006_PKT_NORDY)    // 0x00,未收到包
 662             {
 663 //              printf(">>dm9006 Not yet received data package\r\n");
 664                 // 清除所有中断标志位
 665                 DM9k_iow(DM9006_REG_ISR, ISR_LKNCHG | ISR_UDRUN | ISR_ROO | ISR_ROS | ISR_PT | ISR_PR);    
 666             }else
 667             {
 668 //                dm9k_reset();
 669                 DM9k_iow(DM9006_REG_ISR,ISR_PT);            //清除所有中断标志位
 670                 DM9k_iow(DM9006_REG_IMR, IMR_PAR | IMR_PRI);    // 重新开启 DM9006A 中断
 671             }
 672    }
 673      
 674 //    OSMutexPost(dm9000lock);                            //发送互斥信号量,解锁DM9000
 675     return (struct pbuf*)p; 
 676 }
 677 
 678 /*
 679 *    函数名: dm9k_ReadID
 680 *    参  数: 无
 681 *    返  回: 无
 682 *    功  能: 读取芯片ID
 683 */
 684 uint32_t dm9k_ReadID(void)
 685 {
 686     uint8_t vid1, vid2, pid1, pid2;
 687 
 688     if(s_FSMC_Init_Ok == 0)
 689     {
 690         DM9K_CtrlLinesConfig();
 691         DM9K_FSMCConfig();
 692 
 693         s_FSMC_Init_Ok = 1;
 694     }
 695 
 696     vid1 = DM9k_ior(DM9006_REG_VID_L) & 0xFF;
 697     vid2 = DM9k_ior(DM9006_REG_VID_H) & 0xFF;
 698     pid1 = DM9k_ior(DM9006_REG_PID_L) & 0xFF;
 699     pid2 = DM9k_ior(DM9006_REG_PID_H) & 0xFF;
 700 
 701     return (pid2 << 24) | (pid1 << 16) | (vid2 << 8) | vid1;
 702 }
 703 
 704 /*
 705 *    函数名: etherdev_init
 706 *    参  数: 无
 707 *    返  回: 无
 708 *    功  能: uIP 接口函数,初始化网卡
 709 */
 710 void etherdev_init(void)
 711 {
 712     DM9K_CtrlLinesConfig();
 713     DM9K_FSMCConfig();
 714 
 715     s_FSMC_Init_Ok = 1;
 716 
 717     dm9k_initnic();
 718 }
 719 
 720 /*
 721 *    函数名: DM9006AE_CtrlLinesConfig
 722 *    参  数: 无
 723 *    返  回: 无
 724 *    功  能: 配置DM9000AE控制口线,FSMC管脚设置为复用功能 (For SMT32F4)
 725 */
 726 static void DM9K_CtrlLinesConfig(void)
 727 {
 728     GPIO_InitTypeDef GPIO_InitStructure;
 729 
 730     /* 使能FSMC时钟 */
 731     RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);
 732     /* 使能 GPIO时钟 */
 733     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG, ENABLE);
 734 
 735     /* 设置 PD.00(D2), PD.01(D3), PD.04(NOE), PD.05(NWE), PD.08(D13), PD.09(D14),
 736      PD.10(D15), PD.14(D0), PD.15(D1) 为复用推挽输出 */
 737 
 738     GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC);
 739     GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
 740     GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
 741     GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);
 742     GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC);
 743     GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC);
 744     GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC);
 745     GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
 746     GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);
 747     
 748     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
 749                                 GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 |
 750                                 GPIO_Pin_15;
 751     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 752     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
 753     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 754     GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
 755     GPIO_Init(GPIOD, &GPIO_InitStructure);
 756     
 757     /* 设置 PE.07(D4), PE.08(D5), PE.09(D6), PE.10(D7), PE.11(D8), PE.12(D9), PE.13(D10),
 758      PE.14(D11), PE.15(D12) 为复用推挽输出 */
 759     
 760     GPIO_PinAFConfig(GPIOE, GPIO_PinSource4 , GPIO_AF_FSMC);
 761     GPIO_PinAFConfig(GPIOE, GPIO_PinSource5 , GPIO_AF_FSMC);
 762 
 763     GPIO_PinAFConfig(GPIOE, GPIO_PinSource7 , GPIO_AF_FSMC);
 764     GPIO_PinAFConfig(GPIOE, GPIO_PinSource8 , GPIO_AF_FSMC);
 765     GPIO_PinAFConfig(GPIOE, GPIO_PinSource9 , GPIO_AF_FSMC);
 766     GPIO_PinAFConfig(GPIOE, GPIO_PinSource10 , GPIO_AF_FSMC);
 767     GPIO_PinAFConfig(GPIOE, GPIO_PinSource11 , GPIO_AF_FSMC);
 768     GPIO_PinAFConfig(GPIOE, GPIO_PinSource12 , GPIO_AF_FSMC);
 769     GPIO_PinAFConfig(GPIOE, GPIO_PinSource13 , GPIO_AF_FSMC);
 770     GPIO_PinAFConfig(GPIOE, GPIO_PinSource14 , GPIO_AF_FSMC);
 771     GPIO_PinAFConfig(GPIOE, GPIO_PinSource15 , GPIO_AF_FSMC);
 772 
 773     GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
 774                                 GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
 775                                 GPIO_Pin_15; // GPIO_Pin_4 | GPIO_Pin_5 | 
 776     GPIO_Init(GPIOE, &GPIO_InitStructure);
 777 
 778     /* 设置 PD.13(A18 (RS))  为复用推挽输出 */
 779     GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_FSMC);
 780 
 781     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
 782     GPIO_Init(GPIOD, &GPIO_InitStructure);
 783 
 784     /* 设置 PG10 (CS)) 为复用推挽输出 */
 785     GPIO_PinAFConfig(GPIOG, GPIO_PinSource10, GPIO_AF_FSMC);
 786 
 787     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
 788     GPIO_Init(GPIOG, &GPIO_InitStructure);
 789 
 790     /* PB12 是DM9006_NRST复位输入口(本程序使用) */
 791     GPIO_InitStructure.GPIO_Pin   = DM9006_NRSTPIN;
 792     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;     // 普通输出模式
 793     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;     // 推挽输出
 794     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 100MHz
 795     GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
 796     GPIO_Init(DM9006_NRSTPORT, &GPIO_InitStructure);                         // 初始化
 797 
 798   // 对DM9006进行硬件复位
 799     ETH_NRST_PIN_LOW();//    硬件复位
 800     HAL_Delay(30);
 801     ETH_NRST_PIN_HIGH(); // 硬件复位结束
 802     HAL_Delay(30); //    等待DM9006准备就绪
 803     
 804     // PG13 是DM9006_INT中断输入口(本程序使用) 
 805 
 806 }
 807 
 808 /*
 809 *    函数名: DM9K_FSMCConfig
 810 *    参  数: 无
 811 *    返  回: 无
 812 *    功  能: 配置FSMC并口访问时序
 813 */
 814 static void DM9K_FSMCConfig(void)
 815 {
 816     FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
 817     FSMC_NORSRAMTimingInitTypeDef  readWriteTiming;
 818 
 819     /*-- FSMC Configuration ------------------------------------------------------*/
 820     /*----------------------- SRAM Bank 3 ----------------------------------------*/
 821     /*-- FSMC Configuration ------------------------------------------------------*/
 822     readWriteTiming.FSMC_AddressSetupTime = 3;    // 6 设置为2会出错; 3正常 地址建立时间(ADDSET)为1个HCLK 1/36M=27ns
 823     readWriteTiming.FSMC_AddressHoldTime = 2;   // 地址保持时间(ADDHLD)模式A未用到
 824     readWriteTiming.FSMC_DataSetupTime = 4;            // 设置为1出错,2正常 数据保持时间(DATAST)为9个HCLK 6*9=54ns
 825     readWriteTiming.FSMC_BusTurnAroundDuration = 1;
 826     readWriteTiming.FSMC_CLKDivision = 0;
 827     readWriteTiming.FSMC_DataLatency = 0;
 828     readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A; //模式A
 829 
 830     FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;  // 这里我们使用NE3,也就对应BTCR[4],[5]
 831     FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
 832     FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;    // FSMC_MemoryType_PSRAM;
 833     FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; // 存储器数据宽度为16bit
 834     FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
 835     FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
 836     FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
 837     FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
 838     FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
 839     FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; // 存储器写使能
 840     FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
 841     FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; // 读写使用相同的时序
 842     FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
 843     
 844     FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming;
 845     FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &readWriteTiming; //读写同样时序
 846 
 847     FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); // 初始化FSMC配置
 848     /*!< Enable FSMC Bank1_SRAM3 Bank */
 849     FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE); // 使能BANK3
 850     
 851 }
 852 
 853 #ifdef UIP
 854 
 855 /*
 856 *    函数名: dm9k_send_packet
 857 *    参  数: p_char : 发送数据缓冲区
 858 *            length : 数据长度
 859 *    返  回: 无
 860 *    功  能: 发送一包数据
 861 */
 862 void dm9k_send_packet(uint8_t *p_char, uint16_t length)
 863 {
 864     uint16_t SendLength = length;
 865     uint16_t *SendData = (uint16_t *) p_char;
 866     uint16_t i;
 867     uint16_t calc_len;
 868     __IO uint16_t calc_MWR;
 869 
 870 #ifdef FifoPointCheck
 871     /* 计算下一个传送的指针位 , 若接收长度为奇数,需加一对齐偶字节。*/
 872     /* 若是超过 0x0bff ,则需回归绕到 0x0000 起始位置 */
 873     calc_MWR = (DM9k_ior(DM9006_REG_MWRH) << 8) + DM9k_ior(DM9006_REG_MWRL);
 874     calc_MWR += SendLength;
 875 
 876     if(SendLength & 0x01) calc_MWR++;
 877 
 878     if(calc_MWR > 0x0bff) calc_MWR -= 0x0c00;
 879 
 880 #endif
 881 
 882     DM9k_iow(DM9006_REG_IMR, DM9006_IMR_OFF);            // 关闭 DM9006A 中断 
 883     
 884     // 设置传送封包的长度
 885     DM9k_iow(DM9006_REG_TXPLH, (SendLength >> 8) & 0xff);    
 886     DM9k_iow(DM9006_REG_TXPLL, SendLength & 0xff);
 887 
 888     // 开始将系统的资料搬到到内存中,每次移动一个 word
 889     NET_REG_ADDR = DM9006_REG_MWCMD;
 890     calc_len = (SendLength + 1) >> 1;
 891 
 892     for(i = 0; i < calc_len; i++)
 893     {
 894         NET_REG_DATA = SendData[i];    
 895     }
 896 
 897     // 进行传送
 898     DM9k_iow(DM9006_REG_TCR, DM9006_TCR_SET);            
 899   DM9k_iow(DM9006_REG_IMR, 0x83);    // 开启 DM9006A 中断    
 900 //    DM9k_iow(DM9006_REG_IMR, 0xA3);
 901 
 902 #ifdef FifoPointCheck
 903 
 904     if(calc_MWR != ((DM9k_ior(DM9006_REG_MWRH) << 8) + DM9k_ior(DM9006_REG_MWRL)))
 905     {
 906 #ifdef Point_Error_Reset
 907 
 908         /* 若是指针出错,等待此一封包送完 , 之後进行重置 */
 909         while(DM9k_ior(DM9006_REG_TCR) & DM9006_TCR_SET) dm9k_udelay(5);
 910 
 911         dm9k_reset();
 912         return;
 913 #endif
 914         /*若是指针出错,将指针移到下一个传送包的包头位置  */
 915         DM9k_iow(DM9006_REG_MWRH, (calc_MWR >> 8) & 0xff);
 916         DM9k_iow(DM9006_REG_MWRL, calc_MWR & 0xff);
 917     }
 918 
 919 #endif
 920     return;
 921 }
 922 
 923 /*
 924 *    函数名: dm9k_receive_packet
 925 *    参  数: _uip_buf : 接收缓冲区
 926 *    返  回: > 0 表示接收的数据长度, 0表示没有数据
 927 *    功  能: 读取一包数据
 928 */
 929 uint16_t dm9k_receive_packet(uint8_t *_uip_buf)
 930 {
 931     uint16_t ReceiveLength;
 932     uint16_t *ReceiveData;
 933     uint8_t  rx_int_count = 0;
 934     uint8_t  rx_checkbyte;
 935     uint16_t rx_status, rx_length;
 936     uint8_t  jump_packet;
 937     uint16_t i;
 938     uint16_t calc_len;
 939     uint16_t calc_MRR;
 940 
 941     do
 942     {
 943         ReceiveLength = 0;            // 清除接收的长度
 944         ReceiveData = (uint16_t *)_uip_buf;
 945         jump_packet = 0;                // 清除跳包动作
 946         DM9k_ior(DM9006_REG_MRCMDX);    // 读取内存数据,地址不增加
 947         
 948         // 计算内存数据位置 
 949         calc_MRR = (DM9k_ior(DM9006_REG_MRRH) << 8) + DM9k_ior(DM9006_REG_MRRL);
 950         rx_checkbyte = DM9k_ior(DM9006_REG_MRCMDX);
 951 
 952         if(rx_checkbyte == DM9006_PKT_RDY)                /**/
 953         {
 954             // 读取封包相关资讯 及 长度
 955             NET_REG_ADDR = DM9006_REG_MRCMD;
 956             rx_status = NET_REG_DATA;
 957             rx_length = NET_REG_DATA;
 958 
 959             // 若收到超过系统可承受的封包,此包跳过
 960             if(rx_length > Max_Ethernet_Lenth)
 961                 jump_packet = 1;
 962 
 963 #ifdef Broadcast_Jump
 964             // 若收到的广播或多播包超过特定长度,此包跳过
 965             if(rx_status & 0x4000)
 966             {
 967                 if(rx_length > Max_Broadcast_Lenth)
 968                     jump_packet = 1;
 969             }
 970 #endif
 971             // 计算下一个包的指针位 , 若接收长度为奇数,需加一对齐偶字节
 972             // 若是超过 0x3fff,则需回归绕到 0x0c00 起始位置
 973             calc_MRR += (rx_length + 4);
 974 
 975             if(rx_length & 0x01) calc_MRR ++;
 976 
 977             if(calc_MRR > 0x3fff) calc_MRR -= 0x3400;
 978 
 979             if( jump_packet == 0x01 )
 980             {
 981                 // 将指针移到下一个包的包头位置
 982                 DM9k_iow(DM9006_REG_MRRH, (calc_MRR >> 8) & 0xff);
 983                 DM9k_iow(DM9006_REG_MRRL, calc_MRR & 0xff);
 984                 continue;
 985             }
 986 
 987             // 开始将内存的资料搬到到系统中,每次移动一个 word
 988             calc_len = (rx_length + 1) >> 1;
 989 
 990             for(i = 0 ; i < calc_len ; i++)
 991                 ReceiveData[i] = NET_REG_DATA;
 992 
 993             // 将包长回报给 TCP/IP 上层,并减去最後 4 BYTE 的 CRC-32 检核码
 994             ReceiveLength = rx_length - 4;
 995 
 996             rx_int_count++;                                /* 累计收包次数 */
 997 
 998 #ifdef FifoPointCheck
 999 
1000             if(calc_MRR != ((DM9k_ior(DM9006_REG_MRRH) << 8) + DM9k_ior(DM9006_REG_MRRL)))
1001             {
1002 #ifdef Point_Error_Reset
1003                 dm9k_reset();                                /* 若是指针出错,重置 */
1004                 return ReceiveLength;
1005 #endif
1006                 /*若是指针出错,将指针移到下一个包的包头位置  */
1007                 DM9k_iow(DM9006_REG_MRRH, (calc_MRR >> 8) & 0xff);
1008                 DM9k_iow(DM9006_REG_MRRL, calc_MRR & 0xff);
1009             }
1010 
1011 #endif
1012             return ReceiveLength;
1013         }else
1014         {
1015             if(rx_checkbyte == DM9006_PKT_NORDY)        /* 未收到包 */
1016             {
1017                 DM9k_iow(DM9006_REG_ISR, 0x3f);                /*  */
1018             }else
1019             {
1020                 dm9k_initnic();                                // 接收指针出错,重置
1021             }
1022 
1023             return (0);
1024         }
1025     } while(rx_int_count < Max_Int_Count); // 是否超过最多接收封包计数
1026 
1027     return 0;
1028 }
1029 
1030 /*
1031 *    函数名: etherdev_send
1032 *    参  数: p_char : 数据缓冲区
1033 *            length : 数据长度
1034 *    返  回: 无
1035 *    功  能: uIP 接口函数,发送一包数据
1036 */
1037 void etherdev_send(uint8_t *p_char, uint16_t length)
1038 {
1039     dm9k_send_packet(p_char, length);
1040 }
1041 
1042 /*
1043 *    函数名: etherdev_read
1044 *    参  数: p_char : 数据缓冲区
1045 *    返  回: 无
1046 *    功  能: uIP 接口函数,发送一包数据
1047 */
1048 uint16_t etherdev_read(uint8_t *p_char)
1049 {
1050     return dm9k_receive_packet(p_char);
1051 }
1052 
1053 /*
1054 *    函数名: etherdev_chkmedia
1055 *    参  数: 无
1056 *    返  回: 无
1057 *    功  能: uIP 接口函数, 检测网络连接状态
1058 */
1059 void etherdev_chkmedia(void)
1060 {
1061 //    uint8_t status;
1062 
1063     while( !(DM9k_ior( DM9006_REG_NSR) & DM9006_PHY) )
1064     {
1065         dm9k_udelay(2000);
1066     }
1067 }
1068 
1069 #endif

bsp_dm9006.h

  1 #define EPCR_EETYPE            (1<<7)                                            //    EEPROM Type 0:3C46    1:93C56
  2 #define EPCR_REEP                (1<<5)                                            //    Reload EEPROM.Driver needs to clear it up after the operation completes
  3 #define EPCR_WEP                (1<<4)                                            //    Write EEPROM Enable
  4 #define EPCR_EPOS                (1<<3)                                            //    EEPROM or PHY Operation Select
  5 #define EPCR_ERPRR            (1<<2)                                            //    EEPROM Read or PHY Reister Read Command
  6 #define EPCR_ERORW            (1<<1)                                            //     EEPROM Write or PHY Register Write Command
  7 #define EPCR_ERRE                (1<<0)                                            //     EEPROM Access Status or PHY Access Status
  8 /*EEPROM & PHY Address Register*/
  9 #define EPAR_PHY_ADR        (3<<6)                                            //     PHY Address bit 1 and 0; the PHY address bit[4:2] is force to 0
 10 #define EPAR_EPOA                (0x1F)                                            //    EEPROM Word Address or PHY Register Address
 11 /*EEPROM & PHY Data Register*/
 12 #define EPDR_EPDR                (0xFF)
 13 /*Link Change Control Register*/
 14 #define LCCR_LINKEN            (1<<5)                                            //    Link Change Event Enable
 15 #define LCCR_LINKST            (1<<2)                                            //     Link Change Event Status
 16 /*Processor Port Physical Address Register*/
 17 #define PPPAR_PAB5            (0xFF)                                        
 18 #define PPPAR_PAB4            (0xFF)
 19 #define PPPAR_PAB3            (0xFF)
 20 #define PPPAR_PAB2            (0xFF)
 21 #define PPPAR_PAB1            (0xFF)
 22 #define PPPAR_PAB0            (0xFF)
 23 /*Processor Port Multicast Address Register*/
 24 #define PPMAR_MAB7            (0xFF)
 25 #define PPMAR_MAB6            (0xFF)
 26 #define PPMAR_MAB5            (0xFF)
 27 #define PPMAR_MAB4            (0xFF)
 28 #define PPMAR_MAB3            (0xFF)
 29 #define PPMAR_MAB2            (0xFF)
 30 #define PPMAR_MAB1            (0xFF)
 31 #define PPMAR_MAB0            (0xFF)
 32 /*RX Packet Length Low Register*/
 33 #define RXPLLR_RXPLL        (0xFF)
 34 /*RX Packet Length High Register*/
 35 #define RXPLHR_RXPLH        (0xFF)
 36 /*RX Additional Status Register*/
 37 #define RXASR_RPTRS            (3<<0)
 38 /*RX Additional Control Register*/
 39 #define RXACR_RPRD            (1<<7)                                            //    RX Pointer Restriction Disable
 40 /*Verdor ID Registers*/
 41 #define VIDR_VIDH                (0xFF)                                            //    Verdor ID High Byte
 42 #define VIDR_VIDL                (0xFF)                                            //    Verdor ID Low Byte
 43 /*Product ID Register*/
 44 #define PIDR_PIDH                (0xFF)
 45 #define PIDR_PIDL                (0xFF)
 46 /*Chip Revision Register*/
 47 #define CRR_PR                    (0xFF)                                            //    CHIP Revision
 48 /*Transmit Check Sum Control Register*/
 49 #define TCSCR_UDPCSE        (1<<2)                                            //    UDP Checksum Generation Enable
 50 #define TCSCR_TCPCSE        (1<<1)                                            //    TCP_Checksum Generation Enable
 51 #define TCSCR_IPCSE            (1<<0)                                            //    IP Chechsum Generation Enable
 52 /*Recevice Check Sum Control Status Register*/
 53 #define RCCSR_UDPS            (1<<7)                                            //    UDP Checksum Status.1:UDP Packet Checksum is Fail;0:UDP Packet Checksum is OK or it is not a UDP Packet
 54 #define RCCSR_TCPS            (1<<6)                                            //    TCP Checksum Status.1:TCP Packet Checksum is Fail;0:TCP Packet Checksum is OK or it is not a TCP Packet
 55 #define RCCSR_IPS                (1<<5)                                            //    IP Checksum Status.1:IP Packet Checksum is Fail;0:IP Packet Checksum is OK or it is not a IP Packet
 56 #define RCCSR_UDPP            (1<<4)                                            //    This is an UDP Packet
 57 #define RCCSR_TCPP            (1<<3)                                            //    This is a TCP Packet
 58 #define RCCSR_IPP                (1<<2)                                            //    This is a an Packet
 59 #define RCCSR_RCSEN            (1<<1)                                            //    Receive Checksum Checking Enable
 60 #define RCCSR_DCSE            (1<<0)                                            //    Discard Checksum Error Packet
 61 /*Up Data Bus Driving Capability Register*/
 62 #define UDBCR_ISA_CURR    (3<<5)                                            //    SD Bus Current Driving/Sinking Capability
 63 #define UDBCR_STEP            (1<<2)                                            //    Data Bus Output Stepping
 64 #define UDBCR_IOW_SPIKE    (1<<1)                                            //    Eliminate IOW Spike
 65 #define UDBCR_IOR_SPIKE    (1<<0)                                            //    Eliminate IOR Spike
 66 /*IRQ Pin Control Register*/
 67 #define IRQPCR_DELAY        (7<<5)                                            //    IRQ Delayed Output Interval
 68 #define IRQPCR_TYPE            (1<<1)                                            //    IRQ Pin Output Type Control.1:IRQ Open-collector output;0:IRQ Direct Output
 69 #define IRQPCR_POL            (1<<0)                                            //    IRQ Pin Polarity Control.1:IRQ Active Low;0:IRQ Active High
 70 /*TX/RX Memory Size Control Register*/
 71 #define TRMSCE_TX_SIZE    (0x1F)
 72 /*
 73     TX Block Size
 74     This Value Defines the Transmit Block Size In 256-Byte unit.
 75     TX Memory Size = TX_SIZE * 256 Bytes
 76     And Then
 77     RX Memory Size = 16KB - (TX_SIZE + 1) * 256-Byte
 78     Note:The Value of TX_SIZE Should be Between 14H and 30H
 79     NOte2:If the Default Value is Changed, the reset switch command(REG52H bit 6)Should be set to initialize DM9006 Memory Allocation
 80 */
 81 /*Switch Control Register*/
 82 #define SCR_MEM_BIST        (1<<7)                                            //    Address Memory Test BIST Status
 83 #define SCR_RST_SW            (1<<6)                                            //    Reset Switch Core and Auto Clear After 10us
 84 #define SCR_RST_ANLG        (1<<5)                                            //    Reset Analog PHY Core and Auto Clear After 10us
 85 #define SCR_SNF_PORT        (3<<3)                                            //    Sniffer Port Number
 86 #define SCR_CRC_DIS            (1<<2)                                            //    CRC Checking Disable
 87 /*VLAN Control Register*/
 88 #define VLCR_TOS6                (1<<7)                                            //    Full ToS Using Enable
 89 #define VLCR_UNICASR        (1<<5)                                            //    Unicast Packet Can Across VLAN Boundary
 90 #define VLCR_VIDFFF            (1<<4)                                            //    Replace VID FFF
 91 #define VLCR_VID1                (1<<3)                                            //    Replace VID 001
 92 #define VLCR_VID0                (1<<2)                                            //    Replace VID    000
 93 #define VLCR_PRI                (1<<1)                                            //    Replace priority field in the tag with value define in Reg 6FH bit 7~5
 94 #define VLCR_VLAN                (1<<0)                                            //    VLAN Mode Enable
 95 /*DSP PHY Control Register*/
 96 #define DSPCR_DSP_CTL1    (0xFF)                                            //    DSP Control Register 1 for testing only(58H)
 97 #define DSPCR_DSP_CTL2    (0xFF)                                            //    DSP Control Register 2 for testing only(59H)
 98 /*Per Port Control/Status Index Register*/
 99 #define PCSIR_IDX                (3<<0)                                            //    Port Index For Register 61H~84H
100 /*Per Port Control Data Register*/
101 #define PCDR_FAST_LEV        (1<<7)                                            //    IGMP Snooping Fast Leave Enable
102 #define PCDR_PARTI_EN        (1<<6)                                            //    Enable Partition Detection
103 #define PCDR_NO_DIS_RX    (1<<5)                                            //    Don't Discard RX Packets when Ingress Bandwidth Control
104 #define PCDR_FLOW_DIS        (1<<4)                                            //    Flow Control In Full Duplex Mode, or back Presure In Half Duplex Mode Enable.0:Enable, 1:Diasble
105 #define PCDR_BANDWIDTH    (1<<3)                                            //    Bandwidth Control.0:Control with Ingress and Egress separately, ref to Register 66H;1:Control with Ingress or Egress, ref to Register 67H
106 #define PCDR_BP_DIS            (1<<2)                                            //    Broadcasr Packet Filter.0:Accept Broadcast Packets;1:Reject Broadcast Packets
107 #define PCDR_MP_DIS            (1<<1)                                            //    Multicast Packet Filter.0:Accept Multicast Packet;1:Reject Multicast Packets
108 #define PCDR_MP_STORM        (1<<0)                                            //    Broadcast Storm Control.0:Only Broadcast Packets Storm are Controlled;1:Multicast packets also same as broadcast storm control
109 /*Per Port Status Data Register*/
110 #define PSDR_LP_FCS            (1<<5)                                            //    Link Partner Flow Control Enable Status
111 #define PSDR_BIST                (1<<4)                                            //    BIST Status.1:SRAM BIST Fail;0:SRAM BIST Pass
112 #define PSDR_SPEED2            (1<<2)                                            //    PHY Speed Status.0:10Mbps;1:100Mbps
113 #define PSDR_FDX2                (1<<1)                                            //    PHY Duplex Status.0:half-duplex;1:full-duplex
114 #define PSDR_LINK2            (1<<0)                                            //    PHY Link Status.0:Link Fail; 1:Link OK
115 /*Per Port Forward Control Register*/
116 #define PFCR_LOOPBACK        (1<<7)                                            //    Loop-Back Mode
117 #define PFCR_MONI_TX        (1<<6)                                            //    TX Packet Monitored
118 #define PFCR_MONI_RX        (1<<5)                                            //    RX Packet Monitored
119 #define PFCR_DISC_BMP        (1<<4)                                            //    Broad/Multicast not Monitored
120 #define PFCR_TX_DIS            (1<<2)                                            //    Packet Transmit Disabled
121 #define PFCR_RX_DIS            (1<<1)                                            //    Packet Receive Disabled
122 #define PFCR_ADR_DIS        (1<<0)                                            //    Address Learning Disabled,
123 /*Per Port Ingress and Egress Control Register*/
124 #define PPIECR_IGS            (0x0F<<4)                                        //    Ingress Rate Control
125 #define PIECR_EGS                (0x0F)                                            //    Egress Rate Control
126 /*Per Port Bandwidth Control Setting Register*/
127 #define PBCSR_BSTH            (0x0F<<4)                                        //    Broad Storm Threshold
128 #define PBCSR_BW_CTRL        (0x0F)                                            //    Received Pakcer Length Counted.Bandwidth Table Below
129 /*Per Port Block Unicast Ports Control Register*/
130 #define PBUPCR_BLK_UP        (0x0F)                                            //    Ports of Unicast Packet Be Blocked
131 /*Per Port Block Multicast Ports Control Register*/
132 #define PBMPCR_BLK_MP        (0x0F)                                            //    Ports of Multicast Packet Be Blocked
133 /*Per Port Block Broadcast Ports Control Register*/
134 #define PBBPCR_BLK_BP        (0x0F)                                            //    Ports of Broadcast Packet Be Blocked
135 /*Per Port Security & STP Register*/
136 #define PSSR_STPS                (3<<4)                                            //    Spanning Tree State
137 #define PSSE_PS_UNK            (1<<2)                                            //    Unknown Source Address Handling When Port Security is Enabled.0:Discardd Unknown(Default);1:Unknown to UP Port
138 #define PSSE_PS_EN            (3<<0)                                            //    Port Security Enable.00:Port Security Disable(Default);1:First Lock;2:First Link Lock;3:Assign Lock
139 /*Per Port Priority Queue Control Register*/
140 #define PPQCR_TAG_OUT        (1<<7)                                            //    Output Packet Tagging Enable
141 #define PPQCR_PRI_DIS        (1<<6)                                            //    Priority Queue Disable
142 #define PPQCR_WFQUE            (1<<5)                                            //    Weighted Round_Robin Queuing
143 #define PPQCR_TOS_PRI        (1<<4)                                            //    Priority ToS Over VLAN
144 #define PPQCR_TOS_OFF        (1<<3)                                            //    ToS Priority Classification Disable
145 #define PPACR_PRI_OFF        (1<<2)                                            //    802.1 p Priority Classification Disable
146 #define PPACR_P_PRI            (3<<0)                                            //    Port Base Priority 
147 /*Per Port VLAN Tag Low Byte Register*/
148 #define PVTLB_VID70            (0xFF)                                            //    VID[7:0]
149 /*Per Port VLAN Tag High Byte Register*/
150 #define PVTHB_PRI                (0x07<<5)                                        //    Tag[15:13]
151 #define PVTHB_CFI                (1<<4)                                            //    Tag[12]
152 #define PVTHB_VID118        (0x0F)                                            //    VID[11:8]
153 /*Ethernet Address Control/Status Register1*/
154 #define EACS_EACS                (3<<5)                                            //    Status of Ethernet Address Command.00:Command OK,Entry Non-Exist;01:Command OK,Entry Exist;1X:Command Error
155 #define EACS_EAI                (3<<3)                                            //    Ethernet Address Table Index.0:Unicast Address Table;1:Multicast Address Table;2:IGMP Table(Read Only);3:Reserved
156 #define EACS_EAC                (3<<1)                                            //    Ethernet Address Command.0:Read;1:Write;2:Delete;3:Search
157 #define EACS_EAS                (1<<0)                                            //    Ethernet Address Table Status.0:Available;1:Busy
158 /*Ethernet Address Data Register(71H~76H)*/
159 #define EADR_EAD0                (0xFF)                                            //    MAC Address bit 07~00
160 #define EADR_EAD1                (0xFF)                                            //    MAC Address bit 15~08
161 #define EADR_EAD2                (0xFF)                                            //    MAC Address bit 23~16
162 #define EADR_EAD3                (0xFF)                                            //    MAC Address bit 31~24
163 #define EADR_EAD4                (0xFF)                                            //    MAC Address bit 39~32
164 #define EADR_EAD5                (0xFF)                                            //    MAC Address bit 47~40
165 /*Ethernet Address Control/Status Registe*/
166 #define EACR_OVERRIDE        (1<<6)
167 #define EACR_IGMPE            (1<<5)                                            //    When Reading Multicast Address Table, This bie Indicated the entry is IGMP entry or Not.0:Non-IGMP Entry;1:IGMP Entry
168 #define EACR_EA_STATIC    (1<<4)                                            //    0:Entry is Dynamic;1:Entry is Static,never be Age-out
169 #define EACR_PORT                (0x0F)                                            
170 /*Snooping Control Register*/
171 #define SCR_UIPMPC            (3<<5)                                            //    Unregistered IP Multicast Packet Control
172 #define SCR_UD_IGP            (1<<4)                                            //    User-defined IGMP Router Port configutation Enable.0:Disable; 1:Enable
173 #define SCR_SIGS2UP            (1<<3)                                            //    IGMP Packet Forward to UP Port only when SoftWare-IGS
174 #define SCR_HIGS2UP            (1<<2)                                            //    IGMP Packet Forward to UP Port Also WHen Hardware-IGS
175 #define SCR_SIGS_EN            (1<<1)                                            //    Software-based IGMP Snooping Enable.0:Hardware based IGMP Snooping, without software intervention(Defualt);1:Software based IGMP Snooping
176 #define SCR_IGS_EN            (1<<0)                                            //    IGMP Snooping Enable. 0:Disable; 1:Enable.
177 /*Snooping Control Register2*/
178 #define SCR2_SCP_PE            (1<<7)                                            //    Snooping Control Packet Priority Enable.0:Disable;1:Enable
179 #define SCR2_SCP_PRI        (3<<5)                                            //    Snooping Control Packet Prioeity
180 #define SCR2_SCP_OTC        (3<<3)                                            //    Snooping Control Packet Output Tag Control
181 #define SCR2_RPP                (7<<0)                                            //     Router Port Portmap
182 /*Snooping Control Register3*/
183 #define SCR3_QI                    (0xFF)                                            //    Query Interval.Define Query Interval when Hardware-IGS is Enabled
184 /*Snooping Control Register4*/
185 #define SCR4_RV                    (3<<0)                                            //    Robustness Variable.Define Robustness Variable when Hardware-IGS is Enabled.0:REserved;1:1times:2:2times(default);3:3times
186 /*Snooping Control Register5*/
187 #define SCR5_MLD2UP            (1<<1)                                            //    MLD Packet Forward to UP Port Only
188 #define SCR5_MLDS_EN        (1<<0)                                            //    MLD Snooping Enable.0:Disable;1:Enable
189 /*MIB Counter Port Index Register*/
190 #define MIBCPI_READY        (1<<7)                                            //    MIB Counter Data is Ready
191 #define MIBCPI_MIB_DIS    (1<<6)                                            //    When Write 0:Enabled,1:Disabled;When Read 0:Disabled,1:Enabled
192 #define MIBCPI_INDEX        (0x1F)                                            //    MIB Counter Index 0~9,each Counter is 32-bit in Register 81h~84h
193 /*Interrupt Status Register*/
194 #define ISR_IOMODE            (1<<7)                                            //    0:16bit mode; 1:8bit mode
195 #define ISR_LKNCHG            (1<<5)                                            //    Link Status Change of port 0 or 1
196 #define ISR_UDRUN                (1<<4)                                            //    Memory Management error
197 #define ISR_ROO                    (1<<3)                                            //    Receive Overflow Counter Overflow
198 #define ISR_ROS                    (1<<2)                                            //    Receive Overflow
199 #define ISR_PT                    (1<<1)                                            //    Packet Transmit
200 #define ISR_PR                    (1<<0)                                            //    Packet Received
201 /*Interrupt Mask Register*/
202 #define IMR_PAR                    (1<<7)                                            
203 #define IMR_LNKCHFI            (1<<5)                                            //    Enable Link Status Change Interrupt
204 #define IMR_UDRUNI            (1<<4)                                            //    Enable Transmit Under-run Interrupt
205 #define IMR_ROOI                (1<<3)                                            //    Enable Receive Overflow Counter Overflow Interrupt
206 #define IMR_POI                    (1<<2)                                            //    Enable Receive Overflow Interrupt
207 #define IMR_PTI                    (1<<1)                                            //    Enable Packet Transmit Interrupt
208 #define IMR_PRI                    (1<<0)                                            //    Enable Packet Received Interrupt
209 
210 /* DM9006 REGISTER LIST */
211 #define DM9006_REG_NCR        0x00 //Network Control Register
212 #define DM9006_REG_NSR        0x01 //Network Status Register
213 #define DM9006_REG_TCR        0x02 //TX Control Register
214 #define DM9006_REG_RCR        0x05 //RX Control Register
215 #define DM9006_REG_RSR        0x06 //RX Status Register
216 #define DM9006_REG_ROCR       0x07 //Receive Overflow Counter Register
217 #define DM9006_REG_BPTR       0x08
218 #define DM9006_REG_FCTR       0x09
219 #define DM9006_REG_FCR        0x0A //Flow Control Register
220 #define DM9006_REG_EPCR       0x0B //EEPROM & PHY Control Register
221 #define DM9006_REG_EPAR       0x0C //EEPROM & PHY Address Register
222 #define DM9006_REG_EPDRL      0x0D //EEPROM & PHY Low Byte Data Register
223 #define DM9006_REG_EPDRH      0x0E //EEPROM & PHY Hign Byte Data Register
224 #define DM9006_REG_WAR        0x0F //Link Change Control Register
225 #define DM9006_REG_PAR        0x10 //Processor Port Physical Address Registers
226 #define DM9006_REG_MAR        0x16 //Processor Port Multicast Address Registers
227 //#define DM9006_REG_MAR7                0x1D
228 //#define DM9006_REG_GPCR       0x1E
229 //#define DM9006_REG_GPR        0x1F
230 #define DM9006_REG_RXPLLR            0x20 //RX Packet Length Low Register
231 #define DM9006_REG_RXPLHR            0x21 //RX Packet Length High Register
232 #define DM9006_REG_RASR                0x26 //RX Additional Status Register
233 #define DM9006_REG_RACR                0x27 //RX Additional Control Register
234 #define DM9006_REG_VID_L      0x28 //Vendor ID Register
235 #define DM9006_REG_VID_H      0x29
236 #define DM9006_REG_PID_L      0x2A //Product ID Register
237 #define DM9006_REG_PID_H      0x2B
238 #define DM9006_REG_CHIPR      0x2C //CHIP Revision Register
239 //#define DM9006_REG_TCR2       0x2D
240 //#define DM9006_REG_OTCR       0x2E
241 //#define DM9006_REG_SMCR       0x2F
242 //#define DM9006_REG_ETXCSR     0x30 //early transmit control/status register
243 #define DM9006_REG_TCSCR      0x31 //Transmit Check Sum Control Register
244 #define DM9006_REG_RCSCSR     0x32 //Receive Check Sum Control Status Register
245 #define DM9006_REG_DRIVER            0x38 //uP Data Bus driving capability Register
246 #define DM9006_REG_IRQCR            0x39 //IRQ Pin Control Register
247 #define DM9006_REG_TRMSCR            0x3F //TX/RX Memory Size Control Register
248 #define DM9006_REG_SWITCHCR        0x52 //Switch Control Register
249 #define DM9006_REG_VLANCR            0x53 //VLAN Control Register
250 #define DM9006_REG_DSP1                0x58 //DSP Control Register I
251 #define DM9006_REG_DSP2                0x59 //DSP Control Register II
252 #define DM9006_REG_P_INDEX        0x60 //Per Port Control/Status Index Registe
253 #define DM9006_REG_P_CTRL            0x61 //Per Port Control Data Register
254 #define DM9006_REG_P_STUS            0x62 //Per Port Status Data Register
255 #define DM9006_REG_P_RATE            0x66 //Per Port Ingress and Egress Rate Control Register
256 #define DM9006_REG_P_BW                0x67 //Per Port Bandwidth Control Setting Register
257 #define DM9006_REG_P_UNICAST    0x68 //Per Port Block Unicast Ports Control Register
258 #define DM9006_REG_P_MULTI        0x69 //Per Port Block Multicast Ports Control Register
259 #define DM9006_REG_P_BCAST        0x6A //Per Port Block Broadcast Ports Control Register
260 #define DM9006_REG_P_UNKNWN        0x6B //Per Port Block Unknown Ports Control Register
261 #define DM9006_REG_P_SSTPR        0x6C //Per Port Security & STP Register
262 #define DM9006_REG_P_PRI            0x6D //Per Port Priority Queue Control Register
263 #define DM9006_REG_VLAN_TAGL    0x6E //Per Port VLAN Tag Low Byte Register
264 #define DM9006_REG_VLAN_TAGH    0x6F //Per Port VLAN Tag High Byte Register
265 #define DM9006_REG_EAD0                0x71 //Ethernet Address Data Register (71H~76H)
266 #define    DM9006_REG_EAD1                0x72
267 #define DM9006_REG_EAD2                0x73
268 #define    DM9006_REG_EAD3                0x74
269 #define    DM9006_REG_EAD4                0x75
270 #define DM9006_REG_EAD5                0x76
271 #define DM9006_REG_P_MIB_IDX    0x80 //Per Port MIB counter Index Register
272 #define DM9006_REG_MIB_DAT1        0x81 //MIB counter Data Register bit 0~7
273 #define DM9006_REG_MIB_DAT2        0x82 //MIB counter Data Register bit 8~15 
274 #define DM9006_REG_MIB_DAT3        0x83 //MIB counter Data Register bit 16~23
275 #define DM9006_REG_MIB_DAT4        0x84 //MIB counter Data Register bit 24~31
276 #define DM9006_REG_PVLAN          0xB0 //Port-based VLAN mapping table registers B0-BFH
277 #define DM9006_REG_TOS_MAP        0xC0 //TOS Priority Map Registers C0-CFH
278 #define DM9006_REG_VLAN_MAP        0xD0 //VLAN Priority Map Registers D0-D1H
279 #define DM9006_REG_MRCMDX     0xF0 //Memory Data Pre-Fetch Read Command Without Address Increment Register
280 #define DM9006_REG_MRCMD      0xF2 //Memory Data Read Command With Address Increment
281 #define DM9006_REG_MRRL       0xF4 //Memory Data Read_address Register Low Byte
282 #define DM9006_REG_MRRH       0xF5 //Memory Data Read_address Register High Byte
283 #define DM9006_REG_MWCMDX     0xF6 //Memory Data Write Command Without Address Increment
284 #define DM9006_REG_MWCMD      0xF8 //Memory Data Write Command With Address Increment Register
285 #define DM9006_REG_MWRL       0xFA //Memory Data Write_address Register Low Byte
286 #define DM9006_REG_MWRH       0xFB //Memory Data Write_address Register High Byte
287 #define DM9006_REG_TXPLL      0xFC //TX Packet Length Low Byte Register
288 #define DM9006_REG_TXPLH      0xFD //TX Packet Length High Byte Register
289 #define DM9006_REG_ISR        0xFE //Interrupt Status Register
290 #define DM9006_REG_IMR        0xFF //Interrupt Mask Register
291 
292 /* 相关宏设置 */
293 #define DM9000A_ID                 0x90000A46    
294 #define DM9006A_ID                 0x90060A46    
295 #define Max_Ethernet_Lenth      1536
296 #define MAXPACKAGESIZE                 1518
297 
298 #define DM9006_BYTE_MODE      0x01
299 #define DM9006_WORD_MODE      0x00
300 #define DM9006_PHY            0x20
301 #define DM9006_PKT_RDY        0x01
302 #define DM9006_PKT_NORDY      0x00
303 #define DM9006_REG_RESET      0x03
304 
305 #define DM9006_RX_INTR        0x01                /* 接收中断判断 bit */
306 #define DM9006_TX_INTR        0x02                /* 传送中断判断 bit */
307 #define DM9006_OVERFLOW_INTR  0x04                /* 内存溢出中断判断 bit */
308 #define DM9006_LINK_CHANG     0x20                /* 连接变动中断判断 bit */
309 
310 #define DM9006_PHY_ON         0x00                /* 设定 PHY 开启 */
311 #define DM9006_PHY_OFF        0x01                /* 设定 PHY 关闭 */
312 #define DM9006_RCR_SET        0x31                /* 设定 接收功能 (不收 CRC 及 超长包) */
313 #define DM9006_TCR_SET        0x01                /* 设定 传送功能 */
314 #define DM9006_RCR_OFF        0x00                /* 设定 接收功能关关闭设置 */
315 #define DM9006_BPTR_SET       0x37                /* 设定 Back Pressure 条件设置 */
316 #define DM9006_FCTR_SET       0x38                /* 设定 Flow Control 条件设置 */
317 #define DM9006_TCR2_SET       0x80                /* 设置 LED 显示模式 */
318 #define DM9006_OTCR_SET       0x80                /* 设置 DM9006 工作频率 0x80 = 100Mhz */
319 #define DM9006_ETXCSR_SET     0x83                /* 设置 Early Tramsmit 条件设置 */
320 #define DM9006_FCR_SET        0x28                /* 开启 网络流控功能设置 */
321 #define DM9006_TCSCR_SET      0x07                /* 设定 CHECKSUM 传送运算 设置 */
322 #define DM9006_RCSCSR_SET     0x03                /* 设定 CHECKSUM 接收检查 设置 */
323 #define DM9006_IMR_SET        0x81                /* 设定 启用中断使能 条件设置 */
324 #define DM9006_IMR_OFF        0x80                /* 设定 关闭中断使能 条件设置 */
325 
326 //DM9006内部PHY寄存器
327 #define DM9006_PHY_BMCR               0x00 //Basic Mode Control Register (BMCR)
328 #define DM9006_PHY_BMSR               0x01 //Basic Mode Status Register (BMSR)
329 #define DM9006_PHY_PHYID1           0x02 //PHY ID Identifier Register #1 (PHYID1)
330 #define DM9006_PHY_PHYID2           0x03 //PHY ID Identifier Register #2 (PHYID2) 
331 #define DM9006_PHY_ANAR               0x04 //Auto-negotiation Advertisement Register (ANAR) 
332 #define DM9006_PHY_ANLPAR           0x05 //Auto-negotiation Link Partner Ability Register (ANLPAR)
333 #define DM9006_PHY_ANER               0x06 //Auto-negotiation Expansion Register (ANER)
334 #define DM9006_PHY_DSCR               0x10 //DAVICOM Specified Configuration Register (DSCR
335 #define DM9006_PHY_DSCSR           0x11 //DAVICOM Specified Configuration and Status Register (DSCSR) 
336 #define DM9006_PHY_10BTCSR       0x12 //10BASE-T Configuration/Status (10BTCSR)
337 #define DM9006_PHY_PWDOR           0x13 //Power Down Control Register (PWDOR)
338 #define DM9006_PHY_SCR               0x14 //(Specified config) Register
339 #define DM9006_PHY_RECR                 0x16 //DAVICOM Specified Receive Error Counter Register (RECR) 
340 #define DM9006_PHY_DSICR             0x17 //DAVICOM Specified Disconnect Counter Register (DISCR) 
341 #define DM9006_PHY_PSCR                 0x1D //Power Saving Control Register (PSCR) 
342 #define DM9006_PHY_DATA                 0x1E //DAVICOM indirect DATA Register (DATA)
343 #define DM9006_PHY_ADDR                 0x1F //DAVICOM indirect ADDR Register (ADDR)  
344 #define DM9006_PHY_TX_OUT_CNTL 0x04 //DAVICOM indirect TX Amplitude Control Register (TX_OUT_CNTL) – indirect-04H
345 
346 #define ETH_EXTI_LINE          EXTI_Line13
347 #define ETH_EXTI_PORT_SOURCE   EXTI_PortSourceGPIOG
348 #define ETH_EXTI_PIN_SOURCE    EXTI_PinSource13
349 #define ETH_EXTI_IRQn          EXTI15_10_IRQn
350 
351 #define    DM9006_INTPORT             GPIOG
352 #define DM9006_INTPIN                 GPIO_Pin_13
353 
354 #define    DM9006_NRSTPORT                 GPIOB
355 #define DM9006_NRSTPIN             GPIO_Pin_12
356 
357 #define FSMC_NE1_ADDR                  (0x60000000)
358 #define FSMC_NE2_ADDR                  (0x64000000)
359 #define FSMC_NE3_ADDR                  (0x68000000)
360 #define FSMC_NE4_ADDR                  (0x6C000000)
361 
362 // 分配地址参考链接:
363 // https://blog.csdn.net/u011878611/article/details/107317741/
364 // http://www.armbbs.cn/forum.php?mod=viewthread&tid=14566
365 // 地址由FSMC_NE3 + A18共同决定, DM9006 网卡地址: 0x6800 0000 ~ 0x6808 0000
366 #define NET_BASE_ADDR                  (FSMC_NE3_ADDR) 
367 #define NET_REG_ADDR                  (*((volatile uint16_t *) (NET_BASE_ADDR | (1<<1)) )) // | (1<<1)
368 #define NET_REG_DATA                  (*((volatile uint16_t *) (NET_BASE_ADDR | (1<<19)) ))
369 
370 /*
371 *********************************************************************************************************
372 *                                              全局结构体
373 *********************************************************************************************************
374 */
375 enum DM9006_PHY_MODE{
376     DM9006_10MHD = 0,
377     DM9006_100MHD = 1,
378     DM9006_10MFD = 4,
379     DM9006_100MFD = 5,
380     DM9006_AUTO = 8,
381 };
382 
383 
384 /**********************************************************************************************************
385 *                                             参数细分
386 **********************************************************************************************************/
387 
388 
389 
390 
391 /**********************************************************************************************************
392 *                                        外部全局变量参数细分
393 **********************************************************************************************************/
394 
395 
396 
397 /*
398 *********************************************************************************************************
399 *                                             函数声明
400 *
401 *********************************************************************************************************
402 */
403 
404 void bsp_exti_init(GPIO_TypeDef *_GPIOx, uint32_t _pin, uint32_t _mode, uint8_t _Priority, uint8_t _SubPriority);
405 
406 void dm9k_phy_write(uint8_t phy_reg, uint16_t writedata,uint8_t port);
407 uint16_t dm9k_phy_read(uint8_t phy_reg,uint8_t port);
408 
409 uint8_t DM9k_ior(uint8_t reg);
410 void DM9k_iow(uint8_t reg, uint8_t writedata);
411 void DM9k_WaitBitClear(uint8_t reg, uint8_t bit);
412 
413 void etherdev_send(uint8_t *p_char, uint16_t length);
414 uint16_t etherdev_read(uint8_t *p_char);
415 uint16_t dm9k_receive_packet(uint8_t *_uip_buf);
416 
417 static void DM9K_CtrlLinesConfig(void);
418 static void DM9K_FSMCConfig(void);
419 
420 void etherdev_chkmedia(void);
421 uint32_t dm9k_ReadID(void);
422 
423 void etherdev_init(void);
424 uint8_t DM9006_LinkStat(void);
425 
426 void dm9k_debug_test(void);
427 
428 void dm9k_init(void);
429 
430 struct pbuf *DM9006_Receive_Packet(void);
431 
432 #ifdef __cplusplus
433 }
434 #endif
435 
436 #endif /* __DM9006_H */
437 
438 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

最后在添加到lwip支持网卡数据收发的文件ethetnetif.c文件,

  1 /**
  2 * @file
  3 * Ethernet Interface Skeleton
  4 *
  5 */
  6 
  7 /*
  8 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
  9 * All rights reserved.
 10 *
 11 * Redistribution and use in source and binary forms, with or without modification,
 12 * are permitted provided that the following conditions are met:
 13 *
 14 * 1. Redistributions of source code must retain the above copyright notice,
 15 *    this list of conditions and the following disclaimer.
 16 * 2. Redistributions in binary form must reproduce the above copyright notice,
 17 *    this list of conditions and the following disclaimer in the documentation
 18 *    and/or other materials provided with the distribution.
 19 * 3. The name of the author may not be used to endorse or promote products
 20 *    derived from this software without specific prior written permission.
 21 *
 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 25 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 27 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 31 * OF SUCH DAMAGE.
 32 *
 33 * This file is part of the lwIP TCP/IP stack.
 34 *
 35 * Author: Adam Dunkels <adam@sics.se>
 36 *
 37 */
 38 
 39 /*
 40 * This file is a skeleton for developing Ethernet network interface
 41 * drivers for lwIP. Add code to the low_level functions and do a
 42 * search-and-replace for the word "ethernetif" to replace it with
 43 * something that better describes your network interface.
 44 */
 45 
 46 #include "lwip/opt.h"
 47 #include "lwip/def.h"
 48 #include "lwip/mem.h"
 49 #include "lwip/pbuf.h"
 50 #include "lwip/timers.h"
 51 #include "netif/etharp.h"
 52 #include "lwip/stats.h"
 53 #include "lwip/snmp.h"
 54 #include "lwip/tcpip.h"
 55 #include "err.h"
 56 #include "ethernetif.h"
 57 #include "netconf.h"
 58 #include <string.h>
 59 
 60 #include "global.h"
 61 #include "malloc.h"
 62 #include "bsp_dm9006.h"
 63 
 64 /*
 65 *********************************************************************************************************
 66 *                                              全局宏定义
 67 *********************************************************************************************************
 68 */
 69 
 70 #define netifINTERFACE_TASK_STACK_SIZE          ( configMINIMAL_STACK_SIZE * 2  )
 71 #define netifINTERFACE_TASK_PRIORITY            ( configMAX_PRIORITIES - 3 )
 72 #define netifGUARD_BLOCK_TIME                   ( 1000 )
 73 /* The time to block waiting for input. */
 74 #define emacBLOCK_TIME_WAITING_FOR_INPUT        ( ( portTickType ) 100 )
 75 
 76 /* Define those to better describe your network interface. */
 77 #define IFNAME0 'e'
 78 #define IFNAME1 'n'
 79 
 80 xSemaphoreHandle s_xSemaphore = NULL;
 81 static void arp_timer(void *arg);
 82 
 83 /**
 84 * In this function, the hardware should be initialized.
 85 * Called from ethernetif_init().
 86 *
 87 * @param netif the already initialized lwip network interface structure
 88 *        for this ethernetif
 89 */
 90 static void low_level_init(struct netif *netif)
 91 {
 92     uint32_t i;
 93         
 94 //        VariableMemInit();
 95     
 96     /* set netif MAC hardware address length */
 97     netif->hwaddr_len = ETHARP_HWADDR_LEN;
 98 
 99     /* set netif MAC hardware address */
100 //  netif->hwaddr[0] =  MAC_ADDR0;
101 //  netif->hwaddr[1] =  MAC_ADDR1;
102 //  netif->hwaddr[2] =  MAC_ADDR2;
103 //  netif->hwaddr[3] =  MAC_ADDR3;
104 //  netif->hwaddr[4] =  MAC_ADDR4;
105 //  netif->hwaddr[5] =  MAC_ADDR5;
106 
107     netif->hwaddr[0] = lwipdev.mac[0];
108     netif->hwaddr[1] = lwipdev.mac[1];
109     netif->hwaddr[2] = lwipdev.mac[2];
110     netif->hwaddr[3] = lwipdev.mac[3];
111     netif->hwaddr[4] = lwipdev.mac[4];
112     netif->hwaddr[5] = lwipdev.mac[5];
113 
114     /* set netif maximum transfer unit */
115     netif->mtu = 1500;  //最大允许传输单元,允许该网卡广播和ARP功能
116 
117     /* Accept broadcast address and ARP traffic */
118     netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
119 
120     //添加IGMP,实现网络组播时开启
121 //        netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_IGMP;
122     
123         //添加IGMP,实现网络组播时开启,不标记已连接
124 //        netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
125         
126          
127     /* create binary semaphore used for informing ethernetif of frame reception */
128     if (s_xSemaphore == NULL)
129     {
130             vSemaphoreCreateBinary(s_xSemaphore);
131             xSemaphoreTake(s_xSemaphore, 0);
132     }
133 
134     /* create the task that handles the ETH_MAC */
135     xTaskCreate(ethernetif_input, (const char *)"Eth_if", netifINTERFACE_TASK_STACK_SIZE, 
136                                 (void *)netif,  // 传递给任务函数的参数
137                 netifINTERFACE_TASK_PRIORITY, 
138                                 NULL);
139 
140     ethernet_link_check_state(netif);
141 }
142 
143 
144 /**
145 * This function should do the actual transmission of the packet. The packet is
146 * contained in the pbuf that is passed to the function. This pbuf
147 * might be chained.
148 *
149 * @param netif the lwip network interface structure for this ethernetif
150 * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
151 * @return ERR_OK if the packet could be sent
152 *         an err_t value if the packet couldn't be sent
153 *
154 * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
155 *       strange results. You might consider waiting for space in the DMA queue
156 *       to become availale since the stack doesn't retry to send a packet
157 *       dropped because of memory failure (except for the TCP timers).
158 */
159 
160 static err_t low_level_output(struct netif *netif, struct pbuf *p)
161 {
162     static xSemaphoreHandle xTxSemaphore = NULL;
163       struct pbuf *q = NULL;
164         
165         uint16_t pbuf_index = 0;
166         uint8_t  word[2], word_index = 0;
167     
168     if (xTxSemaphore == NULL)
169     {
170        vSemaphoreCreateBinary(xTxSemaphore);
171     }
172 
173     if (xSemaphoreTake(xTxSemaphore, netifGUARD_BLOCK_TIME))
174     {
175       
176             DM9k_iow(DM9006_REG_IMR, DM9006_IMR_OFF);    // 关闭 DM9006A 中断
177             NET_REG_ADDR = DM9006_REG_MWCMD;
178             
179             q = p;
180             //向DM9006的TX SRAM中写入数据,一次写入两个字节数据
181             //当要发送的数据长度为奇数的时候,我们需要将最后一个字节单独写入DM9006的TX SRAM中
182             while(q)
183             {
184                 if (pbuf_index < q->len)
185                 {
186                     word[word_index++] = ((u8_t*)q->payload)[pbuf_index++];
187                     if (word_index == 2)
188                     {
189                         NET_REG_DATA = ((u16)word[1]<<8) | word[0];
190                         word_index = 0;
191                     }
192                 }else
193                 {
194                     q = q->next;
195                     pbuf_index = 0;
196                 }
197             }
198             
199             //还有一个字节未写入TX SRAM
200             if( word_index == 1)
201                 NET_REG_DATA = word[0];
202             //向DM9000写入发送长度
203             DM9k_iow(DM9006_REG_TXPLH, (p->tot_len >> 8) & 0xff);    // 设置传送封包的长度
204             DM9k_iow(DM9006_REG_TXPLL, p->tot_len & 0xff);
205             
206             DM9k_iow(DM9006_REG_TCR, DM9006_TCR_SET);    // 进行传送
207             while( (DM9k_ior(DM9006_REG_ISR) & DM9006_TX_INTR ) == 0); // 等待发送完成
208             DM9k_iow(DM9006_REG_ISR, DM9006_TX_INTR); // 清除发送完成中断 
209             DM9k_iow(DM9006_REG_IMR, IMR_PAR | IMR_PRI);    // 开启 DM9006A 中断
210             
211             xSemaphoreGive(xTxSemaphore);
212     }    
213 
214     return ERR_OK;
215 }
216 
217 /**
218 * Should allocate a pbuf and transfer the bytes of the incoming
219 * packet from the interface into the pbuf.
220 *
221 * @param netif the lwip network interface structure for this ethernetif
222 * @return a pbuf filled with the received packet (including MAC header)
223 *         NULL on memory error
224 */
225 static struct pbuf *low_level_input(struct netif *netif)
226 {
227   struct pbuf *p = NULL;
228     
229     p = DM9006_Receive_Packet();
230     
231     return p;
232 }
233 
234 
235 /**
236 * This function is the ethernetif_input task, it is processed when a packet
237 * is ready to be read from the interface. It uses the function low_level_input()
238 * that should handle the actual reception of bytes from the network
239 * interface. Then the type of the received packet is determined and
240 * the appropriate input function is called.
241 *
242 * @param netif the lwip network interface structure for this ethernetif
243 */
244 void ethernetif_input(void *pvParameters)
245 {
246     struct pbuf *p;
247     struct netif *netif = (struct netif *) pvParameters;
248     
249     for (;;)
250     {
251             // 请求信号量
252             if (xSemaphoreTake(s_xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT) == pdTRUE)
253             {
254                 do
255                 {
256 //                    LOCK_TCPIP_CORE();
257                     p = low_level_input(netif); //调用low_level_input函数接收数据
258                     if(p != NULL)
259                     {
260                         if(netif->input(p, netif) != ERR_OK) //调用netif结构体中的input字段(一个函数)来处理数据包
261                         {
262                             LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
263                             pbuf_free(p);
264                         }
265                     }
266 //                    UNLOCK_TCPIP_CORE();
267                 } while(p != NULL);
268             }
269     }
270 }
271 
272 /**
273 * Should be called at the beginning of the program to set up the
274 * network interface. It calls the function low_level_init() to do the
275 * actual setup of the hardware.
276 *
277 * This function should be passed as a parameter to netif_add().
278 *
279 * @param netif the lwip network interface structure for this ethernetif
280 * @return ERR_OK if the loopif is initialized
281 *         ERR_MEM if private data couldn't be allocated
282 *         any other err_t on error
283 */
284 err_t ethernetif_init(struct netif *netif)
285 {
286     LWIP_ASSERT("netif != NULL", (netif != NULL));
287 
288 #if LWIP_NETIF_HOSTNAME
289     /* Initialize interface hostname */
290     netif->hostname = "lwip";
291 #endif /* LWIP_NETIF_HOSTNAME */
292 
293     netif->name[0] = IFNAME0; //初始化变量netif的name字段
294     netif->name[1] = IFNAME1; //在文件外定义这里不用关心具体值
295 
296     netif->output = etharp_output; //IP层发送数据包函数
297     netif->linkoutput = low_level_output; //ARP模块发送数据包函数
298 
299     /* initialize the hardware */
300     low_level_init(netif); //底层硬件初始化函数
301 
302     etharp_init();
303     sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
304 
305     return ERR_OK;
306 }
307 
308 /**
309   * @brief  Custom Rx pbuf free callback
310   * @param  pbuf: pbuf to be freed
311   * @retval None
312   */
313 static void pbuf_free_custom(struct pbuf *p)
314 {
315     if(p != NULL)
316     {
317         memset(p, 0, sizeof(struct pbuf));
318     }
319 }
320 
321 /**
322   * @brief  arp_timer
323   * @param  void
324   * @retval None
325   */
326 static void arp_timer(void *arg)
327 {
328     etharp_tmr();
329     sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
330 }
331 
332 
333 /**
334   * @brief  Ethernet Rx Transfer completed callback
335   * @param  heth: ETH handle
336   * @retval None
337   */
338 void EXTI15_10_IRQHandler(void)
339 {
340     uint16_t  save_reg;
341     uint16_t  int_status;
342     
343     portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
344 
345     if ( EXTI_GetITStatus(ETH_EXTI_LINE) != RESET )
346     {
347         // Clear interrupt pending bit
348         EXTI_ClearITPendingBit(ETH_EXTI_LINE);
349         
350         save_reg = NET_REG_ADDR; // 暂存所使用的位置 
351         
352         DM9k_iow(DM9006_REG_IMR, DM9006_IMR_OFF); //    关发送和接收中断
353         
354         //    got DM9006 interrupt status
355         int_status = DM9k_ior(DM9006_REG_ISR);    //    Got ISR,取得中断产生值 
356         // 清除中断标志位,DM9006的ISR寄存器的bit0~bit5写1清零
357         DM9k_iow(DM9006_REG_ISR, int_status);      //    Clear ISR status,清除中断产生值
358         
359         // overflow
360         if(int_status & ISR_ROS)
361         {
362             printf(">>DM9006 overflow \r\n");
363         }
364         // overflow counter overflow
365     if(int_status & ISR_ROO)
366         {
367             printf(">>DM9006 overflow counter overflow \r\n");    
368         }
369         //    Receive the coming packet
370         if (int_status & DM9006_RX_INTR) // 检查是否为接收中断
371         {
372 //            printf(">>DM9006A_EXTI RX\r\n");
373             // Give the semaphore to wakeup LwIP task 
374             xSemaphoreGiveFromISR( s_xSemaphore, &xHigherPriorityTaskWoken );
375 //        DM9006_Receive_Packet();
376         }
377         
378         //    Transmit interrupt check
379         if (int_status & DM9006_TX_INTR) // 检查是否为发送中断
380         {
381             //发送中断处理,这里没用到
382 //            printf(">>DM9006A_EXTI TX\r\n");
383 //            DM9006_TxDone();
384         }
385         
386         DM9k_iow(DM9006_REG_IMR, IMR_PAR | IMR_PRI);
387 //        DM9k_iow(DM9006_REG_IMR, 0xA3);
388     
389         NET_REG_ADDR = save_reg; // 恢复所使用的位置
390         
391     }
392     
393     /* Switch tasks if necessary. */
394     if (xHigherPriorityTaskWoken != pdFALSE)
395     {
396             portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
397     }
398 }
399 
400 
401 /**
402   * @brief  Check the ETH link state and update netif accordingly.
403   * @param  argument: netif
404   * @retval None
405   */
406 void ethernet_link_check_state(struct netif *netif)
407 {
408     uint8_t linkchanged = 0;
409 
410     linkchanged = DM9006_LinkStat();
411 
412     if( netif_is_link_up(netif) && (linkchanged == 0) )
413     {
414         netif_set_down(netif);
415         netif_set_link_down(netif);
416     }
417     else if( !netif_is_link_up(netif) && (linkchanged == 1))
418     {
419         netif_set_up(netif);
420         netif_set_link_up(netif);
421     }
422 }
423 
424 /**
425   * @brief  Check the ETH link state and update netif accordingly.
426   * @param  argument: netif
427   * @retval None
428   */
429 void ethernet_dm9006_link_thread(void *pvParameters)
430 {
431     struct netif *netif = (struct netif *) pvParameters;
432 
433     for(;;)
434     {
435         ethernet_link_check_state(netif);
436         vTaskDelay(200);
437     }
438 }

剩下初始化,按照默认的套路来,就可以,下载,插入网线板子自动获取到IP地址,不过时间测试最大网速也就是83Mbps,查看数据手册发现,这个片子最大也就支持到88Mbps.

posted @ 2020-09-09 14:59  求隐  阅读(1151)  评论(2编辑  收藏  举报