ESPHome 2026.5.0-dev
Loading...
Searching...
No Matches
spi.h
Go to the documentation of this file.
1#pragma once
4#include "esphome/core/hal.h"
5#include "esphome/core/log.h"
6#include <map>
7#include <utility>
8#include <vector>
9
10#ifdef USE_ESP32
11
12#include "driver/spi_master.h"
13
14using SPIInterface = spi_host_device_t;
15
16#elif defined(USE_ARDUINO)
17
18#include <SPI.h>
19
20#ifdef USE_RP2040
21using SPIInterface = SPIClassRP2040 *;
22#else
23using SPIInterface = SPIClass *;
24#endif
25
26#elif defined(USE_HOST) || defined(CLANG_TIDY)
27
28using SPIInterface = void *; // Stub for platforms without SPI (e.g., host, Zephyr)
29
30#endif // USE_ESP32 / USE_ARDUINO
31
35namespace esphome::spi {
36
37#define LOG_SPI_DEVICE(this) ESP_LOGCONFIG(TAG, " CS Pin: %d", esphome::spi::Utility::get_pin_no(this->cs_));
38
72
78enum SPIMode {
79 MODE0 = 0,
80 MODE1 = 1,
81 MODE2 = 2,
82 MODE3 = 3,
83};
93 DATA_RATE_1MHZ = 1000000,
94 DATA_RATE_2MHZ = 2000000,
95 DATA_RATE_4MHZ = 4000000,
96 DATA_RATE_5MHZ = 5000000,
97 DATA_RATE_8MHZ = 8000000,
98 DATA_RATE_10MHZ = 10000000,
99 DATA_RATE_20MHZ = 20000000,
100 DATA_RATE_40MHZ = 40000000,
101 DATA_RATE_80MHZ = 80000000,
102};
103
107class NullPin : public GPIOPin {
108 friend class SPIComponent;
109
110 friend class SPIDelegate;
111
112 friend class Utility;
113
114 public:
115 void setup() override {}
116
117 void pin_mode(gpio::Flags flags) override {}
118
119 gpio::Flags get_flags() const override { return gpio::Flags::FLAG_NONE; }
120
121 bool digital_read() override { return false; }
122
123 void digital_write(bool value) override {}
124
125 size_t dump_summary(char *buffer, size_t len) const override {
126 if (len > 0)
127 buffer[0] = '\0';
128 return 0;
129 }
130
131 protected:
132 static GPIOPin *const NULL_PIN; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
133 // https://bugs.llvm.org/show_bug.cgi?id=48040
134};
135
136class Utility {
137 public:
138 static int get_pin_no(GPIOPin *pin) {
139 if (pin == nullptr || !pin->is_internal())
140 return -1;
141 if (((InternalGPIOPin *) pin)->is_inverted())
142 return -1;
143 return ((InternalGPIOPin *) pin)->get_pin();
144 }
145
147 if (polarity == CLOCK_POLARITY_HIGH) {
148 return phase == CLOCK_PHASE_LEADING ? MODE2 : MODE3;
149 }
150 return phase == CLOCK_PHASE_LEADING ? MODE0 : MODE1;
151 }
152
154 switch (mode) {
155 case MODE0:
156 case MODE2:
157 return CLOCK_PHASE_LEADING;
158 default:
160 }
161 }
162
164 switch (mode) {
165 case MODE0:
166 case MODE1:
167 return CLOCK_POLARITY_LOW;
168 default:
169 return CLOCK_POLARITY_HIGH;
170 }
171 }
172};
173
174class SPIDelegateDummy;
175
176// represents a device attached to an SPI bus, with a defined clock rate, mode and bit order. On Arduino this is
177// a thin wrapper over SPIClass.
179 friend class SPIClient;
180
181 public:
182 SPIDelegate() = default;
183
184 SPIDelegate(uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin)
185 : bit_order_(bit_order), data_rate_(data_rate), mode_(mode), cs_pin_(cs_pin) {
186 if (this->cs_pin_ == nullptr)
188 this->cs_pin_->setup();
189 this->cs_pin_->digital_write(true);
190 }
191
192 virtual ~SPIDelegate(){};
193
194 // enable CS if configured.
195 virtual void begin_transaction() { this->cs_pin_->digital_write(false); }
196
197 // end the transaction
198 virtual void end_transaction() { this->cs_pin_->digital_write(true); }
199
200 // transfer one byte, return the byte that was read.
201 virtual uint8_t transfer(uint8_t data) = 0;
202
203 // transfer a buffer, replace the contents with read data
204 virtual void transfer(uint8_t *ptr, size_t length) { this->transfer(ptr, ptr, length); }
205
206 virtual void transfer(const uint8_t *txbuf, uint8_t *rxbuf, size_t length) {
207 for (size_t i = 0; i != length; i++)
208 rxbuf[i] = this->transfer(txbuf[i]);
209 }
210
216 virtual void write(uint16_t data, size_t num_bits) {
217 esph_log_e("spi_device", "variable length write not implemented");
218 }
219
220 virtual void write_cmd_addr_data(size_t cmd_bits, uint32_t cmd, size_t addr_bits, uint32_t address,
221 const uint8_t *data, size_t length, uint8_t bus_width) {
222 esph_log_e("spi_device", "write_cmd_addr_data not implemented");
223 }
224 // write 16 bits
225 virtual void write16(uint16_t data) {
226 if (this->bit_order_ == BIT_ORDER_MSB_FIRST) {
227 uint16_t buffer;
228 buffer = (data >> 8) | (data << 8);
229 this->write_array(reinterpret_cast<const uint8_t *>(&buffer), 2);
230 } else {
231 this->write_array(reinterpret_cast<const uint8_t *>(&data), 2);
232 }
233 }
234
235 virtual void write_array16(const uint16_t *data, size_t length) {
236 for (size_t i = 0; i != length; i++) {
237 this->write16(data[i]);
238 }
239 }
240
241 // write the contents of a buffer, ignore read data (buffer is unchanged.)
242 virtual void write_array(const uint8_t *ptr, size_t length) {
243 for (size_t i = 0; i != length; i++)
244 this->transfer(ptr[i]);
245 }
246
247 // read into a buffer, write nulls
248 virtual void read_array(uint8_t *ptr, size_t length) {
249 for (size_t i = 0; i != length; i++)
250 ptr[i] = this->transfer(0);
251 }
252
253 // check if device is ready
254 virtual bool is_ready();
255
256 protected:
261 static SPIDelegate *const NULL_DELEGATE; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
262};
263
269 public:
270 SPIDelegateDummy() = default;
271
272 uint8_t transfer(uint8_t data) override { return 0; }
273 void end_transaction() override{};
274
275 void begin_transaction() override;
276};
277
283 public:
284 SPIDelegateBitBash(uint32_t clock, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin, GPIOPin *clk_pin,
285 GPIOPin *sdo_pin, GPIOPin *sdi_pin)
286 : SPIDelegate(clock, bit_order, mode, cs_pin), clk_pin_(clk_pin), sdo_pin_(sdo_pin), sdi_pin_(sdi_pin) {
287 // this calculation is pretty meaningless except at very low bit rates.
288 this->wait_cycle_ = uint32_t(arch_get_cpu_freq_hz()) / this->data_rate_ / 2ULL;
291 }
292
293 uint8_t transfer(uint8_t data) override;
294
295 void write(uint16_t data, size_t num_bits) override;
296
297 void write16(uint16_t data) override { this->write(data, 16); };
298
299 protected:
307
308 void HOT cycle_clock_() {
309 while (this->last_transition_ - arch_get_cpu_cycle_count() < this->wait_cycle_)
310 continue;
311 this->last_transition_ += this->wait_cycle_;
312 }
313 uint16_t transfer_(uint16_t data, size_t num_bits);
314};
315
316class SPIBus {
317 public:
318 SPIBus() = default;
319
320 SPIBus(GPIOPin *clk, GPIOPin *sdo, GPIOPin *sdi) : clk_pin_(clk), sdo_pin_(sdo), sdi_pin_(sdi) {}
321
322 virtual SPIDelegate *get_delegate(uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin,
323 bool release_device, bool write_only) {
324 return new SPIDelegateBitBash(data_rate, bit_order, mode, cs_pin, this->clk_pin_, this->sdo_pin_, this->sdi_pin_);
325 }
326
327 virtual bool is_hw() { return false; }
328
329 protected:
333};
334
335class SPIClient;
336
337class SPIComponent : public Component {
338 public:
339 SPIDelegate *register_device(SPIClient *device, SPIMode mode, SPIBitOrder bit_order, uint32_t data_rate,
340 GPIOPin *cs_pin, bool release_device, bool write_only);
341 void unregister_device(SPIClient *device);
342
343 void set_clk(GPIOPin *clk) { this->clk_pin_ = clk; }
344
345 void set_miso(GPIOPin *sdi) { this->sdi_pin_ = sdi; }
346
347 void set_mosi(GPIOPin *sdo) { this->sdo_pin_ = sdo; }
348 void set_data_pins(std::vector<uint8_t> pins) { this->data_pins_ = std::move(pins); }
349
350 void set_interface(SPIInterface interface) {
351 this->interface_ = interface;
352 this->using_hw_ = true;
353 }
354
355 void set_interface_name(const char *name) { this->interface_name_ = name; }
356
357 float get_setup_priority() const override { return setup_priority::BUS; }
358
359 void setup() override;
360 void dump_config() override;
361 size_t get_bus_width() const {
362 if (this->data_pins_.empty()) {
363 return 1;
364 }
365 return this->data_pins_.size();
366 }
367
368 protected:
369 GPIOPin *clk_pin_{nullptr};
370 GPIOPin *sdi_pin_{nullptr};
371 GPIOPin *sdo_pin_{nullptr};
372 std::vector<uint8_t> data_pins_{};
373
375 bool using_hw_{false};
376 const char *interface_name_{nullptr};
378 std::map<SPIClient *, SPIDelegate *> devices_;
379
380 static SPIBus *get_bus(SPIInterface interface, GPIOPin *clk, GPIOPin *sdo, GPIOPin *sdi,
381 const std::vector<uint8_t> &data_pins);
382};
383
390 public:
392 : bit_order_(bit_order), mode_(mode), data_rate_(data_rate) {}
393
394 virtual void spi_setup() {
395 esph_log_d("spi_device", "mode %u, data_rate %ukHz", (unsigned) this->mode_, (unsigned) (this->data_rate_ / 1000));
396 this->delegate_ = this->parent_->register_device(this, this->mode_, this->bit_order_, this->data_rate_, this->cs_,
397 this->release_device_, this->write_only_);
398 }
399
400 virtual void spi_teardown() {
401 this->parent_->unregister_device(this);
403 }
404
405 bool spi_is_ready() { return this->delegate_->is_ready(); }
406 void set_release_device(bool release) { this->release_device_ = release; }
407 void set_write_only(bool write_only) { this->write_only_ = write_only; }
408
409 protected:
414 GPIOPin *cs_{nullptr};
415 bool release_device_{false};
416 bool write_only_{false};
418};
419
428template<SPIBitOrder BIT_ORDER, SPIClockPolarity CLOCK_POLARITY, SPIClockPhase CLOCK_PHASE, SPIDataRate DATA_RATE>
429class SPIDevice : public SPIClient {
430 public:
431 SPIDevice() : SPIClient(BIT_ORDER, Utility::get_mode(CLOCK_POLARITY, CLOCK_PHASE), DATA_RATE) {}
432
433 SPIDevice(SPIComponent *parent, GPIOPin *cs_pin) {
434 this->set_spi_parent(parent);
435 this->set_cs_pin(cs_pin);
436 }
437
438 void spi_setup() override { SPIClient::spi_setup(); }
439
441
442 void set_spi_parent(SPIComponent *parent) { this->parent_ = parent; }
443
444 void set_cs_pin(GPIOPin *cs) { this->cs_ = cs; }
445
446 void set_data_rate(uint32_t data_rate) { this->data_rate_ = data_rate; }
447
448 void set_bit_order(SPIBitOrder order) { this->bit_order_ = order; }
449
450 void set_mode(SPIMode mode) { this->mode_ = mode; }
451
452 uint8_t read_byte() { return this->delegate_->transfer(0); }
453
454 void read_array(uint8_t *data, size_t length) { return this->delegate_->read_array(data, length); }
455
461 void write(uint16_t data, size_t num_bits) { this->delegate_->write(data, num_bits); };
462
463 /* Write command, address and data. Command and address will be written as single-bit SPI,
464 * data phase can be multiple bit (currently only 1 or 4)
465 * @param cmd_bits Number of bits to write in the command phase
466 * @param cmd The command value to write
467 * @param addr_bits Number of bits to write in addr phase
468 * @param address Address data
469 * @param data Plain data bytes
470 * @param length Number of data bytes
471 * @param bus_width The number of data lines to use for the data phase.
472 */
473 void write_cmd_addr_data(size_t cmd_bits, uint32_t cmd, size_t addr_bits, uint32_t address, const uint8_t *data,
474 size_t length, uint8_t bus_width = 1) {
475 this->delegate_->write_cmd_addr_data(cmd_bits, cmd, addr_bits, address, data, length, bus_width);
476 }
477
478 void write_byte(uint8_t data) { this->delegate_->write_array(&data, 1); }
479
485 void transfer_array(uint8_t *data, size_t length) { this->delegate_->transfer(data, length); }
486
487 uint8_t transfer_byte(uint8_t data) { return this->delegate_->transfer(data); }
488
491 void write_byte16(uint16_t data) { this->delegate_->write16(data); }
492
499 void write_array16(const uint16_t *data, size_t length) { this->delegate_->write_array16(data, length); }
500
501 void enable() { this->delegate_->begin_transaction(); }
502
503 void disable() { this->delegate_->end_transaction(); }
504
505 void write_array(const uint8_t *data, size_t length) { this->delegate_->write_array(data, length); }
506
507 template<size_t N> void write_array(const std::array<uint8_t, N> &data) { this->write_array(data.data(), N); }
508
509 void write_array(const std::vector<uint8_t> &data) { this->write_array(data.data(), data.size()); }
510
511 template<size_t N> void transfer_array(std::array<uint8_t, N> &data) { this->transfer_array(data.data(), N); }
512};
513
514} // namespace esphome::spi
BedjetMode mode
BedJet operating mode.
uint8_t address
Definition bl0906.h:4
virtual void setup()=0
virtual void digital_write(bool value)=0
virtual ESPDEPRECATED("Override dump_summary(char*, size_t) instead. Will be removed in 2026.7.0.", "2026.1.0") virtual std boo is_internal)()
Get a summary of this pin as a string.
Definition gpio.h:88
A pin to replace those that don't exist.
Definition spi.h:107
gpio::Flags get_flags() const override
Definition spi.h:119
static GPIOPin *const NULL_PIN
Definition spi.h:132
bool digital_read() override
Definition spi.h:121
void setup() override
Definition spi.h:115
void pin_mode(gpio::Flags flags) override
Definition spi.h:117
size_t dump_summary(char *buffer, size_t len) const override
Definition spi.h:125
void digital_write(bool value) override
Definition spi.h:123
virtual bool is_hw()
Definition spi.h:327
GPIOPin * sdo_pin_
Definition spi.h:331
GPIOPin * clk_pin_
Definition spi.h:330
SPIBus(GPIOPin *clk, GPIOPin *sdo, GPIOPin *sdi)
Definition spi.h:320
virtual SPIDelegate * get_delegate(uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin, bool release_device, bool write_only)
Definition spi.h:322
GPIOPin * sdi_pin_
Definition spi.h:332
Base class for SPIDevice, un-templated.
Definition spi.h:389
void set_release_device(bool release)
Definition spi.h:406
virtual void spi_teardown()
Definition spi.h:400
uint32_t data_rate_
Definition spi.h:412
void set_write_only(bool write_only)
Definition spi.h:407
SPIBitOrder bit_order_
Definition spi.h:410
SPIDelegate * delegate_
Definition spi.h:417
virtual void spi_setup()
Definition spi.h:394
SPIComponent * parent_
Definition spi.h:413
SPIClient(SPIBitOrder bit_order, SPIMode mode, uint32_t data_rate)
Definition spi.h:391
void setup() override
Definition spi.cpp:38
size_t get_bus_width() const
Definition spi.h:361
void set_interface(SPIInterface interface)
Definition spi.h:350
void unregister_device(SPIClient *device)
Definition spi.cpp:29
static SPIBus * get_bus(SPIInterface interface, GPIOPin *clk, GPIOPin *sdo, GPIOPin *sdi, const std::vector< uint8_t > &data_pins)
Definition spi.cpp:123
std::map< SPIClient *, SPIDelegate * > devices_
Definition spi.h:378
float get_setup_priority() const override
Definition spi.h:357
void set_clk(GPIOPin *clk)
Definition spi.h:343
void set_data_pins(std::vector< uint8_t > pins)
Definition spi.h:348
void dump_config() override
Definition spi.cpp:65
void set_miso(GPIOPin *sdi)
Definition spi.h:345
SPIInterface interface_
Definition spi.h:374
SPIDelegate * register_device(SPIClient *device, SPIMode mode, SPIBitOrder bit_order, uint32_t data_rate, GPIOPin *cs_pin, bool release_device, bool write_only)
Definition spi.cpp:17
const char * interface_name_
Definition spi.h:376
void set_interface_name(const char *name)
Definition spi.h:355
void set_mosi(GPIOPin *sdo)
Definition spi.h:347
std::vector< uint8_t > data_pins_
Definition spi.h:372
An implementation of SPI that relies only on software toggling of pins.
Definition spi.h:282
uint8_t transfer(uint8_t data) override
Definition spi.cpp:82
SPIClockPolarity clock_polarity_
Definition spi.h:305
SPIDelegateBitBash(uint32_t clock, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin, GPIOPin *clk_pin, GPIOPin *sdo_pin, GPIOPin *sdi_pin)
Definition spi.h:284
void write(uint16_t data, size_t num_bits) override
Definition spi.cpp:84
SPIClockPhase clock_phase_
Definition spi.h:306
uint16_t transfer_(uint16_t data, size_t num_bits)
Definition spi.cpp:86
void write16(uint16_t data) override
Definition spi.h:297
A dummy SPIDelegate that complains if it's used.
Definition spi.h:268
uint8_t transfer(uint8_t data) override
Definition spi.h:272
void end_transaction() override
Definition spi.h:273
void begin_transaction() override
Definition spi.cpp:80
virtual uint8_t transfer(uint8_t data)=0
SPIDelegate(uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin)
Definition spi.h:184
virtual void end_transaction()
Definition spi.h:198
virtual ~SPIDelegate()
Definition spi.h:192
virtual void begin_transaction()
Definition spi.h:195
virtual void read_array(uint8_t *ptr, size_t length)
Definition spi.h:248
virtual void write(uint16_t data, size_t num_bits)
write a variable length data item, up to 16 bits.
Definition spi.h:216
virtual bool is_ready()
Definition spi.cpp:13
virtual void transfer(uint8_t *ptr, size_t length)
Definition spi.h:204
virtual void write_array(const uint8_t *ptr, size_t length)
Definition spi.h:242
virtual void write_cmd_addr_data(size_t cmd_bits, uint32_t cmd, size_t addr_bits, uint32_t address, const uint8_t *data, size_t length, uint8_t bus_width)
Definition spi.h:220
SPIBitOrder bit_order_
Definition spi.h:257
virtual void write16(uint16_t data)
Definition spi.h:225
virtual void transfer(const uint8_t *txbuf, uint8_t *rxbuf, size_t length)
Definition spi.h:206
virtual void write_array16(const uint16_t *data, size_t length)
Definition spi.h:235
static SPIDelegate *const NULL_DELEGATE
Definition spi.h:261
The SPIDevice is what components using the SPI will create.
Definition spi.h:429
void set_data_rate(uint32_t data_rate)
Definition spi.h:446
void write_byte16(uint16_t data)
Write 16 bit data.
Definition spi.h:491
void write_array(const std::array< uint8_t, N > &data)
Definition spi.h:507
void spi_setup() override
Definition spi.h:438
void set_cs_pin(GPIOPin *cs)
Definition spi.h:444
void set_mode(SPIMode mode)
Definition spi.h:450
void transfer_array(uint8_t *data, size_t length)
Write the array data, replace with received data.
Definition spi.h:485
void set_bit_order(SPIBitOrder order)
Definition spi.h:448
void set_spi_parent(SPIComponent *parent)
Definition spi.h:442
void transfer_array(std::array< uint8_t, N > &data)
Definition spi.h:511
uint8_t read_byte()
Definition spi.h:452
void write_byte(uint8_t data)
Definition spi.h:478
void write(uint16_t data, size_t num_bits)
Write a single data item, up to 32 bits.
Definition spi.h:461
void write_array16(const uint16_t *data, size_t length)
Write an array of data as 16 bit values, byte-swapping if required.
Definition spi.h:499
uint8_t transfer_byte(uint8_t data)
Definition spi.h:487
void write_array(const uint8_t *data, size_t length)
Definition spi.h:505
void write_array(const std::vector< uint8_t > &data)
Definition spi.h:509
void write_cmd_addr_data(size_t cmd_bits, uint32_t cmd, size_t addr_bits, uint32_t address, const uint8_t *data, size_t length, uint8_t bus_width=1)
Definition spi.h:473
SPIDevice(SPIComponent *parent, GPIOPin *cs_pin)
Definition spi.h:433
void spi_teardown() override
Definition spi.h:440
void read_array(uint8_t *data, size_t length)
Definition spi.h:454
static int get_pin_no(GPIOPin *pin)
Definition spi.h:138
static SPIClockPhase get_phase(SPIMode mode)
Definition spi.h:153
static SPIClockPolarity get_polarity(SPIMode mode)
Definition spi.h:163
static SPIMode get_mode(SPIClockPolarity polarity, SPIClockPhase phase)
Definition spi.h:146
uint16_t flags
@ FLAG_NONE
Definition gpio.h:26
constexpr float BUS
For communication buses like i2c/spi.
Definition component.h:36
Implementation of SPI Controller mode.
Definition spi.cpp:5
SPIMode
Modes mapping to clock phase and polarity.
Definition spi.h:78
@ MODE0
Definition spi.h:79
@ MODE2
Definition spi.h:81
@ MODE1
Definition spi.h:80
@ MODE3
Definition spi.h:82
SPIDataRate
The SPI clock signal frequency, which determines the transfer bit rate/second.
Definition spi.h:89
@ DATA_RATE_200KHZ
Definition spi.h:92
@ DATA_RATE_20MHZ
Definition spi.h:99
@ DATA_RATE_1KHZ
Definition spi.h:90
@ DATA_RATE_2MHZ
Definition spi.h:94
@ DATA_RATE_5MHZ
Definition spi.h:96
@ DATA_RATE_8MHZ
Definition spi.h:97
@ DATA_RATE_80MHZ
Definition spi.h:101
@ DATA_RATE_10MHZ
Definition spi.h:98
@ DATA_RATE_4MHZ
Definition spi.h:95
@ DATA_RATE_1MHZ
Definition spi.h:93
@ DATA_RATE_40MHZ
Definition spi.h:100
@ DATA_RATE_75KHZ
Definition spi.h:91
SPIBitOrder
The bit-order for SPI devices. This defines how the data read from and written to the device is inter...
Definition spi.h:40
@ BIT_ORDER_LSB_FIRST
The least significant bit is transmitted/received first.
Definition spi.h:42
@ BIT_ORDER_MSB_FIRST
The most significant bit is transmitted/received first.
Definition spi.h:44
SPIClockPolarity
The SPI clock signal polarity,.
Definition spi.h:50
@ CLOCK_POLARITY_HIGH
The clock signal idles on HIGH.
Definition spi.h:60
@ CLOCK_POLARITY_LOW
The clock signal idles on LOW.
Definition spi.h:55
SPIClockPhase
The SPI clock signal phase.
Definition spi.h:66
@ CLOCK_PHASE_LEADING
The data is sampled on a leading clock edge. (CPHA=0)
Definition spi.h:68
@ CLOCK_PHASE_TRAILING
The data is sampled on a trailing clock edge. (CPHA=1)
Definition spi.h:70
uint32_t arch_get_cpu_cycle_count()
Definition core.cpp:56
std::string size_t len
Definition helpers.h:1045
uint32_t arch_get_cpu_freq_hz()
Definition core.cpp:57
static void uint32_t
spi_host_device_t SPIInterface
Definition spi.h:14
uint16_t length
Definition tt21100.cpp:0