cueOS  2.4
cueOS - Universal Show Control OS for ARM
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
ethernet_driver.c
1
20/* Includes ------------------------------------------------------------------*/
21#include "lwip/opt.h"
22#include "lwip/timeouts.h"
23#include "netif/ethernet.h"
24#include "netif/etharp.h"
25#include "lwip/ethip6.h"
26#include <string.h>
27#include "cmsis_os.h"
28#include "stm32f4xx_hal.h"
29#include "ethernet_driver.h"
30
31
32/* Private define ------------------------------------------------------------*/
33/* The time to block waiting for input. */
34#define TIME_WAITING_FOR_INPUT ( portMAX_DELAY )
35/* Stack size of the interface thread */
36#define INTERFACE_THREAD_STACK_SIZE ( 350 )
37/* Network interface name */
38#define IFNAME0 's'
39#define IFNAME1 't'
40
41/* USER CODE BEGIN 1 */
42
43/* USER CODE END 1 */
44
45/* Private variables ---------------------------------------------------------*/
46#if defined ( __ICCARM__ )
47 #pragma data_alignment=4
48#endif
49__ALIGN_BEGIN ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB] __ALIGN_END;/* Ethernet Rx MA Descriptor */
50
51#if defined ( __ICCARM__ )
52 #pragma data_alignment=4
53#endif
54__ALIGN_BEGIN ETH_DMADescTypeDef DMATxDscrTab[ETH_TXBUFNB] __ALIGN_END;/* Ethernet Tx DMA Descriptor */
55
56#if defined ( __ICCARM__ )
57 #pragma data_alignment=4
58#endif
59__ALIGN_BEGIN uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __ALIGN_END; /* Ethernet Receive Buffer */
60
61#if defined ( __ICCARM__ )
62 #pragma data_alignment=4
63#endif
64__ALIGN_BEGIN uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __ALIGN_END; /* Ethernet Transmit Buffer */
65
66/* USER CODE BEGIN 2 */
67
68/* USER CODE END 2 */
69
70/* Semaphore to signal incoming packets */
71osSemaphoreId_t s_xSemaphore = NULL;
72/* Global Ethernet handle */
73ETH_HandleTypeDef heth;
74/* USER CODE BEGIN 3 */
75
76/* USER CODE END 3 */
77
78/* Private functions ---------------------------------------------------------*/
79
80void HAL_ETH_MspInit(ETH_HandleTypeDef* ethHandle)
81{
82 GPIO_InitTypeDef GPIO_InitStruct = {0};
83 if(ethHandle->Instance==ETH)
84 {
85 /* USER CODE BEGIN ETH_MspInit 0 */
86
87 /* USER CODE END ETH_MspInit 0 */
88 /* Enable Peripheral clock */
89 __HAL_RCC_ETH_CLK_ENABLE();
90
91 __HAL_RCC_GPIOC_CLK_ENABLE();
92 __HAL_RCC_GPIOA_CLK_ENABLE();
93 __HAL_RCC_GPIOB_CLK_ENABLE();
105 GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5;
106 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
107 GPIO_InitStruct.Pull = GPIO_NOPULL;
108 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
109 GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
110 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
111
112 GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7;
113 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
114 GPIO_InitStruct.Pull = GPIO_NOPULL;
115 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
116 GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
117 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
118
119 GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13;
120 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
121 GPIO_InitStruct.Pull = GPIO_NOPULL;
122 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
123 GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
124 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
125
126 /* Peripheral interrupt init */
127 HAL_NVIC_SetPriority(ETH_IRQn, 5, 0);
128 HAL_NVIC_EnableIRQ(ETH_IRQn);
129 /* USER CODE BEGIN ETH_MspInit 1 */
130
131 /* USER CODE END ETH_MspInit 1 */
132 }
133}
134
135void HAL_ETH_MspDeInit(ETH_HandleTypeDef* ethHandle)
136{
137 if(ethHandle->Instance==ETH)
138 {
139 /* USER CODE BEGIN ETH_MspDeInit 0 */
140
141 /* USER CODE END ETH_MspDeInit 0 */
142 /* Peripheral clock disable */
143 __HAL_RCC_ETH_CLK_DISABLE();
144
156 HAL_GPIO_DeInit(GPIOC, GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5);
157
158 HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7);
159
160 HAL_GPIO_DeInit(GPIOB, GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13);
161
162 /* Peripheral interrupt Deinit*/
163 HAL_NVIC_DisableIRQ(ETH_IRQn);
164
165 /* USER CODE BEGIN ETH_MspDeInit 1 */
166
167 /* USER CODE END ETH_MspDeInit 1 */
168 }
169}
170
176void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
177{
178 osSemaphoreRelease(s_xSemaphore);
179}
180
181/* USER CODE BEGIN 4 */
182
183/* USER CODE END 4 */
184
185/*******************************************************************************
186 LL Driver Interface ( LwIP stack --> ETH)
187*******************************************************************************/
195static void low_level_init(struct netif *netif)
196{
197 uint32_t regvalue = 0;
198 HAL_StatusTypeDef hal_eth_init_status;
199/* Init ETH */
200
201 uint8_t MACAddr[6] ;
202 heth.Instance = ETH;
203 heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
204 heth.Init.PhyAddress = LAN8742A_PHY_ADDRESS;
205 MACAddr[0] = MAC_ADDR0;
206 MACAddr[1] = MAC_ADDR1;
207 MACAddr[2] = MAC_ADDR2;
208 MACAddr[3] = MAC_ADDR3;
209 MACAddr[4] = MAC_ADDR4;
210 MACAddr[5] = MAC_ADDR5;
211 heth.Init.MACAddr = &MACAddr[0];
212 heth.Init.RxMode = ETH_RXINTERRUPT_MODE;
213 heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
214 heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
215
216 /* USER CODE BEGIN MACADDRESS */
217
218 /* USER CODE END MACADDRESS */
219
220 hal_eth_init_status = HAL_ETH_Init(&heth);
221
222 if (hal_eth_init_status == HAL_OK)
223 {
224 /* Set netif link flag */
225 netif->flags |= NETIF_FLAG_LINK_UP;
226 netif->flags |= NETIF_FLAG_IGMP;
227 }
228 /* Initialize Tx Descriptors list: Chain Mode */
229 HAL_ETH_DMATxDescListInit(&heth, DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
230
231 /* Initialize Rx Descriptors list: Chain Mode */
232 HAL_ETH_DMARxDescListInit(&heth, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
233
234#if LWIP_ARP || LWIP_ETHERNET
235
236 /* set MAC hardware address length */
237 netif->hwaddr_len = ETH_HWADDR_LEN;
238
239 /* set MAC hardware address */
240 netif->hwaddr[0] = heth.Init.MACAddr[0];
241 netif->hwaddr[1] = heth.Init.MACAddr[1];
242 netif->hwaddr[2] = heth.Init.MACAddr[2];
243 netif->hwaddr[3] = heth.Init.MACAddr[3];
244 netif->hwaddr[4] = heth.Init.MACAddr[4];
245 netif->hwaddr[5] = heth.Init.MACAddr[5];
246
247 /* maximum transfer unit */
248 netif->mtu = 1500;
249
250 /* Accept broadcast address and ARP traffic */
251 /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
252 #if LWIP_ARP
253 netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
254 #else
255 netif->flags |= NETIF_FLAG_BROADCAST;
256 #endif /* LWIP_ARP */
257
258/* create a binary semaphore used for informing ethernetif of frame reception */
259 s_xSemaphore = osSemaphoreNew(1, 1, NULL);
260
261 /*FIXME: FIX for semaphore corruption
262 * THREAD SIZE INCREMENTED TO TCPIP STACKSIZE INSTEAD OF PROVIDED INTERFACE THREAD STACK SIZE
263 * TO BE TESTED !!!!!!*/
264 sys_thread_new("EthIf", ethernetif_input, netif, TCPIP_THREAD_STACKSIZE, osPriorityRealtime);
265
266 HAL_ETH_Start(&heth);
267
268/* USER CODE BEGIN PHY_PRE_CONFIG */
269
270/* USER CODE END PHY_PRE_CONFIG */
271
272
273 /* Read Register Configuration */
274 HAL_ETH_ReadPHYRegister(&heth, PHY_ISFR, &regvalue);
275 regvalue |= (PHY_ISFR_INT4);
276
277 /* Enable Interrupt on change of link status */
278 HAL_ETH_WritePHYRegister(&heth, PHY_ISFR , regvalue );
279
280 /* Read Register Configuration */
281 HAL_ETH_ReadPHYRegister(&heth, PHY_ISFR , &regvalue);
282
283/* USER CODE BEGIN PHY_POST_CONFIG */
284
285/* USER CODE END PHY_POST_CONFIG */
286
287#endif /* LWIP_ARP || LWIP_ETHERNET */
288
289/* USER CODE BEGIN LOW_LEVEL_INIT */
290
291/* USER CODE END LOW_LEVEL_INIT */
292}
293
310static err_t low_level_output(struct netif *netif, struct pbuf *p)
311{
312 err_t errval;
313 struct pbuf *q;
314 uint8_t *buffer = (uint8_t *)(heth.TxDesc->Buffer1Addr);
315 __IO ETH_DMADescTypeDef *DmaTxDesc;
316 uint32_t framelength = 0;
317 uint32_t bufferoffset = 0;
318 uint32_t byteslefttocopy = 0;
319 uint32_t payloadoffset = 0;
320 DmaTxDesc = heth.TxDesc;
321 bufferoffset = 0;
322
323 /* copy frame from pbufs to driver buffers */
324 for(q = p; q != NULL; q = q->next)
325 {
326 /* Is this buffer available? If not, goto error */
327 if((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
328 {
329 errval = ERR_USE;
330 goto error;
331 }
332
333 /* Get bytes in current lwIP buffer */
334 byteslefttocopy = q->len;
335 payloadoffset = 0;
336
337 /* Check if the length of data to copy is bigger than Tx buffer size*/
338 while( (byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE )
339 {
340 /* Copy data to Tx buffer*/
341 memcpy( (uint8_t*)((uint8_t*)buffer + bufferoffset), (uint8_t*)((uint8_t*)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset) );
342
343 /* Point to next descriptor */
344 DmaTxDesc = (ETH_DMADescTypeDef *)(DmaTxDesc->Buffer2NextDescAddr);
345
346 /* Check if the buffer is available */
347 if((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
348 {
349 errval = ERR_USE;
350 goto error;
351 }
352
353 buffer = (uint8_t *)(DmaTxDesc->Buffer1Addr);
354
355 byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset);
356 payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset);
357 framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset);
358 bufferoffset = 0;
359 }
360
361 /* Copy the remaining bytes */
362 memcpy( (uint8_t*)((uint8_t*)buffer + bufferoffset), (uint8_t*)((uint8_t*)q->payload + payloadoffset), byteslefttocopy );
363 bufferoffset = bufferoffset + byteslefttocopy;
364 framelength = framelength + byteslefttocopy;
365 }
366
367 /* Prepare transmit descriptors to give to DMA */
368 HAL_ETH_TransmitFrame(&heth, framelength);
369
370 errval = ERR_OK;
371
372error:
373
374 /* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */
375 if ((heth.Instance->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET)
376 {
377 /* Clear TUS ETHERNET DMA flag */
378 heth.Instance->DMASR = ETH_DMASR_TUS;
379
380 /* Resume DMA transmission*/
381 heth.Instance->DMATPDR = 0;
382 }
383 return errval;
384}
385
394static struct pbuf * low_level_input(struct netif *netif)
395{
396 struct pbuf *p = NULL;
397 struct pbuf *q = NULL;
398 uint16_t len = 0;
399 uint8_t *buffer;
400 __IO ETH_DMADescTypeDef *dmarxdesc;
401 uint32_t bufferoffset = 0;
402 uint32_t payloadoffset = 0;
403 uint32_t byteslefttocopy = 0;
404 uint32_t i=0;
405
406
407 /* get received frame */
408 if (HAL_ETH_GetReceivedFrame_IT(&heth) != HAL_OK)
409 return NULL;
410
411 /* Obtain the size of the packet and put it into the "len" variable. */
412 len = heth.RxFrameInfos.length;
413 buffer = (uint8_t *)heth.RxFrameInfos.buffer;
414
415 if (len > 0)
416 {
417 /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
418 p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
419 }
420
421 if (p != NULL)
422 {
423 dmarxdesc = heth.RxFrameInfos.FSRxDesc;
424 bufferoffset = 0;
425 for(q = p; q != NULL; q = q->next)
426 {
427 byteslefttocopy = q->len;
428 payloadoffset = 0;
429
430 /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/
431 while( (byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE )
432 {
433 /* Copy data to pbuf */
434 memcpy( (uint8_t*)((uint8_t*)q->payload + payloadoffset), (uint8_t*)((uint8_t*)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset));
435
436 /* Point to next descriptor */
437 dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
438 buffer = (uint8_t *)(dmarxdesc->Buffer1Addr);
439
440 byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset);
441 payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset);
442 bufferoffset = 0;
443 }
444 /* Copy remaining data in pbuf */
445 memcpy( (uint8_t*)((uint8_t*)q->payload + payloadoffset), (uint8_t*)((uint8_t*)buffer + bufferoffset), byteslefttocopy);
446 bufferoffset = bufferoffset + byteslefttocopy;
447 }
448 }
449
450 /* Release descriptors to DMA */
451 /* Point to first descriptor */
452 dmarxdesc = heth.RxFrameInfos.FSRxDesc;
453 /* Set Own bit in Rx descriptors: gives the buffers back to DMA */
454 for (i=0; i< heth.RxFrameInfos.SegCount; i++)
455 {
456 dmarxdesc->Status |= ETH_DMARXDESC_OWN;
457 dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
458 }
459
460 /* Clear Segment_Count */
461 heth.RxFrameInfos.SegCount =0;
462
463 /* When Rx Buffer unavailable flag is set: clear it and resume reception */
464 if ((heth.Instance->DMASR & ETH_DMASR_RBUS) != (uint32_t)RESET)
465 {
466 /* Clear RBUS ETHERNET DMA flag */
467 heth.Instance->DMASR = ETH_DMASR_RBUS;
468 /* Resume DMA reception */
469 heth.Instance->DMARPDR = 0;
470 }
471 return p;
472}
473
483void ethernetif_input(void * argument)
484{
485 struct pbuf *p;
486 struct netif *netif = (struct netif *) argument;
487
488 for( ;; )
489 {
490 if (osSemaphoreAcquire(s_xSemaphore, TIME_WAITING_FOR_INPUT) == osOK)
491 {
492 do
493 {
494 p = low_level_input( netif );
495 if (p != NULL)
496 {
497 if (netif->input( p, netif) != ERR_OK )
498 {
499 pbuf_free(p);
500 }
501 }
502 } while(p!=NULL);
503 }
504 }
505}
506
507#if !LWIP_ARP
514static err_t low_level_output_arp_off(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr)
515{
516 err_t errval;
517 errval = ERR_OK;
518
519/* USER CODE BEGIN 5 */
520
521/* USER CODE END 5 */
522
523 return errval;
524
525}
526#endif /* LWIP_ARP */
527
540err_t ethernetif_init(struct netif *netif)
541{
542 LWIP_ASSERT("netif != NULL", (netif != NULL));
543
544#if LWIP_NETIF_HOSTNAME
545 /* Initialize interface hostname */
546 netif->hostname = "lwip";
547#endif /* LWIP_NETIF_HOSTNAME */
548
549 netif->name[0] = IFNAME0;
550 netif->name[1] = IFNAME1;
551 /* We directly use etharp_output() here to save a function call.
552 * You can instead declare your own function an call etharp_output()
553 * from it if you have to do some checks before sending (e.g. if link
554 * is available...) */
555
556#if LWIP_IPV4
557#if LWIP_ARP || LWIP_ETHERNET
558#if LWIP_ARP
559 netif->output = etharp_output;
560#else
561 /* The user should write ist own code in low_level_output_arp_off function */
562 netif->output = low_level_output_arp_off;
563#endif /* LWIP_ARP */
564#endif /* LWIP_ARP || LWIP_ETHERNET */
565#endif /* LWIP_IPV4 */
566
567#if LWIP_IPV6
568 netif->output_ip6 = ethip6_output;
569#endif /* LWIP_IPV6 */
570
571 netif->linkoutput = low_level_output;
572
573 /* initialize the hardware */
574 low_level_init(netif);
575
576 return ERR_OK;
577}
578
579/* USER CODE BEGIN 6 */
580
587u32_t sys_jiffies(void)
588{
589 return HAL_GetTick();
590}
591
598u32_t sys_now(void)
599{
600 return HAL_GetTick();
601}
602
603/* USER CODE END 6 */
604
610void ethernetif_set_link(void *argument)
611{
612 uint32_t regvalue = 0;
613 struct link_str *link_arg = (struct link_str *)argument;
614
615 for(;;)
616 {
617 /* Read PHY_BSR*/
618 HAL_ETH_ReadPHYRegister(&heth, PHY_BSR, &regvalue);
619
620 regvalue &= PHY_LINKED_STATUS;
621
622 /* Check whether the netif link down and the PHY link is up */
623 if(!netif_is_link_up(link_arg->netif) && (regvalue))
624 {
625 /* network cable is connected */
626 netif_set_link_up(link_arg->netif);
627 }
628 else if(netif_is_link_up(link_arg->netif) && (!regvalue))
629 {
630 /* network cable is dis-connected */
631 netif_set_link_down(link_arg->netif);
632 }
633
634 /* Suspend thread for 200 ms */
635 osDelay(200);
636 }
637}
638
639/* USER CODE BEGIN 7 */
640
641/* USER CODE END 7 */
642
643#if LWIP_NETIF_LINK_CALLBACK
650void ethernetif_update_config(struct netif *netif)
651{
652 __IO uint32_t tickstart = 0;
653 uint32_t regvalue = 0;
654
655 if(netif_is_link_up(netif))
656 {
657 /* Restart the auto-negotiation */
658 if(heth.Init.AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE)
659 {
660 /* Enable Auto-Negotiation */
661 HAL_ETH_WritePHYRegister(&heth, PHY_BCR, PHY_AUTONEGOTIATION);
662
663 /* Get tick */
664 tickstart = HAL_GetTick();
665
666 /* Wait until the auto-negotiation will be completed */
667 do
668 {
669 HAL_ETH_ReadPHYRegister(&heth, PHY_BSR, &regvalue);
670
671 /* Check for the Timeout ( 1s ) */
672 if((HAL_GetTick() - tickstart ) > 1000)
673 {
674 /* In case of timeout */
675 goto error;
676 }
677 } while (((regvalue & PHY_AUTONEGO_COMPLETE) != PHY_AUTONEGO_COMPLETE));
678
679 /* Read the result of the auto-negotiation */
680 HAL_ETH_ReadPHYRegister(&heth, PHY_SR, &regvalue);
681
682 /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
683 if((regvalue & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
684 {
685 /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
686 heth.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
687 }
688 else
689 {
690 /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
691 heth.Init.DuplexMode = ETH_MODE_HALFDUPLEX;
692 }
693 /* Configure the MAC with the speed fixed by the auto-negotiation process */
694 if(regvalue & PHY_SPEED_STATUS)
695 {
696 /* Set Ethernet speed to 10M following the auto-negotiation */
697 heth.Init.Speed = ETH_SPEED_10M;
698 }
699 else
700 {
701 /* Set Ethernet speed to 100M following the auto-negotiation */
702 heth.Init.Speed = ETH_SPEED_100M;
703 }
704 }
705 else /* AutoNegotiation Disable */
706 {
707 error :
708 /* Check parameters */
709 assert_param(IS_ETH_SPEED(heth.Init.Speed));
710 assert_param(IS_ETH_DUPLEX_MODE(heth.Init.DuplexMode));
711
712 /* Set MAC Speed and Duplex Mode to PHY */
713 HAL_ETH_WritePHYRegister(&heth, PHY_BCR, ((uint16_t)(heth.Init.DuplexMode >> 3) |
714 (uint16_t)(heth.Init.Speed >> 1)));
715 }
716
717 /* ETHERNET MAC Re-Configuration */
718 HAL_ETH_ConfigMAC(&heth, (ETH_MACInitTypeDef *) NULL);
719
720 /* Restart MAC interface */
721 HAL_ETH_Start(&heth);
722 }
723 else
724 {
725 /* Stop MAC interface */
726 HAL_ETH_Stop(&heth);
727 }
728
730}
731
732/* USER CODE BEGIN 8 */
738__weak void ethernetif_notify_conn_changed(struct netif *netif)
739{
740
741}
742/* USER CODE END 8 */
743#endif /* LWIP_NETIF_LINK_CALLBACK */
744
745/* USER CODE BEGIN 9 */
746
747/* USER CODE END 9 */
748/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
749
u32_t sys_now(void)
Returns the current time in milliseconds when LWIP_TIMERS == 1 and NO_SYS == 1.
void ethernetif_notify_conn_changed(struct netif *netif)
Function called on ethernet interface link change.
Definition: net.c:214
err_t ethernetif_init(struct netif *netif)
void ethernetif_set_link(void *argument)
This function sets the netif link status.
void ethernetif_input(void *argument)
u32_t sys_jiffies(void)
Returns the current time in milliseconds when LWIP_TIMERS == 1 and NO_SYS == 1.