10#ifndef M5_UNIT_COMPONENT_HPP
11#define M5_UNIT_COMPONENT_HPP
62 explicit Component(
const uint8_t addr = 0x00);
84 return _component_cfg;
107 virtual void update(
const bool force =
false)
118 return unit_device_name();
123 return unit_identifier();
128 return unit_attribute();
133 return unit_category();
148 return _manager !=
nullptr;
161 return _adapter.get();
166 typename std::remove_cv<typename std::remove_pointer<T>::type>::type*
168 using U =
typename std::remove_cv<typename std::remove_pointer<T>::type>::type;
169 static_assert(std::is_base_of<Adapter, U>::value,
"T must be derived from Adapter");
170 return (_adapter->type() == t) ?
static_cast<U*
>(_adapter.get()) :
nullptr;
173 inline auto asAdapter(
const Adapter::Type t)
const ->
const
174 typename std::remove_cv<typename std::remove_pointer<T>::type>::type*
176 using U =
typename std::remove_cv<typename std::remove_pointer<T>::type>::type;
177 static_assert(std::is_base_of<Adapter, U>::value,
"T must be derived from Adapter");
178 return (_adapter->type() == t) ?
static_cast<const U*
>(_adapter.get()) :
nullptr;
184 bool canAccessI2C()
const;
185 bool canAccessGPIO()
const;
193 return in_periodic();
221 virtual bool assign(m5::hal::bus::Bus* bus);
223 virtual bool assign(TwoWire& wire);
225 virtual bool assign(
const int8_t rx_pin,
const int8_t tx_pin);
234 return _parent !=
nullptr;
239 return (_prev !=
nullptr) || (_next !=
nullptr);
263 Component*
child(
const uint8_t chhanle)
const;
265 bool add(Component& c,
const int16_t
channel);
271 template <
typename T>
274 using iterator_category = std::forward_iterator_tag;
275 using difference_type = std::ptrdiff_t;
276 using value_type = T;
278 using reference = T&;
280 explicit iterator(Component* c =
nullptr) : _ptr(c)
284 reference operator*()
const
288 pointer operator->()
const
292 iterator& operator++()
294 _ptr = _ptr ? _ptr->_next :
nullptr;
297 iterator operator++(
int)
303 friend bool operator==(
const iterator& a,
const iterator& b)
305 return a._ptr == b._ptr;
307 friend bool operator!=(
const iterator& a,
const iterator& b)
309 return a._ptr != b._ptr;
316 using child_iterator = iterator<Component>;
317 using const_child_iterator = iterator<const Component>;
318 inline child_iterator childBegin() noexcept
320 return child_iterator(_child);
322 inline child_iterator childEnd() noexcept
324 return child_iterator();
326 inline const_child_iterator childBegin() const noexcept
328 return const_child_iterator(_child);
330 inline const_child_iterator childEnd() const noexcept
332 return const_child_iterator();
346 template <
typename Reg,
347 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
348 std::nullptr_t>::type =
nullptr>
349 bool readRegister(
const Reg reg, uint8_t* rbuf,
const size_t len,
const uint32_t delayMillis,
350 const bool stop =
true);
351 template <
typename Reg,
352 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
353 std::nullptr_t>::type =
nullptr>
354 bool readRegister8(
const Reg reg, uint8_t& result,
const uint32_t delayMillis,
const bool stop =
true);
356 template <
typename Reg,
357 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
358 std::nullptr_t>::type =
nullptr>
359 inline bool readRegister16BE(
const Reg reg, uint16_t& result,
const uint32_t delayMillis,
const bool stop =
true)
361 return read_register16E(reg, result, delayMillis, stop,
true);
364 template <
typename Reg,
365 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
366 std::nullptr_t>::type =
nullptr>
367 inline bool readRegister16LE(
const Reg reg, uint16_t& result,
const uint32_t delayMillis,
const bool stop =
true)
369 return read_register16E(reg, result, delayMillis, stop,
false);
372 template <
typename Reg,
373 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
374 std::nullptr_t>::type =
nullptr>
375 inline bool readRegister32BE(
const Reg reg, uint32_t& result,
const uint32_t delayMillis,
const bool stop =
true)
377 return read_register32E(reg, result, delayMillis, stop,
true);
380 template <
typename Reg,
381 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
382 std::nullptr_t>::type =
nullptr>
383 inline bool readRegister32LE(
const Reg reg, uint32_t& result,
const uint32_t delayMillis,
const bool stop =
true)
385 return read_register32E(reg, result, delayMillis, stop,
false);
388 m5::hal::error::error_t
writeWithTransaction(
const uint8_t* data,
const size_t len,
const uint32_t exparam = 1);
390 template <
typename Reg,
391 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
392 std::nullptr_t>::type =
nullptr>
393 m5::hal::error::error_t
writeWithTransaction(
const Reg reg,
const uint8_t* data,
const size_t len,
394 const bool stop =
true);
396 template <
typename Reg,
397 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
398 std::nullptr_t>::type =
nullptr>
399 bool writeRegister(
const Reg reg,
const uint8_t* buf =
nullptr,
const size_t len = 0U,
const bool stop =
true);
401 template <
typename Reg,
402 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
403 std::nullptr_t>::type =
nullptr>
404 bool writeRegister8(
const Reg reg,
const uint8_t value,
const bool stop =
true);
406 template <
typename Reg,
407 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
408 std::nullptr_t>::type =
nullptr>
409 inline bool writeRegister16BE(
const Reg reg,
const uint16_t value,
const bool stop =
true)
411 return write_register16E(reg, value, stop,
true);
414 template <
typename Reg,
415 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
416 std::nullptr_t>::type =
nullptr>
417 inline bool writeRegister16LE(
const Reg reg,
const uint16_t value,
const bool stop =
true)
419 return write_register16E(reg, value, stop,
false);
422 template <
typename Reg,
423 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
424 std::nullptr_t>::type =
nullptr>
425 inline bool writeRegister32BE(
const Reg reg,
const uint32_t value,
const bool stop =
true)
427 return write_register32E(reg, value, stop,
true);
430 template <
typename Reg,
431 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
432 std::nullptr_t>::type =
nullptr>
433 inline bool writeRegister32LE(
const Reg reg,
const uint32_t value,
const bool stop =
true)
435 return write_register32E(reg, value, stop,
false);
439 bool pinModeRX(
const gpio::Mode m);
440 bool writeDigitalRX(
const bool high);
441 bool readDigitalRX(
bool& high);
442 bool writeAnalogRX(
const uint16_t v);
443 bool readAnalogRX(uint16_t& v);
444 bool pulseInRX(uint32_t& duration,
const int state,
const uint32_t timeout_us = 1000000);
446 bool pinModeTX(
const gpio::Mode m);
447 bool writeDigitalTX(
const bool high);
448 bool readDigitalTX(
bool& high);
449 bool writeAnalogTX(
const uint16_t v);
450 bool readAnalogTX(uint16_t& v);
451 bool pulseInTX(uint32_t& duration,
const int state,
const uint32_t timeout_us = 1000000);
454#if defined(DOXYGEN_PROCESS)
462 template <
typename Reg>
463 bool readRegister(
const Reg reg, uint8_t* rbuf,
const size_t len,
const uint32_t delayMillis,
464 const bool stop =
true);
466 template <
typename Reg>
467 bool readRegister8(
const Reg reg, uint8_t& result,
const uint32_t delayMillis,
const bool stop =
true);
469 template <
typename Reg>
470 bool readRegister16BE(
const Reg reg, uint16_t& result,
const uint32_t delayMillis,
const bool stop =
true);
472 template <
typename Reg>
473 bool readRegister16LE(
const Reg reg, uint16_t& result,
const uint32_t delayMillis,
const bool stop =
true);
475 template <
typename Reg>
476 bool readRegister32BE(
const Reg reg, uint32_t& result,
const uint32_t delayMillis,
const bool stop =
true);
478 template <
typename Reg>
479 bool readRegister32LE(
const Reg reg, uint32_t& result,
const uint32_t delayMillis,
const bool stop =
true);
484 template <
typename Reg>
486 const bool stop =
true);
488 template <
typename Reg>
489 bool writeRegister(
const Reg reg,
const uint8_t* buf =
nullptr,
const size_t len = 0U,
const bool stop =
true);
491 template <
typename Reg>
494 template <
typename Reg>
497 template <
typename Reg>
500 template <
typename Reg>
503 template <
typename Reg>
510 virtual const char* unit_device_name()
const = 0;
515 return types::category_t::None;
517 inline virtual bool in_periodic()
const
522 inline virtual std::shared_ptr<Adapter> ensure_adapter(
const uint8_t )
528 inline virtual m5::hal::error::error_t select_channel(
const uint8_t)
530 return m5::hal::error::error_t::OK;
533 inline size_t stored_size()
const
535 return _component_cfg.stored_size;
538 bool add_child(Component* c);
541 bool changeAddress(
const uint8_t addr);
542 template <
typename Reg,
543 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
544 std::nullptr_t>::type =
nullptr>
545 bool read_register16E(
const Reg reg, uint16_t& result,
const uint32_t delayMillis,
const bool stop,
547 template <
typename Reg,
548 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value &&
sizeof(Reg) <= 2,
549 std::nullptr_t>::type =
nullptr>
550 bool write_register16E(
const Reg reg,
const uint16_t value,
const bool stop,
const bool endifan);
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_register32E(
const Reg reg, uint32_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_register32E(
const Reg reg,
const uint32_t value,
const bool stop,
const bool endifan);
563 types::elapsed_time_t _latest{}, _interval{};
568 UnitUnified* _manager{};
569 std::shared_ptr<m5::unit::Adapter> _adapter{};
572 component_config_t _component_cfg{};
573 int16_t _channel{-1};
578 Component* _parent{};
583 friend class UnitUnified;
603template <
class Derived,
typename MD>
614 template <
typename... Args>
618 return static_cast<Derived*
>(
this)->start_periodic_measurement(std::forward<Args>(args)...);
626 template <
typename... Args>
630 return static_cast<Derived*
>(
this)->stop_periodic_measurement(std::forward<Args>(args)...);
639 return available_periodic_measurement_data();
644 return empty_periodic_measurement_data();
649 return full_periodic_measurement_data();
654 return static_cast<const Derived*
>(
this)->oldest_periodic_data();
659 return static_cast<const Derived*
>(
this)->latest_periodic_data();
664 discard_periodic_measurement_data();
669 flush_periodic_measurement_data();
677 virtual size_t available_periodic_measurement_data()
const = 0;
678 virtual bool empty_periodic_measurement_data()
const = 0;
679 virtual bool full_periodic_measurement_data()
const = 0;
680 virtual void discard_periodic_measurement_data() = 0;
681 virtual void flush_periodic_measurement_data() = 0;
690#define M5_UNIT_COMPONENT_HPP_BUILDER(cls, reg) \
692 constexpr static uint8_t DEFAULT_ADDRESS{(reg)}; \
693 static const types::uid_t uid; \
694 static const types::attr_t attr; \
695 static const char name[]; \
697 cls(const cls&) = delete; \
699 cls& operator=(const cls&) = delete; \
701 cls(cls&&) noexcept = default; \
703 cls& operator=(cls&&) noexcept = default; \
706 inline virtual const char* unit_device_name() const override \
710 inline virtual types::uid_t unit_identifier() const override \
714 inline virtual types::attr_t unit_attribute() const override \
720#define M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(cls, md) \
722 friend class PeriodicMeasurementAdapter<cls, md>; \
724 inline md oldest_periodic_data() const \
726 return !_data->empty() ? _data->front().value() : md{}; \
728 inline md latest_periodic_data() const \
730 return !_data->empty() ? _data->back().value() : md{}; \
732 inline virtual size_t available_periodic_measurement_data() const override \
734 return _data->size(); \
736 inline virtual bool empty_periodic_measurement_data() const override \
738 return _data->empty(); \
740 inline virtual bool full_periodic_measurement_data() const override \
742 return _data->full(); \
744 inline virtual void discard_periodic_measurement_data() override \
746 _data->pop_front(); \
748 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:107
types::attr_t attribute() const
Gets the attributes.
Definition M5UnitComponent.hpp:126
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:87
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:54
bool selectChannel(const uint8_t ch=8)
Select valid channel if exists.
Definition M5UnitComponent.cpp:144
Component * parent()
Gets the parent unit.
Definition M5UnitComponent.hpp:251
component_config_t component_config()
Gets the common configurations in each unit.
Definition M5UnitComponent.hpp:82
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:242
bool isRegistered() const
Is the unit registered with the manager?
Definition M5UnitComponent.hpp:146
virtual std::string debugInfo() const
Output information for debug.
Definition M5UnitComponent.cpp:349
static const char name[]
Device name string.
Definition M5UnitComponent.hpp:56
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:191
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:108
Adapter * adapter() const
Gets the access adapter.
Definition M5UnitComponent.hpp:159
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:232
bool hasSiblings() const
Are there any other devices connected to the same parent unit besides yourself?
Definition M5UnitComponent.hpp:237
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:121
const char * deviceName() const
Gets the device name.
Definition M5UnitComponent.hpp:116
virtual bool assign(m5::hal::bus::Bus *bus)
Assgin m5::hal::bus.
Definition M5UnitComponent.cpp:120
bool updated() const
Periodic measurement data updated?
Definition M5UnitComponent.hpp:196
types::elapsed_time_t updatedMillis() const
Time elapsed since start-up when the measurement data was updated in update()
Definition M5UnitComponent.hpp:204
static const types::attr_t attr
Attributes.
Definition M5UnitComponent.hpp:55
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:173
m5::hal::error::error_t readWithTransaction(uint8_t *data, const size_t len)
Read any data with transaction.
Definition M5UnitComponent.cpp:153
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:151
virtual bool begin()
Begin unit.
Definition M5UnitComponent.hpp:99
int16_t channel() const
Gets the channel if connected to another unit.
Definition M5UnitComponent.hpp:141
types::elapsed_time_t interval() const
Gets the periodic measurement interval.
Definition M5UnitComponent.hpp:212
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:165
bool add(Component &c, const int16_t channel)
Connect the unit to the specified channel.
Definition M5UnitComponent.cpp:57
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:136
types::category_t category() const
Gets the category.
Definition M5UnitComponent.hpp:131
Interface class for periodic measurement (CRTP)
Definition M5UnitComponent.hpp:604
MD oldest() const
Retrieve oldest stored data.
Definition M5UnitComponent.hpp:652
size_t available() const
Gets the number of stored data.
Definition M5UnitComponent.hpp:637
bool startPeriodicMeasurement(Args &&... args)
Start periodic measurement.
Definition M5UnitComponent.hpp:615
void discard()
Discard the oldest data accumulated.
Definition M5UnitComponent.hpp:662
MD latest() const
Retrieve latest stored data.
Definition M5UnitComponent.hpp:657
bool stopPeriodicMeasurement(Args &&... args)
Stop periodic measurement.
Definition M5UnitComponent.hpp:627
bool empty() const
Is empty stored data?
Definition M5UnitComponent.hpp:642
bool full() const
Is stored data full?
Definition M5UnitComponent.hpp:647
void flush()
Discard all data.
Definition M5UnitComponent.hpp:667
Top level namespace of M5stack.
Definition test_helper.hpp:18
Component basic settings for begin.
Definition M5UnitComponent.hpp:40
uint32_t clock
Clock for communication (default as 100000)
Definition M5UnitComponent.hpp:42
uint32_t stored_size
Maximum number of periodic measurement data to be stored.
Definition M5UnitComponent.hpp:44
uint8_t max_children
Maximum number of units that can be connected (default as 0)
Definition M5UnitComponent.hpp:48
bool self_update
Does the user call Unit's update? (default as false)
Definition M5UnitComponent.hpp:46
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