espressif / esp-at

AT application for ESP32/ESP32-C2/ESP32-C3/ESP32-C6/ESP8266
Apache License 2.0
838 stars 698 forks source link

Ethernet + SPI (W5500) commands #852

Open pedrorovi opened 5 days ago

pedrorovi commented 5 days ago

Answers checklist.

General issue report

Hey, I have a problem. The AT firmware can't store cmd commands with SPI defined to use Ethernet. I have implemented the example and I get these logs:

I (2908) eth_example: Ethernet Started
I (2913) eth_example: SPI Driver installed correctly 
E (2918) esp_eth: esp_eth_driver_install(189): can't set eth->mac or eth->phy to null
regist ethernet cmd fail
I (2930) main_task: Returned from app_main()
D (4913) w5500.mac: working in 100Mbps
D (4914) w5500.mac: working in full duplex
D (4914) w5500.mac: link is up
D (4914) event: running post ETH_EVENT:2 with handler 0x400dc820 and context 0x3ffb8288 on loop 0x3ffbc400
D (4924) event: running post ETH_EVENT:2 with handler 0x4013e168 and context 0x3ffb965c on loop 0x3ffbc400
D (4933) esp_eth.netif.netif_glue: eth_action_connected: 0x3ffb95c8, 0x3f4110a4, 2, 0x3ffb9830, 0x3ffb9550
D (4943) esp_netif_handlers: esp_netif action connected with netif0x3ffb82a8 from event_id=2
D (4951) esp_netif_lwip: check: remote, if=0x3ffb82a8 fn=0x40124a94

D (4958) esp_netif_lwip: esp_netif_up_api esp_netif:0x3ffb82a8
D (4963) esp_netif_lwip: check: local, if=0x3ffb82a8 fn=0x4012568c

D (4970) esp_netif_lwip: esp_netif_update_default_netif_lwip 0x3ffb82a8
D (4976) esp_netif_lwip: call api in lwip: ret=0x0, give sem
D (4982) esp_netif_lwip: check: remote, if=0x3ffb82a8 fn=0x401242c0

D (4989) esp_netif_lwip: esp_netif_dhcpc_start_api esp_netif:0x3ffb82a8
D (4995) esp_netif_lwip: esp_netif_start_ip_lost_timer esp_netif:0x3ffb82a8
D (5002) esp_netif_lwip: if0x3ffb82a8 start ip lost tmr: no need start because netif=0x3ffb832c interval=120 ip=0
D (5012) esp_netif_lwip: starting dhcp client
D (5019) esp_netif_lwip: call api in lwip: ret=0x0, give sem
D (5023) event: running post ETH_EVENT:2 with handler 0x400ecdbc and context 0x3ffb96e0 on loop 0x3ffbc400
I (5032) eth_example: Ethernet Link Up
I (5037) eth_example: Ethernet HW Addr 02:00:00:12:34:56
D (5052) w5500.mac: receive len=60
D (5146) w5500.mac: receive len=60
D (7092) w5500.mac: receive len=365
D (7212) w5500.mac: receive len=365
D (8021) esp_netif_lwip: esp_netif_internal_dhcpc_cb lwip-netif:0x3ffb832c
D (8022) esp_netif_lwip: if0x3ffb82a8 ip changed=1
D (8023) event: running post IP_EVENT:4 with handler 0x400dc820 and context 0x3ffb8254 on loop 0x3ffbc400
D (8033) event: running post IP_EVENT:4 with handler 0x4013e0f0 and context 0x3ffb96ac on loop 0x3ffbc400
D (8042) esp_eth.netif.netif_glue: eth_action_got_ip: 0x3ffb95c8, 0x3f40c9cc, 4, 0x3ffb9894, 0x3ffb82a8
D (8051) esp_netif_handlers: esp_netif action got_ip with netif0x3ffb82a8 from event_id=4
I (8059) esp_netif_handlers: eth0 ip: 192.168.1.157, mask: 255.255.255.0, gw: 192.168.1.1
D (8068) event: running post IP_EVENT:4 with handler 0x400ecd14 and context 0x3ffb9700 on loop 0x3ffbc400
I (8078) eth_example: Ethernet Got IP Address
I (8083) eth_example: ~~~~~~~~~~~
I (8086) eth_example: ETHIP:192.168.1.157
I (8091) eth_example: ETHMASK:255.255.255.0
I (8096) eth_example: ETHGW:192.168.1.1
I (8100) eth_example: ~~~~~~~~~~~

The driver install is working at components/at/src/at_eth_init.c but I think this function _esp_at_eth_cmdregist try to do something similar, but it is using the old physical layers models instead the SPI configured.

I tried already with some releases (3.2, 3.4 and 4.0) and master. In any of them works.

Can you give me some help?

pedrorovi commented 4 days ago

I added this custom commands while the issue is not fixed.

uint8_t get_mac_spi_eth() {
  uint8_t mac_addr[6] = {0};
  esp_netif_t *eth_netif = get_spi_eth_netif(0);
  ESP_ERROR_CHECK(esp_netif_get_mac(eth_netif, mac_addr));
  char text[64] = {0};
  snprintf(text, sizeof(text), "+MAC:%02X:%02X:%02X:%02X:%02X:%02X\r\n",
           mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4],
           mac_addr[5]);
  esp_at_port_write_data((uint8_t *)text, sizeof(text));
  return ESP_AT_RESULT_CODE_OK;
}

uint8_t set_mac_spi_eth(const uint8_t *mac) {
  ESP_LOGI(TAG, "Setting SPI MAC %s", mac);
  uint8_t res = ESP_AT_RESULT_CODE_OK;
  uint8_t mac_bytes[6] = {0, 0, 0, 0, 0, 0};

  int success_parsed_vbles =
      sscanf((const char *)mac, "%02X:%02X:%02X:%02X:%02X:%02X", &mac_bytes[0],
             &mac_bytes[1], &mac_bytes[2], &mac_bytes[3], &mac_bytes[4],
             &mac_bytes[5]);
  ESP_LOGI(TAG, "Parsed %d variables: %02X:%02X:%02X:%02X:%02X:%02X",
           success_parsed_vbles, mac_bytes[0], mac_bytes[1], mac_bytes[2],
           mac_bytes[3], mac_bytes[4], mac_bytes[5]);

  if (success_parsed_vbles != 6) {
    ESP_LOGE(TAG, "Error scanning MAC");
    res = ESP_AT_RESULT_CODE_FAIL;
    return res;
  }

  esp_netif_t *eth_netif = get_spi_eth_netif(0);
  ESP_ERROR_CHECK(esp_netif_set_mac(eth_netif, mac_bytes));

  return ESP_AT_RESULT_CODE_OK;
}

uint8_t get_ip_spi_eth() {
  uint8_t ip_addr[4] = {0};
  esp_netif_ip_info_t ip_info;
  esp_netif_t *eth_netif = get_spi_eth_netif(0);

  ESP_ERROR_CHECK(esp_netif_get_ip_info(eth_netif, &ip_info));

  char *ip = ip4addr_ntoa(&ip_info.ip);
  ESP_LOGI(TAG, "IP: %s", ip);
  char text[64] = {0};
  snprintf(text, sizeof(text), "+IP:%s\r\n", ip);
  esp_at_port_write_data((uint8_t *)text, sizeof(text));

  return ESP_AT_RESULT_CODE_OK;
}

uint8_t set_ip_spi_eth(const uint8_t *ip) {
  uint8_t res = ESP_AT_RESULT_CODE_OK;

  uint8_t ip_bytes[4] = {0, 0, 0, 0};
  ip4_addr_t toCheck;

  int success_parsed_vbles =
      sscanf((const char *)ip, "%u.%u.%u.%u", &ip_bytes[0], &ip_bytes[1],
             &ip_bytes[2], &ip_bytes[3]);
  ESP_LOGI(TAG, "Parsed %d variables: %u.%u.%u.%u", success_parsed_vbles,
           ip_bytes[0], ip_bytes[1], ip_bytes[2], ip_bytes[3]);
  if (success_parsed_vbles != 4) {
    ESP_LOGE(TAG, "Error scanning IP");
    res = ESP_AT_RESULT_CODE_FAIL;
    return res;
  }

  esp_netif_t *eth_netif = get_spi_eth_netif(0);
  esp_netif_ip_info_t ip_info;
  ESP_ERROR_CHECK(esp_netif_dhcpc_stop(eth_netif)); // Stop DHCP client

  // Set static IP
  IP4_ADDR(&ip_info.ip, ip_bytes[0], ip_bytes[1], ip_bytes[2], ip_bytes[3]);
  IP4_ADDR(&ip_info.gw, ip_bytes[0], ip_bytes[1], ip_bytes[2], 1);
  IP4_ADDR(&ip_info.netmask, 255, 255, 255, 0);

  ESP_ERROR_CHECK(esp_netif_set_ip_info(eth_netif, &ip_info));

  return ESP_AT_RESULT_CODE_OK;
}