ethernetif_dm9k.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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. }
  92. dm9k_WriteReg(DM9K_REG_TXPLH, (framelen >> 8) & 0xff); /* 设置传送封包的长度 */
  93. dm9k_WriteReg(DM9K_REG_TXPLL, framelen & 0xff);
  94. dm9k_WriteReg(DM9K_REG_TCR, DM9K_TCR_SET); /* 进行传送 */
  95. while ((dm9k_ReadReg(DM9K_REG_ISR) & 0x02) == 0)
  96. ; /* 等待发送完成 */
  97. dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 开启 dm9kA 中断 */
  98. return errval;
  99. }
  100. static struct pbuf *low_level_input(struct netif *netif)
  101. {
  102. struct pbuf *p = NULL;
  103. uint32_t framelen = 0;
  104. framelen = etherdev_read(Rx_Buff[current_pbuf_idx]);
  105. if (framelen)
  106. {
  107. // p = pbuf_alloced_custom(PBUF_RAW, framelen, PBUF_REF, custom_pbuf[current_pbuf_idx], Rx_Buff[current_pbuf_idx], Max_Ethernet_Lenth);
  108. if (current_pbuf_idx < (DM9K_RX_DESC_CNT - 1))
  109. {
  110. current_pbuf_idx++;
  111. }
  112. else
  113. {
  114. current_pbuf_idx = 0;
  115. }
  116. }
  117. return p;
  118. }
  119. void ethernetif_input(void *pvParameters)
  120. {
  121. struct pbuf *p;
  122. INT8U err;
  123. SYS_ARCH_DECL_PROTECT(sr);
  124. for (;;)
  125. {
  126. OSSemPend(g_dm9k_rx_sem, 0, &err);
  127. TRY_GET_NEXT_FRAME:
  128. SYS_ARCH_PROTECT(sr);
  129. p = low_level_input(low_netif);
  130. SYS_ARCH_UNPROTECT(sr);
  131. if (p != NULL)
  132. {
  133. if (ERR_OK != low_netif->input(p, low_netif))
  134. {
  135. pbuf_free(p);
  136. }
  137. else
  138. {
  139. goto TRY_GET_NEXT_FRAME;
  140. }
  141. }
  142. }
  143. }
  144. err_t ethernetif_dm9k_init(struct netif *netif)
  145. {
  146. LWIP_ASSERT("netif != NULL", (netif != NULL));
  147. #if LWIP_NETIF_HOSTNAME
  148. /* Initialize interface hostname */
  149. netif->hostname = "lwip";
  150. #endif /* LWIP_NETIF_HOSTNAME */
  151. /*
  152. * Initialize the snmp variables and counters inside the struct netif.
  153. * The last argument should be replaced with your link speed, in units
  154. * of bits per second.
  155. */
  156. netif->name[0] = IFNAME0;
  157. netif->name[1] = IFNAME1;
  158. /* We directly use etharp_output() here to save a function call.
  159. * You can instead declare your own function an call etharp_output()
  160. * from it if you have to do some checks before sending (e.g. if link
  161. * is available...) */
  162. netif->output = etharp_output;
  163. netif->linkoutput = low_level_output;
  164. /* initialize the hardware */
  165. low_level_init(netif);
  166. return ERR_OK;
  167. }
  168. /**
  169. * @brief Custom Rx pbuf free callback
  170. * @param pbuf: pbuf to be freed
  171. * @retval None
  172. */
  173. static void pbuf_free_custom(struct pbuf *p)
  174. {
  175. if (p != NULL)
  176. {
  177. memset(p, 0, sizeof(struct pbuf));
  178. }
  179. }
  180. void EXTI15_10_IRQHandler(void)
  181. {
  182. if (EXTI_GetITStatus(EXTI_Line14) != RESET)
  183. {
  184. BSP_GPIO15_EXTI_Callback();
  185. EXTI_ClearITPendingBit(EXTI_Line14); /* 清除中断标志位 */
  186. }
  187. }
  188. /**
  189. * @brief Ethernet Rx Transfer completed callback
  190. * @param heth: ETH handle
  191. * @retval None
  192. */
  193. void BSP_GPIO15_EXTI_Callback(void)
  194. {
  195. uint8_t save_reg;
  196. uint8_t isr_status;
  197. save_reg = NET_REG_ADDR; /* 暂存所使用的位置 */
  198. isr_status = dm9k_ReadReg(DM9K_REG_ISR); /* 取得中断产生值 */
  199. dm9k_WriteReg(DM9K_REG_ISR, isr_status); /* 清除中断产生值 */
  200. if (isr_status & DM9K_RX_INTR) /* 检查是否为接收中断 */
  201. {
  202. OSSemPost(g_dm9k_rx_sem); /* 执行接收处理程序 */
  203. }
  204. NET_REG_ADDR = save_reg; /* 回复所使用的位置 */
  205. }
  206. /**
  207. * @brief Check the ETH link state and update netif accordingly.
  208. * @param argument: netif
  209. * @retval None
  210. */
  211. void ethernet_link_check_state(struct netif *netif)
  212. {
  213. uint8_t linkchanged = 0;
  214. linkchanged = dm9k_linkstat();
  215. if (netif_is_link_up(netif) && (linkchanged == 0))
  216. {
  217. netif_set_down(netif);
  218. netif_set_link_down(netif);
  219. }
  220. else if (!netif_is_link_up(netif) && (linkchanged == 1))
  221. {
  222. netif_set_up(netif);
  223. netif_set_link_up(netif);
  224. }
  225. }
  226. void ethernet_dm9k_link_thread(void const *argument)
  227. {
  228. struct netif *netif = (struct netif *)argument;
  229. for (;;)
  230. {
  231. ethernet_link_check_state(netif);
  232. OSTimeDly(100);
  233. }
  234. }