ethernetif.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  1. /**
  2. ******************************************************************************
  3. * @file LwIP/LwIP_HTTP_Server_Socket_RTOS/Src/ethernetif.c
  4. * @author MCD Application Team
  5. * @brief This file implements Ethernet network interface drivers for lwIP
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
  10. * All rights reserved.</center></h2>
  11. *
  12. * This software component is licensed by ST under BSD 3-Clause license,
  13. * the "License"; You may not use this file except in compliance with the
  14. * License. You may obtain a copy of the License at:
  15. * opensource.org/licenses/BSD-3-Clause
  16. *
  17. ******************************************************************************
  18. */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "stm32f2xx_hal.h"
  21. #include "lwip/timeouts.h"
  22. #include "netif/etharp.h"
  23. #include "ethernetif.h"
  24. #include <string.h>
  25. #include "myFile.h"
  26. /* Private typedef -----------------------------------------------------------*/
  27. /* Private define ------------------------------------------------------------*/
  28. /* The time to block waiting for input. */
  29. #define TIME_WAITING_FOR_INPUT ( osWaitForever )
  30. /* Stack size of the interface thread */
  31. #define INTERFACE_THREAD_STACK_SIZE ( 350 )
  32. /* Define those to better describe your network interface. */
  33. #define IFNAME0 's'
  34. #define IFNAME1 't'
  35. /* Private macro -------------------------------------------------------------*/
  36. /* Private variables ---------------------------------------------------------*/
  37. #if defined ( __ICCARM__ ) /*!< IAR Compiler */
  38. #pragma data_alignment=4
  39. #endif
  40. __ALIGN_BEGIN ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB] __ALIGN_END;/* Ethernet Rx MA Descriptor */
  41. #if defined ( __ICCARM__ ) /*!< IAR Compiler */
  42. #pragma data_alignment=4
  43. #endif
  44. __ALIGN_BEGIN ETH_DMADescTypeDef DMATxDscrTab[ETH_TXBUFNB] __ALIGN_END;/* Ethernet Tx DMA Descriptor */
  45. #if defined ( __ICCARM__ ) /*!< IAR Compiler */
  46. #pragma data_alignment=4
  47. #endif
  48. __ALIGN_BEGIN uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __ALIGN_END; /* Ethernet Receive Buffer */
  49. #if defined ( __ICCARM__ ) /*!< IAR Compiler */
  50. #pragma data_alignment=4
  51. #endif
  52. __ALIGN_BEGIN uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __ALIGN_END; /* Ethernet Transmit Buffer */
  53. /* Semaphore to signal incoming packets */
  54. osSemaphoreId s_xSemaphore = NULL;
  55. /* Global Ethernet handle*/
  56. ETH_HandleTypeDef EthHandle;
  57. /* Private function prototypes -----------------------------------------------*/
  58. static void ethernetif_input( void const * argument );
  59. static void vTaskUserIF(void *pvParameters);
  60. void HAL_ETH_RESET();
  61. void HAL_ETH_SET();
  62. void HAL_ETH_RESET_INIT();
  63. /* Private functions ---------------------------------------------------------*/
  64. /*******************************************************************************
  65. Ethernet MSP Routines
  66. *******************************************************************************/
  67. /**
  68. * @brief Initializes the ETH MSP.
  69. * @param heth: ETH handle
  70. * @retval None
  71. */
  72. void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
  73. {
  74. GPIO_InitTypeDef GPIO_InitStructure;
  75. /* Enable GPIOs clocks */
  76. __HAL_RCC_GPIOA_CLK_ENABLE();
  77. __HAL_RCC_GPIOB_CLK_ENABLE();
  78. __HAL_RCC_GPIOC_CLK_ENABLE();
  79. __HAL_RCC_GPIOG_CLK_ENABLE();
  80. /* Ethernet pins configuration ************************************************/
  81. /*
  82. ETH_MDIO -------------------------> PA2 PA2
  83. ETH_MDC --------------------------> PC1 PC1
  84. ETH_MII_CRS ----------------------> PH2 PA0
  85. ETH_MII_COL ----------------------> PH3 PA3
  86. ETH_MII_RX_ER --------------------> PI10 PB10
  87. ETH_MII_RXD2 ---------------------> PH6 PB0
  88. ETH_MII_RXD3 ---------------------> PH7 PB1
  89. ETH_MII_TX_CLK -------------------> PC3 PC3
  90. ETH_MII_TXD2 ---------------------> PC2 PC2
  91. ETH_MII_TXD3 ---------------------> PB8 PB8
  92. ETH_MII_RX_CLK/ETH_RMII_REF_CLK---> PA1 PA1
  93. ETH_MII_RX_DV/ETH_RMII_CRS_DV ----> PA7 PA7
  94. ETH_MII_RXD0/ETH_RMII_RXD0 -------> PC4 PC4
  95. ETH_MII_RXD1/ETH_RMII_RXD1 -------> PC5 PC5
  96. ETH_MII_TX_EN/ETH_RMII_TX_EN -----> PG11 PG11
  97. ETH_MII_TXD0/ETH_RMII_TXD0 -------> PG13 PG13
  98. ETH_MII_TXD1/ETH_RMII_TXD1 -------> PG14 PG14
  99. */
  100. HAL_ETH_RESET_INIT();
  101. /* Configure PA0,PA1, PA2 , PA3 , PA7 */
  102. GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_7;
  103. GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
  104. GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
  105. GPIO_InitStructure.Pull = GPIO_NOPULL;
  106. GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
  107. HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
  108. /* Configure PB0 , PB1 ,PB8 , PB10 */
  109. GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_10;
  110. HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
  111. /* Configure PC1, PC2, PC3, PC4 and PC5 */
  112. GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
  113. HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
  114. /* Configure PG11 PG14 and PG13 */
  115. GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14;
  116. HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
  117. /* Enable the Ethernet global Interrupt */
  118. HAL_NVIC_SetPriority(ETH_IRQn, 0x6, 0);
  119. HAL_NVIC_EnableIRQ(ETH_IRQn);
  120. /* Enable ETHERNET clock */
  121. __HAL_RCC_ETH_CLK_ENABLE();
  122. HAL_ETH_SET();
  123. if (heth->Init.MediaInterface == ETH_MEDIA_INTERFACE_MII)
  124. {
  125. /* Output HSE clock (25MHz) on MCO pin (PA8) to clock the PHY */
  126. HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_1);
  127. }
  128. }
  129. /*
  130. *
  131. */
  132. void HAL_ETH_RESET_INIT()
  133. {
  134. __HAL_RCC_GPIOE_CLK_ENABLE();
  135. GPIO_InitTypeDef GPIO_InitStructure;
  136. /* Configure PE2*/
  137. GPIO_InitStructure.Pin = GPIO_PIN_2 ;
  138. GPIO_InitStructure.Speed=GPIO_SPEED_LOW;
  139. GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  140. GPIO_InitStructure.Pull = GPIO_PULLDOWN;
  141. HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);
  142. }
  143. void HAL_ETH_RESET()
  144. {
  145. HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET);
  146. }
  147. void HAL_ETH_SET()
  148. {
  149. HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_SET);
  150. }
  151. /**
  152. * @brief Ethernet Rx Transfer completed callback
  153. * @param heth: ETH handle
  154. * @retval None
  155. */
  156. void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
  157. {
  158. // LED2_TOGGLE;
  159. portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
  160. xSemaphoreGiveFromISR( s_xSemaphore, &xHigherPriorityTaskWoken );
  161. portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
  162. }
  163. /*******************************************************************************
  164. LL Driver Interface ( LwIP stack --> ETH)
  165. *******************************************************************************/
  166. /**
  167. * @brief In this function, the hardware should be initialized.
  168. * Called from ethernetif_init().
  169. *
  170. * @param netif the already initialized lwip network interface structure
  171. * for this ethernetif
  172. */
  173. static void low_level_init(struct netif *netif)
  174. {
  175. uint32_t regvalue = 0;
  176. uint8_t macaddress[6]= { MAC_ADDR0, MAC_ADDR1, MAC_ADDR2, MAC_ADDR3, MAC_ADDR4, MAC_ADDR5 };
  177. EthHandle.Instance = ETH;
  178. EthHandle.Init.MACAddr = macaddress;
  179. EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
  180. EthHandle.Init.Speed = ETH_SPEED_100M;
  181. EthHandle.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
  182. EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_MII;
  183. EthHandle.Init.RxMode = ETH_RXINTERRUPT_MODE;
  184. EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
  185. EthHandle.Init.PhyAddress = DP83848_PHY_ADDRESS;
  186. /* configure ethernet peripheral (GPIOs, clocks, MAC, DMA) */
  187. if (HAL_ETH_Init(&EthHandle) == HAL_OK)
  188. {
  189. /* Set netif link flag */
  190. netif->flags |= NETIF_FLAG_LINK_UP;
  191. }
  192. /* Initialize Tx Descriptors list: Chain Mode */
  193. HAL_ETH_DMATxDescListInit(&EthHandle, DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
  194. /* Initialize Rx Descriptors list: Chain Mode */
  195. HAL_ETH_DMARxDescListInit(&EthHandle, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
  196. /* set netif MAC hardware address length */
  197. netif->hwaddr_len = ETH_HWADDR_LEN;
  198. /* set netif MAC hardware address */
  199. netif->hwaddr[0] = MAC_ADDR0;
  200. netif->hwaddr[1] = MAC_ADDR1;
  201. netif->hwaddr[2] = MAC_ADDR2;
  202. netif->hwaddr[3] = MAC_ADDR3;
  203. netif->hwaddr[4] = MAC_ADDR4;
  204. netif->hwaddr[5] = MAC_ADDR5;
  205. /* set netif maximum transfer unit */
  206. netif->mtu = 1500;
  207. /* Accept broadcast address and ARP traffic */
  208. netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
  209. /* create a binary semaphore used for informing ethernetif of frame reception */
  210. osSemaphoreDef(SEM);
  211. s_xSemaphore = xSemaphoreCreateCounting(40,0);
  212. /* create the task that handles the ETH_MAC */
  213. osThreadDef(EthIf, ethernetif_input, osPriorityRealtime, 0, INTERFACE_THREAD_STACK_SIZE * 3);
  214. osThreadCreate (osThread(EthIf), netif);
  215. /* Enable MAC and DMA transmission and reception */
  216. HAL_ETH_Start(&EthHandle);
  217. /**** Configure PHY to generate an interrupt when Eth Link state changes ****/
  218. /* Read Register Configuration */
  219. HAL_ETH_ReadPHYRegister(&EthHandle, PHY_MICR, &regvalue);
  220. regvalue |= (PHY_MICR_INT_EN | PHY_MICR_INT_OE);
  221. /* Enable Interrupts */
  222. HAL_ETH_WritePHYRegister(&EthHandle, PHY_MICR, regvalue );
  223. /* Read Register Configuration */
  224. HAL_ETH_ReadPHYRegister(&EthHandle, PHY_MISR, &regvalue);
  225. regvalue |= PHY_MISR_LINK_INT_EN;
  226. /* Enable Interrupt on change of link status */
  227. HAL_ETH_WritePHYRegister(&EthHandle, PHY_MISR, regvalue);
  228. }
  229. /**
  230. * @brief This function should do the actual transmission of the packet. The packet is
  231. * contained in the pbuf that is passed to the function. This pbuf
  232. * might be chained.
  233. *
  234. * @param netif the lwip network interface structure for this ethernetif
  235. * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
  236. * @return ERR_OK if the packet could be sent
  237. * an err_t value if the packet couldn't be sent
  238. *
  239. * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
  240. * strange results. You might consider waiting for space in the DMA queue
  241. * to become available since the stack doesn't retry to send a packet
  242. * dropped because of memory failure (except for the TCP timers).
  243. */
  244. static err_t low_level_output(struct netif *netif, struct pbuf *p)
  245. {
  246. err_t errval;
  247. struct pbuf *q;
  248. uint8_t *buffer = (uint8_t *)(EthHandle.TxDesc->Buffer1Addr);
  249. __IO ETH_DMADescTypeDef *DmaTxDesc;
  250. uint32_t framelength = 0;
  251. uint32_t bufferoffset = 0;
  252. uint32_t byteslefttocopy = 0;
  253. uint32_t payloadoffset = 0;
  254. DmaTxDesc = EthHandle.TxDesc;
  255. bufferoffset = 0;
  256. /* copy frame from pbufs to driver buffers */
  257. for(q = p; q != NULL; q = q->next)
  258. {
  259. /* Is this buffer available? If not, goto error */
  260. if((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
  261. {
  262. errval = ERR_USE;
  263. goto error;
  264. }
  265. /* Get bytes in current lwIP buffer */
  266. byteslefttocopy = q->len;
  267. payloadoffset = 0;
  268. /* Check if the length of data to copy is bigger than Tx buffer size*/
  269. while( (byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE )
  270. {
  271. /* Copy data to Tx buffer*/
  272. memcpy( (uint8_t*)((uint8_t*)buffer + bufferoffset), (uint8_t*)((uint8_t*)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset) );
  273. /* Point to next descriptor */
  274. DmaTxDesc = (ETH_DMADescTypeDef *)(DmaTxDesc->Buffer2NextDescAddr);
  275. /* Check if the buffer is available */
  276. if((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
  277. {
  278. errval = ERR_USE;
  279. goto error;
  280. }
  281. buffer = (uint8_t *)(DmaTxDesc->Buffer1Addr);
  282. byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset);
  283. payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset);
  284. framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset);
  285. bufferoffset = 0;
  286. }
  287. /* Copy the remaining bytes */
  288. memcpy( (uint8_t*)((uint8_t*)buffer + bufferoffset), (uint8_t*)((uint8_t*)q->payload + payloadoffset), byteslefttocopy );
  289. bufferoffset = bufferoffset + byteslefttocopy;
  290. framelength = framelength + byteslefttocopy;
  291. }
  292. /* Prepare transmit descriptors to give to DMA */
  293. HAL_ETH_TransmitFrame(&EthHandle, framelength);
  294. errval = ERR_OK;
  295. error:
  296. /* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */
  297. if ((EthHandle.Instance->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET)
  298. {
  299. /* Clear TUS ETHERNET DMA flag */
  300. EthHandle.Instance->DMASR = ETH_DMASR_TUS;
  301. /* Resume DMA transmission*/
  302. EthHandle.Instance->DMATPDR = 0;
  303. }
  304. return errval;
  305. }
  306. /**
  307. * @brief Should allocate a pbuf and transfer the bytes of the incoming
  308. * packet from the interface into the pbuf.
  309. *
  310. * @param netif the lwip network interface structure for this ethernetif
  311. * @return a pbuf filled with the received packet (including MAC header)
  312. * NULL on memory error
  313. */
  314. static struct pbuf * low_level_input(struct netif *netif)
  315. {
  316. struct pbuf *p = NULL, *q = NULL;
  317. uint16_t len = 0;
  318. uint8_t *buffer;
  319. __IO ETH_DMADescTypeDef *dmarxdesc;
  320. uint32_t bufferoffset = 0;
  321. uint32_t payloadoffset = 0;
  322. uint32_t byteslefttocopy = 0;
  323. uint32_t i=0;
  324. /* get received frame */
  325. if(HAL_ETH_GetReceivedFrame_IT(&EthHandle) != HAL_OK)
  326. return NULL;
  327. /* Obtain the size of the packet and put it into the "len" variable. */
  328. len = EthHandle.RxFrameInfos.length;
  329. buffer = (uint8_t *)EthHandle.RxFrameInfos.buffer;
  330. if (len > 0)
  331. {
  332. /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
  333. p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
  334. }
  335. if (p != NULL)
  336. {
  337. dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
  338. bufferoffset = 0;
  339. for(q = p; q != NULL; q = q->next)
  340. {
  341. byteslefttocopy = q->len;
  342. payloadoffset = 0;
  343. /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size */
  344. while( (byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE )
  345. {
  346. /* Copy data to pbuf */
  347. memcpy( (uint8_t*)((uint8_t*)q->payload + payloadoffset), (uint8_t*)((uint8_t*)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset));
  348. /* Point to next descriptor */
  349. dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
  350. buffer = (uint8_t *)(dmarxdesc->Buffer1Addr);
  351. byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset);
  352. payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset);
  353. bufferoffset = 0;
  354. }
  355. /* Copy remaining data in pbuf */
  356. memcpy( (uint8_t*)((uint8_t*)q->payload + payloadoffset), (uint8_t*)((uint8_t*)buffer + bufferoffset), byteslefttocopy);
  357. bufferoffset = bufferoffset + byteslefttocopy;
  358. }
  359. }
  360. /* Release descriptors to DMA */
  361. /* Point to first descriptor */
  362. dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
  363. /* Set Own bit in Rx descriptors: gives the buffers back to DMA */
  364. for (i=0; i< EthHandle.RxFrameInfos.SegCount; i++)
  365. {
  366. dmarxdesc->Status |= ETH_DMARXDESC_OWN;
  367. dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
  368. }
  369. /* Clear Segment_Count */
  370. EthHandle.RxFrameInfos.SegCount =0;
  371. /* When Rx Buffer unavailable flag is set: clear it and resume reception */
  372. if ((EthHandle.Instance->DMASR & ETH_DMASR_RBUS) != (uint32_t)RESET)
  373. {
  374. /* Clear RBUS ETHERNET DMA flag */
  375. EthHandle.Instance->DMASR = ETH_DMASR_RBUS;
  376. /* Resume DMA reception */
  377. EthHandle.Instance->DMARPDR = 0;
  378. }
  379. return p;
  380. }
  381. /**
  382. * @brief This function is the ethernetif_input task, it is processed when a packet
  383. * is ready to be read from the interface. It uses the function low_level_input()
  384. * that should handle the actual reception of bytes from the network
  385. * interface. Then the type of the received packet is determined and
  386. * the appropriate input function is called.
  387. *
  388. * @param netif the lwip network interface structure for this ethernetif
  389. */
  390. void ethernetif_input( void const * argument )
  391. {
  392. struct pbuf *p;
  393. struct netif *netif = (struct netif *) argument;
  394. for( ;; )
  395. {
  396. if (xSemaphoreTake( s_xSemaphore, portMAX_DELAY ) == pdTRUE)
  397. {
  398. do
  399. {
  400. p = low_level_input( netif );
  401. if (p != NULL)
  402. {
  403. if (netif->input( p, netif) != ERR_OK )
  404. {
  405. pbuf_free(p);
  406. }
  407. }
  408. }while(p!=NULL);
  409. }
  410. }
  411. }
  412. /**
  413. * @brief Should be called at the beginning of the program to set up the
  414. * network interface. It calls the function low_level_init() to do the
  415. * actual setup of the hardware.
  416. *
  417. * This function should be passed as a parameter to netif_add().
  418. *
  419. * @param netif the lwip network interface structure for this ethernetif
  420. * @return ERR_OK if the loopif is initialized
  421. * ERR_MEM if private data couldn't be allocated
  422. * any other err_t on error
  423. */
  424. err_t ethernetif_init(struct netif *netif)
  425. {
  426. LWIP_ASSERT("netif != NULL", (netif != NULL));
  427. #if LWIP_NETIF_HOSTNAME
  428. /* Initialize interface hostname */
  429. netif->hostname = "lwip";
  430. #endif /* LWIP_NETIF_HOSTNAME */
  431. netif->name[0] = IFNAME0;
  432. netif->name[1] = IFNAME1;
  433. netif->output = etharp_output;
  434. netif->linkoutput = low_level_output;
  435. /* initialize the hardware */
  436. low_level_init(netif);
  437. return ERR_OK;
  438. }
  439. /**
  440. * @brief This function sets the netif link status.
  441. * @param netif: the network interface
  442. * @retval None
  443. */
  444. void ethernetif_set_link(void const *argument)
  445. {
  446. char flag; // ÍøÂç±ê־λ
  447. uint32_t regvalue = 0;
  448. struct link_str *link_arg = (struct link_str *)argument;
  449. for(;;)
  450. {
  451. // if (osSemaphoreWait( link_arg->semaphore, osWaitForever)== osOK)
  452. // {
  453. /* Read PHY_MISR*/
  454. HAL_ETH_ReadPHYRegister(&EthHandle, PHY_MISR, &regvalue);
  455. /* Check whether the link interrupt has occurred or not */
  456. if((regvalue & PHY_LINK_INTERRUPT) != (uint16_t)RESET)
  457. {
  458. /* Read PHY_SR*/
  459. HAL_ETH_ReadPHYRegister(&EthHandle, PHY_SR, &regvalue);
  460. /* Check whether the link is up or down*/
  461. if((regvalue & PHY_LINK_STATUS)!= (uint16_t)RESET)
  462. {
  463. flag = 1;
  464. write_file("ETH.txt",&flag,1);
  465. netif_set_link_up(link_arg->netif);
  466. __set_PRIMASK(1);
  467. NVIC_SystemReset();
  468. }
  469. else
  470. {
  471. flag = 0;
  472. portENTER_CRITICAL();
  473. write_file("ETH.txt",&flag,1);
  474. portEXIT_CRITICAL();
  475. netif_set_link_down(link_arg->netif);
  476. __set_PRIMASK(1);
  477. NVIC_SystemReset();
  478. }
  479. }
  480. // }
  481. }
  482. }
  483. /**
  484. * @brief Link callback function, this function is called on change of link status
  485. * to update low level driver configuration.
  486. * @param netif: The network interface
  487. * @retval None
  488. */
  489. void ethernetif_update_config(struct netif *netif)
  490. {
  491. __IO uint32_t tickstart = 0;
  492. uint32_t regvalue = 0;
  493. if(netif_is_link_up(netif))
  494. {
  495. /* Restart the auto-negotiation */
  496. if(EthHandle.Init.AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE)
  497. {
  498. /* Enable Auto-Negotiation */
  499. HAL_ETH_WritePHYRegister(&EthHandle, PHY_BCR, PHY_AUTONEGOTIATION);
  500. /* Get tick */
  501. tickstart = HAL_GetTick();
  502. /* Wait until the auto-negotiation will be completed */
  503. do
  504. {
  505. HAL_ETH_ReadPHYRegister(&EthHandle, PHY_BSR, &regvalue);
  506. /* Check for the Timeout ( 1s ) */
  507. if((HAL_GetTick() - tickstart ) > 1000)
  508. {
  509. /* In case of timeout */
  510. goto error;
  511. }
  512. } while (((regvalue & PHY_AUTONEGO_COMPLETE) != PHY_AUTONEGO_COMPLETE));
  513. /* Read the result of the auto-negotiation */
  514. HAL_ETH_ReadPHYRegister(&EthHandle, PHY_SR, &regvalue);
  515. /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
  516. if((regvalue & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
  517. {
  518. /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
  519. EthHandle.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
  520. }
  521. else
  522. {
  523. /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
  524. EthHandle.Init.DuplexMode = ETH_MODE_HALFDUPLEX;
  525. }
  526. /* Configure the MAC with the speed fixed by the auto-negotiation process */
  527. if(regvalue & PHY_SPEED_STATUS)
  528. {
  529. /* Set Ethernet speed to 10M following the auto-negotiation */
  530. EthHandle.Init.Speed = ETH_SPEED_10M;
  531. }
  532. else
  533. {
  534. /* Set Ethernet speed to 100M following the auto-negotiation */
  535. EthHandle.Init.Speed = ETH_SPEED_100M;
  536. }
  537. }
  538. else /* AutoNegotiation Disable */
  539. {
  540. error :
  541. /* Check parameters */
  542. assert_param(IS_ETH_SPEED(EthHandle.Init.Speed));
  543. assert_param(IS_ETH_DUPLEX_MODE(EthHandle.Init.DuplexMode));
  544. /* Set MAC Speed and Duplex Mode to PHY */
  545. HAL_ETH_WritePHYRegister(&EthHandle, PHY_BCR, ((uint16_t)(EthHandle.Init.DuplexMode >> 3) |
  546. (uint16_t)(EthHandle.Init.Speed >> 1)));
  547. }
  548. /* ETHERNET MAC Re-Configuration */
  549. HAL_ETH_ConfigMAC(&EthHandle, (ETH_MACInitTypeDef *) NULL);
  550. /* Restart MAC interface */
  551. HAL_ETH_Start(&EthHandle);
  552. }
  553. else
  554. {
  555. /* Stop MAC interface */
  556. HAL_ETH_Stop(&EthHandle);
  557. }
  558. ethernetif_notify_conn_changed(netif);
  559. }
  560. /**
  561. * @brief This function notify user about link status changement.
  562. * @param netif: the network interface
  563. * @retval None
  564. */
  565. __weak void ethernetif_notify_conn_changed(struct netif *netif)
  566. {
  567. /* NOTE : This is function could be implemented in user file
  568. when the callback is needed,
  569. */
  570. }
  571. u32_t sys_now(void)
  572. {
  573. return HAL_GetTick();
  574. }
  575. static void vTaskUserIF(void *pvParameters)
  576. {
  577. uint8_t pcWriteBuffer[500];
  578. while(1)
  579. {
  580. vTaskList((char *)&pcWriteBuffer);
  581. osDelay(100);
  582. }
  583. }
  584. void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
  585. {
  586. printf("eth err\n");
  587. }
  588. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/