M5UnitUnified 0.5.5 git rev:bf711f3
Loading...
Searching...
No Matches
M5UnitComponent.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UNIT_COMPONENT_HPP
11#define M5_UNIT_COMPONENT_HPP
12
15#if defined(ESP_PLATFORM)
16#include <driver/uart.h> // for uart_port_t
17#include <driver/spi_master.h> // for spi_device_handle_t
18#endif
19#if defined(ESP_PLATFORM) && __has_include(<driver/i2c_master.h>)
20#include <driver/i2c_master.h> // for i2c_master_bus_handle_t
21#elif defined(ESP_PLATFORM)
22#include <driver/i2c.h> // for i2c_port_t / gpio_num_t
23#endif
24#include <cstdint>
25#include <vector>
26#include <algorithm>
27#include <iterator>
28#include <type_traits>
29#include <memory>
30
31#if defined(ARDUINO) || defined(DOXYGEN_PROCESS)
32class TwoWire;
33class HardwareSerial;
34class SPIClass;
35struct SPISettings;
36#endif
37
38namespace m5 {
39class I2C_Class;
40namespace unit {
41
42class UnitUnified;
43class Adapter;
44
49class Component {
50public:
57 uint32_t clock{100000};
59 uint32_t stored_size{1};
61 bool self_update{false};
63 uint8_t max_children{0};
64 };
65
69 static const types::uid_t uid;
70 static const types::attr_t attr;
71 static const char name[];
73
77 explicit Component(const uint8_t addr = 0x00); // I2C address
78
79 Component(const Component&) = delete;
80
81 Component(Component&&) noexcept = default;
83
87 Component& operator=(const Component&) = delete;
88
89 Component& operator=(Component&&) noexcept = default;
91
92 virtual ~Component() = default;
93
96
101 {
102 return _component_cfg;
103 }
108 inline void component_config(const component_config_t& cfg)
109 {
110 _component_cfg = cfg;
111 }
113
116
120 virtual bool begin()
121 {
122 return true;
123 }
128 virtual void update(const bool force = false)
129 {
130 (void)force;
131 }
133
136
140 inline const char* deviceName() const
141 {
142 return unit_device_name();
143 }
149 {
150 return unit_identifier();
151 }
157 {
158 return unit_attribute();
159 }
165 {
166 return unit_category();
167 }
172 inline uint32_t order() const
173 {
174 return _order;
175 }
180 inline int16_t channel() const
181 {
182 return _channel;
183 }
188 inline bool isRegistered() const
189 {
190 return _manager != nullptr;
191 }
196 inline uint8_t address() const
197 {
198 return _addr;
199 }
205 inline Adapter* adapter() const
206 {
207 return _adapter.get();
208 }
215 template <class T>
216 inline auto asAdapter(const Adapter::Type t) ->
217 typename std::remove_cv<typename std::remove_pointer<T>::type>::type*
218 {
219 using U = typename std::remove_cv<typename std::remove_pointer<T>::type>::type;
220 static_assert(std::is_base_of<Adapter, U>::value, "T must be derived from Adapter");
221 return (_adapter->type() == t) ? static_cast<U*>(_adapter.get()) : nullptr;
222 }
229 template <class T>
230 inline auto asAdapter(const Adapter::Type t) const -> const
231 typename std::remove_cv<typename std::remove_pointer<T>::type>::type*
232 {
233 using U = typename std::remove_cv<typename std::remove_pointer<T>::type>::type;
234 static_assert(std::is_base_of<Adapter, U>::value, "T must be derived from Adapter");
235 return (_adapter->type() == t) ? static_cast<const U*>(_adapter.get()) : nullptr;
236 }
238
241
245 bool canAccessI2C() const;
250 bool canAccessGPIO() const;
255 bool canAccessUART() const;
260 bool canAccessSPI() const;
262
265
269 inline bool inPeriodic() const
270 {
271 return in_periodic();
272 }
277 inline bool updated() const
278 {
279 return _updated;
280 }
286 {
287 return _latest;
288 }
294 {
295 return _interval;
296 }
298
301#if defined(ARDUINO) || defined(DOXYGEN_PROCESS)
307 virtual bool assign(TwoWire& wire);
308#endif
309#if defined(DOXYGEN_PROCESS) || (defined(ESP_PLATFORM) && __has_include(<driver/i2c_master.h>))
315 virtual bool assign(i2c_master_bus_handle_t bus);
316#endif
317#if defined(DOXYGEN_PROCESS) || (defined(ESP_PLATFORM) && !__has_include(<driver/i2c_master.h>))
325 virtual bool assign(const i2c_port_t port, const gpio_num_t sda, const gpio_num_t scl);
326#endif
332 virtual bool assign(m5::I2C_Class& i2c);
334
337
343 virtual bool assign(const int8_t rx_pin, const int8_t tx_pin);
345
348#if defined(ARDUINO) || defined(DOXYGEN_PROCESS)
354 virtual bool assign(HardwareSerial& serial);
355#endif
356#if defined(ESP_PLATFORM) || defined(DOXYGEN_PROCESS)
363 virtual bool assign(const uart_port_t uart_num);
364#endif
366
369#if defined(ARDUINO) || defined(DOXYGEN_PROCESS)
376 virtual bool assign(SPIClass& spi, const SPISettings& settings);
377#endif
378#if defined(ESP_PLATFORM) || defined(DOXYGEN_PROCESS)
386 virtual bool assign(spi_device_handle_t handle, const gpio_num_t cs = GPIO_NUM_NC);
387#endif
389
392
397 virtual bool assign(m5::hal::bus::Bus* bus);
399
403
407 inline bool hasParent() const
408 {
409 return _parent != nullptr;
410 }
415 inline bool hasSiblings() const
416 {
417 return (_prev != nullptr) || (_next != nullptr);
418 }
423 inline bool hasChildren() const
424 {
425 return _child;
426 }
431 size_t childrenSize() const;
437 bool existsChild(const uint8_t ch) const;
443 {
444 return _parent;
445 }
451 Component* child(const uint8_t channel) const;
458 bool add(Component& c, const int16_t channel);
464 bool selectChannel(const uint8_t ch = 8);
466
468 template <typename T>
469 class iterator {
470 public:
471 using iterator_category = std::forward_iterator_tag;
472 using difference_type = std::ptrdiff_t;
473 using value_type = T;
474 using pointer = T*;
475 using reference = T&;
476
477 explicit iterator(Component* c = nullptr) : _ptr(c)
478 {
479 }
480
481 reference operator*() const
482 {
483 return *_ptr;
484 }
485 pointer operator->() const
486 {
487 return _ptr;
488 }
489 iterator& operator++()
490 {
491 _ptr = _ptr ? _ptr->_next : nullptr;
492 return *this;
493 }
494 iterator operator++(int)
495 {
496 auto tmp = *this;
497 ++(*this);
498 return tmp;
499 }
500 friend bool operator==(const iterator& a, const iterator& b)
501 {
502 return a._ptr == b._ptr;
503 }
504 friend bool operator!=(const iterator& a, const iterator& b)
505 {
506 return a._ptr != b._ptr;
507 }
508
509 private:
510 Component* _ptr;
511 };
512
513 using child_iterator = iterator<Component>;
514 using const_child_iterator = iterator<const Component>;
515 inline child_iterator childBegin() noexcept
516 {
517 return child_iterator(_child);
518 }
519 inline child_iterator childEnd() noexcept
520 {
521 return child_iterator();
522 }
523 inline const_child_iterator childBegin() const noexcept
524 {
525 return const_child_iterator(_child);
526 }
527 inline const_child_iterator childEnd() const noexcept
528 {
529 return const_child_iterator();
530 }
532
539 bool generalCall(const uint8_t* data, const size_t len);
540
545 virtual std::string debugInfo() const;
546
548
549 // I2C R/W
551 m5::hal::error::error_t readWithTransaction(uint8_t* data, const size_t len);
552
553 template <typename Reg,
554 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
555 std::nullptr_t>::type = nullptr>
556 bool readRegister(const Reg reg, uint8_t* rbuf, const size_t len, const uint32_t delayMillis,
557 const bool stop = true);
558 template <typename Reg,
559 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
560 std::nullptr_t>::type = nullptr>
561 bool readRegister8(const Reg reg, uint8_t& result, const uint32_t delayMillis, const bool stop = true);
562
563 template <typename Reg,
564 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
565 std::nullptr_t>::type = nullptr>
566 inline bool readRegister16BE(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true)
567 {
568 return read_register16E(reg, result, delayMillis, stop, true);
569 }
570
571 template <typename Reg,
572 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
573 std::nullptr_t>::type = nullptr>
574 inline bool readRegister16LE(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true)
575 {
576 return read_register16E(reg, result, delayMillis, stop, false);
577 }
578
579 template <typename Reg,
580 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
581 std::nullptr_t>::type = nullptr>
582 inline bool readRegister32BE(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop = true)
583 {
584 return read_register32E(reg, result, delayMillis, stop, true);
585 }
586
587 template <typename Reg,
588 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
589 std::nullptr_t>::type = nullptr>
590 inline bool readRegister32LE(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop = true)
591 {
592 return read_register32E(reg, result, delayMillis, stop, false);
593 }
594
595 m5::hal::error::error_t writeWithTransaction(const uint8_t* data, const size_t len, const uint32_t exparam = 1);
596
597 template <typename Reg,
598 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
599 std::nullptr_t>::type = nullptr>
600 m5::hal::error::error_t writeWithTransaction(const Reg reg, const uint8_t* data, const size_t len,
601 const bool stop = true);
602
603 template <typename Reg,
604 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
605 std::nullptr_t>::type = nullptr>
606 bool writeRegister(const Reg reg, const uint8_t* buf = nullptr, const size_t len = 0U, const bool stop = true);
607
608 template <typename Reg,
609 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
610 std::nullptr_t>::type = nullptr>
611 bool writeRegister8(const Reg reg, const uint8_t value, const bool stop = true);
612
613 template <typename Reg,
614 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
615 std::nullptr_t>::type = nullptr>
616 inline bool writeRegister16BE(const Reg reg, const uint16_t value, const bool stop = true)
617 {
618 return write_register16E(reg, value, stop, true);
619 }
620
621 template <typename Reg,
622 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
623 std::nullptr_t>::type = nullptr>
624 inline bool writeRegister16LE(const Reg reg, const uint16_t value, const bool stop = true)
625 {
626 return write_register16E(reg, value, stop, false);
627 }
628
629 template <typename Reg,
630 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
631 std::nullptr_t>::type = nullptr>
632 inline bool writeRegister32BE(const Reg reg, const uint32_t value, const bool stop = true)
633 {
634 return write_register32E(reg, value, stop, true);
635 }
636
637 template <typename Reg,
638 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
639 std::nullptr_t>::type = nullptr>
640 inline bool writeRegister32LE(const Reg reg, const uint32_t value, const bool stop = true)
641 {
642 return write_register32E(reg, value, stop, false);
643 }
644
645 // GPIO
646 bool pinModeRX(const gpio::Mode m);
647 bool writeDigitalRX(const bool high);
648 bool readDigitalRX(bool& high);
649 bool writeAnalogRX(const uint16_t v);
650 bool readAnalogRX(uint16_t& v);
651 bool readAnalogMilliVoltsRX(uint32_t& mv);
652 bool pulseInRX(uint32_t& duration, const int state, const uint32_t timeout_us = 1000000);
653
654 bool pinModeTX(const gpio::Mode m);
655 bool writeDigitalTX(const bool high);
656 bool readDigitalTX(bool& high);
657 bool writeAnalogTX(const uint16_t v);
658 bool readAnalogTX(uint16_t& v);
659 bool readAnalogMilliVoltsTX(uint32_t& mv);
660 bool pulseInTX(uint32_t& duration, const int state, const uint32_t timeout_us = 1000000);
662
663#if defined(DOXYGEN_PROCESS)
664 // There is a problem with the Doxygen output of templates containing std::enable_if,
665 // so we need a section for Doxygen output
669 m5::hal::error::error_t readWithTransaction(uint8_t* data, const size_t len);
671 template <typename Reg>
672 bool readRegister(const Reg reg, uint8_t* rbuf, const size_t len, const uint32_t delayMillis,
673 const bool stop = true);
675 template <typename Reg>
676 bool readRegister8(const Reg reg, uint8_t& result, const uint32_t delayMillis, const bool stop = true);
678 template <typename Reg>
679 bool readRegister16BE(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true);
681 template <typename Reg>
682 bool readRegister16LE(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true);
684 template <typename Reg>
685 bool readRegister32BE(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop = true);
687 template <typename Reg>
688 bool readRegister32LE(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop = true);
689
691 m5::hal::error::error_t writeWithTransaction(const uint8_t* data, const size_t len, const bool stop = true);
693 template <typename Reg>
694 m5::hal::error::error_t writeWithTransaction(const Reg reg, const uint8_t* data, const size_t len,
695 const bool stop = true);
697 template <typename Reg>
698 bool writeRegister(const Reg reg, const uint8_t* buf = nullptr, const size_t len = 0U, const bool stop = true);
700 template <typename Reg>
701 bool writeRegister8(const Reg reg, const uint8_t value, const bool stop = true);
703 template <typename Reg>
704 bool writeRegister16BE(const Reg reg, const uint16_t value, const bool stop = true);
706 template <typename Reg>
707 bool writeRegister16LE(const Reg reg, const uint16_t value, const bool stop = true);
709 template <typename Reg>
710 bool writeRegister32BE(const Reg reg, const uint32_t value, const bool stop = true);
712 template <typename Reg>
713 bool writeRegister32LE(const Reg reg, const uint32_t value, const bool stop = true);
715#endif
716
717protected:
718 // Proper implementation in derived classes is required
719 virtual const char* unit_device_name() const = 0;
720 virtual types::uid_t unit_identifier() const = 0;
721 virtual types::attr_t unit_attribute() const = 0;
722 inline virtual types::category_t unit_category() const
723 {
724 return types::category_t::None;
725 }
726 inline virtual bool in_periodic() const
727 {
728 return _periodic;
729 }
730
731 inline virtual std::shared_ptr<Adapter> ensure_adapter(const uint8_t /*ch*/)
732 {
733 return _adapter; // By default, offer my adapter for sharing
734 }
735
736 // Select valid channel if exists(PaHub etc...)
737 inline virtual m5::hal::error::error_t select_channel(const uint8_t)
738 {
739 return m5::hal::error::error_t::OK;
740 }
741
742 inline size_t stored_size() const
743 {
744 return _component_cfg.stored_size;
745 }
746
747 bool add_child(Component* c);
748
749 // I2C
750 bool changeAddress(const uint8_t addr); // Functions for dynamically addressable devices
751 template <typename Reg,
752 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
753 std::nullptr_t>::type = nullptr>
754 bool read_register16E(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop,
755 const bool endian);
756 template <typename Reg,
757 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
758 std::nullptr_t>::type = nullptr>
759 bool write_register16E(const Reg reg, const uint16_t value, const bool stop, const bool endian);
760 template <typename Reg,
761 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
762 std::nullptr_t>::type = nullptr>
763 bool read_register32E(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop,
764 const bool endian);
765 template <typename Reg,
766 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
767 std::nullptr_t>::type = nullptr>
768 bool write_register32E(const Reg reg, const uint32_t value, const bool stop, const bool endian);
769
770protected:
771 // For periodic measurement
772 types::elapsed_time_t _latest{}, _interval{};
773 bool _periodic{}; // During periodic measurement?
774 bool _updated{};
775
776private:
777 UnitUnified* _manager{};
778 std::shared_ptr<m5::unit::Adapter> _adapter{};
779
780 uint32_t _order{};
781 component_config_t _component_cfg{};
782 int16_t _channel{-1}; // valid [0...]
783 uint8_t _addr{};
784 bool _begun{};
785
786 // for chain
787 Component* _parent{};
788 Component* _next{};
789 Component* _prev{};
790 Component* _child{};
791
792 friend class UnitUnified;
793};
794
812template <class Derived, typename MD>
814public:
817
823 template <typename... Args>
824 inline bool startPeriodicMeasurement(Args&&... args)
825 {
826 // Prepare for future common initiation preprocessing needs
827 return static_cast<Derived*>(this)->start_periodic_measurement(std::forward<Args>(args)...);
828 }
835 template <typename... Args>
836 inline bool stopPeriodicMeasurement(Args&&... args)
837 {
838 // Prepare for future common stopping preprocessing needs
839 return static_cast<Derived*>(this)->stop_periodic_measurement(std::forward<Args>(args)...);
840 }
842
846 inline size_t available() const
847 {
848 return available_periodic_measurement_data();
849 }
851 inline bool empty() const
852 {
853 return empty_periodic_measurement_data();
854 }
856 inline bool full() const
857 {
858 return full_periodic_measurement_data();
859 }
861 inline MD oldest() const
862 {
863 return static_cast<const Derived*>(this)->oldest_periodic_data();
864 }
866 inline MD latest() const
867 {
868 return static_cast<const Derived*>(this)->latest_periodic_data();
869 }
871 inline void discard()
872 {
873 discard_periodic_measurement_data();
874 }
876 inline void flush()
877 {
878 flush_periodic_measurement_data();
879 }
881
882protected:
886 virtual size_t available_periodic_measurement_data() const = 0;
887 virtual bool empty_periodic_measurement_data() const = 0;
888 virtual bool full_periodic_measurement_data() const = 0;
889 virtual void discard_periodic_measurement_data() = 0;
890 virtual void flush_periodic_measurement_data() = 0;
892};
893
894} // namespace unit
895} // namespace m5
896
897// Helper for creating derived classes from Component
899#define M5_UNIT_COMPONENT_HPP_BUILDER(cls, reg) \
900public: \
901 constexpr static uint8_t DEFAULT_ADDRESS{(reg)}; \
902 static const types::uid_t uid; \
903 static const types::attr_t attr; \
904 static const char name[]; \
905 \
906 cls(const cls&) = delete; \
907 \
908 cls& operator=(const cls&) = delete; \
909 \
910 cls(cls&&) noexcept = default; \
911 \
912 cls& operator=(cls&&) noexcept = default; \
913 \
914protected: \
915 inline virtual const char* unit_device_name() const override \
916 { \
917 return name; \
918 } \
919 inline virtual types::uid_t unit_identifier() const override \
920 { \
921 return uid; \
922 } \
923 inline virtual types::attr_t unit_attribute() const override \
924 { \
925 return attr; \
926 }
927
928// Helper for creating derived class from PeriodicMeasurementAdapter
929#define M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(cls, md) \
930protected: \
931 friend class PeriodicMeasurementAdapter<cls, md>; \
932 \
933 inline md oldest_periodic_data() const \
934 { \
935 return !_data->empty() ? _data->front().value() : md{}; \
936 } \
937 inline md latest_periodic_data() const \
938 { \
939 return !_data->empty() ? _data->back().value() : md{}; \
940 } \
941 inline virtual size_t available_periodic_measurement_data() const override \
942 { \
943 return _data->size(); \
944 } \
945 inline virtual bool empty_periodic_measurement_data() const override \
946 { \
947 return _data->empty(); \
948 } \
949 inline virtual bool full_periodic_measurement_data() const override \
950 { \
951 return _data->full(); \
952 } \
953 inline virtual void discard_periodic_measurement_data() override \
954 { \
955 _data->pop_front(); \
956 } \
957 inline virtual void flush_periodic_measurement_data() override \
958 { \
959 _data->clear(); \
960 }
961
963#endif
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.
Type
Adapter type.
Definition adapter_base.hpp:28
Base class of unit component.
virtual void update(const bool force=false)
Update unit.
Definition M5UnitComponent.hpp:128
types::attr_t attribute() const
Gets the attributes.
Definition M5UnitComponent.hpp:156
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 another 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 canAccessI2C() const
Can the unit access via I2C?
Definition M5UnitComponent.cpp:47
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:108
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:69
bool selectChannel(const uint8_t ch=8)
Select valid channel if exists.
Definition M5UnitComponent.cpp:261
Component * parent()
Gets the parent unit.
Definition M5UnitComponent.hpp:442
bool writeRegister32BE(const Reg reg, const uint32_t value, const bool stop=true)
Write dword in big-endian order with transaction to register.
bool canAccessGPIO() const
Can the unit access via GPIO?
Definition M5UnitComponent.cpp:52
bool hasChildren() const
Are there other devices connected to me?
Definition M5UnitComponent.hpp:423
virtual bool assign(const i2c_port_t port, const gpio_num_t sda, const gpio_num_t scl)
Assign I2C (ESP-IDF legacy driver, pre-installed port)
bool isRegistered() const
Is the unit registered with the manager?
Definition M5UnitComponent.hpp:188
virtual std::string debugInfo() const
Output information for debug.
Definition M5UnitComponent.cpp:476
static const char name[]
Device name string.
Definition M5UnitComponent.hpp:71
bool writeRegister32LE(const Reg reg, const uint32_t value, const bool stop=true)
Write dword in little-endian order with transaction to register.
virtual bool assign(const uart_port_t uart_num)
Assign UART (ESP-IDF native driver, pre-installed port)
bool inPeriodic() const
In periodic measurement?
Definition M5UnitComponent.hpp:269
bool writeRegister16BE(const Reg reg, const uint16_t value, const bool stop=true)
Write word in big-endian order with transaction to register.
virtual bool assign(SPIClass &spi, const SPISettings &settings)
Assign SPIClass as the communication bus.
Adapter * adapter() const
Gets the access adapter.
Definition M5UnitComponent.hpp:205
bool canAccessUART() const
Can the unit access via UART?
Definition M5UnitComponent.cpp:57
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:407
bool hasSiblings() const
Are there any other devices connected to the same parent unit besides yourself?
Definition M5UnitComponent.hpp:415
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:148
const char * deviceName() const
Gets the device name.
Definition M5UnitComponent.hpp:140
bool updated() const
Periodic measurement data updated?
Definition M5UnitComponent.hpp:277
types::elapsed_time_t updatedMillis() const
Time elapsed since start-up when the measurement data was updated in update()
Definition M5UnitComponent.hpp:285
static const types::attr_t attr
Attributes.
Definition M5UnitComponent.hpp:70
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.
Component * child(const uint8_t channel) const
Gets the device connected to the specified channel.
Definition M5UnitComponent.cpp:124
auto asAdapter(const Adapter::Type t) const -> const typename std::remove_cv< typename std::remove_pointer< T >::type >::type *
Gets the access adapter cast to the specified type (const overload)
Definition M5UnitComponent.hpp:230
m5::hal::error::error_t readWithTransaction(uint8_t *data, const size_t len)
Read any data with transaction.
Definition M5UnitComponent.cpp:270
virtual bool assign(TwoWire &wire)
Assign TwoWire as the communication bus.
bool writeRegister16LE(const Reg reg, const uint16_t value, const bool stop=true)
Write word in little-endian order with transaction to 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:196
virtual bool begin()
Begin unit.
Definition M5UnitComponent.hpp:120
int16_t channel() const
Gets the channel if connected to another unit.
Definition M5UnitComponent.hpp:180
types::elapsed_time_t interval() const
Gets the periodic measurement interval.
Definition M5UnitComponent.hpp:293
bool generalCall(const uint8_t *data, const size_t len)
General call for I2C.
virtual bool assign(i2c_master_bus_handle_t bus)
Assign I2C master bus (ESP-IDF native driver)
auto asAdapter(const Adapter::Type t) -> typename std::remove_cv< typename std::remove_pointer< T >::type >::type *
Gets the access adapter cast to the specified type.
Definition M5UnitComponent.hpp:216
bool add(Component &c, const int16_t channel)
Connect the unit to the specified channel.
Definition M5UnitComponent.cpp:67
virtual bool assign(spi_device_handle_t handle, const gpio_num_t cs=GPIO_NUM_NC)
Assign SPI device handle (ESP-IDF native driver, borrowed)
virtual bool assign(HardwareSerial &serial)
Assign HardwareSerial as the communication bus.
component_config_t component_config() const
Gets the common configurations in each unit.
Definition M5UnitComponent.hpp:100
bool canAccessSPI() const
Can the unit access via SPI?
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:172
types::category_t category() const
Gets the category.
Definition M5UnitComponent.hpp:164
Interface class for periodic measurement (CRTP)
Definition M5UnitComponent.hpp:813
MD oldest() const
Retrieve oldest stored data.
Definition M5UnitComponent.hpp:861
size_t available() const
Gets the number of stored data.
Definition M5UnitComponent.hpp:846
bool startPeriodicMeasurement(Args &&... args)
Start periodic measurement.
Definition M5UnitComponent.hpp:824
void discard()
Discard the oldest data accumulated.
Definition M5UnitComponent.hpp:871
MD latest() const
Retrieve latest stored data.
Definition M5UnitComponent.hpp:866
bool stopPeriodicMeasurement(Args &&... args)
Stop periodic measurement.
Definition M5UnitComponent.hpp:836
bool empty() const
Is empty stored data?
Definition M5UnitComponent.hpp:851
bool full() const
Is stored data full?
Definition M5UnitComponent.hpp:856
void flush()
Discard all data.
Definition M5UnitComponent.hpp:876
Top level namespace of M5Stack.
Definition test_helper.hpp:20
Unit-related namespace.
Component basic settings for begin.
Definition M5UnitComponent.hpp:55
uint32_t clock
Clock for communication (default as 100000)
Definition M5UnitComponent.hpp:57
uint32_t stored_size
Maximum number of periodic measurement data to be stored.
Definition M5UnitComponent.hpp:59
uint8_t max_children
Maximum number of units that can be connected (default as 0)
Definition M5UnitComponent.hpp:63
bool self_update
Does the user call Unit's update? (default as false)
Definition M5UnitComponent.hpp:61
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