[PATCH] STM32 lwIP addition
Robin Mueller
robin.mueller.m at gmail.com
Tue Apr 27 17:41:35 UTC 2021
This patch adds the STM32H7 / NUCLEO-H743ZI lwIP port.
It also improves the architecture to make integration
of new BSPs easier.
https://github.com/rmspacefish/rtems-stm32-lwip is a self-contained
repository to test the lwIP integration for the arm/stm32h7
and arm/nucleo-h743zi BSP.
The STM32 port includes the LAN driver (lan8742.c), the
primary port functions in ethernetif.c and some application code
taken from CubeH7, which can serve as a starting point for
implementations and was also tailored to RTEMS.
The common source file were refactored to be more generic and independent
of the used BSP.
---
.gitignore | 10 +
.gitmodules | 1 +
README.md | 23 +
lwip-to-rtems.py | 0
.../drivers/{eth_lwip.c => rtems_lwip.c} | 181 +++--
.../drivers/{eth_lwip.h => rtems_lwip.h} | 79 +-
.../{eth_lwip_default.h => rtems_lwip_conf.h} | 30 +-
lwip/ports/drivers/stm32h7/app_dhcp.c | 217 +++++
lwip/ports/drivers/stm32h7/app_ethernet.c | 187 +++++
lwip/ports/drivers/stm32h7/ethernetif.c | 758 ++++++++++++++++++
.../stm32h7/include/lwip_port/app_dhcp.h | 38 +
.../stm32h7/include/lwip_port/app_ethernet.h | 56 ++
.../stm32h7/include/lwip_port/ethernetif.h | 56 ++
lwip/ports/drivers/stm32h7/lan8742.c | 664 +++++++++++++++
lwip/ports/drivers/stm32h7/lan8742.h | 448 +++++++++++
.../stm32h7/template/lwipopts_template.h | 289 +++++++
.../ports/drivers/{ => tms570}/phy_dp83848h.c | 0
.../ports/drivers/{ => tms570}/phy_dp83848h.h | 0
.../tms570/template/lwipopts_template.h | 75 ++
lwip/ports/drivers/{ => tms570}/ti_drv_emac.h | 0
lwip/ports/drivers/{ => tms570}/ti_drv_mdio.h | 0
lwip/ports/drivers/{ => tms570}/tms570_emac.h | 0
.../ports/drivers/{ => tms570}/tms570_netif.c | 11 +-
.../ports/drivers/{ => tms570}/tms570_netif.h | 31 +
lwip/ports/os/rtems/arch/cc.h | 3 +
lwip/ports/os/rtems/arch/sys_arch.c | 32 +-
lwip/ports/os/rtems/arch/sys_arch.h | 18 +-
lwip/src/include/lwip/sys.h | 1 -
lwip/{ports/os => test}/lwipopts.h | 0
waf | 0
30 files changed, 3078 insertions(+), 130 deletions(-)
create mode 100644 README.md
mode change 100755 => 100644 lwip-to-rtems.py
rename lwip/ports/drivers/{eth_lwip.c => rtems_lwip.c} (57%)
rename lwip/ports/drivers/{eth_lwip.h => rtems_lwip.h} (56%)
rename lwip/ports/drivers/{eth_lwip_default.h => rtems_lwip_conf.h} (68%)
create mode 100644 lwip/ports/drivers/stm32h7/app_dhcp.c
create mode 100644 lwip/ports/drivers/stm32h7/app_ethernet.c
create mode 100644 lwip/ports/drivers/stm32h7/ethernetif.c
create mode 100644 lwip/ports/drivers/stm32h7/include/lwip_port/app_dhcp.h
create mode 100644 lwip/ports/drivers/stm32h7/include/lwip_port/app_ethernet.h
create mode 100644 lwip/ports/drivers/stm32h7/include/lwip_port/ethernetif.h
create mode 100644 lwip/ports/drivers/stm32h7/lan8742.c
create mode 100644 lwip/ports/drivers/stm32h7/lan8742.h
create mode 100644 lwip/ports/drivers/stm32h7/template/lwipopts_template.h
rename lwip/ports/drivers/{ => tms570}/phy_dp83848h.c (100%)
rename lwip/ports/drivers/{ => tms570}/phy_dp83848h.h (100%)
create mode 100644 lwip/ports/drivers/tms570/template/lwipopts_template.h
rename lwip/ports/drivers/{ => tms570}/ti_drv_emac.h (100%)
rename lwip/ports/drivers/{ => tms570}/ti_drv_mdio.h (100%)
rename lwip/ports/drivers/{ => tms570}/tms570_emac.h (100%)
rename lwip/ports/drivers/{ => tms570}/tms570_netif.c (99%)
rename lwip/ports/drivers/{ => tms570}/tms570_netif.h (74%)
rename lwip/{ports/os => test}/lwipopts.h (100%)
mode change 100755 => 100644 waf
diff --git a/.gitignore b/.gitignore
index 618d791..31a00bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,14 @@
+# Eclipse files
+/.cproject
+/.project
+/.settings
+
+# Python
__pycache__
+
+# Waf
.lock-waf*
.waf*
+
+# Builds
build/
diff --git a/.gitmodules b/.gitmodules
index 4ea46da..a98aac6 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,3 +4,4 @@
[submodule "rtems_waf"]
path = rtems_waf
url = git://git.rtems.org/rtems_waf.git
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e789219
--- /dev/null
+++ b/README.md
@@ -0,0 +1,23 @@
+RTEMS lwIP Repository
+======
+
+This repository contains the RTEMS lwIP support and all available ports.
+Currently, the following RTEMS BSPs are supported:
+
+ - All `arm/tms*` BSPs.
+ - The `arm/stm32h7` and the `arm/nucleo-h743zi` BSP. An example application can be
+ found [here](https://github.com/rmspacefish/rtems-stm32-lwip).
+
+# Using this repository
+
+The repository contains the lwIP sources, the OS port for RTEMS and port files
+belonging to a RTEMS BSP.
+
+The user still needs to supply the `lwipopts.h` configuration file. The port folders contain
+template option files to get started. The user can copy and rename this files into the application
+and then pass the include path to the build system.
+
+# Compiling with CMake
+
+# Compiling with waf
+
diff --git a/lwip-to-rtems.py b/lwip-to-rtems.py
old mode 100755
new mode 100644
diff --git a/lwip/ports/drivers/eth_lwip.c b/lwip/ports/drivers/rtems_lwip.c
similarity index 57%
rename from lwip/ports/drivers/eth_lwip.c
rename to lwip/ports/drivers/rtems_lwip.c
index b1ae4bb..85b6f07 100644
--- a/lwip/ports/drivers/eth_lwip.c
+++ b/lwip/ports/drivers/rtems_lwip.c
@@ -31,53 +31,47 @@
* Based on work of Carlos Jenkins, Rostislav Lisovy, Jan Dolezal
*/
-//#define DEBUG 1
-#include "lwip/tcpip.h" /* includes - lwip/opt.h, lwip/api_msg.h, lwip/netifapi.h, lwip/pbuf.h, lwip/api.h, lwip/sys.h, lwip/timers.h, lwip/netif.h */
+#include "rtems_lwip.h"
+#include "rtems_lwip_conf.h"
+
+#include "lwip/init.h"
#include "lwip/stats.h"
#include "lwip/dhcp.h"
+#include "netif/ethernet.h"
+
+#if LWIP_NETIF_API == 1
#include "lwip/netifapi.h"
-#include "netif/etharp.h" /* includes - lwip/ip.h, lwip/netif.h, lwip/ip_addr.h, lwip/pbuf.h */
-#include "eth_lwip_default.h"
-#include "eth_lwip.h"
-#include "tms570_netif.h"
-#include <stdio.h>
+#endif
-/* The lwIP network interface structure for the Ethernet EMAC. */
-#ifndef MAX_EMAC_INSTANCE
-#define MAX_EMAC_INSTANCE 1
-#endif /*MAX_EMAC_INSTANCE*/
+#if NO_SYS == 0
+#include "lwip/tcpip.h"
+#endif
+
+#include <stdio.h>
#define SUCCESS ERR_OK
#define FAILURE ERR_IF
-static struct netif eth_lwip_netifs[MAX_EMAC_INSTANCE];
-static void eth_lwip_conv_IP_decimal_Str(ip_addr_t ip, uint8_t *ipStr);
-
+/* Assigned in specific port */
+extern netif_init_fn eth_lwip_init_fnc;
-void
-eth_lwip_get_dhcp_info(void)
-{
- struct netif *netif = eth_lwip_get_netif(0);
+/* The lwIP network interface structure for the Ethernet EMAC. */
+#ifndef MAX_EMAC_INSTANCE
+#define MAX_EMAC_INSTANCE 1
+#endif /*MAX_EMAC_INSTANCE*/
- if (dhcp_supplied_address(netif)) {
- uint8_t ipString[16]; // FIXME change the functions to use char
- eth_lwip_conv_IP_decimal_Str(netif->ip_addr, ipString);
- printf("Address: %s\n", ipString);
- eth_lwip_conv_IP_decimal_Str(netif->netmask, ipString);
- printf("Netmask: %s\n", ipString);
- eth_lwip_conv_IP_decimal_Str(netif->gw, ipString);
- printf("Gateway: %s\n", ipString);
- } else {
- printf("dhcp not bound\n");
- }
-}
+struct netif eth_lwip_netifs[MAX_EMAC_INSTANCE];
int8_t
-eth_lwip_init(uint8_t *mac_addr)
+rtems_lwip_init(uint8_t *mac_addr, netif_status_callback_fn netif_status_cb)
{
unsigned int instance_number = 0;
- int8_t retVal = SUCCESS;
+ int8_t retval = SUCCESS;
+#if NO_SYS == 1
+ /* Initialize the lwIP stack */
+ lwip_init();
+#endif
ip4_addr_t ip_addr;
ip4_addr_t net_mask;
@@ -89,63 +83,77 @@ eth_lwip_init(uint8_t *mac_addr)
if (mac_addr == NULL)
mac_addr = default_mac; /* use default MAC */
- eth_lwip_set_hwaddr(netif, mac_addr);
+ rtems_lwip_set_hwaddr(netif, mac_addr);
+
+#if NO_SYS == 0
tcpip_init(NULL, NULL);
+#endif
+
+ rtems_lwip_determine_static_ipv4_address(&ip_addr, &net_mask, &gw_addr);
-#if STATIC_IP_ADDRESS
- ip_addr.addr = htonl(ETH_IP_ADDR);
- net_mask.addr = htonl(ETH_NETMASK);
- gw_addr.addr = htonl(ETH_GW);
+ netif_input_fn netif_input_fnc = NULL;
+#if NO_SYS == 1
+ netif_input_fnc = ðernet_input;
#else
- ip_addr.addr = 0;
- net_mask.addr = 0;
- gw_addr.addr = 0;
+ netif_input_fnc = &tcpip_input;
#endif
netif_tmp = netif_add(netif, &ip_addr, &net_mask, &gw_addr,
- NULL, ETH_LWIP_INIT_NETIF_FNC, tcpip_input);
+ NULL, eth_lwip_init_fnc, netif_input_fnc);
if (netif_tmp == NULL)
return NETIF_ADD_ERR;
netif_set_default(netif);
+
+#if LWIP_NETIF_API == 1
netifapi_netif_set_up(netif);
-#if !STATIC_IP_ADDRESS
+#endif
+
+#if LWIP_NETIF_LINK_CALLBACK
+ if(netif_status_cb != NULL) {
+ netif_status_cb(netif);
+ netif_set_link_callback(netif, netif_status_cb);
+ }
+#endif
+
+#if !STATIC_IP_ADDRESS && NO_SYS == 0 && LWIP_NETIF_API == 1
netifapi_dhcp_start(netif);
#endif
- return retVal;
+ return retval;
+}
+
+void
+rtems_lwip_print_dhcp_info(void)
+{
+ struct netif *netif = rtems_lwip_get_netif(0);
+
+ if (dhcp_supplied_address(netif)) {
+ printf("DHCP information: \n\r");
+ printf("Address: %s\n\r", ip4addr_ntoa(netif_ip4_addr(netif)));
+ printf("Netmask: %s\n\r", ip4addr_ntoa(netif_ip4_netmask(netif)));
+ printf("Gateway: %s\n\r", ip4addr_ntoa(netif_ip4_gw(netif)));
+ } else {
+ printf("DHCP not bound\n\r");
+ }
}
int
-eth_lwip_get_netif_status_cmd(int argc, char *arg[])
+rtems_lwip_get_netif_status_cmd(int argc, char *arg[])
{
stats_display();
return 0;
}
struct netif *
-eth_lwip_get_netif(uint32_t instance_number)
+rtems_lwip_get_netif(uint32_t instance_number)
{
if (instance_number >= MAX_EMAC_INSTANCE)
return NULL;
return ð_lwip_netifs[instance_number];
}
-static void
-eth_lwip_conv_IP_decimal_Str(ip_addr_t ip, uint8_t *ipStr)
-{
- uint32_t addr;
- #if LWIP_IPV6
- addr = ip.u_addr.ip4.addr;
- #else
- addr = ip.addr;
- #endif
-
- snprintf((char *)ipStr, 16, "%lu.%lu.%lu.%lu",
- (addr >> 24), ((addr >> 16) & 0xff), ((addr >> 8) & 0xff), (addr & 0xff));
-}
-
/*
* Function to set the MAC address to the interface
* @param inst_num the instance number
@@ -153,7 +161,7 @@ eth_lwip_conv_IP_decimal_Str(ip_addr_t ip, uint8_t *ipStr)
* @note mac_addr[0] is considered MSB
*/
void
-eth_lwip_set_hwaddr(struct netif *netif, uint8_t *mac_addr)
+rtems_lwip_set_hwaddr(struct netif *netif, uint8_t *mac_addr)
{
int i;
@@ -171,18 +179,61 @@ eth_lwip_set_hwaddr(struct netif *netif, uint8_t *mac_addr)
}
void
-eth_lwip_get_hwaddr_str(struct netif *netif, uint8_t *macStr)
+rtems_lwip_get_hwaddr_str(struct netif *netif, uint8_t *mac_str)
{
uint8_t index, outindex = 0;
char ch;
for (index = 0; index < netif->hwaddr_len; index++) {
if (index)
- macStr[outindex++] = ':';
+ mac_str[outindex++] = ':';
ch = (netif->hwaddr[index] >> 4);
- macStr[outindex++] = (ch < 10) ? (ch + '0') : (ch - 10 + 'A');
+ mac_str[outindex++] = (ch < 10) ? (ch + '0') : (ch - 10 + 'A');
ch = (netif->hwaddr[index] & 0xf);
- macStr[outindex++] = (ch < 10) ? (ch + '0') : (ch - 10 + 'A');
+ mac_str[outindex++] = (ch < 10) ? (ch + '0') : (ch - 10 + 'A');
}
- macStr[outindex] = 0;
+ mac_str[outindex] = 0;
+}
+
+void
+rtems_lwip_convert_ip_to_decimal_str(ip_addr_t ip, uint8_t *ip_str)
+{
+ uint32_t addr;
+ #if LWIP_IPV6
+ addr = ip.u_addr.ip4.addr;
+ #else
+ addr = ip.addr;
+ #endif
+
+ snprintf((char *)ip_str, 16, "%lu.%lu.%lu.%lu",
+ (addr >> 24), ((addr >> 16) & 0xff), ((addr >> 8) & 0xff), (addr & 0xff));
+}
+
+void rtems_lwip_determine_static_ipv4_address(ip4_addr_t* ip_addr, ip4_addr_t* netmask,
+ ip4_addr_t* gw_addr) {
+#if STATIC_IP_ADDRESS == 1
+
+#if CALCULATE_ETH_IP_ADDR == 1
+ IP_ADDR4(ip_addr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
+#else
+ ip_addr->addr = htonl(ETH_IP_ADDR);
+#endif
+
+#if CALCULATE_ETH_NETMASK == 1
+ IP_ADDR4(net_mask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
+#else
+ net_mask->addr = htonl(ETH_NETMASK);
+#endif
+
+#if CALCULATE_GW_ADDRESS == 1
+ IP_ADDR4(gw_addr, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
+#else
+ gw_addr->addr = htonl(ETH_GW);
+#endif
+
+#else
+ ip_addr_set_zero_ip4(ip_addr);
+ ip_addr_set_zero_ip4(netmask);
+ ip_addr_set_zero_ip4(gw_addr);
+#endif /* STATIC_IP_ADDRESS == 0 */
}
diff --git a/lwip/ports/drivers/eth_lwip.h b/lwip/ports/drivers/rtems_lwip.h
similarity index 56%
rename from lwip/ports/drivers/eth_lwip.h
rename to lwip/ports/drivers/rtems_lwip.h
index a9c0325..39a6d16 100644
--- a/lwip/ports/drivers/eth_lwip.h
+++ b/lwip/ports/drivers/rtems_lwip.h
@@ -34,67 +34,64 @@
#ifndef __ETH_LWIP_H
#define __ETH_LWIP_H
+#include "lwip/netif.h"
+#include "rtems_lwip_conf.h"
+
#include <stdio.h>
#include <stdbool.h>
-#include "lwip/netif.h"
-
-/**
- * While scanning phy addresses no alive phy was found.
- * Return value of rpp_eth_hw_init() function.
- */
-#define NO_PHY_ALIVE -1
-/**
- * Scanning default phy address, it was found it's not alive.
- * Return value of rpp_eth_hw_init() function.
- */
-#define DFLT_PHY_NOT_ALIVE -1
-/**
- * When setting autonegotiation parameters to EMAC module, there was found impossible mode (usually on timeout of autonegotiation).
- * Return value of rpp_eth_hw_init_postInit() function.
- */
-#define UNKN_DUPLEX_MODE -2 /* this could mean that autonegotiation was not completed yet */
-/**
- * Phy is down error.
- * Return value of rpp_eth_init_postInit() function.
- */
-#define PHY_LINK_DOWN -3
+#ifdef __cplusplus
+extern "C" {
+#endif
/**
* LwIP netif couldn't be added, it is likely that there was an error during initialization of the hardware.
*/
#define NETIF_ADD_ERR -10 /* could be one of previous, except PHY_LINK_DOWN - currently */
+
/**
- * Memory requirements couldn't be satisfied.
+ * @brief RTEMS lwIP initialization function.
+ *
+ * Call this method before using this module. This function also takes care of initializing
+ * the lwIP stack by calling lwip_init.
+ * @param mac_addr Can be set to NULL to use default mac address
+ * @param netif_status_cb Callback function which will be called if the network
+ * link status changes
+ * @return
+ * - SUCCESS if initialization successful.\n
+ * - NETIF_ADD_ERR Error adding net interface.
*/
-#define DHCP_MEM_ERR -11
+int8_t rtems_lwip_init(uint8_t *mac_addr, netif_status_callback_fn netif_status_cb);
/**
- * configures whether rpp_eth_get_macAddrStr() creates string with big or small latin letters
+ * @brief Access to the net interface instances
*/
-#define MAC_BIG_LETTERS 1
+struct netif *rtems_lwip_get_netif(uint32_t instance_number);
/**
- * ETH module system startup initialization.
- *
- * Call this method before using this module.
- * This method starts autonegotiation and doesn't check for end of autoneg.
- * When eth module is about to be used, you have to run rpp_eth_init_postInit()
- * first and you should check whether link is up.
- *
- * @return SUCCESS if initialization successful.\n
- * FAILURE if module already initialized.
+ * @brief Print information about the assigned DHCP address.
*/
-int8_t eth_lwip_init(uint8_t *mac_addr);
-void eth_lwip_get_dhcp_info(void);
-int eth_lwip_get_netif_status_cmd(int argc, char *arg[]);
-void eth_lwip_set_hwaddr(struct netif *netif, uint8_t *mac_addr);
-void eth_lwip_get_hwaddr_str(struct netif *netif, uint8_t *macStr);
-struct netif *eth_lwip_get_netif(uint32_t instance_number);
+void rtems_lwip_print_dhcp_info(void);
+
+void rtems_lwip_convert_ip_to_decimal_str(ip_addr_t ip, uint8_t *ip_str);
+int rtems_lwip_get_netif_status_cmd(int argc, char *arg[]);
+void rtems_lwip_set_hwaddr(struct netif *netif, uint8_t *mac_addr);
+void rtems_lwip_get_hwaddr_str(struct netif *netif, uint8_t *mac_str);
+/**
+ * @brief Determines a static IP address from the configuration files.
+ * @param ip_addr
+ * @param netmask
+ * @param gw
+ */
+void rtems_lwip_determine_static_ipv4_address(ip4_addr_t* ip_addr, ip4_addr_t* netmask,
+ ip4_addr_t* gw);
+#ifdef __cplusplus
+}
+#endif
#endif /* __ETH_LWIP_H */
diff --git a/lwip/ports/drivers/eth_lwip_default.h b/lwip/ports/drivers/rtems_lwip_conf.h
similarity index 68%
rename from lwip/ports/drivers/eth_lwip_default.h
rename to lwip/ports/drivers/rtems_lwip_conf.h
index 6194d06..85e48f3 100644
--- a/lwip/ports/drivers/eth_lwip_default.h
+++ b/lwip/ports/drivers/rtems_lwip_conf.h
@@ -1,14 +1,8 @@
#ifndef __ETH_LWIP_DEFAULT_H
#define __ETH_LWIP_DEFAULT_H
-/* #define DEBUG 1 */
-/* #define STATIC_IP_ADDRESS 1 */
-
-void tms570_eth_memp_avaible(int type);
-
-#define ETH_LWIP_INIT_NETIF_FNC tms570_eth_init_netif
-/*called from memp_free() when a memp pool was empty and an item is now available*/
-#define LWIP_HOOK_MEMP_AVAILABLE tms570_eth_memp_avaible
+#include "lwipopts.h"
+#include "lwip/etharp.h"
/* this MAC address is used when user put NULL on the right place when calling postInit function */
/**
@@ -20,29 +14,43 @@ void tms570_eth_memp_avaible(int type);
#define ETH_MAC_ADDR { 0x12 /* Unicast, Locally administered */, 0x34, 0x56, 0x78, 0x9A, 0xBC }
#endif
-#if STATIC_IP_ADDRESS
-
/**
* When static IP is configured in lwipopts.h, this IP address is used for interface.
*/
#ifndef ETH_IP_ADDR
+
+#if defined(IP_ADDR0) && defined(IP_ADDR1) && defined(IP_ADDR2) && defined(IP_ADDR3)
+#define CALCULATE_ETH_IP_ADDR
+#else
#define ETH_IP_ADDR 0xC0A8F701 /* 192.168.247.1 */
#endif
+#endif
+
/**
* When static IP is configured in lwipopts.h, this NETMASK address is used for interface.
*/
#ifndef ETH_NETMASK
+
+#if defined(NETMASK_ADDR0) && defined(NETMASK_ADDR1) && defined(NETMASK_ADDR2) && defined(NETMASK_ADDR3)
+#define CALCULATE_ETH_NETMASK
+#else
#define ETH_NETMASK 0xFFFFFF00 /* 255.255.255.0 */
#endif
+#endif
+
/**
* When static IP is configured in lwipopts.h, this Gateway address is used for interface.
*/
#ifndef ETH_GW
+
+#if defined(GW_ADDR0) && defined(GW_ADDR1) && defined(GW_ADDR2) && defined(GW_ADDR3)
+#define CALCULATE_GW_ADDRESS
+#else
#define ETH_GW 0xC0A8F7FE /* 192.168.247.254*/
#endif
-#endif /* STATIC_IP_ADDRESS */
+#endif /* ETH_GW */
#endif /* __ETH_LWIP_DEFAULT_H */
diff --git a/lwip/ports/drivers/stm32h7/app_dhcp.c b/lwip/ports/drivers/stm32h7/app_dhcp.c
new file mode 100644
index 0000000..3889ad7
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/app_dhcp.c
@@ -0,0 +1,217 @@
+/* Includes ------------------------------------------------------------------*/
+#include "app_dhcp.h"
+#include "ethernetif.h"
+#include "stm32h7xx_hal.h"
+#include "lwip/opt.h"
+#include "lwip/dhcp.h"
+#include "lwip/ip_addr.h"
+#include "rtems_lwip.h"
+#include "rtems_lwip_conf.h"
+
+#if NO_SYS == 0
+#include "lwip/sys.h"
+#endif
+#include <sys/unistd.h>
+
+#if LWIP_DHCP
+
+#ifndef MAX_DHCP_TRIES
+#define MAX_DHCP_TRIES 4
+#endif
+
+
+#if NO_SYS == 1
+uint32_t DHCPfineTimer = 0;
+
+#ifndef RTEMS_LWIP_DHCP_TASK_INTERVAL_MS
+#define RTEMS_LWIP_DHCP_TASK_INTERVAL_MS 500
+#endif
+
+#endif
+
+void dhcp_thread(void* argument);
+
+LwipThreadArgs dhcp_args;
+
+uint8_t DHCP_state = DHCP_START;
+
+#if NO_SYS == 0
+
+void rtems_lwip_start_dhcp_thread(uint32_t task_interval_ms,
+ size_t task_stack, uint8_t task_priority) {
+ dhcp_args.netif = rtems_lwip_get_netif(0);
+ dhcp_args.task_interval_ms = task_interval_ms;
+ sys_thread_new("DHCP", dhcp_thread, (void*) &dhcp_args, task_stack, task_priority);
+}
+
+#endif
+
+/**
+ * @brief DHCP Process
+ * @param argument: network interface
+ * @retval None
+ */
+void dhcp_thread(void* argument)
+{
+ ip_addr_t ipaddr;
+ ip_addr_t netmask;
+ ip_addr_t gw;
+ struct dhcp *dhcp = NULL;
+ LwipThreadArgs* args = (LwipThreadArgs*) argument;
+ if(args == NULL) {
+ printf("dhcp_thread: Passed arguments are invalid!\n\r");
+ exit(1);
+ }
+
+ struct netif* netif = args->netif;
+ if(netif == NULL) {
+ printf("dhcp_thread: Passed netif is invalid!\n\r");
+ exit(1);
+ }
+
+ for (;;)
+ {
+ switch (DHCP_state)
+ {
+ case DHCP_START:
+ {
+ ip_addr_set_zero_ip4(&netif->ip_addr);
+ ip_addr_set_zero_ip4(&netif->netmask);
+ ip_addr_set_zero_ip4(&netif->gw);
+ DHCP_state = DHCP_WAIT_ADDRESS;
+
+ dhcp_start(netif);
+ }
+ break;
+ case DHCP_WAIT_ADDRESS:
+ {
+ if (dhcp_supplied_address(netif))
+ {
+ DHCP_state = DHCP_ADDRESS_ASSIGNED;
+ printf("IP address assigned by a DHCP server: %s\n\r",
+ ip4addr_ntoa(netif_ip4_addr(netif)));
+ }
+ else
+ {
+ dhcp = (struct dhcp *)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP);
+
+ /* DHCP timeout */
+ if (dhcp->tries > MAX_DHCP_TRIES)
+ {
+ DHCP_state = DHCP_TIMEOUT;
+
+ uint8_t iptxt[20];
+ sprintf((char *)iptxt, "%s", ip4addr_ntoa(netif_ip4_addr(netif)));
+ printf("DHCP timeout\n\r");
+ printf("Setting static IP address %s..\n\r", iptxt);
+ /* Static address used */
+ rtems_lwip_determine_static_ipv4_address(&ipaddr, &netmask, &gw);
+ netif_set_addr(netif, ip_2_ip4(&ipaddr), ip_2_ip4(&netmask), ip_2_ip4(&gw));
+
+ }
+ }
+ }
+ break;
+ case DHCP_LINK_DOWN:
+ {
+ DHCP_state = DHCP_OFF;
+ }
+ break;
+ default: break;
+ }
+
+ usleep(args->task_interval_ms * 1000);
+ }
+}
+
+#if NO_SYS == 1
+
+void DHCP_Process(struct netif *netif);
+
+/**
+ * @brief DHCP periodic check
+ * @param netif
+ * @retval None
+ */
+void dhcp_periodic_handle(struct netif *netif)
+{
+ /* Fine DHCP periodic process every 500ms */
+ if (HAL_GetTick() - DHCPfineTimer >= RTEMS_LWIP_DHCP_TASK_INTERVAL_MS)
+ {
+ DHCPfineTimer = HAL_GetTick();
+ /* process DHCP state machine */
+ DHCP_Process(netif);
+ }
+}
+
+/**
+ * @brief DHCP_Process_Handle
+ * @param None
+ * @retval None
+ */
+void DHCP_Process(struct netif *netif)
+{
+ ip_addr_t ipaddr;
+ ip_addr_t netmask;
+ ip_addr_t gw;
+ struct dhcp *dhcp = NULL;
+ switch (DHCP_state)
+ {
+ case DHCP_START: {
+
+ ip_addr_set_zero_ip4(&netif->ip_addr);
+ ip_addr_set_zero_ip4(&netif->netmask);
+ ip_addr_set_zero_ip4(&netif->gw);
+ dhcp_start(netif);
+ DHCP_state = DHCP_WAIT_ADDRESS;
+ }
+ break;
+
+ case DHCP_WAIT_ADDRESS: {
+ if (dhcp_supplied_address(netif)) {
+ DHCP_state = DHCP_ADDRESS_ASSIGNED;
+ printf("IP address assigned by a DHCP server: %s\n\r", ip4addr_ntoa(netif_ip4_addr(netif)));
+ }
+ else
+ {
+ dhcp = (struct dhcp *)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP);
+
+ /* DHCP timeout */
+ if (dhcp->tries > MAX_DHCP_TRIES)
+ {
+ DHCP_state = DHCP_TIMEOUT;
+
+ uint8_t iptxt[20];
+ sprintf((char *)iptxt, "%s", ip4addr_ntoa(netif_ip4_addr(netif)));
+ printf("DHCP timeout\n\r");
+ printf("Setting static IP address %s..\n\r", iptxt);
+ /* Static address used */
+ rtems_lwip_determine_static_ipv4_address(&ipaddr, &netmask, &gw);
+ netif_set_addr(netif, &ipaddr, &netmask, &gw);
+
+ }
+ }
+ }
+ break;
+ case DHCP_LINK_DOWN: {
+ /* Stop DHCP */
+ //dhcp_release_and_stop(netif);
+ DHCP_state = DHCP_OFF;
+ }
+ break;
+ default: break;
+ }
+}
+
+#endif /* NO_SYS == 1 */
+
+void set_dhcp_state(uint8_t new_state) {
+ DHCP_state = new_state;
+}
+
+uint8_t get_dhcp_state() {
+ return DHCP_state;
+}
+
+#endif /* LWIP_DHCP */
+
diff --git a/lwip/ports/drivers/stm32h7/app_ethernet.c b/lwip/ports/drivers/stm32h7/app_ethernet.c
new file mode 100644
index 0000000..bafec01
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/app_ethernet.c
@@ -0,0 +1,187 @@
+/**
+ ******************************************************************************
+ * @file LwIP/LwIP_HTTP_Server_Netconn_RTOS/Src/app_ethernet.c
+ * @author MCD Application Team
+ * @brief Ethernet specefic module
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+#include "rtems_lwip_conf.h"
+#include "rtems_lwip.h"
+#include "stm32h7/lan8742.h"
+#include "stm32h7xx_hal.h"
+#include "lwip/opt.h"
+#if LWIP_DHCP
+#include "lwip/dhcp.h"
+#endif
+
+#if NO_SYS == 0
+#include "lwip/sys.h"
+#endif
+
+#include "app_ethernet.h"
+#include "app_dhcp.h"
+#include "ethernetif.h"
+
+void set_dhcp_state(uint8_t new_state);
+
+/* Private typedef -----------------------------------------------------------*/
+LwipThreadArgs linkArgs;
+
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+#if NO_SYS == 1
+uint32_t ethernet_link_timer = 0;
+#endif
+
+/* Private function prototypes -----------------------------------------------*/
+void ethernet_link_thread( void* argument );
+lan8742_Object_t* get_lan_phy_handle();
+ETH_HandleTypeDef* get_eth_handle();
+
+/* Private functions ---------------------------------------------------------*/
+/**
+ * @brief Notify the User about the nework interface config status
+ * @param netif: the network interface
+ * @retval None
+ */
+void ethernet_link_status_updated(struct netif *netif)
+{
+ if (netif_is_up(netif)) {
+#if LWIP_DHCP
+ printf("Ethernet link up. Setting DHCP state..\n\r");
+ /* Update DHCP state machine */
+ set_dhcp_state(DHCP_START);
+#endif /* LWIP_DHCP */
+ }
+ else {
+#if LWIP_DHCP
+ printf("Ethernet link down. Setting DHCP state..\n\r");
+ /* Update DHCP state machine */
+ set_dhcp_state(DHCP_LINK_DOWN);
+#endif /* LWIP_DHCP */
+ }
+}
+
+#if LWIP_NETIF_LINK_CALLBACK == 1 && NO_SYS == 1
+/**
+ * @brief Ethernet Link periodic check
+ * @param netif
+ * @retval None
+ */
+void ethernet_link_periodic_handle(struct netif *netif)
+{
+ uint32_t time_now = HAL_GetTick();
+ /* Ethernet Link every 100ms */
+ if (time_now - ethernet_link_timer >= 100)
+ {
+ ethernet_link_timer = time_now;
+ ethernet_link_check_state(netif);
+ }
+}
+#endif
+
+#if NO_SYS == 0
+
+void rtems_lwip_start_link_thread(uint32_t task_interval_ms,
+ size_t task_stack, uint8_t task_priority) {
+ linkArgs.netif = rtems_lwip_get_netif(0);
+ linkArgs.task_interval_ms = task_interval_ms;
+ sys_thread_new("LINK", ethernet_link_thread, (void*) &linkArgs, task_stack, task_priority);
+}
+
+#endif
+
+/**
+ * @brief Check the ETH link state and update netif accordingly.
+ * @param argument: netif
+ * @retval None
+ */
+void ethernet_link_thread( void* argument )
+{
+ ETH_MACConfigTypeDef MACConf;
+ int32_t PHYLinkState;
+ uint32_t linkchanged = 0, speed = 0, duplex =0;
+ LwipThreadArgs* args = (LwipThreadArgs*) argument;
+ if(args == NULL) {
+ printf("ethernet_link_thread: Passed arguments are invalid!\n\r");
+ exit(1);
+ }
+
+ struct netif *netif = args->netif;
+ if(netif == NULL) {
+ printf("ethernet_link_thread: Passed netif is invalid!\n\r");
+ exit(1);
+ }
+
+ lan8742_Object_t* lan = get_lan_phy_handle();
+ ETH_HandleTypeDef* eth = get_eth_handle();
+ for(;;)
+ {
+
+ PHYLinkState = LAN8742_GetLinkState(lan);
+
+ if(netif_is_link_up(netif) && (PHYLinkState <= LAN8742_STATUS_LINK_DOWN))
+ {
+ HAL_ETH_Stop_IT(eth);
+ netif_set_down(netif);
+ netif_set_link_down(netif);
+ }
+ else if(!netif_is_link_up(netif) && (PHYLinkState > LAN8742_STATUS_LINK_DOWN))
+ {
+ switch (PHYLinkState)
+ {
+ case LAN8742_STATUS_100MBITS_FULLDUPLEX:
+ duplex = ETH_FULLDUPLEX_MODE;
+ speed = ETH_SPEED_100M;
+ linkchanged = 1;
+ break;
+ case LAN8742_STATUS_100MBITS_HALFDUPLEX:
+ duplex = ETH_HALFDUPLEX_MODE;
+ speed = ETH_SPEED_100M;
+ linkchanged = 1;
+ break;
+ case LAN8742_STATUS_10MBITS_FULLDUPLEX:
+ duplex = ETH_FULLDUPLEX_MODE;
+ speed = ETH_SPEED_10M;
+ linkchanged = 1;
+ break;
+ case LAN8742_STATUS_10MBITS_HALFDUPLEX:
+ duplex = ETH_HALFDUPLEX_MODE;
+ speed = ETH_SPEED_10M;
+ linkchanged = 1;
+ break;
+ default:
+ break;
+ }
+
+ if(linkchanged)
+ {
+ /* Get MAC Config MAC */
+ HAL_ETH_GetMACConfig(eth, &MACConf);
+ MACConf.DuplexMode = duplex;
+ MACConf.Speed = speed;
+ HAL_ETH_SetMACConfig(eth, &MACConf);
+ HAL_ETH_Start_IT(eth);
+ netif_set_up(netif);
+ netif_set_link_up(netif);
+ }
+ }
+
+ usleep(args->task_interval_ms * 1000);
+ }
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/lwip/ports/drivers/stm32h7/ethernetif.c b/lwip/ports/drivers/stm32h7/ethernetif.c
new file mode 100644
index 0000000..c6b8820
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/ethernetif.c
@@ -0,0 +1,758 @@
+/**
+ ******************************************************************************
+ * @file LwIP/LwIP_HTTP_Server_Netconn_RTOS/Src/ethernetif.c
+ * @author MCD Application Team
+ * @brief This file implements Ethernet network interface drivers for lwIP
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+#include "lwip/timeouts.h"
+#include "netif/ethernet.h"
+#include "netif/etharp.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+#include "lwip/tcpip.h"
+#include "ethernetif.h"
+
+#include "lan8742.h"
+#include <string.h>
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define DMA_DESCRIPTOR_ALIGNMENT ( 0x20 )
+
+/* RTEMS priorities range from 1 (highest) to 255 (lowest) */
+#ifndef RTEMS_LWIP_INTERFACE_THREAD_PRIORITY
+#define RTEMS_LWIP_INTERFACE_THREAD_PRIORITY ( 50 )
+#endif
+
+/* Stack size of the interface thread */
+#ifndef RTEMS_LWIP_INTERFACE_THREAD_STACK_SIZE
+#define RTEMS_LWIP_INTERFACE_THREAD_STACK_SIZE ( RTEMS_MINIMUM_STACK_SIZE )
+#endif
+
+/* Define those to better describe your network interface. */
+#define IFNAME0 's'
+#define IFNAME1 't'
+
+#ifndef RTEMS_LWIP_ETH_DMA_TRANSMIT_TIMEOUT
+#define RTEMS_LWIP_ETH_DMA_TRANSMIT_TIMEOUT ( 20U )
+#endif
+
+/* The MPU protection is unreliable for the Socket API. The exact cause is not know yet.
+It's safer to always clean data cache for now */
+#ifndef RTEMS_LWIP_PROTECT_LWIP_HEAP_WITH_MPU
+#define RTEMS_LWIP_PROTECT_LWIP_HEAP_WITH_MPU 1
+#endif
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/*
+ at Note: This interface is implemented to operate in zero-copy mode only:
+ - Rx buffers are allocated statically and passed directly to the LwIP stack,
+ they will return back to ETH DMA after been processed by the stack.
+ - Tx Buffers will be allocated from LwIP stack memory heap,
+ then passed to ETH HAL driver.
+
+ at Notes:
+ 1.a. ETH DMA Rx descriptors must be contiguous, the default count is 4,
+ to customize it please redefine ETH_RX_DESC_CNT in stm32xxxx_hal_conf.h
+ 1.b. ETH DMA Tx descriptors must be contiguous, the default count is 4,
+ to customize it please redefine ETH_TX_DESC_CNT in stm32xxxx_hal_conf.h
+
+ 2.a. Rx Buffers number must be between ETH_RX_DESC_CNT and 2*ETH_RX_DESC_CNT
+ 2.b. Rx Buffers must have the same size: ETH_RX_BUFFER_SIZE, this value must
+ passed to ETH DMA in the init field (EthHandle.Init.RxBuffLen)
+ 2.c The RX Ruffers addresses and sizes must be properly defined to be aligned
+ to L1-CACHE line size (32 bytes).
+*/
+
+netif_init_fn eth_lwip_init_fnc = ðernetif_init;
+
+/* Put into special RTEMS section and align correctly */
+ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".bsp_nocache"), __aligned__(DMA_DESCRIPTOR_ALIGNMENT))); /* Ethernet Rx DMA Descriptors */
+/* Put into special RTEMS section and align correctly */
+ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".bsp_nocache"), __aligned__(DMA_DESCRIPTOR_ALIGNMENT))); /* Ethernet Tx DMA Descriptors */
+/* Ethernet Receive Buffers. Just place somewhere is BSS instead of explicitely placing it */
+uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE] RTEMS_ALIGNED(DMA_DESCRIPTOR_ALIGNMENT);
+
+ETH_HandleTypeDef EthHandle;
+ETH_TxPacketConfig TxConfig;
+
+lan8742_Object_t LAN8742;
+
+#if NO_SYS == 0
+sys_sem_t RxPktSemaphore; /* Semaphore to signal incoming packets */
+#endif
+
+/* Private function prototypes -----------------------------------------------*/
+#if !STATIC_IP_ADDRESS && NO_SYS == 0 && LWIP_NETIF_API == 1
+void set_dhcp_state(uint8_t new_state);
+#endif
+
+uint8_t determine_mpu_region_size_select(size_t lwip_heap_size);
+static void low_level_init(struct netif *netif);
+static err_t low_level_output(struct netif *netif, struct pbuf *p);
+void ethernet_link_check_state(struct netif *netif);
+
+void pbuf_free_custom(struct pbuf *p);
+
+int32_t ETH_PHY_IO_Init(void);
+int32_t ETH_PHY_IO_DeInit (void);
+int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal);
+int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal);
+int32_t ETH_PHY_IO_GetTick(void);
+
+
+lan8742_IOCtx_t LAN8742_IOCtx = {ETH_PHY_IO_Init,
+ ETH_PHY_IO_DeInit,
+ ETH_PHY_IO_WriteReg,
+ ETH_PHY_IO_ReadReg,
+ ETH_PHY_IO_GetTick};
+
+LWIP_MEMPOOL_DECLARE(RX_POOL, 10, sizeof(struct pbuf_custom), "Zero-copy RX PBUF pool");
+
+/* Private functions ---------------------------------------------------------*/
+/*******************************************************************************
+ LL Driver Interface ( LwIP stack --> ETH)
+*******************************************************************************/
+
+/**
+ * @brief Should be called at the beginning of the program to set up the
+ * network interface. It calls the function low_level_init() to do the
+ * actual setup of the hardware.
+ *
+ * This function should be passed as a parameter to netif_add().
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @return ERR_OK if the loopif is initialized
+ * ERR_MEM if private data couldn't be allocated
+ * any other err_t on error
+ */
+err_t ethernetif_init(struct netif *netif)
+{
+ LWIP_ASSERT("netif != NULL", (netif != NULL));
+
+#if RTEMS_LWIP_PROTECT_LWIP_HEAP_WITH_MPU == 1
+ mpu_config_tx_buffers(LWIP_RAM_HEAP_POINTER, MEM_SIZE);
+#endif
+
+#if LWIP_NETIF_HOSTNAME
+ /* Initialize interface hostname */
+ netif->hostname = "lwip";
+#endif /* LWIP_NETIF_HOSTNAME */
+
+#if NO_SYS == 0
+ /*
+ * Initialize the snmp variables and counters inside the struct netif.
+ * The last argument should be replaced with your link speed, in units
+ * of bits per second.
+ */
+ MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
+#endif
+
+ netif->name[0] = IFNAME0;
+ netif->name[1] = IFNAME1;
+
+ /* We directly use etharp_output() here to save a function call.
+ * You can instead declare your own function an call etharp_output()
+ * from it if you have to do some checks before sending (e.g. if link
+ * is available...) */
+ netif->output = etharp_output;
+ netif->linkoutput = low_level_output;
+
+ /* This is already done by the generic driver, so the internal state machine is set accordingly */
+#if !STATIC_IP_ADDRESS && NO_SYS == 0 && LWIP_NETIF_API == 1
+ set_dhcp_state(DHCP_WAIT_ADDRESS);
+#endif
+
+ /* initialize the hardware */
+ low_level_init(netif);
+
+ return ERR_OK;
+}
+
+/**
+ * @brief In this function, the hardware should be initialized.
+ * Called from ethernetif_init().
+ *
+ * @param netif the already initialized lwip network interface structure
+ * for this ethernetif
+ */
+static void low_level_init(struct netif *netif)
+{
+#if NO_SYS == 0
+ int32_t PHYLinkState;
+ ETH_MACConfigTypeDef MACConf;
+ uint32_t duplex, speed = 0;
+#endif
+ uint32_t idx = 0;
+ uint8_t macaddress[6]= {ETH_MAC_ADDR0, ETH_MAC_ADDR1, ETH_MAC_ADDR2, ETH_MAC_ADDR3, ETH_MAC_ADDR4, ETH_MAC_ADDR5};
+
+ EthHandle.Instance = ETH;
+ EthHandle.Init.MACAddr = macaddress;
+ EthHandle.Init.MediaInterface = HAL_ETH_RMII_MODE;
+ EthHandle.Init.RxDesc = DMARxDscrTab;
+ EthHandle.Init.TxDesc = DMATxDscrTab;
+ EthHandle.Init.RxBuffLen = ETH_RX_BUFFER_SIZE;
+
+ /* configure ethernet peripheral (GPIOs, clocks, MAC, DMA) */
+ HAL_ETH_Init(&EthHandle);
+
+#if NO_SYS == 0
+ /* Enable the Ethernet global Interrupt */
+ HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0);
+ HAL_NVIC_EnableIRQ(ETH_IRQn);
+#endif
+
+ /* set MAC hardware address length */
+ netif->hwaddr_len = ETH_HWADDR_LEN;
+
+ /* set MAC hardware address */
+ netif->hwaddr[0] = ETH_MAC_ADDR0;
+ netif->hwaddr[1] = ETH_MAC_ADDR1;
+ netif->hwaddr[2] = ETH_MAC_ADDR2;
+ netif->hwaddr[3] = ETH_MAC_ADDR3;
+ netif->hwaddr[4] = ETH_MAC_ADDR4;
+ netif->hwaddr[5] = ETH_MAC_ADDR5;
+
+ /* maximum transfer unit */
+ netif->mtu = ETH_MAX_PAYLOAD;
+
+ /* device capabilities */
+ /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
+ netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
+
+ for(idx = 0; idx < ETH_RX_DESC_CNT; idx ++)
+ {
+ HAL_ETH_DescAssignMemory(&EthHandle, idx, Rx_Buff[idx], NULL);
+ }
+
+ /* Initialize the RX POOL */
+ LWIP_MEMPOOL_INIT(RX_POOL);
+
+ memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig));
+ TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;
+ TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
+ TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT;
+
+#if NO_SYS == 0
+ /* create a binary semaphore used for informing ethernetif of frame reception */
+ sys_sem_new(&RxPktSemaphore, 1);
+
+ /* create the task that handles the ETH_MAC */
+ sys_thread_new(
+ "ETHM",
+ (lwip_thread_fn) ethernetif_input,
+ netif,
+ RTEMS_LWIP_INTERFACE_THREAD_STACK_SIZE,
+ RTEMS_LWIP_INTERFACE_THREAD_PRIORITY
+ );
+
+#endif
+
+ /* Set PHY IO functions */
+ LAN8742_RegisterBusIO(&LAN8742, &LAN8742_IOCtx);
+
+ /* Initialize the LAN8742 ETH PHY */
+ LAN8742_Init(&LAN8742);
+
+#if NO_SYS == 0
+ PHYLinkState = LAN8742_GetLinkState(&LAN8742);
+
+ /* Get link state */
+ if(PHYLinkState <= LAN8742_STATUS_LINK_DOWN)
+ {
+ netif_set_link_down(netif);
+ netif_set_down(netif);
+ }
+ else
+ {
+ switch (PHYLinkState)
+ {
+ case LAN8742_STATUS_100MBITS_FULLDUPLEX:
+ duplex = ETH_FULLDUPLEX_MODE;
+ speed = ETH_SPEED_100M;
+ break;
+ case LAN8742_STATUS_100MBITS_HALFDUPLEX:
+ duplex = ETH_HALFDUPLEX_MODE;
+ speed = ETH_SPEED_100M;
+ break;
+ case LAN8742_STATUS_10MBITS_FULLDUPLEX:
+ duplex = ETH_FULLDUPLEX_MODE;
+ speed = ETH_SPEED_10M;
+ break;
+ case LAN8742_STATUS_10MBITS_HALFDUPLEX:
+ duplex = ETH_HALFDUPLEX_MODE;
+ speed = ETH_SPEED_10M;
+ break;
+ default:
+ duplex = ETH_FULLDUPLEX_MODE;
+ speed = ETH_SPEED_100M;
+ break;
+ }
+
+ /* Get MAC Config MAC */
+ HAL_ETH_GetMACConfig(&EthHandle, &MACConf);
+ MACConf.DuplexMode = duplex;
+ MACConf.Speed = speed;
+ HAL_ETH_SetMACConfig(&EthHandle, &MACConf);
+ HAL_ETH_Start_IT(&EthHandle);
+ /* Install the ETH IRQ for RTEMS */
+ rtems_interrupt_handler_install(ETH_IRQn, NULL, RTEMS_INTERRUPT_UNIQUE,
+ (rtems_interrupt_handler) &HAL_ETH_IRQHandler, &EthHandle);
+ netif_set_up(netif);
+ netif_set_link_up(netif);
+ }
+#endif
+
+ ethernet_link_check_state(netif);
+}
+
+/**
+ * @brief This function should do the actual transmission of the packet. The packet is
+ * contained in the pbuf that is passed to the function. This pbuf
+ * might be chained.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
+ * @return ERR_OK if the packet could be sent
+ * an err_t value if the packet couldn't be sent
+ *
+ * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
+ * strange results. You might consider waiting for space in the DMA queue
+ * to become available since the stack doesn't retry to send a packet
+ * dropped because of memory failure (except for the TCP timers).
+ */
+static err_t low_level_output(struct netif *netif, struct pbuf *p)
+{
+ uint32_t i=0;
+ struct pbuf *q;
+ err_t errval = ERR_OK;
+ ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT];
+
+ memset(Txbuffer, 0 , ETH_TX_DESC_CNT*sizeof(ETH_BufferTypeDef));
+
+ for(q = p; q != NULL; q = q->next)
+ {
+ if(i >= ETH_TX_DESC_CNT)
+ return ERR_IF;
+
+ Txbuffer[i].buffer = q->payload;
+ Txbuffer[i].len = q->len;
+
+ /* For the socket API, a custom send buffer might be used which is not protected by the
+ MPU. Therefore, clean DCache here as well */
+#if RTEMS_LWIP_PROTECT_LWIP_HEAP_WITH_MPU == 0 || LWIP_SOCKET == 1
+ /* Cleaning cache isn't necessary if the tx buffers are in a not-cacheable MPU region. */
+ uint8_t *dataStart = q->payload;
+ uint8_t *lineStart = (uint8_t *)((uint32_t)dataStart & ~31);
+ SCB_CleanDCache_by_Addr((uint32_t *)lineStart, q->len + (dataStart - lineStart));
+#endif
+
+ if(i>0)
+ {
+ Txbuffer[i-1].next = &Txbuffer[i];
+ }
+
+ if(q->next == NULL)
+ {
+ Txbuffer[i].next = NULL;
+ }
+
+ i++;
+ }
+
+ TxConfig.Length = p->tot_len;
+ TxConfig.TxBuffer = Txbuffer;
+
+ HAL_ETH_Transmit(&EthHandle, &TxConfig, RTEMS_LWIP_ETH_DMA_TRANSMIT_TIMEOUT);
+
+ return errval;
+}
+
+/**
+ * @brief Should allocate a pbuf and transfer the bytes of the incoming
+ * packet from the interface into the pbuf.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @return a pbuf filled with the received packet (including MAC header)
+ * NULL on memory error
+ */
+static struct pbuf * low_level_input(struct netif *netif)
+{
+ struct pbuf *p = NULL;
+ ETH_BufferTypeDef RxBuff[ETH_RX_DESC_CNT];
+ uint32_t framelength = 0, i = 0;;
+ struct pbuf_custom* custom_pbuf;
+
+ memset(RxBuff, 0 , ETH_RX_DESC_CNT*sizeof(ETH_BufferTypeDef));
+
+ for(i = 0; i < ETH_RX_DESC_CNT -1; i++)
+ {
+ RxBuff[i].next=&RxBuff[i+1];
+ }
+
+#if NO_SYS == 0
+ if(HAL_ETH_GetRxDataBuffer(&EthHandle, RxBuff) == HAL_OK)
+#else
+ if (HAL_ETH_IsRxDataAvailable(&EthHandle))
+#endif
+ {
+
+#if NO_SYS == 1
+ HAL_ETH_GetRxDataBuffer(&EthHandle, RxBuff);
+#endif
+
+ HAL_ETH_GetRxDataLength(&EthHandle, &framelength);
+
+ /* Build Rx descriptor to be ready for next data reception */
+ HAL_ETH_BuildRxDescriptors(&EthHandle);
+
+ /* Invalidate data cache for ETH Rx Buffers */
+ SCB_InvalidateDCache_by_Addr((uint32_t *)RxBuff->buffer, framelength);
+
+ custom_pbuf = (struct pbuf_custom*)LWIP_MEMPOOL_ALLOC(RX_POOL);
+ if(custom_pbuf != NULL)
+ {
+ custom_pbuf->custom_free_function = pbuf_free_custom;
+
+ p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_REF, custom_pbuf, RxBuff->buffer, framelength);
+ }
+
+ }
+
+ return p;
+}
+
+#if NO_SYS == 0
+/**
+ * @brief This function is the ethernetif_input task, it is processed when a packet
+ * is ready to be read from the interface. It uses the function low_level_input()
+ * that should handle the actual reception of bytes from the network
+ * interface. Then the type of the received packet is determined and
+ * the appropriate input function is called.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ */
+void ethernetif_input(struct netif *netif)
+{
+ struct pbuf *p;
+
+ for( ;; )
+ {
+ if (sys_arch_sem_wait(&RxPktSemaphore, 0) != SYS_ARCH_TIMEOUT)
+ {
+ do
+ {
+ p = low_level_input( netif );
+ if (p != NULL)
+ {
+ if (netif->input( p, netif) != ERR_OK )
+ {
+ pbuf_free(p);
+ }
+ }
+
+ }while(p!=NULL);
+ }
+ }
+}
+#else
+/**
+ * @brief This function is the ethernetif_input task, it is processed when a packet
+ * is ready to be read from the interface. It uses the function low_level_input()
+ * that should handle the actual reception of bytes from the network
+ * interface. Then the type of the received packet is determined and
+ * the appropriate input function is called.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ */
+void ethernetif_input(struct netif *netif)
+{
+ err_t err;
+ struct pbuf *p;
+
+ /* move received packet into a new pbuf */
+ p = low_level_input(netif);
+
+ /* no packet could be read, silently ignore this */
+ if (p == NULL) return;
+
+ /* entry point to the LwIP stack */
+ err = netif->input(p, netif);
+
+ if (err != ERR_OK)
+ {
+ LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
+ pbuf_free(p);
+ p = NULL;
+ }
+}
+#endif /* NO_SYS == 1 */
+
+/**
+ * @brief Custom Rx pbuf free callback
+ * @param pbuf: pbuf to be freed
+ * @retval None
+ */
+void pbuf_free_custom(struct pbuf *p)
+{
+ struct pbuf_custom* custom_pbuf = (struct pbuf_custom*)p;
+ LWIP_MEMPOOL_FREE(RX_POOL, custom_pbuf);
+}
+
+
+/*******************************************************************************
+ Ethernet MSP Routines
+*******************************************************************************/
+/**
+ * @brief Note: HAL_ETH_MspInit of RTEMS BSP is used.
+ * @param heth: ETH handle
+ * @retval None
+*/
+
+#if NO_SYS == 0
+/**
+ * @brief Ethernet Rx Transfer completed callback
+ * @param heth: ETH handle
+ * @retval None
+ */
+void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
+{
+ sys_sem_signal(&RxPktSemaphore);
+}
+#endif
+
+/*******************************************************************************
+ PHI IO Functions
+*******************************************************************************/
+/**
+ * @brief Initializes the MDIO interface GPIO and clocks.
+ * @param None
+ * @retval 0 if OK, -1 if ERROR
+ */
+int32_t ETH_PHY_IO_Init(void)
+{
+ /* We assume that MDIO GPIO configuration is already done
+ in the ETH_MspInit() else it should be done here
+ */
+
+ /* Configure the MDIO Clock */
+ HAL_ETH_SetMDIOClockRange(&EthHandle);
+
+ return 0;
+}
+
+/**
+ * @brief De-Initializes the MDIO interface .
+ * @param None
+ * @retval 0 if OK, -1 if ERROR
+ */
+int32_t ETH_PHY_IO_DeInit (void)
+{
+ return 0;
+}
+
+/**
+ * @brief Read a PHY register through the MDIO interface.
+ * @param DevAddr: PHY port address
+ * @param RegAddr: PHY register address
+ * @param pRegVal: pointer to hold the register value
+ * @retval 0 if OK -1 if Error
+ */
+int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal)
+{
+ if(HAL_ETH_ReadPHYRegister(&EthHandle, DevAddr, RegAddr, pRegVal) != HAL_OK)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Write a value to a PHY register through the MDIO interface.
+ * @param DevAddr: PHY port address
+ * @param RegAddr: PHY register address
+ * @param RegVal: Value to be written
+ * @retval 0 if OK -1 if Error
+ */
+int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal)
+{
+ if(HAL_ETH_WritePHYRegister(&EthHandle, DevAddr, RegAddr, RegVal) != HAL_OK)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Get the time in millisecons used for internal PHY driver process.
+ * @retval Time value
+ */
+int32_t ETH_PHY_IO_GetTick(void)
+{
+ return HAL_GetTick();
+}
+
+void ethernet_link_check_state(struct netif *netif)
+{
+ ETH_MACConfigTypeDef MACConf;
+ uint32_t PHYLinkState;
+ uint32_t linkchanged = 0, speed = 0, duplex =0;
+
+ PHYLinkState = LAN8742_GetLinkState(&LAN8742);
+
+ if(netif_is_link_up(netif) && (PHYLinkState <= LAN8742_STATUS_LINK_DOWN))
+ {
+ HAL_ETH_Stop(&EthHandle);
+ netif_set_down(netif);
+ netif_set_link_down(netif);
+ }
+ else if(!netif_is_link_up(netif) && (PHYLinkState > LAN8742_STATUS_LINK_DOWN))
+ {
+ switch (PHYLinkState)
+ {
+ case LAN8742_STATUS_100MBITS_FULLDUPLEX:
+ duplex = ETH_FULLDUPLEX_MODE;
+ speed = ETH_SPEED_100M;
+ linkchanged = 1;
+ break;
+ case LAN8742_STATUS_100MBITS_HALFDUPLEX:
+ duplex = ETH_HALFDUPLEX_MODE;
+ speed = ETH_SPEED_100M;
+ linkchanged = 1;
+ break;
+ case LAN8742_STATUS_10MBITS_FULLDUPLEX:
+ duplex = ETH_FULLDUPLEX_MODE;
+ speed = ETH_SPEED_10M;
+ linkchanged = 1;
+ break;
+ case LAN8742_STATUS_10MBITS_HALFDUPLEX:
+ duplex = ETH_HALFDUPLEX_MODE;
+ speed = ETH_SPEED_10M;
+ linkchanged = 1;
+ break;
+ default:
+ break;
+ }
+
+ if(linkchanged)
+ {
+ /* Get MAC Config MAC */
+ HAL_ETH_GetMACConfig(&EthHandle, &MACConf);
+ MACConf.DuplexMode = duplex;
+ MACConf.Speed = speed;
+ HAL_ETH_SetMACConfig(&EthHandle, &MACConf);
+ HAL_ETH_Start(&EthHandle);
+ netif_set_up(netif);
+ netif_set_link_up(netif);
+ }
+ }
+}
+
+#if NO_SYS == 1
+/* Even for NO_SYS == 1 this needs to be implemented */
+uint32_t
+sys_now()
+{
+ /* Forward call to HAL function which already implements returning millisecond ticks */
+ return HAL_GetTick();
+}
+
+#endif /* NO_SYS == 1 */
+
+/* Configure the MPU for the lwIP heap. */
+void mpu_config_tx_buffers(uint32_t base_addr, size_t region_size)
+{
+ MPU_Region_InitTypeDef MPU_InitStruct;
+ uint8_t region_select = determine_mpu_region_size_select(region_size);
+
+ /* Disable the MPU */
+ HAL_MPU_Disable();
+
+ /* Configure the MPU attributes as Normal Non Cacheable
+ for LwIP RAM heap which contains the Tx buffers */
+ MPU_InitStruct.Enable = MPU_REGION_ENABLE;
+ MPU_InitStruct.BaseAddress = base_addr;
+ MPU_InitStruct.Size = region_select;
+ MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
+ MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
+ MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
+ MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
+ MPU_InitStruct.Number = MPU_REGION_NUMBER1;
+ MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
+ MPU_InitStruct.SubRegionDisable = 0x00;
+ MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
+
+ HAL_MPU_ConfigRegion(&MPU_InitStruct);
+
+ SCB_CleanDCache_by_Addr((uint32_t*) base_addr, region_size);
+
+ /* Enable the MPU */
+ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
+
+}
+
+uint8_t determine_mpu_region_size_select(size_t lwip_heap_size)
+{
+ if(lwip_heap_size <= 1024) {
+ return MPU_REGION_SIZE_1KB;
+ }
+ else if(lwip_heap_size <= 2 * 1024) {
+ return MPU_REGION_SIZE_2KB;
+ }
+ else if(lwip_heap_size <= 4 * 1024) {
+ return MPU_REGION_SIZE_4KB;
+ }
+ else if(lwip_heap_size <= 8 * 1024) {
+ return MPU_REGION_SIZE_8KB;
+ }
+ else if(lwip_heap_size <= 16 * 1024) {
+ return MPU_REGION_SIZE_16KB;
+ }
+ else if(lwip_heap_size <= 32 * 1024) {
+ return MPU_REGION_SIZE_32KB;
+ }
+ else if(lwip_heap_size <= 64 * 1024) {
+ return MPU_REGION_SIZE_64KB;
+ }
+ else if(lwip_heap_size <= 128 * 1024) {
+ return MPU_REGION_SIZE_128KB;
+ }
+ else if(lwip_heap_size <= 256 * 1024) {
+ return MPU_REGION_SIZE_256KB;
+ }
+ else if(lwip_heap_size <= 512 * 1024) {
+ return MPU_REGION_SIZE_512KB;
+ }
+ else {
+ /* There is only 1MB RAM available so a MPU protection of 1MB does not really make sense */
+ return MPU_REGION_SIZE_512KB;
+ }
+}
+
+lan8742_Object_t* get_lan_phy_handle() {
+ return &LAN8742;
+}
+
+ETH_HandleTypeDef* get_eth_handle() {
+ return &EthHandle;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/lwip/ports/drivers/stm32h7/include/lwip_port/app_dhcp.h b/lwip/ports/drivers/stm32h7/include/lwip_port/app_dhcp.h
new file mode 100644
index 0000000..ce51a74
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/include/lwip_port/app_dhcp.h
@@ -0,0 +1,38 @@
+#ifndef LWIP_PORTS_DRIVERS_STM32H7_APP_DHCP_H_
+#define LWIP_PORTS_DRIVERS_STM32H7_APP_DHCP_H_
+
+#include <lwipopts.h>
+#include <stdint.h>
+
+#include <lwip/netif.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint8_t get_dhcp_state();
+
+/* DHCP process states */
+#define DHCP_OFF (uint8_t) 0
+#define DHCP_START (uint8_t) 1
+#define DHCP_WAIT_ADDRESS (uint8_t) 2
+#define DHCP_ADDRESS_ASSIGNED (uint8_t) 3
+#define DHCP_TIMEOUT (uint8_t) 4
+#define DHCP_LINK_DOWN (uint8_t) 5
+
+#if NO_SYS == 1
+
+void dhcp_periodic_handle(struct netif *netif);
+
+#else
+
+void rtems_lwip_start_dhcp_thread(uint32_t task_interval_ms,
+ size_t task_stack, uint8_t task_priority);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_PORTS_DRIVERS_STM32H7_APP_DHCP_H_ */
diff --git a/lwip/ports/drivers/stm32h7/include/lwip_port/app_ethernet.h b/lwip/ports/drivers/stm32h7/include/lwip_port/app_ethernet.h
new file mode 100644
index 0000000..b961132
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/include/lwip_port/app_ethernet.h
@@ -0,0 +1,56 @@
+/**
+ ******************************************************************************
+ * @file LwIP/LwIP_HTTP_Server_Netconn_RTOS/Inc/app_ethernet.h
+ * @author MCD Application Team
+ * @brief Header for app_ethernet.c module
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __APP_ETHERNET_H
+#define __APP_ETHERNET_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "lwip/netif.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void ethernet_link_status_updated(struct netif *netif);
+#if LWIP_DHCP
+void DHCP_Thread(void const * argument);
+#endif
+
+#if LWIP_NETIF_LINK_CALLBACK == 1 && NO_SYS == 1
+void ethernet_link_periodic_handle(struct netif *netif);
+#endif
+
+void rtems_lwip_start_link_thread(uint32_t task_interval_ms,
+ size_t task_stack, uint8_t task_priority);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APP_ETHERNET_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/lwip/ports/drivers/stm32h7/include/lwip_port/ethernetif.h b/lwip/ports/drivers/stm32h7/include/lwip_port/ethernetif.h
new file mode 100644
index 0000000..33f2129
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/include/lwip_port/ethernetif.h
@@ -0,0 +1,56 @@
+/**
+ ******************************************************************************
+ * @file LwIP/LwIP_HTTP_Server_Netconn_RTOS/Inc/ethernetif.h
+ * @author MCD Application Team
+ * @brief Header for ethernetif.c module
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+#ifndef __ETHERNETIF_H__
+#define __ETHERNETIF_H__
+
+
+#include "lwip/err.h"
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ETH_RX_BUFFER_SIZE (1536UL)
+
+/* Exported types ------------------------------------------------------------*/
+typedef struct {
+ struct netif* netif;
+ uint32_t task_interval_ms;
+} LwipThreadArgs;
+
+/* Structure that include link thread parameters */
+/* Exported functions ------------------------------------------------------- */
+err_t ethernetif_init(struct netif *netif);
+void ethernetif_input(struct netif *netif);
+void ethernet_link_check_state(struct netif *netif);
+
+/**
+ * This function can be used to protect the TX lwIP buffer region (lwIP Heap).
+ * @param base_addr
+ * @param region_size
+ */
+void mpu_config_tx_buffers(uint32_t base_addr, size_t region_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ETHERNETIF_H__ */
diff --git a/lwip/ports/drivers/stm32h7/lan8742.c b/lwip/ports/drivers/stm32h7/lan8742.c
new file mode 100644
index 0000000..a268393
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/lan8742.c
@@ -0,0 +1,664 @@
+/**
+ ******************************************************************************
+ * @file lan8742.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the LAN742
+ * PHY devices.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "lan8742.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Component
+ * @{
+ */
+
+/** @defgroup LAN8742 LAN8742
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup LAN8742_Private_Defines LAN8742 Private Defines
+ * @{
+ */
+#define LAN8742_SW_RESET_TO ((uint32_t)500U)
+#define LAN8742_INIT_TO ((uint32_t)2000U)
+#define LAN8742_MAX_DEV_ADDR ((uint32_t)31U)
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup LAN8742_Private_Functions LAN8742 Private Functions
+ * @{
+ */
+
+/**
+ * @brief Register IO functions to component object
+ * @param pObj: device object of LAN8742_Object_t.
+ * @param ioctx: holds device IO functions.
+ * @retval LAN8742_STATUS_OK if OK
+ * LAN8742_STATUS_ERROR if missing mandatory function
+ */
+int32_t LAN8742_RegisterBusIO(lan8742_Object_t *pObj, lan8742_IOCtx_t *ioctx)
+{
+ if(!pObj || !ioctx->ReadReg || !ioctx->WriteReg || !ioctx->GetTick)
+ {
+ return LAN8742_STATUS_ERROR;
+ }
+
+ pObj->IO.Init = ioctx->Init;
+ pObj->IO.DeInit = ioctx->DeInit;
+ pObj->IO.ReadReg = ioctx->ReadReg;
+ pObj->IO.WriteReg = ioctx->WriteReg;
+ pObj->IO.GetTick = ioctx->GetTick;
+
+ return LAN8742_STATUS_OK;
+}
+
+/**
+ * @brief Initialize the lan8742 and configure the needed hardware resources
+ * @param pObj: device object LAN8742_Object_t.
+ * @retval LAN8742_STATUS_OK if OK
+ * LAN8742_STATUS_ADDRESS_ERROR if cannot find device address
+ * LAN8742_STATUS_READ_ERROR if connot read register
+ * LAN8742_STATUS_WRITE_ERROR if connot write to register
+ * LAN8742_STATUS_RESET_TIMEOUT if cannot perform a software reset
+ */
+ int32_t LAN8742_Init(lan8742_Object_t *pObj)
+ {
+ uint32_t tickstart = 0, regvalue = 0, addr = 0;
+ int32_t status = LAN8742_STATUS_OK;
+
+ if(pObj->Is_Initialized == 0)
+ {
+ if(pObj->IO.Init != 0)
+ {
+ /* GPIO and Clocks initialization */
+ pObj->IO.Init();
+ }
+
+ /* for later check */
+ pObj->DevAddr = LAN8742_MAX_DEV_ADDR + 1;
+
+ /* Get the device address from special mode register */
+ for(addr = 0; addr <= LAN8742_MAX_DEV_ADDR; addr ++)
+ {
+ if(pObj->IO.ReadReg(addr, LAN8742_SMR, ®value) < 0)
+ {
+ status = LAN8742_STATUS_READ_ERROR;
+ /* Can't read from this device address
+ continue with next address */
+ continue;
+ }
+
+ if((regvalue & LAN8742_SMR_PHY_ADDR) == addr)
+ {
+ pObj->DevAddr = addr;
+ status = LAN8742_STATUS_OK;
+ break;
+ }
+ }
+
+ if(pObj->DevAddr > LAN8742_MAX_DEV_ADDR)
+ {
+ status = LAN8742_STATUS_ADDRESS_ERROR;
+ }
+
+ /* if device address is matched */
+ if(status == LAN8742_STATUS_OK)
+ {
+ /* set a software reset */
+ if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, LAN8742_BCR_SOFT_RESET) >= 0)
+ {
+ /* get software reset status */
+ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, ®value) >= 0)
+ {
+ tickstart = pObj->IO.GetTick();
+
+ /* wait until software reset is done or timeout occured */
+ while(regvalue & LAN8742_BCR_SOFT_RESET)
+ {
+ if((pObj->IO.GetTick() - tickstart) <= LAN8742_SW_RESET_TO)
+ {
+ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, ®value) < 0)
+ {
+ status = LAN8742_STATUS_READ_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ status = LAN8742_STATUS_RESET_TIMEOUT;
+ break;
+ }
+ }
+ }
+ else
+ {
+ status = LAN8742_STATUS_READ_ERROR;
+ }
+ }
+ else
+ {
+ status = LAN8742_STATUS_WRITE_ERROR;
+ }
+ }
+ }
+
+ if(status == LAN8742_STATUS_OK)
+ {
+ tickstart = pObj->IO.GetTick();
+
+ /* Wait for 2s to perform initialization */
+ while((pObj->IO.GetTick() - tickstart) <= LAN8742_INIT_TO)
+ {
+ }
+ pObj->Is_Initialized = 1;
+ }
+
+ return status;
+ }
+
+/**
+ * @brief De-Initialize the lan8742 and it's hardware resources
+ * @param pObj: device object LAN8742_Object_t.
+ * @retval None
+ */
+int32_t LAN8742_DeInit(lan8742_Object_t *pObj)
+{
+ if(pObj->Is_Initialized)
+ {
+ if(pObj->IO.DeInit != 0)
+ {
+ if(pObj->IO.DeInit() < 0)
+ {
+ return LAN8742_STATUS_ERROR;
+ }
+ }
+
+ pObj->Is_Initialized = 0;
+ }
+
+ return LAN8742_STATUS_OK;
+}
+
+/**
+ * @brief Disable the LAN8742 power down mode.
+ * @param pObj: device object LAN8742_Object_t.
+ * @retval LAN8742_STATUS_OK if OK
+ * LAN8742_STATUS_READ_ERROR if connot read register
+ * LAN8742_STATUS_WRITE_ERROR if connot write to register
+ */
+int32_t LAN8742_DisablePowerDownMode(lan8742_Object_t *pObj)
+{
+ uint32_t readval = 0;
+ int32_t status = LAN8742_STATUS_OK;
+
+ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) >= 0)
+ {
+ readval &= ~LAN8742_BCR_POWER_DOWN;
+
+ /* Apply configuration */
+ if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, readval) < 0)
+ {
+ status = LAN8742_STATUS_WRITE_ERROR;
+ }
+ }
+ else
+ {
+ status = LAN8742_STATUS_READ_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Enable the LAN8742 power down mode.
+ * @param pObj: device object LAN8742_Object_t.
+ * @retval LAN8742_STATUS_OK if OK
+ * LAN8742_STATUS_READ_ERROR if connot read register
+ * LAN8742_STATUS_WRITE_ERROR if connot write to register
+ */
+int32_t LAN8742_EnablePowerDownMode(lan8742_Object_t *pObj)
+{
+ uint32_t readval = 0;
+ int32_t status = LAN8742_STATUS_OK;
+
+ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) >= 0)
+ {
+ readval |= LAN8742_BCR_POWER_DOWN;
+
+ /* Apply configuration */
+ if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, readval) < 0)
+ {
+ status = LAN8742_STATUS_WRITE_ERROR;
+ }
+ }
+ else
+ {
+ status = LAN8742_STATUS_READ_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Start the auto negotiation process.
+ * @param pObj: device object LAN8742_Object_t.
+ * @retval LAN8742_STATUS_OK if OK
+ * LAN8742_STATUS_READ_ERROR if connot read register
+ * LAN8742_STATUS_WRITE_ERROR if connot write to register
+ */
+int32_t LAN8742_StartAutoNego(lan8742_Object_t *pObj)
+{
+ uint32_t readval = 0;
+ int32_t status = LAN8742_STATUS_OK;
+
+ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) >= 0)
+ {
+ readval |= LAN8742_BCR_AUTONEGO_EN;
+
+ /* Apply configuration */
+ if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, readval) < 0)
+ {
+ status = LAN8742_STATUS_WRITE_ERROR;
+ }
+ }
+ else
+ {
+ status = LAN8742_STATUS_READ_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Get the link state of LAN8742 device.
+ * @param pObj: Pointer to device object.
+ * @param pLinkState: Pointer to link state
+ * @retval LAN8742_STATUS_LINK_DOWN if link is down
+ * LAN8742_STATUS_AUTONEGO_NOTDONE if Auto nego not completed
+ * LAN8742_STATUS_100MBITS_FULLDUPLEX if 100Mb/s FD
+ * LAN8742_STATUS_100MBITS_HALFDUPLEX if 100Mb/s HD
+ * LAN8742_STATUS_10MBITS_FULLDUPLEX if 10Mb/s FD
+ * LAN8742_STATUS_10MBITS_HALFDUPLEX if 10Mb/s HD
+ * LAN8742_STATUS_READ_ERROR if connot read register
+ * LAN8742_STATUS_WRITE_ERROR if connot write to register
+ */
+int32_t LAN8742_GetLinkState(lan8742_Object_t *pObj)
+{
+ uint32_t readval = 0;
+
+ /* Read Status register */
+ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval) < 0)
+ {
+ return LAN8742_STATUS_READ_ERROR;
+ }
+
+ /* Read Status register again */
+ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval) < 0)
+ {
+ return LAN8742_STATUS_READ_ERROR;
+ }
+
+ if((readval & LAN8742_BSR_LINK_STATUS) == 0)
+ {
+ /* Return Link Down status */
+ return LAN8742_STATUS_LINK_DOWN;
+ }
+
+ /* Check Auto negotiaition */
+ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) < 0)
+ {
+ return LAN8742_STATUS_READ_ERROR;
+ }
+
+ if((readval & LAN8742_BCR_AUTONEGO_EN) != LAN8742_BCR_AUTONEGO_EN)
+ {
+ if(((readval & LAN8742_BCR_SPEED_SELECT) == LAN8742_BCR_SPEED_SELECT) && ((readval & LAN8742_BCR_DUPLEX_MODE) == LAN8742_BCR_DUPLEX_MODE))
+ {
+ return LAN8742_STATUS_100MBITS_FULLDUPLEX;
+ }
+ else if ((readval & LAN8742_BCR_SPEED_SELECT) == LAN8742_BCR_SPEED_SELECT)
+ {
+ return LAN8742_STATUS_100MBITS_HALFDUPLEX;
+ }
+ else if ((readval & LAN8742_BCR_DUPLEX_MODE) == LAN8742_BCR_DUPLEX_MODE)
+ {
+ return LAN8742_STATUS_10MBITS_FULLDUPLEX;
+ }
+ else
+ {
+ return LAN8742_STATUS_10MBITS_HALFDUPLEX;
+ }
+ }
+ else /* Auto Nego enabled */
+ {
+ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_PHYSCSR, &readval) < 0)
+ {
+ return LAN8742_STATUS_READ_ERROR;
+ }
+
+ /* Check if auto nego not done */
+ if((readval & LAN8742_PHYSCSR_AUTONEGO_DONE) == 0)
+ {
+ return LAN8742_STATUS_AUTONEGO_NOTDONE;
+ }
+
+ if((readval & LAN8742_PHYSCSR_HCDSPEEDMASK) == LAN8742_PHYSCSR_100BTX_FD)
+ {
+ return LAN8742_STATUS_100MBITS_FULLDUPLEX;
+ }
+ else if ((readval & LAN8742_PHYSCSR_HCDSPEEDMASK) == LAN8742_PHYSCSR_100BTX_HD)
+ {
+ return LAN8742_STATUS_100MBITS_HALFDUPLEX;
+ }
+ else if ((readval & LAN8742_PHYSCSR_HCDSPEEDMASK) == LAN8742_PHYSCSR_10BT_FD)
+ {
+ return LAN8742_STATUS_10MBITS_FULLDUPLEX;
+ }
+ else
+ {
+ return LAN8742_STATUS_10MBITS_HALFDUPLEX;
+ }
+ }
+}
+
+/**
+ * @brief Set the link state of LAN8742 device.
+ * @param pObj: Pointer to device object.
+ * @param pLinkState: link state can be one of the following
+ * LAN8742_STATUS_100MBITS_FULLDUPLEX if 100Mb/s FD
+ * LAN8742_STATUS_100MBITS_HALFDUPLEX if 100Mb/s HD
+ * LAN8742_STATUS_10MBITS_FULLDUPLEX if 10Mb/s FD
+ * LAN8742_STATUS_10MBITS_HALFDUPLEX if 10Mb/s HD
+ * @retval LAN8742_STATUS_OK if OK
+ * LAN8742_STATUS_ERROR if parameter error
+ * LAN8742_STATUS_READ_ERROR if connot read register
+ * LAN8742_STATUS_WRITE_ERROR if connot write to register
+ */
+int32_t LAN8742_SetLinkState(lan8742_Object_t *pObj, uint32_t LinkState)
+{
+ uint32_t bcrvalue = 0;
+ int32_t status = LAN8742_STATUS_OK;
+
+ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &bcrvalue) >= 0)
+ {
+ /* Disable link config (Auto nego, speed and duplex) */
+ bcrvalue &= ~(LAN8742_BCR_AUTONEGO_EN | LAN8742_BCR_SPEED_SELECT | LAN8742_BCR_DUPLEX_MODE);
+
+ if(LinkState == LAN8742_STATUS_100MBITS_FULLDUPLEX)
+ {
+ bcrvalue |= (LAN8742_BCR_SPEED_SELECT | LAN8742_BCR_DUPLEX_MODE);
+ }
+ else if (LinkState == LAN8742_STATUS_100MBITS_HALFDUPLEX)
+ {
+ bcrvalue |= LAN8742_BCR_SPEED_SELECT;
+ }
+ else if (LinkState == LAN8742_STATUS_10MBITS_FULLDUPLEX)
+ {
+ bcrvalue |= LAN8742_BCR_DUPLEX_MODE;
+ }
+ else
+ {
+ /* Wrong link status parameter */
+ status = LAN8742_STATUS_ERROR;
+ }
+ }
+ else
+ {
+ status = LAN8742_STATUS_READ_ERROR;
+ }
+
+ if(status == LAN8742_STATUS_OK)
+ {
+ /* Apply configuration */
+ if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, bcrvalue) < 0)
+ {
+ status = LAN8742_STATUS_WRITE_ERROR;
+ }
+ }
+
+ return status;
+}
+
+/**
+ * @brief Enable loopback mode.
+ * @param pObj: Pointer to device object.
+ * @retval LAN8742_STATUS_OK if OK
+ * LAN8742_STATUS_READ_ERROR if connot read register
+ * LAN8742_STATUS_WRITE_ERROR if connot write to register
+ */
+int32_t LAN8742_EnableLoopbackMode(lan8742_Object_t *pObj)
+{
+ uint32_t readval = 0;
+ int32_t status = LAN8742_STATUS_OK;
+
+ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) >= 0)
+ {
+ readval |= LAN8742_BCR_LOOPBACK;
+
+ /* Apply configuration */
+ if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, readval) < 0)
+ {
+ status = LAN8742_STATUS_WRITE_ERROR;
+ }
+ }
+ else
+ {
+ status = LAN8742_STATUS_READ_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Disable loopback mode.
+ * @param pObj: Pointer to device object.
+ * @retval LAN8742_STATUS_OK if OK
+ * LAN8742_STATUS_READ_ERROR if connot read register
+ * LAN8742_STATUS_WRITE_ERROR if connot write to register
+ */
+int32_t LAN8742_DisableLoopbackMode(lan8742_Object_t *pObj)
+{
+ uint32_t readval = 0;
+ int32_t status = LAN8742_STATUS_OK;
+
+ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) >= 0)
+ {
+ readval &= ~LAN8742_BCR_LOOPBACK;
+
+ /* Apply configuration */
+ if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, readval) < 0)
+ {
+ status = LAN8742_STATUS_WRITE_ERROR;
+ }
+ }
+ else
+ {
+ status = LAN8742_STATUS_READ_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Enable IT source.
+ * @param pObj: Pointer to device object.
+ * @param Interrupt: IT source to be enabled
+ * should be a value or a combination of the following:
+ * LAN8742_WOL_IT
+ * LAN8742_ENERGYON_IT
+ * LAN8742_AUTONEGO_COMPLETE_IT
+ * LAN8742_REMOTE_FAULT_IT
+ * LAN8742_LINK_DOWN_IT
+ * LAN8742_AUTONEGO_LP_ACK_IT
+ * LAN8742_PARALLEL_DETECTION_FAULT_IT
+ * LAN8742_AUTONEGO_PAGE_RECEIVED_IT
+ * @retval LAN8742_STATUS_OK if OK
+ * LAN8742_STATUS_READ_ERROR if connot read register
+ * LAN8742_STATUS_WRITE_ERROR if connot write to register
+ */
+int32_t LAN8742_EnableIT(lan8742_Object_t *pObj, uint32_t Interrupt)
+{
+ uint32_t readval = 0;
+ int32_t status = LAN8742_STATUS_OK;
+
+ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_IMR, &readval) >= 0)
+ {
+ readval |= Interrupt;
+
+ /* Apply configuration */
+ if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_IMR, readval) < 0)
+ {
+ status = LAN8742_STATUS_WRITE_ERROR;
+ }
+ }
+ else
+ {
+ status = LAN8742_STATUS_READ_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Disable IT source.
+ * @param pObj: Pointer to device object.
+ * @param Interrupt: IT source to be disabled
+ * should be a value or a combination of the following:
+ * LAN8742_WOL_IT
+ * LAN8742_ENERGYON_IT
+ * LAN8742_AUTONEGO_COMPLETE_IT
+ * LAN8742_REMOTE_FAULT_IT
+ * LAN8742_LINK_DOWN_IT
+ * LAN8742_AUTONEGO_LP_ACK_IT
+ * LAN8742_PARALLEL_DETECTION_FAULT_IT
+ * LAN8742_AUTONEGO_PAGE_RECEIVED_IT
+ * @retval LAN8742_STATUS_OK if OK
+ * LAN8742_STATUS_READ_ERROR if connot read register
+ * LAN8742_STATUS_WRITE_ERROR if connot write to register
+ */
+int32_t LAN8742_DisableIT(lan8742_Object_t *pObj, uint32_t Interrupt)
+{
+ uint32_t readval = 0;
+ int32_t status = LAN8742_STATUS_OK;
+
+ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_IMR, &readval) >= 0)
+ {
+ readval &= ~Interrupt;
+
+ /* Apply configuration */
+ if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_IMR, readval) < 0)
+ {
+ status = LAN8742_STATUS_WRITE_ERROR;
+ }
+ }
+ else
+ {
+ status = LAN8742_STATUS_READ_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Clear IT flag.
+ * @param pObj: Pointer to device object.
+ * @param Interrupt: IT flag to be cleared
+ * should be a value or a combination of the following:
+ * LAN8742_WOL_IT
+ * LAN8742_ENERGYON_IT
+ * LAN8742_AUTONEGO_COMPLETE_IT
+ * LAN8742_REMOTE_FAULT_IT
+ * LAN8742_LINK_DOWN_IT
+ * LAN8742_AUTONEGO_LP_ACK_IT
+ * LAN8742_PARALLEL_DETECTION_FAULT_IT
+ * LAN8742_AUTONEGO_PAGE_RECEIVED_IT
+ * @retval LAN8742_STATUS_OK if OK
+ * LAN8742_STATUS_READ_ERROR if connot read register
+ */
+int32_t LAN8742_ClearIT(lan8742_Object_t *pObj, uint32_t Interrupt)
+{
+ uint32_t readval = 0;
+ int32_t status = LAN8742_STATUS_OK;
+
+ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_ISFR, &readval) < 0)
+ {
+ status = LAN8742_STATUS_READ_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Get IT Flag status.
+ * @param pObj: Pointer to device object.
+ * @param Interrupt: IT Flag to be checked,
+ * should be a value or a combination of the following:
+ * LAN8742_WOL_IT
+ * LAN8742_ENERGYON_IT
+ * LAN8742_AUTONEGO_COMPLETE_IT
+ * LAN8742_REMOTE_FAULT_IT
+ * LAN8742_LINK_DOWN_IT
+ * LAN8742_AUTONEGO_LP_ACK_IT
+ * LAN8742_PARALLEL_DETECTION_FAULT_IT
+ * LAN8742_AUTONEGO_PAGE_RECEIVED_IT
+ * @retval 1 IT flag is SET
+ * 0 IT flag is RESET
+ * LAN8742_STATUS_READ_ERROR if connot read register
+ */
+int32_t LAN8742_GetITStatus(lan8742_Object_t *pObj, uint32_t Interrupt)
+{
+ uint32_t readval = 0;
+ int32_t status = 0;
+
+ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_ISFR, &readval) >= 0)
+ {
+ status = ((readval & Interrupt) == Interrupt);
+ }
+ else
+ {
+ status = LAN8742_STATUS_READ_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/lwip/ports/drivers/stm32h7/lan8742.h b/lwip/ports/drivers/stm32h7/lan8742.h
new file mode 100644
index 0000000..c1620dd
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/lan8742.h
@@ -0,0 +1,448 @@
+/**
+ ******************************************************************************
+ * @file lan8742.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for the
+ * lan8742.c PHY driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef LAN8742_H
+#define LAN8742_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Component
+ * @{
+ */
+
+/** @defgroup LAN8742
+ * @{
+ */
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup LAN8742_Exported_Constants LAN8742 Exported Constants
+ * @{
+ */
+
+/** @defgroup LAN8742_Registers_Mapping LAN8742 Registers Mapping
+ * @{
+ */
+#define LAN8742_BCR ((uint16_t)0x0000U)
+#define LAN8742_BSR ((uint16_t)0x0001U)
+#define LAN8742_PHYI1R ((uint16_t)0x0002U)
+#define LAN8742_PHYI2R ((uint16_t)0x0003U)
+#define LAN8742_ANAR ((uint16_t)0x0004U)
+#define LAN8742_ANLPAR ((uint16_t)0x0005U)
+#define LAN8742_ANER ((uint16_t)0x0006U)
+#define LAN8742_ANNPTR ((uint16_t)0x0007U)
+#define LAN8742_ANNPRR ((uint16_t)0x0008U)
+#define LAN8742_MMDACR ((uint16_t)0x000DU)
+#define LAN8742_MMDAADR ((uint16_t)0x000EU)
+#define LAN8742_ENCTR ((uint16_t)0x0010U)
+#define LAN8742_MCSR ((uint16_t)0x0011U)
+#define LAN8742_SMR ((uint16_t)0x0012U)
+#define LAN8742_TPDCR ((uint16_t)0x0018U)
+#define LAN8742_TCSR ((uint16_t)0x0019U)
+#define LAN8742_SECR ((uint16_t)0x001AU)
+#define LAN8742_SCSIR ((uint16_t)0x001BU)
+#define LAN8742_CLR ((uint16_t)0x001CU)
+#define LAN8742_ISFR ((uint16_t)0x001DU)
+#define LAN8742_IMR ((uint16_t)0x001EU)
+#define LAN8742_PHYSCSR ((uint16_t)0x001FU)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_BCR_Bit_Definition LAN8742 BCR Bit Definition
+ * @{
+ */
+#define LAN8742_BCR_SOFT_RESET ((uint16_t)0x8000U)
+#define LAN8742_BCR_LOOPBACK ((uint16_t)0x4000U)
+#define LAN8742_BCR_SPEED_SELECT ((uint16_t)0x2000U)
+#define LAN8742_BCR_AUTONEGO_EN ((uint16_t)0x1000U)
+#define LAN8742_BCR_POWER_DOWN ((uint16_t)0x0800U)
+#define LAN8742_BCR_ISOLATE ((uint16_t)0x0400U)
+#define LAN8742_BCR_RESTART_AUTONEGO ((uint16_t)0x0200U)
+#define LAN8742_BCR_DUPLEX_MODE ((uint16_t)0x0100U)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_BSR_Bit_Definition LAN8742 BSR Bit Definition
+ * @{
+ */
+#define LAN8742_BSR_100BASE_T4 ((uint16_t)0x8000U)
+#define LAN8742_BSR_100BASE_TX_FD ((uint16_t)0x4000U)
+#define LAN8742_BSR_100BASE_TX_HD ((uint16_t)0x2000U)
+#define LAN8742_BSR_10BASE_T_FD ((uint16_t)0x1000U)
+#define LAN8742_BSR_10BASE_T_HD ((uint16_t)0x0800U)
+#define LAN8742_BSR_100BASE_T2_FD ((uint16_t)0x0400U)
+#define LAN8742_BSR_100BASE_T2_HD ((uint16_t)0x0200U)
+#define LAN8742_BSR_EXTENDED_STATUS ((uint16_t)0x0100U)
+#define LAN8742_BSR_AUTONEGO_CPLT ((uint16_t)0x0020U)
+#define LAN8742_BSR_REMOTE_FAULT ((uint16_t)0x0010U)
+#define LAN8742_BSR_AUTONEGO_ABILITY ((uint16_t)0x0008U)
+#define LAN8742_BSR_LINK_STATUS ((uint16_t)0x0004U)
+#define LAN8742_BSR_JABBER_DETECT ((uint16_t)0x0002U)
+#define LAN8742_BSR_EXTENDED_CAP ((uint16_t)0x0001U)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_PHYI1R_Bit_Definition LAN8742 PHYI1R Bit Definition
+ * @{
+ */
+#define LAN8742_PHYI1R_OUI_3_18 ((uint16_t)0xFFFFU)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_PHYI2R_Bit_Definition LAN8742 PHYI2R Bit Definition
+ * @{
+ */
+#define LAN8742_PHYI2R_OUI_19_24 ((uint16_t)0xFC00U)
+#define LAN8742_PHYI2R_MODEL_NBR ((uint16_t)0x03F0U)
+#define LAN8742_PHYI2R_REVISION_NBR ((uint16_t)0x000FU)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_ANAR_Bit_Definition LAN8742 ANAR Bit Definition
+ * @{
+ */
+#define LAN8742_ANAR_NEXT_PAGE ((uint16_t)0x8000U)
+#define LAN8742_ANAR_REMOTE_FAULT ((uint16_t)0x2000U)
+#define LAN8742_ANAR_PAUSE_OPERATION ((uint16_t)0x0C00U)
+#define LAN8742_ANAR_PO_NOPAUSE ((uint16_t)0x0000U)
+#define LAN8742_ANAR_PO_SYMMETRIC_PAUSE ((uint16_t)0x0400U)
+#define LAN8742_ANAR_PO_ASYMMETRIC_PAUSE ((uint16_t)0x0800U)
+#define LAN8742_ANAR_PO_ADVERTISE_SUPPORT ((uint16_t)0x0C00U)
+#define LAN8742_ANAR_100BASE_TX_FD ((uint16_t)0x0100U)
+#define LAN8742_ANAR_100BASE_TX ((uint16_t)0x0080U)
+#define LAN8742_ANAR_10BASE_T_FD ((uint16_t)0x0040U)
+#define LAN8742_ANAR_10BASE_T ((uint16_t)0x0020U)
+#define LAN8742_ANAR_SELECTOR_FIELD ((uint16_t)0x000FU)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_ANLPAR_Bit_Definition LAN8742 ANLPAR Bit Definition
+ * @{
+ */
+#define LAN8742_ANLPAR_NEXT_PAGE ((uint16_t)0x8000U)
+#define LAN8742_ANLPAR_REMOTE_FAULT ((uint16_t)0x2000U)
+#define LAN8742_ANLPAR_PAUSE_OPERATION ((uint16_t)0x0C00U)
+#define LAN8742_ANLPAR_PO_NOPAUSE ((uint16_t)0x0000U)
+#define LAN8742_ANLPAR_PO_SYMMETRIC_PAUSE ((uint16_t)0x0400U)
+#define LAN8742_ANLPAR_PO_ASYMMETRIC_PAUSE ((uint16_t)0x0800U)
+#define LAN8742_ANLPAR_PO_ADVERTISE_SUPPORT ((uint16_t)0x0C00U)
+#define LAN8742_ANLPAR_100BASE_TX_FD ((uint16_t)0x0100U)
+#define LAN8742_ANLPAR_100BASE_TX ((uint16_t)0x0080U)
+#define LAN8742_ANLPAR_10BASE_T_FD ((uint16_t)0x0040U)
+#define LAN8742_ANLPAR_10BASE_T ((uint16_t)0x0020U)
+#define LAN8742_ANLPAR_SELECTOR_FIELD ((uint16_t)0x000FU)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_ANER_Bit_Definition LAN8742 ANER Bit Definition
+ * @{
+ */
+#define LAN8742_ANER_RX_NP_LOCATION_ABLE ((uint16_t)0x0040U)
+#define LAN8742_ANER_RX_NP_STORAGE_LOCATION ((uint16_t)0x0020U)
+#define LAN8742_ANER_PARALLEL_DETECT_FAULT ((uint16_t)0x0010U)
+#define LAN8742_ANER_LP_NP_ABLE ((uint16_t)0x0008U)
+#define LAN8742_ANER_NP_ABLE ((uint16_t)0x0004U)
+#define LAN8742_ANER_PAGE_RECEIVED ((uint16_t)0x0002U)
+#define LAN8742_ANER_LP_AUTONEG_ABLE ((uint16_t)0x0001U)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_ANNPTR_Bit_Definition LAN8742 ANNPTR Bit Definition
+ * @{
+ */
+#define LAN8742_ANNPTR_NEXT_PAGE ((uint16_t)0x8000U)
+#define LAN8742_ANNPTR_MESSAGE_PAGE ((uint16_t)0x2000U)
+#define LAN8742_ANNPTR_ACK2 ((uint16_t)0x1000U)
+#define LAN8742_ANNPTR_TOGGLE ((uint16_t)0x0800U)
+#define LAN8742_ANNPTR_MESSAGGE_CODE ((uint16_t)0x07FFU)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_ANNPRR_Bit_Definition LAN8742 ANNPRR Bit Definition
+ * @{
+ */
+#define LAN8742_ANNPTR_NEXT_PAGE ((uint16_t)0x8000U)
+#define LAN8742_ANNPRR_ACK ((uint16_t)0x4000U)
+#define LAN8742_ANNPRR_MESSAGE_PAGE ((uint16_t)0x2000U)
+#define LAN8742_ANNPRR_ACK2 ((uint16_t)0x1000U)
+#define LAN8742_ANNPRR_TOGGLE ((uint16_t)0x0800U)
+#define LAN8742_ANNPRR_MESSAGGE_CODE ((uint16_t)0x07FFU)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_MMDACR_Bit_Definition LAN8742 MMDACR Bit Definition
+ * @{
+ */
+#define LAN8742_MMDACR_MMD_FUNCTION ((uint16_t)0xC000U)
+#define LAN8742_MMDACR_MMD_FUNCTION_ADDR ((uint16_t)0x0000U)
+#define LAN8742_MMDACR_MMD_FUNCTION_DATA ((uint16_t)0x4000U)
+#define LAN8742_MMDACR_MMD_DEV_ADDR ((uint16_t)0x001FU)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_ENCTR_Bit_Definition LAN8742 ENCTR Bit Definition
+ * @{
+ */
+#define LAN8742_ENCTR_TX_ENABLE ((uint16_t)0x8000U)
+#define LAN8742_ENCTR_TX_TIMER ((uint16_t)0x6000U)
+#define LAN8742_ENCTR_TX_TIMER_1S ((uint16_t)0x0000U)
+#define LAN8742_ENCTR_TX_TIMER_768MS ((uint16_t)0x2000U)
+#define LAN8742_ENCTR_TX_TIMER_512MS ((uint16_t)0x4000U)
+#define LAN8742_ENCTR_TX_TIMER_265MS ((uint16_t)0x6000U)
+#define LAN8742_ENCTR_RX_ENABLE ((uint16_t)0x1000U)
+#define LAN8742_ENCTR_RX_MAX_INTERVAL ((uint16_t)0x0C00U)
+#define LAN8742_ENCTR_RX_MAX_INTERVAL_64MS ((uint16_t)0x0000U)
+#define LAN8742_ENCTR_RX_MAX_INTERVAL_256MS ((uint16_t)0x0400U)
+#define LAN8742_ENCTR_RX_MAX_INTERVAL_512MS ((uint16_t)0x0800U)
+#define LAN8742_ENCTR_RX_MAX_INTERVAL_1S ((uint16_t)0x0C00U)
+#define LAN8742_ENCTR_EX_CROSS_OVER ((uint16_t)0x0002U)
+#define LAN8742_ENCTR_EX_MANUAL_CROSS_OVER ((uint16_t)0x0001U)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_MCSR_Bit_Definition LAN8742 MCSR Bit Definition
+ * @{
+ */
+#define LAN8742_MCSR_EDPWRDOWN ((uint16_t)0x2000U)
+#define LAN8742_MCSR_FARLOOPBACK ((uint16_t)0x0200U)
+#define LAN8742_MCSR_ALTINT ((uint16_t)0x0040U)
+#define LAN8742_MCSR_ENERGYON ((uint16_t)0x0002U)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_SMR_Bit_Definition LAN8742 SMR Bit Definition
+ * @{
+ */
+#define LAN8742_SMR_MODE ((uint16_t)0x00E0U)
+#define LAN8742_SMR_PHY_ADDR ((uint16_t)0x001FU)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_TPDCR_Bit_Definition LAN8742 TPDCR Bit Definition
+ * @{
+ */
+#define LAN8742_TPDCR_DELAY_IN ((uint16_t)0x8000U)
+#define LAN8742_TPDCR_LINE_BREAK_COUNTER ((uint16_t)0x7000U)
+#define LAN8742_TPDCR_PATTERN_HIGH ((uint16_t)0x0FC0U)
+#define LAN8742_TPDCR_PATTERN_LOW ((uint16_t)0x003FU)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_TCSR_Bit_Definition LAN8742 TCSR Bit Definition
+ * @{
+ */
+#define LAN8742_TCSR_TDR_ENABLE ((uint16_t)0x8000U)
+#define LAN8742_TCSR_TDR_AD_FILTER_ENABLE ((uint16_t)0x4000U)
+#define LAN8742_TCSR_TDR_CH_CABLE_TYPE ((uint16_t)0x0600U)
+#define LAN8742_TCSR_TDR_CH_CABLE_DEFAULT ((uint16_t)0x0000U)
+#define LAN8742_TCSR_TDR_CH_CABLE_SHORTED ((uint16_t)0x0200U)
+#define LAN8742_TCSR_TDR_CH_CABLE_OPEN ((uint16_t)0x0400U)
+#define LAN8742_TCSR_TDR_CH_CABLE_MATCH ((uint16_t)0x0600U)
+#define LAN8742_TCSR_TDR_CH_STATUS ((uint16_t)0x0100U)
+#define LAN8742_TCSR_TDR_CH_LENGTH ((uint16_t)0x00FFU)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_SCSIR_Bit_Definition LAN8742 SCSIR Bit Definition
+ * @{
+ */
+#define LAN8742_SCSIR_AUTO_MDIX_ENABLE ((uint16_t)0x8000U)
+#define LAN8742_SCSIR_CHANNEL_SELECT ((uint16_t)0x2000U)
+#define LAN8742_SCSIR_SQE_DISABLE ((uint16_t)0x0800U)
+#define LAN8742_SCSIR_XPOLALITY ((uint16_t)0x0010U)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_CLR_Bit_Definition LAN8742 CLR Bit Definition
+ * @{
+ */
+#define LAN8742_CLR_CABLE_LENGTH ((uint16_t)0xF000U)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_IMR_ISFR_Bit_Definition LAN8742 IMR ISFR Bit Definition
+ * @{
+ */
+#define LAN8742_INT_8 ((uint16_t)0x0100U)
+#define LAN8742_INT_7 ((uint16_t)0x0080U)
+#define LAN8742_INT_6 ((uint16_t)0x0040U)
+#define LAN8742_INT_5 ((uint16_t)0x0020U)
+#define LAN8742_INT_4 ((uint16_t)0x0010U)
+#define LAN8742_INT_3 ((uint16_t)0x0008U)
+#define LAN8742_INT_2 ((uint16_t)0x0004U)
+#define LAN8742_INT_1 ((uint16_t)0x0002U)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_PHYSCSR_Bit_Definition LAN8742 PHYSCSR Bit Definition
+ * @{
+ */
+#define LAN8742_PHYSCSR_AUTONEGO_DONE ((uint16_t)0x1000U)
+#define LAN8742_PHYSCSR_HCDSPEEDMASK ((uint16_t)0x001CU)
+#define LAN8742_PHYSCSR_10BT_HD ((uint16_t)0x0004U)
+#define LAN8742_PHYSCSR_10BT_FD ((uint16_t)0x0014U)
+#define LAN8742_PHYSCSR_100BTX_HD ((uint16_t)0x0008U)
+#define LAN8742_PHYSCSR_100BTX_FD ((uint16_t)0x0018U)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_Status LAN8742 Status
+ * @{
+ */
+
+#define LAN8742_STATUS_READ_ERROR ((int32_t)-5)
+#define LAN8742_STATUS_WRITE_ERROR ((int32_t)-4)
+#define LAN8742_STATUS_ADDRESS_ERROR ((int32_t)-3)
+#define LAN8742_STATUS_RESET_TIMEOUT ((int32_t)-2)
+#define LAN8742_STATUS_ERROR ((int32_t)-1)
+#define LAN8742_STATUS_OK ((int32_t) 0)
+#define LAN8742_STATUS_LINK_DOWN ((int32_t) 1)
+#define LAN8742_STATUS_100MBITS_FULLDUPLEX ((int32_t) 2)
+#define LAN8742_STATUS_100MBITS_HALFDUPLEX ((int32_t) 3)
+#define LAN8742_STATUS_10MBITS_FULLDUPLEX ((int32_t) 4)
+#define LAN8742_STATUS_10MBITS_HALFDUPLEX ((int32_t) 5)
+#define LAN8742_STATUS_AUTONEGO_NOTDONE ((int32_t) 6)
+/**
+ * @}
+ */
+
+/** @defgroup LAN8742_IT_Flags LAN8742 IT Flags
+ * @{
+ */
+#define LAN8742_WOL_IT LAN8742_INT_8
+#define LAN8742_ENERGYON_IT LAN8742_INT_7
+#define LAN8742_AUTONEGO_COMPLETE_IT LAN8742_INT_6
+#define LAN8742_REMOTE_FAULT_IT LAN8742_INT_5
+#define LAN8742_LINK_DOWN_IT LAN8742_INT_4
+#define LAN8742_AUTONEGO_LP_ACK_IT LAN8742_INT_3
+#define LAN8742_PARALLEL_DETECTION_FAULT_IT LAN8742_INT_2
+#define LAN8742_AUTONEGO_PAGE_RECEIVED_IT LAN8742_INT_1
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup LAN8742_Exported_Types LAN8742 Exported Types
+ * @{
+ */
+typedef int32_t (*lan8742_Init_Func) (void);
+typedef int32_t (*lan8742_DeInit_Func) (void);
+typedef int32_t (*lan8742_ReadReg_Func) (uint32_t, uint32_t, uint32_t *);
+typedef int32_t (*lan8742_WriteReg_Func) (uint32_t, uint32_t, uint32_t);
+typedef int32_t (*lan8742_GetTick_Func) (void);
+
+typedef struct
+{
+ lan8742_Init_Func Init;
+ lan8742_DeInit_Func DeInit;
+ lan8742_WriteReg_Func WriteReg;
+ lan8742_ReadReg_Func ReadReg;
+ lan8742_GetTick_Func GetTick;
+} lan8742_IOCtx_t;
+
+
+typedef struct
+{
+ uint32_t DevAddr;
+ uint32_t Is_Initialized;
+ lan8742_IOCtx_t IO;
+ void *pData;
+}lan8742_Object_t;
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup LAN8742_Exported_Functions LAN8742 Exported Functions
+ * @{
+ */
+int32_t LAN8742_RegisterBusIO(lan8742_Object_t *pObj, lan8742_IOCtx_t *ioctx);
+int32_t LAN8742_Init(lan8742_Object_t *pObj);
+int32_t LAN8742_DeInit(lan8742_Object_t *pObj);
+int32_t LAN8742_DisablePowerDownMode(lan8742_Object_t *pObj);
+int32_t LAN8742_EnablePowerDownMode(lan8742_Object_t *pObj);
+int32_t LAN8742_StartAutoNego(lan8742_Object_t *pObj);
+int32_t LAN8742_GetLinkState(lan8742_Object_t *pObj);
+int32_t LAN8742_SetLinkState(lan8742_Object_t *pObj, uint32_t LinkState);
+int32_t LAN8742_EnableLoopbackMode(lan8742_Object_t *pObj);
+int32_t LAN8742_DisableLoopbackMode(lan8742_Object_t *pObj);
+int32_t LAN8742_EnableIT(lan8742_Object_t *pObj, uint32_t Interrupt);
+int32_t LAN8742_DisableIT(lan8742_Object_t *pObj, uint32_t Interrupt);
+int32_t LAN8742_ClearIT(lan8742_Object_t *pObj, uint32_t Interrupt);
+int32_t LAN8742_GetITStatus(lan8742_Object_t *pObj, uint32_t Interrupt);
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* LAN8742_H */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/lwip/ports/drivers/stm32h7/template/lwipopts_template.h b/lwip/ports/drivers/stm32h7/template/lwipopts_template.h
new file mode 100644
index 0000000..756060c
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/template/lwipopts_template.h
@@ -0,0 +1,289 @@
+/**
+ ******************************************************************************
+ * @file LwIP/LwIP_HTTP_Server_Netconn_RTOS/Inc/lwipopts.h
+ * @author MCD Application Team
+ * @brief lwIP Options Configuration.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
+ * All rights reserved.</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted, provided that the following conditions are met:
+ *
+ * 1. Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of other
+ * contributors to this software may be used to endorse or promote products
+ * derived from this software without specific written permission.
+ * 4. This software, including modifications and/or derivative works of this
+ * software, must execute solely and exclusively on microcontroller or
+ * microprocessor devices manufactured by or for STMicroelectronics.
+ * 5. Redistribution and use of this software other than as permitted under
+ * this license is void and will automatically terminate your rights under
+ * this license.
+ *
+ * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
+ * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
+ * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+#ifndef __LWIPOPTS_H__
+#define __LWIPOPTS_H__
+
+#include "conf_app.h"
+#include "bsp.h"
+
+/**
+ * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
+ * critical regions during buffer allocation, deallocation and memory
+ * allocation and deallocation.
+ */
+#define SYS_LIGHTWEIGHT_PROT 0
+
+/**
+ * NO_SYS==1: Provides VERY minimal functionality. Otherwise,
+ * use lwIP facilities.
+ */
+#define NO_SYS 1
+
+#define LWIP_NETIF_API 0
+
+/* ---------- Memory options ---------- */
+/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
+ lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
+ byte alignment -> define MEM_ALIGNMENT to 2. */
+#define MEM_ALIGNMENT 4
+
+/* MEM_SIZE: the size of the heap memory. If the application will send
+a lot of data that needs to be copied, this should be set high. */
+#define MEM_SIZE (8*1024)
+
+/* Relocate the LwIP RAM heap pointer. Place in SRAM3 */
+#define LWIP_RAM_HEAP_POINTER (0x30040000)
+
+/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
+ sends a lot of data out of ROM (or other static memory), this
+ should be set high. */
+#define MEMP_NUM_PBUF 10
+/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
+ per active UDP "connection". */
+#define MEMP_NUM_UDP_PCB 6
+/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
+ connections. */
+#define MEMP_NUM_TCP_PCB 10
+/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
+ connections. */
+#define MEMP_NUM_TCP_PCB_LISTEN 5
+/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
+ segments. */
+#define MEMP_NUM_TCP_SEG 8
+/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
+ timeouts. */
+#define MEMP_NUM_SYS_TIMEOUT 10
+
+
+/* ---------- Pbuf options ---------- */
+/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool.
+ @ note: used to allocate Tx pbufs only */
+#define PBUF_POOL_SIZE 4
+
+/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
+#define PBUF_POOL_BUFSIZE 1528
+
+/* LWIP_SUPPORT_CUSTOM_PBUF == 1: to pass directly MAC Rx buffers to the stack
+ no copy is needed */
+#define LWIP_SUPPORT_CUSTOM_PBUF 1
+
+/* ---------- IPv4 options ---------- */
+#define LWIP_IPV4 1
+
+/* ---------- TCP options ---------- */
+#define LWIP_TCP 1
+#define TCP_TTL 255
+
+/* Controls if TCP should queue segments that arrive out of
+ order. Define to 0 if your device is low on memory. */
+#define TCP_QUEUE_OOSEQ 0
+
+/* TCP Maximum segment size. */
+#define TCP_MSS (1500 - 40) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */
+
+/* TCP sender buffer space (bytes). */
+#define TCP_SND_BUF (4*TCP_MSS)
+
+/* TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least
+ as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. */
+
+#define TCP_SND_QUEUELEN (2* TCP_SND_BUF/TCP_MSS)
+
+/* TCP receive window. */
+#define TCP_WND (2*TCP_MSS)
+
+/* ---------- ICMP options ---------- */
+#define LWIP_ICMP 1
+
+/* ---------- DHCP options ---------- */
+#define LWIP_DHCP 1
+
+/* ---------- UDP options ---------- */
+#define LWIP_UDP 1
+#define UDP_TTL 255
+
+/* ---------- link callback options ---------- */
+/* LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface
+ * whenever the link changes (i.e., link down)
+ */
+#define LWIP_NETIF_LINK_CALLBACK 1
+
+
+/* Static IP ADDRESS */
+#define IP_ADDR0 169
+#define IP_ADDR1 254
+#define IP_ADDR2 1
+#define IP_ADDR3 38
+
+/* NETMASK */
+#define NETMASK_ADDR0 255
+#define NETMASK_ADDR1 255
+#define NETMASK_ADDR2 0
+#define NETMASK_ADDR3 0
+
+/* Gateway Address */
+#define GW_ADDR0 192
+#define GW_ADDR1 168
+#define GW_ADDR2 178
+#define GW_ADDR3 1
+
+
+/*
+ --------------------------------------
+ ---------- Checksum options ----------
+ --------------------------------------
+*/
+
+/*
+The STM32H7xx allows computing and verifying the IP, UDP, TCP and ICMP checksums by hardware:
+ - To use this feature let the following define uncommented.
+ - To disable it and process by CPU comment the the checksum.
+*/
+#define CHECKSUM_BY_HARDWARE
+
+
+#ifdef CHECKSUM_BY_HARDWARE
+ /* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/
+ #define CHECKSUM_GEN_IP 0
+ /* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/
+ #define CHECKSUM_GEN_UDP 0
+ /* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/
+ #define CHECKSUM_GEN_TCP 0
+ /* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/
+ #define CHECKSUM_CHECK_IP 0
+ /* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/
+ #define CHECKSUM_CHECK_UDP 0
+ /* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/
+ #define CHECKSUM_CHECK_TCP 0
+ /* CHECKSUM_CHECK_ICMP==0: Check checksums by hardware for incoming ICMP packets.*/
+ #define CHECKSUM_GEN_ICMP 0
+#else
+ /* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/
+ #define CHECKSUM_GEN_IP 1
+ /* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/
+ #define CHECKSUM_GEN_UDP 1
+ /* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/
+ #define CHECKSUM_GEN_TCP 1
+ /* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/
+ #define CHECKSUM_CHECK_IP 1
+ /* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/
+ #define CHECKSUM_CHECK_UDP 1
+ /* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/
+ #define CHECKSUM_CHECK_TCP 1
+ /* CHECKSUM_CHECK_ICMP==1: Check checksums by hardware for incoming ICMP packets.*/
+ #define CHECKSUM_GEN_ICMP 1
+#endif
+
+
+/*
+ ----------------------------------------------
+ ---------- Sequential layer options ----------
+ ----------------------------------------------
+*/
+/**
+ * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
+ */
+#define LWIP_NETCONN 0
+
+/*
+ ------------------------------------
+ ---------- Socket options ----------
+ ------------------------------------
+*/
+/**
+ * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
+ */
+#define LWIP_SOCKET 0
+
+/*
+ ------------------------------------
+ ---------- httpd options ----------
+ ------------------------------------
+*/
+/** Set this to 1 to include "fsdata_custom.c" instead of "fsdata.c" for the
+ * file system (to prevent changing the file included in CVS) */
+#define HTTPD_USE_CUSTOM_FSDATA 1
+
+
+/*
+ ---------------------------------
+ ---------- OS options ----------
+ ---------------------------------
+*/
+
+#define TCPIP_THREAD_NAME "LWIP"
+#define TCPIP_THREAD_STACKSIZE RTEMS_MINIMUM_STACK_SIZE
+#define TCPIP_MBOX_SIZE 6
+#define DEFAULT_UDP_RECVMBOX_SIZE 6
+#define DEFAULT_TCP_RECVMBOX_SIZE 6
+#define DEFAULT_ACCEPTMBOX_SIZE 6
+#define DEFAULT_THREAD_STACKSIZE 500
+#define TCPIP_THREAD_PRIO 60
+
+/*
+ ---------------------------------
+ ---------- ASSERT options ----------
+ ---------------------------------
+*/
+#define LWIP_NOASSERT
+
+
+#define ETH_MAC_ADDR0 ((uint8_t)0x02)
+#define ETH_MAC_ADDR1 ((uint8_t)0x00)
+#define ETH_MAC_ADDR2 ((uint8_t)0x00)
+#define ETH_MAC_ADDR3 ((uint8_t)0x00)
+#define ETH_MAC_ADDR4 ((uint8_t)0x00)
+#define ETH_MAC_ADDR5 ((uint8_t)0x00)
+#define ETH_MAC_ADDR { ETH_MAC_ADDR0, ETH_MAC_ADDR1, \
+ ETH_MAC_ADDR2, ETH_MAC_ADDR3, \
+ ETH_MAC_ADDR4, ETH_MAC_ADDR5 }
+
+/* #undef LWIP_DEBUG */
+
+#endif /* __LWIPOPTS_H__ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/lwip/ports/drivers/phy_dp83848h.c b/lwip/ports/drivers/tms570/phy_dp83848h.c
similarity index 100%
rename from lwip/ports/drivers/phy_dp83848h.c
rename to lwip/ports/drivers/tms570/phy_dp83848h.c
diff --git a/lwip/ports/drivers/phy_dp83848h.h b/lwip/ports/drivers/tms570/phy_dp83848h.h
similarity index 100%
rename from lwip/ports/drivers/phy_dp83848h.h
rename to lwip/ports/drivers/tms570/phy_dp83848h.h
diff --git a/lwip/ports/drivers/tms570/template/lwipopts_template.h b/lwip/ports/drivers/tms570/template/lwipopts_template.h
new file mode 100644
index 0000000..fb55e7a
--- /dev/null
+++ b/lwip/ports/drivers/tms570/template/lwipopts_template.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt
+ *
+ */
+#ifndef LWIP_HDR_LWIPOPTS_H__
+#define LWIP_HDR_LWIPOPTS_H__
+
+/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */
+#define NO_SYS 0
+#define LWIP_NETCONN 1
+#define LWIP_SOCKET 1
+#define LWIP_DNS 1
+
+#define LWIP_IPV6 1
+#define LWIP_IPV4 1
+
+#define LWIP_ETHERNET 1
+#define LWIP_NETIF_API 1
+/* Enable DHCP to test it, disable UDP checksum to easier inject packets */
+#define LWIP_DHCP 1
+#define LWIP_TIMEVAL_PRIVATE 0
+#define LWIP_POSIX_SOCKETS_IO_NAMES 0
+
+/* Minimal changes to opt.h required for tcp unit tests: */
+#define MEM_SIZE 16000
+#define TCP_SND_QUEUELEN 40
+#define MEMP_NUM_TCP_SEG TCP_SND_QUEUELEN
+#define TCP_SND_BUF (12 * TCP_MSS)
+#define TCP_WND (10 * TCP_MSS)
+#define LWIP_WND_SCALE 1
+#define TCP_RCV_SCALE 0
+#define PBUF_POOL_SIZE 400 // pbuf tests need ~200KByte
+
+/* Minimal changes to opt.h required for etharp unit tests: */
+#define ETHARP_SUPPORT_STATIC_ENTRIES 1
+
+#define ETH_IP_ADDR 0xC0A8F701 /* 192.168.247.1 */
+#define ETH_NETMASK 0xFFFFFF00 /* 255.255.255.0 */
+#define ETH_GW 0xC0A8F7FE /* 192.168.247.254 */
+
+#define LWIP_NETIF_LINK_CALLBACK 1
+
+void tms570_eth_memp_avaible(int type);
+
+/*called from memp_free() when a memp pool was empty and an item is now available*/
+#define LWIP_HOOK_MEMP_AVAILABLE tms570_eth_memp_avaible
+
+#endif /* LWIP_HDR_LWIPOPTS_H__ */
diff --git a/lwip/ports/drivers/ti_drv_emac.h b/lwip/ports/drivers/tms570/ti_drv_emac.h
similarity index 100%
rename from lwip/ports/drivers/ti_drv_emac.h
rename to lwip/ports/drivers/tms570/ti_drv_emac.h
diff --git a/lwip/ports/drivers/ti_drv_mdio.h b/lwip/ports/drivers/tms570/ti_drv_mdio.h
similarity index 100%
rename from lwip/ports/drivers/ti_drv_mdio.h
rename to lwip/ports/drivers/tms570/ti_drv_mdio.h
diff --git a/lwip/ports/drivers/tms570_emac.h b/lwip/ports/drivers/tms570/tms570_emac.h
similarity index 100%
rename from lwip/ports/drivers/tms570_emac.h
rename to lwip/ports/drivers/tms570/tms570_emac.h
diff --git a/lwip/ports/drivers/tms570_netif.c b/lwip/ports/drivers/tms570/tms570_netif.c
similarity index 99%
rename from lwip/ports/drivers/tms570_netif.c
rename to lwip/ports/drivers/tms570/tms570_netif.c
index 8d14687..2c99362 100644
--- a/lwip/ports/drivers/tms570_netif.c
+++ b/lwip/ports/drivers/tms570/tms570_netif.c
@@ -54,13 +54,15 @@
#include <bsp/tms570.h>
#include <bsp/tms570-pinmux.h>
#include "arch/cc.h"
-#include "eth_lwip.h"
+#include "rtems_lwip.h"
#include "tms570_netif.h"
#include "ti_drv_emac.h"
#include "ti_drv_mdio.h"
#include "phy_dp83848h.h"
#include "tms570_emac.h"
+netif_init_fn eth_lwip_init_fnc = &tms570_eth_init_netif;
+
#define LINK_SPEED_OF_YOUR_NETIF_IN_BPS 10000000
/* Number of EMAC Instances */
@@ -150,6 +152,7 @@ static err_t tms570_eth_init_control_structures(struct netif *netif);
static void tms570_eth_init_netif_fill(struct netif *netif);
static void tms570_eth_init_buffer_descriptors(struct tms570_netif_state *nf_state);
static void tms570_eth_init_set_pinmux();
+static void sys_arch_data_sync_barier();
/***** initializing functions **********************************************/
@@ -1122,10 +1125,12 @@ tms570_eth_memp_avaible(int type)
return;
if (type != MEMP_PBUF_POOL)
return;
- netifapi_netif_common(eth_lwip_get_netif(0), tms570_eth_rx_pbuf_refill_single, NULL);
+ netifapi_netif_common(rtems_lwip_get_netif(0), tms570_eth_rx_pbuf_refill_single, NULL);
}
-
+void sys_arch_data_sync_barier() {
+ _ARM_Data_synchronization_barrier();
+}
#if TMS570_NETIF_DEBUG
diff --git a/lwip/ports/drivers/tms570_netif.h b/lwip/ports/drivers/tms570/tms570_netif.h
similarity index 74%
rename from lwip/ports/drivers/tms570_netif.h
rename to lwip/ports/drivers/tms570/tms570_netif.h
index 325249a..6636f3f 100644
--- a/lwip/ports/drivers/tms570_netif.h
+++ b/lwip/ports/drivers/tms570/tms570_netif.h
@@ -36,6 +36,37 @@
//#define TMS570_NETIF_DEBUG 1
+/**
+ * While scanning phy addresses no alive phy was found.
+ * Return value of rpp_eth_hw_init() function.
+ */
+#define NO_PHY_ALIVE -1
+/**
+ * Scanning default phy address, it was found it's not alive.
+ * Return value of rpp_eth_hw_init() function.
+ */
+#define DFLT_PHY_NOT_ALIVE -1
+/**
+ * When setting autonegotiation parameters to EMAC module, there was found impossible mode (usually on timeout of autonegotiation).
+ * Return value of rpp_eth_hw_init_postInit() function.
+ */
+#define UNKN_DUPLEX_MODE -2 /* this could mean that autonegotiation was not completed yet */
+/**
+ * Phy is down error.
+ * Return value of rpp_eth_init_postInit() function.
+ */
+#define PHY_LINK_DOWN -3
+
+/**
+ * Memory requirements couldn't be satisfied.
+ */
+#define DHCP_MEM_ERR -11
+
+/**
+ * configures whether rpp_eth_get_macAddrStr() creates string with big or small latin letters
+ */
+#define MAC_BIG_LETTERS 1
+
#ifdef TMS570_NETIF_DEBUG
#define tms570_eth_debug_printf sys_arch_printk
#else
diff --git a/lwip/ports/os/rtems/arch/cc.h b/lwip/ports/os/rtems/arch/cc.h
index 84138ff..0e298c7 100644
--- a/lwip/ports/os/rtems/arch/cc.h
+++ b/lwip/ports/os/rtems/arch/cc.h
@@ -39,6 +39,9 @@
#ifndef __CC_H__
#define __CC_H__
+/* Use timeval provided by RTEMS be defining this to 0 */
+#define LWIP_TIMEVAL_PRIVATE 0
+
#include <stdio.h>
#include <rtems/malloc.h> /*printk*/
#include <inttypes.h>
diff --git a/lwip/ports/os/rtems/arch/sys_arch.c b/lwip/ports/os/rtems/arch/sys_arch.c
index ca7f8be..f845c2c 100644
--- a/lwip/ports/os/rtems/arch/sys_arch.c
+++ b/lwip/ports/os/rtems/arch/sys_arch.c
@@ -37,15 +37,22 @@
* DETAILS: ./lwip/doc/sys_arch.txt
*/
+
+/* lwIP includes. */
+#include "lwip/debug.h"
+#include "lwip/def.h"
+#include "lwip/sys.h"
+#include "lwip/mem.h"
+#include "lwip/stats.h"
+
+#if !NO_SYS
+
+#include "sys_arch.h"
#include <stdint.h>
#include <arch/cc.h>
#include <rtems/rtems/clock.h>
#include <rtems/rtems/sem.h>
#include <rtems.h>
-#include "sys_arch.h"
-#include "lwip/err.h"
-#include "lwip/tcpip.h"
-#include "lwipopts.h"
#define SYS_LWIP_MBOX_SIZE (sizeof(void *))
@@ -268,8 +275,21 @@ sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stack_s
rtems_id id;
rtems_status_code res;
+ rtems_name lwip_task_name = 0;
+ if(name == NULL) {
+ lwip_task_name = rtems_build_name('L', 'W', 'I', 'P');
+ }
+ else {
+ if(name[0] == '\0') {
+ lwip_task_name = rtems_build_name('L', 'W', 'I', 'P');
+ }
+ else {
+ lwip_task_name = rtems_build_name(name[0], name[1], name[2], name[3]);
+ }
+ }
+
res = rtems_task_create(
- rtems_build_name('L', 'W', 'I', 'P'),
+ lwip_task_name,
prio,
stack_size,
RTEMS_PREEMPT,
@@ -376,3 +396,5 @@ sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg)
return sys_mbox_trypost(q, msg);
}
+#endif /* NO_SYS == 0 */
+
diff --git a/lwip/ports/os/rtems/arch/sys_arch.h b/lwip/ports/os/rtems/arch/sys_arch.h
index c89abd4..f4a73a7 100644
--- a/lwip/ports/os/rtems/arch/sys_arch.h
+++ b/lwip/ports/os/rtems/arch/sys_arch.h
@@ -39,17 +39,23 @@
#ifndef __ARCH_SYS_ARCH_H__
#define __ARCH_SYS_ARCH_H__
+#include "lwip/opt.h"
+
+#if (NO_SYS != 0)
+#error "RTEMS SYS_ARCH cannot be compiled in NO_SYS variant"
+#endif
+
#include <rtems/rtems/sem.h>
#include <rtems/rtems/intr.h>
#include <rtems/score/cpu.h>
#include <bsp/irq-generic.h>
-//#include "eth_lwip_default.h"
-/* Typedefs for the various port-specific types. */
-#if defined(NO_SYS) && NO_SYS
- #error "RTEMS SYS_ARCH cannot be compiled in NO_SYS variant"
+#ifdef __cplusplus
+extern "C" {
#endif
+/* Typedefs for the various port-specific types. */
+
#define sys_arch_printk printk
typedef struct {
@@ -105,4 +111,8 @@ sys_prot_t sys_arch_protect();
void sys_arch_unprotect(sys_prot_t pval);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __ARCH_SYS_ARCH_H__ */
diff --git a/lwip/src/include/lwip/sys.h b/lwip/src/include/lwip/sys.h
index 1933590..168e465 100644
--- a/lwip/src/include/lwip/sys.h
+++ b/lwip/src/include/lwip/sys.h
@@ -38,7 +38,6 @@
#define LWIP_HDR_SYS_H
#include "lwip/opt.h"
-#include "arch/sys_arch.h"
#ifdef __cplusplus
extern "C" {
diff --git a/lwip/ports/os/lwipopts.h b/lwip/test/lwipopts.h
similarity index 100%
rename from lwip/ports/os/lwipopts.h
rename to lwip/test/lwipopts.h
diff --git a/waf b/waf
old mode 100755
new mode 100644
--
2.27.0
More information about the devel
mailing list