10#ifndef M5_UNIT_COMPONENT_HPP
11#define M5_UNIT_COMPONENT_HPP
66 explicit Component(
const uint8_t addr = 0x00);
88 return _component_cfg;
111 virtual void update(
const bool force =
false)
122 return unit_device_name();
127 return unit_identifier();
132 return unit_attribute();
137 return unit_category();
152 return _manager !=
nullptr;
165 return _adapter.get();
170 typename std::remove_cv<typename std::remove_pointer<T>::type>::type*
172 using U =
typename std::remove_cv<typename std::remove_pointer<T>::type>::type;
173 static_assert(std::is_base_of<Adapter, U>::value,
"T must be derived from Adapter");
174 return (_adapter->type() == t) ?
static_cast<U*
>(_adapter.get()) :
nullptr;
177 inline auto asAdapter(
const Adapter::Type t)
const ->
const
178 typename std::remove_cv<typename std::remove_pointer<T>::type>::type*
180 using U =
typename std::remove_cv<typename std::remove_pointer<T>::type>::type;
181 static_assert(std::is_base_of<Adapter, U>::value,
"T must be derived from Adapter");
182 return (_adapter->type() == t) ?
static_cast<const U*
>(_adapter.get()) :
nullptr;
188 bool canAccessI2C()
const;
189 bool canAccessGPIO()
const;
190 bool canAccessUART()
const;
191 bool canAccessSPI()
const;
199 return in_periodic();
227 virtual bool assign(m5::hal::bus::Bus* bus);
229 virtual bool assign(TwoWire& wire);
231 virtual bool assign(m5::I2C_Class& i2c);
233 virtual bool assign(
const int8_t rx_pin,
const int8_t tx_pin);
235 virtual bool assign(HardwareSerial& serial);
237 virtual bool assign(SPIClass& spi,
const SPISettings& settings);
246 return _parent !=
nullptr;
251 return (_prev !=
nullptr) || (_next !=
nullptr);
276 template <
typename T>
279 using iterator_category = std::forward_iterator_tag;
280 using difference_type = std::ptrdiff_t;
281 using value_type = T;
283 using reference = T&;
285 explicit iterator(
Component* c =
nullptr) : _ptr(c)
289 reference operator*()
const
293 pointer operator->()
const
297 iterator& operator++()
299 _ptr = _ptr ? _ptr->_next :
nullptr;
302 iterator operator++(
int)
308 friend bool operator==(
const iterator& a,
const iterator& b)
310 return a._ptr == b._ptr;
312 friend bool operator!=(
const iterator& a,
const iterator& b)
314 return a._ptr != b._ptr;
321 using child_iterator = iterator<Component>;
322 using const_child_iterator = iterator<const Component>;
323 inline child_iterator childBegin() noexcept
325 return child_iterator(_child);
327 inline child_iterator childEnd() noexcept
329 return child_iterator();
331 inline const_child_iterator childBegin() const noexcept
333 return const_child_iterator(_child);
335 inline const_child_iterator childEnd() const noexcept
337 return const_child_iterator();
353 template <
typename Reg,
354 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
355 std::nullptr_t>::type =
nullptr>
356 bool readRegister(
const Reg reg, uint8_t* rbuf,
const size_t len,
const uint32_t delayMillis,
357 const bool stop =
true);
358 template <
typename Reg,
359 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
360 std::nullptr_t>::type =
nullptr>
361 bool readRegister8(
const Reg reg, uint8_t& result,
const uint32_t delayMillis,
const bool stop =
true);
363 template <
typename Reg,
364 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
365 std::nullptr_t>::type =
nullptr>
366 inline bool readRegister16BE(
const Reg reg, uint16_t& result,
const uint32_t delayMillis,
const bool stop =
true)
368 return read_register16E(reg, result, delayMillis, stop,
true);
371 template <
typename Reg,
372 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
373 std::nullptr_t>::type =
nullptr>
374 inline bool readRegister16LE(
const Reg reg, uint16_t& result,
const uint32_t delayMillis,
const bool stop =
true)
376 return read_register16E(reg, result, delayMillis, stop,
false);
379 template <
typename Reg,
380 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
381 std::nullptr_t>::type =
nullptr>
382 inline bool readRegister32BE(
const Reg reg, uint32_t& result,
const uint32_t delayMillis,
const bool stop =
true)
384 return read_register32E(reg, result, delayMillis, stop,
true);
387 template <
typename Reg,
388 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
389 std::nullptr_t>::type =
nullptr>
390 inline bool readRegister32LE(
const Reg reg, uint32_t& result,
const uint32_t delayMillis,
const bool stop =
true)
392 return read_register32E(reg, result, delayMillis, stop,
false);
395 m5::hal::error::error_t
writeWithTransaction(
const uint8_t* data,
const size_t len,
const uint32_t exparam = 1);
397 template <
typename Reg,
398 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
399 std::nullptr_t>::type =
nullptr>
400 m5::hal::error::error_t
writeWithTransaction(
const Reg reg,
const uint8_t* data,
const size_t len,
401 const bool stop =
true);
403 template <
typename Reg,
404 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
405 std::nullptr_t>::type =
nullptr>
406 bool writeRegister(
const Reg reg,
const uint8_t* buf =
nullptr,
const size_t len = 0U,
const bool stop =
true);
408 template <
typename Reg,
409 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
410 std::nullptr_t>::type =
nullptr>
411 bool writeRegister8(
const Reg reg,
const uint8_t value,
const bool stop =
true);
413 template <
typename Reg,
414 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
415 std::nullptr_t>::type =
nullptr>
416 inline bool writeRegister16BE(
const Reg reg,
const uint16_t value,
const bool stop =
true)
418 return write_register16E(reg, value, stop,
true);
421 template <
typename Reg,
422 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
423 std::nullptr_t>::type =
nullptr>
424 inline bool writeRegister16LE(
const Reg reg,
const uint16_t value,
const bool stop =
true)
426 return write_register16E(reg, value, stop,
false);
429 template <
typename Reg,
430 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
431 std::nullptr_t>::type =
nullptr>
432 inline bool writeRegister32BE(
const Reg reg,
const uint32_t value,
const bool stop =
true)
434 return write_register32E(reg, value, stop,
true);
437 template <
typename Reg,
438 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
439 std::nullptr_t>::type =
nullptr>
440 inline bool writeRegister32LE(
const Reg reg,
const uint32_t value,
const bool stop =
true)
442 return write_register32E(reg, value, stop,
false);
446 bool pinModeRX(
const gpio::Mode m);
447 bool writeDigitalRX(
const bool high);
448 bool readDigitalRX(
bool& high);
449 bool writeAnalogRX(
const uint16_t v);
450 bool readAnalogRX(uint16_t& v);
451 bool readAnalogMilliVoltsRX(uint32_t& mv);
452 bool pulseInRX(uint32_t& duration,
const int state,
const uint32_t timeout_us = 1000000);
454 bool pinModeTX(
const gpio::Mode m);
455 bool writeDigitalTX(
const bool high);
456 bool readDigitalTX(
bool& high);
457 bool writeAnalogTX(
const uint16_t v);
458 bool readAnalogTX(uint16_t& v);
459 bool readAnalogMilliVoltsTX(uint32_t& mv);
460 bool pulseInTX(uint32_t& duration,
const int state,
const uint32_t timeout_us = 1000000);
463#if defined(DOXYGEN_PROCESS)
471 template <
typename Reg>
472 bool readRegister(
const Reg reg, uint8_t* rbuf,
const size_t len,
const uint32_t delayMillis,
473 const bool stop =
true);
475 template <
typename Reg>
476 bool readRegister8(
const Reg reg, uint8_t& result,
const uint32_t delayMillis,
const bool stop =
true);
478 template <
typename Reg>
479 bool readRegister16BE(
const Reg reg, uint16_t& result,
const uint32_t delayMillis,
const bool stop =
true);
481 template <
typename Reg>
482 bool readRegister16LE(
const Reg reg, uint16_t& result,
const uint32_t delayMillis,
const bool stop =
true);
484 template <
typename Reg>
485 bool readRegister32BE(
const Reg reg, uint32_t& result,
const uint32_t delayMillis,
const bool stop =
true);
487 template <
typename Reg>
488 bool readRegister32LE(
const Reg reg, uint32_t& result,
const uint32_t delayMillis,
const bool stop =
true);
493 template <
typename Reg>
495 const bool stop =
true);
497 template <
typename Reg>
498 bool writeRegister(
const Reg reg,
const uint8_t* buf =
nullptr,
const size_t len = 0U,
const bool stop =
true);
500 template <
typename Reg>
503 template <
typename Reg>
506 template <
typename Reg>
509 template <
typename Reg>
512 template <
typename Reg>
519 virtual const char* unit_device_name()
const = 0;
524 return types::category_t::None;
526 inline virtual bool in_periodic()
const
531 inline virtual std::shared_ptr<Adapter> ensure_adapter(
const uint8_t )
537 inline virtual m5::hal::error::error_t select_channel(
const uint8_t)
539 return m5::hal::error::error_t::OK;
542 inline size_t stored_size()
const
544 return _component_cfg.stored_size;
547 bool add_child(Component* c);
550 bool changeAddress(
const uint8_t addr);
551 template <
typename Reg,
552 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
553 std::nullptr_t>::type =
nullptr>
554 bool read_register16E(
const Reg reg, uint16_t& result,
const uint32_t delayMillis,
const bool stop,
556 template <
typename Reg,
557 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
558 std::nullptr_t>::type =
nullptr>
559 bool write_register16E(
const Reg reg,
const uint16_t value,
const bool stop,
const bool endifan);
560 template <
typename Reg,
561 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
562 std::nullptr_t>::type =
nullptr>
563 bool read_register32E(
const Reg reg, uint32_t& result,
const uint32_t delayMillis,
const bool stop,
565 template <
typename Reg,
566 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
567 std::nullptr_t>::type =
nullptr>
568 bool write_register32E(
const Reg reg,
const uint32_t value,
const bool stop,
const bool endifan);
572 types::elapsed_time_t _latest{}, _interval{};
577 UnitUnified* _manager{};
578 std::shared_ptr<m5::unit::Adapter> _adapter{};
581 component_config_t _component_cfg{};
582 int16_t _channel{-1};
587 Component* _parent{};
592 friend class UnitUnified;
612template <
class Derived,
typename MD>
623 template <
typename... Args>
627 return static_cast<Derived*
>(
this)->start_periodic_measurement(std::forward<Args>(args)...);
635 template <
typename... Args>
639 return static_cast<Derived*
>(
this)->stop_periodic_measurement(std::forward<Args>(args)...);
648 return available_periodic_measurement_data();
653 return empty_periodic_measurement_data();
658 return full_periodic_measurement_data();
663 return static_cast<const Derived*
>(
this)->oldest_periodic_data();
668 return static_cast<const Derived*
>(
this)->latest_periodic_data();
673 discard_periodic_measurement_data();
678 flush_periodic_measurement_data();
686 virtual size_t available_periodic_measurement_data()
const = 0;
687 virtual bool empty_periodic_measurement_data()
const = 0;
688 virtual bool full_periodic_measurement_data()
const = 0;
689 virtual void discard_periodic_measurement_data() = 0;
690 virtual void flush_periodic_measurement_data() = 0;
699#define M5_UNIT_COMPONENT_HPP_BUILDER(cls, reg) \
701 constexpr static uint8_t DEFAULT_ADDRESS{(reg)}; \
702 static const types::uid_t uid; \
703 static const types::attr_t attr; \
704 static const char name[]; \
706 cls(const cls&) = delete; \
708 cls& operator=(const cls&) = delete; \
710 cls(cls&&) noexcept = default; \
712 cls& operator=(cls&&) noexcept = default; \
715 inline virtual const char* unit_device_name() const override \
719 inline virtual types::uid_t unit_identifier() const override \
723 inline virtual types::attr_t unit_attribute() const override \
729#define M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(cls, md) \
731 friend class PeriodicMeasurementAdapter<cls, md>; \
733 inline md oldest_periodic_data() const \
735 return !_data->empty() ? _data->front().value() : md{}; \
737 inline md latest_periodic_data() const \
739 return !_data->empty() ? _data->back().value() : md{}; \
741 inline virtual size_t available_periodic_measurement_data() const override \
743 return _data->size(); \
745 inline virtual bool empty_periodic_measurement_data() const override \
747 return _data->empty(); \
749 inline virtual bool full_periodic_measurement_data() const override \
751 return _data->full(); \
753 inline virtual void discard_periodic_measurement_data() override \
755 _data->pop_front(); \
757 inline virtual void flush_periodic_measurement_data() override \
Adapters to treat M5HAL and any connection in the same way.
Adapter base class to treat M5HAL and TwoWire,GPIO,Serial,SPI... in the same way.
Base class of unit component.
virtual void update(const bool force=false)
Update unit.
Definition M5UnitComponent.hpp:111
types::attr_t attribute() const
Gets the attributes.
Definition M5UnitComponent.hpp:130
bool writeRegister8(const Reg reg, const uint8_t value, const bool stop=true)
Write byte with transaction to register.
bool existsChild(const uint8_t ch) const
Is there an other unit connected to the specified channel?
Definition M5UnitComponent.cpp:39
bool readRegister8(const Reg reg, uint8_t &result, const uint32_t delayMillis, const bool stop=true)
Read byte with transaction from register.
bool readRegister16BE(const Reg reg, uint16_t &result, const uint32_t delayMillis, const bool stop=true)
Read word in big-endian order with transaction from register.
void component_config(const component_config_t &cfg)
Set the common configurations in each unit.
Definition M5UnitComponent.hpp:91
bool writeRegister(const Reg reg, const uint8_t *buf=nullptr, const size_t len=0U, const bool stop=true)
Write any data with transaction to register.
static const types::uid_t uid
Unique identifier.
Definition M5UnitComponent.hpp:58
bool selectChannel(const uint8_t ch=8)
Select valid channel if exists.
Definition M5UnitComponent.cpp:189
Component * parent()
Gets the parent unit.
Definition M5UnitComponent.hpp:263
component_config_t component_config()
Gets the common configurations in each unit.
Definition M5UnitComponent.hpp:86
bool writeRegister32BE(const Reg reg, const uint32_t value, const bool stop=true)
Write dword in big-endian order with transaction from register.
bool hasChildren() const
Are there other devices connected to me?
Definition M5UnitComponent.hpp:254
bool isRegistered() const
Is the unit registered with the manager?
Definition M5UnitComponent.hpp:150
virtual std::string debugInfo() const
Output information for debug.
Definition M5UnitComponent.cpp:404
static const char name[]
Device name string.
Definition M5UnitComponent.hpp:60
bool writeRegister32LE(const Reg reg, const uint32_t value, const bool stop=true)
Write dword in little-endian order with transaction from register.
bool inPeriodic() const
In periodic measurement?
Definition M5UnitComponent.hpp:197
bool writeRegister16BE(const Reg reg, const uint16_t value, const bool stop=true)
Write word in big-endian order with transaction from register.
Component * child(const uint8_t chhanle) const
Gets the device connected to the specified channel.
Definition M5UnitComponent.cpp:124
Adapter * adapter() const
Gets the access adapter.
Definition M5UnitComponent.hpp:163
m5::hal::error::error_t writeWithTransaction(const Reg reg, const uint8_t *data, const size_t len, const bool stop=true)
Write any data with transaction to register.
bool hasParent() const
Has parent unit?
Definition M5UnitComponent.hpp:244
bool hasSiblings() const
Are there any other devices connected to the same parent unit besides yourself?
Definition M5UnitComponent.hpp:249
size_t childrenSize() const
Number of units connected to me.
Definition M5UnitComponent.cpp:28
types::uid_t identifier() const
Gets the identifier.
Definition M5UnitComponent.hpp:125
const char * deviceName() const
Gets the device name.
Definition M5UnitComponent.hpp:120
virtual bool assign(m5::hal::bus::Bus *bus)
Assgin m5::hal::bus.
Definition M5UnitComponent.cpp:136
bool updated() const
Periodic measurement data updated?
Definition M5UnitComponent.hpp:202
types::elapsed_time_t updatedMillis() const
Time elapsed since start-up when the measurement data was updated in update()
Definition M5UnitComponent.hpp:210
static const types::attr_t attr
Attributes.
Definition M5UnitComponent.hpp:59
bool readRegister16LE(const Reg reg, uint16_t &result, const uint32_t delayMillis, const bool stop=true)
Read word in little-endian order with transaction from register.
bool readRegister32BE(const Reg reg, uint32_t &result, const uint32_t delayMillis, const bool stop=true)
Read dword in big-endian order with transaction from register.
auto asAdapter(const Adapter::Type t) const -> const typename std::remove_cv< typename std::remove_pointer< T >::type >::type *
Gets the device name.
Definition M5UnitComponent.hpp:177
m5::hal::error::error_t readWithTransaction(uint8_t *data, const size_t len)
Read any data with transaction.
Definition M5UnitComponent.cpp:198
bool writeRegister16LE(const Reg reg, const uint16_t value, const bool stop=true)
Write word in little-endian order with transaction from register.
m5::hal::error::error_t writeWithTransaction(const uint8_t *data, const size_t len, const bool stop=true)
Write any data with transaction.
bool readRegister(const Reg reg, uint8_t *rbuf, const size_t len, const uint32_t delayMillis, const bool stop=true)
Read any data with transaction from register.
uint8_t address() const
Address used to I2C access the device.
Definition M5UnitComponent.hpp:155
virtual bool begin()
Begin unit.
Definition M5UnitComponent.hpp:103
int16_t channel() const
Gets the channel if connected to another unit.
Definition M5UnitComponent.hpp:145
types::elapsed_time_t interval() const
Gets the periodic measurement interval.
Definition M5UnitComponent.hpp:218
bool generalCall(const uint8_t *data, const size_t len)
General call for I2C.
auto asAdapter(const Adapter::Type t) -> typename std::remove_cv< typename std::remove_pointer< T >::type >::type *
Gets the access adapter.
Definition M5UnitComponent.hpp:169
bool add(Component &c, const int16_t channel)
Connect the unit to the specified channel.
Definition M5UnitComponent.cpp:67
bool readRegister32LE(const Reg reg, uint32_t &result, const uint32_t delayMillis, const bool stop=true)
Read dword in little-endian order with transaction from register.
uint32_t order() const
Gets the registered order (== 0 means not yet)
Definition M5UnitComponent.hpp:140
types::category_t category() const
Gets the category.
Definition M5UnitComponent.hpp:135
Interface class for periodic measurement (CRTP)
Definition M5UnitComponent.hpp:613
MD oldest() const
Retrieve oldest stored data.
Definition M5UnitComponent.hpp:661
size_t available() const
Gets the number of stored data.
Definition M5UnitComponent.hpp:646
bool startPeriodicMeasurement(Args &&... args)
Start periodic measurement.
Definition M5UnitComponent.hpp:624
void discard()
Discard the oldest data accumulated.
Definition M5UnitComponent.hpp:671
MD latest() const
Retrieve latest stored data.
Definition M5UnitComponent.hpp:666
bool stopPeriodicMeasurement(Args &&... args)
Stop periodic measurement.
Definition M5UnitComponent.hpp:636
bool empty() const
Is empty stored data?
Definition M5UnitComponent.hpp:651
bool full() const
Is stored data full?
Definition M5UnitComponent.hpp:656
void flush()
Discard all data.
Definition M5UnitComponent.hpp:676
Top level namespace of M5stack.
Definition test_helper.hpp:20
Component basic settings for begin.
Definition M5UnitComponent.hpp:44
uint32_t clock
Clock for communication (default as 100000)
Definition M5UnitComponent.hpp:46
uint32_t stored_size
Maximum number of periodic measurement data to be stored.
Definition M5UnitComponent.hpp:48
uint8_t max_children
Maximum number of units that can be connected (default as 0)
Definition M5UnitComponent.hpp:52
bool self_update
Does the user call Unit's update? (default as false)
Definition M5UnitComponent.hpp:50
Type and enumerator definitions.
unsigned long elapsed_time_t
Elapsed time unit (ms)
Definition types.hpp:42
uint32_t attr_t
Component attribute bits.
Definition types.hpp:41
uint32_t uid_t
Component unique identifier.
Definition types.hpp:40
category_t
Unit category (used for static class determination)
Definition types.hpp:35