ethernetif_dm9k.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /* Includes ------------------------------------------------------------------*/
  2. #include "ethernetif_dm9k.h"
  3. #include "dm9k.h"
  4. #include "lwip/tcpip.h"
  5. #include "lwip/timeouts.h"
  6. #include "lwip_dm9k.h"
  7. #include "memory_manager.h"
  8. #include "netif/etharp.h"
  9. #include "netif/ethernet.h"
  10. // #include "snmp.h"
  11. #include "lwip_init.h"
  12. #include "string.h"
  13. #define DM9K_RX_TASK_PRIO 4
  14. #define DM9K_RX_TASK_STK_SIZE 2048
  15. CPU_STK dm9k_rx_task_stk[DM9K_RX_TASK_STK_SIZE];
  16. /* Define those to better describe your network interface. */
  17. #define IFNAME0 'D'
  18. #define IFNAME1 '2'
  19. #define DM9K_RX_DESC_CNT 4
  20. #define DM9K_RX_Lenth 1536UL
  21. /* Private macro -------------------------------------------------------------*/
  22. /* Private variables ---------------------------------------------------------*/
  23. static uint8_t *Rx_Buff[DM9K_RX_DESC_CNT] = {0}; /* Ethernet Rx Buffer */
  24. uint8_t current_pbuf_idx = 0; /* Zero-copy RX PBUF pool */
  25. static struct pbuf_custom *custom_pbuf[DM9K_RX_DESC_CNT] = {0};
  26. /* Private function prototypes -----------------------------------------------*/
  27. static void pbuf_free_custom(struct pbuf *p);
  28. static void ethernetif_input(void *pvParameters);
  29. // static void ethernet_link_check_state(struct netif *netif);
  30. static OS_EVENT *g_dm9k_rx_sem = NULL;
  31. static OS_EVENT *dm9k_mutex = NULL;
  32. static struct netif *low_netif = NULL;
  33. /*
  34. *********************************************************************************************************
  35. * 函 数 名: VariableMemInit
  36. * 功能说明: 申请串口相关的变量内存
  37. * 形 参: 无
  38. * 返 回 值: 无
  39. *********************************************************************************************************
  40. */
  41. static void VariableMemInit(void)
  42. {
  43. uint16_t idx = 0;
  44. for (idx = 0; idx < DM9K_RX_DESC_CNT; idx++)
  45. {
  46. if (Rx_Buff[idx] == 0)
  47. Rx_Buff[idx] = pMemoryMalloc(&SRAM0, DM9K_RX_Lenth); // 因为不释放,避免重复申请
  48. if (custom_pbuf[idx] == 0)
  49. custom_pbuf[idx] = pMemoryMalloc(&SRAM0, sizeof(struct pbuf_custom)); // 因为不释放,避免重复申请
  50. }
  51. }
  52. static void low_level_init(struct netif *netif)
  53. {
  54. INT32U idx = 0;
  55. VariableMemInit();
  56. INT8U err;
  57. /* set MAC hardware address length */
  58. netif->hwaddr_len = ETHARP_HWADDR_LEN;
  59. /* set MAC hardware address */ /* 网卡的 MAC 修改2 */
  60. netif->hwaddr[0] = dm9kdev.mac[0];
  61. netif->hwaddr[1] = dm9kdev.mac[1];
  62. netif->hwaddr[2] = dm9kdev.mac[2];
  63. netif->hwaddr[3] = dm9kdev.mac[3];
  64. netif->hwaddr[4] = dm9kdev.mac[4];
  65. netif->hwaddr[5] = dm9kdev.mac[5];
  66. /* maximum transfer unit */
  67. netif->mtu = 1500;
  68. /* device capabilities */
  69. /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
  70. netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
  71. low_netif = netif;
  72. for (idx = 0; idx < DM9K_RX_DESC_CNT; idx++)
  73. {
  74. custom_pbuf[idx]->custom_free_function = pbuf_free_custom;
  75. }
  76. if (NULL == dm9k_mutex)
  77. {
  78. dm9k_mutex = OSMutexCreate(1, &err);
  79. }
  80. /* create binary semaphore used for informing ethernetif of frame reception */
  81. if (NULL == g_dm9k_rx_sem)
  82. {
  83. g_dm9k_rx_sem = OSSemCreate(0);
  84. }
  85. OSTaskCreateExt((void (*)(void *))ethernetif_input,
  86. (void *)0,
  87. (OS_STK *)&dm9k_rx_task_stk[DM9K_RX_TASK_STK_SIZE - 1],
  88. (INT8U)DM9K_RX_TASK_PRIO,
  89. (INT16U)DM9K_RX_TASK_PRIO,
  90. (OS_STK *)&dm9k_rx_task_stk[0],
  91. (INT32U)DM9K_RX_TASK_STK_SIZE,
  92. (void *)0,
  93. (INT16U)OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR | OS_TASK_OPT_SAVE_FP);
  94. // ethernet_link_check_state(netif);
  95. }
  96. /**
  97. * @brief This function should do the actual transmission of the packet. The packet is
  98. * contained in the pbuf that is passed to the function. This pbuf
  99. * might be chained.
  100. *
  101. * @param netif the lwip network interface structure for this ethernetif
  102. * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
  103. * @return ERR_OK if the packet could be sent
  104. * an err_t value if the packet couldn't be sent
  105. *
  106. * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
  107. * strange results. You might consider waiting for space in the DMA queue
  108. * to become available since the stack doesn't retry to send a packet
  109. * dropped because of memory failure (except for the TCP timers).
  110. */
  111. static err_t low_level_output(struct netif *netif, struct pbuf *p)
  112. {
  113. INT8U err;
  114. err_t errval = ERR_OK;
  115. uint32_t i = 0, framelen = 0, calc_len = 0;
  116. struct pbuf *q;
  117. SYS_ARCH_DECL_PROTECT(sr);
  118. OSMutexPend(dm9k_mutex, 1000, &err);
  119. SYS_ARCH_PROTECT(sr);
  120. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 关闭 dm9kA 中断 */
  121. NET_REG_ADDR = DM9K_REG_MWCMD;
  122. for (q = p; q != NULL; q = q->next)
  123. {
  124. framelen = framelen + q->len;
  125. calc_len = (q->len + 1) >> 1;
  126. for (i = 0; i < calc_len; i++)
  127. {
  128. NET_REG_DATA = ((uint16_t *)q->payload)[i];
  129. }
  130. }
  131. dm9k_WriteReg(DM9K_REG_TXPLH, (framelen >> 8) & 0xff); /* 设置传送封包的长度 */
  132. dm9k_WriteReg(DM9K_REG_TXPLL, framelen & 0xff);
  133. dm9k_WriteReg(DM9K_REG_TCR, DM9K_TCR_SET); /* 进行传送 */
  134. while ((dm9k_ReadReg(DM9K_REG_ISR) & 0x02) == 0)
  135. ; /* 等待发送完成 */
  136. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 开启 dm9kA 中断 */
  137. SYS_ARCH_UNPROTECT(sr);
  138. OSMutexPost(dm9k_mutex);
  139. return errval;
  140. }
  141. static struct pbuf *low_level_input(struct netif *netif)
  142. {
  143. struct pbuf *p = NULL;
  144. uint32_t framelen = 0;
  145. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 关闭 DM9000A 中断 */
  146. framelen = etherdev_read(Rx_Buff[current_pbuf_idx]);
  147. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 开启 DM9000A 中断 */
  148. if (framelen)
  149. {
  150. // p = pbuf_alloc(PBUF_RAW, framelen, PBUF_POOL);
  151. p = pbuf_alloced_custom(PBUF_RAW, framelen, PBUF_REF, custom_pbuf[current_pbuf_idx], Rx_Buff[current_pbuf_idx], Max_Ethernet_Lenth);
  152. if (current_pbuf_idx < (DM9K_RX_DESC_CNT - 1))
  153. {
  154. current_pbuf_idx++;
  155. }
  156. else
  157. {
  158. current_pbuf_idx = 0;
  159. }
  160. }
  161. return p;
  162. }
  163. #if 1
  164. void ethernetif_input(void *pvParameters)
  165. {
  166. struct pbuf *p;
  167. INT8U err;
  168. SYS_ARCH_DECL_PROTECT(sr);
  169. for (;;)
  170. {
  171. OSSemPend(g_dm9k_rx_sem, 100, &err);
  172. TRY_GET_NEXT_FRAME:
  173. SYS_ARCH_PROTECT(sr);
  174. p = low_level_input(low_netif);
  175. SYS_ARCH_UNPROTECT(sr);
  176. if (p != NULL)
  177. {
  178. if (ERR_OK != low_netif->input(p, low_netif))
  179. {
  180. pbuf_free(p);
  181. }
  182. else
  183. {
  184. goto TRY_GET_NEXT_FRAME;
  185. }
  186. }
  187. }
  188. }
  189. #else
  190. void ethernetif_input(void *argument)
  191. {
  192. struct pbuf *p;
  193. // struct netif *netif = (struct netif *)argument;
  194. INT8U err;
  195. for (;;)
  196. {
  197. OSSemPend(g_dm9k_rx_sem, 0, &err);
  198. // if (err == OS)
  199. // {
  200. if (err == ERR_OK)
  201. {
  202. do
  203. {
  204. LOCK_TCPIP_CORE();
  205. p = low_level_input(low_netif);
  206. if (p != NULL)
  207. {
  208. err = low_netif->input(p, low_netif);
  209. if (err != ERR_OK)
  210. {
  211. LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
  212. pbuf_free(p);
  213. }
  214. }
  215. UNLOCK_TCPIP_CORE();
  216. } while (p != NULL);
  217. }
  218. // }
  219. }
  220. }
  221. #endif
  222. err_t ethernetif_dm9k_init(struct netif *netif)
  223. {
  224. LWIP_ASSERT("netif != NULL", (netif != NULL));
  225. #if LWIP_NETIF_HOSTNAME
  226. /* Initialize interface hostname */
  227. netif->hostname = "DM9000";
  228. #endif /* LWIP_NETIF_HOSTNAME */
  229. /*
  230. * Initialize the snmp variables and counters inside the struct netif.
  231. * The last argument should be replaced with your link speed, in units
  232. * of bits per second.
  233. */
  234. // MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
  235. netif->name[0] = IFNAME0;
  236. netif->name[1] = IFNAME1;
  237. /* We directly use etharp_output() here to save a function call.
  238. * You can instead declare your own function an call etharp_output()
  239. * from it if you have to do some checks before sending (e.g. if link
  240. * is available...) */
  241. netif->output = etharp_output;
  242. netif->linkoutput = low_level_output;
  243. /* initialize the hardware */
  244. low_level_init(netif);
  245. return ERR_OK;
  246. }
  247. /**
  248. * @brief Custom Rx pbuf free callback
  249. * @param pbuf: pbuf to be freed
  250. * @retval None
  251. */
  252. static void pbuf_free_custom(struct pbuf *p)
  253. {
  254. if (p != NULL)
  255. {
  256. memset(p, 0, sizeof(struct pbuf));
  257. }
  258. }
  259. void dm9k_interrupt(void)
  260. {
  261. uint8_t save_reg;
  262. uint16_t isr_status;
  263. save_reg = NET_REG_ADDR; /* 暂存所使用的位置 */
  264. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 关闭 DM9KA 中断 */
  265. isr_status = dm9k_ReadReg(DM9K_REG_ISR); /* 取得中断产生值 */
  266. // isr_status = isr_status & DM9K_RX_INTR;
  267. if (isr_status & DM9K_RX_INTR)
  268. { /* 检查是否为接收中断 */
  269. OSSemPost(g_dm9k_rx_sem);
  270. // dm9k_receive_packet(); /* 执行接收处理程序 */
  271. }
  272. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 开启 DM9KA 中断 */
  273. NET_REG_ADDR = save_reg; /* 回复所使用的位置 */
  274. }
  275. /**
  276. * @brief Ethernet Rx Transfer completed callback
  277. * @param heth: ETH handle
  278. * @retval None
  279. */
  280. void BSP_GPIO15_EXTI_Callback(void)
  281. {
  282. uint8_t save_reg;
  283. uint8_t isr_status;
  284. save_reg = NET_REG_ADDR; /* 暂存所使用的位置 */
  285. isr_status = dm9k_ReadReg(DM9K_REG_ISR); /* 取得中断产生值 */
  286. dm9k_WriteReg(DM9K_REG_ISR, isr_status); /* 清除中断产生值 */
  287. // isr_status = isr_status & DM9K_RX_INTR;
  288. if (isr_status & DM9K_RX_INTR) /* 检查是否为接收中断 */
  289. {
  290. OSSemPost(g_dm9k_rx_sem); /* 执行接收处理程序 */
  291. }
  292. NET_REG_ADDR = save_reg; /* 回复所使用的位置 */
  293. }
  294. //中断处理函数,注意不是中断服函数,需要在中断服务函数中调用
  295. void DMA9K_ISRHandler(void)
  296. {
  297. u16 int_status;
  298. u16 last_io;
  299. last_io = NET_REG_ADDR;
  300. int_status = dm9k_ReadReg(DM9K_REG_ISR);
  301. dm9k_WriteReg(DM9K_REG_ISR, int_status); //清除中断标志位
  302. if (int_status & DM9K_RX_INTR) //接收中断
  303. {
  304. OSSemPost(g_dm9k_rx_sem);
  305. //接收完成中断,用户自己添加代码
  306. }
  307. if (int_status & DM9K_TX_INTR) //发送中断
  308. {
  309. // OSSemPost(g_dm9k_tx_sem);
  310. //发送完成中断,用户自己添加代码
  311. }
  312. NET_REG_ADDR = last_io;
  313. }
  314. void EXTI15_10_IRQHandler(void)
  315. {
  316. OSIntEnter();
  317. EXTI_ClearITPendingBit(EXTI_Line15); /* 清除中断标志位 */
  318. if (EXTI_GetITStatus(EXTI_Line15) != RESET)
  319. {
  320. BSP_GPIO15_EXTI_Callback();
  321. }
  322. OSIntExit();
  323. }
  324. void ethernet_link_check_state(struct netif *netif)
  325. {
  326. uint8_t linkchanged = 0;
  327. linkchanged = dm9k_linkstat();
  328. if (netif_is_link_up(netif) && (linkchanged == 0))
  329. {
  330. netif_set_down(netif);
  331. netif_set_link_down(netif);
  332. }
  333. else if (!netif_is_link_up(netif) && (linkchanged == 1))
  334. {
  335. netif_set_up(netif);
  336. netif_set_link_up(netif);
  337. }
  338. }