32#include "../SensorCommBase.hpp"
34#if !defined(ARDUINO) && defined(ESP_PLATFORM)
35#include "driver/spi_master.h"
36#include "driver/gpio.h"
45 SensorCommSPI(spi_host_device_t host, spi_device_handle_t &spi, uint8_t csPin,
SensorHal *hal) : host(host), spi(spi), csPin(csPin), hal(hal) {}
46 SensorCommSPI(spi_host_device_t host, spi_device_handle_t &spi, uint8_t csPin,
int mosi,
int miso,
int sck,
SensorHal *hal) : host(host), spi(spi),
47 csPin(csPin), hal(hal), mosi(mosi), miso(miso), sck(sck) {}
55 if (mosi != -1 && miso != -1 && sck != -1) {
56 spi_bus_config_t buscfg ;
57 buscfg.miso_io_num = miso,
58 buscfg.mosi_io_num = mosi,
59 buscfg.sclk_io_num = sck,
60 buscfg.quadwp_io_num = -1,
61 buscfg.quadhd_io_num = -1,
62 buscfg.data4_io_num = -1,
63 buscfg.data5_io_num = -1,
64 buscfg.data6_io_num = -1,
65 buscfg.data7_io_num = -1,
66 buscfg.max_transfer_sz = 128;
68 buscfg.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO;
69 buscfg.intr_flags = 0;
71 spi_device_interface_config_t devcfg ;
72 memset(&devcfg, 0,
sizeof(devcfg));
73 devcfg.address_bits = 8;
74 devcfg.clock_speed_hz = spiSetting.clock;
75 devcfg.mode = spiSetting.dataMode;
76 devcfg.spics_io_num = -1;
77 devcfg.queue_size = 2;
81 ret = spi_bus_initialize(host, &buscfg, SPI_DMA_CH_AUTO);
87 ret = spi_bus_add_device(host, &devcfg, &spi);
94 hal->pinMode(csPin, OUTPUT);
95 hal->digitalWrite(csPin, HIGH);
102 spi_bus_remove_device(spi);
108 if (hal ==
nullptr) {
112 hal->digitalWrite(csPin, LOW);
114 spi_transaction_t trans;
115 memset(&trans, 0,
sizeof(trans));
118 trans.addr = reg & WRITE_MASK;
119 trans.length = len * 8;
122 trans.tx_buffer =
buf;
123 trans.rx_buffer = NULL;
124 esp_err_t ret = spi_device_transmit(spi, &trans);
126 hal->digitalWrite(csPin, HIGH);
133 if (!
buf || len == 0 || hal ==
nullptr) {
137 hal->digitalWrite(csPin, LOW);
138 spi_transaction_t trans;
139 memset(&trans, 0,
sizeof(trans));
140 trans.addr = READ_MASK;
141 trans.length = len * 8;
142 trans.rxlength = len * 8;
143 trans.rx_buffer =
buf;
144 esp_err_t ret = spi_device_transmit(spi, &trans);
145 hal->digitalWrite(csPin, HIGH);
152 if (!
buf || len == 0 || hal ==
nullptr) {
156 hal->digitalWrite(csPin, LOW);
158 spi_transaction_t trans;
159 memset(&trans, 0,
sizeof(trans));
160 trans.length = 8 * len;
161 trans.tx_buffer =
buf;
162 esp_err_t ret = spi_device_polling_transmit(spi, &trans);
164 hal->digitalWrite(csPin, HIGH);
165 return ret == ESP_OK ? 0 : -1;
171 if (!
buf || len == 0 || hal ==
nullptr) {
175 hal->digitalWrite(csPin, LOW);
177 spi_transaction_t trans;
178 memset(&trans, 0,
sizeof(trans));
179 trans.addr = reg | READ_MASK;
180 trans.length = len * 8;
181 trans.rxlength = len * 8;
182 trans.rx_buffer =
buf;
183 esp_err_t ret = spi_device_transmit(spi, &trans);
185 hal->digitalWrite(csPin, HIGH);
189 int writeThenRead(
const uint8_t *write_buffer,
size_t write_len, uint8_t *read_buffer,
size_t read_len)
override
191 if (!write_buffer || write_len == 0 || !read_buffer || read_len == 0 || hal ==
nullptr) {
195 hal->digitalWrite(csPin, LOW);
198 spi_transaction_t trans;
199 memset(&trans, 0,
sizeof(trans));
201 auto perform_transmission = [&](
const uint8_t *tx_buf,
size_t len, uint8_t *rx_buf) {
202 trans.length = 8 * len;
203 trans.tx_buffer = tx_buf;
204 trans.rx_buffer = rx_buf;
205 return spi_device_polling_transmit(spi, &trans);
208 ret = perform_transmission(write_buffer, write_len,
nullptr);
210 hal->digitalWrite(csPin, HIGH);
214 ret = perform_transmission(
nullptr, read_len, read_buffer);
216 hal->digitalWrite(csPin, HIGH);
224#if defined(__cpp_rtti)
225 const auto pdat =
dynamic_cast<const SPIParam *
>(¶ms);
227 const auto pdat =
static_cast<const SPIParam *
>(¶ms);
237 static constexpr const uint8_t READ_MASK = 0x80;
238 static constexpr const uint8_t WRITE_MASK = 0x7F;
239 spi_host_device_t host;
240 spi_device_handle_t spi;
Abstract base for all communication parameter objects.
SPI communication parameters.
SPISettings getSetting() const
Retrieve the stored SPI settings.
Emulation of Arduino's SPISettings class.
Abstract base class for low‑level sensor communication.
virtual int writeThenRead(const uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len)=0
Perform a write followed by a read (e.g., for register‑based sensors).
virtual int readBuffer(uint8_t *buf, size_t len)=0
Read bytes directly from the device (no register address sent).
virtual int writeBuffer(uint8_t *buffer, size_t len)=0
Write a buffer directly to the device (no register address).
virtual void setParams(const CommParamsBase ¶ms)=0
Apply communication parameters (e.g., I2C address, SPI settings).
virtual int readRegister(const uint8_t reg)
Read a single byte from a register.
virtual void deinit()=0
Deinitialise the communication interface (close device, etc.).
virtual bool init()=0
Initialise the communication interface (open device, etc.).
virtual int writeRegister(const uint8_t reg, uint8_t val)
Write a single byte to a register.
void setError(SENSOR_ERROR_CODE e)
Abstract hardware abstraction layer.