idfxx 1.0.0
Modern C++23 components for ESP-IDF
Loading...
Searching...
No Matches
master.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Chris Leishman
3
4#pragma once
5
22#include <idfxx/cpu>
23#include <idfxx/error>
24#include <idfxx/flags>
25#include <idfxx/future>
26#include <idfxx/gpio>
27#include <idfxx/intr_alloc>
28
29#include <atomic>
30#include <chrono>
31#include <cstdint>
32#include <driver/spi_master.h>
33#include <esp_idf_version.h>
34#include <frequency/frequency>
35#include <memory>
36#include <optional>
37#include <span>
38#include <string>
39#include <vector>
40
45namespace idfxx::spi {
46
51enum class host_device : int {
52 spi1 = SPI1_HOST,
53 spi2 = SPI2_HOST,
54#if SOC_SPI_PERIPH_NUM > 2
55 spi3 = SPI3_HOST,
56#endif
57};
58
63enum class dma_chan : int {
64 disabled = SPI_DMA_DISABLED,
65#if CONFIG_IDF_TARGET_ESP32
66 ch_1 = SPI_DMA_CH1,
67 ch_2 = SPI_DMA_CH2,
68#endif
69 ch_auto = SPI_DMA_CH_AUTO,
70};
71
81enum class bus_flags : uint32_t {
82 slave = SPICOMMON_BUSFLAG_SLAVE,
83 master = SPICOMMON_BUSFLAG_MASTER,
84 iomux_pins = SPICOMMON_BUSFLAG_IOMUX_PINS,
85 sclk = SPICOMMON_BUSFLAG_SCLK,
86 miso = SPICOMMON_BUSFLAG_MISO,
87 mosi = SPICOMMON_BUSFLAG_MOSI,
88 dual =
89 SPICOMMON_BUSFLAG_DUAL,
90 wphd = SPICOMMON_BUSFLAG_WPHD,
91 quad = SPICOMMON_BUSFLAG_QUAD,
93 io4_io7 = SPICOMMON_BUSFLAG_IO4_IO7,
94 octal = SPICOMMON_BUSFLAG_OCTAL,
96 native_pins = SPICOMMON_BUSFLAG_NATIVE_PINS,
97 slp_allow_pd = SPICOMMON_BUSFLAG_SLP_ALLOW_PD,
99};
100
108enum class device_flags : uint32_t {
109 txbit_lsbfirst = SPI_DEVICE_TXBIT_LSBFIRST,
110 rxbit_lsbfirst = SPI_DEVICE_RXBIT_LSBFIRST,
111 bit_lsbfirst = SPI_DEVICE_BIT_LSBFIRST,
112 three_wire = SPI_DEVICE_3WIRE,
113 positive_cs = SPI_DEVICE_POSITIVE_CS,
114 halfduplex = SPI_DEVICE_HALFDUPLEX,
115 clk_as_cs = SPI_DEVICE_CLK_AS_CS,
116 no_dummy = SPI_DEVICE_NO_DUMMY,
117 ddrclk = SPI_DEVICE_DDRCLK,
118 no_return_result = SPI_DEVICE_NO_RETURN_RESULT,
119};
120
128enum class trans_flags : uint32_t {
129 mode_dio = SPI_TRANS_MODE_DIO,
130 mode_qio = SPI_TRANS_MODE_QIO,
131 mode_oct = SPI_TRANS_MODE_OCT,
132 use_rxdata = SPI_TRANS_USE_RXDATA,
133 use_txdata = SPI_TRANS_USE_TXDATA,
134 multiline_addr = SPI_TRANS_MULTILINE_ADDR,
135 multiline_cmd = SPI_TRANS_MULTILINE_CMD,
136 variable_cmd = SPI_TRANS_VARIABLE_CMD,
137 variable_addr = SPI_TRANS_VARIABLE_ADDR,
138 variable_dummy = SPI_TRANS_VARIABLE_DUMMY,
139 cs_keep_active = SPI_TRANS_CS_KEEP_ACTIVE,
140 dma_buffer_align_manual = SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL,
141#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0)
142 dma_use_psram = SPI_TRANS_DMA_USE_PSRAM,
143#endif
144};
145
146} // namespace idfxx::spi
147
148template<>
149inline constexpr bool idfxx::enable_flags_operators<idfxx::spi::bus_flags> = true;
150
151template<>
152inline constexpr bool idfxx::enable_flags_operators<idfxx::spi::device_flags> = true;
153
154template<>
155inline constexpr bool idfxx::enable_flags_operators<idfxx::spi::trans_flags> = true;
156
157namespace idfxx::spi {
158
177 uint16_t cmd = 0;
178 uint64_t addr = 0;
179 std::span<const uint8_t> tx_buffer = {};
180 std::span<uint8_t> rx_buffer = {};
181 size_t length = 0;
182 size_t rx_length = 0;
183 freq::hertz override_freq{0};
184 uint8_t command_bits = 0;
185 uint8_t address_bits = 0;
186 uint8_t dummy_bits = 0;
187};
188
189class master_device;
190
246
257public:
258#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
269 [[nodiscard]] explicit master_bus(enum host_device host, enum dma_chan dma_chan, struct bus_config config);
270#endif
271
281 [[nodiscard]] static result<master_bus>
282 make(enum host_device host, enum dma_chan dma_chan, struct bus_config config);
283
285
286 master_bus(const master_bus&) = delete;
287 master_bus& operator=(const master_bus&) = delete;
288
290 master_bus(master_bus&& other) noexcept;
291
293 master_bus& operator=(master_bus&& other) noexcept;
294
296 [[nodiscard]] enum host_device host() const { return _host; }
297
306 [[nodiscard]] size_t max_transaction_length() const;
307
308private:
309 explicit master_bus(enum host_device host);
310
311 enum host_device _host;
312 bool _initialized = true;
313};
314
341public:
355 struct config {
356 uint8_t command_bits = 0;
357 uint8_t address_bits = 0;
358 uint8_t dummy_bits = 0;
359 uint8_t mode = 0;
360 uint16_t duty_cycle_pos = 0;
361 uint16_t cs_ena_pretrans = 0;
362 uint8_t cs_ena_posttrans = 0;
363 freq::hertz clock_speed{0};
364 std::chrono::nanoseconds input_delay{0};
367 int queue_size = 1;
368 };
369
370#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
391 [[nodiscard]] explicit master_device(master_bus& bus, const struct config& config);
392#endif
393
413 [[nodiscard]] static result<master_device> make(master_bus& bus, const struct config& config);
414
416
417 master_device(const master_device&) = delete;
419 master_device(master_device&& other) noexcept;
421
422 // =========================================================================
423 // Accessors
424 // =========================================================================
425
430 [[nodiscard]] master_bus& bus() const {
431 assert(_bus != nullptr);
432 return *_bus;
433 }
434
436 [[nodiscard]] spi_device_handle_t idf_handle() const { return _handle; }
437
447 [[nodiscard]] freq::hertz frequency() const;
448
449 // =========================================================================
450 // Simple API (byte-oriented, blocking)
451 // =========================================================================
452
453#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
467 void transmit(std::span<const uint8_t> tx_data) { unwrap(try_transmit(tx_data)); }
468
477 void receive(std::span<uint8_t> rx_data) { unwrap(try_receive(rx_data)); }
478
493 [[nodiscard]] std::vector<uint8_t> receive(size_t size) { return unwrap(try_receive(size)); }
494
510 void transfer(std::span<const uint8_t> tx_data, std::span<uint8_t> rx_data) {
511 unwrap(try_transfer(tx_data, rx_data));
512 }
513#endif
514
522 [[nodiscard]] result<void> try_transmit(std::span<const uint8_t> tx_data);
523
531 [[nodiscard]] result<void> try_receive(std::span<uint8_t> rx_data);
532
540 [[nodiscard]] result<std::vector<uint8_t>> try_receive(size_t size);
541
550 [[nodiscard]] result<void> try_transfer(std::span<const uint8_t> tx_data, std::span<uint8_t> rx_data);
551
552 // =========================================================================
553 // Full transaction API (blocking)
554 // =========================================================================
555
556#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
565 void transmit(const transaction& trans) { unwrap(try_transmit(trans)); }
566#endif
567
575 [[nodiscard]] result<void> try_transmit(const transaction& trans);
576
577 // =========================================================================
578 // Polling API (busy-wait)
579 // =========================================================================
580
581#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
592 void polling_transmit(std::span<const uint8_t> tx_data) { unwrap(try_polling_transmit(tx_data)); }
593
604 void polling_receive(std::span<uint8_t> rx_data) { unwrap(try_polling_receive(rx_data)); }
605
618 [[nodiscard]] std::vector<uint8_t> polling_receive(size_t size) { return unwrap(try_polling_receive(size)); }
619
631 void polling_transfer(std::span<const uint8_t> tx_data, std::span<uint8_t> rx_data) {
632 unwrap(try_polling_transfer(tx_data, rx_data));
633 }
634
646#endif
647
658 [[nodiscard]] result<void> try_polling_transmit(std::span<const uint8_t> tx_data);
659
670 [[nodiscard]] result<void> try_polling_receive(std::span<uint8_t> rx_data);
671
683
695 [[nodiscard]] result<void> try_polling_transfer(std::span<const uint8_t> tx_data, std::span<uint8_t> rx_data);
696
707 [[nodiscard]] result<void> try_polling_transmit(const transaction& trans);
708
709 // =========================================================================
710 // Async queue API
711 // =========================================================================
712
713#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
736 [[nodiscard]] idfxx::future<void> queue_trans(const transaction& trans) { return unwrap(try_queue_trans(trans)); }
737
751 template<typename Rep, typename Period>
752 [[nodiscard]] idfxx::future<void>
753 queue_trans(const transaction& trans, const std::chrono::duration<Rep, Period>& timeout) {
754 return unwrap(try_queue_trans(trans, timeout));
755 }
756
757#endif
758
776
787 template<typename Rep, typename Period>
788 [[nodiscard]] result<idfxx::future<void>>
789 try_queue_trans(const transaction& trans, const std::chrono::duration<Rep, Period>& timeout) {
790 return _try_queue_trans(trans, std::chrono::ceil<std::chrono::milliseconds>(timeout));
791 }
792
793 // =========================================================================
794 // Bus exclusivity (Lockable interface)
795 // =========================================================================
796
819 void lock() const;
820
830 [[nodiscard]] bool try_lock() const noexcept;
831
837 void unlock() const;
838
839private:
840 // Opaque async state held in the .cpp. master_device keeps a single
841 // unique_ptr to it, so the class stays cheap to move while the mutexes,
842 // condition variable, and slot pool keep a stable address across the
843 // device's lifetime.
844 struct async_state;
845
846 explicit master_device(master_bus* bus, spi_device_handle_t handle, size_t queue_size);
847
848 void _delete() noexcept;
849
850 using _trans_fn = esp_err_t (*)(spi_device_handle_t, spi_transaction_t*);
851
852 [[nodiscard]] result<void> _simple_trans(std::span<const uint8_t> tx, std::span<uint8_t> rx, _trans_fn fn);
853 [[nodiscard]] result<void> _full_trans(const transaction& trans, _trans_fn fn);
854
855 [[nodiscard]] result<idfxx::future<void>>
856 _try_queue_trans(const transaction& trans, std::optional<std::chrono::milliseconds> timeout);
857 [[nodiscard]] result<void> _try_wait_for(
858 const std::shared_ptr<std::atomic<bool>>& done_flag,
859 std::optional<std::chrono::milliseconds> timeout
860 );
861
862 [[nodiscard]] result<uint16_t> _acquire_slot(std::optional<std::chrono::milliseconds> timeout);
863 void _release_slot(uint16_t slot_idx) noexcept;
864
865 static void _prepare_idf_trans(spi_transaction_t& idf_trans, const transaction& trans);
866 static void _prepare_idf_trans_ext(spi_transaction_ext_t& idf_ext, const transaction& trans);
867
868 master_bus* _bus = nullptr;
869 spi_device_handle_t _handle = nullptr;
870 std::unique_ptr<async_state> _async;
871};
872
// end of idfxx_spi
874
875} // namespace idfxx::spi
876
877namespace idfxx {
878
886[[nodiscard]] inline std::string to_string(spi::host_device h) {
887 switch (h) {
889 return "SPI1";
891 return "SPI2";
892#if SOC_SPI_PERIPH_NUM > 2
894 return "SPI3";
895#endif
896 default:
897 return "unknown(" + std::to_string(static_cast<int>(h)) + ")";
898 }
899}
900
901} // namespace idfxx
902
903#include "sdkconfig.h"
904#ifdef CONFIG_IDFXX_STD_FORMAT
906#include <algorithm>
907#include <format>
908namespace std {
909template<>
910struct formatter<idfxx::spi::host_device> {
911 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
912
913 template<typename FormatContext>
914 auto format(idfxx::spi::host_device h, FormatContext& ctx) const {
915 auto s = idfxx::to_string(h);
916 return std::copy(s.begin(), s.end(), ctx.out());
917 }
918};
919} // namespace std
921#endif // CONFIG_IDFXX_STD_FORMAT
Type-safe set of flags from a scoped enum.
Definition flags.hpp:88
Async completion token.
Definition future.hpp:62
A GPIO pin.
Definition gpio.hpp:62
static constexpr gpio nc()
Returns a GPIO representing "not connected".
Definition gpio.hpp:255
level
GPIO output/input level.
Definition gpio.hpp:68
@ low
Logic low (0)
A SPI master bus.
Definition master.hpp:256
master_bus(master_bus &&other) noexcept
Move constructor.
master_bus(const master_bus &)=delete
static result< master_bus > make(enum host_device host, enum dma_chan dma_chan, struct bus_config config)
Creates a new SPI master bus.
master_bus(enum host_device host, enum dma_chan dma_chan, struct bus_config config)
Constructs a new SPI master bus.
enum host_device host() const
Returns the host device ID the bus is using.
Definition master.hpp:296
size_t max_transaction_length() const
Returns the maximum transaction length for this bus.
master_bus & operator=(master_bus &&other) noexcept
Move assignment.
master_bus & operator=(const master_bus &)=delete
A device on a SPI master bus.
Definition master.hpp:340
bool try_lock() const noexcept
Tries to acquire exclusive access without waiting for the device.
master_bus & bus() const
Returns the parent bus.
Definition master.hpp:430
void transmit(const transaction &trans)
Executes a full-control transaction.
Definition master.hpp:565
std::vector< uint8_t > receive(size_t size)
Receives data from the device.
Definition master.hpp:493
void transfer(std::span< const uint8_t > tx_data, std::span< uint8_t > rx_data)
Performs a full-duplex transfer.
Definition master.hpp:510
void transmit(std::span< const uint8_t > tx_data)
Transmits data to the device.
Definition master.hpp:467
result< std::vector< uint8_t > > try_receive(size_t size)
Receives data from the device.
result< void > try_polling_receive(std::span< uint8_t > rx_data)
Receives data using polling (busy-wait).
std::vector< uint8_t > polling_receive(size_t size)
Receives data using polling (busy-wait).
Definition master.hpp:618
idfxx::future< void > queue_trans(const transaction &trans, const std::chrono::duration< Rep, Period > &timeout)
Queues a transaction for asynchronous execution with timeout.
Definition master.hpp:753
void polling_transfer(std::span< const uint8_t > tx_data, std::span< uint8_t > rx_data)
Performs a full-duplex transfer using polling (busy-wait).
Definition master.hpp:631
result< idfxx::future< void > > try_queue_trans(const transaction &trans, const std::chrono::duration< Rep, Period > &timeout)
Queues a transaction for asynchronous execution with timeout.
Definition master.hpp:789
result< void > try_polling_transmit(std::span< const uint8_t > tx_data)
Transmits data using polling (busy-wait).
result< void > try_transfer(std::span< const uint8_t > tx_data, std::span< uint8_t > rx_data)
Performs a full-duplex transfer.
master_device & operator=(master_device &&other) noexcept
master_device(master_bus &bus, const struct config &config)
Creates a new SPI device on the specified bus.
master_device(master_device &&other) noexcept
void unlock() const
Releases exclusive access acquired by lock() or try_lock().
master_device(const master_device &)=delete
result< idfxx::future< void > > try_queue_trans(const transaction &trans)
Queues a transaction for asynchronous execution.
spi_device_handle_t idf_handle() const
Returns the underlying ESP-IDF device handle.
Definition master.hpp:436
master_device & operator=(const master_device &)=delete
void lock() const
Acquires exclusive access to this device and its bus.
static result< master_device > make(master_bus &bus, const struct config &config)
Creates a new SPI device on the specified bus.
void polling_transmit(std::span< const uint8_t > tx_data)
Transmits data using polling (busy-wait).
Definition master.hpp:592
void receive(std::span< uint8_t > rx_data)
Receives data from the device into the provided buffer.
Definition master.hpp:477
result< void > try_transmit(const transaction &trans)
Executes a full-control transaction.
result< void > try_transmit(std::span< const uint8_t > tx_data)
Transmits data to the device.
result< void > try_polling_transmit(const transaction &trans)
Executes a full-control transaction using polling (busy-wait).
result< std::vector< uint8_t > > try_polling_receive(size_t size)
Receives data using polling (busy-wait).
idfxx::future< void > queue_trans(const transaction &trans)
Queues a transaction for asynchronous execution.
Definition master.hpp:736
result< void > try_receive(std::span< uint8_t > rx_data)
Receives data from the device into the provided buffer.
void polling_transmit(const transaction &trans)
Executes a full-control transaction using polling (busy-wait).
Definition master.hpp:645
freq::hertz frequency() const
Returns the actual clock frequency in use.
void polling_receive(std::span< uint8_t > rx_data)
Receives data using polling (busy-wait).
Definition master.hpp:604
result< void > try_polling_transfer(std::span< const uint8_t > tx_data, std::span< uint8_t > rx_data)
Performs a full-duplex transfer using polling (busy-wait).
int esp_err_t
Definition error.hpp:35
std::string to_string(core_id c)
Returns a string representation of a CPU core identifier.
Definition cpu.hpp:52
trans_flags
SPI transaction flags.
Definition master.hpp:128
dma_chan
SPI DMA channel selection.
Definition master.hpp:63
bus_flags
SPI bus capability and configuration flags.
Definition master.hpp:81
device_flags
SPI device capability and configuration flags.
Definition master.hpp:108
host_device
General purpose SPI Host Controller ID.
Definition master.hpp:51
@ multiline_cmd
Use multi-line mode for command phase.
@ dma_use_psram
Use PSRAM for DMA buffer directly. Requires ESP-IDF 6.0+.
@ mode_qio
Transmit/receive data in 4-bit mode.
@ variable_cmd
Use per-transaction command_bits length.
@ use_rxdata
Receive into inline rx_data instead of rx_buffer.
@ use_txdata
Transmit inline tx_data instead of tx_buffer.
@ cs_keep_active
Keep CS active after data transfer.
@ mode_oct
Transmit/receive data in 8-bit mode.
@ variable_addr
Use per-transaction address_bits length.
@ variable_dummy
Use per-transaction dummy_bits length.
@ dma_buffer_align_manual
Disable automatic DMA buffer re-alignment.
@ multiline_addr
Use multi-line mode for address phase.
@ mode_dio
Transmit/receive data in 2-bit mode.
@ ch_auto
Auto select DMA channel.
@ slp_allow_pd
Allow to power down the peripheral during light sleep, and auto recover then.
@ slave
Bus supports slave mode.
@ iomux_pins
Bus uses IOMUX pins.
@ octal
Check existing of MOSI/MISO/WP/HD/SPIIO4/SPIIO5/SPIIO6/SPIIO7 pins as output.
@ dual
Check MOSI and MISO pins can output. Or indicates bus able to work under DIO mode.
@ quad
Check existing of MOSI/MISO/WP/HD pins as output.
@ io4_io7
Check existing of IO4~IO7 pins. Or indicates IO4~IO7 pins initialized.
@ wphd
Check existing of WP and HD pins. Or indicates WP & HD pins initialized.
@ native_pins
Bus uses native pins.
@ mosi
Check existing of MOSI pin. Or indicates MOSI line initialized.
@ miso
Check existing of MISO pin. Or indicates MISO line initialized.
@ master
Bus supports master mode.
@ sclk
Check existing of SCLK pin. Or indicates CLK line initialized.
@ no_dummy
Disable automatic dummy bit insertion.
@ halfduplex
Transmit data before receiving, not simultaneously.
@ three_wire
Use MOSI for both sending and receiving.
@ ddrclk
Use double data rate clocking.
@ clk_as_cs
Output clock on CS line while CS is active.
@ txbit_lsbfirst
Transmit command/address/data LSB first.
@ bit_lsbfirst
Transmit and receive LSB first.
@ rxbit_lsbfirst
Receive data LSB first.
@ no_return_result
Don't return descriptor on completion (use post_cb).
@ positive_cs
CS is active high during a transaction.
SPI driver classes.
Definition master.hpp:45
Definition adc.hpp:48
T unwrap(result< T > result)
Throws a std::system_error if the result is an error.
Definition error.hpp:307
@ timeout
Operation timed out.
std::expected< T, std::error_code > result
result type wrapping a value or error code.
Definition error.hpp:120
SPI bus configuration.
Definition master.hpp:207
gpio::level data_idle_level
Data pin output level while no transaction is active.
Definition master.hpp:230
idfxx::flags< idfxx::intr_flag > intr_flags
Behavioral interrupt flags.
Definition master.hpp:241
idfxx::gpio data7
GPIO pin for spi data7 signal in octal mode, or gpio::nc() if not used.
Definition master.hpp:228
idfxx::gpio mosi
GPIO pin for Master Out Slave In (=spi_d) signal.
Definition master.hpp:209
idfxx::gpio data1
GPIO pin for spi data1 signal in quad/octal mode.
Definition master.hpp:214
idfxx::gpio miso
GPIO pin for Master In Slave Out (=spi_q) signal.
Definition master.hpp:213
idfxx::gpio data2
GPIO pin for spi data2 signal in quad/octal mode, or gpio::nc() if not used.
Definition master.hpp:219
idfxx::gpio data4
GPIO pin for spi data4 signal in octal mode, or gpio::nc() if not used.
Definition master.hpp:225
idfxx::gpio quadwp
GPIO pin for WP (Write Protect) signal, or gpio::nc() if not used.
Definition master.hpp:218
size_t max_transfer_sz
Maximum transfer size, in bytes (DMA only).
Definition master.hpp:231
idfxx::gpio data0
GPIO pin for spi data0 signal in quad/octal mode.
Definition master.hpp:210
idfxx::gpio data5
GPIO pin for spi data5 signal in octal mode, or gpio::nc() if not used.
Definition master.hpp:226
idfxx::gpio sclk
GPIO pin for SPI Clock signal.
Definition master.hpp:216
idfxx::gpio data3
GPIO pin for spi data3 signal in quad/octal mode, or gpio::nc() if not used.
Definition master.hpp:223
idfxx::gpio quadhd
GPIO pin for HD (Hold) signal, or gpio::nc() if not used.
Definition master.hpp:222
idfxx::gpio data6
GPIO pin for spi data6 signal in octal mode, or gpio::nc() if not used.
Definition master.hpp:227
std::optional< idfxx::core_id > isr_cpu_id
Select cpu core to register SPI ISR.
Definition master.hpp:238
SPI device configuration.
Definition master.hpp:355
std::chrono::nanoseconds input_delay
Maximum data valid time of slave.
Definition master.hpp:364
uint8_t mode
SPI mode (0-3): (CPOL, CPHA) pair.
Definition master.hpp:359
uint16_t cs_ena_pretrans
SPI bit-cycles CS is active before transmission (half-duplex only).
Definition master.hpp:361
uint8_t cs_ena_posttrans
SPI bit-cycles CS stays active after transmission.
Definition master.hpp:362
freq::hertz clock_speed
SPI clock speed in Hz.
Definition master.hpp:363
uint8_t dummy_bits
Dummy bits between address and data phase.
Definition master.hpp:358
uint8_t address_bits
Default address phase length in bits (0-64).
Definition master.hpp:357
int queue_size
Transaction queue depth for async API.
Definition master.hpp:367
uint8_t command_bits
Default command phase length in bits (0-16).
Definition master.hpp:356
uint16_t duty_cycle_pos
Duty cycle of positive clock in 1/256 increments (128 = 50%, 0 = default).
Definition master.hpp:360
idfxx::gpio cs
GPIO pin for chip select, or gpio::nc() if not used.
Definition master.hpp:365
SPI transaction descriptor for full-control transactions.
Definition master.hpp:175
size_t length
Total data length in bits.
Definition master.hpp:181
uint8_t dummy_bits
Dummy length for variable_dummy flag.
Definition master.hpp:186
uint64_t addr
Address data (length set by device config or variable_addr).
Definition master.hpp:178
std::span< uint8_t > rx_buffer
Receive buffer, or empty for no MISO phase.
Definition master.hpp:180
freq::hertz override_freq
Override clock speed for this transaction (0 = no override).
Definition master.hpp:183
uint16_t cmd
Command data (length set by device config or variable_cmd).
Definition master.hpp:177
std::span< const uint8_t > tx_buffer
Transmit buffer, or empty for no MOSI phase.
Definition master.hpp:179
size_t rx_length
Receive length in bits (0 = same as length).
Definition master.hpp:182
uint8_t command_bits
Command length for variable_cmd flag.
Definition master.hpp:184
uint8_t address_bits
Address length for variable_addr flag.
Definition master.hpp:185