SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
SensorCommBase.hpp
Go to the documentation of this file.
1
40#pragma once
41#include "SensorLib.h"
42#include <memory>
43#include "SensorErrorMixin.hpp"
44
45//--------------------------------------------------------------------------
46// C++11 compatibility: provide std::make_unique if not yet in the standard.
47//--------------------------------------------------------------------------
48#if __cplusplus == 201103L
49namespace std
50{
59template<typename T, typename... Args>
60std::unique_ptr<T> make_unique(Args &&... args)
61{
62 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
63}
64}
65#endif
66
67//--------------------------------------------------------------------------
68// Compile‑time array size utility
69//--------------------------------------------------------------------------
77template <typename T, size_t N>
78constexpr size_t arraySize(const T (&arr)[N])
79{
80 return N;
81}
82
83//============================================================================
84// Communication parameter base classes
85//============================================================================
86
92{
93public:
94 virtual ~CommParamsBase() = default;
95};
96
97//--------------------------------------------------------------------------
98// I2C specific parameters
99//--------------------------------------------------------------------------
105{
106public:
117
124
129 uint32_t getParams() const
130 {
131 return params;
132 }
133
138 uint8_t getType() const
139 {
140 return type;
141 }
142
143protected:
145 uint32_t params;
146};
147
148//--------------------------------------------------------------------------
149// SPI settings emulation for non‑Arduino environments
150//--------------------------------------------------------------------------
151#if !defined(ARDUINO)
152
153// Standard SPI mode constants (mirror Arduino's definitions)
154#define SPI_MODE0 0
155#define SPI_MODE1 1
156#define SPI_MODE2 2
157#define SPI_MODE3 3
158
159#define SPI_LSB 0
160#define SPI_MSB 1
161
167{
168public:
170 SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) :
172
173 uint32_t clock;
174 uint8_t bitOrder;
175 uint8_t dataMode;
176};
177#endif
178
179//--------------------------------------------------------------------------
180// SPI specific parameters
181//--------------------------------------------------------------------------
187{
188private:
189 SPISettings setting;
190
191public:
196 SPIParam(SPISettings setting) : setting(setting) {}
197
203 {
204 return setting;
205 }
206};
207
208//============================================================================
209// Abstract sensor communication interface
210//============================================================================
211// Note: SensorErrorMixin is assumed to be defined elsewhere and provides
212// error handling / status reporting.
213
220{
221public:
222 //----------------------------------------------------------------------
223 // Initialisation / deinitialisation
224 //----------------------------------------------------------------------
229 virtual bool init() = 0;
230
234 virtual void deinit() = 0;
235
236 //----------------------------------------------------------------------
237 // Read operations
238 //----------------------------------------------------------------------
244 virtual int readRegister(const uint8_t reg)
245 {
246 int err = 0;
247 uint8_t value = 0x00;
248 err = readRegister(reg, &value, 1);
249 if (err < 0) {
250 return err; // Propagate read error
251 }
252 return value;
253 }
254
262 virtual int readRegister(const uint8_t reg, uint8_t *buf, size_t len) = 0;
263
270 virtual int readBuffer(uint8_t *buf, size_t len) = 0;
271
272 //----------------------------------------------------------------------
273 // Write operations
274 //----------------------------------------------------------------------
281 virtual int writeRegister(const uint8_t reg, uint8_t val)
282 {
283 return writeRegister(reg, &val, 1);
284 }
285
293 virtual int writeRegister(const uint8_t reg, uint8_t *buf, size_t len) = 0;
294
303 virtual int writeRegister(const uint8_t reg, uint8_t norVal, uint8_t orVal)
304 {
305 int val = readRegister(reg);
306 if (val < 0) {
307 return val; // Propagate read error
308 }
309 val &= norVal;
310 val |= orVal;
311 return writeRegister(reg, reinterpret_cast<uint8_t *>(&val), 1);
312 }
313
320 virtual int writeBuffer(uint8_t *buffer, size_t len) = 0;
321
322 //----------------------------------------------------------------------
323 // Combined transactions
324 //----------------------------------------------------------------------
333 virtual int writeThenRead(const uint8_t *write_buffer, size_t write_len,
334 uint8_t *read_buffer, size_t read_len) = 0;
335
336 //----------------------------------------------------------------------
337 // Bit‑level register manipulation
338 //----------------------------------------------------------------------
345 virtual bool setRegisterBit(const uint8_t reg, uint8_t bit)
346 {
347 int value = readRegister(reg);
348 if (value < 0)
349 return false;
350 value |= (1 << bit);
351 return writeRegister(reg, reinterpret_cast<uint8_t *>(&value), 1) == 0;
352 }
353
360 virtual bool clrRegisterBit(const uint8_t reg, uint8_t bit)
361 {
362 int value = readRegister(reg);
363 if (value < 0)
364 return false;
365 value &= ~(1 << bit);
366 return writeRegister(reg, reinterpret_cast<uint8_t *>(&value), 1) == 0;
367 }
368
375 virtual bool getRegisterBit(const uint8_t reg, uint8_t bit)
376 {
377 int value = readRegister(reg);
378 if (value < 0)
379 return false;
380 return (value & (1 << bit)) != 0;
381 }
382
390 virtual int updateBits(uint8_t reg, uint8_t mask, uint8_t value_shifted)
391 {
392 int cur = readRegister(reg);
393 if (cur < 0) return cur; // Propagate read error
394 uint8_t newv = (uint8_t(cur) & ~mask) | (value_shifted & mask);
395 return writeRegister(reg, newv);
396 }
397
398 //----------------------------------------------------------------------
399 // Parameter configuration
400 //----------------------------------------------------------------------
405 virtual void setParams(const CommParamsBase &params) = 0;
406
407 //----------------------------------------------------------------------
408 // Destructor
409 //----------------------------------------------------------------------
410 virtual ~SensorCommBase() = default;
411};
412
413//============================================================================
414// Hardware abstraction layers
415//============================================================================
416
422{
423public:
424 // Type aliases for callback signatures
425 using CustomWrite = void(*)(uint8_t pin, uint8_t level);
426 using CustomRead = uint8_t(*)(uint8_t pin);
427 using CustomMode = void(*)(uint8_t pin, uint8_t mode);
428
429 SensorHalCustom() : writeCallback(nullptr), readCallback(nullptr), modeCallback(nullptr) {}
430
436 {
437 writeCallback = callback;
438 }
439
445 {
446 readCallback = callback;
447 }
448
454 {
455 modeCallback = callback;
456 }
457
458protected:
462};
463
469{
470public:
476 virtual void pinMode(uint8_t pin, uint8_t mode) = 0;
477
483 virtual void digitalWrite(uint8_t pin, uint8_t level) = 0;
484
490 virtual uint8_t digitalRead(uint8_t pin) = 0;
491
496 virtual uint32_t millis() = 0;
497
502 virtual void delay(uint32_t ms) = 0;
503
508 virtual void delayMicroseconds(uint32_t us) = 0;
509};
constexpr size_t arraySize(const T(&arr)[N])
Returns the number of elements in a C‑style array at compile time.
#define SPI_MODE0
CPOL = 0, CPHA = 0.
#define SPI_MSB
Most significant bit first.
@license MIT License
@license MIT License
uint8_t level
Abstract base for all communication parameter objects.
virtual ~CommParamsBase()=default
I2C communication parameters.
uint8_t getType() const
Retrieve the parameter type.
uint32_t params
The value of the parameter.
I2CParamType
Identifiers for the various I2C settings that can be changed.
@ I2C_SET_ADDR
Set device address.
@ I2C_SET_CLOCK
Set I2C clock frequency.
@ I2C_SET_FLAG
Set a generic flag (interpretation depends on driver)
@ I2C_SET_READ_DELAY_US
Delay after read operations (microseconds)
@ I2C_SET_WRITE_DELAY_US
Delay after write operations (microseconds)
uint32_t getParams() const
Retrieve the stored parameter value.
I2CParam(I2CParamType type, uint32_t params)
Construct an I2C parameter object.
enum I2CParamType type
Which I2C parameter this object represents.
SPI communication parameters.
SPIParam(SPISettings setting)
Construct an SPI parameter object from an SPISettings.
SPISettings getSetting() const
Retrieve the stored SPI settings.
Emulation of Arduino's SPISettings class.
SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
uint32_t clock
SPI clock frequency in Hz.
uint8_t bitOrder
SPI_LSB or SPI_MSB.
uint8_t dataMode
SPI_MODE0 .. SPI_MODE3.
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 bool clrRegisterBit(const uint8_t reg, uint8_t bit)
Clear a specific bit in a register.
virtual int readRegister(const uint8_t reg, uint8_t *buf, size_t len)=0
Read multiple bytes from a register into a buffer.
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 ~SensorCommBase()=default
virtual int writeRegister(const uint8_t reg, uint8_t *buf, size_t len)=0
Write multiple bytes to a register.
virtual int writeRegister(const uint8_t reg, uint8_t norVal, uint8_t orVal)
Modify a register using a NOR and OR mask.
virtual bool setRegisterBit(const uint8_t reg, uint8_t bit)
Set a specific bit in a register.
virtual void setParams(const CommParamsBase &params)=0
Apply communication parameters (e.g., I2C address, SPI settings).
virtual int updateBits(uint8_t reg, uint8_t mask, uint8_t value_shifted)
Update specific bits in a register.
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.
virtual bool getRegisterBit(const uint8_t reg, uint8_t bit)
Read the state of a specific bit in a register.
Customisation point for low‑level GPIO callbacks.
void(*)(uint8_t pin, uint8_t mode) CustomMode
Set pin mode (INPUT/OUTPUT, etc.)
void setCustomRead(CustomRead callback)
Set a custom digitalRead implementation.
CustomMode modeCallback
Custom pinMode, nullptr if not set.
CustomWrite writeCallback
Custom digitalWrite, nullptr if not set.
void(*)(uint8_t pin, uint8_t level) CustomWrite
Set pin level (0/1)
CustomRead readCallback
Custom digitalRead, nullptr if not set.
void setCustomMode(CustomMode callback)
Set a custom pinMode implementation.
void setCustomWrite(CustomWrite callback)
Set a custom digitalWrite implementation.
uint8_t(*)(uint8_t pin) CustomRead
Read pin level.
Abstract hardware abstraction layer.
virtual uint8_t digitalRead(uint8_t pin)=0
Read the digital value from a pin.
virtual void pinMode(uint8_t pin, uint8_t mode)=0
Set the mode of a digital pin.
virtual void digitalWrite(uint8_t pin, uint8_t level)=0
Write a digital value to a pin.
virtual void delay(uint32_t ms)=0
Blocking delay for a given number of milliseconds.
virtual void delayMicroseconds(uint32_t us)=0
Blocking delay for a given number of microseconds.
virtual uint32_t millis()=0
Get the current system time in milliseconds.
char buf[64]