dm9k.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  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. #include "interface.h"
  20. #include "lwip_dm9k.h"
  21. /****************************************************************************
  22. * Copyright (C), 2009-2010, www.armfly.com 安富莱电子
  23. *
  24. * 【本驱动在安富莱STM32F103ZE-EK开发板上调试通过 】
  25. * 【QQ: 1295744630, 旺旺:armfly, Email: [email protected]
  26. *
  27. * 文件名: dm9k_uip.c
  28. * 内容简述: Davicom DM9KA uP NIC fast Ethernet driver for uIP.
  29. *
  30. * 文件历史:
  31. * 版本号 日期 作者 说明
  32. * v0.1 2010-01-18 armfly 创建该文件
  33. *
  34. */
  35. #include "Lwip_init.h"
  36. /* DM9KA 接收函数设置宏 */
  37. //#define Rx_Int_enable
  38. #define Max_Int_Count 1
  39. #define Broadcast_Jump
  40. #define Max_Broadcast_Lenth 500
  41. /* DM9KA 传送函数设置宏 */
  42. #define Max_Send_Pack 2
  43. //#define FifoPointCheck
  44. //#define DM9KA_FLOW_CONTROL
  45. //#define DM9KA_UPTO_100M
  46. //#define Fifo_Point_Check
  47. //#define Point_Error_Reset
  48. #define Fix_Note_Address
  49. /*=============================================================================
  50. 系统全域的变量
  51. =============================================================================*/
  52. uint8_t SendPackOk = 0;
  53. uint8_t s_FSMC_Init_Ok = 0; /* 用于指示FSMC是否初始化 */
  54. //#define printk(...)
  55. #define printk myprintf
  56. void dm9k_debug_test(void);
  57. void dm9k_udelay(uint16_t time);
  58. static void dm9k_fsmc(void);
  59. /*******************************************************************************
  60. * 函数名: dm9k_udelay
  61. * 参 数: time : 延迟时间,不精确,us级别
  62. * 返 回: 无
  63. * 功 能: 延迟函数
  64. */
  65. void dm9k_udelay(uint16_t time)
  66. {
  67. us_delay(time);
  68. }
  69. /*******************************************************************************
  70. * 函数名: ior
  71. * 参 数: reg :寄存器地址
  72. * 返 回: 无
  73. * 功 能: 读出寄存器的值
  74. */
  75. uint8_t dm9k_ReadReg(uint8_t reg)
  76. {
  77. NET_REG_ADDR = reg;
  78. return (NET_REG_DATA);
  79. }
  80. /*******************************************************************************
  81. * 函数名: iow
  82. * 参 数: reg :寄存器地址
  83. * writedata : 写入的数据
  84. * 返 回: 无
  85. * 功 能: 写DM9KAE寄存器的值
  86. */
  87. void dm9k_WriteReg(uint8_t reg, uint8_t writedata)
  88. {
  89. NET_REG_ADDR = reg;
  90. NET_REG_DATA = writedata;
  91. }
  92. /*******************************************************************************
  93. * 函数名: dm9k_hash_table
  94. * 参 数: 无
  95. * 返 回: 无
  96. * 功 能: 设置 DM9KA MAC 、 广播 、 多播 寄存器
  97. */
  98. void dm9k_hash_table(uint8_t *MacAdd)
  99. {
  100. uint8_t i;
  101. /* 设置 网卡 MAC 位置,来自於 MyHardware */
  102. for (i = 0; i < 6; i++)
  103. dm9k_WriteReg(DM9K_REG_PAR + i, MacAdd[i]);
  104. for (i = 0; i < 8; i++) /* 清除 网卡多播设置 */
  105. dm9k_WriteReg(DM9K_REG_MAR + i, 0xff);
  106. }
  107. /*******************************************************************************
  108. * 函数名: dm9k_reset
  109. * 参 数: 无
  110. * 返 回: 无
  111. * 功 能: 对DM9KAE进行软件复位
  112. */
  113. void dm9k_reset(void)
  114. {
  115. dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET); /* 对 DM9KA 进行软件重置 */
  116. dm9k_udelay(10); /* delay 10us */
  117. dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET); /* 对 DM9KA 进行软件重置 */
  118. dm9k_udelay(10); /* delay 10us */
  119. /* 基本记存器相关设置 */
  120. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 开启内存自环模式 */
  121. dm9k_WriteReg(DM9K_REG_TCR2, DM9K_TCR2_SET); /* 设置 LED 显示模式1:全双工亮,半双工灭 */
  122. /* 清除多余资讯 */
  123. dm9k_WriteReg(DM9K_REG_NSR, 0x2c);
  124. dm9k_WriteReg(DM9K_REG_TCR, 0x00);
  125. dm9k_WriteReg(DM9K_REG_ISR, 0x3f);
  126. #ifdef DM9KA_FLOW_CONTROL
  127. dm9k_WriteReg(DM9K_REG_BPTR, DM9K_BPTR_SET); /* 半双工流控设置 */
  128. dm9k_WriteReg(DM9K_REG_FCTR, DM9K_FCTR_SET); /* 全双工流控设置 */
  129. dm9k_WriteReg(DM9K_REG_FCR, DM9K_FCR_SET); /* 开启流控设置 */
  130. #endif
  131. #ifdef DM9KA_UPTO_100M
  132. /* DM9KA无此寄存器 */
  133. dm9k_WriteReg(DM9K_REG_OTCR, DM9K_OTCR_SET); /* 工作频率到 100Mhz 设置 */
  134. #endif
  135. #ifdef Rx_Int_enable
  136. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 开启 中断模式 */
  137. #else
  138. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 关闭 中断模式 */
  139. #endif
  140. dm9k_WriteReg(DM9K_REG_RCR, DM9K_RCR_SET); /* 开启 接收工能 */
  141. SendPackOk = 0;
  142. }
  143. /*******************************************************************************
  144. * 函数名: dm9k_phy_write
  145. * 参 数: phy_reg : 寄存器地址
  146. * writedata : 写入的数据
  147. * 返 回: 无
  148. * 功 能: 写DM9KA PHY 寄存器
  149. */
  150. void dm9k_phy_write(uint8_t phy_reg, uint16_t writedata)
  151. {
  152. /* 设置写入 PHY 寄存器的位置 */
  153. dm9k_WriteReg(DM9K_REG_EPAR, phy_reg | DM9K_PHY);
  154. /* 设置写入 PHY 寄存器的值 */
  155. dm9k_WriteReg(DM9K_REG_EPDRH, (writedata >> 8) & 0xff);
  156. dm9k_WriteReg(DM9K_REG_EPDRL, writedata & 0xff);
  157. dm9k_WriteReg(DM9K_REG_EPCR, 0x0a); /* 将资料写入 PHY 寄存器 */
  158. while (dm9k_ReadReg(DM9K_REG_EPCR) & 0x01)
  159. ; /* 查寻是否执行结束 */
  160. dm9k_WriteReg(DM9K_REG_EPCR, 0x08); /* 清除写入命令 */
  161. }
  162. /*******************************************************************************
  163. * 函数名: dm9k_phy_read
  164. * 参 数: phy_reg : 寄存器地址
  165. * 返 回: 无
  166. * 功 能: 读DM9KA PHY 寄存器
  167. */
  168. uint16_t dm9k_phy_read(uint8_t phy_reg)
  169. {
  170. uint16_t temp;
  171. /* 设置写入 PHY 寄存器的位置 */
  172. dm9k_WriteReg(DM9K_REG_EPAR, phy_reg | DM9K_PHY);
  173. /* 设置写入 PHY 寄存器的值 */
  174. dm9k_WriteReg(DM9K_REG_EPCR, 0x0C); //选中PHY,发送读命令
  175. while (dm9k_ReadReg(DM9K_REG_EPCR) & 0x01)
  176. ; /* 查寻是否执行结束 */
  177. dm9k_WriteReg(DM9K_REG_EPCR, 0x00); //清除读命令
  178. temp = (dm9k_ReadReg(DM9K_REG_EPDRH) << 8) | (dm9k_ReadReg(DM9K_REG_EPDRL));
  179. return temp;
  180. }
  181. /*******************************************************************************
  182. * 函数名: dm9k_linkstat
  183. * 参 数: 无
  184. * 返 回: 0,未连接
  185. * 1,已连接
  186. * 功 能: 获取DM9K的连接状态
  187. */
  188. uint8_t dm9k_linkstat(void)
  189. {
  190. uint8_t linkchanged = 0;
  191. linkchanged = (dm9k_ReadReg(DM9K_PHY_BMSR) >> 6) & 0x01;
  192. return linkchanged;
  193. }
  194. /*******************************************************************************
  195. * 函数名: DM9K_Get_SpeedAndDuplex
  196. * 参 数: 无
  197. * 返 回: 0,100M半双工
  198. * 1,100M全双工
  199. * 2,10M半双工
  200. * 3,10M全双工
  201. * 0XFF,连接失败!
  202. * 功 能: 获取DM9K的连接速度和双工模式
  203. */
  204. uint8_t DM9K_Get_SpeedAndDuplex(void)
  205. {
  206. uint8_t temp;
  207. uint8_t i = 0;
  208. while (!(dm9k_phy_read(DM9K_PHY_BMSR) & 0x0020)) //等待自动协商完成
  209. {
  210. ms_delay(100);
  211. i++;
  212. if (i > 100)
  213. return 0XFF; //自动协商失败
  214. }
  215. temp = ((dm9k_ReadReg(DM9K_REG_NSR) >> 6) & 0x02); //获取DM9K的连接速度 0:100M 1:10M
  216. temp |= ((dm9k_ReadReg(DM9K_REG_NCR) >> 3) & 0x01); //获取DM9K的双工状态
  217. return temp;
  218. }
  219. /*******************************************************************************
  220. * 函数名: dm9k_initnic
  221. * 参 数: 无
  222. * 返 回: 无
  223. * 功 能: 初始化DM9KAE
  224. */
  225. void dm9k_initnic(void)
  226. {
  227. // uint8_t temp;
  228. if (DM9KA_ID != dm9k_ReadID()) /* 进行 设备ID读取判断 */
  229. return;
  230. dm9k_WriteReg(DM9K_REG_GPCR, 0x01); /* 设置GPCR bit[0]=1,使DM9K为GPIO0为输出 */
  231. dm9k_WriteReg(DM9K_REG_GPR, 0x00); /* GPR bit[0]=0,使GPIO0输出低电平以激活内部PHY */
  232. ms_delay(5);
  233. dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET); /* 对 DM9KA 进行软件重置 */
  234. dm9k_udelay(100); /* delay 100us */
  235. dm9k_WriteReg(DM9K_REG_NCR, DM9K_REG_RESET); /* 对 DM9KA 进行软件重置 */
  236. dm9k_udelay(100); /* delay 100us */
  237. /* 清除多余资讯 */
  238. dm9k_WriteReg(DM9K_REG_NCR, 0x00); /* 复位完成,设置正常工作模式 */
  239. dm9k_WriteReg(DM9K_REG_NSR, 0x2c); /* 清除各种状态标志位 */
  240. dm9k_WriteReg(DM9K_REG_TCR, 0x00); /* 清除 发送控制寄存器 */
  241. dm9k_WriteReg(DM9K_REG_ISR, 0x3f); /* 清除 中断状态寄存器 */
  242. /* 基本记存器相关设置 */
  243. dm9k_WriteReg(DM9K_REG_IMR, 0x80); /* 开启内存自环模式 */
  244. dm9k_WriteReg(DM9K_REG_TCR2, 0x80); /* 设置 LED 显示模式1:全双工亮,半双工灭 */
  245. dm9k_WriteReg(DM9K_REG_BPTR, 0x3F); /* 半双工流控设置 默认 0x37 */
  246. dm9k_WriteReg(DM9K_REG_FCTR, 0x38); /* 全双工流控设置 默认 0x38 */
  247. dm9k_WriteReg(DM9K_REG_RCR, DM9K_RCR_SET); /* 开启 接收工能 */
  248. dm9k_hash_table(dm9kdev.mac); /* 设置 DM9KA MAC 及 多播*/
  249. dm9k_WriteReg(DM9K_REG_GPR, DM9K_PHY_OFF); /* 关闭 PHY ,进行 PHY 设置*/
  250. dm9k_phy_write(DM9K_PHY_BMCR, 0x8000); /* 重置 PHY 的寄存器 */
  251. /* 连接模式设置
  252. 0x0000 : 固定10M半双工 ANAR_Value:0x21
  253. 0x0100 : 固定10M全双工 ANAR_Value:0x41
  254. 0x2000 : 固定100M半双工 ANAR_Value:0x81
  255. 0x2100 : 固定100M全双工 ANAR_Value:0x0101
  256. 0x1000 : 自适应模式 ANAR_Value:0x01E1
  257. */
  258. dm9k_phy_write(DM9K_PHY_BMCR, 0x1000); /* 设置 基本连接模式 */
  259. dm9k_phy_write(DM9K_PHY_ANAR, 0x01E1); /* 设置 自适应模式相容表 */
  260. dm9k_WriteReg(DM9K_REG_GPR, DM9K_PHY_ON); /* 结束 PHY 设置, 开启 PHY */
  261. // temp = DM9K_Get_SpeedAndDuplex(); /* 获取DM9K的连接速度和双工状态 */
  262. // if(temp != 0xFF) /* 连接成功,通过串口显示连接速度和双工状态 */
  263. // {
  264. // myprintf("DM9K Speed:%dMbps,Duplex:%s duplex mode\r\n", (temp & 0x02) ? 10 : 100, (temp & 0x01) ? "Full" : "Half");
  265. // }
  266. // else
  267. // {
  268. // myprintf("DM9K Establish Link Failed!\r\n");
  269. // }
  270. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 设置中断 */
  271. EXTI_InitTypeDef EXTI_InitStructure;
  272. NVIC_InitTypeDef NVIC_InitStructure;
  273. SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, GPIO_PinSource15);
  274. /* 配置 EXTI LineXXX */
  275. EXTI_InitStructure.EXTI_Line = EXTI_Line15;
  276. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  277. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  278. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  279. EXTI_Init(&EXTI_InitStructure);
  280. EXTI_ClearITPendingBit(EXTI_Line15);
  281. NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
  282. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8;
  283. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  284. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  285. NVIC_Init(&NVIC_InitStructure);
  286. SendPackOk = 0;
  287. }
  288. /*******************************************************************************
  289. * 函数名: dm9k_receive_packet
  290. * 参 数: _uip_buf : 接收缓冲区
  291. * 返 回: > 0 表示接收的数据长度, 0表示没有数据
  292. * 功 能: 读取一包数据
  293. */
  294. uint16_t dm9k_receive_packet(uint8_t *_uip_buf)
  295. {
  296. uint16_t ReceiveLength;
  297. uint16_t *ReceiveData;
  298. uint8_t rx_int_count = 0;
  299. uint8_t rx_checkbyte;
  300. uint16_t rx_status, rx_length;
  301. uint8_t jump_packet;
  302. uint16_t i;
  303. uint16_t calc_len;
  304. uint16_t calc_MRR;
  305. do
  306. {
  307. ReceiveLength = 0; /* 清除接收的长度 */
  308. ReceiveData = (uint16_t *)_uip_buf;
  309. jump_packet = 0; /* 清除跳包动作 */
  310. dm9k_ReadReg(DM9K_REG_MRCMDX); /* 读取内存数据,地址不增加 */
  311. /* 计算内存数据位置 */
  312. calc_MRR = (dm9k_ReadReg(DM9K_REG_MRRH) << 8) + dm9k_ReadReg(DM9K_REG_MRRL);
  313. rx_checkbyte = dm9k_ReadReg(DM9K_REG_MRCMDX); /* */
  314. if (rx_checkbyte == DM9K_PKT_RDY) /* 取 */
  315. {
  316. /* 读取封包相关资讯 及 长度 */
  317. NET_REG_ADDR = DM9K_REG_MRCMD;
  318. rx_status = NET_REG_DATA;
  319. rx_length = NET_REG_DATA;
  320. /* 若收到超过系统可承受的封包,此包跳过 */
  321. if (rx_length > Max_Ethernet_Lenth)
  322. jump_packet = 1;
  323. #ifdef Broadcast_Jump
  324. /* 若收到的广播或多播包超过特定长度,此包跳过 */
  325. if (rx_status & 0x4000)
  326. {
  327. if (rx_length > Max_Broadcast_Lenth)
  328. jump_packet = 1;
  329. }
  330. #endif
  331. /* 计算下一个包的指针位 , 若接收长度为奇数,需加一对齐偶字节。*/
  332. /* 若是超过 0x3fff ,则需回归绕到 0x0c00 起始位置 */
  333. calc_MRR += (rx_length + 4);
  334. if (rx_length & 0x01)
  335. calc_MRR++;
  336. if (calc_MRR > 0x3fff)
  337. calc_MRR -= 0x3400;
  338. if (jump_packet == 0x01)
  339. {
  340. /* 将指针移到下一个包的包头位置 */
  341. dm9k_WriteReg(DM9K_REG_MRRH, (calc_MRR >> 8) & 0xff);
  342. dm9k_WriteReg(DM9K_REG_MRRL, calc_MRR & 0xff);
  343. continue;
  344. }
  345. /* 开始将内存的资料搬到到系统中,每次移动一个 word */
  346. calc_len = (rx_length + 1) >> 1;
  347. for (i = 0; i < calc_len; i++)
  348. ReceiveData[i] = NET_REG_DATA;
  349. /* 将包长回报给 TCP/IP 上层,并减去最後 4 BYTE 的 CRC-32 检核码 */
  350. ReceiveLength = rx_length - 4;
  351. rx_int_count++; /* 累计收包次数 */
  352. #ifdef FifoPointCheck
  353. if (calc_MRR != ((dm9k_ReadReg(DM9K_REG_MRRH) << 8) + dm9k_ReadReg(DM9K_REG_MRRL)))
  354. {
  355. #ifdef Point_Error_Reset
  356. dm9k_reset(); /* 若是指针出错,重置 */
  357. return ReceiveLength;
  358. #endif
  359. /*若是指针出错,将指针移到下一个包的包头位置 */
  360. dm9k_WriteReg(DM9K_REG_MRRH, (calc_MRR >> 8) & 0xff);
  361. dm9k_WriteReg(DM9K_REG_MRRL, calc_MRR & 0xff);
  362. }
  363. #endif
  364. return ReceiveLength;
  365. }
  366. else
  367. {
  368. if (rx_checkbyte == DM9K_PKT_NORDY) /* 未收到包 */
  369. {
  370. dm9k_WriteReg(DM9K_REG_ISR, 0x3f); /* */
  371. }
  372. else
  373. {
  374. dm9k_initnic(); /* 接收指针出错,重置 */
  375. }
  376. return (0);
  377. }
  378. } while (rx_int_count < Max_Int_Count); /* 是否超过最多接收封包计数 */
  379. return 0;
  380. }
  381. /*******************************************************************************
  382. * 函数名: dm9k_send_packet
  383. * 参 数: p_char : 发送数据缓冲区
  384. * length : 数据长度
  385. * 返 回: 无
  386. * 功 能: 发送一包数据
  387. */
  388. void dm9k_send_packet(uint8_t *p_char, uint16_t length)
  389. {
  390. uint16_t SendLength = length;
  391. uint16_t *SendData = (uint16_t *)p_char;
  392. uint16_t i;
  393. uint16_t calc_len;
  394. __IO uint16_t calc_MWR;
  395. #ifdef FifoPointCheck
  396. /* 计算下一个传送的指针位 , 若接收长度为奇数,需加一对齐偶字节。*/
  397. /* 若是超过 0x0bff ,则需回归绕到 0x0000 起始位置 */
  398. calc_MWR = (dm9k_ReadReg(DM9K_REG_MWRH) << 8) + dm9k_ReadReg(DM9K_REG_MWRL);
  399. calc_MWR += SendLength;
  400. if (SendLength & 0x01)
  401. calc_MWR++;
  402. if (calc_MWR > 0x0bff)
  403. calc_MWR -= 0x0c00;
  404. #endif
  405. dm9k_WriteReg(DM9K_REG_TXPLH, (SendLength >> 8) & 0xff); /* 设置传送封包的长度 */
  406. dm9k_WriteReg(DM9K_REG_TXPLL, SendLength & 0xff);
  407. /* 开始将系统的资料搬到到内存中,每次移动一个 word */
  408. NET_REG_ADDR = DM9K_REG_MWCMD;
  409. calc_len = (SendLength + 1) >> 1;
  410. for (i = 0; i < calc_len; i++)
  411. {
  412. NET_REG_DATA = SendData[i];
  413. }
  414. dm9k_WriteReg(DM9K_REG_TCR, DM9K_TCR_SET); /* 进行传送 */
  415. #ifdef FifoPointCheck
  416. if (calc_MWR != ((dm9k_ReadReg(DM9K_REG_MWRH) << 8) + dm9k_ReadReg(DM9K_REG_MWRL)))
  417. {
  418. #ifdef Point_Error_Reset
  419. /* 若是指针出错,等待此一封包送完 , 之後进行重置 */
  420. while (dm9k_ReadReg(DM9K_REG_TCR) & DM9K_TCR_SET)
  421. dm9k_udelay(5);
  422. dm9k_reset();
  423. return;
  424. #endif
  425. /*若是指针出错,将指针移到下一个传送包的包头位置 */
  426. dm9k_WriteReg(DM9K_REG_MWRH, (calc_MWR >> 8) & 0xff);
  427. dm9k_WriteReg(DM9K_REG_MWRL, calc_MWR & 0xff);
  428. }
  429. #endif
  430. return;
  431. }
  432. /*******************************************************************************
  433. * 函数名: dm9k_init
  434. * 参 数: 无
  435. * 返 回: 无
  436. * 功 能: uIP 接口函数,初始化网卡
  437. */
  438. void dm9k_init(void)
  439. {
  440. dm9k_fsmc();
  441. s_FSMC_Init_Ok = 1;
  442. dm9k_initnic();
  443. }
  444. /*******************************************************************************
  445. * 函数名: etherdev_send
  446. * 参 数: p_char : 数据缓冲区
  447. * length : 数据长度
  448. * 返 回: 无
  449. * 功 能: uIP 接口函数,发送一包数据
  450. */
  451. void etherdev_send(uint8_t *p_char, uint16_t length)
  452. {
  453. dm9k_send_packet(p_char, length);
  454. }
  455. uint16_t etherdev_read(uint8_t *p_char)
  456. {
  457. return dm9k_receive_packet(p_char);
  458. }
  459. /*******************************************************************************
  460. * 函数名: etherdev_chkmedia
  461. * 参 数: p_char : 数据缓冲区
  462. * length : 数据长度
  463. * 返 回: 无
  464. * 功 能: uIP 接口函数, 检测网络连接状态
  465. */
  466. void etherdev_chkmedia(void)
  467. {
  468. // uint8_t status;
  469. while (!(dm9k_ReadReg(DM9K_REG_NSR) & DM9K_PHY))
  470. {
  471. dm9k_udelay(2000);
  472. }
  473. }
  474. /*******************************************************************************
  475. * 函数名: dm9k_ReadID
  476. * 参 数: 无
  477. * 返 回: 无
  478. * 功 能: 读取芯片ID
  479. */
  480. uint32_t dm9k_ReadID(void)
  481. {
  482. uint8_t vid1, vid2, pid1, pid2;
  483. if (s_FSMC_Init_Ok == 0)
  484. {
  485. dm9k_fsmc();
  486. s_FSMC_Init_Ok = 1;
  487. }
  488. vid1 = dm9k_ReadReg(DM9K_REG_VID_L) & 0xFF;
  489. vid2 = dm9k_ReadReg(DM9K_REG_VID_H) & 0xFF;
  490. pid1 = dm9k_ReadReg(DM9K_REG_PID_L) & 0xFF;
  491. pid2 = dm9k_ReadReg(DM9K_REG_PID_H) & 0xFF;
  492. return (pid2 << 24) | (pid1 << 16) | (vid2 << 8) | vid1;
  493. }
  494. static void dm9k_fsmc(void)
  495. {
  496. FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
  497. FSMC_NORSRAMTimingInitTypeDef p;
  498. /*-- FSMC Configuration ------------------------------------------------------*/
  499. /*----------------------- SRAM Bank 3 ----------------------------------------*/
  500. /*-- FSMC Configuration ------------------------------------------------------*/
  501. p.FSMC_AddressSetupTime = 3; /* 设置为2会出错; 3正常 */
  502. p.FSMC_AddressHoldTime = 0;
  503. p.FSMC_DataSetupTime = 3; /* 设置为1出错,2正常 */
  504. p.FSMC_BusTurnAroundDuration = 0;
  505. p.FSMC_CLKDivision = 0;
  506. p.FSMC_DataLatency = 0;
  507. p.FSMC_AccessMode = FSMC_AccessMode_A;
  508. FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;
  509. FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
  510. FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; // FSMC_MemoryType_PSRAM;
  511. FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
  512. FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
  513. FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
  514. FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
  515. FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
  516. FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
  517. FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
  518. FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
  519. FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
  520. FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
  521. FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
  522. FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
  523. FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
  524. /*!< Enable FSMC Bank1_SRAM3 Bank */
  525. FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);
  526. }