mirror of https://github.com/lumapu/ahoy.git
				
				
			
				 12 changed files with 313 additions and 324 deletions
			
			
		| @ -1,78 +0,0 @@ | |||
| //-----------------------------------------------------------------------------
 | |||
| // 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,196 @@ | |||
| //-----------------------------------------------------------------------------
 | |||
| // 2023 Ahoy, https://www.mikrocontroller.net/topic/525778
 | |||
| // Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
 | |||
| //-----------------------------------------------------------------------------
 | |||
| 
 | |||
| #ifndef __CMT_HAL_H__ | |||
| #define __CMT_HAL_H__ | |||
| 
 | |||
| #pragma once | |||
| 
 | |||
| #include "../utils/SpiPatcher.h" | |||
| 
 | |||
| #include <driver/gpio.h> | |||
| 
 | |||
| #define CMT_DEFAULT_SPI_SPEED 4000000 // 4 MHz
 | |||
| 
 | |||
| class cmtHal : public SpiPatcherHandle { | |||
|     public: | |||
|         cmtHal() { | |||
|             mSpiPatcher = SpiPatcher::getInstance(SPI2_HOST); | |||
|         } | |||
| 
 | |||
|         void patch() override { | |||
|             esp_rom_gpio_connect_out_signal(mPinSdio, spi_periph_signal[mHostDevice].spid_out, false, false); | |||
|             esp_rom_gpio_connect_in_signal(mPinSdio, spi_periph_signal[mHostDevice].spid_in, false); | |||
|             esp_rom_gpio_connect_out_signal(mPinClk, spi_periph_signal[mHostDevice].spiclk_out, false, false); | |||
|         } | |||
| 
 | |||
|         void unpatch() override { | |||
|             esp_rom_gpio_connect_out_signal(mPinSdio, SIG_GPIO_OUT_IDX, false, false); | |||
|             esp_rom_gpio_connect_in_signal(mPinSdio, GPIO_MATRIX_CONST_ZERO_INPUT, false); | |||
|             esp_rom_gpio_connect_out_signal(mPinClk, SIG_GPIO_OUT_IDX, false, false); | |||
|         } | |||
| 
 | |||
|         void init(int8_t sdio, int8_t clk, int8_t cs, int8_t fcs, int32_t speed = CMT_DEFAULT_SPI_SPEED) { | |||
|             mPinSdio  = static_cast<gpio_num_t>(sdio); | |||
|             mPinClk   = static_cast<gpio_num_t>(clk); | |||
|             mPinCs    = static_cast<gpio_num_t>(cs); | |||
|             mPinFcs   = static_cast<gpio_num_t>(fcs); | |||
|             mSpiSpeed = speed; | |||
| 
 | |||
|             mHostDevice = mSpiPatcher->getDevice(); | |||
| 
 | |||
|             gpio_reset_pin(mPinSdio); | |||
|             gpio_set_direction(mPinSdio, GPIO_MODE_INPUT_OUTPUT); | |||
|             gpio_set_level(mPinSdio, 1); | |||
| 
 | |||
|             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_reg = { | |||
|                 .command_bits = 1, | |||
|                 .address_bits = 7, | |||
|                 .dummy_bits = 0, | |||
|                 .mode = 0, | |||
|                 .duty_cycle_pos = 0, | |||
|                 .cs_ena_pretrans = 1, | |||
|                 .cs_ena_posttrans = 1, | |||
|                 .clock_speed_hz = mSpiSpeed, | |||
|                 .input_delay_ns = 0, | |||
|                 .spics_io_num = mPinCs, | |||
|                 .flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE, | |||
|                 .queue_size = 1, | |||
|                 .pre_cb = nullptr, | |||
|                 .post_cb = nullptr | |||
|             }; | |||
|             ESP_ERROR_CHECK(spi_bus_add_device(mHostDevice, &devcfg_reg, &spi_reg)); | |||
| 
 | |||
|             gpio_reset_pin(mPinFcs); | |||
|             spi_device_interface_config_t devcfg_fifo = { | |||
|                 .command_bits = 0, | |||
|                 .address_bits = 0, | |||
|                 .dummy_bits = 0, | |||
|                 .mode = 0, | |||
|                 .duty_cycle_pos = 0, | |||
|                 .cs_ena_pretrans = 2, | |||
|                 .cs_ena_posttrans = static_cast<uint8_t>(2 * mSpiSpeed / 1000000), // >2 us
 | |||
|                 .clock_speed_hz = mSpiSpeed, | |||
|                 .input_delay_ns = 0, | |||
|                 .spics_io_num = mPinFcs, | |||
|                 .flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE, | |||
|                 .queue_size = 1, | |||
|                 .pre_cb = nullptr, | |||
|                 .post_cb = nullptr | |||
|             }; | |||
|             ESP_ERROR_CHECK(spi_bus_add_device(mHostDevice, &devcfg_fifo, &spi_fifo)); | |||
|         } | |||
| 
 | |||
|         uint8_t readReg(uint8_t addr) { | |||
|             uint8_t data; | |||
| 
 | |||
|             request_spi(); | |||
| 
 | |||
|             spi_transaction_t t = { | |||
|                 .flags = 0, | |||
|                 .cmd = 1, | |||
|                 .addr = addr, | |||
|                 .length = 0, | |||
|                 .rxlength = 8, | |||
|                 .user = NULL, | |||
|                 .tx_buffer = NULL, | |||
|                 .rx_buffer = &data | |||
|             }; | |||
|             ESP_ERROR_CHECK(spi_device_polling_transmit(spi_reg, &t)); | |||
| 
 | |||
|             release_spi(); | |||
| 
 | |||
|             return data; | |||
|         } | |||
| 
 | |||
|         void writeReg(uint8_t addr, uint8_t data) { | |||
|             request_spi(); | |||
| 
 | |||
|             spi_transaction_t t = { | |||
|                 .flags = 0, | |||
|                 .cmd = 0, | |||
|                 .addr = addr, | |||
|                 .length = 8, | |||
|                 .rxlength = 0, | |||
|                 .user = NULL, | |||
|                 .tx_buffer = &data, | |||
|                 .rx_buffer = NULL | |||
|             }; | |||
|             ESP_ERROR_CHECK(spi_device_polling_transmit(spi_reg, &t)); | |||
| 
 | |||
|             release_spi(); | |||
|         } | |||
| 
 | |||
|         void readFifo(uint8_t buf[], uint8_t *len, uint8_t maxlen) { | |||
|             request_spi(); | |||
| 
 | |||
|             spi_transaction_t t = { | |||
|                 .flags = 0, | |||
|                 .cmd = 0, | |||
|                 .addr = 0, | |||
|                 .length = 0, | |||
|                 .rxlength = 8, | |||
|                 .user = NULL, | |||
|                 .tx_buffer = NULL, | |||
|                 .rx_buffer = NULL | |||
|             }; | |||
|             for (uint8_t i = 0; i < maxlen; i++) { | |||
|                 if(0 == i) | |||
|                     t.rx_buffer = len; | |||
|                 else | |||
|                     t.rx_buffer = buf + i - 1; | |||
|                 ESP_ERROR_CHECK(spi_device_polling_transmit(spi_fifo, &t)); | |||
|             } | |||
| 
 | |||
|             release_spi(); | |||
|         } | |||
|         void writeFifo(const uint8_t buf[], uint16_t len) { | |||
|             request_spi(); | |||
| 
 | |||
|             spi_transaction_t t = { | |||
|                 .flags = 0, | |||
|                 .cmd = 0, | |||
|                 .addr = 0, | |||
|                 .length = 8, | |||
|                 .rxlength = 0, | |||
|                 .user = NULL, | |||
|                 .tx_buffer = NULL, | |||
|                 .rx_buffer = NULL | |||
|             }; | |||
|             for (uint16_t i = 0; i < len; i++) { | |||
|                 t.tx_buffer = buf + i; | |||
|                 ESP_ERROR_CHECK(spi_device_polling_transmit(spi_fifo, &t)); | |||
|             } | |||
| 
 | |||
|             release_spi(); | |||
|         } | |||
| 
 | |||
|     private: | |||
|         inline void request_spi() { | |||
|             mSpiPatcher->request(this); | |||
|         } | |||
| 
 | |||
|         inline void release_spi() { | |||
|             mSpiPatcher->release(); | |||
|         } | |||
| 
 | |||
|     private: | |||
|         gpio_num_t mPinSdio = GPIO_NUM_NC; | |||
|         gpio_num_t mPinClk  = GPIO_NUM_NC; | |||
|         gpio_num_t mPinCs   = GPIO_NUM_NC; | |||
|         gpio_num_t mPinFcs  = GPIO_NUM_NC; | |||
|         int32_t mSpiSpeed   = CMT_DEFAULT_SPI_SPEED; | |||
| 
 | |||
|         spi_host_device_t mHostDevice; | |||
|         spi_device_handle_t spi_reg, spi_fifo; | |||
|         SpiPatcher *mSpiPatcher; | |||
| }; | |||
| 
 | |||
| #endif /*__CMT_HAL_H__*/ | |||
| @ -1,183 +0,0 @@ | |||
| //-----------------------------------------------------------------------------
 | |||
| // 2023 Ahoy, https://github.com/lumpapu/ahoy
 | |||
| // Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
 | |||
| //-----------------------------------------------------------------------------
 | |||
| 
 | |||
| #ifndef __ESP32_3WSPI_H__ | |||
| #define __ESP32_3WSPI_H__ | |||
| 
 | |||
| #include "Arduino.h" | |||
| #if defined(ESP32) | |||
| #include "driver/spi_master.h" | |||
| #include "esp_rom_gpio.h" // for esp_rom_gpio_connect_out_signal | |||
| 
 | |||
| #define SPI_CLK     1 * 1000 * 1000 // 1MHz
 | |||
| 
 | |||
| #define SPI_PARAM_LOCK() \ | |||
|     do {                 \ | |||
|     } while (xSemaphoreTake(paramLock, portMAX_DELAY) != pdPASS) | |||
| #define SPI_PARAM_UNLOCK() xSemaphoreGive(paramLock) | |||
| 
 | |||
| // for ESP32 this is the so-called HSPI
 | |||
| // for ESP32-S2/S3/C3 this nomenclature does not really exist anymore,
 | |||
| // it is simply the first externally usable hardware SPI master controller
 | |||
| #define SPI_CMT SPI2_HOST | |||
| 
 | |||
| class esp32_3wSpi { | |||
|     public: | |||
|         esp32_3wSpi() { | |||
|             mInitialized = false; | |||
|         } | |||
| 
 | |||
|         void setup(uint8_t pinSclk = DEF_CMT_SCLK, uint8_t pinSdio = DEF_CMT_SDIO, uint8_t pinCsb = DEF_CMT_CSB, uint8_t pinFcsb = DEF_CMT_FCSB) { | |||
|             paramLock = xSemaphoreCreateMutex(); | |||
|             spi_bus_config_t buscfg = { | |||
|                 .mosi_io_num = pinSdio, | |||
|                 .miso_io_num = -1, // single wire MOSI/MISO
 | |||
|                 .sclk_io_num = pinSclk, | |||
|                 .quadwp_io_num = -1, | |||
|                 .quadhd_io_num = -1, | |||
|                 .max_transfer_sz = 32, | |||
|             }; | |||
|             spi_device_interface_config_t devcfg = { | |||
|                 .command_bits = 1, | |||
|                 .address_bits = 7, | |||
|                 .dummy_bits = 0, | |||
|                 .mode = 0, | |||
|                 .cs_ena_pretrans = 1, | |||
|                 .cs_ena_posttrans = 1, | |||
|                 .clock_speed_hz = SPI_CLK, | |||
|                 .spics_io_num = pinCsb, | |||
|                 .flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE, | |||
|                 .queue_size = 1, | |||
|                 .pre_cb = NULL, | |||
|                 .post_cb = NULL, | |||
|             }; | |||
| 
 | |||
|             ESP_ERROR_CHECK(spi_bus_initialize(SPI_CMT, &buscfg, SPI_DMA_DISABLED)); | |||
|             ESP_ERROR_CHECK(spi_bus_add_device(SPI_CMT, &devcfg, &spi_reg)); | |||
| 
 | |||
|             // FiFo
 | |||
|             spi_device_interface_config_t devcfg2 = { | |||
|                 .command_bits = 0, | |||
|                 .address_bits = 0, | |||
|                 .dummy_bits = 0, | |||
|                 .mode = 0, | |||
|                 .cs_ena_pretrans = 2, | |||
|                 .cs_ena_posttrans = (uint8_t)(1 / (SPI_CLK * 10e6 * 2) + 2), // >2 us
 | |||
|                 .clock_speed_hz = SPI_CLK, | |||
|                 .spics_io_num = pinFcsb, | |||
|                 .flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE, | |||
|                 .queue_size = 1, | |||
|                 .pre_cb = NULL, | |||
|                 .post_cb = NULL, | |||
|             }; | |||
|             ESP_ERROR_CHECK(spi_bus_add_device(SPI_CMT, &devcfg2, &spi_fifo)); | |||
| 
 | |||
|             esp_rom_gpio_connect_out_signal(pinSdio, spi_periph_signal[SPI_CMT].spid_out, true, false); | |||
|             delay(100); | |||
| 
 | |||
|             //pinMode(pinGpio3, INPUT);
 | |||
|             mInitialized = true; | |||
|         } | |||
| 
 | |||
|         void writeReg(uint8_t addr, uint8_t reg) { | |||
|             if(!mInitialized) | |||
|                 return; | |||
| 
 | |||
|             uint8_t tx_data; | |||
|             tx_data = ~reg; | |||
|             spi_transaction_t t = { | |||
|                 .cmd = 1, | |||
|                 .addr = (uint64_t)(~addr), | |||
|                 .length = 8, | |||
|                 .tx_buffer = &tx_data, | |||
|                 .rx_buffer = NULL | |||
|             }; | |||
|             SPI_PARAM_LOCK(); | |||
|             ESP_ERROR_CHECK(spi_device_polling_transmit(spi_reg, &t)); | |||
|             SPI_PARAM_UNLOCK(); | |||
|             delayMicroseconds(100); | |||
|         } | |||
| 
 | |||
|         uint8_t readReg(uint8_t addr) { | |||
|             if(!mInitialized) | |||
|                 return 0; | |||
| 
 | |||
|             uint8_t rx_data; | |||
|             spi_transaction_t t = { | |||
|                 .cmd = 0, | |||
|                 .addr = (uint64_t)(~addr), | |||
|                 .length = 8, | |||
|                 .rxlength = 8, | |||
|                 .tx_buffer = NULL, | |||
|                 .rx_buffer = &rx_data | |||
|             }; | |||
| 
 | |||
|             SPI_PARAM_LOCK(); | |||
|             ESP_ERROR_CHECK(spi_device_polling_transmit(spi_reg, &t)); | |||
|             SPI_PARAM_UNLOCK(); | |||
|             delayMicroseconds(100); | |||
|             return rx_data; | |||
|         } | |||
| 
 | |||
|         void writeFifo(uint8_t buf[], uint8_t len) { | |||
|             if(!mInitialized) | |||
|                 return; | |||
|             uint8_t tx_data; | |||
| 
 | |||
|             spi_transaction_t t = { | |||
|                 .length    = 8, | |||
|                 .tx_buffer = &tx_data, // reference to write data
 | |||
|                 .rx_buffer = NULL | |||
|             }; | |||
| 
 | |||
|             SPI_PARAM_LOCK(); | |||
|             for(uint8_t i = 0; i < len; i++) { | |||
|                 tx_data = ~buf[i]; // negate buffer contents
 | |||
|                 ESP_ERROR_CHECK(spi_device_polling_transmit(spi_fifo, &t)); | |||
|                 delayMicroseconds(4); // > 4 us
 | |||
|             } | |||
|             SPI_PARAM_UNLOCK(); | |||
|         } | |||
| 
 | |||
|         void readFifo(uint8_t buf[], uint8_t *len, uint8_t maxlen) { | |||
|             if(!mInitialized) | |||
|                 return; | |||
|             uint8_t rx_data; | |||
| 
 | |||
|             spi_transaction_t t = { | |||
|                 .length = 8, | |||
|                 .rxlength = 8, | |||
|                 .tx_buffer = NULL, | |||
|                 .rx_buffer = &rx_data | |||
|             }; | |||
| 
 | |||
|             SPI_PARAM_LOCK(); | |||
|             for(uint8_t i = 0; i < maxlen; i++) { | |||
|                 ESP_ERROR_CHECK(spi_device_polling_transmit(spi_fifo, &t)); | |||
|                 delayMicroseconds(4); // > 4 us
 | |||
|                 if(0 == i) | |||
|                     *len = rx_data; | |||
|                 else | |||
|                     buf[i-1] = rx_data; | |||
|             } | |||
|             SPI_PARAM_UNLOCK(); | |||
|         } | |||
| 
 | |||
|     private: | |||
|         spi_device_handle_t spi_reg, spi_fifo; | |||
|         bool mInitialized; | |||
|         SemaphoreHandle_t paramLock = NULL; | |||
| }; | |||
| #else | |||
|     template<uint8_t CSB_PIN=5, uint8_t FCSB_PIN=4> | |||
|     class esp32_3wSpi { | |||
|         public: | |||
|             esp32_3wSpi() {} | |||
|             void setup() {} | |||
|             void loop() {} | |||
|     }; | |||
| #endif | |||
| 
 | |||
| #endif /*__ESP32_3WSPI_H__*/ | |||
| @ -0,0 +1,9 @@ | |||
| //-----------------------------------------------------------------------------
 | |||
| // 2023 Ahoy, https://www.mikrocontroller.net/topic/525778
 | |||
| // Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
 | |||
| //-----------------------------------------------------------------------------
 | |||
| 
 | |||
| 
 | |||
| #include "spiPatcher.h" | |||
| 
 | |||
| SpiPatcher *SpiPatcher::mInstance = nullptr; | |||
| @ -0,0 +1,84 @@ | |||
| //-----------------------------------------------------------------------------
 | |||
| // 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 { | |||
|     protected: | |||
|         SpiPatcher(spi_host_device_t dev) : | |||
|             mHostDevice(dev), mCurHandle(nullptr) { | |||
|             // Use binary semaphore instead of mutex for performance reasons
 | |||
|             mutex = xSemaphoreCreateBinaryStatic(&mutex_buffer); | |||
|             xSemaphoreGive(mutex); | |||
| 
 | |||
|             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(mHostDevice, &buscfg, SPI_DMA_DISABLED)); | |||
|         } | |||
| 
 | |||
|     public: | |||
|         SpiPatcher(SpiPatcher &other) = delete; | |||
|         void operator=(const SpiPatcher &) = delete; | |||
| 
 | |||
|         static SpiPatcher* getInstance(spi_host_device_t dev) { | |||
|             if(nullptr == mInstance) | |||
|                 mInstance = new SpiPatcher(dev); | |||
|             return mInstance; | |||
|         } | |||
| 
 | |||
|         ~SpiPatcher() { vSemaphoreDelete(mutex); } | |||
| 
 | |||
|         spi_host_device_t getDevice() { | |||
|             return mHostDevice; | |||
|         } | |||
| 
 | |||
|         inline void request(SpiPatcherHandle* handle) { | |||
|             xSemaphoreTake(mutex, portMAX_DELAY); | |||
| 
 | |||
|             if (mCurHandle != handle) { | |||
|                 if (mCurHandle) { | |||
|                     mCurHandle->unpatch(); | |||
|                 } | |||
|                 mCurHandle = handle; | |||
|                 if (mCurHandle) { | |||
|                     mCurHandle->patch(); | |||
|                 } | |||
|             } | |||
|         } | |||
| 
 | |||
|         inline void release() { | |||
|             xSemaphoreGive(mutex); | |||
|         } | |||
| 
 | |||
|     protected: | |||
|         static SpiPatcher *mInstance; | |||
| 
 | |||
|     private: | |||
|         const spi_host_device_t mHostDevice; | |||
|         SpiPatcherHandle* mCurHandle; | |||
|         SemaphoreHandle_t mutex; | |||
|         StaticSemaphore_t mutex_buffer; | |||
| }; | |||
| 
 | |||
| #endif /*__SPI_PATCHER_H__*/ | |||
					Loading…
					
					
				
		Reference in new issue