ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
spi.h
Go to the documentation of this file.
1#pragma once
4#include "esphome/core/hal.h"
6#include "esphome/core/log.h"
7#include <map>
8#include <utility>
9#include <vector>
10
11#ifdef USE_ESP32
12
13#include "driver/spi_master.h"
14
15using SPIInterface = spi_host_device_t;
16
17#elif defined(USE_ARDUINO) && !defined(USE_LIBRETINY)
18
19#include <SPI.h>
20
21#ifdef USE_RP2
22using SPIInterface = SPIClassRP2040 *;
23#else
24using SPIInterface = SPIClass *;
25#endif
26
27#elif defined(USE_ZEPHYR)
28
29struct device;
30using SPIInterface = const device *;
31
32#elif defined(USE_HOST) || defined(CLANG_TIDY)
33
34using SPIInterface = void *; // Stub for platforms without SPI (e.g., host)
35
36#endif // USE_ESP32 / USE_ARDUINO
37
41namespace esphome::spi {
42
43#define LOG_SPI_DEVICE(this) ESP_LOGCONFIG(TAG, " CS Pin: %d", esphome::spi::Utility::get_pin_no(this->cs_));
44
78
84enum SPIMode {
85 MODE0 = 0,
86 MODE1 = 1,
87 MODE2 = 2,
88 MODE3 = 3,
89};
109
113class NullPin : public GPIOPin {
114 friend class SPIComponent;
115
116 friend class SPIDelegate;
117
118 friend class Utility;
119
120 public:
121 void setup() override {}
122
123 void pin_mode(gpio::Flags flags) override {}
124
125 gpio::Flags get_flags() const override { return gpio::Flags::FLAG_NONE; }
126
127 bool digital_read() override { return false; }
128
129 void digital_write(bool value) override {}
130
131 size_t dump_summary(char *buffer, size_t len) const override {
132 if (len > 0)
133 buffer[0] = '\0';
134 return 0;
135 }
136
137 protected:
138 static GPIOPin *const NULL_PIN; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
139 // https://bugs.llvm.org/show_bug.cgi?id=48040
140};
141
142class Utility {
143 public:
144 static int get_pin_no(GPIOPin *pin) {
145 if (pin == nullptr || !pin->is_internal())
146 return -1;
147 if (((InternalGPIOPin *) pin)->is_inverted())
148 return -1;
149 return ((InternalGPIOPin *) pin)->get_pin();
150 }
151
153 if (polarity == CLOCK_POLARITY_HIGH) {
154 return phase == CLOCK_PHASE_LEADING ? MODE2 : MODE3;
155 }
156 return phase == CLOCK_PHASE_LEADING ? MODE0 : MODE1;
157 }
158
160 switch (mode) {
161 case MODE0:
162 case MODE2:
163 return CLOCK_PHASE_LEADING;
164 default:
166 }
167 }
168
170 switch (mode) {
171 case MODE0:
172 case MODE1:
173 return CLOCK_POLARITY_LOW;
174 default:
175 return CLOCK_POLARITY_HIGH;
176 }
177 }
178};
179
180class SPIDelegateDummy;
181
182// represents a device attached to an SPI bus, with a defined clock rate, mode and bit order. On Arduino this is
183// a thin wrapper over SPIClass.
185 friend class SPIClient;
186 friend class SPIComponent; // hands out NULL_DELEGATE for a failed bus
187
188 public:
189 SPIDelegate() = default;
190
191 SPIDelegate(uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin)
192 : bit_order_(bit_order), data_rate_(data_rate), mode_(mode), cs_pin_(cs_pin) {
193 if (this->cs_pin_ == nullptr)
195 this->cs_pin_->setup();
196 this->cs_pin_->digital_write(true);
197 }
198
199 virtual ~SPIDelegate() {};
200
201 // enable CS if configured.
202 virtual void begin_transaction() { this->cs_pin_->digital_write(false); }
203
204 // end the transaction
205 virtual void end_transaction() { this->cs_pin_->digital_write(true); }
206
207 // transfer one byte, return the byte that was read.
208 virtual uint8_t transfer(uint8_t data) = 0;
209
210 // transfer a buffer, replace the contents with read data
211 virtual void transfer(uint8_t *ptr, size_t length) { this->transfer(ptr, ptr, length); }
212
213 virtual void transfer(const uint8_t *txbuf, uint8_t *rxbuf, size_t length) {
214 for (size_t i = 0; i != length; i++)
215 rxbuf[i] = this->transfer(txbuf[i]);
216 }
217
223 virtual void write(uint16_t data, size_t num_bits) {
224 esph_log_e("spi_device", "variable length write not implemented");
225 }
226
227 virtual void write_cmd_addr_data(size_t cmd_bits, uint32_t cmd, size_t addr_bits, uint32_t address,
228 const uint8_t *data, size_t length, uint8_t bus_width) {
229 esph_log_e("spi_device", "write_cmd_addr_data not implemented");
230 }
231 // write 16 bits
232 virtual void write16(uint16_t data) {
233 if (this->bit_order_ == BIT_ORDER_MSB_FIRST) {
234 uint16_t buffer = byteswap(data);
235 this->write_array(reinterpret_cast<const uint8_t *>(&buffer), 2);
236 } else {
237 this->write_array(reinterpret_cast<const uint8_t *>(&data), 2);
238 }
239 }
240
241 virtual void write_array16(const uint16_t *data, size_t length) {
242 for (size_t i = 0; i != length; i++) {
243 this->write16(data[i]);
244 }
245 }
246
247 // write the contents of a buffer, ignore read data (buffer is unchanged.)
248 virtual void write_array(const uint8_t *ptr, size_t length) {
249 for (size_t i = 0; i != length; i++)
250 this->transfer(ptr[i]);
251 }
252
253 // read into a buffer, write nulls
254 virtual void read_array(uint8_t *ptr, size_t length) {
255 for (size_t i = 0; i != length; i++)
256 ptr[i] = this->transfer(0);
257 }
258
259 // check if device is ready
260 virtual bool is_ready();
261
262#ifdef USE_SPI_PSRAM_DMA
263 void set_psram_dma(bool enable) { this->psram_dma_ = enable; }
264#endif
265
266 protected:
271#ifdef USE_SPI_PSRAM_DMA
272 bool psram_dma_{false};
273#endif
274 static SPIDelegate *const NULL_DELEGATE; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
275};
276
282 public:
283 SPIDelegateDummy() = default;
284
285 uint8_t transfer(uint8_t data) override { return 0; }
286 void end_transaction() override {};
287
288 void begin_transaction() override;
289};
290
296 public:
297 SPIDelegateBitBash(uint32_t clock, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin, GPIOPin *clk_pin,
298 GPIOPin *sdo_pin, GPIOPin *sdi_pin)
299 : SPIDelegate(clock, bit_order, mode, cs_pin), clk_pin_(clk_pin), sdo_pin_(sdo_pin), sdi_pin_(sdi_pin) {
300 // this calculation is pretty meaningless except at very low bit rates.
301 this->wait_cycle_ = uint32_t(arch_get_cpu_freq_hz()) / this->data_rate_ / 2ULL;
304 }
305
306 uint8_t transfer(uint8_t data) override;
307
308 void write(uint16_t data, size_t num_bits) override;
309
310 void write16(uint16_t data) override { this->write(data, 16); };
311
312 protected:
320
321 void HOT cycle_clock_() {
322 while (this->last_transition_ - arch_get_cpu_cycle_count() < this->wait_cycle_)
323 continue;
324 this->last_transition_ += this->wait_cycle_;
325 }
326 uint16_t transfer_(uint16_t data, size_t num_bits);
327};
328
329class SPIBus {
330 public:
331 SPIBus() = default;
332
333 SPIBus(GPIOPin *clk, GPIOPin *sdo, GPIOPin *sdi) : clk_pin_(clk), sdo_pin_(sdo), sdi_pin_(sdi) {}
334
335 virtual SPIDelegate *get_delegate(uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin,
336 bool release_device, bool write_only) {
337 return new SPIDelegateBitBash(data_rate, bit_order, mode, cs_pin, this->clk_pin_, this->sdo_pin_, this->sdi_pin_);
338 }
339
340 virtual bool is_hw() { return false; }
341
342 protected:
346};
347
348class SPIClient;
349
350class SPIComponent final : public Component {
351 public:
352 SPIDelegate *register_device(SPIClient *device, SPIMode mode, SPIBitOrder bit_order, uint32_t data_rate,
353 GPIOPin *cs_pin, bool release_device, bool write_only);
354 void unregister_device(SPIClient *device);
355
356 void set_clk(GPIOPin *clk) { this->clk_pin_ = clk; }
357
358 void set_miso(GPIOPin *sdi) { this->sdi_pin_ = sdi; }
359
360 void set_mosi(GPIOPin *sdo) { this->sdo_pin_ = sdo; }
361 void set_data_pins(std::vector<uint8_t> pins) { this->data_pins_ = std::move(pins); }
362
363 void set_interface(SPIInterface interface) {
364 this->interface_ = interface;
365 this->using_hw_ = true;
366 }
367
368 SPIInterface get_interface() const { return this->interface_; }
369
370 void set_interface_name(const char *name) { this->interface_name_ = name; }
371
372 float get_setup_priority() const override { return setup_priority::BUS; }
373
374 void setup() override;
375 void dump_config() override;
376 size_t get_bus_width() const {
377 if (this->data_pins_.empty()) {
378 return 1;
379 }
380 return this->data_pins_.size();
381 }
382
383 protected:
384 GPIOPin *clk_pin_{nullptr};
385 GPIOPin *sdi_pin_{nullptr};
386 GPIOPin *sdo_pin_{nullptr};
387 std::vector<uint8_t> data_pins_{};
388
390 bool using_hw_{false};
391 const char *interface_name_{nullptr};
393 std::map<SPIClient *, SPIDelegate *> devices_;
394
395 static SPIBus *get_bus(SPIInterface interface, GPIOPin *clk, GPIOPin *sdo, GPIOPin *sdi,
396 const std::vector<uint8_t> &data_pins);
397};
398
405 public:
407 : bit_order_(bit_order), mode_(mode), data_rate_(data_rate) {}
408
409 virtual void spi_setup() {
410 esph_log_d("spi_device", "mode %u, data_rate %ukHz", (unsigned) this->mode_, (unsigned) (this->data_rate_ / 1000));
411 this->delegate_ = this->parent_->register_device(this, this->mode_, this->bit_order_, this->data_rate_, this->cs_,
412 this->release_device_, this->write_only_);
413#ifdef USE_SPI_PSRAM_DMA
414 this->delegate_->set_psram_dma(this->psram_dma_);
415 if (this->psram_dma_) {
416 esph_log_config("spi_device", "PSRAM DMA: enabled");
417 }
418#endif
419 }
420
421 virtual void spi_teardown() {
422 this->parent_->unregister_device(this);
424 }
425
426 bool spi_is_ready() { return this->delegate_->is_ready(); }
427 void set_release_device(bool release) { this->release_device_ = release; }
428 void set_write_only(bool write_only) { this->write_only_ = write_only; }
429#ifdef USE_SPI_PSRAM_DMA
430 void set_psram_dma(bool enable) { this->psram_dma_ = enable; }
431#endif
432
433 protected:
438 GPIOPin *cs_{nullptr};
439 bool release_device_{false};
440 bool write_only_{false};
441#ifdef USE_SPI_PSRAM_DMA
442 bool psram_dma_{false};
443#endif
445};
446
455template<SPIBitOrder BIT_ORDER, SPIClockPolarity CLOCK_POLARITY, SPIClockPhase CLOCK_PHASE, SPIDataRate DATA_RATE>
456class SPIDevice : public SPIClient {
457 public:
458 SPIDevice() : SPIClient(BIT_ORDER, Utility::get_mode(CLOCK_POLARITY, CLOCK_PHASE), DATA_RATE) {}
459
460 SPIDevice(SPIComponent *parent, GPIOPin *cs_pin) {
461 this->set_spi_parent(parent);
462 this->set_cs_pin(cs_pin);
463 }
464
465 void spi_setup() override { SPIClient::spi_setup(); }
466
468
469 void set_spi_parent(SPIComponent *parent) { this->parent_ = parent; }
470
471 void set_cs_pin(GPIOPin *cs) { this->cs_ = cs; }
472
473 void set_data_rate(uint32_t data_rate) { this->data_rate_ = data_rate; }
474
475 void set_bit_order(SPIBitOrder order) { this->bit_order_ = order; }
476
477 void set_mode(SPIMode mode) { this->mode_ = mode; }
478
479 uint8_t read_byte() { return this->delegate_->transfer(0); }
480
481 void read_array(uint8_t *data, size_t length) { this->delegate_->read_array(data, length); }
482
488 void write(uint16_t data, size_t num_bits) { this->delegate_->write(data, num_bits); };
489
490 /* Write command, address and data. Command and address will be written as single-bit SPI,
491 * data phase can be multiple bit (currently only 1 or 4)
492 * @param cmd_bits Number of bits to write in the command phase
493 * @param cmd The command value to write
494 * @param addr_bits Number of bits to write in addr phase
495 * @param address Address data
496 * @param data Plain data bytes
497 * @param length Number of data bytes
498 * @param bus_width The number of data lines to use for the data phase.
499 */
500 void write_cmd_addr_data(size_t cmd_bits, uint32_t cmd, size_t addr_bits, uint32_t address, const uint8_t *data,
501 size_t length, uint8_t bus_width = 1) {
502 this->delegate_->write_cmd_addr_data(cmd_bits, cmd, addr_bits, address, data, length, bus_width);
503 }
504
505 void write_byte(uint8_t data) { this->delegate_->write_array(&data, 1); }
506
512 void transfer_array(uint8_t *data, size_t length) { this->delegate_->transfer(data, length); }
513
514 uint8_t transfer_byte(uint8_t data) { return this->delegate_->transfer(data); }
515
518 void write_byte16(uint16_t data) { this->delegate_->write16(data); }
519
526 void write_array16(const uint16_t *data, size_t length) { this->delegate_->write_array16(data, length); }
527
528 void enable() { this->delegate_->begin_transaction(); }
529
530 void disable() { this->delegate_->end_transaction(); }
531
532 void write_array(const uint8_t *data, size_t length) { this->delegate_->write_array(data, length); }
533
534 template<size_t N> void write_array(const std::array<uint8_t, N> &data) { this->write_array(data.data(), N); }
535
536 void write_array(const std::vector<uint8_t> &data) { this->write_array(data.data(), data.size()); }
537
538 template<size_t N> void transfer_array(std::array<uint8_t, N> &data) { this->transfer_array(data.data(), N); }
539};
540
541} // 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 bool is_internal()
Only the platform pin class behind the InternalGPIOPin alias may return true: callers static_cast to ...
Definition gpio_pin.h:87
A pin to replace those that don't exist.
Definition spi.h:113
gpio::Flags get_flags() const override
Definition spi.h:125
static GPIOPin *const NULL_PIN
Definition spi.h:138
bool digital_read() override
Definition spi.h:127
void setup() override
Definition spi.h:121
void pin_mode(gpio::Flags flags) override
Definition spi.h:123
size_t dump_summary(char *buffer, size_t len) const override
Definition spi.h:131
void digital_write(bool value) override
Definition spi.h:129
virtual bool is_hw()
Definition spi.h:340
GPIOPin * sdo_pin_
Definition spi.h:344
GPIOPin * clk_pin_
Definition spi.h:343
SPIBus(GPIOPin *clk, GPIOPin *sdo, GPIOPin *sdi)
Definition spi.h:333
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:335
GPIOPin * sdi_pin_
Definition spi.h:345
Base class for SPIDevice, un-templated.
Definition spi.h:404
void set_release_device(bool release)
Definition spi.h:427
virtual void spi_teardown()
Definition spi.h:421
uint32_t data_rate_
Definition spi.h:436
void set_write_only(bool write_only)
Definition spi.h:428
SPIBitOrder bit_order_
Definition spi.h:434
SPIDelegate * delegate_
Definition spi.h:444
virtual void spi_setup()
Definition spi.h:409
void set_psram_dma(bool enable)
Definition spi.h:430
SPIComponent * parent_
Definition spi.h:437
SPIClient(SPIBitOrder bit_order, SPIMode mode, uint32_t data_rate)
Definition spi.h:406
void setup() override
Definition spi.cpp:48
size_t get_bus_width() const
Definition spi.h:376
void set_interface(SPIInterface interface)
Definition spi.h:363
SPIInterface get_interface() const
Definition spi.h:368
void unregister_device(SPIClient *device)
Definition spi.cpp:36
static SPIBus * get_bus(SPIInterface interface, GPIOPin *clk, GPIOPin *sdo, GPIOPin *sdi, const std::vector< uint8_t > &data_pins)
Definition spi.cpp:136
std::map< SPIClient *, SPIDelegate * > devices_
Definition spi.h:393
float get_setup_priority() const override
Definition spi.h:372
void set_clk(GPIOPin *clk)
Definition spi.h:356
void set_data_pins(std::vector< uint8_t > pins)
Definition spi.h:361
void dump_config() override
Definition spi.cpp:75
void set_miso(GPIOPin *sdi)
Definition spi.h:358
SPIInterface interface_
Definition spi.h:389
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:21
const char * interface_name_
Definition spi.h:391
void set_interface_name(const char *name)
Definition spi.h:370
void set_mosi(GPIOPin *sdo)
Definition spi.h:360
std::vector< uint8_t > data_pins_
Definition spi.h:387
An implementation of SPI that relies only on software toggling of pins.
Definition spi.h:295
uint8_t transfer(uint8_t data) override
Definition spi.cpp:95
SPIClockPolarity clock_polarity_
Definition spi.h:318
SPIDelegateBitBash(uint32_t clock, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin, GPIOPin *clk_pin, GPIOPin *sdo_pin, GPIOPin *sdi_pin)
Definition spi.h:297
void write(uint16_t data, size_t num_bits) override
Definition spi.cpp:97
SPIClockPhase clock_phase_
Definition spi.h:319
uint16_t transfer_(uint16_t data, size_t num_bits)
Definition spi.cpp:99
void write16(uint16_t data) override
Definition spi.h:310
A dummy SPIDelegate that complains if it's used.
Definition spi.h:281
uint8_t transfer(uint8_t data) override
Definition spi.h:285
void end_transaction() override
Definition spi.h:286
void begin_transaction() override
Definition spi.cpp:93
virtual uint8_t transfer(uint8_t data)=0
SPIDelegate(uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin)
Definition spi.h:191
virtual void end_transaction()
Definition spi.h:205
virtual ~SPIDelegate()
Definition spi.h:199
void set_psram_dma(bool enable)
Definition spi.h:263
virtual void begin_transaction()
Definition spi.h:202
virtual void read_array(uint8_t *ptr, size_t length)
Definition spi.h:254
virtual void write(uint16_t data, size_t num_bits)
write a variable length data item, up to 16 bits.
Definition spi.h:223
virtual bool is_ready()
Definition spi.cpp:17
virtual void transfer(uint8_t *ptr, size_t length)
Definition spi.h:211
virtual void write_array(const uint8_t *ptr, size_t length)
Definition spi.h:248
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:227
SPIBitOrder bit_order_
Definition spi.h:267
virtual void write16(uint16_t data)
Definition spi.h:232
virtual void transfer(const uint8_t *txbuf, uint8_t *rxbuf, size_t length)
Definition spi.h:213
virtual void write_array16(const uint16_t *data, size_t length)
Definition spi.h:241
static SPIDelegate *const NULL_DELEGATE
Definition spi.h:274
The SPIDevice is what components using the SPI will create.
Definition spi.h:456
void set_data_rate(uint32_t data_rate)
Definition spi.h:473
void write_byte16(uint16_t data)
Write 16 bit data.
Definition spi.h:518
void write_array(const std::array< uint8_t, N > &data)
Definition spi.h:534
void spi_setup() override
Definition spi.h:465
void set_cs_pin(GPIOPin *cs)
Definition spi.h:471
void set_mode(SPIMode mode)
Definition spi.h:477
void transfer_array(uint8_t *data, size_t length)
Write the array data, replace with received data.
Definition spi.h:512
void set_bit_order(SPIBitOrder order)
Definition spi.h:475
void set_spi_parent(SPIComponent *parent)
Definition spi.h:469
void transfer_array(std::array< uint8_t, N > &data)
Definition spi.h:538
uint8_t read_byte()
Definition spi.h:479
void write_byte(uint8_t data)
Definition spi.h:505
void write(uint16_t data, size_t num_bits)
Write a single data item, up to 32 bits.
Definition spi.h:488
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:526
uint8_t transfer_byte(uint8_t data)
Definition spi.h:514
void write_array(const uint8_t *data, size_t length)
Definition spi.h:532
void write_array(const std::vector< uint8_t > &data)
Definition spi.h:536
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:500
SPIDevice(SPIComponent *parent, GPIOPin *cs_pin)
Definition spi.h:460
void spi_teardown() override
Definition spi.h:467
void read_array(uint8_t *data, size_t length)
Definition spi.h:481
static int get_pin_no(GPIOPin *pin)
Definition spi.h:144
static SPIClockPhase get_phase(SPIMode mode)
Definition spi.h:159
static SPIClockPolarity get_polarity(SPIMode mode)
Definition spi.h:169
static SPIMode get_mode(SPIClockPolarity polarity, SPIClockPhase phase)
Definition spi.h:152
uint16_t flags
uint32_t buffer
Definition gif.cpp:50
constexpr float BUS
For communication buses like i2c/spi.
Definition component.h:39
Implementation of SPI Controller mode.
Definition spi.cpp:9
SPIMode
Modes mapping to clock phase and polarity.
Definition spi.h:84
@ MODE0
Definition spi.h:85
@ MODE2
Definition spi.h:87
@ MODE1
Definition spi.h:86
@ MODE3
Definition spi.h:88
SPIDataRate
The SPI clock signal frequency, which determines the transfer bit rate/second.
Definition spi.h:95
@ DATA_RATE_200KHZ
Definition spi.h:98
@ DATA_RATE_20MHZ
Definition spi.h:105
@ DATA_RATE_1KHZ
Definition spi.h:96
@ DATA_RATE_2MHZ
Definition spi.h:100
@ DATA_RATE_5MHZ
Definition spi.h:102
@ DATA_RATE_8MHZ
Definition spi.h:103
@ DATA_RATE_80MHZ
Definition spi.h:107
@ DATA_RATE_10MHZ
Definition spi.h:104
@ DATA_RATE_4MHZ
Definition spi.h:101
@ DATA_RATE_1MHZ
Definition spi.h:99
@ DATA_RATE_40MHZ
Definition spi.h:106
@ DATA_RATE_75KHZ
Definition spi.h:97
SPIBitOrder
The bit-order for SPI devices. This defines how the data read from and written to the device is inter...
Definition spi.h:46
@ BIT_ORDER_LSB_FIRST
The least significant bit is transmitted/received first.
Definition spi.h:48
@ BIT_ORDER_MSB_FIRST
The most significant bit is transmitted/received first.
Definition spi.h:50
SPIClockPolarity
The SPI clock signal polarity,.
Definition spi.h:56
@ CLOCK_POLARITY_HIGH
The clock signal idles on HIGH.
Definition spi.h:66
@ CLOCK_POLARITY_LOW
The clock signal idles on LOW.
Definition spi.h:61
SPIClockPhase
The SPI clock signal phase.
Definition spi.h:72
@ CLOCK_PHASE_LEADING
The data is sampled on a leading clock edge. (CPHA=0)
Definition spi.h:74
@ CLOCK_PHASE_TRAILING
The data is sampled on a trailing clock edge. (CPHA=1)
Definition spi.h:76
uint32_t arch_get_cpu_cycle_count()
Definition hal.cpp:71
const void size_t len
Definition hal.h:68
uint32_t arch_get_cpu_freq_hz()
Definition hal.cpp:55
static void uint32_t
spi_host_device_t SPIInterface
Definition spi.h:15
void byteswap()
uint16_t length
Definition tt21100.cpp:0