3636 ******************************************************************************
3737 */
3838
39+ #include "Arduino.h"
3940#include "stm32_eth.h"
4041#include "lwip/init.h"
4142#include "lwip/netif.h"
4647#include "lwip/prot/dhcp.h"
4748#include "lwip/dns.h"
4849
49- //Keeps compatibilty with older version of the STM32 core
50- #if __has_include ("core_callback.h" )
51- #include "core_callback.h"
52- #else
53- void registerCoreCallback (void (* func )(void )) {
54- UNUSED (func );
55- }
56- #endif
57-
58-
5950#ifdef __cplusplus
6051 extern "C" {
6152#endif
@@ -69,6 +60,11 @@ void registerCoreCallback(void (*func)(void)) {
6960/* Maximum number of retries for DHCP request */
7061#define MAX_DHCP_TRIES 4
7162
63+ /* Timer used to call the scheduler */
64+ #ifndef DEFAULT_ETHERNET_TIMER
65+ #define DEFAULT_ETHERNET_TIMER TIM14
66+ #endif
67+
7268/* Ethernet configuration: user parameters */
7369struct stm32_eth_config {
7470 ip_addr_t ipaddr ;
@@ -94,13 +90,16 @@ static uint8_t DHCP_Started_by_user = 0;
9490/* Ethernet link status periodic timer */
9591static uint32_t gEhtLinkTickStart = 0 ;
9692
93+ /* Handler for stimer */
94+ static stimer_t TimHandle ;
95+
9796/*************************** Function prototype *******************************/
9897static void Netif_Config (void );
99- static void tcp_connection_close (struct tcp_pcb * tpcb , struct tcp_struct * tcp );
10098static err_t tcp_recv_callback (void * arg , struct tcp_pcb * tpcb , struct pbuf * p , err_t err );
10199static err_t tcp_sent_callback (void * arg , struct tcp_pcb * tpcb , u16_t len );
102100static void tcp_err_callback (void * arg , err_t err );
103-
101+ static void scheduler_callback (stimer_t * htim );
102+ static void TIM_scheduler_Config (void );
104103
105104/**
106105* @brief Configurates the network interface
@@ -132,54 +131,90 @@ static void Netif_Config(void)
132131#endif /* LWIP_NETIF_LINK_CALLBACK */
133132}
134133
134+ /**
135+ * @brief Scheduler callback. Call by a timer interrupt.
136+ * @param htim: pointer to stimer_t
137+ * @retval None
138+ */
139+ static void scheduler_callback (stimer_t * htim )
140+ {
141+ UNUSED (htim );
142+ stm32_eth_scheduler ();
143+ }
144+
145+ /**
146+ * @brief Enable the timer used to call ethernet scheduler function at regular
147+ * interval.
148+ * @param None
149+ * @retval None
150+ */
151+ static void TIM_scheduler_Config (void )
152+ {
153+ /* Set TIMx instance. */
154+ TimHandle .timer = DEFAULT_ETHERNET_TIMER ;
155+
156+ /* Timer set to 1ms */
157+ TimerHandleInit (& TimHandle , (uint16_t )(1000 - 1 ), ((uint32_t )(getTimerClkFreq (DEFAULT_ETHERNET_TIMER ) / (1000000 )) - 1 ));
158+
159+ attachIntHandle (& TimHandle , scheduler_callback );
160+ }
161+
135162void stm32_eth_init (const uint8_t * mac , const uint8_t * ip , const uint8_t * gw , const uint8_t * netmask )
136163{
137- /* Initialize the LwIP stack */
138- lwip_init ();
164+ static uint8_t initDone = 0 ;
165+
166+ if (!initDone ) {
167+ /* Initialize the LwIP stack */
168+ lwip_init ();
169+
170+ if (mac != NULL ) {
171+ ethernetif_set_mac_addr (mac );
172+ } // else default value is used: MAC_ADDR0 ... MAC_ADDR5
173+
174+ if (ip != NULL ) {
175+ IP_ADDR4 (& (gconfig .ipaddr ),ip [0 ],ip [1 ],ip [2 ],ip [3 ]);
176+ } else {
177+ #if LWIP_DHCP
178+ ip_addr_set_zero_ip4 (& (gconfig .ipaddr ));
179+ #else
180+ IP_ADDR4 (& (gconfig .ipaddr ),IP_ADDR0 ,IP_ADDR1 ,IP_ADDR2 ,IP_ADDR3 );
181+ #endif /* LWIP_DHCP */
182+ }
139183
140- if (mac != NULL ) {
141- ethernetif_set_mac_addr (mac );
142- } // else default value is used: MAC_ADDR0 ... MAC_ADDR5
184+ if (gw != NULL ) {
185+ IP_ADDR4 (& (gconfig .gw ),gw [0 ],gw [1 ],gw [2 ],gw [3 ]);
186+ } else {
187+ #if LWIP_DHCP
188+ ip_addr_set_zero_ip4 (& (gconfig .gw ));
189+ #else
190+ IP_ADDR4 (& (gconfig .gw ),GW_ADDR0 ,GW_ADDR1 ,GW_ADDR2 ,GW_ADDR3 );
191+ #endif /* LWIP_DHCP */
192+ }
143193
144- if (ip != NULL ) {
145- IP_ADDR4 (& (gconfig .ipaddr ), ip [0 ],ip [1 ],ip [2 ],ip [3 ]);
146- } else {
147- #if LWIP_DHCP
148- ip_addr_set_zero_ip4 (& (gconfig .ipaddr ));
149- #else
150- IP_ADDR4 (& (gconfig .ipaddr ), IP_ADDR0 , IP_ADDR1 , IP_ADDR2 , IP_ADDR3 );
151- #endif /* LWIP_DHCP */
152- }
194+ if (netmask != NULL ) {
195+ IP_ADDR4 (& (gconfig .netmask ), netmask [0 ],netmask [1 ],netmask [2 ],netmask [3 ]);
196+ } else {
197+ #if LWIP_DHCP
198+ ip_addr_set_zero_ip4 (& (gconfig .netmask ));
199+ #else
200+ IP_ADDR4 (& (gconfig .netmask ), NETMASK_ADDR0 , NETMASK_ADDR1 , NETMASK_ADDR2 , NETMASK_ADDR3 );
201+ #endif /* LWIP_DHCP */
202+ }
153203
154- if (gw != NULL ) {
155- IP_ADDR4 (& (gconfig .gw ),gw [0 ],gw [1 ],gw [2 ],gw [3 ]);
156- } else {
157- #if LWIP_DHCP
158- ip_addr_set_zero_ip4 (& (gconfig .gw ));
159- #else
160- IP_ADDR4 (& (gconfig .gw ),GW_ADDR0 ,GW_ADDR1 ,GW_ADDR2 ,GW_ADDR3 );
161- #endif /* LWIP_DHCP */
162- }
204+ /* Configure the Network interface */
205+ Netif_Config ();
163206
164- if (netmask != NULL ) {
165- IP_ADDR4 (& (gconfig .netmask ),netmask [0 ],netmask [1 ],netmask [2 ],netmask [3 ]);
166- } else {
167- #if LWIP_DHCP
168- ip_addr_set_zero_ip4 (& (gconfig .netmask ));
169- #else
170- IP_ADDR4 (& (gconfig .netmask ),NETMASK_ADDR0 ,NETMASK_ADDR1 ,NETMASK_ADDR2 ,NETMASK_ADDR3 );
171- #endif /* LWIP_DHCP */
172- }
207+ // stm32_eth_scheduler() will be called every 1ms.
208+ TIM_scheduler_Config ();
173209
174- /* Configure the Network interface */
175- Netif_Config ();
210+ initDone = 1 ;
211+ }
176212
213+ /* Reset DHCP if used */
177214 User_notification (& gnetif );
178215
216+ /* Update LwIP stack */
179217 stm32_eth_scheduler ();
180-
181- // stm32_eth_scheduler() will be called directly inside the loop of the main() function.
182- registerCoreCallback (stm32_eth_scheduler );
183218}
184219
185220/**
@@ -954,7 +989,7 @@ static void tcp_err_callback(void *arg, err_t err)
954989 * @param es: pointer on echoclient structure
955990 * @retval None
956991 */
957- static void tcp_connection_close (struct tcp_pcb * tpcb , struct tcp_struct * tcp )
992+ void tcp_connection_close (struct tcp_pcb * tpcb , struct tcp_struct * tcp )
958993{
959994 /* remove callbacks */
960995 tcp_recv (tpcb , NULL );
0 commit comments