3#if defined(USE_ESP32) && defined(USE_ETHERNET_W5500)
5#include <driver/spi_master.h>
6#include <freertos/FreeRTOS.h>
7#include <freertos/semphr.h>
18struct W5500CustomSpiContext {
23W5500CustomSpiContext w5500_context{};
27constexpr uint32_t W5500_SPI_BULK_THRESHOLD = 64;
28constexpr uint32_t W5500_SPI_LOCK_TIMEOUT_MS = 50;
30void *w5500_custom_spi_init(
const void *spi_config) {
31 const auto *config =
static_cast<const eth_w5500_config_t *
>(spi_config);
32 auto *ctx = &w5500_context;
35 spi_device_interface_config_t devcfg = *config->spi_devcfg;
36 devcfg.command_bits = 16;
37 devcfg.address_bits = 8;
38 if (spi_bus_add_device(config->spi_host_id, &devcfg, &ctx->handle) != ESP_OK) {
39 ctx->handle =
nullptr;
42 ctx->lock = xSemaphoreCreateMutex();
43 if (ctx->lock ==
nullptr) {
44 spi_bus_remove_device(ctx->handle);
45 ctx->handle =
nullptr;
51esp_err_t w5500_custom_spi_deinit(
void *spi_ctx) {
52 auto *ctx =
static_cast<W5500CustomSpiContext *
>(spi_ctx);
53 spi_bus_remove_device(ctx->handle);
54 vSemaphoreDelete(ctx->lock);
62esp_err_t w5500_custom_spi_transfer(W5500CustomSpiContext *ctx, spi_transaction_t *trans,
uint32_t len) {
63 if (xSemaphoreTake(ctx->lock, pdMS_TO_TICKS(W5500_SPI_LOCK_TIMEOUT_MS)) != pdTRUE) {
64 return ESP_ERR_TIMEOUT;
67 if (
len > W5500_SPI_BULK_THRESHOLD) {
68 ret = spi_device_transmit(ctx->handle, trans);
70 ret = spi_device_polling_transmit(ctx->handle, trans);
72 xSemaphoreGive(ctx->lock);
77 auto *ctx =
static_cast<W5500CustomSpiContext *
>(spi_ctx);
78 spi_transaction_t trans = {};
79 trans.cmd =
static_cast<uint16_t
>(cmd);
81 trans.length = 8 *
len;
82 trans.tx_buffer =
data;
83 return w5500_custom_spi_transfer(ctx, &trans,
len);
87 auto *ctx =
static_cast<W5500CustomSpiContext *
>(spi_ctx);
88 spi_transaction_t trans = {};
91 const bool use_rxdata =
len <= 4;
92 trans.flags = use_rxdata ? SPI_TRANS_USE_RXDATA : 0;
93 trans.cmd =
static_cast<uint16_t
>(cmd);
95 trans.length = 8 *
len;
96 trans.rx_buffer =
data;
97 esp_err_t
ret = w5500_custom_spi_transfer(ctx, &trans,
len);
98 if (use_rxdata && (
ret == ESP_OK)) {
99 memcpy(data, trans.rx_data,
len);
110 config.custom_spi_driver.config = &config;
111 config.custom_spi_driver.init = w5500_custom_spi_init;
112 config.custom_spi_driver.deinit = w5500_custom_spi_deinit;
113 config.custom_spi_driver.read = w5500_custom_spi_read;
114 config.custom_spi_driver.write = w5500_custom_spi_write;
void install_w5500_async_spi(eth_w5500_config_t &config)
std::span< const uint8_t > data
spi_device_handle_t handle