SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
SensorCommEspIDF_SPI.hpp
Go to the documentation of this file.
1
30#pragma once
31
32#include "../SensorCommBase.hpp"
33
34#if !defined(ARDUINO) && defined(ESP_PLATFORM)
35#include "driver/spi_master.h"
36#include "driver/gpio.h"
37#include "esp_err.h"
38#include "esp_log.h"
39
40
41
42class SensorCommSPI : public SensorCommBase
43{
44public:
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) {}
48
49 bool init() override
50 {
51 if (!hal) {
53 return false;
54 }
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;
67 buscfg.flags = 0;
68 buscfg.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO;
69 buscfg.intr_flags = 0;
70
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;
78 devcfg.pre_cb = NULL;
79
80 esp_err_t ret;
81 ret = spi_bus_initialize(host, &buscfg, SPI_DMA_CH_AUTO);
82 if (ret != ESP_OK) {
84 return false;
85 }
86
87 ret = spi_bus_add_device(host, &devcfg, &spi);
88 if (ret != ESP_OK) {
90 return false;
91 }
92 }
93
94 hal->pinMode(csPin, OUTPUT);
95 hal->digitalWrite(csPin, HIGH);
96
97 return true;
98 }
99
100 void deinit() override
101 {
102 spi_bus_remove_device(spi);
103 // spi_bus_free(host);
104 }
105
106 int writeRegister(const uint8_t reg, uint8_t *buf, size_t len) override
107 {
108 if (hal == nullptr) {
110 }
111
112 hal->digitalWrite(csPin, LOW);
113
114 spi_transaction_t trans;
115 memset(&trans, 0, sizeof(trans));
116 trans.flags = 0;
117 trans.cmd = 0;
118 trans.addr = reg & WRITE_MASK;
119 trans.length = len * 8;
120 trans.rxlength = 0;
121 trans.user = NULL;
122 trans.tx_buffer = buf;
123 trans.rx_buffer = NULL;
124 esp_err_t ret = spi_device_transmit(spi, &trans);
125
126 hal->digitalWrite(csPin, HIGH);
127
128 return ret == ESP_OK ? SENSOR_OK : SENSOR_ERR_COMM_NACK;
129 }
130
131 int readBuffer(uint8_t *buf, size_t len) override
132 {
133 if (!buf || len == 0 || hal == nullptr) {
135 }
136
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);
146 return ret == ESP_OK ? SENSOR_OK : SENSOR_ERR_COMM_NACK;
147 }
148
149
150 int writeBuffer(uint8_t *buf, size_t len)
151 {
152 if (!buf || len == 0 || hal == nullptr) {
154 }
155
156 hal->digitalWrite(csPin, LOW);
157
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);
163
164 hal->digitalWrite(csPin, HIGH);
165 return ret == ESP_OK ? 0 : -1;
166 }
167
168 int readRegister(const uint8_t reg, uint8_t *buf, size_t len) override
169 {
170
171 if (!buf || len == 0 || hal == nullptr) {
173 }
174
175 hal->digitalWrite(csPin, LOW);
176
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);
184
185 hal->digitalWrite(csPin, HIGH);
186 return ret == ESP_OK ? SENSOR_OK : SENSOR_ERR_COMM_NACK;
187 }
188
189 int writeThenRead(const uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len) override
190 {
191 if (!write_buffer || write_len == 0 || !read_buffer || read_len == 0 || hal == nullptr) {
193 }
194
195 hal->digitalWrite(csPin, LOW);
196
197 esp_err_t ret;
198 spi_transaction_t trans;
199 memset(&trans, 0, sizeof(trans)); // Zero out the trans
200
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);
206 };
207
208 ret = perform_transmission(write_buffer, write_len, nullptr);
209 if (ret != ESP_OK) {
210 hal->digitalWrite(csPin, HIGH);
211 return -1;
212 }
213
214 ret = perform_transmission(nullptr, read_len, read_buffer);
215
216 hal->digitalWrite(csPin, HIGH);
217
218 return ret == ESP_OK ? SENSOR_OK : SENSOR_ERR_COMM_NACK;
219 }
220
221
222 void setParams(const CommParamsBase &params) override
223 {
224#if defined(__cpp_rtti)
225 const auto pdat = dynamic_cast<const SPIParam *>(&params);
226#else
227 const auto pdat = static_cast<const SPIParam *>(&params);
228#endif
229 pdat->getSetting();
230
231 /*Remove SPI BUS and re-initialize according to the new settings*/
232 // spi_bus_remove_device(spi);
233 // spi_bus_free(host);
234 }
235
236private:
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;
241 uint8_t csPin;
242 SensorHal *hal;
243 int mosi, miso, sck;
244 SPISettings spiSetting;
245};
246
247#endif //*ESP_PLATFORM
@ SENSOR_OK
Definition SensorErr.hpp:37
@ SENSOR_ERR_COMM_NACK
Definition SensorErr.hpp:55
@ SENSOR_ERR_INVALID_ARG
Definition SensorErr.hpp:43
@ SENSOR_ERR_COMM_INIT
Definition SensorErr.hpp:53
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 &params)=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.
char buf[64]