ESP32-IDF:CH390D以太网驱动


概述

该文章主要介绍如何在ESP32-IDF-V5.3.1中添加CH390D以太网驱动获取IP地址实现上网功能。

参考

https://components.espressif.com/components/espressif/ch390
https://docs.espressif.com/projects/esp-idf/zh_CN/v5.3.1/esp32/api-reference/network/esp_eth.html#driver-configuration-and-installation


该工程基于ethernet/basic例程编写
参考ethernet/enc28j60例程

一、下载CH390D驱动

1、打开https://components.espressif.com/components/espressif/ch390在网页右侧点击download archive下载CH390D驱动包
在这里插入图片描述

二、移植CH390D驱动

将驱动包中的esp_eth_mac_ch390.c、esp_eth_mac_ch390.h、esp_eth_phy_ch390.c、esp_eth_phy_ch390.h及ch390.h文件复制到目标工程中。
在这里插入图片描述

三、修改宏定义

使能支持SPI-Ethernet模块。
在这里插入图片描述

四、使用CH390D

添加ch390d_driver.c文件

#include <stdio.h>
#include <string.h>
#include "driver/spi_master.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_netif.h"
#include "esp_eth.h"
#include "esp_event.h"
#include "ethernet_init.h"
#include "sdkconfig.h"

#include "esp_eth_mac_ch390.h"
#include "esp_eth_phy_ch390.h"
#include "ch390.h"

#include "ch390d_driver.h"


static const char *TAG = "CH390D";

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, "以太网连接成功");
        break;
    case ETHERNET_EVENT_DISCONNECTED:
        ESP_LOGI(TAG, "以太网断开连接");
        break;
    case ETHERNET_EVENT_START:
        ESP_LOGI(TAG, "以太网开始工作");
        break;
    case ETHERNET_EVENT_STOP:
        ESP_LOGI(TAG, "以太网停止工作");
        break;
    default:
        break;
    }
}

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));
}


void eth_ch390h_driver_init(void)
{
    // Initialize TCP/IP network interface aka the esp-netif (should be called only once in application)
    ESP_ERROR_CHECK(esp_netif_init());
    // Create default event loop that running in background
    ESP_ERROR_CHECK(esp_event_loop_create_default());

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

    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();
    phy_config.autonego_timeout_ms = 0; // ENC28J60 doesn't support auto-negotiation
    phy_config.reset_gpio_num = -1; // ENC28J60 doesn't have a pin to reset internal PHY
    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));

    /* attach Ethernet driver to TCP/IP stack */
    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));
}



添加ch390d_driver.h文件

#ifndef _CH390D_DRIVER_H_
#define _CH390D_DRIVER_H_



//根据自己实际情况修改
#define ETH_CS_GPIO        2
#define ETH_MOSI_GPIO      14
#define ETH_MISO_GPIO      15
#define ETH_SCLK_GPIO      12
#define ETH_INT_GPIO       4
#define SPI_HOST           SPI3_HOST
#define SPI_CLOCK_MHZ      5

void eth_ch390h_driver_init(void);



#endif



修改app_main函数

void app_main(void)
{
    eth_ch390h_driver_init();
}

五、测试结果

ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:7176
load:0x40078000,len:15564
ho 0 tail 12 room 4
load:0x40080400,len:4
load:0x40080404,len:3904
entry 0x40080640
I (30) boot: ESP-IDF v5.3.1 2nd stage bootloader
I (30) boot: compile time Mar 25 2025 15:33:20
I (31) boot: Multicore bootloader
I (35) boot: chip revision: v1.0
I (38) boot.esp32: SPI Speed      : 40MHz
I (43) boot.esp32: SPI Mode       : DIO
I (48) boot.esp32: SPI Flash Size : 4MB
I (52) boot: Enabling RNG early entropy source...
I (58) boot: Partition Table:
I (61) boot: ## Label            Usage          Type ST Offset   Length
I (68) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (76) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (83) boot:  2 factory          factory app      00 00 00010000 00100000
I (91) boot: End of partition table
I (95) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=13484h ( 78980) map
I (131) esp_image: segment 1: paddr=000234ac vaddr=3ffb0000 size=024c4h (  9412) load
I (134) esp_image: segment 2: paddr=00025978 vaddr=40080000 size=0a6a0h ( 42656) load
I (153) esp_image: segment 3: paddr=00030020 vaddr=400d0020 size=31098h (200856) map
I (222) esp_image: segment 4: paddr=000610c0 vaddr=4008a6a0 size=04b14h ( 19220) load
I (237) boot: Loaded app from partition at offset 0x10000
I (238) boot: Disabling RNG early entropy source...
I (250) cpu_start: Multicore app
I (258) cpu_start: Pro cpu start user code
I (258) cpu_start: cpu freq: 160000000 Hz
I (258) app_init: Application information:
I (261) app_init: Project name:     ethernet_basic
I (266) app_init: App version:      1
I (271) app_init: Compile time:     Mar 25 2025 15:34:35
I (277) app_init: ELF file SHA256:  161cd5241...
I (282) app_init: ESP-IDF:          v5.3.1
I (287) efuse_init: Min chip rev:     v0.0
I (292) efuse_init: Max chip rev:     v3.99 
I (296) efuse_init: Chip rev:         v1.0
I (302) heap_init: Initializing. RAM available for dynamic allocation:
I (309) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (315) heap_init: At 3FFB37B0 len 0002C850 (178 KiB): DRAM
I (321) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (327) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (334) heap_init: At 4008F1B4 len 00010E4C (67 KiB): IRAM
I (341) spi_flash: detected chip: generic
I (344) spi_flash: flash io: dio
I (349) main_task: Started on CPU0
I (359) main_task: Calling app_main()
I (389) esp_eth.netif.netif_glue: 3c:ab:72:44:56:6a
I (389) esp_eth.netif.netif_glue: ethernet attached to netif
I (389) CH390D: 以太网开始工作
I (389) main_task: Returned from app_main()
I (16399) CH390D: 以太网连接成功
I (17399) esp_netif_handlers: eth ip: 192.168.31.249, mask: 255.255.255.0, gw: 192.168.31.1
I (17399) CH390D: 获取到的IP: 192.168.31.249
I (22399) CH390D: 以太网断开连接

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值