ethernetif.c 22 KB

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