-
-
Notifications
You must be signed in to change notification settings - Fork 230
/
Copy pathcmtHal.h
202 lines (169 loc) · 6.4 KB
/
cmtHal.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
//-----------------------------------------------------------------------------
// 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() {}
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;
#if defined(CONFIG_IDF_TARGET_ESP32S3)
mHostDevice = SPI2_HOST;
#else
mHostDevice = (14 == clk) ? SPI2_HOST : SPI_HOST_OTHER;
#endif
mSpiPatcher = SpiPatcher::getInstance(mHostDevice);
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);
request_spi();
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
};
mSpiPatcher->addDevice(mHostDevice, &devcfg_reg, &spi_reg);
release_spi();
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 = 0;
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__*/