Created
September 23, 2021 15:47
-
-
Save david-cermak/87462309176722d6051ac2bd56e5d32b to your computer and use it in GitHub Desktop.
eth_w5500_power_cycle_4.3.1.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string.h> | |
#include "sys/socket.h" | |
#include "freertos/FreeRTOS.h" | |
#include "freertos/event_groups.h" | |
#include "freertos/task.h" | |
#include "esp_netif.h" | |
#include "esp_eth.h" | |
#include "esp_event.h" | |
#include "esp_log.h" | |
#include "sdkconfig.h" | |
#include "driver/spi_master.h" | |
#include "driver/gpio.h" | |
#define PC_ADDR "...." | |
static const char *TAG = "eth_example"; | |
esp_netif_t *eth_netif; | |
static EventGroupHandle_t event_group = NULL; | |
static const int CONNECT_BIT = BIT0; | |
/** Event handler for Ethernet events */ | |
static void eth_event_handler(void *arg, esp_event_base_t event_base, | |
int32_t event_id, void *event_data) | |
{ | |
uint8_t mac_addr[6] = {0}; | |
/* we can get the ethernet driver handle from event data */ | |
esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data; | |
switch (event_id) { | |
case ETHERNET_EVENT_CONNECTED: | |
esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr); | |
ESP_LOGI(TAG, "Ethernet Link Up"); | |
ESP_LOGI(TAG, "Ethernet HW Addr %02x:%02x:%02x:%02x:%02x:%02x", | |
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); | |
break; | |
case ETHERNET_EVENT_DISCONNECTED: | |
ESP_LOGI(TAG, "Ethernet Link Down"); | |
break; | |
case ETHERNET_EVENT_START: | |
ESP_LOGI(TAG, "Ethernet Started"); | |
break; | |
case ETHERNET_EVENT_STOP: | |
ESP_LOGI(TAG, "Ethernet Stopped"); | |
break; | |
default: | |
break; | |
} | |
} | |
static void on_got_ipv6(void *arg, esp_event_base_t event_base, | |
int32_t event_id, void *event_data) | |
{ | |
ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; | |
esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); | |
ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %d", esp_netif_get_desc(event->esp_netif), | |
IPV62STR(event->ip6_info.ip), ipv6_type); | |
xEventGroupSetBits(event_group, CONNECT_BIT); | |
} | |
/** Event handler for IP_EVENT_ETH_GOT_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; | |
const esp_netif_ip_info_t *ip_info = &event->ip_info; | |
ESP_LOGI(TAG, "Ethernet Got IP Address"); | |
ESP_LOGI(TAG, "~~~~~~~~~~~"); | |
ESP_LOGI(TAG, "ETHIP:" IPSTR, IP2STR(&ip_info->ip)); | |
ESP_LOGI(TAG, "ETHMASK:" IPSTR, IP2STR(&ip_info->netmask)); | |
ESP_LOGI(TAG, "ETHGW:" IPSTR, IP2STR(&ip_info->gw)); | |
ESP_LOGI(TAG, "~~~~~~~~~~~"); | |
esp_netif_create_ip6_linklocal(eth_netif); | |
} | |
static void send_udp() | |
{ | |
char rx_buffer[128]; | |
char host_ip[] = PC_ADDR; | |
struct sockaddr_in6 dest_addr = { 0 }; | |
inet6_aton(host_ip, &dest_addr.sin6_addr); | |
dest_addr.sin6_family = AF_INET6; | |
dest_addr.sin6_port = htons(3333); | |
dest_addr.sin6_scope_id = esp_netif_get_netif_impl_index(eth_netif); | |
int sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IPV6); | |
if (sock < 0) { | |
ESP_LOGE(TAG, "Unable to create socket: errno %d", errno); | |
abort(); | |
} | |
ESP_LOGI(TAG, "Sending data to %s", host_ip); | |
while (sendto(sock, "Command", 7, 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) < 0) { | |
ESP_LOGE(TAG, "Error occurred during sending: errno %d, retrying...", errno); | |
} | |
ESP_LOGI(TAG, "Message sent"); | |
struct sockaddr_storage source_addr; // Large enough for both IPv4 or IPv6 | |
socklen_t socklen = sizeof(source_addr); | |
int len = recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&source_addr, &socklen); | |
if (len < 0) { | |
ESP_LOGE(TAG, "recvfrom failed: errno %d", errno); | |
abort(); | |
} else { | |
rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string | |
ESP_LOGI(TAG, "Received %d bytes from %s:", len, host_ip); | |
ESP_LOGI(TAG, "%s", rx_buffer); | |
if (strncmp(rx_buffer, "OK: ", 4) == 0) { | |
ESP_LOGI(TAG, "Received OK"); | |
} | |
} | |
ESP_LOGI(TAG, "Shutting down the socket..."); | |
shutdown(sock, 0); | |
close(sock); | |
} | |
void app_main(void) { | |
ESP_ERROR_CHECK(esp_netif_init()); | |
ESP_ERROR_CHECK(esp_event_loop_create_default()); | |
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH(); | |
gpio_config_t io_conf = {0}; | |
io_conf.intr_type = GPIO_INTR_DISABLE; | |
io_conf.pin_bit_mask = BIT64(3); | |
io_conf.mode = GPIO_MODE_OUTPUT; | |
io_conf.pull_up_en = 0; | |
io_conf.pull_down_en = 0; | |
gpio_config(&io_conf); | |
event_group = xEventGroupCreate(); | |
gpio_install_isr_service(0); | |
spi_device_handle_t spi_handle = NULL; | |
spi_bus_config_t buscfg = { | |
.miso_io_num = CONFIG_EXAMPLE_ETH_SPI_MISO_GPIO, | |
.mosi_io_num = CONFIG_EXAMPLE_ETH_SPI_MOSI_GPIO, | |
.sclk_io_num = CONFIG_EXAMPLE_ETH_SPI_SCLK_GPIO, | |
.quadwp_io_num = -1, | |
.quadhd_io_num = -1, | |
}; | |
ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, 1)); | |
spi_device_interface_config_t devcfg = { | |
.command_bits = 16, // Actually it's the address phase in W5500 SPI frame | |
.address_bits = 8, // Actually it's the control phase in W5500 SPI frame | |
.mode = 0, | |
.clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000, | |
.spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO, | |
.queue_size = 20 | |
}; | |
ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle)); | |
eth_netif = esp_netif_new(&cfg); | |
// Register user defined event handers | |
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, NULL)); | |
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL)); | |
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL)); | |
while (1) { | |
gpio_set_level(3, 0); | |
vTaskDelay(pdMS_TO_TICKS(1000)); | |
ESP_ERROR_CHECK(esp_eth_set_default_handlers(eth_netif)); | |
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); | |
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); | |
phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR; | |
phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO; | |
/* w5500 ethernet driver is based on spi driver */ | |
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(spi_handle); | |
w5500_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO; | |
esp_eth_mac_t *mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config); | |
esp_eth_phy_t *phy = esp_eth_phy_new_w5500(&phy_config); | |
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy); | |
config.check_link_period_ms = 10; | |
esp_eth_handle_t eth_handle = NULL; | |
ESP_ERROR_CHECK(esp_eth_driver_install(&config, ð_handle)); | |
ESP_ERROR_CHECK(esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, (uint8_t[]) { | |
0x02, 0x00, 0x00, 0x12, 0x34, 0x56 | |
})); | |
/* attach Ethernet driver to TCP/IP stack */ | |
void *glue = esp_eth_new_netif_glue(eth_handle); | |
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, glue)); | |
ESP_ERROR_CHECK(esp_eth_start(eth_handle)); | |
// wait for the IPv6 and send something | |
xEventGroupWaitBits(event_group, CONNECT_BIT, true, true, portMAX_DELAY); | |
send_udp(); | |
vTaskDelay(pdMS_TO_TICKS(1000)); | |
ESP_LOGI(TAG, "\nTurning OFF!!!\n"); | |
ESP_ERROR_CHECK(esp_eth_stop(eth_handle)); | |
ESP_ERROR_CHECK(esp_eth_del_netif_glue(glue)); | |
ESP_ERROR_CHECK(esp_eth_clear_default_handlers(eth_netif)); | |
ESP_ERROR_CHECK(esp_eth_driver_uninstall(eth_handle)); | |
ESP_ERROR_CHECK(phy->del(phy)); | |
ESP_ERROR_CHECK(mac->del(mac)); | |
gpio_set_level(3, 1); | |
vTaskDelay(pdMS_TO_TICKS(10000)); | |
ESP_LOGI(TAG, "\nTurning ON\n"); | |
} | |
esp_netif_destroy(eth_netif); | |
vEventGroupDelete(event_group); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment