ethernetif_dm9k.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /* Includes ------------------------------------------------------------------*/
  2. #include "ethernetif_dm9k.h"
  3. #include "dm9k.h"
  4. #include "lwip/tcpip.h"
  5. #include "lwip/timeouts.h"
  6. #include "netif/etharp.h"
  7. #include "netif/ethernet.h"
  8. #include "string.h"
  9. #define DM9K_RX_TASK_PRIO (4)
  10. #define DM9K_RX_TASK_STK_SIZE (2048)
  11. CPU_STK dm9k_rx_task_stk[DM9K_RX_TASK_STK_SIZE];
  12. /* Define those to better describe your network interface. */
  13. #define IFNAME0 's'
  14. #define IFNAME1 't'
  15. #define DM9K_RX_DESC_CNT 3
  16. #define DM9K_RX_Lenth 1536UL * 2
  17. /* Private macro -------------------------------------------------------------*/
  18. /* Private variables ---------------------------------------------------------*/
  19. static uint8_t *Rx_Buff[DM9K_RX_DESC_CNT] = {0}; /* Ethernet Rx Buffer */
  20. static uint8_t current_pbuf_idx = 0; /* Zero-copy RX PBUF pool */
  21. static struct pbuf_custom *custom_pbuf[DM9K_RX_DESC_CNT] = {0};
  22. /* Private function prototypes -----------------------------------------------*/
  23. static void pbuf_free_custom(struct pbuf *p);
  24. static void ethernetif_input(void *pvParameters);
  25. static void ethernet_link_check_state(struct netif *netif);
  26. static OS_EVENT *g_dm9k_rx_sem = NULL;
  27. static struct netif *low_netif = NULL;
  28. static void low_level_init(struct netif *netif)
  29. {
  30. // VariableMemInit();
  31. /* set MAC hardware address length */
  32. netif->hwaddr_len = ETHARP_HWADDR_LEN;
  33. /* set MAC hardware address */ /* 网卡的 MAC 修改2 */
  34. netif->hwaddr[0] = DM9K_MAC_ADDR0;
  35. netif->hwaddr[1] = DM9K_MAC_ADDR1;
  36. netif->hwaddr[2] = DM9K_MAC_ADDR2;
  37. netif->hwaddr[3] = DM9K_MAC_ADDR3;
  38. netif->hwaddr[4] = DM9K_MAC_ADDR4;
  39. netif->hwaddr[5] = DM9K_MAC_ADDR5;
  40. /* maximum transfer unit */
  41. netif->mtu = 1500;
  42. /* device capabilities */
  43. /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
  44. netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
  45. /* create binary semaphore used for informing ethernetif of frame reception */
  46. if (NULL == g_dm9k_rx_sem)
  47. {
  48. g_dm9k_rx_sem = OSSemCreate(0);
  49. }
  50. OSTaskCreateExt((void (*)(void *))ethernetif_input,
  51. (void *)0,
  52. (OS_STK *)&dm9k_rx_task_stk[DM9K_RX_TASK_STK_SIZE - 1],
  53. (INT8U)DM9K_RX_TASK_PRIO,
  54. (INT16U)DM9K_RX_TASK_PRIO,
  55. (OS_STK *)&dm9k_rx_task_stk[0],
  56. (INT32U)DM9K_RX_TASK_STK_SIZE,
  57. (void *)0,
  58. (INT16U)OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR | OS_TASK_OPT_SAVE_FP);
  59. ethernet_link_check_state(netif);
  60. }
  61. /**
  62. * @brief This function should do the actual transmission of the packet. The packet is
  63. * contained in the pbuf that is passed to the function. This pbuf
  64. * might be chained.
  65. *
  66. * @param netif the lwip network interface structure for this ethernetif
  67. * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
  68. * @return ERR_OK if the packet could be sent
  69. * an err_t value if the packet couldn't be sent
  70. *
  71. * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
  72. * strange results. You might consider waiting for space in the DMA queue
  73. * to become available since the stack doesn't retry to send a packet
  74. * dropped because of memory failure (except for the TCP timers).
  75. */
  76. static err_t low_level_output(struct netif *netif, struct pbuf *p)
  77. {
  78. err_t errval = ERR_OK;
  79. uint32_t i = 0, framelen = 0, calc_len = 0;
  80. struct pbuf *q;
  81. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 关闭 dm9kA 中断 */
  82. NET_REG_ADDR = DM9K_REG_MWCMD;
  83. for (q = p; q != NULL; q = q->next)
  84. {
  85. framelen = framelen + q->len;
  86. calc_len = (q->len + 1) >> 1;
  87. for (i = 0; i < calc_len; i++)
  88. {
  89. NET_REG_DATA = ((uint16_t *)q->payload)[i];
  90. }
  91. // UsartSend((uint8_t *)q->payload, p->tot_len);
  92. }
  93. dm9k_WriteReg(DM9K_REG_TXPLH, (framelen >> 8) & 0xff); /* 设置传送封包的长度 */
  94. dm9k_WriteReg(DM9K_REG_TXPLL, framelen & 0xff);
  95. dm9k_WriteReg(DM9K_REG_TCR, DM9K_TCR_SET); /* 进行传送 */
  96. while ((dm9k_ReadReg(DM9K_REG_ISR) & 0x02) == 0)
  97. ; /* 等待发送完成 */
  98. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 开启 dm9kA 中断 */
  99. return errval;
  100. }
  101. static struct pbuf *low_level_input(struct netif *netif)
  102. {
  103. struct pbuf *p = NULL;
  104. uint32_t framelen = 0;
  105. framelen = etherdev_read(Rx_Buff[current_pbuf_idx]);
  106. if (framelen)
  107. {
  108. // p = pbuf_alloced_custom(PBUF_RAW, framelen, PBUF_REF, custom_pbuf[current_pbuf_idx], Rx_Buff[current_pbuf_idx], Max_Ethernet_Lenth);
  109. if (current_pbuf_idx < (DM9K_RX_DESC_CNT - 1))
  110. {
  111. current_pbuf_idx++;
  112. }
  113. else
  114. {
  115. current_pbuf_idx = 0;
  116. }
  117. }
  118. return p;
  119. }
  120. void ethernetif_input(void *pvParameters)
  121. {
  122. struct pbuf *p;
  123. INT8U err;
  124. SYS_ARCH_DECL_PROTECT(sr);
  125. for (;;)
  126. {
  127. OSSemPend(g_dm9k_rx_sem, 0, &err);
  128. TRY_GET_NEXT_FRAME:
  129. SYS_ARCH_PROTECT(sr);
  130. p = low_level_input(low_netif);
  131. SYS_ARCH_UNPROTECT(sr);
  132. if (p != NULL)
  133. {
  134. if (ERR_OK != low_netif->input(p, low_netif))
  135. {
  136. pbuf_free(p);
  137. }
  138. else
  139. {
  140. goto TRY_GET_NEXT_FRAME;
  141. }
  142. }
  143. }
  144. }
  145. err_t ethernetif_dm9k_init(struct netif *netif)
  146. {
  147. LWIP_ASSERT("netif != NULL", (netif != NULL));
  148. #if LWIP_NETIF_HOSTNAME
  149. /* Initialize interface hostname */
  150. netif->hostname = "lwip";
  151. #endif /* LWIP_NETIF_HOSTNAME */
  152. /*
  153. * Initialize the snmp variables and counters inside the struct netif.
  154. * The last argument should be replaced with your link speed, in units
  155. * of bits per second.
  156. */
  157. netif->name[0] = IFNAME0;
  158. netif->name[1] = IFNAME1;
  159. /* We directly use etharp_output() here to save a function call.
  160. * You can instead declare your own function an call etharp_output()
  161. * from it if you have to do some checks before sending (e.g. if link
  162. * is available...) */
  163. netif->output = etharp_output;
  164. netif->linkoutput = low_level_output;
  165. /* initialize the hardware */
  166. low_level_init(netif);
  167. return ERR_OK;
  168. }
  169. /**
  170. * @brief Custom Rx pbuf free callback
  171. * @param pbuf: pbuf to be freed
  172. * @retval None
  173. */
  174. static void pbuf_free_custom(struct pbuf *p)
  175. {
  176. if (p != NULL)
  177. {
  178. memset(p, 0, sizeof(struct pbuf));
  179. }
  180. }
  181. /**
  182. * @brief Ethernet Rx Transfer completed callback
  183. * @param heth: ETH handle
  184. * @retval None
  185. */
  186. void BSP_GPIO15_EXTI_Callback(void)
  187. {
  188. uint8_t save_reg;
  189. uint8_t isr_status;
  190. save_reg = NET_REG_ADDR; /* 暂存所使用的位置 */
  191. // dm9k_WriteReg(dm9k_REG_IMR, dm9k_IMR_OFF); /* 关闭 dm9kA 中断 */
  192. isr_status = dm9k_ReadReg(DM9K_REG_ISR); /* 取得中断产生值 */
  193. dm9k_WriteReg(DM9K_REG_ISR, isr_status); /* 清除中断产生值 */
  194. if (isr_status & DM9K_RX_INTR) /* 检查是否为接收中断 */
  195. {
  196. // osSemaphoreRelease(RxPktSemaphore); /* 执行接收处理程序 */
  197. }
  198. // dm9k_WriteReg(dm9k_REG_IMR, dm9k_IMR_SET); /* 开启 dm9kA 中断 */
  199. NET_REG_ADDR = save_reg; /* 回复所使用的位置 */
  200. }
  201. /**
  202. * @brief Check the ETH link state and update netif accordingly.
  203. * @param argument: netif
  204. * @retval None
  205. */
  206. void ethernet_link_check_state(struct netif *netif)
  207. {
  208. uint8_t linkchanged = 0;
  209. linkchanged = dm9k_linkstat();
  210. if (netif_is_link_up(netif) && (linkchanged == 0))
  211. {
  212. netif_set_down(netif);
  213. netif_set_link_down(netif);
  214. }
  215. else if (!netif_is_link_up(netif) && (linkchanged == 1))
  216. {
  217. netif_set_up(netif);
  218. netif_set_link_up(netif);
  219. }
  220. }
  221. void ethernet_dm9k_link_thread(void const *argument)
  222. {
  223. struct netif *netif = (struct netif *)argument;
  224. for (;;)
  225. {
  226. ethernet_link_check_state(netif);
  227. OSTimeDly(100);
  228. }
  229. }