diff --git a/Core/Src/main.c b/Core/Src/main.c index 94c53c9..5c328b9 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -27,6 +27,7 @@ #include "ethernetif.h" #include "ch390_runtime.h" #include "lwip/init.h" +#include "lwip/etharp.h" #include "lwip/timeouts.h" #include "tcp_client.h" #include "tcp_server.h" @@ -41,6 +42,9 @@ #define APP_TCP_TO_UART_CHUNK_SIZE 128u #define STACK_GUARD_WORD 0xA5A5A5A5u #define APP_HEALTH_CHECK_INTERVAL_MS 5000u +#define APP_LINK_SETTLE_MS 1500u +#define APP_ARP_ANNOUNCE_INTERVAL_MS 500u +#define APP_ARP_ANNOUNCE_COUNT 3u /* USER CODE END PD */ /* Private variables ---------------------------------------------------------*/ @@ -51,6 +55,10 @@ volatile uint8_t g_uart1_rx_probe_byte = 0u; static uint8_t g_stack_guard_reported = 0u; static uint8_t g_mux_response_frame[272]; static uint8_t g_links_started = 0u; +static uint8_t g_link_was_up = 0u; +static uint8_t g_arp_announces_sent = 0u; +static uint32_t g_link_up_tick = 0u; +static uint32_t g_last_arp_announce_tick = 0u; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ @@ -198,10 +206,25 @@ static void App_ConfigureLinks(const device_config_t *cfg) static void App_StartLinksIfNeeded(void) { int any_failed; + uint32_t now; if ((g_links_started != 0u) || !netif_is_link_up(&ch390_netif)) { return; } + now = HAL_GetTick(); + if ((uint32_t)(now - g_link_up_tick) < APP_LINK_SETTLE_MS) { + return; + } + + while (g_arp_announces_sent < APP_ARP_ANNOUNCE_COUNT) { + if ((g_arp_announces_sent != 0u) && + ((uint32_t)(now - g_last_arp_announce_tick) < APP_ARP_ANNOUNCE_INTERVAL_MS)) { + return; + } + (void)etharp_gratuitous(&ch390_netif); + g_arp_announces_sent++; + g_last_arp_announce_tick = now; + } any_failed = 0; for (uint8_t i = 0; i < TCP_SERVER_INSTANCE_COUNT; ++i) { @@ -243,6 +266,36 @@ static void App_StopLinksIfNeeded(void) g_links_started = 0u; } +static void App_HandleLinkTransition(void) +{ + uint8_t link_up = netif_is_link_up(&ch390_netif) ? 1u : 0u; + + if (link_up == g_link_was_up) { + return; + } + + g_link_was_up = link_up; + if (link_up != 0u) { + g_link_up_tick = HAL_GetTick(); + g_arp_announces_sent = 0u; + g_last_arp_announce_tick = 0u; + etharp_cleanup_netif(&ch390_netif); + SEGGER_RTT_WriteString(0, "NET link up, settling before TCP start\r\n"); + } else { + for (uint8_t i = 0; i < TCP_CLIENT_INSTANCE_COUNT; ++i) { + (void)tcp_client_disconnect(i); + } + for (uint8_t i = 0; i < TCP_SERVER_INSTANCE_COUNT; ++i) { + (void)tcp_server_stop(i); + } + etharp_cleanup_netif(&ch390_netif); + g_links_started = 0u; + g_arp_announces_sent = 0u; + g_last_arp_announce_tick = 0u; + SEGGER_RTT_WriteString(0, "NET link down, cleared TCP and ARP state\r\n"); + } +} + static void App_Init(void) { const device_config_t *cfg; @@ -648,10 +701,13 @@ static void App_Poll(void) ethernetif_poll(); ethernetif_check_link(); sys_check_timeouts(); + App_HandleLinkTransition(); App_StopLinksIfNeeded(); App_StartLinksIfNeeded(); tcp_server_poll(); - tcp_client_poll(); + if (g_links_started != 0u) { + tcp_client_poll(); + } uart_trans_poll(); StackGuard_Check(); config_poll(); diff --git a/MDK-ARM/keil-build-viewer-record.txt b/MDK-ARM/keil-build-viewer-record.txt index c93fe9e..803f061 100644 --- a/MDK-ARM/keil-build-viewer-record.txt +++ b/MDK-ARM/keil-build-viewer-record.txt @@ -5,7 +5,7 @@ 3958 0 591 8 1240 0 config.o 8 0 0 0 0 0 def.o 124 0 0 0 0 0 dma.o - 1772 0 0 1 240 0 etharp.o + 1816 0 0 1 240 0 etharp.o 238 0 12 0 0 0 ethernet.o 178 0 0 0 48 0 ethernetif.o 246 0 0 0 0 0 flash_param.o @@ -17,7 +17,7 @@ 778 0 0 2 0 0 ip4.o 46 0 4 0 0 0 ip4_addr.o 44 0 0 0 12 0 iwdg.o - 3264 0 300 12 272 0 main.o + 3532 0 300 20 272 0 main.o 828 0 0 12 4115 0 mem.o 196 0 244 32 6464 0 memp.o 582 0 0 12 0 0 netif.o @@ -57,8 +57,8 @@ Memory Map of the image Load Region LR_IROM1 - Execution Region ER_IROM1 (Exec base: 0x08000000, Size: 0x0000DFA0, Max: 0x00010000, END) + Execution Region ER_IROM1 (Exec base: 0x08000000, Size: 0x0000E0B8, Max: 0x00010000, END) - Execution Region RW_IRAM1 (Exec base: 0x20000000, Size: 0x00004FD8, Max: 0x00005000, END) + Execution Region RW_IRAM1 (Exec base: 0x20000000, Size: 0x00004FE0, Max: 0x00005000, END) Image component sizes \ No newline at end of file