dm9161.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /*!
  2. \file gd32f4xx_enet_eval.c
  3. \brief ethernet hardware configuration
  4. */
  5. /*
  6. Copyright (C) 2016 GigaDevice
  7. 2016-08-15, V1.0.0, firmware for GD32F4xx
  8. */
  9. #include "stm32f4x7_eth.h"
  10. #include "dm9161.h"
  11. #include "netconf.h"
  12. #include "interface.h"
  13. #include "lwip/sockets.h"
  14. #include "lwip/api.h"
  15. static __IO uint32_t enet_init_status = 0;
  16. static void dm9161_gpio_config(void);
  17. static void dm9161_mac_dma_config(void);
  18. static void nvic_configuration(void);
  19. static uint32_t Eth_Link_PHYITConfig(uint16_t PHYAddress);
  20. /*!
  21. \brief setup ethernet system(GPIOs, clocks, MAC, DMA, systick)
  22. \param[in] none
  23. \param[out] none
  24. \retval none
  25. */
  26. void enet_system_setup(void)
  27. {
  28. nvic_configuration();
  29. /* configure the GPIO ports for ethernet pins */
  30. dm9161_gpio_config();
  31. /* configure the ethernet MAC/DMA */
  32. dm9161_mac_dma_config();
  33. // /* Read PHY status register: Get Ethernet link status */
  34. // if (ETH_ReadPHYRegister(0x01, PHY_SR) & 1)
  35. // {
  36. // enet_init_status |= 0x10;
  37. // }
  38. // /* Configure the PHY to generate an interrupt on change of link status */
  39. // Eth_Link_PHYITConfig(0x01);
  40. /* Configure the EXTI for Ethernet link status. */
  41. // Eth_Link_EXTIConfig();
  42. if (enet_init_status == 0)
  43. {
  44. return;
  45. }
  46. // ETH_MACITConfig(ETH_MAC_IT_PMT, ENABLE);
  47. ETH_DMAITConfig(ETH_DMA_IT_R, ENABLE);
  48. ETH_DMAITConfig(ETH_DMA_IT_NIS, ENABLE);
  49. // ETH_MACReceptionCmd(ENABLE);
  50. }
  51. /*!
  52. \brief configures the ethernet interface
  53. \param[in] none
  54. \param[out] none
  55. \retval none
  56. */
  57. static void dm9161_mac_dma_config(void)
  58. {
  59. ErrorStatus reval_state = ERROR;
  60. /* reset ethernet on AHB bus */
  61. ETH_DeInit();
  62. /* Software reset */
  63. ETH_SoftwareReset();
  64. /* Wait for software reset */
  65. reval_state = ETH_GetSoftwareResetStatus();
  66. if (reval_state == ERROR)
  67. {
  68. return;
  69. }
  70. // while (ETH_GetSoftwareResetStatus() == SET)
  71. // ;
  72. // /* ETHERNET Configuration --------------------------------------------------*/
  73. // /* Call ETH_StructInit if you don't like to configure all ETH_InitStructure parameter */
  74. ETH_InitTypeDef ETH_InitStructure;
  75. ETH_StructInit(&ETH_InitStructure);
  76. /* Fill ETH_InitStructure parametrs */
  77. /*------------------------ MAC -----------------------------------*/
  78. ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable;
  79. // ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Disable;
  80. // ETH_InitStructure.ETH_Speed = ETH_Speed_10M;
  81. // ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;
  82. ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;
  83. ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable;
  84. ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;
  85. ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable;
  86. ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;
  87. ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;
  88. ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;
  89. ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;
  90. #ifdef CHECKSUM_BY_HARDWARE
  91. ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable;
  92. #endif
  93. /*------------------------ DMA -----------------------------------------*/
  94. /* When we use the Checksum offload feature, we need to enable the Store and Forward mode:
  95. the store and forward guarantee that a whole frame is stored in the FIFO, so the MAC can insert/verify the checksum,
  96. if the checksum is OK the DMA can handle the frame otherwise the frame is dropped */
  97. ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable;
  98. ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;
  99. ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;
  100. ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;
  101. ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable;
  102. ETH_InitStructure.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable;
  103. ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;
  104. ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable;
  105. ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat;
  106. ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat;
  107. ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1;
  108. /* Configure Ethernet */
  109. enet_init_status = ETH_Init(&ETH_InitStructure, 0x01);
  110. }
  111. /*!
  112. \brief configures the nested vectored interrupt controller
  113. \param[in] none
  114. \param[out] none
  115. \retval none
  116. */
  117. static void nvic_configuration(void)
  118. {
  119. NVIC_InitTypeDef NVIC_InitStructure;
  120. NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn;
  121. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  122. NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
  123. NVIC_Init(&NVIC_InitStructure);
  124. }
  125. /*!
  126. \brief configures the different GPIO ports
  127. \param[in] none
  128. \param[out] none
  129. \retval none
  130. */
  131. static void dm9161_gpio_config(void)
  132. {
  133. INT16U i = 0;
  134. GPIO_InitTypeDef GPIO_StructInit;
  135. GPIO_StructInit.GPIO_Mode = GPIO_Mode_OUT;
  136. // GPIO_StructInit.GPIO_OType = interface_info[index].GPIO_OType;
  137. GPIO_StructInit.GPIO_Speed = GPIO_High_Speed;
  138. GPIO_StructInit.GPIO_PuPd = GPIO_PuPd_DOWN;
  139. GPIO_StructInit.GPIO_Pin = ETH_RESET_PIN;
  140. GPIO_Init(ETH_RESET_PORT, &GPIO_StructInit);
  141. ETH_RESET_ON;
  142. while (i < 1000)
  143. {
  144. i++;
  145. }
  146. i = 0;
  147. ETH_RESET_OFF;
  148. while (i < 1000)
  149. {
  150. i++;
  151. }
  152. i = 0;
  153. /* Enable SYSCFG clock */
  154. RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  155. #ifdef MII_MODE
  156. #ifdef PHY_CLOCK_MCO
  157. /* output HXTAL clock (25MHz) on CKOUT0 pin(PA8) to clock the PHY */
  158. RCC_MCO1Config(RCC_MCO1Source_HSE, RCC_MCO1Div_1);
  159. #endif /* PHY_CLOCK_MCO */
  160. SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_MII);
  161. #elif defined RMII_MODE
  162. SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII);
  163. #endif
  164. }
  165. uint32_t Eth_Link_PHYITConfig(uint16_t PHYAddress)
  166. {
  167. uint16_t tmpreg = 0;
  168. /* Read MICR register */
  169. tmpreg = ETH_ReadPHYRegister(PHYAddress, PHY_MICR);
  170. /* Enable output interrupt events to signal via the INT pin */
  171. tmpreg |= (uint16_t)(PHY_MICR_INT_EN | PHY_MICR_INT_OE);
  172. if (!(ETH_WritePHYRegister(PHYAddress, PHY_MICR, tmpreg)))
  173. {
  174. /* Return ERROR in case of write timeout */
  175. return ETH_ERROR;
  176. }
  177. /* Read MISR register */
  178. tmpreg = ETH_ReadPHYRegister(PHYAddress, PHY_MISR);
  179. /* Enable Interrupt on change of link status */
  180. tmpreg |= (uint16_t)PHY_MISR_LINK_INT_EN;
  181. if (!(ETH_WritePHYRegister(PHYAddress, PHY_MISR, tmpreg)))
  182. {
  183. /* Return ERROR in case of write timeout */
  184. return ETH_ERROR;
  185. }
  186. /* Return SUCCESS */
  187. return ETH_SUCCESS;
  188. }
  189. static err_t bms_net_process(int fd, void *data, int len)
  190. {
  191. INT8U response[2] = {0xBB, 0xAA};
  192. if ((len == 2) && (((INT8U *)data)[0] == 0xAA) && (((INT8U *)data)[1] == 0xBB))
  193. {
  194. send(fd, (void *)response, sizeof(response), 0);
  195. }
  196. return 1;
  197. }
  198. void dm9161_task(void)
  199. {
  200. INT8U buf[50];
  201. INT32S ret = 0;
  202. INT32S sockfd = -1, newfd = -1;
  203. INT32U len = 0;
  204. struct sockaddr_in svr_addr, clt_addr;
  205. svr_addr.sin_family = AF_INET;
  206. svr_addr.sin_port = htons(TCP_PORT);
  207. svr_addr.sin_addr.s_addr = htons(INADDR_ANY);
  208. while (1)
  209. {
  210. sockfd = socket(AF_INET, SOCK_STREAM, 0);
  211. if (sockfd < 0)
  212. {
  213. continue;
  214. }
  215. ret = bind(sockfd, (struct sockaddr *)&svr_addr, sizeof(svr_addr));
  216. if (ret < 0)
  217. {
  218. lwip_close(sockfd);
  219. sockfd = -1;
  220. continue;
  221. }
  222. ret = listen(sockfd, 1);
  223. if (ret < 0)
  224. {
  225. lwip_close(sockfd);
  226. continue;
  227. }
  228. len = sizeof(clt_addr);
  229. newfd = accept(sockfd, NULL, NULL);
  230. while (-1 != newfd)
  231. {
  232. ret = recv(newfd, buf, sizeof(buf) - 1, 0);
  233. if (ret <= 0)
  234. {
  235. lwip_close(newfd);
  236. newfd = -1;
  237. break;
  238. }
  239. bms_net_process(newfd, buf, ret);
  240. }
  241. lwip_close(sockfd);
  242. sockfd = -1;
  243. OSTimeDly(10);
  244. }
  245. }