diff --git a/lib/SpiManager/src/SpiBus.cpp b/lib/SpiManager/src/SpiBus.cpp index 26b361cc..0dcb5e4f 100644 --- a/lib/SpiManager/src/SpiBus.cpp +++ b/lib/SpiManager/src/SpiBus.cpp @@ -1,12 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0-or-later #include "SpiBus.h" - #include "SpiBusConfig.h" #include "SpiCallback.h" -SpiBus::SpiBus(const std::string &_id, spi_host_device_t _host_device) : - id(_id), - host_device(_host_device), - cur_config(nullptr) +SpiBus::SpiBus(const std::string& _id, spi_host_device_t _host_device) + : id(_id) + , host_device(_host_device) + , cur_config(nullptr) { spi_bus_config_t bus_config { .mosi_io_num = -1, @@ -25,11 +25,13 @@ SpiBus::SpiBus(const std::string &_id, spi_host_device_t _host_device) : ESP_ERROR_CHECK(spi_bus_initialize(host_device, &bus_config, SPI_DMA_CH_AUTO)); } -SpiBus::~SpiBus() { +SpiBus::~SpiBus() +{ ESP_ERROR_CHECK(spi_bus_free(host_device)); } -spi_device_handle_t SpiBus::add_device(const std::shared_ptr &bus_config, spi_device_interface_config_t &device_config) { +spi_device_handle_t SpiBus::add_device(const std::shared_ptr& bus_config, spi_device_interface_config_t& device_config) +{ if (!SpiCallback::patch(shared_from_this(), bus_config, device_config)) return nullptr; @@ -40,7 +42,8 @@ spi_device_handle_t SpiBus::add_device(const std::shared_ptr &bus_ // TODO: add remove_device (with spi_device_acquire_bus) -void SpiBus::apply_config(SpiBusConfig *config) { +void SpiBus::apply_config(SpiBusConfig* config) +{ if (cur_config) cur_config->unpatch(host_device); cur_config = config; diff --git a/lib/SpiManager/src/SpiBus.h b/lib/SpiManager/src/SpiBus.h index a5fde06c..1ca79c7c 100644 --- a/lib/SpiManager/src/SpiBus.h +++ b/lib/SpiManager/src/SpiBus.h @@ -1,7 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include - #include #include @@ -9,37 +9,41 @@ class SpiBusConfig; class SpiBus : public std::enable_shared_from_this { public: - explicit SpiBus(const std::string &id, spi_host_device_t host_device); + explicit SpiBus(const std::string& id, spi_host_device_t host_device); SpiBus(const SpiBus&) = delete; - SpiBus &operator=(const SpiBus&) = delete; + SpiBus& operator=(const SpiBus&) = delete; ~SpiBus(); - inline __attribute__((always_inline)) void require_config(SpiBusConfig *config) { + inline __attribute__((always_inline)) void require_config(SpiBusConfig* config) + { if (config == cur_config) return; apply_config(config); } - inline __attribute__((always_inline)) void free_config(SpiBusConfig *config) { + inline __attribute__((always_inline)) void free_config(SpiBusConfig* config) + { if (config != cur_config) return; apply_config(nullptr); } - inline const std::string &get_id() const { + inline const std::string& get_id() const + { return id; } - inline spi_host_device_t get_host_device() const { + inline spi_host_device_t get_host_device() const + { return host_device; } - spi_device_handle_t add_device(const std::shared_ptr &bus_config, spi_device_interface_config_t &device_config); + spi_device_handle_t add_device(const std::shared_ptr& bus_config, spi_device_interface_config_t& device_config); private: - void apply_config(SpiBusConfig *config); + void apply_config(SpiBusConfig* config); std::string id; spi_host_device_t host_device; - SpiBusConfig *cur_config; + SpiBusConfig* cur_config; }; diff --git a/lib/SpiManager/src/SpiBusConfig.cpp b/lib/SpiManager/src/SpiBusConfig.cpp index c3cc0196..64234d65 100644 --- a/lib/SpiManager/src/SpiBusConfig.cpp +++ b/lib/SpiManager/src/SpiBusConfig.cpp @@ -1,13 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-or-later #include "SpiBusConfig.h" #include #include #include -SpiBusConfig::SpiBusConfig(gpio_num_t _pin_mosi, gpio_num_t _pin_miso, gpio_num_t _pin_sclk) : - pin_mosi(_pin_mosi), - pin_miso(_pin_miso), - pin_sclk(_pin_sclk) +SpiBusConfig::SpiBusConfig(gpio_num_t _pin_mosi, gpio_num_t _pin_miso, gpio_num_t _pin_sclk) + : pin_mosi(_pin_mosi) + , pin_miso(_pin_miso) + , pin_sclk(_pin_sclk) { if (pin_mosi != GPIO_NUM_NC) { ESP_ERROR_CHECK(gpio_reset_pin(pin_mosi)); @@ -25,7 +26,8 @@ SpiBusConfig::SpiBusConfig(gpio_num_t _pin_mosi, gpio_num_t _pin_miso, gpio_num_ } } -SpiBusConfig::~SpiBusConfig() { +SpiBusConfig::~SpiBusConfig() +{ if (pin_mosi != GPIO_NUM_NC) ESP_ERROR_CHECK(gpio_reset_pin(pin_mosi)); @@ -36,7 +38,8 @@ SpiBusConfig::~SpiBusConfig() { ESP_ERROR_CHECK(gpio_reset_pin(pin_sclk)); } -void SpiBusConfig::patch(spi_host_device_t host_device) { +void SpiBusConfig::patch(spi_host_device_t host_device) +{ if (pin_mosi != GPIO_NUM_NC) { esp_rom_gpio_connect_out_signal(pin_mosi, spi_periph_signal[host_device].spid_out, false, false); esp_rom_gpio_connect_in_signal(pin_mosi, spi_periph_signal[host_device].spid_in, false); @@ -51,7 +54,8 @@ void SpiBusConfig::patch(spi_host_device_t host_device) { } } -void SpiBusConfig::unpatch(spi_host_device_t host_device) { +void SpiBusConfig::unpatch(spi_host_device_t host_device) +{ if (pin_mosi != GPIO_NUM_NC) { esp_rom_gpio_connect_out_signal(pin_mosi, SIG_GPIO_OUT_IDX, false, false); esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, spi_periph_signal[host_device].spid_in, false); diff --git a/lib/SpiManager/src/SpiBusConfig.h b/lib/SpiManager/src/SpiBusConfig.h index e4549ef1..736b8951 100644 --- a/lib/SpiManager/src/SpiBusConfig.h +++ b/lib/SpiManager/src/SpiBusConfig.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include @@ -7,7 +8,7 @@ class SpiBusConfig { public: explicit SpiBusConfig(gpio_num_t pin_mosi, gpio_num_t pin_miso, gpio_num_t pin_sclk); SpiBusConfig(const SpiBusConfig&) = delete; - SpiBusConfig &operator=(const SpiBusConfig&) = delete; + SpiBusConfig& operator=(const SpiBusConfig&) = delete; ~SpiBusConfig(); void patch(spi_host_device_t host_device); diff --git a/lib/SpiManager/src/SpiCallback.cpp b/lib/SpiManager/src/SpiCallback.cpp index e281db98..e353d04b 100644 --- a/lib/SpiManager/src/SpiCallback.cpp +++ b/lib/SpiManager/src/SpiCallback.cpp @@ -1,65 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0-or-later #include "SpiCallback.h" #include "SpiBus.h" - #include #include namespace SpiCallback { - namespace { - struct CallbackData { - std::shared_ptr bus; - std::shared_ptr config; - transaction_cb_t inner_pre_cb; - transaction_cb_t inner_post_cb; - }; +namespace { + struct CallbackData { + std::shared_ptr bus; + std::shared_ptr config; + transaction_cb_t inner_pre_cb; + transaction_cb_t inner_post_cb; + }; - std::array, SPI_MANAGER_CALLBACK_COUNT> instances; + std::array, SPI_MANAGER_CALLBACK_COUNT> instances; - template - void IRAM_ATTR fn_pre_cb(spi_transaction_t *trans) { - instances[N]->bus->require_config(instances[N]->config.get()); - if (instances[N]->inner_pre_cb) - instances[N]->inner_pre_cb(trans); - } - - template - void IRAM_ATTR fn_post_cb(spi_transaction_t *trans) { - if (instances[N]->inner_post_cb) - instances[N]->inner_post_cb(trans); - } - - template - inline __attribute__((always_inline)) bool alloc(CallbackData *&instance, transaction_cb_t &pre_cb, transaction_cb_t &post_cb) { - if constexpr (N > 0) { - if (alloc(instance, pre_cb, post_cb)) - return true; - if (!instances[N - 1]) { - instances[N - 1].emplace(); - instance = &*instances[N - 1]; - pre_cb = fn_pre_cb; - post_cb = fn_post_cb; - return true; - } - } - return false; - } + template + void IRAM_ATTR fn_pre_cb(spi_transaction_t* trans) + { + instances[N]->bus->require_config(instances[N]->config.get()); + if (instances[N]->inner_pre_cb) + instances[N]->inner_pre_cb(trans); } - bool patch(const std::shared_ptr &bus, const std::shared_ptr &bus_config, spi_device_interface_config_t &device_config) { - CallbackData *instance; - transaction_cb_t pre_cb; - transaction_cb_t post_cb; - if (!alloc(instance, pre_cb, post_cb)) - return false; + template + void IRAM_ATTR fn_post_cb(spi_transaction_t* trans) + { + if (instances[N]->inner_post_cb) + instances[N]->inner_post_cb(trans); + } - instance->bus = bus; - instance->config = bus_config; - instance->inner_pre_cb = device_config.pre_cb; - instance->inner_post_cb = device_config.post_cb; - device_config.pre_cb = pre_cb; - device_config.post_cb = post_cb; - - return true; + template + inline __attribute__((always_inline)) bool alloc(CallbackData*& instance, transaction_cb_t& pre_cb, transaction_cb_t& post_cb) + { + if constexpr (N > 0) { + if (alloc(instance, pre_cb, post_cb)) + return true; + if (!instances[N - 1]) { + instances[N - 1].emplace(); + instance = &*instances[N - 1]; + pre_cb = fn_pre_cb; + post_cb = fn_post_cb; + return true; + } + } + return false; } } + +bool patch(const std::shared_ptr& bus, const std::shared_ptr& bus_config, spi_device_interface_config_t& device_config) +{ + CallbackData* instance; + transaction_cb_t pre_cb; + transaction_cb_t post_cb; + if (!alloc(instance, pre_cb, post_cb)) + return false; + + instance->bus = bus; + instance->config = bus_config; + instance->inner_pre_cb = device_config.pre_cb; + instance->inner_post_cb = device_config.post_cb; + device_config.pre_cb = pre_cb; + device_config.post_cb = post_cb; + + return true; +} +} diff --git a/lib/SpiManager/src/SpiCallback.h b/lib/SpiManager/src/SpiCallback.h index f8d52d0d..98222b1a 100644 --- a/lib/SpiManager/src/SpiCallback.h +++ b/lib/SpiManager/src/SpiCallback.h @@ -1,7 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include - #include // Pre and post callbacks for 2 buses with 3 devices each @@ -11,5 +11,5 @@ class SpiBus; class SpiBusConfig; namespace SpiCallback { - bool patch(const std::shared_ptr &bus, const std::shared_ptr &bus_config, spi_device_interface_config_t &device_config); +bool patch(const std::shared_ptr& bus, const std::shared_ptr& bus_config, spi_device_interface_config_t& device_config); } diff --git a/lib/SpiManager/src/SpiManager.cpp b/lib/SpiManager/src/SpiManager.cpp index efbd5e0a..d727a96e 100644 --- a/lib/SpiManager/src/SpiManager.cpp +++ b/lib/SpiManager/src/SpiManager.cpp @@ -1,15 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-or-later #include "SpiManager.h" #ifdef ARDUINO #include #endif -SpiManager::SpiManager() { +SpiManager::SpiManager() +{ } #ifdef ARDUINO -std::optional SpiManager::to_arduino(spi_host_device_t host_device) { +std::optional SpiManager::to_arduino(spi_host_device_t host_device) +{ switch (host_device) { #if CONFIG_IDF_TARGET_ESP32 case SPI1_HOST: @@ -34,7 +37,8 @@ std::optional SpiManager::to_arduino(spi_host_device_t host_device) { #endif -bool SpiManager::register_bus(spi_host_device_t host_device) { +bool SpiManager::register_bus(spi_host_device_t host_device) +{ for (int i = 0; i < SPI_MANAGER_NUM_BUSES; ++i) { if (available_buses[i]) continue; @@ -46,7 +50,8 @@ bool SpiManager::register_bus(spi_host_device_t host_device) { return false; } -bool SpiManager::claim_bus(spi_host_device_t &host_device) { +bool SpiManager::claim_bus(spi_host_device_t& host_device) +{ for (int i = SPI_MANAGER_NUM_BUSES - 1; i >= 0; --i) { if (!available_buses[i]) continue; @@ -61,7 +66,8 @@ bool SpiManager::claim_bus(spi_host_device_t &host_device) { #ifdef ARDUINO -std::optional SpiManager::claim_bus_arduino() { +std::optional SpiManager::claim_bus_arduino() +{ spi_host_device_t host_device; if (!claim_bus(host_device)) return std::nullopt; @@ -70,7 +76,8 @@ std::optional SpiManager::claim_bus_arduino() { #endif -spi_device_handle_t SpiManager::alloc_device(const std::string &bus_id, const std::shared_ptr &bus_config, spi_device_interface_config_t &device_config) { +spi_device_handle_t SpiManager::alloc_device(const std::string& bus_id, const std::shared_ptr& bus_config, spi_device_interface_config_t& device_config) +{ std::shared_ptr shared_bus = get_shared_bus(bus_id); if (!shared_bus) return nullptr; @@ -78,7 +85,8 @@ spi_device_handle_t SpiManager::alloc_device(const std::string &bus_id, const st return shared_bus->add_device(bus_config, device_config); } -std::shared_ptr SpiManager::get_shared_bus(const std::string &bus_id) { +std::shared_ptr SpiManager::get_shared_bus(const std::string& bus_id) +{ // look for existing shared bus for (int i = 0; i < SPI_MANAGER_NUM_BUSES; ++i) { if (!shared_buses[i]) diff --git a/lib/SpiManager/src/SpiManager.h b/lib/SpiManager/src/SpiManager.h index ee3b56a5..1e8f6e1b 100644 --- a/lib/SpiManager/src/SpiManager.h +++ b/lib/SpiManager/src/SpiManager.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include "SpiBus.h" @@ -16,22 +17,22 @@ class SpiManager { public: explicit SpiManager(); SpiManager(const SpiManager&) = delete; - SpiManager &operator=(const SpiManager&) = delete; + SpiManager& operator=(const SpiManager&) = delete; #ifdef ARDUINO static std::optional to_arduino(spi_host_device_t host_device); #endif bool register_bus(spi_host_device_t host_device); - bool claim_bus(spi_host_device_t &host_device); + bool claim_bus(spi_host_device_t& host_device); #ifdef ARDUINO std::optional claim_bus_arduino(); #endif - spi_device_handle_t alloc_device(const std::string &bus_id, const std::shared_ptr &bus_config, spi_device_interface_config_t &device_config); + spi_device_handle_t alloc_device(const std::string& bus_id, const std::shared_ptr& bus_config, spi_device_interface_config_t& device_config); private: - std::shared_ptr get_shared_bus(const std::string &bus_id); + std::shared_ptr get_shared_bus(const std::string& bus_id); std::array, SPI_MANAGER_NUM_BUSES> available_buses; std::array, SPI_MANAGER_NUM_BUSES> shared_buses;