SPI
The spi component provides a C++ wrapper around ESP-IDF’s SPI master driver.
Spi owns the bus and Spi::Device owns attached peripherals on that bus.
API Reference
Header File
Classes
-
class Spi : public espp::BaseComponent
SPI master wrapper and helpers.
`Spi` owns an SPI bus and can create one or more attached `Device` instances. Those devices support blocking reads/writes, queued transactions, and bus acquisition.
Example
constexpr spi_host_device_t spi_host = SPI2_HOST; constexpr auto sclk_gpio = GPIO_NUM_36; constexpr auto mosi_gpio = GPIO_NUM_38; constexpr auto miso_gpio = GPIO_NUM_35; constexpr auto cs_gpio = GPIO_NUM_37; constexpr uint8_t read_address = 0x80; espp::Spi spi({ .host = spi_host, .sclk_io_num = sclk_gpio, .mosi_io_num = mosi_gpio, .miso_io_num = miso_gpio, .max_transfer_sz = 16, }); std::error_code ec; auto device = spi.add_device( { .address_bits = 8, .mode = 0, .clock_speed_hz = 1 * 1000 * 1000, .cs_io_num = cs_gpio, .queue_size = 1, }, ec); if (ec || !device) { std::printf("Failed to create SPI device: %s\n", ec.message().c_str()); return; } std::array<uint8_t, 2> rx_data{}; if (!device->read(rx_data, {.address = read_address}, ec)) { std::printf("SPI read failed: %s\n", ec.message().c_str()); return; } std::printf("Read bytes: 0x%02x 0x%02x\n", rx_data[0], rx_data[1]);
Public Functions
-
explicit Spi(const Config &config)
Construct the SPI bus wrapper.
- Parameters:
config – SPI bus configuration.
-
~Spi()
Deinitialize the SPI bus and remove any remaining devices.
-
void init(std::error_code &ec)
Initialize the SPI bus.
- Parameters:
ec – Error code populated on failure.
-
void deinit(std::error_code &ec)
Deinitialize the SPI bus.
- Parameters:
ec – Error code populated on failure.
-
bool initialized() const
Check whether the SPI bus is initialized.
- Returns:
True if the SPI bus is initialized.
-
spi_host_device_t host() const
Get the configured SPI host.
- Returns:
Configured SPI host controller.
-
std::shared_ptr<Device> add_device(const DeviceConfig &config, std::error_code &ec)
Add a device to the SPI bus.
- Parameters:
config – Device configuration.
ec – Error code populated on failure.
- Returns:
Shared pointer to the registered device, or nullptr on failure.
-
inline const std::string &get_name() const
Get the name of the component
Note
This is the tag of the logger
- Returns:
A const reference to the name of the component
-
inline void set_log_tag(const std::string_view &tag)
Set the tag for the logger
- Parameters:
tag – The tag to use for the logger
-
inline espp::Logger::Verbosity get_log_level() const
Get the log level for the logger
See also
See also
- Returns:
The verbosity level of the logger
-
inline void set_log_level(espp::Logger::Verbosity level)
Set the log level for the logger
See also
See also
- Parameters:
level – The verbosity level to use for the logger
-
inline void set_log_verbosity(espp::Logger::Verbosity level)
Set the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls set_log_level
- Parameters:
level – The verbosity level to use for the logger
-
inline espp::Logger::Verbosity get_log_verbosity() const
Get the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls get_log_level
- Returns:
The verbosity level of the logger
-
inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)
Set the rate limit for the logger
See also
Note
Only calls to the logger that have _rate_limit suffix will be rate limited
- Parameters:
rate_limit – The rate limit to use for the logger
Public Static Functions
-
static spi_bus_config_t make_bus_config(const Config &config)
Convert a `Spi::Config` into an ESP-IDF `spi_bus_config_t`.
- Parameters:
config – High-level SPI bus configuration.
- Returns:
Equivalent ESP-IDF bus configuration.
-
static spi_device_interface_config_t make_device_config(const DeviceConfig &config)
Convert a `Spi::DeviceConfig` into an ESP-IDF device config.
- Parameters:
config – High-level SPI device configuration.
- Returns:
Equivalent ESP-IDF device interface configuration.
-
class BusLock
RAII helper for holding an acquired SPI device bus lock.
Public Functions
-
BusLock()
Construct an empty bus lock.
-
BusLock(BusLock &&other) noexcept
Move-construct the bus lock.
- Parameters:
other – Lock to move from.
-
BusLock &operator=(BusLock &&other) noexcept
Move-assign the bus lock.
- Parameters:
other – Lock to move from.
- Returns:
Reference to this lock.
-
~BusLock()
Release the held bus lock on destruction.
-
void release()
Release the held SPI bus lock, if any.
-
explicit operator bool() const
Check whether this object currently owns a bus lock.
- Returns:
True if a bus lock is held.
-
BusLock()
-
struct Config
Bus-level configuration for the SPI master.
Public Members
-
int isr_core_id = -1
Core on which to initialize the SPI bus.
-
spi_host_device_t host = SPI2_HOST
SPI host controller to use.
-
gpio_num_t sclk_io_num = GPIO_NUM_NC
Clock pin.
-
gpio_num_t mosi_io_num = GPIO_NUM_NC
MOSI pin.
-
gpio_num_t miso_io_num = GPIO_NUM_NC
MISO pin.
-
gpio_num_t quadwp_io_num = GPIO_NUM_NC
Quad WP pin.
-
gpio_num_t quadhd_io_num = GPIO_NUM_NC
Quad HD pin.
-
int max_transfer_sz = 0
Maximum transfer size in bytes.
-
uint32_t bus_flags = 0
ESP-IDF bus configuration flags.
-
spi_dma_chan_t dma_channel = SPI_DMA_CH_AUTO
DMA channel selection.
-
bool auto_init = true
Automatically initialize on construction.
-
int isr_core_id = -1
-
class Device : public espp::BaseComponent
Attached SPI device wrapper.
Public Functions
-
explicit Device(Logger::Verbosity log_level, const DeviceConfig &config)
Construct an unattached device wrapper.
- Parameters:
log_level – Logger verbosity inherited from the owning SPI bus.
config – Device configuration.
-
~Device()
Remove the device from the SPI bus on destruction.
-
bool initialized() const
Check whether the device is attached to the SPI bus.
- Returns:
True if the device has a valid ESP-IDF handle.
-
spi_device_handle_t handle() const
Get the underlying ESP-IDF device handle.
- Returns:
SPI device handle, or nullptr if unattached.
-
const DeviceConfig &config() const
Get the configuration used to create this device.
- Returns:
Device configuration.
-
void remove_device(std::error_code &ec)
Remove this device from the SPI bus.
- Parameters:
ec – Error code populated on failure.
-
bool transmit(spi_transaction_t &transaction, std::error_code &ec)
Submit a blocking SPI transaction.
- Parameters:
transaction – Transaction to execute.
ec – Error code populated on failure.
- Returns:
True on success.
-
bool polling_transmit(spi_transaction_t &transaction, std::error_code &ec)
Submit a polling SPI transaction.
- Parameters:
transaction – Transaction to execute.
ec – Error code populated on failure.
- Returns:
True on success.
-
bool queue_transaction(spi_transaction_t &transaction, TickType_t timeout, std::error_code &ec)
Queue an asynchronous SPI transaction.
- Parameters:
transaction – Transaction to queue.
timeout – Queue timeout in FreeRTOS ticks.
ec – Error code populated on failure.
- Returns:
True on success.
-
bool get_transaction_result(spi_transaction_t **transaction, TickType_t timeout, std::error_code &ec)
Wait for a queued SPI transaction to complete.
- Parameters:
transaction – Filled with the completed transaction pointer.
timeout – Wait timeout in FreeRTOS ticks.
ec – Error code populated on failure.
- Returns:
True on success.
-
BusLock acquire_bus(TickType_t timeout, std::error_code &ec)
Acquire exclusive access to the SPI bus for this device.
- Parameters:
timeout – Acquire timeout in FreeRTOS ticks.
ec – Error code populated on failure.
- Returns:
RAII bus lock object.
-
bool write(std::span<const uint8_t> data, const TransactionConfig &config, std::error_code &ec)
Write a transmit buffer using the configured per-transaction overrides.
- Parameters:
data – Data to transmit.
config – Transaction overrides.
ec – Error code populated on failure.
- Returns:
True on success.
-
bool read(std::span<uint8_t> data, const TransactionConfig &config, std::error_code &ec)
Read data using the configured per-transaction overrides.
- Parameters:
data – Receive buffer to fill.
config – Transaction overrides.
ec – Error code populated on failure.
- Returns:
True on success.
-
bool transfer(std::span<const uint8_t> tx_data, std::span<uint8_t> rx_data, const TransactionConfig &config, std::error_code &ec)
Perform a combined transmit/receive transaction.
- Parameters:
tx_data – Transmit buffer.
rx_data – Receive buffer.
config – Transaction overrides.
ec – Error code populated on failure.
- Returns:
True on success.
-
inline const std::string &get_name() const
Get the name of the component
Note
This is the tag of the logger
- Returns:
A const reference to the name of the component
-
inline void set_log_tag(const std::string_view &tag)
Set the tag for the logger
- Parameters:
tag – The tag to use for the logger
-
inline espp::Logger::Verbosity get_log_level() const
Get the log level for the logger
See also
See also
- Returns:
The verbosity level of the logger
-
inline void set_log_level(espp::Logger::Verbosity level)
Set the log level for the logger
See also
See also
- Parameters:
level – The verbosity level to use for the logger
-
inline void set_log_verbosity(espp::Logger::Verbosity level)
Set the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls set_log_level
- Parameters:
level – The verbosity level to use for the logger
-
inline espp::Logger::Verbosity get_log_verbosity() const
Get the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls get_log_level
- Returns:
The verbosity level of the logger
-
inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)
Set the rate limit for the logger
See also
Note
Only calls to the logger that have _rate_limit suffix will be rate limited
- Parameters:
rate_limit – The rate limit to use for the logger
-
explicit Device(Logger::Verbosity log_level, const DeviceConfig &config)
-
struct DeviceConfig
Per-device configuration for a device attached to the SPI bus.
Public Members
-
int command_bits = 0
Number of command bits sent before payload data.
-
int address_bits = 0
Number of address bits sent before payload data.
-
int dummy_bits = 0
Number of dummy bits inserted before payload data.
-
uint8_t mode = 0
SPI mode.
-
int clock_speed_hz = 1 * 1000 * 1000
Device clock speed.
-
int input_delay_ns = 0
Input delay in nanoseconds.
-
gpio_num_t cs_io_num = GPIO_NUM_NC
Chip-select pin.
-
int queue_size = 1
Queue depth for asynchronous transactions.
-
uint32_t flags = 0
ESP-IDF device flags.
-
uint16_t cs_ena_pretrans = 0
CS lead time in SPI bit-cycles.
-
uint16_t cs_ena_posttrans = 0
CS hold time in SPI bit-cycles.
-
transaction_cb_t pre_cb = nullptr
Optional pre-transfer callback.
-
transaction_cb_t post_cb = nullptr
Optional post-transfer callback.
-
int command_bits = 0
-
struct TransactionConfig
Per-transaction overrides for read/write/transfer helpers.
Public Members
-
uint16_t command = 0
Command value for this transaction.
-
uint64_t address = 0
Address value for this transaction.
-
uint32_t flags = 0
ESP-IDF transaction flags.
-
size_t rx_length_bits = 0
Optional receive length override, in bits. For this byte-oriented API it must be a multiple of 8, must not exceed the RX buffer capacity, and must not exceed the TX bit length when both TX and RX are used in the same transaction.
-
uint16_t command = 0
-
explicit Spi(const Config &config)
-
class BusLock
RAII helper for holding an acquired SPI device bus lock.
Public Functions
-
BusLock()
Construct an empty bus lock.
-
BusLock(BusLock &&other) noexcept
Move-construct the bus lock.
- Parameters:
other – Lock to move from.
-
BusLock &operator=(BusLock &&other) noexcept
Move-assign the bus lock.
- Parameters:
other – Lock to move from.
- Returns:
Reference to this lock.
-
~BusLock()
Release the held bus lock on destruction.
-
void release()
Release the held SPI bus lock, if any.
-
explicit operator bool() const
Check whether this object currently owns a bus lock.
- Returns:
True if a bus lock is held.
-
BusLock()
-
class Device : public espp::BaseComponent
Attached SPI device wrapper.
Public Functions
-
explicit Device(Logger::Verbosity log_level, const DeviceConfig &config)
Construct an unattached device wrapper.
- Parameters:
log_level – Logger verbosity inherited from the owning SPI bus.
config – Device configuration.
-
~Device()
Remove the device from the SPI bus on destruction.
-
bool initialized() const
Check whether the device is attached to the SPI bus.
- Returns:
True if the device has a valid ESP-IDF handle.
-
spi_device_handle_t handle() const
Get the underlying ESP-IDF device handle.
- Returns:
SPI device handle, or nullptr if unattached.
-
const DeviceConfig &config() const
Get the configuration used to create this device.
- Returns:
Device configuration.
-
void remove_device(std::error_code &ec)
Remove this device from the SPI bus.
- Parameters:
ec – Error code populated on failure.
-
bool transmit(spi_transaction_t &transaction, std::error_code &ec)
Submit a blocking SPI transaction.
- Parameters:
transaction – Transaction to execute.
ec – Error code populated on failure.
- Returns:
True on success.
-
bool polling_transmit(spi_transaction_t &transaction, std::error_code &ec)
Submit a polling SPI transaction.
- Parameters:
transaction – Transaction to execute.
ec – Error code populated on failure.
- Returns:
True on success.
-
bool queue_transaction(spi_transaction_t &transaction, TickType_t timeout, std::error_code &ec)
Queue an asynchronous SPI transaction.
- Parameters:
transaction – Transaction to queue.
timeout – Queue timeout in FreeRTOS ticks.
ec – Error code populated on failure.
- Returns:
True on success.
-
bool get_transaction_result(spi_transaction_t **transaction, TickType_t timeout, std::error_code &ec)
Wait for a queued SPI transaction to complete.
- Parameters:
transaction – Filled with the completed transaction pointer.
timeout – Wait timeout in FreeRTOS ticks.
ec – Error code populated on failure.
- Returns:
True on success.
-
BusLock acquire_bus(TickType_t timeout, std::error_code &ec)
Acquire exclusive access to the SPI bus for this device.
- Parameters:
timeout – Acquire timeout in FreeRTOS ticks.
ec – Error code populated on failure.
- Returns:
RAII bus lock object.
-
bool write(std::span<const uint8_t> data, const TransactionConfig &config, std::error_code &ec)
Write a transmit buffer using the configured per-transaction overrides.
- Parameters:
data – Data to transmit.
config – Transaction overrides.
ec – Error code populated on failure.
- Returns:
True on success.
-
bool read(std::span<uint8_t> data, const TransactionConfig &config, std::error_code &ec)
Read data using the configured per-transaction overrides.
- Parameters:
data – Receive buffer to fill.
config – Transaction overrides.
ec – Error code populated on failure.
- Returns:
True on success.
-
bool transfer(std::span<const uint8_t> tx_data, std::span<uint8_t> rx_data, const TransactionConfig &config, std::error_code &ec)
Perform a combined transmit/receive transaction.
- Parameters:
tx_data – Transmit buffer.
rx_data – Receive buffer.
config – Transaction overrides.
ec – Error code populated on failure.
- Returns:
True on success.
-
inline const std::string &get_name() const
Get the name of the component
Note
This is the tag of the logger
- Returns:
A const reference to the name of the component
-
inline void set_log_tag(const std::string_view &tag)
Set the tag for the logger
- Parameters:
tag – The tag to use for the logger
-
inline espp::Logger::Verbosity get_log_level() const
Get the log level for the logger
See also
See also
- Returns:
The verbosity level of the logger
-
inline void set_log_level(espp::Logger::Verbosity level)
Set the log level for the logger
See also
See also
- Parameters:
level – The verbosity level to use for the logger
-
inline void set_log_verbosity(espp::Logger::Verbosity level)
Set the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls set_log_level
- Parameters:
level – The verbosity level to use for the logger
-
inline espp::Logger::Verbosity get_log_verbosity() const
Get the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls get_log_level
- Returns:
The verbosity level of the logger
-
inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)
Set the rate limit for the logger
See also
Note
Only calls to the logger that have _rate_limit suffix will be rate limited
- Parameters:
rate_limit – The rate limit to use for the logger
-
explicit Device(Logger::Verbosity log_level, const DeviceConfig &config)