-
-
Notifications
You must be signed in to change notification settings - Fork 230
/
Copy pathspiPatcher.h
130 lines (109 loc) · 4.07 KB
/
spiPatcher.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//-----------------------------------------------------------------------------
// 2024 Ahoy, https://github.com/lumpapu/ahoy
// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed
//-----------------------------------------------------------------------------
#ifndef __SPI_PATCHER_H__
#define __SPI_PATCHER_H__
#pragma once
#if defined(ESP32)
#include "dbg.h"
#include "spiPatcherHandle.h"
#include <driver/spi_master.h>
#include <freertos/semphr.h>
#if (SOC_SPI_PERIPH_NUM > 2)
#define SPI_HOST_OTHER SPI3_HOST
#else
#define SPI_HOST_OTHER SPI2_HOST
#endif
class SpiPatcher {
protected:
explicit SpiPatcher(spi_host_device_t dev) :
mCurHandle(nullptr) {
// Use binary semaphore instead of mutex for performance reasons
mutex = xSemaphoreCreateBinaryStatic(&mutex_buffer);
xSemaphoreGive(mutex);
mDev = dev;
mBusState = ESP_FAIL;
}
public:
SpiPatcher(const SpiPatcher &other) = delete;
void operator=(const SpiPatcher &) = delete;
esp_err_t initBus(int mosi = -1, int miso = -1, int sclk = -1, spi_common_dma_t dmaType = SPI_DMA_DISABLED) {
mBusConfig = spi_bus_config_t {
.mosi_io_num = mosi,
.miso_io_num = miso,
.sclk_io_num = 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 = SOC_SPI_MAXIMUM_BUFFER_SIZE,
.flags = 0,
.intr_flags = 0
};
ESP_ERROR_CHECK((mBusState = spi_bus_initialize(mDev, &mBusConfig, dmaType)));
return mBusState;
}
static SpiPatcher* getInstance(spi_host_device_t dev, bool initialize = true) {
if(SPI2_HOST == dev) {
if(nullptr == InstanceHost2) {
InstanceHost2 = new SpiPatcher(dev);
if(initialize)
InstanceHost2->initBus();
}
return InstanceHost2;
} else { // SPI3_HOST
if(nullptr == InstanceHost3) {
InstanceHost3 = new SpiPatcher(dev);
if(initialize)
InstanceHost3->initBus();
}
return InstanceHost3;
}
}
~SpiPatcher() { vSemaphoreDelete(mutex); }
inline void addDevice(spi_host_device_t host_id, const spi_device_interface_config_t *dev_config, spi_device_handle_t *handle) {
assert(mBusState == ESP_OK);
if(SPI2_HOST == host_id)
mHost2Cnt++;
#if (SOC_SPI_PERIPH_NUM > 2)
if(SPI3_HOST == host_id)
mHost3Cnt++;
#endif
if((mHost2Cnt > 3) || (mHost3Cnt > 3))
DPRINTLN(DBG_ERROR, F("maximum number of SPI devices reached (3)"));
ESP_ERROR_CHECK(spi_bus_add_device(host_id, dev_config, handle));
}
inline void request(SpiPatcherHandle* handle) {
assert(mBusState == ESP_OK);
xSemaphoreTake(mutex, portMAX_DELAY);
if (mCurHandle != handle) {
if (mCurHandle) {
mCurHandle->unpatch();
}
mCurHandle = handle;
if (mCurHandle) {
mCurHandle->patch();
}
}
}
inline void release() {
assert(mBusState == ESP_OK);
xSemaphoreGive(mutex);
}
protected:
static SpiPatcher *InstanceHost2;
static SpiPatcher *InstanceHost3;
private:
SpiPatcherHandle* mCurHandle;
SemaphoreHandle_t mutex;
StaticSemaphore_t mutex_buffer;
uint8_t mHost2Cnt = 0, mHost3Cnt = 0;
spi_host_device_t mDev = SPI2_HOST;
esp_err_t mBusState = ESP_FAIL;
spi_bus_config_t mBusConfig;
};
#endif /*ESP32*/
#endif /*__SPI_PATCHER_H__*/