mirror of https://github.com/lumapu/ahoy.git
				
				
			
				 10 changed files with 557 additions and 51 deletions
			
			
		| @ -0,0 +1,141 @@ | |||||
|  | //-----------------------------------------------------------------------------
 | ||||
|  | // 2023 Ahoy, https://www.mikrocontroller.net/topic/525778
 | ||||
|  | // Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
 | ||||
|  | //-----------------------------------------------------------------------------
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | #if defined(CONFIG_IDF_TARGET_ESP32S3) | ||||
|  | #if defined(ETHERNET) | ||||
|  | #ifndef __ETH_SPI_H__ | ||||
|  | #define __ETH_SPI_H__ | ||||
|  | 
 | ||||
|  | #pragma once | ||||
|  | 
 | ||||
|  | #include <Arduino.h> | ||||
|  | #include <esp_netif.h> | ||||
|  | #include <WiFiGeneric.h> | ||||
|  | #include <driver/spi_master.h> | ||||
|  | 
 | ||||
|  | // Functions from WiFiGeneric
 | ||||
|  | void tcpipInit(); | ||||
|  | void add_esp_interface_netif(esp_interface_t interface, esp_netif_t* esp_netif); | ||||
|  | 
 | ||||
|  | class EthSpi { | ||||
|  |     public: | ||||
|  | 
 | ||||
|  |         EthSpi() : | ||||
|  |             eth_handle(nullptr), | ||||
|  |             eth_netif(nullptr) {} | ||||
|  | 
 | ||||
|  |         void begin(int8_t pin_miso, int8_t pin_mosi, int8_t pin_sclk, int8_t pin_cs, int8_t pin_int, int8_t pin_rst) { | ||||
|  |             gpio_reset_pin(static_cast<gpio_num_t>(pin_rst)); | ||||
|  |             gpio_set_direction(static_cast<gpio_num_t>(pin_rst), GPIO_MODE_OUTPUT); | ||||
|  |             gpio_set_level(static_cast<gpio_num_t>(pin_rst), 0); | ||||
|  | 
 | ||||
|  |             gpio_reset_pin(static_cast<gpio_num_t>(pin_sclk)); | ||||
|  |             gpio_reset_pin(static_cast<gpio_num_t>(pin_mosi)); | ||||
|  |             gpio_reset_pin(static_cast<gpio_num_t>(pin_miso)); | ||||
|  |             gpio_reset_pin(static_cast<gpio_num_t>(pin_cs)); | ||||
|  |             gpio_set_pull_mode(static_cast<gpio_num_t>(pin_miso), GPIO_PULLUP_ONLY); | ||||
|  | 
 | ||||
|  |             // Workaround, because calling gpio_install_isr_service directly causes issues with attachInterrupt later
 | ||||
|  |             attachInterrupt(digitalPinToInterrupt(pin_int), nullptr, CHANGE); | ||||
|  |             detachInterrupt(digitalPinToInterrupt(pin_int)); | ||||
|  |             gpio_reset_pin(static_cast<gpio_num_t>(pin_int)); | ||||
|  |             gpio_set_pull_mode(static_cast<gpio_num_t>(pin_int), GPIO_PULLUP_ONLY); | ||||
|  | 
 | ||||
|  |             spi_bus_config_t buscfg = { | ||||
|  |                 .mosi_io_num = pin_mosi, | ||||
|  |                 .miso_io_num = pin_miso, | ||||
|  |                 .sclk_io_num = pin_sclk, | ||||
|  |                 .quadwp_io_num = -1, | ||||
|  |                 .quadhd_io_num = -1, | ||||
|  |                 .data4_io_num = -1, | ||||
|  |                 .data5_io_num = -1, | ||||
|  |                 .data6_io_num = -1, | ||||
|  |                 .data7_io_num = -1, | ||||
|  |                 .max_transfer_sz = 0, // uses default value internally
 | ||||
|  |                 .flags = 0, | ||||
|  |                 .intr_flags = 0 | ||||
|  |             }; | ||||
|  | 
 | ||||
|  |             ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &buscfg, SPI_DMA_CH_AUTO)); | ||||
|  | 
 | ||||
|  |             spi_device_interface_config_t devcfg = { | ||||
|  |                 .command_bits = 16, // actually address phase
 | ||||
|  |                 .address_bits = 8, // actually command phase
 | ||||
|  |                 .dummy_bits = 0, | ||||
|  |                 .mode = 0, | ||||
|  |                 .duty_cycle_pos = 0, | ||||
|  |                 .cs_ena_pretrans = 0, // only 0 supported
 | ||||
|  |                 .cs_ena_posttrans = 0, // only 0 supported
 | ||||
|  |                 .clock_speed_hz = 20000000, // stable with on OpenDTU Fusion Shield
 | ||||
|  |                 .input_delay_ns = 0, | ||||
|  |                 .spics_io_num = pin_cs, | ||||
|  |                 .flags = 0, | ||||
|  |                 .queue_size = 20, | ||||
|  |                 .pre_cb = nullptr, | ||||
|  |                 .post_cb = nullptr | ||||
|  |             }; | ||||
|  | 
 | ||||
|  |             spi_device_handle_t spi; | ||||
|  |             ESP_ERROR_CHECK(spi_bus_add_device(SPI3_HOST, &devcfg, &spi)); | ||||
|  | 
 | ||||
|  |             // Reset sequence
 | ||||
|  |             delayMicroseconds(500); | ||||
|  |             gpio_set_level(static_cast<gpio_num_t>(pin_rst), 1); | ||||
|  |             delayMicroseconds(1000); | ||||
|  | 
 | ||||
|  |             // Arduino function to start networking stack if not already started
 | ||||
|  |             tcpipInit(); | ||||
|  | 
 | ||||
|  |             ESP_ERROR_CHECK(tcpip_adapter_set_default_eth_handlers()); // ?
 | ||||
|  | 
 | ||||
|  |             eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(spi); | ||||
|  |             w5500_config.int_gpio_num = pin_int; | ||||
|  | 
 | ||||
|  |             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_w5500(&w5500_config, &mac_config); | ||||
|  | 
 | ||||
|  |             eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); | ||||
|  |             phy_config.reset_gpio_num = -1; | ||||
|  |             esp_eth_phy_t *phy = esp_eth_phy_new_w5500(&phy_config); | ||||
|  | 
 | ||||
|  |             esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy); | ||||
|  |             ESP_ERROR_CHECK(esp_eth_driver_install(ð_config, ð_handle)); | ||||
|  | 
 | ||||
|  |             // Configure MAC address
 | ||||
|  |             uint8_t mac_addr[6]; | ||||
|  |             ESP_ERROR_CHECK(esp_efuse_mac_get_default(mac_addr)); | ||||
|  |             mac_addr[5] |= 0x03; // derive ethernet MAC address from base MAC address
 | ||||
|  |             ESP_ERROR_CHECK(esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, mac_addr)); | ||||
|  | 
 | ||||
|  |             esp_netif_config_t netif_config = ESP_NETIF_DEFAULT_ETH(); | ||||
|  |             eth_netif = esp_netif_new(&netif_config); | ||||
|  | 
 | ||||
|  |             ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle))); | ||||
|  | 
 | ||||
|  |             // Add to Arduino
 | ||||
|  |             add_esp_interface_netif(ESP_IF_ETH, eth_netif); | ||||
|  | 
 | ||||
|  |             ESP_ERROR_CHECK(esp_eth_start(eth_handle)); | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         String macAddress() { | ||||
|  |             uint8_t mac_addr[6] = {0, 0, 0, 0, 0, 0}; | ||||
|  |             esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr); | ||||
|  |             char mac_addr_str[24]; | ||||
|  |             snprintf(mac_addr_str, sizeof(mac_addr_str), "%02X:%02X:%02X:%02X:%02X:%02X", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); | ||||
|  |             return String(mac_addr_str); | ||||
|  |         } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  |     private: | ||||
|  |         esp_eth_handle_t eth_handle; | ||||
|  |         esp_netif_t *eth_netif; | ||||
|  | }; | ||||
|  | 
 | ||||
|  | #endif /*__ETH_SPI_H__*/ | ||||
|  | #endif /*ETHERNET*/ | ||||
|  | #endif /*CONFIG_IDF_TARGET_ESP32S3*/ | ||||
| @ -0,0 +1,241 @@ | |||||
|  | //-----------------------------------------------------------------------------
 | ||||
|  | // 2023 Ahoy, https://www.mikrocontroller.net/topic/525778
 | ||||
|  | // Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
 | ||||
|  | //-----------------------------------------------------------------------------
 | ||||
|  | 
 | ||||
|  | #ifndef __NRF_HAL_H__ | ||||
|  | #define __NRF_HAL_H__ | ||||
|  | 
 | ||||
|  | #pragma once | ||||
|  | 
 | ||||
|  | #include "spiPatcher.h" | ||||
|  | 
 | ||||
|  | #include <esp_rom_gpio.h> | ||||
|  | #include <RF24_hal.h> | ||||
|  | 
 | ||||
|  | #define NRF_MAX_TRANSFER_SZ 64 | ||||
|  | #define NRF_DEFAULT_SPI_SPEED 10000000 // 10 MHz
 | ||||
|  | 
 | ||||
|  | class nrfHal: public RF24_hal, public SpiPatcherHandle { | ||||
|  |     public: | ||||
|  |         nrfHal() : mSpiPatcher(SPI2_HOST) {} | ||||
|  | 
 | ||||
|  |         void patch() override { | ||||
|  |             esp_rom_gpio_connect_out_signal(mPinMosi, spi_periph_signal[host_device].spid_out, false, false); | ||||
|  |             esp_rom_gpio_connect_in_signal(mPinMiso, spi_periph_signal[host_device].spiq_in, false); | ||||
|  |             esp_rom_gpio_connect_out_signal(mPinClk, spi_periph_signal[host_device].spiclk_out, false, false); | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         void unpatch() override { | ||||
|  |             esp_rom_gpio_connect_out_signal(mPinMosi, SIG_GPIO_OUT_IDX, false, false); | ||||
|  |             esp_rom_gpio_connect_in_signal(mPinMiso, GPIO_MATRIX_CONST_ZERO_INPUT, false); | ||||
|  |             esp_rom_gpio_connect_out_signal(mPinClk, SIG_GPIO_OUT_IDX, false, false); | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         void init(int8_t mosi, int8_t miso, int8_t sclk, int8_t cs, int8_t en, int32_t speed = 0) { | ||||
|  |             DHEX(mosi); | ||||
|  |             DBGPRINT(" "); | ||||
|  |             DHEX(miso); | ||||
|  |             DBGPRINT(" "); | ||||
|  |             DHEX(sclk); | ||||
|  |             DBGPRINT(" "); | ||||
|  |             DHEX(cs); | ||||
|  |             DBGPRINT(" "); | ||||
|  |             DHEX(en); | ||||
|  |             DBGPRINTLN(" "); | ||||
|  |             delay(300); | ||||
|  |             mPinMosi = static_cast<>(mosi); | ||||
|  |             DBGPRINTLN("21"); | ||||
|  |             delay(300); | ||||
|  |             mPinMiso = static_cast<gpio_num_t>(miso); | ||||
|  |             DBGPRINTLN("22"); | ||||
|  |             delay(300); | ||||
|  |             mPinClk = static_cast<gpio_num_t>(sclk); | ||||
|  |             DBGPRINTLN("23"); | ||||
|  |             delay(300); | ||||
|  |             mPinCs = static_cast<gpio_num_t>(cs); | ||||
|  |             DBGPRINTLN("24"); | ||||
|  |             delay(300); | ||||
|  |             mPinEn = static_cast<gpio_num_t>(en); | ||||
|  |             DBGPRINTLN("25"); | ||||
|  |             delay(300); | ||||
|  |             mSpiSpeed = speed; | ||||
|  | 
 | ||||
|  |             DBGPRINTLN("3"); | ||||
|  |             delay(300); | ||||
|  |             host_device = mSpiPatcher.init(); | ||||
|  |             DBGPRINTLN("4"); | ||||
|  |             delay(300); | ||||
|  | 
 | ||||
|  |             gpio_reset_pin(mPinMosi); | ||||
|  |             gpio_set_direction(mPinMosi, GPIO_MODE_OUTPUT); | ||||
|  |             gpio_set_level(mPinMosi, 1); | ||||
|  | 
 | ||||
|  |             gpio_reset_pin(mPinMiso); | ||||
|  |             gpio_set_direction(mPinMiso, GPIO_MODE_INPUT); | ||||
|  | 
 | ||||
|  |             gpio_reset_pin(mPinClk); | ||||
|  |             gpio_set_direction(mPinClk, GPIO_MODE_OUTPUT); | ||||
|  |             gpio_set_level(mPinClk, 0); | ||||
|  | 
 | ||||
|  |             gpio_reset_pin(mPinCs); | ||||
|  |             spi_device_interface_config_t devcfg = { | ||||
|  |                 .command_bits = 0, | ||||
|  |                 .address_bits = 0, | ||||
|  |                 .dummy_bits = 0, | ||||
|  |                 .mode = 0, | ||||
|  |                 .duty_cycle_pos = 0, | ||||
|  |                 .cs_ena_pretrans = 0, | ||||
|  |                 .cs_ena_posttrans = 0, | ||||
|  |                 .clock_speed_hz = mSpiSpeed, | ||||
|  |                 .input_delay_ns = 0, | ||||
|  |                 .spics_io_num = mPinCs, | ||||
|  |                 .flags = 0, | ||||
|  |                 .queue_size = 1, | ||||
|  |                 .pre_cb = nullptr, | ||||
|  |                 .post_cb = nullptr | ||||
|  |             }; | ||||
|  |             ESP_ERROR_CHECK(spi_bus_add_device(host_device, &devcfg, &spi)); | ||||
|  | 
 | ||||
|  |             gpio_reset_pin(mPinEn); | ||||
|  |             gpio_set_direction(mPinEn, GPIO_MODE_OUTPUT); | ||||
|  |             gpio_set_level(mPinEn, 0); | ||||
|  |         } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  |         bool begin() override { | ||||
|  |             return true; | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         void end() override {} | ||||
|  | 
 | ||||
|  |         void ce(bool level) override { | ||||
|  |             gpio_set_level(mPinEn, level); | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         uint8_t write(uint8_t cmd, const uint8_t* buf, uint8_t len) override { | ||||
|  |             uint8_t data[NRF_MAX_TRANSFER_SZ]; | ||||
|  |             data[0] = cmd; | ||||
|  |             std::copy(&buf[0], &buf[len], &data[1]); | ||||
|  | 
 | ||||
|  |             request_spi(); | ||||
|  | 
 | ||||
|  |             size_t spiLen = (static_cast<size_t>(len) + 1u) << 3; | ||||
|  |             spi_transaction_t t = { | ||||
|  |                 .flags = 0, | ||||
|  |                 .cmd = 0, | ||||
|  |                 .addr = 0, | ||||
|  |                 .length = spiLen, | ||||
|  |                 .rxlength = spiLen, | ||||
|  |                 .user = NULL, | ||||
|  |                 .tx_buffer = data, | ||||
|  |                 .rx_buffer = data | ||||
|  |             }; | ||||
|  |             ESP_ERROR_CHECK(spi_device_polling_transmit(spi, &t)); | ||||
|  | 
 | ||||
|  |             release_spi(); | ||||
|  | 
 | ||||
|  |             return data[0]; // status
 | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         uint8_t write(uint8_t cmd, const uint8_t* buf, uint8_t data_len, uint8_t blank_len) override { | ||||
|  |             uint8_t data[NRF_MAX_TRANSFER_SZ]; | ||||
|  |             data[0] = cmd; | ||||
|  |             memset(data, 0, NRF_MAX_TRANSFER_SZ); | ||||
|  |             std::copy(&buf[0], &buf[data_len], &data[1]); | ||||
|  | 
 | ||||
|  |             request_spi(); | ||||
|  | 
 | ||||
|  |             size_t spiLen = (static_cast<size_t>(data_len) + static_cast<size_t>(blank_len) + 1u) << 3; | ||||
|  |             spi_transaction_t t = { | ||||
|  |                 .flags = 0, | ||||
|  |                 .cmd = 0, | ||||
|  |                 .addr = 0, | ||||
|  |                 .length = spiLen, | ||||
|  |                 .rxlength = spiLen, | ||||
|  |                 .user = NULL, | ||||
|  |                 .tx_buffer = data, | ||||
|  |                 .rx_buffer = data | ||||
|  |             }; | ||||
|  |             ESP_ERROR_CHECK(spi_device_polling_transmit(spi, &t)); | ||||
|  | 
 | ||||
|  |             release_spi(); | ||||
|  | 
 | ||||
|  |             return data[0]; // status
 | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         uint8_t read(uint8_t cmd, uint8_t* buf, uint8_t len) override { | ||||
|  |             uint8_t data[NRF_MAX_TRANSFER_SZ]; | ||||
|  |             data[0] = cmd; | ||||
|  |             memset(&data[1], 0xff, len); | ||||
|  | 
 | ||||
|  |             request_spi(); | ||||
|  | 
 | ||||
|  |             size_t spiLen = (static_cast<size_t>(len) + 1u) << 3; | ||||
|  |             spi_transaction_t t = { | ||||
|  |                 .flags = 0, | ||||
|  |                 .cmd = 0, | ||||
|  |                 .addr = 0, | ||||
|  |                 .length = spiLen, | ||||
|  |                 .rxlength = spiLen, | ||||
|  |                 .user = NULL, | ||||
|  |                 .tx_buffer = data, | ||||
|  |                 .rx_buffer = data | ||||
|  |             }; | ||||
|  |             ESP_ERROR_CHECK(spi_device_polling_transmit(spi, &t)); | ||||
|  | 
 | ||||
|  |             release_spi(); | ||||
|  | 
 | ||||
|  |             std::copy(&data[1], &data[len+1], buf); | ||||
|  |             return data[0]; // status
 | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         uint8_t read(uint8_t cmd, uint8_t* buf, uint8_t data_len, uint8_t blank_len) override { | ||||
|  |             uint8_t data[NRF_MAX_TRANSFER_SZ]; | ||||
|  |             data[0] = cmd; | ||||
|  |             memset(&data[1], 0xff, (data_len + blank_len)); | ||||
|  | 
 | ||||
|  |             request_spi(); | ||||
|  | 
 | ||||
|  |             size_t spiLen = (static_cast<size_t>(data_len) + static_cast<size_t>(blank_len) + 1u) << 3; | ||||
|  |             spi_transaction_t t = { | ||||
|  |                 .flags = 0, | ||||
|  |                 .cmd = 0, | ||||
|  |                 .addr = 0, | ||||
|  |                 .length = spiLen, | ||||
|  |                 .rxlength = spiLen, | ||||
|  |                 .user = NULL, | ||||
|  |                 .tx_buffer = data, | ||||
|  |                 .rx_buffer = data | ||||
|  |             }; | ||||
|  |             ESP_ERROR_CHECK(spi_device_polling_transmit(spi, &t)); | ||||
|  | 
 | ||||
|  |             release_spi(); | ||||
|  | 
 | ||||
|  |             std::copy(&data[1], &data[data_len+1], buf); | ||||
|  |             return data[0]; // status
 | ||||
|  |         } | ||||
|  | 
 | ||||
|  |     private: | ||||
|  |         inline void request_spi() { | ||||
|  |             mSpiPatcher.request(this); | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         inline void release_spi() { | ||||
|  |             mSpiPatcher.release(); | ||||
|  |         } | ||||
|  | 
 | ||||
|  |     private: | ||||
|  |         gpio_num_t mPinMosi = GPIO_NUM_NC; | ||||
|  |         gpio_num_t mPinMiso = GPIO_NUM_NC; | ||||
|  |         gpio_num_t mPinClk = GPIO_NUM_NC; | ||||
|  |         gpio_num_t mPinCs = GPIO_NUM_NC; | ||||
|  |         gpio_num_t mPinEn = GPIO_NUM_NC; | ||||
|  |         int32_t mSpiSpeed = NRF_DEFAULT_SPI_SPEED; | ||||
|  | 
 | ||||
|  |         spi_host_device_t host_device; | ||||
|  |         spi_device_handle_t spi; | ||||
|  |         SpiPatcher mSpiPatcher; | ||||
|  | }; | ||||
|  | 
 | ||||
|  | #endif /*__NRF_HAL_H__*/ | ||||
| @ -0,0 +1,78 @@ | |||||
|  | //-----------------------------------------------------------------------------
 | ||||
|  | // 2023 Ahoy, https://www.mikrocontroller.net/topic/525778
 | ||||
|  | // Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
 | ||||
|  | //-----------------------------------------------------------------------------
 | ||||
|  | 
 | ||||
|  | #ifndef __SPI_PATCHER_H__ | ||||
|  | #define __SPI_PATCHER_H__ | ||||
|  | #pragma once | ||||
|  | 
 | ||||
|  | #include "spiPatcherHandle.h" | ||||
|  | 
 | ||||
|  | #include <driver/spi_master.h> | ||||
|  | #include <freertos/semphr.h> | ||||
|  | 
 | ||||
|  | class SpiPatcher { | ||||
|  |     public: | ||||
|  |         explicit SpiPatcher(spi_host_device_t host_device) : | ||||
|  |             host_device(host_device), initialized(false), cur_handle(nullptr) { | ||||
|  |             // Use binary semaphore instead of mutex for performance reasons
 | ||||
|  |             mutex = xSemaphoreCreateBinaryStatic(&mutex_buffer); | ||||
|  |             xSemaphoreGive(mutex); | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         ~SpiPatcher() { vSemaphoreDelete(mutex); } | ||||
|  | 
 | ||||
|  |         spi_host_device_t init() { | ||||
|  |             if (!initialized) { | ||||
|  |                 initialized = true; | ||||
|  | 
 | ||||
|  |                 spi_bus_config_t buscfg = { | ||||
|  |                     .mosi_io_num = -1, | ||||
|  |                     .miso_io_num = -1, | ||||
|  |                     .sclk_io_num = -1, | ||||
|  |                     .quadwp_io_num = -1, | ||||
|  |                     .quadhd_io_num = -1, | ||||
|  |                     .data4_io_num = -1, | ||||
|  |                     .data5_io_num = -1, | ||||
|  |                     .data6_io_num = -1, | ||||
|  |                     .data7_io_num = -1, | ||||
|  |                     .max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE, | ||||
|  |                     .flags = 0, | ||||
|  |                     .intr_flags = 0 | ||||
|  |                 }; | ||||
|  |                 ESP_ERROR_CHECK(spi_bus_initialize(host_device, &buscfg, SPI_DMA_DISABLED)); | ||||
|  |             } | ||||
|  | 
 | ||||
|  |             return host_device; | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         inline void request(SpiPatcherHandle* handle) { | ||||
|  |             xSemaphoreTake(mutex, portMAX_DELAY); | ||||
|  | 
 | ||||
|  |             if (cur_handle != handle) { | ||||
|  |                 if (cur_handle) { | ||||
|  |                     cur_handle->unpatch(); | ||||
|  |                 } | ||||
|  |                 cur_handle = handle; | ||||
|  |                 if (cur_handle) { | ||||
|  |                     cur_handle->patch(); | ||||
|  |                 } | ||||
|  |             } | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         inline void release() { | ||||
|  |             xSemaphoreGive(mutex); | ||||
|  |         } | ||||
|  | 
 | ||||
|  |     private: | ||||
|  |         const spi_host_device_t host_device; | ||||
|  |         bool initialized; | ||||
|  | 
 | ||||
|  |         SpiPatcherHandle* cur_handle; | ||||
|  | 
 | ||||
|  |         SemaphoreHandle_t mutex; | ||||
|  |         StaticSemaphore_t mutex_buffer; | ||||
|  | }; | ||||
|  | 
 | ||||
|  | #endif /*__SPI_PATCHER_H__*/ | ||||
| @ -0,0 +1,17 @@ | |||||
|  | //-----------------------------------------------------------------------------
 | ||||
|  | // 2023 Ahoy, https://www.mikrocontroller.net/topic/525778
 | ||||
|  | // Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
 | ||||
|  | //-----------------------------------------------------------------------------
 | ||||
|  | 
 | ||||
|  | #ifndef __SPI_PATCHER_HANDLE_H__ | ||||
|  | #define __SPI_PATCHER_HANDLE_H__ | ||||
|  | #pragma once | ||||
|  | 
 | ||||
|  | class SpiPatcherHandle { | ||||
|  |     public: | ||||
|  |         virtual ~SpiPatcherHandle() {} | ||||
|  |         virtual void patch() = 0; | ||||
|  |         virtual void unpatch() = 0; | ||||
|  | }; | ||||
|  | 
 | ||||
|  | #endif /*__SPI_PATCHER_HANDLE_H__*/ | ||||
					Loading…
					
					
				
		Reference in new issue