/* ********************************************************************************************************* * * 模块名称 : DM9KAEP 底层驱动模块(For STM32F4XX, uip) * 文件名称 : dm9k_uip.c * 版 本 : V1.1 * 说 明 : 这是硬件底层驱动程序的主文件。每个c文件可以 #include "bsp.h" 来包含所有的外设驱动模块。 * bsp = Borad surport packet 板级支持包 * 修改记录 : * 版本号 日期 作者 说明 * V1.0 2013-03-01 armfly 正式发布 * V1.1 2013-06-20 armfly 规范注释,添加必要说明 * * Copyright (C), 2013-2014, 安富莱电子 www.armfly.com * ********************************************************************************************************* */ #include "dm9k.h" uint8_t SendPackOk = 0; uint8_t is_fsmc_ok = 0; /* 用于指示FSMC是否初始化 */ void dm9k_debug_test(void); static void dm9k_fsmc(void); static void dm9k_initnic(void); /* ********************************************************************************************************* * 函 数 名: dm9k_init * 功能说明: uIP 接口函数,初始化网卡. uIP 接口函数. * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void dm9k_init(void) { dm9k_fsmc(); is_fsmc_ok = 1; dm9k_initnic(); /* 配置DM9K */ } /* ********************************************************************************************************* * 函 数 名: dm9k_fsmc * 功能说明: 配置FSMC并口访问时序 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ static void dm9k_fsmc(void) { FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; FSMC_NORSRAMTimingInitTypeDef p; /*-- FSMC Configuration ------------------------------------------------------*/ /*----------------------- SRAM Bank 3 ----------------------------------------*/ /*-- FSMC Configuration ------------------------------------------------------*/ p.FSMC_AddressSetupTime = 6; /* 设置为2会出错; 3正常 */ p.FSMC_AddressHoldTime = 2; p.FSMC_DataSetupTime = 4; /* 设置为1出错,2正常 */ p.FSMC_BusTurnAroundDuration = 1; p.FSMC_CLKDivision = 0; p.FSMC_DataLatency = 0; p.FSMC_AccessMode = FSMC_AccessMode_A; FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3; FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; // FSMC_MemoryType_PSRAM; FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); /*!< Enable FSMC Bank1_SRAM3 Bank */ FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE); } /* ********************************************************************************************************* * 函 数 名: dm9k_ReadReg * 功能说明: 读出DM9K指定寄存器的值 * 形 参: reg 寄存器地址 * 返 回 值: 寄存器值 ********************************************************************************************************* */ uint8_t dm9k_ReadReg(uint8_t reg) { NET_REG_ADDR = reg; return (NET_REG_DATA); } /* ********************************************************************************************************* * 函 数 名: dm9k_WriteReg * 功能说明: 读出DM9K指定寄存器的值 * 形 参: reg :寄存器地址 * writedata : 写入的数据 * 返 回 值: 无 ********************************************************************************************************* */ void dm9k_WriteReg(uint8_t reg, uint8_t writedata) { NET_REG_ADDR = reg; NET_REG_DATA = writedata; } /* ********************************************************************************************************* * 函 数 名: dm9k_hash_table * 功能说明: 设置 DM9KA MAC 、 广播 、 多播 寄存器 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void dm9k_hash_table() { uint8_t i; /* 设置 网卡 MAC 位置,来自於 MyHardware */ dm9k_WriteReg(DM9K_REG_PAR, DM9K_MAC_ADDR0); dm9k_WriteReg(DM9K_REG_PAR + 1, DM9K_MAC_ADDR1); dm9k_WriteReg(DM9K_REG_PAR + 2, DM9K_MAC_ADDR2); dm9k_WriteReg(DM9K_REG_PAR + 3, DM9K_MAC_ADDR3); dm9k_WriteReg(DM9K_REG_PAR + 4, DM9K_MAC_ADDR4); dm9k_WriteReg(DM9K_REG_PAR + 5, DM9K_MAC_ADDR5); /* 清除 网卡多播设置 */ for (i = 0; i < 8; i++) { dm9k_WriteReg(DM9K_REG_MAR + i, 0x00); } /* 设置 广播包 设置 */ dm9k_WriteReg(DM9K_REG_MAR + 7, 0x80); } /* ********************************************************************************************************* * 函 数 名: dm9k_reset * 功能说明: 软件复位DM9KAE * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void dm9k_reset(void) { dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET); /* 对 DM9KA 进行软件重置 */ OSTimeDly(10); /* delay 10us */ dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET); /* 对 DM9KA 进行软件重置 */ OSTimeDly(10); /* delay 10us */ /* 基本记存器相关设置 */ dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 开启内存自环模式 */ dm9k_WriteReg(DM9K_REG_TCR2, DM9K_TCR2_SET); /* 设置 LED 显示模式1:全双工亮,半双工灭 */ /* 清除多余资讯 */ dm9k_WriteReg(DM9K_REG_NSR, 0x2c); dm9k_WriteReg(DM9K_REG_TCR, 0x00); dm9k_WriteReg(DM9K_REG_ISR, 0x3f); #ifdef DM9KA_FLOW_CONTROL dm9k_WriteReg(DM9K_REG_BPTR, DM9K_BPTR_SET); /* 半双工流控设置 */ dm9k_WriteReg(DM9K_REG_FCTR, DM9K_FCTR_SET); /* 全双工流控设置 */ dm9k_WriteReg(DM9K_REG_FCR, DM9K_FCR_SET); /* 开启流控设置 */ #endif #ifdef DM9KA_UPTO_100M /* DM9KA无此寄存器 */ dm9k_WriteReg(DM9K_REG_OTCR, DM9K_OTCR_SET); /* 工作频率到 100Mhz 设置 */ #endif #ifdef Rx_Int_enable dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 开启 中断模式 */ #else dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 关闭 中断模式 */ #endif dm9k_WriteReg(DM9K_REG_RCR, DM9K_RCR_SET); /* 开启 接收工能 */ SendPackOk = 0; } /* ********************************************************************************************************* * 函 数 名: dm9k_phy_write * 功能说明: 软件复位DM9KAE * 形 参: phy_reg : PHY寄存器地址 * writedata : 写入的数据 * 返 回 值: 无 ********************************************************************************************************* */ void dm9k_phy_write(uint8_t phy_reg, uint16_t writedata) { /* 设置写入 PHY 寄存器的位置 */ dm9k_WriteReg(DM9K_REG_EPAR, phy_reg | DM9K_PHY); /* 设置写入 PHY 寄存器的值 */ dm9k_WriteReg(DM9K_REG_EPDRH, (writedata >> 8) & 0xff); dm9k_WriteReg(DM9K_REG_EPDRL, writedata & 0xff); dm9k_WriteReg(DM9K_REG_EPCR, 0x0a); /* 将资料写入 PHY 寄存器 */ while (dm9k_ReadReg(DM9K_REG_EPCR) & 0x01) ; /* 查寻是否执行结束 */ dm9k_WriteReg(DM9K_REG_EPCR, 0x08); /* 清除写入命令 */ } /* ********************************************************************************************************* * 函 数 名: dm9k_initnic * 功能说明: 配置DM9KAE芯片(初始化) * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ static void dm9k_initnic(void) { dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET); /* 对 DM9KA 进行软件重置 */ OSTimeDly(10); /* delay 10us */ dm9k_hash_table(); /* 设置 DM9KA MAC 及 多播*/ dm9k_reset(); /* 进行 DM9KA 软件设置 */ dm9k_WriteReg(DM9K_REG_GPR, DM9K_PHY_OFF); /* 关闭 PHY ,进行 PHY 设置*/ dm9k_phy_write(0x00, 0x8000); /* 重置 PHY 的寄存器 */ #ifdef DM9KA_FLOW_CONTROL dm9k_phy_write(0x04, 0x01e1 | 0x0400); /* 设置 自适应模式相容表 */ #else dm9k_phy_write(0x04, 0x01e1); /* 设置 自适应模式相容表 */ #endif // dm9k_phy_write(0x00, 0x1000); /* 设置 基本连接模式 */ /* 连接模式设置 0x0000 : 固定10M半双工 0x0100 : 固定10M全双工 0x2000 : 固定100M半双工 0x2100 : 固定100M全双工 0x1000 : 自适应模式 */ dm9k_phy_write(0x00, 0x1000); /* 设置 基本连接模式 */ dm9k_WriteReg(DM9K_REG_GPR, DM9K_PHY_ON); /* 结束 PHY 设置, 开启 PHY */ // dm9k_debug_test(); } /* ********************************************************************************************************* * 函 数 名: dm9k_receive_packet * 功能说明: 配置DM9KAE芯片(初始化) * 形 参: _uip_buf : 接收结果存放的缓冲区指针 * 返 回 值: > 0 表示接收的数据长度, 0表示没有数据 ********************************************************************************************************* */ uint16_t dm9k_receive_packet(uint8_t *_uip_buf) { uint16_t ReceiveLength; uint16_t *ReceiveData; uint8_t rx_int_count = 0; uint8_t rx_checkbyte; uint16_t rx_status, rx_length; uint8_t jump_packet; uint16_t i; uint16_t calc_len; uint16_t calc_MRR; do { ReceiveLength = 0; /* 清除接收的长度 */ ReceiveData = (uint16_t *)_uip_buf; jump_packet = 0; /* 清除跳包动作 */ dm9k_ReadReg(DM9K_REG_MRCMDX); /* 读取内存数据,地址不增加 */ /* 计算内存数据位置 */ calc_MRR = (dm9k_ReadReg(DM9K_REG_MRRH) << 8) + dm9k_ReadReg(DM9K_REG_MRRL); rx_checkbyte = dm9k_ReadReg(DM9K_REG_MRCMDX); /* */ if (rx_checkbyte == DM9K_PKT_RDY) /* 取 */ { /* 读取封包相关资讯 及 长度 */ NET_REG_ADDR = DM9K_REG_MRCMD; rx_status = NET_REG_DATA; rx_length = NET_REG_DATA; /* 若收到超过系统可承受的封包,此包跳过 */ if (rx_length > Max_Ethernet_Lenth) jump_packet = 1; #ifdef Broadcast_Jump /* 若收到的广播或多播包超过特定长度,此包跳过 */ if (rx_status & 0x4000) { if (rx_length > Max_Broadcast_Lenth) jump_packet = 1; } #endif /* 计算下一个包的指针位 , 若接收长度为奇数,需加一对齐偶字节。*/ /* 若是超过 0x3fff ,则需回归绕到 0x0c00 起始位置 */ calc_MRR += (rx_length + 4); if (rx_length & 0x01) calc_MRR++; if (calc_MRR > 0x3fff) calc_MRR -= 0x3400; if (jump_packet == 0x01) { /* 将指针移到下一个包的包头位置 */ dm9k_WriteReg(DM9K_REG_MRRH, (calc_MRR >> 8) & 0xff); dm9k_WriteReg(DM9K_REG_MRRL, calc_MRR & 0xff); continue; } /* 开始将内存的资料搬到到系统中,每次移动一个 word */ calc_len = (rx_length + 1) >> 1; for (i = 0; i < calc_len; i++) ReceiveData[i] = NET_REG_DATA; /* 将包长回报给 TCP/IP 上层,并减去最後 4 BYTE 的 CRC-32 检核码 */ ReceiveLength = rx_length - 4; rx_int_count++; /* 累计收包次数 */ #ifdef FifoPointCheck if (calc_MRR != ((dm9k_ReadReg(DM9K_REG_MRRH) << 8) + dm9k_ReadReg(DM9K_REG_MRRL))) { #ifdef Point_Error_Reset dm9k_reset(); /* 若是指针出错,重置 */ return ReceiveLength; #endif /*若是指针出错,将指针移到下一个包的包头位置 */ dm9k_WriteReg(DM9K_REG_MRRH, (calc_MRR >> 8) & 0xff); dm9k_WriteReg(DM9K_REG_MRRL, calc_MRR & 0xff); } #endif return ReceiveLength; } else { if (rx_checkbyte == DM9K_PKT_NORDY) /* 未收到包 */ { dm9k_WriteReg(DM9K_REG_ISR, 0x3f); /* */ } else { dm9k_reset(); /* 接收指针出错,重置 */ } return (0); } } while (rx_int_count < Max_Int_Count); /* 是否超过最多接收封包计数 */ return 0; } /* ********************************************************************************************************* * 函 数 名: dm9k_send_packet * 功能说明: 发送一包数据 * 形 参: p_char : 发送数据缓冲区 * 返 回 值: length : 数据长度 ********************************************************************************************************* */ void dm9k_send_packet(uint8_t *p_char, uint16_t length) { uint16_t SendLength = length; uint16_t *SendData = (uint16_t *)p_char; uint16_t i; uint16_t calc_len; __IO uint16_t calc_MWR; /* 检查 DM9KA 是否还在传送中!若是等待直到传送结束 */ if (SendPackOk == Max_Send_Pack) { while (dm9k_ReadReg(DM9K_REG_TCR) & DM9K_TCR_SET) { OSTimeDly(5); } SendPackOk = 0; } SendPackOk++; /* 设置传送计数 */ #ifdef FifoPointCheck /* 计算下一个传送的指针位 , 若接收长度为奇数,需加一对齐偶字节。*/ /* 若是超过 0x0bff ,则需回归绕到 0x0000 起始位置 */ calc_MWR = (dm9k_ReadReg(DM9K_REG_MWRH) << 8) + dm9k_ReadReg(DM9K_REG_MWRL); calc_MWR += SendLength; if (SendLength & 0x01) calc_MWR++; if (calc_MWR > 0x0bff) calc_MWR -= 0x0c00; #endif dm9k_WriteReg(DM9K_REG_TXPLH, (SendLength >> 8) & 0xff); /* 设置传送封包的长度 */ dm9k_WriteReg(DM9K_REG_TXPLL, SendLength & 0xff); /* 开始将系统的资料搬到到内存中,每次移动一个 word */ NET_REG_ADDR = DM9K_REG_MWCMD; calc_len = (SendLength + 1) >> 1; for (i = 0; i < calc_len; i++) NET_REG_DATA = SendData[i]; dm9k_WriteReg(DM9K_REG_TCR, DM9K_TCR_SET); /* 进行传送 */ #ifdef FifoPointCheck if (calc_MWR != ((dm9k_ReadReg(DM9K_REG_MWRH) << 8) + dm9k_ReadReg(DM9K_REG_MWRL))) { #ifdef Point_Error_Reset /* 若是指针出错,等待此一封包送完 , 之後进行重置 */ while (dm9k_ReadReg(DM9K_REG_TCR) & DM9K_TCR_SET) bsp_DelayUS(5); dm9k_reset(); return; #endif /*若是指针出错,将指针移到下一个传送包的包头位置 */ dm9k_WriteReg(DM9K_REG_MWRH, (calc_MWR >> 8) & 0xff); dm9k_WriteReg(DM9K_REG_MWRL, calc_MWR & 0xff); } #endif return; } /******************************************************************************* * 函数名: etherdev_send * 参 数: p_char : 数据缓冲区 * length : 数据长度 * 返 回: 无 * 功 能: uIP 接口函数,发送一包数据 */ void etherdev_send(uint8_t *p_char, uint16_t length) { dm9k_send_packet(p_char, length); } uint16_t etherdev_read(uint8_t *p_char) { return dm9k_receive_packet(p_char); } /******************************************************************************* * 函数名: etherdev_chkmedia * 参 数: p_char : 数据缓冲区 * length : 数据长度 * 返 回: 无 * 功 能: uIP 接口函数, 检测网络连接状态 */ void etherdev_chkmedia(void) { // uint8_t status; while (!(dm9k_ReadReg(DM9K_REG_NSR) & DM9K_PHY)) { OSTimeDly(2000); } } /* ********************************************************************************************************* * 函 数 名: dm9k_interrupt * 功能说明: 中断处理函数 (webserver例程未使用中断) * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void dm9k_interrupt(void) { uint8_t save_reg; uint16_t isr_status; save_reg = NET_REG_ADDR; /* 暂存所使用的位置 */ dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 关闭 DM9KA 中断 */ isr_status = dm9k_ReadReg(DM9K_REG_ISR); /* 取得中断产生值 */ if (isr_status & DM9K_RX_INTR) { /* 检查是否为接收中断 */ // dm9k_receive_packet(); /* 执行接收处理程序 */ } dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 开启 DM9KA 中断 */ NET_REG_ADDR = save_reg; /* 回复所使用的位置 */ } /******************************************************************************* * 函数名: dm9k_ReadID * 参 数: 无 * 返 回: 无 * 功 能: 读取芯片ID */ uint32_t dm9k_ReadID(void) { uint8_t vid1, vid2, pid1, pid2; if (is_fsmc_ok == 0) { dm9k_fsmc(); is_fsmc_ok = 1; } vid1 = dm9k_ReadReg(DM9K_REG_VID_L) & 0xFF; vid2 = dm9k_ReadReg(DM9K_REG_VID_H) & 0xFF; pid1 = dm9k_ReadReg(DM9K_REG_PID_L) & 0xFF; pid2 = dm9k_ReadReg(DM9K_REG_PID_H) & 0xFF; return (vid2 << 24) | (vid1 << 16) | (pid2 << 8) | pid1; } uint8_t dm9k_linkstat(void) { uint8_t linkchanged = 0; linkchanged = (dm9k_ReadReg(DM9K_PHY_BMSR) >> 6) & 0x01; return linkchanged; } #if 0 /* ********************************************************************************************************* * 函 数 名: dm9k_debug_test * 功能说明: 测试DM9KAE的函数,用于排错 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void dm9k_debug_test(void) { uint32_t check_device; uint8_t check_iomode; uint8_t check_reg_fail = 0; uint8_t check_fifo_fail = 0; uint16_t i; uint16_t j; dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET); /* 对 DM9KA 进行软件重置 */ OSTimeDly(10); /* delay 10us */ dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET); /* 对 DM9KA 进行软件重置 */ OSTimeDly(10); /* delay 10us */ check_device = dm9k_ReadReg(DM9K_REG_VID_L); check_device |= dm9k_ReadReg(DM9K_REG_VID_H) << 8; check_device |= dm9k_ReadReg(DM9K_REG_PID_L) << 16; check_device |= dm9k_ReadReg(DM9K_REG_PID_H) << 24; if(check_device != 0x90000A46) { printk("DM9K_DEBUG ==> DEIVCE NOT FOUND, SYSTEM HOLD !!\n"); while(1); } else { printk("DM9K_DEBUG ==> DEIVCE FOUND !!\n"); } check_iomode = dm9k_ReadReg(DM9K_REG_ISR) >> 6; if(check_iomode != DM9K_WORD_MODE) { printk("DM9K_DEBUG ==> DEIVCE NOT WORD MODE, SYSTEM HOLD !!\n"); while(1); } else { printk("DM9K_DEBUG ==> DEIVCE IS WORD MODE !!\n"); } printk("DM9K_DEBUG ==> REGISTER R/W TEST !!\n"); NET_REG_ADDR = DM9K_REG_MAR; for(i = 0; i < 0x0100; i++) { NET_REG_DATA = i; if(i != (NET_REG_DATA & 0xff)) { printk(" > error W %02x , R %02x \n", i , NET_REG_DATA); check_reg_fail = 1; } } if(check_reg_fail) { printk("DM9K_DEBUG ==> REGISTER R/W FAIL, SYSTEM HOLD !!\n"); while(1); } printk("DM9K_DEBUG ==> FIFO R/W TEST !!\n"); printk("DM9K_DEBUG ==> FIFO WRITE START POINT 0x%02x%02x \n", dm9k_ReadReg(DM9K_REG_MWRH), dm9k_ReadReg(DM9K_REG_MWRL)); NET_REG_ADDR = DM9K_REG_MWCMD; for(i = 0; i < 0x1000; i++) NET_REG_DATA = ((i & 0xff) * 0x0101); printk("DM9K_DEBUG ==> FIFO WRITE END POINT 0x%02x%02x \n", dm9k_ReadReg(DM9K_REG_MWRH), dm9k_ReadReg(DM9K_REG_MWRL)); if((dm9k_ReadReg(DM9K_REG_MWRH) != 0x20) || (dm9k_ReadReg(DM9K_REG_MWRL) != 0x00)) { printk("DM9K_DEBUG ==> FIFO WRITE FAIL, SYSTEM HOLD !!\n"); while(1); } dm9k_ReadReg(DM9K_REG_MRCMDX); printk("DM9K_DEBUG ==> FIFO READ START POINT 0x%02x%02x \n", dm9k_ReadReg(DM9K_REG_MRRH), dm9k_ReadReg(DM9K_REG_MRRL)); dm9k_ReadReg(DM9K_REG_MRCMDX); NET_REG_ADDR = DM9K_REG_MRCMD; for(i = 0; i < 0x1000; i++) { j = NET_REG_DATA; if(((i & 0xff) * 0x0101) != j) { //printk(" > error W %04x , R %04x \n", // ((i & 0xff) * 0x0101) , j); check_fifo_fail = 1; } } printk("DM9K_DEBUG ==> FIFO READ END POINT 0x%02x%02x \n", dm9k_ReadReg(DM9K_REG_MRRH), dm9k_ReadReg(DM9K_REG_MRRL)); if((dm9k_ReadReg(DM9K_REG_MRRH) != 0x20) || (dm9k_ReadReg(DM9K_REG_MRRL) != 0x00)) { printk("DM9K_DEBUG ==> FIFO WRITE FAIL, SYSTEM HOLD !!\n"); while(1); } if(check_fifo_fail) { printk("DM9K_DEBUG ==> FIFO R/W DATA FAIL, SYSTEM HOLD !!\n"); while(1); } printk("DM9K_DEBUG ==> PACKET SEND & INT TEST !! \n"); dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET); OSTimeDly(10); dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET); OSTimeDly(10); dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF | DM9K_TX_INTR); dm9k_WriteReg(DM9K_REG_TXPLH, 0x01); dm9k_WriteReg(DM9K_REG_TXPLL, 0x00); do { dm9k_WriteReg(DM9K_REG_ISR, DM9K_TX_INTR); printk("DM9K_DEBUG ==> INT PIN IS OFF\n"); NET_REG_ADDR = DM9K_REG_MWCMD; for(i = 0; i < (0x0100 / 2); i++) { if(i < 3) NET_REG_DATA = 0xffff; else NET_REG_DATA = i * 0x0101; } printk("DM9K_DEBUG ==> PACKET IS SEND \n"); dm9k_WriteReg(DM9K_REG_TCR, DM9K_TCR_SET); while(dm9k_ReadReg(DM9K_REG_TCR) & DM9K_TCR_SET) bsp_DelayUS (5); if(dm9k_ReadReg(DM9K_REG_ISR) & DM9K_TX_INTR) printk("DM9K_DEBUG ==> INT PIN IS ACTIVE \n"); else printk("DM9K_DEBUG ==> INT PIN IS NOT ACTIVE \n"); for(i = 0; i < 10; i++) bsp_DelayUS(1000); }while(1); } /* ********************************************************************************************************* * 函 数 名: etherdev_chkmedia * 功能说明: 检测网络连接状态 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void etherdev_chkmedia(void) { // uint8_t status; while(!(dm9k_ReadReg(DM9K_REG_NSR) & DM9K_PHY)) { bsp_DelayUS(2000); } } /******************************************************************************* * 函数名: etherdev_poll * 参 数: 无 * 返 回: 无 * 功 能: uIP 接口函数, 采用查询方式接收一个IP包 */ /* etherdev_poll() This function will read an entire IP packet into the uip_buf. If it must wait for more than 0.5 seconds, it will return with the return value 0. Otherwise, when a full packet has been read into the uip_buf buffer, the length of the packet is returned. */ uint16_t etherdev_poll(void) { uint16_t bytes_read = 0; #if 0 /* tick_count threshold should be 12 for 0.5 sec bail-out One second (24) worked better for me, but socket recycling is then slower. I set UIP_TIME_WAIT_TIMEOUT 60 in uipopt.h to counter this. Retransmission timing etc. is affected also. */ while ((!(bytes_read = etherdev_read())) && (timer0_tick() < 12)) continue; timer0_reset(); #endif return bytes_read; } #endif