#include "task_net_poll.h" #include "FreeRTOS.h" #include "task.h" #include "semphr.h" #include "CH390.h" #include #if !DIAG_CH390_RAW_POLL #include "lwip/tcpip.h" #include "lwip/ip4_addr.h" #endif #include "ethernetif.h" #include "config.h" #include "app_runtime.h" #include "debug_log.h" #define CH390_RESTART_HOLD_DOWN_MS 500u #define NETWORK_TASK_DELETE_SETTLE_MS 50u #define CH390_EXPECTED_VENDOR_ID 0x1C00u #define CH390_EXPECTED_PRODUCT_ID 0x9151u static void net_poll_wait_for_network_tasks_stop(void) { while (app_network_tasks_are_stopped() == pdFALSE) { vTaskDelay(pdMS_TO_TICKS(20)); } } static BaseType_t net_poll_restart_network_stack(const device_config_t *cfg) { #if !DIAG_CH390_RAW_POLL ip4_addr_t ipaddr; ip4_addr_t netmask; ip4_addr_t gateway; uint16_t vendor_id; uint16_t product_id; uint8_t revision; IP4_ADDR(&ipaddr, cfg->net.ip[0], cfg->net.ip[1], cfg->net.ip[2], cfg->net.ip[3]); IP4_ADDR(&netmask, cfg->net.mask[0], cfg->net.mask[1], cfg->net.mask[2], cfg->net.mask[3]); IP4_ADDR(&gateway, cfg->net.gw[0], cfg->net.gw[1], cfg->net.gw[2], cfg->net.gw[3]); #endif ethernetif_force_link_down(); g_netif_ready = pdFALSE; app_request_network_task_stop(); net_poll_wait_for_network_tasks_stop(); vTaskDelay(pdMS_TO_TICKS(NETWORK_TASK_DELETE_SETTLE_MS)); vTaskDelay(pdMS_TO_TICKS(CH390_RESTART_HOLD_DOWN_MS)); #if DIAG_CH390_RAW_POLL ethernetif_diag_ch390_init(); #else ethernetif_force_full_recovery(&ipaddr, &netmask, &gateway, cfg->net.mac); vendor_id = ethernetif_ch390_get_vendor_id(); product_id = ethernetif_ch390_get_product_id(); revision = ethernetif_ch390_get_revision(); if ((vendor_id != CH390_EXPECTED_VENDOR_ID) || (product_id != CH390_EXPECTED_PRODUCT_ID)) { debug_log_printf("[NET] restart-recovery id-warn vid=0x%04X pid=0x%04X rev=0x%02X free=%lu min=%lu\r\n", (unsigned int)vendor_id, (unsigned int)product_id, (unsigned int)revision, (unsigned long)xPortGetFreeHeapSize(), (unsigned long)xPortGetMinimumEverFreeHeapSize()); } #endif app_clear_network_task_stop(); g_netif_ready = pdTRUE; app_start_network_tasks(); app_clear_network_restart_request(); return pdTRUE; } void NetPollTask(void *argument) { const device_config_t *cfg; #if !DIAG_CH390_RAW_POLL ip4_addr_t ipaddr; ip4_addr_t netmask; ip4_addr_t gateway; #else static uint8_t s_diag_rx_buffer[CH390_PKT_MAX]; #endif BaseType_t loop_logged = pdFALSE; (void)argument; debug_log_write("[NET] task-entry\r\n"); cfg = config_get(); debug_log_write("[NET] config-ok\r\n"); #if DIAG_CH390_RAW_POLL g_netif_phase = 1u; debug_log_write("[NET] diag-ch390-init enter\r\n"); ethernetif_diag_ch390_init(); g_netif_phase = 7u; debug_log_write("[NET] diag-ch390-init exit\r\n"); if (g_netif_init_ok != 1) { for (;;) { vTaskDelay(pdMS_TO_TICKS(1000)); } } g_netif_ready = pdTRUE; app_start_network_tasks(); debug_log_write("[NET] diag-ch390-ready\r\n"); #else debug_log_write("[NET] tcpip-init enter\r\n"); tcpip_init(NULL, NULL); debug_log_write("[NET] tcpip-init exit\r\n"); vTaskDelay(pdMS_TO_TICKS(50)); debug_log_write("[NET] post-delay\r\n"); IP4_ADDR(&ipaddr, cfg->net.ip[0], cfg->net.ip[1], cfg->net.ip[2], cfg->net.ip[3]); IP4_ADDR(&netmask, cfg->net.mask[0], cfg->net.mask[1], cfg->net.mask[2], cfg->net.mask[3]); IP4_ADDR(&gateway, cfg->net.gw[0], cfg->net.gw[1], cfg->net.gw[2], cfg->net.gw[3]); g_netif_phase = 1u; debug_log_printf("[NET] netif-call hwm=%lu\r\n", (unsigned long)uxTaskGetStackHighWaterMark(NULL)); debug_log_write("[NET] netif-init enter\r\n"); lwip_netif_init(&ipaddr, &netmask, &gateway); g_netif_phase = 7u; debug_log_write("[NET] netif-init exit\r\n"); debug_log_printf("[NET] post-init ok=%ld hwm=%lu free=%lu min=%lu\r\n", (long)g_netif_init_ok, (unsigned long)uxTaskGetStackHighWaterMark(NULL), (unsigned long)xPortGetFreeHeapSize(), (unsigned long)xPortGetMinimumEverFreeHeapSize()); if (g_netif_init_ok != 1) { for (;;) { vTaskDelay(pdMS_TO_TICKS(1000)); } } debug_log_write("[NET] pre-ready\r\n"); g_netif_ready = pdTRUE; debug_log_write("[NET] start-network-tasks call\r\n"); app_start_network_tasks(); debug_log_printf("[NET] post-ready free=%lu min=%lu\r\n", (unsigned long)xPortGetFreeHeapSize(), (unsigned long)xPortGetMinimumEverFreeHeapSize()); debug_log_write("[NET] netif-ready\r\n"); #endif for (;;) { if (loop_logged == pdFALSE) { g_netif_phase = 8u; debug_log_write("[NET] loop-enter\r\n"); loop_logged = pdTRUE; } if (app_network_restart_requested() != pdFALSE) { (void)net_poll_restart_network_stack(cfg); } (void)xSemaphoreTake(xNetSemaphore, pdMS_TO_TICKS(2)); #if DIAG_CH390_RAW_POLL ethernetif_diag_poll_status(); if (ch390_read_reg(CH390_NSR) & NSR_RXRDY) { uint8_t rx_status = 0u; uint32_t rx_len = ch390_runtime_receive_packet(s_diag_rx_buffer, &rx_status); if (rx_len > 0u) { debug_log_printf("[RAW] rx len=%lu st=0x%02X h=%02X %02X %02X %02X\r\n", (unsigned long)rx_len, (unsigned int)rx_status, (unsigned int)s_diag_rx_buffer[0], (unsigned int)s_diag_rx_buffer[1], (unsigned int)s_diag_rx_buffer[2], (unsigned int)s_diag_rx_buffer[3]); } } #else if (g_netif_ready != pdFALSE) { ethernetif_poll(); ethernetif_check_link(); } #endif } }