10#ifndef M5_UNIT_COMPONENT_HPP
11#define M5_UNIT_COMPONENT_HPP
63 explicit Component(
const uint8_t addr = 0x00);
85 return _component_cfg;
108 virtual void update(
const bool force =
false)
119 return unit_device_name();
124 return unit_identifier();
129 return unit_attribute();
134 return unit_category();
149 return _manager !=
nullptr;
162 return _adapter.get();
167 typename std::remove_cv<typename std::remove_pointer<T>::type>::type*
169 using U =
typename std::remove_cv<typename std::remove_pointer<T>::type>::type;
170 static_assert(std::is_base_of<Adapter, U>::value,
"T must be derived from Adapter");
171 return (_adapter->type() == t) ?
static_cast<U*
>(_adapter.get()) :
nullptr;
174 inline auto asAdapter(
const Adapter::Type t)
const ->
const
175 typename std::remove_cv<typename std::remove_pointer<T>::type>::type*
177 using U =
typename std::remove_cv<typename std::remove_pointer<T>::type>::type;
178 static_assert(std::is_base_of<Adapter, U>::value,
"T must be derived from Adapter");
179 return (_adapter->type() == t) ?
static_cast<const U*
>(_adapter.get()) :
nullptr;
185 bool canAccessI2C()
const;
186 bool canAccessGPIO()
const;
187 bool canAccessUART()
const;
195 return in_periodic();
223 virtual bool assign(m5::hal::bus::Bus* bus);
225 virtual bool assign(TwoWire& wire);
227 virtual bool assign(
const int8_t rx_pin,
const int8_t tx_pin);
229 virtual bool assign(HardwareSerial& serial);
238 return _parent !=
nullptr;
243 return (_prev !=
nullptr) || (_next !=
nullptr);
267 Component*
child(
const uint8_t chhanle)
const;
269 bool add(Component& c,
const int16_t
channel);
275 template <
typename T>
278 using iterator_category = std::forward_iterator_tag;
279 using difference_type = std::ptrdiff_t;
280 using value_type = T;
282 using reference = T&;
284 explicit iterator(Component* c =
nullptr) : _ptr(c)
288 reference operator*()
const
292 pointer operator->()
const
296 iterator& operator++()
298 _ptr = _ptr ? _ptr->_next :
nullptr;
301 iterator operator++(
int)
307 friend bool operator==(
const iterator& a,
const iterator& b)
309 return a._ptr == b._ptr;
311 friend bool operator!=(
const iterator& a,
const iterator& b)
313 return a._ptr != b._ptr;
320 using child_iterator = iterator<Component>;
321 using const_child_iterator = iterator<const Component>;
322 inline child_iterator childBegin() noexcept
324 return child_iterator(_child);
326 inline child_iterator childEnd() noexcept
328 return child_iterator();
330 inline const_child_iterator childBegin() const noexcept
332 return const_child_iterator(_child);
334 inline const_child_iterator childEnd() const noexcept
336 return const_child_iterator();
350 template <
typename Reg,
351 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
352 std::nullptr_t>::type =
nullptr>
353 bool readRegister(
const Reg reg, uint8_t* rbuf,
const size_t len,
const uint32_t delayMillis,
354 const bool stop =
true);
355 template <
typename Reg,
356 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
357 std::nullptr_t>::type =
nullptr>
358 bool readRegister8(
const Reg reg, uint8_t& result,
const uint32_t delayMillis,
const bool stop =
true);
360 template <
typename Reg,
361 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
362 std::nullptr_t>::type =
nullptr>
363 inline bool readRegister16BE(
const Reg reg, uint16_t& result,
const uint32_t delayMillis,
const bool stop =
true)
365 return read_register16E(reg, result, delayMillis, stop,
true);
368 template <
typename Reg,
369 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
370 std::nullptr_t>::type =
nullptr>
371 inline bool readRegister16LE(
const Reg reg, uint16_t& result,
const uint32_t delayMillis,
const bool stop =
true)
373 return read_register16E(reg, result, delayMillis, stop,
false);
376 template <
typename Reg,
377 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
378 std::nullptr_t>::type =
nullptr>
379 inline bool readRegister32BE(
const Reg reg, uint32_t& result,
const uint32_t delayMillis,
const bool stop =
true)
381 return read_register32E(reg, result, delayMillis, stop,
true);
384 template <
typename Reg,
385 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
386 std::nullptr_t>::type =
nullptr>
387 inline bool readRegister32LE(
const Reg reg, uint32_t& result,
const uint32_t delayMillis,
const bool stop =
true)
389 return read_register32E(reg, result, delayMillis, stop,
false);
392 m5::hal::error::error_t
writeWithTransaction(
const uint8_t* data,
const size_t len,
const uint32_t exparam = 1);
394 template <
typename Reg,
395 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
396 std::nullptr_t>::type =
nullptr>
397 m5::hal::error::error_t
writeWithTransaction(
const Reg reg,
const uint8_t* data,
const size_t len,
398 const bool stop =
true);
400 template <
typename Reg,
401 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
402 std::nullptr_t>::type =
nullptr>
403 bool writeRegister(
const Reg reg,
const uint8_t* buf =
nullptr,
const size_t len = 0U,
const bool stop =
true);
405 template <
typename Reg,
406 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
407 std::nullptr_t>::type =
nullptr>
408 bool writeRegister8(
const Reg reg,
const uint8_t value,
const bool stop =
true);
410 template <
typename Reg,
411 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
412 std::nullptr_t>::type =
nullptr>
413 inline bool writeRegister16BE(
const Reg reg,
const uint16_t value,
const bool stop =
true)
415 return write_register16E(reg, value, stop,
true);
418 template <
typename Reg,
419 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
420 std::nullptr_t>::type =
nullptr>
421 inline bool writeRegister16LE(
const Reg reg,
const uint16_t value,
const bool stop =
true)
423 return write_register16E(reg, value, stop,
false);
426 template <
typename Reg,
427 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
428 std::nullptr_t>::type =
nullptr>
429 inline bool writeRegister32BE(
const Reg reg,
const uint32_t value,
const bool stop =
true)
431 return write_register32E(reg, value, stop,
true);
434 template <
typename Reg,
435 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
436 std::nullptr_t>::type =
nullptr>
437 inline bool writeRegister32LE(
const Reg reg,
const uint32_t value,
const bool stop =
true)
439 return write_register32E(reg, value, stop,
false);
443 bool pinModeRX(
const gpio::Mode m);
444 bool writeDigitalRX(
const bool high);
445 bool readDigitalRX(
bool& high);
446 bool writeAnalogRX(
const uint16_t v);
447 bool readAnalogRX(uint16_t& v);
448 bool pulseInRX(uint32_t& duration,
const int state,
const uint32_t timeout_us = 1000000);
450 bool pinModeTX(
const gpio::Mode m);
451 bool writeDigitalTX(
const bool high);
452 bool readDigitalTX(
bool& high);
453 bool writeAnalogTX(
const uint16_t v);
454 bool readAnalogTX(uint16_t& v);
455 bool pulseInTX(uint32_t& duration,
const int state,
const uint32_t timeout_us = 1000000);
458#if defined(DOXYGEN_PROCESS)
466 template <
typename Reg>
467 bool readRegister(
const Reg reg, uint8_t* rbuf,
const size_t len,
const uint32_t delayMillis,
468 const bool stop =
true);
470 template <
typename Reg>
471 bool readRegister8(
const Reg reg, uint8_t& result,
const uint32_t delayMillis,
const bool stop =
true);
473 template <
typename Reg>
474 bool readRegister16BE(
const Reg reg, uint16_t& result,
const uint32_t delayMillis,
const bool stop =
true);
476 template <
typename Reg>
477 bool readRegister16LE(
const Reg reg, uint16_t& result,
const uint32_t delayMillis,
const bool stop =
true);
479 template <
typename Reg>
480 bool readRegister32BE(
const Reg reg, uint32_t& result,
const uint32_t delayMillis,
const bool stop =
true);
482 template <
typename Reg>
483 bool readRegister32LE(
const Reg reg, uint32_t& result,
const uint32_t delayMillis,
const bool stop =
true);
488 template <
typename Reg>
490 const bool stop =
true);
492 template <
typename Reg>
493 bool writeRegister(
const Reg reg,
const uint8_t* buf =
nullptr,
const size_t len = 0U,
const bool stop =
true);
495 template <
typename Reg>
498 template <
typename Reg>
501 template <
typename Reg>
504 template <
typename Reg>
507 template <
typename Reg>
514 virtual const char* unit_device_name()
const = 0;
519 return types::category_t::None;
521 inline virtual bool in_periodic()
const
526 inline virtual std::shared_ptr<Adapter> ensure_adapter(
const uint8_t )
532 inline virtual m5::hal::error::error_t select_channel(
const uint8_t)
534 return m5::hal::error::error_t::OK;
537 inline size_t stored_size()
const
539 return _component_cfg.stored_size;
542 bool add_child(Component* c);
545 bool changeAddress(
const uint8_t addr);
546 template <
typename Reg,
547 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
548 std::nullptr_t>::type =
nullptr>
549 bool read_register16E(
const Reg reg, uint16_t& result,
const uint32_t delayMillis,
const bool stop,
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 write_register16E(
const Reg reg,
const uint16_t value,
const bool stop,
const bool endifan);
555 template <
typename Reg,
556 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
557 std::nullptr_t>::type =
nullptr>
558 bool read_register32E(
const Reg reg, uint32_t& result,
const uint32_t delayMillis,
const bool stop,
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 write_register32E(
const Reg reg,
const uint32_t value,
const bool stop,
const bool endifan);
567 types::elapsed_time_t _latest{}, _interval{};
572 UnitUnified* _manager{};
573 std::shared_ptr<m5::unit::Adapter> _adapter{};
576 component_config_t _component_cfg{};
577 int16_t _channel{-1};
582 Component* _parent{};
587 friend class UnitUnified;
607template <
class Derived,
typename MD>
618 template <
typename... Args>
622 return static_cast<Derived*
>(
this)->start_periodic_measurement(std::forward<Args>(args)...);
630 template <
typename... Args>
634 return static_cast<Derived*
>(
this)->stop_periodic_measurement(std::forward<Args>(args)...);
643 return available_periodic_measurement_data();
648 return empty_periodic_measurement_data();
653 return full_periodic_measurement_data();
658 return static_cast<const Derived*
>(
this)->oldest_periodic_data();
663 return static_cast<const Derived*
>(
this)->latest_periodic_data();
668 discard_periodic_measurement_data();
673 flush_periodic_measurement_data();
681 virtual size_t available_periodic_measurement_data()
const = 0;
682 virtual bool empty_periodic_measurement_data()
const = 0;
683 virtual bool full_periodic_measurement_data()
const = 0;
684 virtual void discard_periodic_measurement_data() = 0;
685 virtual void flush_periodic_measurement_data() = 0;
694#define M5_UNIT_COMPONENT_HPP_BUILDER(cls, reg) \
696 constexpr static uint8_t DEFAULT_ADDRESS{(reg)}; \
697 static const types::uid_t uid; \
698 static const types::attr_t attr; \
699 static const char name[]; \
701 cls(const cls&) = delete; \
703 cls& operator=(const cls&) = delete; \
705 cls(cls&&) noexcept = default; \
707 cls& operator=(cls&&) noexcept = default; \
710 inline virtual const char* unit_device_name() const override \
714 inline virtual types::uid_t unit_identifier() const override \
718 inline virtual types::attr_t unit_attribute() const override \
724#define M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(cls, md) \
726 friend class PeriodicMeasurementAdapter<cls, md>; \
728 inline md oldest_periodic_data() const \
730 return !_data->empty() ? _data->front().value() : md{}; \
732 inline md latest_periodic_data() const \
734 return !_data->empty() ? _data->back().value() : md{}; \
736 inline virtual size_t available_periodic_measurement_data() const override \
738 return _data->size(); \
740 inline virtual bool empty_periodic_measurement_data() const override \
742 return _data->empty(); \
744 inline virtual bool full_periodic_measurement_data() const override \
746 return _data->full(); \
748 inline virtual void discard_periodic_measurement_data() override \
750 _data->pop_front(); \
752 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:108
types::attr_t attribute() const
Gets the attributes.
Definition M5UnitComponent.hpp:127
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:88
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:55
bool selectChannel(const uint8_t ch=8)
Select valid channel if exists.
Definition M5UnitComponent.cpp:157
Component * parent()
Gets the parent unit.
Definition M5UnitComponent.hpp:255
component_config_t component_config()
Gets the common configurations in each unit.
Definition M5UnitComponent.hpp:83
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:246
bool isRegistered() const
Is the unit registered with the manager?
Definition M5UnitComponent.hpp:147
virtual std::string debugInfo() const
Output information for debug.
Definition M5UnitComponent.cpp:362
static const char name[]
Device name string.
Definition M5UnitComponent.hpp:57
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:193
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:113
Adapter * adapter() const
Gets the access adapter.
Definition M5UnitComponent.hpp:160
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:236
bool hasSiblings() const
Are there any other devices connected to the same parent unit besides yourself?
Definition M5UnitComponent.hpp:241
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:122
const char * deviceName() const
Gets the device name.
Definition M5UnitComponent.hpp:117
virtual bool assign(m5::hal::bus::Bus *bus)
Assgin m5::hal::bus.
Definition M5UnitComponent.cpp:125
bool updated() const
Periodic measurement data updated?
Definition M5UnitComponent.hpp:198
types::elapsed_time_t updatedMillis() const
Time elapsed since start-up when the measurement data was updated in update()
Definition M5UnitComponent.hpp:206
static const types::attr_t attr
Attributes.
Definition M5UnitComponent.hpp:56
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:174
m5::hal::error::error_t readWithTransaction(uint8_t *data, const size_t len)
Read any data with transaction.
Definition M5UnitComponent.cpp:166
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:152
virtual bool begin()
Begin unit.
Definition M5UnitComponent.hpp:100
int16_t channel() const
Gets the channel if connected to another unit.
Definition M5UnitComponent.hpp:142
types::elapsed_time_t interval() const
Gets the periodic measurement interval.
Definition M5UnitComponent.hpp:214
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:166
bool add(Component &c, const int16_t channel)
Connect the unit to the specified channel.
Definition M5UnitComponent.cpp:62
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:137
types::category_t category() const
Gets the category.
Definition M5UnitComponent.hpp:132
Interface class for periodic measurement (CRTP)
Definition M5UnitComponent.hpp:608
MD oldest() const
Retrieve oldest stored data.
Definition M5UnitComponent.hpp:656
size_t available() const
Gets the number of stored data.
Definition M5UnitComponent.hpp:641
bool startPeriodicMeasurement(Args &&... args)
Start periodic measurement.
Definition M5UnitComponent.hpp:619
void discard()
Discard the oldest data accumulated.
Definition M5UnitComponent.hpp:666
MD latest() const
Retrieve latest stored data.
Definition M5UnitComponent.hpp:661
bool stopPeriodicMeasurement(Args &&... args)
Stop periodic measurement.
Definition M5UnitComponent.hpp:631
bool empty() const
Is empty stored data?
Definition M5UnitComponent.hpp:646
bool full() const
Is stored data full?
Definition M5UnitComponent.hpp:651
void flush()
Discard all data.
Definition M5UnitComponent.hpp:671
Top level namespace of M5stack.
Definition test_helper.hpp:18
Component basic settings for begin.
Definition M5UnitComponent.hpp:41
uint32_t clock
Clock for communication (default as 100000)
Definition M5UnitComponent.hpp:43
uint32_t stored_size
Maximum number of periodic measurement data to be stored.
Definition M5UnitComponent.hpp:45
uint8_t max_children
Maximum number of units that can be connected (default as 0)
Definition M5UnitComponent.hpp:49
bool self_update
Does the user call Unit's update? (default as false)
Definition M5UnitComponent.hpp:47
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