dm9k.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. /*
  2. *********************************************************************************************************
  3. *
  4. * 模块名称 : DM9KAEP 底层驱动模块(For STM32F4XX, uip)
  5. * 文件名称 : dm9k_uip.c
  6. * 版 本 : V1.1
  7. * 说 明 : 这是硬件底层驱动程序的主文件。每个c文件可以 #include "bsp.h" 来包含所有的外设驱动模块。
  8. * bsp = Borad surport packet 板级支持包
  9. * 修改记录 :
  10. * 版本号 日期 作者 说明
  11. * V1.0 2013-03-01 armfly 正式发布
  12. * V1.1 2013-06-20 armfly 规范注释,添加必要说明
  13. *
  14. * Copyright (C), 2013-2014, 安富莱电子 www.armfly.com
  15. *
  16. *********************************************************************************************************
  17. */
  18. #include "dm9k.h"
  19. uint8_t SendPackOk = 0;
  20. uint8_t is_fsmc_ok = 0; /* 用于指示FSMC是否初始化 */
  21. void dm9k_debug_test(void);
  22. static void dm9k_fsmc(void);
  23. static void dm9k_initnic(void);
  24. /*
  25. *********************************************************************************************************
  26. * 函 数 名: dm9k_init
  27. * 功能说明: uIP 接口函数,初始化网卡. uIP 接口函数.
  28. * 形 参: 无
  29. * 返 回 值: 无
  30. *********************************************************************************************************
  31. */
  32. void dm9k_init(void)
  33. {
  34. dm9k_fsmc();
  35. is_fsmc_ok = 1;
  36. dm9k_initnic(); /* 配置DM9K */
  37. }
  38. /*
  39. *********************************************************************************************************
  40. * 函 数 名: dm9k_fsmc
  41. * 功能说明: 配置FSMC并口访问时序
  42. * 形 参: 无
  43. * 返 回 值: 无
  44. *********************************************************************************************************
  45. */
  46. static void dm9k_fsmc(void)
  47. {
  48. FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
  49. FSMC_NORSRAMTimingInitTypeDef p;
  50. /*-- FSMC Configuration ------------------------------------------------------*/
  51. /*----------------------- SRAM Bank 3 ----------------------------------------*/
  52. /*-- FSMC Configuration ------------------------------------------------------*/
  53. p.FSMC_AddressSetupTime = 6; /* 设置为2会出错; 3正常 */
  54. p.FSMC_AddressHoldTime = 2;
  55. p.FSMC_DataSetupTime = 4; /* 设置为1出错,2正常 */
  56. p.FSMC_BusTurnAroundDuration = 1;
  57. p.FSMC_CLKDivision = 0;
  58. p.FSMC_DataLatency = 0;
  59. p.FSMC_AccessMode = FSMC_AccessMode_A;
  60. FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;
  61. FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
  62. FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; // FSMC_MemoryType_PSRAM;
  63. FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
  64. FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
  65. FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
  66. FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
  67. FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
  68. FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
  69. FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
  70. FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
  71. FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
  72. FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
  73. FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
  74. FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
  75. FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
  76. /*!< Enable FSMC Bank1_SRAM3 Bank */
  77. FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);
  78. }
  79. /*
  80. *********************************************************************************************************
  81. * 函 数 名: dm9k_ReadReg
  82. * 功能说明: 读出DM9K指定寄存器的值
  83. * 形 参: reg 寄存器地址
  84. * 返 回 值: 寄存器值
  85. *********************************************************************************************************
  86. */
  87. uint8_t dm9k_ReadReg(uint8_t reg)
  88. {
  89. NET_REG_ADDR = reg;
  90. return (NET_REG_DATA);
  91. }
  92. /*
  93. *********************************************************************************************************
  94. * 函 数 名: dm9k_WriteReg
  95. * 功能说明: 读出DM9K指定寄存器的值
  96. * 形 参: reg :寄存器地址
  97. * writedata : 写入的数据
  98. * 返 回 值: 无
  99. *********************************************************************************************************
  100. */
  101. void dm9k_WriteReg(uint8_t reg, uint8_t writedata)
  102. {
  103. NET_REG_ADDR = reg;
  104. NET_REG_DATA = writedata;
  105. }
  106. /*
  107. *********************************************************************************************************
  108. * 函 数 名: dm9k_hash_table
  109. * 功能说明: 设置 DM9KA MAC 、 广播 、 多播 寄存器
  110. * 形 参: 无
  111. * 返 回 值: 无
  112. *********************************************************************************************************
  113. */
  114. void dm9k_hash_table()
  115. {
  116. uint8_t i;
  117. /* 设置 网卡 MAC 位置,来自於 MyHardware */
  118. dm9k_WriteReg(DM9K_REG_PAR, DM9K_MAC_ADDR0);
  119. dm9k_WriteReg(DM9K_REG_PAR + 1, DM9K_MAC_ADDR1);
  120. dm9k_WriteReg(DM9K_REG_PAR + 2, DM9K_MAC_ADDR2);
  121. dm9k_WriteReg(DM9K_REG_PAR + 3, DM9K_MAC_ADDR3);
  122. dm9k_WriteReg(DM9K_REG_PAR + 4, DM9K_MAC_ADDR4);
  123. dm9k_WriteReg(DM9K_REG_PAR + 5, DM9K_MAC_ADDR5);
  124. /* 清除 网卡多播设置 */
  125. for (i = 0; i < 8; i++)
  126. {
  127. dm9k_WriteReg(DM9K_REG_MAR + i, 0x00);
  128. }
  129. /* 设置 广播包 设置 */
  130. dm9k_WriteReg(DM9K_REG_MAR + 7, 0x80);
  131. }
  132. /*
  133. *********************************************************************************************************
  134. * 函 数 名: dm9k_reset
  135. * 功能说明: 软件复位DM9KAE
  136. * 形 参: 无
  137. * 返 回 值: 无
  138. *********************************************************************************************************
  139. */
  140. void dm9k_reset(void)
  141. {
  142. dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET); /* 对 DM9KA 进行软件重置 */
  143. us_delay(10); /* delay 10us */
  144. dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET); /* 对 DM9KA 进行软件重置 */
  145. us_delay(10); /* delay 10us */
  146. /* 基本记存器相关设置 */
  147. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 开启内存自环模式 */
  148. dm9k_WriteReg(DM9K_REG_TCR2, DM9K_TCR2_SET); /* 设置 LED 显示模式1:全双工亮,半双工灭 */
  149. /* 清除多余资讯 */
  150. dm9k_WriteReg(DM9K_REG_NSR, 0x2c);
  151. dm9k_WriteReg(DM9K_REG_TCR, 0x00);
  152. dm9k_WriteReg(DM9K_REG_ISR, 0x3f);
  153. #ifdef DM9KA_FLOW_CONTROL
  154. dm9k_WriteReg(DM9K_REG_BPTR, DM9K_BPTR_SET); /* 半双工流控设置 */
  155. dm9k_WriteReg(DM9K_REG_FCTR, DM9K_FCTR_SET); /* 全双工流控设置 */
  156. dm9k_WriteReg(DM9K_REG_FCR, DM9K_FCR_SET); /* 开启流控设置 */
  157. #endif
  158. #ifdef DM9KA_UPTO_100M
  159. /* DM9KA无此寄存器 */
  160. dm9k_WriteReg(DM9K_REG_OTCR, DM9K_OTCR_SET); /* 工作频率到 100Mhz 设置 */
  161. #endif
  162. #ifdef Rx_Int_enable
  163. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 开启 中断模式 */
  164. #else
  165. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 关闭 中断模式 */
  166. #endif
  167. dm9k_WriteReg(DM9K_REG_RCR, DM9K_RCR_SET); /* 开启 接收工能 */
  168. SendPackOk = 0;
  169. }
  170. /*
  171. *********************************************************************************************************
  172. * 函 数 名: dm9k_phy_write
  173. * 功能说明: 软件复位DM9KAE
  174. * 形 参: phy_reg : PHY寄存器地址
  175. * writedata : 写入的数据
  176. * 返 回 值: 无
  177. *********************************************************************************************************
  178. */
  179. void dm9k_phy_write(uint8_t phy_reg, uint16_t writedata)
  180. {
  181. /* 设置写入 PHY 寄存器的位置 */
  182. dm9k_WriteReg(DM9K_REG_EPAR, phy_reg | DM9K_PHY);
  183. /* 设置写入 PHY 寄存器的值 */
  184. dm9k_WriteReg(DM9K_REG_EPDRH, (writedata >> 8) & 0xff);
  185. dm9k_WriteReg(DM9K_REG_EPDRL, writedata & 0xff);
  186. dm9k_WriteReg(DM9K_REG_EPCR, 0x0a); /* 将资料写入 PHY 寄存器 */
  187. while (dm9k_ReadReg(DM9K_REG_EPCR) & 0x01)
  188. ; /* 查寻是否执行结束 */
  189. dm9k_WriteReg(DM9K_REG_EPCR, 0x08); /* 清除写入命令 */
  190. }
  191. /*
  192. *********************************************************************************************************
  193. * 函 数 名: dm9k_initnic
  194. * 功能说明: 配置DM9KAE芯片(初始化)
  195. * 形 参: 无
  196. * 返 回 值: 无
  197. *********************************************************************************************************
  198. */
  199. static void dm9k_initnic(void)
  200. {
  201. dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET); /* 对 DM9KA 进行软件重置 */
  202. us_delay(10); /* delay 10us */
  203. dm9k_hash_table(); /* 设置 DM9KA MAC 及 多播*/
  204. dm9k_reset(); /* 进行 DM9KA 软件设置 */
  205. dm9k_WriteReg(DM9K_REG_GPR, DM9K_PHY_OFF); /* 关闭 PHY ,进行 PHY 设置*/
  206. dm9k_phy_write(0x00, 0x8000); /* 重置 PHY 的寄存器 */
  207. #ifdef DM9KA_FLOW_CONTROL
  208. dm9k_phy_write(0x04, 0x01e1 | 0x0400); /* 设置 自适应模式相容表 */
  209. #else
  210. dm9k_phy_write(0x04, 0x01e1); /* 设置 自适应模式相容表 */
  211. #endif
  212. // dm9k_phy_write(0x00, 0x1000); /* 设置 基本连接模式 */
  213. /* 连接模式设置
  214. 0x0000 : 固定10M半双工
  215. 0x0100 : 固定10M全双工
  216. 0x2000 : 固定100M半双工
  217. 0x2100 : 固定100M全双工
  218. 0x1000 : 自适应模式
  219. */
  220. dm9k_phy_write(0x00, 0x1000); /* 设置 基本连接模式 */
  221. dm9k_WriteReg(DM9K_REG_GPR, DM9K_PHY_ON); /* 结束 PHY 设置, 开启 PHY */
  222. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 设置中断 */
  223. EXTI_InitTypeDef EXTI_InitStructure;
  224. NVIC_InitTypeDef NVIC_InitStructure;
  225. SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource14);
  226. /* 配置 EXTI LineXXX */
  227. EXTI_InitStructure.EXTI_Line = EXTI_Line2 | EXTI_Line3 | EXTI_Line7 | EXTI_Line8 | EXTI_Line11 | EXTI_Line13 | EXTI_Line14;
  228. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  229. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  230. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  231. EXTI_Init(&EXTI_InitStructure);
  232. NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
  233. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  234. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  235. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  236. NVIC_Init(&NVIC_InitStructure);
  237. // dm9k_debug_test();
  238. }
  239. /*
  240. *********************************************************************************************************
  241. * 函 数 名: dm9k_receive_packet
  242. * 功能说明: 配置DM9KAE芯片(初始化)
  243. * 形 参: _uip_buf : 接收结果存放的缓冲区指针
  244. * 返 回 值: > 0 表示接收的数据长度, 0表示没有数据
  245. *********************************************************************************************************
  246. */
  247. uint16_t dm9k_receive_packet(uint8_t *_uip_buf)
  248. {
  249. uint16_t ReceiveLength;
  250. uint16_t *ReceiveData;
  251. uint8_t rx_int_count = 0;
  252. uint8_t rx_checkbyte;
  253. uint16_t rx_status, rx_length;
  254. uint8_t jump_packet;
  255. uint16_t i;
  256. uint16_t calc_len;
  257. uint16_t calc_MRR;
  258. do
  259. {
  260. ReceiveLength = 0; /* 清除接收的长度 */
  261. ReceiveData = (uint16_t *)_uip_buf;
  262. jump_packet = 0; /* 清除跳包动作 */
  263. dm9k_ReadReg(DM9K_REG_MRCMDX); /* 读取内存数据,地址不增加 */
  264. /* 计算内存数据位置 */
  265. calc_MRR = (dm9k_ReadReg(DM9K_REG_MRRH) << 8) + dm9k_ReadReg(DM9K_REG_MRRL);
  266. rx_checkbyte = dm9k_ReadReg(DM9K_REG_MRCMDX); /* */
  267. if (rx_checkbyte == DM9K_PKT_RDY) /* 取 */
  268. {
  269. /* 读取封包相关资讯 及 长度 */
  270. NET_REG_ADDR = DM9K_REG_MRCMD;
  271. rx_status = NET_REG_DATA;
  272. rx_length = NET_REG_DATA;
  273. /* 若收到超过系统可承受的封包,此包跳过 */
  274. if (rx_length > Max_Ethernet_Lenth)
  275. jump_packet = 1;
  276. #ifdef Broadcast_Jump
  277. /* 若收到的广播或多播包超过特定长度,此包跳过 */
  278. if (rx_status & 0x4000)
  279. {
  280. if (rx_length > Max_Broadcast_Lenth)
  281. jump_packet = 1;
  282. }
  283. #endif
  284. /* 计算下一个包的指针位 , 若接收长度为奇数,需加一对齐偶字节。*/
  285. /* 若是超过 0x3fff ,则需回归绕到 0x0c00 起始位置 */
  286. calc_MRR += (rx_length + 4);
  287. if (rx_length & 0x01)
  288. calc_MRR++;
  289. if (calc_MRR > 0x3fff)
  290. calc_MRR -= 0x3400;
  291. if (jump_packet == 0x01)
  292. {
  293. /* 将指针移到下一个包的包头位置 */
  294. dm9k_WriteReg(DM9K_REG_MRRH, (calc_MRR >> 8) & 0xff);
  295. dm9k_WriteReg(DM9K_REG_MRRL, calc_MRR & 0xff);
  296. continue;
  297. }
  298. /* 开始将内存的资料搬到到系统中,每次移动一个 word */
  299. calc_len = (rx_length + 1) >> 1;
  300. for (i = 0; i < calc_len; i++)
  301. ReceiveData[i] = NET_REG_DATA;
  302. /* 将包长回报给 TCP/IP 上层,并减去最後 4 BYTE 的 CRC-32 检核码 */
  303. ReceiveLength = rx_length - 4;
  304. rx_int_count++; /* 累计收包次数 */
  305. #ifdef FifoPointCheck
  306. if (calc_MRR != ((dm9k_ReadReg(DM9K_REG_MRRH) << 8) + dm9k_ReadReg(DM9K_REG_MRRL)))
  307. {
  308. #ifdef Point_Error_Reset
  309. dm9k_reset(); /* 若是指针出错,重置 */
  310. return ReceiveLength;
  311. #endif
  312. /*若是指针出错,将指针移到下一个包的包头位置 */
  313. dm9k_WriteReg(DM9K_REG_MRRH, (calc_MRR >> 8) & 0xff);
  314. dm9k_WriteReg(DM9K_REG_MRRL, calc_MRR & 0xff);
  315. }
  316. #endif
  317. return ReceiveLength;
  318. }
  319. else
  320. {
  321. if (rx_checkbyte == DM9K_PKT_NORDY) /* 未收到包 */
  322. {
  323. dm9k_WriteReg(DM9K_REG_ISR, 0x3f); /* */
  324. }
  325. else
  326. {
  327. dm9k_reset(); /* 接收指针出错,重置 */
  328. }
  329. return (0);
  330. }
  331. } while (rx_int_count < Max_Int_Count); /* 是否超过最多接收封包计数 */
  332. return 0;
  333. }
  334. /*
  335. *********************************************************************************************************
  336. * 函 数 名: dm9k_send_packet
  337. * 功能说明: 发送一包数据
  338. * 形 参: p_char : 发送数据缓冲区
  339. * 返 回 值: length : 数据长度
  340. *********************************************************************************************************
  341. */
  342. void dm9k_send_packet(uint8_t *p_char, uint16_t length)
  343. {
  344. uint16_t SendLength = length;
  345. uint16_t *SendData = (uint16_t *)p_char;
  346. uint16_t i;
  347. uint16_t calc_len;
  348. __IO uint16_t calc_MWR;
  349. /* 检查 DM9KA 是否还在传送中!若是等待直到传送结束 */
  350. if (SendPackOk == Max_Send_Pack)
  351. {
  352. while (dm9k_ReadReg(DM9K_REG_TCR) & DM9K_TCR_SET)
  353. {
  354. us_delay(5);
  355. }
  356. SendPackOk = 0;
  357. }
  358. SendPackOk++; /* 设置传送计数 */
  359. #ifdef FifoPointCheck
  360. /* 计算下一个传送的指针位 , 若接收长度为奇数,需加一对齐偶字节。*/
  361. /* 若是超过 0x0bff ,则需回归绕到 0x0000 起始位置 */
  362. calc_MWR = (dm9k_ReadReg(DM9K_REG_MWRH) << 8) + dm9k_ReadReg(DM9K_REG_MWRL);
  363. calc_MWR += SendLength;
  364. if (SendLength & 0x01)
  365. calc_MWR++;
  366. if (calc_MWR > 0x0bff)
  367. calc_MWR -= 0x0c00;
  368. #endif
  369. dm9k_WriteReg(DM9K_REG_TXPLH, (SendLength >> 8) & 0xff); /* 设置传送封包的长度 */
  370. dm9k_WriteReg(DM9K_REG_TXPLL, SendLength & 0xff);
  371. /* 开始将系统的资料搬到到内存中,每次移动一个 word */
  372. NET_REG_ADDR = DM9K_REG_MWCMD;
  373. calc_len = (SendLength + 1) >> 1;
  374. for (i = 0; i < calc_len; i++)
  375. NET_REG_DATA = SendData[i];
  376. dm9k_WriteReg(DM9K_REG_TCR, DM9K_TCR_SET); /* 进行传送 */
  377. #ifdef FifoPointCheck
  378. if (calc_MWR != ((dm9k_ReadReg(DM9K_REG_MWRH) << 8) + dm9k_ReadReg(DM9K_REG_MWRL)))
  379. {
  380. #ifdef Point_Error_Reset
  381. /* 若是指针出错,等待此一封包送完 , 之後进行重置 */
  382. while (dm9k_ReadReg(DM9K_REG_TCR) & DM9K_TCR_SET)
  383. bsp_DelayUS(5);
  384. dm9k_reset();
  385. return;
  386. #endif
  387. /*若是指针出错,将指针移到下一个传送包的包头位置 */
  388. dm9k_WriteReg(DM9K_REG_MWRH, (calc_MWR >> 8) & 0xff);
  389. dm9k_WriteReg(DM9K_REG_MWRL, calc_MWR & 0xff);
  390. }
  391. #endif
  392. return;
  393. }
  394. /*******************************************************************************
  395. * 函数名: etherdev_send
  396. * 参 数: p_char : 数据缓冲区
  397. * length : 数据长度
  398. * 返 回: 无
  399. * 功 能: uIP 接口函数,发送一包数据
  400. */
  401. void etherdev_send(uint8_t *p_char, uint16_t length)
  402. {
  403. dm9k_send_packet(p_char, length);
  404. }
  405. uint16_t etherdev_read(uint8_t *p_char)
  406. {
  407. return dm9k_receive_packet(p_char);
  408. }
  409. /*******************************************************************************
  410. * 函数名: etherdev_chkmedia
  411. * 参 数: p_char : 数据缓冲区
  412. * length : 数据长度
  413. * 返 回: 无
  414. * 功 能: uIP 接口函数, 检测网络连接状态
  415. */
  416. void etherdev_chkmedia(void)
  417. {
  418. // uint8_t status;
  419. while (!(dm9k_ReadReg(DM9K_REG_NSR) & DM9K_PHY))
  420. {
  421. us_delay(2000);
  422. }
  423. }
  424. /*
  425. *********************************************************************************************************
  426. * 函 数 名: dm9k_interrupt
  427. * 功能说明: 中断处理函数 (webserver例程未使用中断)
  428. * 形 参: 无
  429. * 返 回 值: 无
  430. *********************************************************************************************************
  431. */
  432. void dm9k_interrupt(void)
  433. {
  434. uint8_t save_reg;
  435. uint16_t isr_status;
  436. save_reg = NET_REG_ADDR; /* 暂存所使用的位置 */
  437. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 关闭 DM9KA 中断 */
  438. isr_status = dm9k_ReadReg(DM9K_REG_ISR); /* 取得中断产生值 */
  439. if (isr_status & DM9K_RX_INTR)
  440. { /* 检查是否为接收中断 */
  441. // dm9k_receive_packet(); /* 执行接收处理程序 */
  442. }
  443. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 开启 DM9KA 中断 */
  444. NET_REG_ADDR = save_reg; /* 回复所使用的位置 */
  445. }
  446. /*******************************************************************************
  447. * 函数名: dm9k_ReadID
  448. * 参 数: 无
  449. * 返 回: 无
  450. * 功 能: 读取芯片ID
  451. */
  452. uint32_t dm9k_ReadID(void)
  453. {
  454. uint8_t vid1, vid2, pid1, pid2;
  455. if (is_fsmc_ok == 0)
  456. {
  457. dm9k_fsmc();
  458. is_fsmc_ok = 1;
  459. }
  460. vid1 = dm9k_ReadReg(DM9K_REG_VID_L) & 0xFF;
  461. vid2 = dm9k_ReadReg(DM9K_REG_VID_H) & 0xFF;
  462. pid1 = dm9k_ReadReg(DM9K_REG_PID_L) & 0xFF;
  463. pid2 = dm9k_ReadReg(DM9K_REG_PID_H) & 0xFF;
  464. return (vid2 << 24) | (vid1 << 16) | (pid2 << 8) | pid1;
  465. }
  466. uint8_t dm9k_linkstat(void)
  467. {
  468. uint8_t linkchanged = 0;
  469. linkchanged = (dm9k_ReadReg(DM9K_PHY_BMSR) >> 6) & 0x01;
  470. return linkchanged;
  471. }
  472. #if 0
  473. /*
  474. *********************************************************************************************************
  475. * 函 数 名: dm9k_debug_test
  476. * 功能说明: 测试DM9KAE的函数,用于排错
  477. * 形 参: 无
  478. * 返 回 值: 无
  479. *********************************************************************************************************
  480. */
  481. void dm9k_debug_test(void)
  482. {
  483. uint32_t check_device;
  484. uint8_t check_iomode;
  485. uint8_t check_reg_fail = 0;
  486. uint8_t check_fifo_fail = 0;
  487. uint16_t i;
  488. uint16_t j;
  489. dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET); /* 对 DM9KA 进行软件重置 */
  490. us_delay(10); /* delay 10us */
  491. dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET); /* 对 DM9KA 进行软件重置 */
  492. us_delay(10); /* delay 10us */
  493. check_device = dm9k_ReadReg(DM9K_REG_VID_L);
  494. check_device |= dm9k_ReadReg(DM9K_REG_VID_H) << 8;
  495. check_device |= dm9k_ReadReg(DM9K_REG_PID_L) << 16;
  496. check_device |= dm9k_ReadReg(DM9K_REG_PID_H) << 24;
  497. if(check_device != 0x90000A46)
  498. {
  499. printk("DM9K_DEBUG ==> DEIVCE NOT FOUND, SYSTEM HOLD !!\n");
  500. while(1);
  501. }
  502. else
  503. {
  504. printk("DM9K_DEBUG ==> DEIVCE FOUND !!\n");
  505. }
  506. check_iomode = dm9k_ReadReg(DM9K_REG_ISR) >> 6;
  507. if(check_iomode != DM9K_WORD_MODE)
  508. {
  509. printk("DM9K_DEBUG ==> DEIVCE NOT WORD MODE, SYSTEM HOLD !!\n");
  510. while(1);
  511. }
  512. else
  513. {
  514. printk("DM9K_DEBUG ==> DEIVCE IS WORD MODE !!\n");
  515. }
  516. printk("DM9K_DEBUG ==> REGISTER R/W TEST !!\n");
  517. NET_REG_ADDR = DM9K_REG_MAR;
  518. for(i = 0; i < 0x0100; i++)
  519. {
  520. NET_REG_DATA = i;
  521. if(i != (NET_REG_DATA & 0xff))
  522. {
  523. printk(" > error W %02x , R %02x \n", i , NET_REG_DATA);
  524. check_reg_fail = 1;
  525. }
  526. }
  527. if(check_reg_fail)
  528. {
  529. printk("DM9K_DEBUG ==> REGISTER R/W FAIL, SYSTEM HOLD !!\n");
  530. while(1);
  531. }
  532. printk("DM9K_DEBUG ==> FIFO R/W TEST !!\n");
  533. printk("DM9K_DEBUG ==> FIFO WRITE START POINT 0x%02x%02x \n",
  534. dm9k_ReadReg(DM9K_REG_MWRH), dm9k_ReadReg(DM9K_REG_MWRL));
  535. NET_REG_ADDR = DM9K_REG_MWCMD;
  536. for(i = 0; i < 0x1000; i++)
  537. NET_REG_DATA = ((i & 0xff) * 0x0101);
  538. printk("DM9K_DEBUG ==> FIFO WRITE END POINT 0x%02x%02x \n",
  539. dm9k_ReadReg(DM9K_REG_MWRH), dm9k_ReadReg(DM9K_REG_MWRL));
  540. if((dm9k_ReadReg(DM9K_REG_MWRH) != 0x20) || (dm9k_ReadReg(DM9K_REG_MWRL) != 0x00))
  541. {
  542. printk("DM9K_DEBUG ==> FIFO WRITE FAIL, SYSTEM HOLD !!\n");
  543. while(1);
  544. }
  545. dm9k_ReadReg(DM9K_REG_MRCMDX);
  546. printk("DM9K_DEBUG ==> FIFO READ START POINT 0x%02x%02x \n",
  547. dm9k_ReadReg(DM9K_REG_MRRH), dm9k_ReadReg(DM9K_REG_MRRL));
  548. dm9k_ReadReg(DM9K_REG_MRCMDX);
  549. NET_REG_ADDR = DM9K_REG_MRCMD;
  550. for(i = 0; i < 0x1000; i++)
  551. {
  552. j = NET_REG_DATA;
  553. if(((i & 0xff) * 0x0101) != j)
  554. {
  555. //printk(" > error W %04x , R %04x \n",
  556. // ((i & 0xff) * 0x0101) , j);
  557. check_fifo_fail = 1;
  558. }
  559. }
  560. printk("DM9K_DEBUG ==> FIFO READ END POINT 0x%02x%02x \n",
  561. dm9k_ReadReg(DM9K_REG_MRRH), dm9k_ReadReg(DM9K_REG_MRRL));
  562. if((dm9k_ReadReg(DM9K_REG_MRRH) != 0x20) || (dm9k_ReadReg(DM9K_REG_MRRL) != 0x00))
  563. {
  564. printk("DM9K_DEBUG ==> FIFO WRITE FAIL, SYSTEM HOLD !!\n");
  565. while(1);
  566. }
  567. if(check_fifo_fail)
  568. {
  569. printk("DM9K_DEBUG ==> FIFO R/W DATA FAIL, SYSTEM HOLD !!\n");
  570. while(1);
  571. }
  572. printk("DM9K_DEBUG ==> PACKET SEND & INT TEST !! \n");
  573. dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET);
  574. us_delay(10);
  575. dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET);
  576. us_delay(10);
  577. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF | DM9K_TX_INTR);
  578. dm9k_WriteReg(DM9K_REG_TXPLH, 0x01);
  579. dm9k_WriteReg(DM9K_REG_TXPLL, 0x00);
  580. do
  581. {
  582. dm9k_WriteReg(DM9K_REG_ISR, DM9K_TX_INTR);
  583. printk("DM9K_DEBUG ==> INT PIN IS OFF\n");
  584. NET_REG_ADDR = DM9K_REG_MWCMD;
  585. for(i = 0; i < (0x0100 / 2); i++)
  586. {
  587. if(i < 3)
  588. NET_REG_DATA = 0xffff;
  589. else
  590. NET_REG_DATA = i * 0x0101;
  591. }
  592. printk("DM9K_DEBUG ==> PACKET IS SEND \n");
  593. dm9k_WriteReg(DM9K_REG_TCR, DM9K_TCR_SET);
  594. while(dm9k_ReadReg(DM9K_REG_TCR) & DM9K_TCR_SET) bsp_DelayUS (5);
  595. if(dm9k_ReadReg(DM9K_REG_ISR) & DM9K_TX_INTR)
  596. printk("DM9K_DEBUG ==> INT PIN IS ACTIVE \n");
  597. else
  598. printk("DM9K_DEBUG ==> INT PIN IS NOT ACTIVE \n");
  599. for(i = 0; i < 10; i++)
  600. bsp_DelayUS(1000);
  601. }while(1);
  602. }
  603. /*
  604. *********************************************************************************************************
  605. * 函 数 名: etherdev_chkmedia
  606. * 功能说明: 检测网络连接状态
  607. * 形 参: 无
  608. * 返 回 值: 无
  609. *********************************************************************************************************
  610. */
  611. void etherdev_chkmedia(void)
  612. {
  613. // uint8_t status;
  614. while(!(dm9k_ReadReg(DM9K_REG_NSR) & DM9K_PHY))
  615. {
  616. bsp_DelayUS(2000);
  617. }
  618. }
  619. /*******************************************************************************
  620. * 函数名: etherdev_poll
  621. * 参 数: 无
  622. * 返 回: 无
  623. * 功 能: uIP 接口函数, 采用查询方式接收一个IP包
  624. */
  625. /*
  626. etherdev_poll()
  627. This function will read an entire IP packet into the uip_buf.
  628. If it must wait for more than 0.5 seconds, it will return with
  629. the return value 0. Otherwise, when a full packet has been read
  630. into the uip_buf buffer, the length of the packet is returned.
  631. */
  632. uint16_t etherdev_poll(void)
  633. {
  634. uint16_t bytes_read = 0;
  635. #if 0
  636. /* tick_count threshold should be 12 for 0.5 sec bail-out
  637. One second (24) worked better for me, but socket recycling
  638. is then slower. I set UIP_TIME_WAIT_TIMEOUT 60 in uipopt.h
  639. to counter this. Retransmission timing etc. is affected also. */
  640. while ((!(bytes_read = etherdev_read())) && (timer0_tick() < 12)) continue;
  641. timer0_reset();
  642. #endif
  643. return bytes_read;
  644. }
  645. #endif