/*
 * 文件: ETH_CH390H.c
 * 描述: CH390H SPI 以太网模块初始化与事件处理封装。
 *
 * 功能:
 *   - 初始化 SPI 总线并配置 CH390H 设备
 *   - 安装并启动 esp-eth 驱动
 *   - 注册以太网事件回调（连接/断开/启动/停止）和获取 IP 回调
 *
 * 用法:
 *   1. 在 app_main() 中调用 eth_init() 完成初始化，例如：
 *        eth_init();
 *   2. 如需自定义 GPIO/SPI 配置，可修改本文件顶部的宏定义。
 *   3. 如需自定义事件处理，修改 eth_event_handler 或 got_ip_event_handler。
 *
 * 注意:
 *   - 本模块使用 esp_netif 和 esp_event，调用前请确保没有重复初始化。
 *   - 调试时可通过调整 mac_config.rx_task_stack_size 或 SPI_CLOCK_MHZ 优化性能。
 */


#include "ETH_CH390H.h"
#include "STATUS_LED.h"


static const char *TAG = "eth_ch390h";



/* 事件处理函数
 * 处理 esp-eth 发出的以太网状态事件：
 *   - ETHERNET_EVENT_CONNECTED    : 已连接（物理链路/链路层可用）
 *   - ETHERNET_EVENT_DISCONNECTED : 断开（物理链路丢失）
 *   - ETHERNET_EVENT_START        : 以太网驱动启动
 *   - ETHERNET_EVENT_STOP         : 以太网驱动停止
 * 参数：
 *   arg        - 注册时传入的参数（当前未使用）
 *   event_base - 事件基（ETH_EVENT）
 *   event_id   - 事件 id
 *   event_data - 事件相关数据（视事件而定）
 */
static void eth_event_handler(void *arg, esp_event_base_t event_base,
                              int32_t event_id, void *event_data)
{
    switch (event_id)
    {
    case ETHERNET_EVENT_CONNECTED:
        ESP_LOGI(TAG, "以太网连接成功");
        status_led_set(1, 1);  // LED1 常亮：物理连接正常
        break;
    case ETHERNET_EVENT_DISCONNECTED:
        ESP_LOGI(TAG, "以太网断开连接");
        status_led_blink_mode(1, 1);  // LED1 快闪：网络断开
        break;
    case ETHERNET_EVENT_START:
        ESP_LOGI(TAG, "以太网开始工作");
        break;
    case ETHERNET_EVENT_STOP:
        ESP_LOGI(TAG, "以太网停止工作");
        break;
    default:
        break;
    }
}

/* 获取 IP 回调
 * 当网口获取到 IP（DHCP 或静态）时调用，打印分配到的 IP 信息。
 * 参数同上，event_data 可转换为 ip_event_got_ip_t* 来读取 ip 信息。
 */
static void got_ip_event_handler(void *arg, esp_event_base_t event_base,
                                 int32_t event_id, void *event_data)
{
    ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
    ESP_LOGI(TAG, "获取到的IP: " IPSTR, IP2STR(&event->ip_info.ip));
    status_led_set(1, 1);  // LED1 常亮：IP获取成功，网络就绪
}

/* eth_init
 * 初始化并启动 CH390H 以太网设备的封装函数：
 * 1. 初始化网络接口与默认事件循环
 * 2. 配置并初始化 SPI 总线（供 CH390H 使用）
 * 3. 配置 CH390H 的 mac/phy，并安装 esp-eth 驱动
 * 4. 将 esp-netif 绑定到以太网驱动，并注册事件回调
 * 5. 启动以太网驱动
 *
 * 注意：
 * - 若需要修改引脚或 SPI 频率，可在文件顶部宏中调整
 * - 可根据需要调整 mac_config、phy_config 中的参数以优化性能
 */
void eth_init(void)
{
    esp_netif_init();
    esp_event_loop_create_default();

    esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
    esp_netif_t *eth_netif = esp_netif_new(&cfg);

    /* 设置以太网设备在 DHCP/路由器中的主机名（需在启动前设置） */
    esp_netif_set_hostname(eth_netif, "Distributed Collector Gateway");

    gpio_install_isr_service(0);

    spi_bus_config_t buscfg = {
        .mosi_io_num = ETH_MOSI_GPIO,
        .miso_io_num = ETH_MISO_GPIO,
        .sclk_io_num = ETH_SCLK_GPIO,
        .quadwp_io_num = -1,
        .quadhd_io_num = -1,
    };
    ESP_ERROR_CHECK(spi_bus_initialize(SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));

    spi_device_interface_config_t spi_devcfg = {
        .mode = 0,
        .clock_speed_hz = SPI_CLOCK_MHZ * 1000 * 1000,
        .spics_io_num = ETH_CS_GPIO,
        .queue_size = 20,
    };

    eth_ch390_config_t ch390_config = ETH_CH390_DEFAULT_CONFIG(SPI_HOST, &spi_devcfg);
    ch390_config.int_gpio_num = ETH_INT_GPIO;

    eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
    mac_config.rx_task_stack_size = 4096;

    esp_eth_mac_t *mac = esp_eth_mac_new_ch390(&ch390_config, &mac_config);

    eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
    esp_eth_phy_t *phy = esp_eth_phy_new_ch390(&phy_config);

    esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);

    esp_eth_handle_t eth_handle = NULL;
    ESP_ERROR_CHECK(esp_eth_driver_install(&eth_config, &eth_handle));

    ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle)));

    esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL);
    esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL);

    ESP_ERROR_CHECK(esp_eth_start(eth_handle));
}
