ethernetif_dm9k.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  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 "lwip_init.h"
  8. #include "netif/etharp.h"
  9. #include "netif/ethernet.h"
  10. #include "string.h"
  11. #include <stdio.h>
  12. #define DM9K_RX_TASK_PRIO 4
  13. #define DM9K_RX_TASK_STK_SIZE 2048
  14. CPU_STK dm9k_rx_task_stk[DM9K_RX_TASK_STK_SIZE];
  15. /* Define those to better describe your network interface. */
  16. #define IFNAME0 'D'
  17. #define IFNAME1 '2'
  18. #define DM9K_RX_DESC_CNT 4
  19. #define DM9K_RX_Lenth 1536UL
  20. /* Private macro -------------------------------------------------------------*/
  21. /* Private variables ---------------------------------------------------------*/
  22. static uint8_t *Rx_Buff[DM9K_RX_DESC_CNT] = {0}; /* Ethernet Rx Buffer */
  23. uint8_t current_pbuf_idx = 0; /* Zero-copy RX PBUF pool */
  24. static struct pbuf_custom *custom_pbuf[DM9K_RX_DESC_CNT] = {0};
  25. /* Private function prototypes -----------------------------------------------*/
  26. static void pbuf_free_custom(struct pbuf *p);
  27. static void ethernetif_input(void *pvParameters);
  28. // static void ethernet_link_check_state(struct netif *netif);
  29. static OS_EVENT *g_dm9k_rx_sem = NULL;
  30. static OS_EVENT *g_dm9k_tx_sem = NULL;
  31. // static OS_EVENT *dm9k_mutex = NULL;
  32. static struct netif *low_netif = NULL;
  33. static void low_level_init(struct netif *netif)
  34. {
  35. /* set MAC hardware address length */
  36. netif->hwaddr_len = ETHARP_HWADDR_LEN;
  37. /* 网卡的 MAC 修改2 */
  38. netif->hwaddr[0] = dm9kdev.mac[0];
  39. netif->hwaddr[1] = dm9kdev.mac[1];
  40. netif->hwaddr[2] = dm9kdev.mac[2];
  41. netif->hwaddr[3] = dm9kdev.mac[3];
  42. netif->hwaddr[4] = dm9kdev.mac[4];
  43. netif->hwaddr[5] = dm9kdev.mac[5];
  44. /* maximum transfer unit */
  45. netif->mtu = 1500;
  46. /* device capabilities */
  47. /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
  48. netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
  49. low_netif = netif;
  50. /* create binary semaphore used for informing ethernetif of frame reception */
  51. if (NULL == g_dm9k_rx_sem)
  52. {
  53. g_dm9k_rx_sem = OSSemCreate(0);
  54. }
  55. OSTaskCreateExt((void (*)(void *))ethernetif_input,
  56. (void *)0,
  57. (OS_STK *)&dm9k_rx_task_stk[DM9K_RX_TASK_STK_SIZE - 1],
  58. (INT8U)DM9K_RX_TASK_PRIO,
  59. (INT16U)DM9K_RX_TASK_PRIO,
  60. (OS_STK *)&dm9k_rx_task_stk[0],
  61. (INT32U)DM9K_RX_TASK_STK_SIZE,
  62. (void *)0,
  63. (INT16U)OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR | OS_TASK_OPT_SAVE_FP);
  64. }
  65. static err_t low_level_output(struct netif *netif, struct pbuf *p)
  66. {
  67. INT8U err;
  68. err_t errval = ERR_OK;
  69. uint32_t i = 0, framelen = 0, calc_len = 0;
  70. struct pbuf *q;
  71. SYS_ARCH_DECL_PROTECT(sr);
  72. if (NULL == g_dm9k_tx_sem)
  73. {
  74. g_dm9k_tx_sem = OSSemCreate(1);
  75. }
  76. OSSemPend(g_dm9k_tx_sem, 0, &err);
  77. SYS_ARCH_PROTECT(sr);
  78. // dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 关闭 dm9kA 中断 */
  79. NET_REG_ADDR = DM9K_REG_MWCMD;
  80. for (q = p; q != NULL; q = q->next)
  81. {
  82. framelen = framelen + q->len;
  83. calc_len = (q->len + 1) >> 1;
  84. for (i = 0; i < calc_len; i++)
  85. {
  86. NET_REG_DATA = ((uint16_t *)q->payload)[i];
  87. }
  88. }
  89. dm9k_WriteReg(DM9K_REG_TXPLH, (framelen >> 8) & 0xff); /* 设置传送封包的长度 */
  90. dm9k_WriteReg(DM9K_REG_TXPLL, framelen & 0xff);
  91. dm9k_WriteReg(DM9K_REG_TCR, DM9K_TCR_SET); /* 进行传送 */
  92. while ((dm9k_ReadReg(DM9K_REG_ISR) & 0x02) == 0)
  93. ; /* 等待发送完成 */
  94. // dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 开启 dm9kA 中断 */
  95. SYS_ARCH_UNPROTECT(sr);
  96. // OSSemPost(g_dm9k_tx_sem);
  97. return errval;
  98. }
  99. static struct pbuf *low_level_input(struct netif *netif)
  100. {
  101. struct pbuf *p = NULL;
  102. uint16_t framelen = 0;
  103. // dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 关闭 DM9000A 中断 */
  104. framelen = etherdev_read(Rx_Buff[current_pbuf_idx]);
  105. // dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 开启 DM9000A 中断 */
  106. if (framelen)
  107. {
  108. printf("REC LEM: %d\r\n", framelen);
  109. p = pbuf_alloc(PBUF_RAW, framelen, PBUF_POOL);
  110. // p = pbuf_alloced_custom(PBUF_RAW, framelen, PBUF_REF, custom_pbuf[current_pbuf_idx], Rx_Buff[current_pbuf_idx], Max_Ethernet_Lenth);
  111. // if (current_pbuf_idx < (DM9K_RX_DESC_CNT - 1))
  112. // {
  113. // current_pbuf_idx++;
  114. // }
  115. // else
  116. // {
  117. // current_pbuf_idx = 0;
  118. // }
  119. }
  120. return p;
  121. }
  122. void ethernetif_input(void *pvParameters)
  123. {
  124. struct pbuf *p;
  125. INT8U err;
  126. SYS_ARCH_DECL_PROTECT(sr);
  127. for (;;)
  128. {
  129. OSSemPend(g_dm9k_rx_sem, 100, &err);
  130. TRY_GET_NEXT_FRAME:
  131. SYS_ARCH_PROTECT(sr);
  132. p = low_level_input(low_netif);
  133. SYS_ARCH_UNPROTECT(sr);
  134. if (p != NULL)
  135. {
  136. if (ERR_OK != low_netif->input(p, low_netif))
  137. {
  138. pbuf_free(p);
  139. }
  140. else
  141. {
  142. goto TRY_GET_NEXT_FRAME;
  143. }
  144. }
  145. }
  146. }
  147. err_t ethernetif_dm9k_init(struct netif *netif)
  148. {
  149. LWIP_ASSERT("netif != NULL", (netif != NULL));
  150. #if LWIP_NETIF_HOSTNAME
  151. /* Initialize interface hostname */
  152. netif->hostname = "DM9000";
  153. #endif /* LWIP_NETIF_HOSTNAME */
  154. /*
  155. * Initialize the snmp variables and counters inside the struct netif.
  156. * The last argument should be replaced with your link speed, in units
  157. * of bits per second.
  158. */
  159. // MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
  160. netif->name[0] = IFNAME0;
  161. netif->name[1] = IFNAME1;
  162. /* We directly use etharp_output() here to save a function call.
  163. * You can instead declare your own function an call etharp_output()
  164. * from it if you have to do some checks before sending (e.g. if link
  165. * is available...) */
  166. netif->output = etharp_output;
  167. netif->linkoutput = low_level_output;
  168. /* initialize the hardware */
  169. low_level_init(netif);
  170. return ERR_OK;
  171. }
  172. /**
  173. * @brief Custom Rx pbuf free callback
  174. * @param pbuf: pbuf to be freed
  175. * @retval None
  176. */
  177. // static void pbuf_free_custom(struct pbuf *p)
  178. // {
  179. // if (p != NULL)
  180. // {
  181. // memset(p, 0, sizeof(struct pbuf));
  182. // }
  183. // }
  184. void dm9k_interrupt(void)
  185. {
  186. uint8_t save_reg;
  187. uint16_t isr_status;
  188. save_reg = NET_REG_ADDR; /* 暂存所使用的位置 */
  189. // dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 关闭 DM9KA 中断 */
  190. isr_status = dm9k_ReadReg(DM9K_REG_ISR); /* 取得中断产生值 */
  191. // isr_status = isr_status & DM9K_RX_INTR;
  192. if (isr_status & DM9K_RX_INTR)
  193. { /* 检查是否为接收中断 */
  194. OSSemPost(g_dm9k_rx_sem);
  195. // dm9k_receive_packet(); /* 执行接收处理程序 */
  196. }
  197. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 开启 DM9KA 中断 */
  198. NET_REG_ADDR = save_reg; /* 回复所使用的位置 */
  199. }
  200. /**
  201. * @brief Ethernet Rx Transfer completed callback
  202. * @param heth: ETH handle
  203. * @retval None
  204. */
  205. void BSP_GPIO15_EXTI_Callback(void)
  206. {
  207. uint8_t save_reg;
  208. uint8_t isr_status;
  209. save_reg = NET_REG_ADDR; /* 暂存所使用的位置 */
  210. isr_status = dm9k_ReadReg(DM9K_REG_ISR); /* 取得中断产生值 */
  211. dm9k_WriteReg(DM9K_REG_ISR, isr_status); /* 清除中断产生值 */
  212. // isr_status = isr_status & DM9K_RX_INTR;
  213. if (isr_status & DM9K_RX_INTR) /* 检查是否为接收中断 */
  214. {
  215. OSSemPost(g_dm9k_rx_sem); /* 执行接收处理程序 */
  216. }
  217. if (isr_status & DM9K_TX_INTR) // 发送中断
  218. {
  219. OSSemPost(g_dm9k_tx_sem);
  220. // 发送完成中断,用户自己添加代码
  221. }
  222. NET_REG_ADDR = save_reg; /* 回复所使用的位置 */
  223. }
  224. // 中断处理函数,注意不是中断服函数,需要在中断服务函数中调用
  225. void DMA9K_ISRHandler(void)
  226. {
  227. u16 int_status;
  228. u16 last_io;
  229. last_io = NET_REG_ADDR;
  230. int_status = dm9k_ReadReg(DM9K_REG_ISR);
  231. dm9k_WriteReg(DM9K_REG_ISR, int_status); // 清除中断标志位
  232. if (int_status & DM9K_RX_INTR) // 接收中断
  233. {
  234. OSSemPost(g_dm9k_rx_sem);
  235. // 接收完成中断,用户自己添加代码
  236. }
  237. if (int_status & DM9K_TX_INTR) // 发送中断
  238. {
  239. // OSSemPost(g_dm9k_tx_sem);
  240. // 发送完成中断,用户自己添加代码
  241. }
  242. NET_REG_ADDR = last_io;
  243. }
  244. void ethernet_link_check_state(struct netif *netif)
  245. {
  246. uint8_t linkchanged = 0;
  247. linkchanged = dm9k_linkstat();
  248. if (netif_is_link_up(netif) && (linkchanged == 0))
  249. {
  250. printf("dm9k LwIP Error interface....\r\n");
  251. netif_set_down(netif);
  252. netif_set_link_down(netif);
  253. }
  254. else if (!netif_is_link_up(netif) && (linkchanged == 1))
  255. {
  256. printf("dm9k LwIP Finish interface....\r\n");
  257. netif_set_up(netif);
  258. netif_set_link_up(netif);
  259. }
  260. }