Files
TCP2UART/App/task_net_poll.c

193 lines
6.1 KiB
C

#include "task_net_poll.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "CH390.h"
#include <string.h>
#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
}
}