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 ---------------------------------------------------------*/ +/* +@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. + +@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 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel