M5UnitUnified 0.6.3 git rev:e38fc73
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
16#if defined(ESP_PLATFORM)
17#include <driver/uart.h> // for uart_port_t
18#include <driver/spi_master.h> // for spi_device_handle_t
19#endif
20#if defined(ESP_PLATFORM) && __has_include(<driver/i2c_master.h>)
21#include <driver/i2c_master.h> // for i2c_master_bus_handle_t
22#elif defined(ESP_PLATFORM)
23#include <driver/i2c.h> // for i2c_port_t / gpio_num_t
24#endif
25#include <cstdint>
26#include <vector>
27#include <algorithm>
28#include <iterator>
29#include <type_traits>
30#include <memory>
31
32#if defined(ARDUINO) || defined(DOXYGEN_PROCESS)
33class TwoWire;
34class HardwareSerial;
35class SPIClass;
36struct SPISettings;
37#endif
38
39namespace m5 {
40class I2C_Class;
41namespace unit {
42
43class UnitUnified;
44class Adapter;
45
50class Component {
51public:
58 uint32_t clock{100000};
60 uint32_t stored_size{1};
62 bool self_update{false};
64 uint8_t max_children{0};
65 };
66
70 static const types::uid_t uid;
71 static const types::attr_t attr;
72 static const char name[];
74
78 explicit Component(const uint8_t addr = 0x00); // I2C address
79
80 Component(const Component&) = delete;
81
82 Component(Component&&) noexcept = default;
84
88 Component& operator=(const Component&) = delete;
89
90 Component& operator=(Component&&) noexcept = default;
92
93 virtual ~Component() = default;
94
97
102 {
103 return _component_cfg;
104 }
109 inline void component_config(const component_config_t& cfg)
110 {
111 _component_cfg = cfg;
112 }
114
117
121 virtual bool begin()
122 {
123 return true;
124 }
129 virtual void update(const bool force = false)
130 {
131 (void)force;
132 }
134
137
141 inline const char* deviceName() const
142 {
143 return unit_device_name();
144 }
150 {
151 return unit_identifier();
152 }
158 {
159 return unit_attribute();
160 }
166 {
167 return unit_category();
168 }
173 inline uint32_t order() const
174 {
175 return _order;
176 }
181 inline int16_t channel() const
182 {
183 return _channel;
184 }
189 inline bool isRegistered() const
190 {
191 return _manager != nullptr;
192 }
197 inline uint8_t address() const
198 {
199 return _addr;
200 }
206 inline Adapter* adapter() const
207 {
208 return _adapter.get();
209 }
216 template <class T>
217 inline auto asAdapter(const Adapter::Type t) ->
218 typename std::remove_cv<typename std::remove_pointer<T>::type>::type*
219 {
220 using U = typename std::remove_cv<typename std::remove_pointer<T>::type>::type;
221 static_assert(std::is_base_of<Adapter, U>::value, "T must be derived from Adapter");
222 return (_adapter->type() == t) ? static_cast<U*>(_adapter.get()) : nullptr;
223 }
230 template <class T>
231 inline auto asAdapter(const Adapter::Type t) const -> const
232 typename std::remove_cv<typename std::remove_pointer<T>::type>::type*
233 {
234 using U = typename std::remove_cv<typename std::remove_pointer<T>::type>::type;
235 static_assert(std::is_base_of<Adapter, U>::value, "T must be derived from Adapter");
236 return (_adapter->type() == t) ? static_cast<const U*>(_adapter.get()) : nullptr;
237 }
239
242
246 bool canAccessI2C() const;
251 bool canAccessGPIO() const;
256 bool canAccessUART() const;
261 bool canAccessSPI() const;
263
266
270 inline bool inPeriodic() const
271 {
272 return in_periodic();
273 }
278 inline bool updated() const
279 {
280 return _updated;
281 }
287 {
288 return _latest;
289 }
295 {
296 return _interval;
297 }
299
302#if defined(ARDUINO) || defined(DOXYGEN_PROCESS)
308 virtual bool assign(TwoWire& wire);
309#endif
310#if defined(DOXYGEN_PROCESS) || (defined(ESP_PLATFORM) && __has_include(<driver/i2c_master.h>))
316 virtual bool assign(i2c_master_bus_handle_t bus);
326 virtual bool assign(i2c_master_bus_handle_t bus, const i2c_port_t port, const gpio_num_t sda, const gpio_num_t scl);
327#endif
328#if defined(DOXYGEN_PROCESS) || (defined(ESP_PLATFORM) && !__has_include(<driver/i2c_master.h>))
336 virtual bool assign(const i2c_port_t port, const gpio_num_t sda, const gpio_num_t scl);
337#endif
343 virtual bool assign(m5::I2C_Class& i2c);
345
346#if defined(ESP_PLATFORM) || defined(DOXYGEN_PROCESS)
349
356 virtual bool assign(const int8_t rx_pin, const int8_t tx_pin);
358#endif
359
362#if defined(ARDUINO) || defined(DOXYGEN_PROCESS)
368 virtual bool assign(HardwareSerial& serial);
369#endif
370#if defined(ESP_PLATFORM) || defined(DOXYGEN_PROCESS)
377 virtual bool assign(const uart_port_t uart_num);
378#endif
380
383#if defined(ARDUINO) || defined(DOXYGEN_PROCESS)
390 virtual bool assign(SPIClass& spi, const SPISettings& settings);
391#endif
392#if defined(ESP_PLATFORM) || defined(DOXYGEN_PROCESS)
400 virtual bool assign(spi_device_handle_t handle, const gpio_num_t cs = GPIO_NUM_NC);
401#endif
403
406
411 virtual bool assign(m5::hal::bus::Bus* bus);
413
417
421 inline bool hasParent() const
422 {
423 return _parent != nullptr;
424 }
429 inline bool hasSiblings() const
430 {
431 return (_prev != nullptr) || (_next != nullptr);
432 }
437 inline bool hasChildren() const
438 {
439 return _child;
440 }
445 size_t childrenSize() const;
451 bool existsChild(const uint8_t ch) const;
457 {
458 return _parent;
459 }
465 Component* child(const uint8_t channel) const;
472 bool add(Component& c, const int16_t channel);
478 bool selectChannel(const uint8_t ch = 8);
480
482 template <typename T>
483 class iterator {
484 public:
485 using iterator_category = std::forward_iterator_tag;
486 using difference_type = std::ptrdiff_t;
487 using value_type = T;
488 using pointer = T*;
489 using reference = T&;
490
491 explicit iterator(Component* c = nullptr) : _ptr(c)
492 {
493 }
494
495 reference operator*() const
496 {
497 return *_ptr;
498 }
499 pointer operator->() const
500 {
501 return _ptr;
502 }
503 iterator& operator++()
504 {
505 _ptr = _ptr ? _ptr->_next : nullptr;
506 return *this;
507 }
508 iterator operator++(int)
509 {
510 auto tmp = *this;
511 ++(*this);
512 return tmp;
513 }
514 friend bool operator==(const iterator& a, const iterator& b)
515 {
516 return a._ptr == b._ptr;
517 }
518 friend bool operator!=(const iterator& a, const iterator& b)
519 {
520 return a._ptr != b._ptr;
521 }
522
523 private:
524 Component* _ptr;
525 };
526
527 using child_iterator = iterator<Component>;
528 using const_child_iterator = iterator<const Component>;
529 inline child_iterator childBegin() noexcept
530 {
531 return child_iterator(_child);
532 }
533 inline child_iterator childEnd() noexcept
534 {
535 return child_iterator();
536 }
537 inline const_child_iterator childBegin() const noexcept
538 {
539 return const_child_iterator(_child);
540 }
541 inline const_child_iterator childEnd() const noexcept
542 {
543 return const_child_iterator();
544 }
546
553 bool generalCall(const uint8_t* data, const size_t len);
554
559 virtual std::string debugInfo() const;
560
562
563 // I2C R/W
565 m5::hal::error::error_t readWithTransaction(uint8_t* data, const size_t len);
566
567 template <typename Reg,
568 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
569 std::nullptr_t>::type = nullptr>
570 bool readRegister(const Reg reg, uint8_t* rbuf, const size_t len, const uint32_t delayMillis,
571 const bool stop = true);
572 template <typename Reg,
573 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
574 std::nullptr_t>::type = nullptr>
575 bool readRegister8(const Reg reg, uint8_t& result, const uint32_t delayMillis, const bool stop = true);
576
577 template <typename Reg,
578 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
579 std::nullptr_t>::type = nullptr>
580 inline bool readRegister16BE(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true)
581 {
582 return read_register16E(reg, result, delayMillis, stop, true);
583 }
584
585 template <typename Reg,
586 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
587 std::nullptr_t>::type = nullptr>
588 inline bool readRegister16LE(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true)
589 {
590 return read_register16E(reg, result, delayMillis, stop, false);
591 }
592
593 template <typename Reg,
594 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
595 std::nullptr_t>::type = nullptr>
596 inline bool readRegister32BE(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop = true)
597 {
598 return read_register32E(reg, result, delayMillis, stop, true);
599 }
600
601 template <typename Reg,
602 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
603 std::nullptr_t>::type = nullptr>
604 inline bool readRegister32LE(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop = true)
605 {
606 return read_register32E(reg, result, delayMillis, stop, false);
607 }
608
609 m5::hal::error::error_t writeWithTransaction(const uint8_t* data, const size_t len, const uint32_t exparam = 1);
610
611 template <typename Reg,
612 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
613 std::nullptr_t>::type = nullptr>
614 m5::hal::error::error_t writeWithTransaction(const Reg reg, const uint8_t* data, const size_t len,
615 const bool stop = true);
616
617 template <typename Reg,
618 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
619 std::nullptr_t>::type = nullptr>
620 bool writeRegister(const Reg reg, const uint8_t* buf = nullptr, const size_t len = 0U, const bool stop = true);
621
622 template <typename Reg,
623 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
624 std::nullptr_t>::type = nullptr>
625 bool writeRegister8(const Reg reg, const uint8_t value, const bool stop = true);
626
627 template <typename Reg,
628 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
629 std::nullptr_t>::type = nullptr>
630 inline bool writeRegister16BE(const Reg reg, const uint16_t value, const bool stop = true)
631 {
632 return write_register16E(reg, value, stop, true);
633 }
634
635 template <typename Reg,
636 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
637 std::nullptr_t>::type = nullptr>
638 inline bool writeRegister16LE(const Reg reg, const uint16_t value, const bool stop = true)
639 {
640 return write_register16E(reg, value, stop, false);
641 }
642
643 template <typename Reg,
644 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
645 std::nullptr_t>::type = nullptr>
646 inline bool writeRegister32BE(const Reg reg, const uint32_t value, const bool stop = true)
647 {
648 return write_register32E(reg, value, stop, true);
649 }
650
651 template <typename Reg,
652 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
653 std::nullptr_t>::type = nullptr>
654 inline bool writeRegister32LE(const Reg reg, const uint32_t value, const bool stop = true)
655 {
656 return write_register32E(reg, value, stop, false);
657 }
658
659 // GPIO (ESP platform only)
660#if defined(ESP_PLATFORM)
661 bool pinModeRX(const gpio::Mode m);
662 bool writeDigitalRX(const bool high);
663 bool readDigitalRX(bool& high);
664 bool writeAnalogRX(const uint16_t v);
665 bool readAnalogRX(uint16_t& v);
666 bool readAnalogMilliVoltsRX(uint32_t& mv);
667 bool pulseInRX(uint32_t& duration, const int state, const uint32_t timeout_us = 1000000);
668
669 bool pinModeTX(const gpio::Mode m);
670 bool writeDigitalTX(const bool high);
671 bool readDigitalTX(bool& high);
672 bool writeAnalogTX(const uint16_t v);
673 bool readAnalogTX(uint16_t& v);
674 bool readAnalogMilliVoltsTX(uint32_t& mv);
675 bool pulseInTX(uint32_t& duration, const int state, const uint32_t timeout_us = 1000000);
676#endif // ESP_PLATFORM
678
679#if defined(DOXYGEN_PROCESS)
680 // There is a problem with the Doxygen output of templates containing std::enable_if,
681 // so we need a section for Doxygen output
685 m5::hal::error::error_t readWithTransaction(uint8_t* data, const size_t len);
687 template <typename Reg>
688 bool readRegister(const Reg reg, uint8_t* rbuf, const size_t len, const uint32_t delayMillis,
689 const bool stop = true);
691 template <typename Reg>
692 bool readRegister8(const Reg reg, uint8_t& result, const uint32_t delayMillis, const bool stop = true);
694 template <typename Reg>
695 bool readRegister16BE(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true);
697 template <typename Reg>
698 bool readRegister16LE(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true);
700 template <typename Reg>
701 bool readRegister32BE(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop = true);
703 template <typename Reg>
704 bool readRegister32LE(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop = true);
705
707 m5::hal::error::error_t writeWithTransaction(const uint8_t* data, const size_t len, const bool stop = true);
709 template <typename Reg>
710 m5::hal::error::error_t writeWithTransaction(const Reg reg, const uint8_t* data, const size_t len,
711 const bool stop = true);
713 template <typename Reg>
714 bool writeRegister(const Reg reg, const uint8_t* buf = nullptr, const size_t len = 0U, const bool stop = true);
716 template <typename Reg>
717 bool writeRegister8(const Reg reg, const uint8_t value, const bool stop = true);
719 template <typename Reg>
720 bool writeRegister16BE(const Reg reg, const uint16_t value, const bool stop = true);
722 template <typename Reg>
723 bool writeRegister16LE(const Reg reg, const uint16_t value, const bool stop = true);
725 template <typename Reg>
726 bool writeRegister32BE(const Reg reg, const uint32_t value, const bool stop = true);
728 template <typename Reg>
729 bool writeRegister32LE(const Reg reg, const uint32_t value, const bool stop = true);
731#endif
732
733protected:
734 // Proper implementation in derived classes is required
735 virtual const char* unit_device_name() const = 0;
736 virtual types::uid_t unit_identifier() const = 0;
737 virtual types::attr_t unit_attribute() const = 0;
738 inline virtual types::category_t unit_category() const
739 {
740 return types::category_t::None;
741 }
742 inline virtual bool in_periodic() const
743 {
744 return _periodic;
745 }
746
747 inline virtual std::shared_ptr<Adapter> ensure_adapter(const uint8_t /*ch*/)
748 {
749 return _adapter; // By default, offer my adapter for sharing
750 }
751
752 // Select valid channel if exists(PaHub etc...)
753 inline virtual m5::hal::error::error_t select_channel(const uint8_t)
754 {
755 return m5::hal::error::error_t::OK;
756 }
757
758 inline size_t stored_size() const
759 {
760 return _component_cfg.stored_size;
761 }
762
763 bool add_child(Component* c);
764
765 // I2C
766 bool changeAddress(const uint8_t addr); // Functions for dynamically addressable devices
767 template <typename Reg,
768 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
769 std::nullptr_t>::type = nullptr>
770 bool read_register16E(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop,
771 const bool endian);
772 template <typename Reg,
773 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
774 std::nullptr_t>::type = nullptr>
775 bool write_register16E(const Reg reg, const uint16_t value, const bool stop, const bool endian);
776 template <typename Reg,
777 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
778 std::nullptr_t>::type = nullptr>
779 bool read_register32E(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop,
780 const bool endian);
781 template <typename Reg,
782 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
783 std::nullptr_t>::type = nullptr>
784 bool write_register32E(const Reg reg, const uint32_t value, const bool stop, const bool endian);
785
786protected:
787 // For periodic measurement
788 types::elapsed_time_t _latest{}, _interval{};
789 bool _periodic{}; // During periodic measurement?
790 bool _updated{};
791
792private:
793 UnitUnified* _manager{};
794 std::shared_ptr<m5::unit::Adapter> _adapter{};
795
796 uint32_t _order{};
797 component_config_t _component_cfg{};
798 int16_t _channel{-1}; // valid [0...]
799 uint8_t _addr{};
800 bool _begun{};
801
802 // for chain
803 Component* _parent{};
804 Component* _next{};
805 Component* _prev{};
806 Component* _child{};
807
808 friend class UnitUnified;
809};
810
828template <class Derived, typename MD>
830public:
833
839 template <typename... Args>
840 inline bool startPeriodicMeasurement(Args&&... args)
841 {
842 // Prepare for future common initiation preprocessing needs
843 return static_cast<Derived*>(this)->start_periodic_measurement(std::forward<Args>(args)...);
844 }
851 template <typename... Args>
852 inline bool stopPeriodicMeasurement(Args&&... args)
853 {
854 // Prepare for future common stopping preprocessing needs
855 return static_cast<Derived*>(this)->stop_periodic_measurement(std::forward<Args>(args)...);
856 }
858
862 inline size_t available() const
863 {
864 return available_periodic_measurement_data();
865 }
867 inline bool empty() const
868 {
869 return empty_periodic_measurement_data();
870 }
872 inline bool full() const
873 {
874 return full_periodic_measurement_data();
875 }
877 inline MD oldest() const
878 {
879 return static_cast<const Derived*>(this)->oldest_periodic_data();
880 }
882 inline MD latest() const
883 {
884 return static_cast<const Derived*>(this)->latest_periodic_data();
885 }
887 inline void discard()
888 {
889 discard_periodic_measurement_data();
890 }
892 inline void flush()
893 {
894 flush_periodic_measurement_data();
895 }
897
898protected:
902 virtual size_t available_periodic_measurement_data() const = 0;
903 virtual bool empty_periodic_measurement_data() const = 0;
904 virtual bool full_periodic_measurement_data() const = 0;
905 virtual void discard_periodic_measurement_data() = 0;
906 virtual void flush_periodic_measurement_data() = 0;
908};
909
910} // namespace unit
911} // namespace m5
912
913// Helper for creating derived classes from Component
915#define M5_UNIT_COMPONENT_HPP_BUILDER(cls, reg) \
916public: \
917 constexpr static uint8_t DEFAULT_ADDRESS{(reg)}; \
918 static const types::uid_t uid; \
919 static const types::attr_t attr; \
920 static const char name[]; \
921 \
922 cls(const cls&) = delete; \
923 \
924 cls& operator=(const cls&) = delete; \
925 \
926 cls(cls&&) noexcept = default; \
927 \
928 cls& operator=(cls&&) noexcept = default; \
929 \
930protected: \
931 inline virtual const char* unit_device_name() const override \
932 { \
933 return name; \
934 } \
935 inline virtual types::uid_t unit_identifier() const override \
936 { \
937 return uid; \
938 } \
939 inline virtual types::attr_t unit_attribute() const override \
940 { \
941 return attr; \
942 }
943
944// Helper for creating derived class from PeriodicMeasurementAdapter
945#define M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(cls, md) \
946protected: \
947 friend class PeriodicMeasurementAdapter<cls, md>; \
948 \
949 inline md oldest_periodic_data() const \
950 { \
951 return !_data->empty() ? _data->front().value() : md{}; \
952 } \
953 inline md latest_periodic_data() const \
954 { \
955 return !_data->empty() ? _data->back().value() : md{}; \
956 } \
957 inline virtual size_t available_periodic_measurement_data() const override \
958 { \
959 return _data->size(); \
960 } \
961 inline virtual bool empty_periodic_measurement_data() const override \
962 { \
963 return _data->empty(); \
964 } \
965 inline virtual bool full_periodic_measurement_data() const override \
966 { \
967 return _data->full(); \
968 } \
969 inline virtual void discard_periodic_measurement_data() override \
970 { \
971 _data->pop_front(); \
972 } \
973 inline virtual void flush_periodic_measurement_data() override \
974 { \
975 _data->clear(); \
976 }
977
979#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:129
types::attr_t attribute() const
Gets the attributes.
Definition M5UnitComponent.hpp:157
bool existsChild(const uint8_t ch) const
Is there another unit connected to the specified channel?
Definition M5UnitComponent.cpp:44
bool canAccessI2C() const
Can the unit access via I2C?
Definition M5UnitComponent.cpp:52
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:109
bool readRegister8(const Reg reg, uint8_t &result, const uint32_t delayMillis, const bool stop=true)
Read byte with transaction from register.
virtual bool assign(const int8_t rx_pin, const int8_t tx_pin)
Assign GPIO pins as the communication bus.
static const types::uid_t uid
Unique identifier.
Definition M5UnitComponent.hpp:70
bool selectChannel(const uint8_t ch=8)
Select valid channel if exists.
Definition M5UnitComponent.cpp:277
Component * parent()
Gets the parent unit.
Definition M5UnitComponent.hpp:456
bool writeRegister8(const Reg reg, const uint8_t value, const bool stop=true)
Write byte with transaction to register.
virtual std::string debugInfo() const
Output information for debug.
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:57
bool hasChildren() const
Are there other devices connected to me?
Definition M5UnitComponent.hpp:437
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:189
static const char name[]
Device name string.
Definition M5UnitComponent.hpp:72
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:270
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:206
bool canAccessUART() const
Can the unit access via UART?
Definition M5UnitComponent.cpp:62
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:421
bool hasSiblings() const
Are there any other devices connected to the same parent unit besides yourself?
Definition M5UnitComponent.hpp:429
size_t childrenSize() const
Number of units connected to me.
Definition M5UnitComponent.cpp:33
virtual bool assign(i2c_master_bus_handle_t bus, const i2c_port_t port, const gpio_num_t sda, const gpio_num_t scl)
Assign I2C master bus with its port and pins (ESP-IDF native driver)
types::uid_t identifier() const
Gets the identifier.
Definition M5UnitComponent.hpp:149
const char * deviceName() const
Gets the device name.
Definition M5UnitComponent.hpp:141
bool updated() const
Periodic measurement data updated?
Definition M5UnitComponent.hpp:278
types::elapsed_time_t updatedMillis() const
Time elapsed since start-up when the measurement data was updated in update()
Definition M5UnitComponent.hpp:286
static const types::attr_t attr
Attributes.
Definition M5UnitComponent.hpp:71
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.
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.
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:129
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:231
m5::hal::error::error_t readWithTransaction(uint8_t *data, const size_t len)
Read any data with transaction.
Definition M5UnitComponent.cpp:286
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.
uint8_t address() const
Address used to I2C access the device.
Definition M5UnitComponent.hpp:197
virtual bool begin()
Begin unit.
Definition M5UnitComponent.hpp:121
int16_t channel() const
Gets the channel if connected to another unit.
Definition M5UnitComponent.hpp:181
types::elapsed_time_t interval() const
Gets the periodic measurement interval.
Definition M5UnitComponent.hpp:294
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:217
bool add(Component &c, const int16_t channel)
Connect the unit to the specified channel.
Definition M5UnitComponent.cpp:72
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:101
bool canAccessSPI() const
Can the unit access via SPI?
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:173
types::category_t category() const
Gets the category.
Definition M5UnitComponent.hpp:165
Interface class for periodic measurement (CRTP)
Definition M5UnitComponent.hpp:829
MD oldest() const
Retrieve oldest stored data.
Definition M5UnitComponent.hpp:877
size_t available() const
Gets the number of stored data.
Definition M5UnitComponent.hpp:862
bool startPeriodicMeasurement(Args &&... args)
Start periodic measurement.
Definition M5UnitComponent.hpp:840
void discard()
Discard the oldest data accumulated.
Definition M5UnitComponent.hpp:887
MD latest() const
Retrieve latest stored data.
Definition M5UnitComponent.hpp:882
bool stopPeriodicMeasurement(Args &&... args)
Stop periodic measurement.
Definition M5UnitComponent.hpp:852
bool empty() const
Is empty stored data?
Definition M5UnitComponent.hpp:867
bool full() const
Is stored data full?
Definition M5UnitComponent.hpp:872
void flush()
Discard all data.
Definition M5UnitComponent.hpp:892
Version of M5UnitUnified, to test at compile time (as ESP_IDF_VERSION)
Top level namespace of M5Stack.
Definition test_helper.hpp:20
Unit-related namespace.
Component basic settings for begin.
Definition M5UnitComponent.hpp:56
uint32_t clock
Clock for communication (default as 100000)
Definition M5UnitComponent.hpp:58
uint32_t stored_size
Maximum number of periodic measurement data to be stored.
Definition M5UnitComponent.hpp:60
uint8_t max_children
Maximum number of units that can be connected (default as 0)
Definition M5UnitComponent.hpp:64
bool self_update
Does the user call Unit's update? (default as false)
Definition M5UnitComponent.hpp:62
Type and enumerator definitions.
unsigned long elapsed_time_t
Elapsed time unit (ms), same type as m5::utility::elapsed_time_t.
Definition types.hpp:44
uint32_t attr_t
Component attribute bits.
Definition types.hpp:43
uint32_t uid_t
Component unique identifier.
Definition types.hpp:42
category_t
Unit category (used for static class determination)
Definition types.hpp:37