M5UnitUnified 0.5.8 git rev:47d29eb
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
335#if defined(ESP_PLATFORM) || defined(DOXYGEN_PROCESS)
338
345 virtual bool assign(const int8_t rx_pin, const int8_t tx_pin);
347#endif
348
351#if defined(ARDUINO) || defined(DOXYGEN_PROCESS)
357 virtual bool assign(HardwareSerial& serial);
358#endif
359#if defined(ESP_PLATFORM) || defined(DOXYGEN_PROCESS)
366 virtual bool assign(const uart_port_t uart_num);
367#endif
369
372#if defined(ARDUINO) || defined(DOXYGEN_PROCESS)
379 virtual bool assign(SPIClass& spi, const SPISettings& settings);
380#endif
381#if defined(ESP_PLATFORM) || defined(DOXYGEN_PROCESS)
389 virtual bool assign(spi_device_handle_t handle, const gpio_num_t cs = GPIO_NUM_NC);
390#endif
392
395
400 virtual bool assign(m5::hal::bus::Bus* bus);
402
406
410 inline bool hasParent() const
411 {
412 return _parent != nullptr;
413 }
418 inline bool hasSiblings() const
419 {
420 return (_prev != nullptr) || (_next != nullptr);
421 }
426 inline bool hasChildren() const
427 {
428 return _child;
429 }
434 size_t childrenSize() const;
440 bool existsChild(const uint8_t ch) const;
446 {
447 return _parent;
448 }
454 Component* child(const uint8_t channel) const;
461 bool add(Component& c, const int16_t channel);
467 bool selectChannel(const uint8_t ch = 8);
469
471 template <typename T>
472 class iterator {
473 public:
474 using iterator_category = std::forward_iterator_tag;
475 using difference_type = std::ptrdiff_t;
476 using value_type = T;
477 using pointer = T*;
478 using reference = T&;
479
480 explicit iterator(Component* c = nullptr) : _ptr(c)
481 {
482 }
483
484 reference operator*() const
485 {
486 return *_ptr;
487 }
488 pointer operator->() const
489 {
490 return _ptr;
491 }
492 iterator& operator++()
493 {
494 _ptr = _ptr ? _ptr->_next : nullptr;
495 return *this;
496 }
497 iterator operator++(int)
498 {
499 auto tmp = *this;
500 ++(*this);
501 return tmp;
502 }
503 friend bool operator==(const iterator& a, const iterator& b)
504 {
505 return a._ptr == b._ptr;
506 }
507 friend bool operator!=(const iterator& a, const iterator& b)
508 {
509 return a._ptr != b._ptr;
510 }
511
512 private:
513 Component* _ptr;
514 };
515
516 using child_iterator = iterator<Component>;
517 using const_child_iterator = iterator<const Component>;
518 inline child_iterator childBegin() noexcept
519 {
520 return child_iterator(_child);
521 }
522 inline child_iterator childEnd() noexcept
523 {
524 return child_iterator();
525 }
526 inline const_child_iterator childBegin() const noexcept
527 {
528 return const_child_iterator(_child);
529 }
530 inline const_child_iterator childEnd() const noexcept
531 {
532 return const_child_iterator();
533 }
535
542 bool generalCall(const uint8_t* data, const size_t len);
543
548 virtual std::string debugInfo() const;
549
551
552 // I2C R/W
554 m5::hal::error::error_t readWithTransaction(uint8_t* data, const size_t len);
555
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 readRegister(const Reg reg, uint8_t* rbuf, const size_t len, const uint32_t delayMillis,
560 const bool stop = true);
561 template <typename Reg,
562 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
563 std::nullptr_t>::type = nullptr>
564 bool readRegister8(const Reg reg, uint8_t& result, const uint32_t delayMillis, const bool stop = true);
565
566 template <typename Reg,
567 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
568 std::nullptr_t>::type = nullptr>
569 inline bool readRegister16BE(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true)
570 {
571 return read_register16E(reg, result, delayMillis, stop, true);
572 }
573
574 template <typename Reg,
575 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
576 std::nullptr_t>::type = nullptr>
577 inline bool readRegister16LE(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true)
578 {
579 return read_register16E(reg, result, delayMillis, stop, false);
580 }
581
582 template <typename Reg,
583 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
584 std::nullptr_t>::type = nullptr>
585 inline bool readRegister32BE(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop = true)
586 {
587 return read_register32E(reg, result, delayMillis, stop, true);
588 }
589
590 template <typename Reg,
591 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
592 std::nullptr_t>::type = nullptr>
593 inline bool readRegister32LE(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop = true)
594 {
595 return read_register32E(reg, result, delayMillis, stop, false);
596 }
597
598 m5::hal::error::error_t writeWithTransaction(const uint8_t* data, const size_t len, const uint32_t exparam = 1);
599
600 template <typename Reg,
601 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
602 std::nullptr_t>::type = nullptr>
603 m5::hal::error::error_t writeWithTransaction(const Reg reg, const uint8_t* data, const size_t len,
604 const bool stop = true);
605
606 template <typename Reg,
607 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
608 std::nullptr_t>::type = nullptr>
609 bool writeRegister(const Reg reg, const uint8_t* buf = nullptr, const size_t len = 0U, const bool stop = true);
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 bool writeRegister8(const Reg reg, const uint8_t value, const bool stop = true);
615
616 template <typename Reg,
617 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
618 std::nullptr_t>::type = nullptr>
619 inline bool writeRegister16BE(const Reg reg, const uint16_t value, const bool stop = true)
620 {
621 return write_register16E(reg, value, stop, true);
622 }
623
624 template <typename Reg,
625 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
626 std::nullptr_t>::type = nullptr>
627 inline bool writeRegister16LE(const Reg reg, const uint16_t value, const bool stop = true)
628 {
629 return write_register16E(reg, value, stop, false);
630 }
631
632 template <typename Reg,
633 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
634 std::nullptr_t>::type = nullptr>
635 inline bool writeRegister32BE(const Reg reg, const uint32_t value, const bool stop = true)
636 {
637 return write_register32E(reg, value, stop, true);
638 }
639
640 template <typename Reg,
641 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
642 std::nullptr_t>::type = nullptr>
643 inline bool writeRegister32LE(const Reg reg, const uint32_t value, const bool stop = true)
644 {
645 return write_register32E(reg, value, stop, false);
646 }
647
648 // GPIO (ESP platform only)
649#if defined(ESP_PLATFORM)
650 bool pinModeRX(const gpio::Mode m);
651 bool writeDigitalRX(const bool high);
652 bool readDigitalRX(bool& high);
653 bool writeAnalogRX(const uint16_t v);
654 bool readAnalogRX(uint16_t& v);
655 bool readAnalogMilliVoltsRX(uint32_t& mv);
656 bool pulseInRX(uint32_t& duration, const int state, const uint32_t timeout_us = 1000000);
657
658 bool pinModeTX(const gpio::Mode m);
659 bool writeDigitalTX(const bool high);
660 bool readDigitalTX(bool& high);
661 bool writeAnalogTX(const uint16_t v);
662 bool readAnalogTX(uint16_t& v);
663 bool readAnalogMilliVoltsTX(uint32_t& mv);
664 bool pulseInTX(uint32_t& duration, const int state, const uint32_t timeout_us = 1000000);
665#endif // ESP_PLATFORM
667
668#if defined(DOXYGEN_PROCESS)
669 // There is a problem with the Doxygen output of templates containing std::enable_if,
670 // so we need a section for Doxygen output
674 m5::hal::error::error_t readWithTransaction(uint8_t* data, const size_t len);
676 template <typename Reg>
677 bool readRegister(const Reg reg, uint8_t* rbuf, const size_t len, const uint32_t delayMillis,
678 const bool stop = true);
680 template <typename Reg>
681 bool readRegister8(const Reg reg, uint8_t& result, const uint32_t delayMillis, const bool stop = true);
683 template <typename Reg>
684 bool readRegister16BE(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true);
686 template <typename Reg>
687 bool readRegister16LE(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true);
689 template <typename Reg>
690 bool readRegister32BE(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop = true);
692 template <typename Reg>
693 bool readRegister32LE(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop = true);
694
696 m5::hal::error::error_t writeWithTransaction(const uint8_t* data, const size_t len, const bool stop = true);
698 template <typename Reg>
699 m5::hal::error::error_t writeWithTransaction(const Reg reg, const uint8_t* data, const size_t len,
700 const bool stop = true);
702 template <typename Reg>
703 bool writeRegister(const Reg reg, const uint8_t* buf = nullptr, const size_t len = 0U, const bool stop = true);
705 template <typename Reg>
706 bool writeRegister8(const Reg reg, const uint8_t value, const bool stop = true);
708 template <typename Reg>
709 bool writeRegister16BE(const Reg reg, const uint16_t value, const bool stop = true);
711 template <typename Reg>
712 bool writeRegister16LE(const Reg reg, const uint16_t value, const bool stop = true);
714 template <typename Reg>
715 bool writeRegister32BE(const Reg reg, const uint32_t value, const bool stop = true);
717 template <typename Reg>
718 bool writeRegister32LE(const Reg reg, const uint32_t value, const bool stop = true);
720#endif
721
722protected:
723 // Proper implementation in derived classes is required
724 virtual const char* unit_device_name() const = 0;
725 virtual types::uid_t unit_identifier() const = 0;
726 virtual types::attr_t unit_attribute() const = 0;
727 inline virtual types::category_t unit_category() const
728 {
729 return types::category_t::None;
730 }
731 inline virtual bool in_periodic() const
732 {
733 return _periodic;
734 }
735
736 inline virtual std::shared_ptr<Adapter> ensure_adapter(const uint8_t /*ch*/)
737 {
738 return _adapter; // By default, offer my adapter for sharing
739 }
740
741 // Select valid channel if exists(PaHub etc...)
742 inline virtual m5::hal::error::error_t select_channel(const uint8_t)
743 {
744 return m5::hal::error::error_t::OK;
745 }
746
747 inline size_t stored_size() const
748 {
749 return _component_cfg.stored_size;
750 }
751
752 bool add_child(Component* c);
753
754 // I2C
755 bool changeAddress(const uint8_t addr); // Functions for dynamically addressable devices
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 read_register16E(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop,
760 const bool endian);
761 template <typename Reg,
762 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
763 std::nullptr_t>::type = nullptr>
764 bool write_register16E(const Reg reg, const uint16_t value, const bool stop, 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 read_register32E(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop,
769 const bool endian);
770 template <typename Reg,
771 typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
772 std::nullptr_t>::type = nullptr>
773 bool write_register32E(const Reg reg, const uint32_t value, const bool stop, const bool endian);
774
775protected:
776 // For periodic measurement
777 types::elapsed_time_t _latest{}, _interval{};
778 bool _periodic{}; // During periodic measurement?
779 bool _updated{};
780
781private:
782 UnitUnified* _manager{};
783 std::shared_ptr<m5::unit::Adapter> _adapter{};
784
785 uint32_t _order{};
786 component_config_t _component_cfg{};
787 int16_t _channel{-1}; // valid [0...]
788 uint8_t _addr{};
789 bool _begun{};
790
791 // for chain
792 Component* _parent{};
793 Component* _next{};
794 Component* _prev{};
795 Component* _child{};
796
797 friend class UnitUnified;
798};
799
817template <class Derived, typename MD>
819public:
822
828 template <typename... Args>
829 inline bool startPeriodicMeasurement(Args&&... args)
830 {
831 // Prepare for future common initiation preprocessing needs
832 return static_cast<Derived*>(this)->start_periodic_measurement(std::forward<Args>(args)...);
833 }
840 template <typename... Args>
841 inline bool stopPeriodicMeasurement(Args&&... args)
842 {
843 // Prepare for future common stopping preprocessing needs
844 return static_cast<Derived*>(this)->stop_periodic_measurement(std::forward<Args>(args)...);
845 }
847
851 inline size_t available() const
852 {
853 return available_periodic_measurement_data();
854 }
856 inline bool empty() const
857 {
858 return empty_periodic_measurement_data();
859 }
861 inline bool full() const
862 {
863 return full_periodic_measurement_data();
864 }
866 inline MD oldest() const
867 {
868 return static_cast<const Derived*>(this)->oldest_periodic_data();
869 }
871 inline MD latest() const
872 {
873 return static_cast<const Derived*>(this)->latest_periodic_data();
874 }
876 inline void discard()
877 {
878 discard_periodic_measurement_data();
879 }
881 inline void flush()
882 {
883 flush_periodic_measurement_data();
884 }
886
887protected:
891 virtual size_t available_periodic_measurement_data() const = 0;
892 virtual bool empty_periodic_measurement_data() const = 0;
893 virtual bool full_periodic_measurement_data() const = 0;
894 virtual void discard_periodic_measurement_data() = 0;
895 virtual void flush_periodic_measurement_data() = 0;
897};
898
899} // namespace unit
900} // namespace m5
901
902// Helper for creating derived classes from Component
904#define M5_UNIT_COMPONENT_HPP_BUILDER(cls, reg) \
905public: \
906 constexpr static uint8_t DEFAULT_ADDRESS{(reg)}; \
907 static const types::uid_t uid; \
908 static const types::attr_t attr; \
909 static const char name[]; \
910 \
911 cls(const cls&) = delete; \
912 \
913 cls& operator=(const cls&) = delete; \
914 \
915 cls(cls&&) noexcept = default; \
916 \
917 cls& operator=(cls&&) noexcept = default; \
918 \
919protected: \
920 inline virtual const char* unit_device_name() const override \
921 { \
922 return name; \
923 } \
924 inline virtual types::uid_t unit_identifier() const override \
925 { \
926 return uid; \
927 } \
928 inline virtual types::attr_t unit_attribute() const override \
929 { \
930 return attr; \
931 }
932
933// Helper for creating derived class from PeriodicMeasurementAdapter
934#define M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(cls, md) \
935protected: \
936 friend class PeriodicMeasurementAdapter<cls, md>; \
937 \
938 inline md oldest_periodic_data() const \
939 { \
940 return !_data->empty() ? _data->front().value() : md{}; \
941 } \
942 inline md latest_periodic_data() const \
943 { \
944 return !_data->empty() ? _data->back().value() : md{}; \
945 } \
946 inline virtual size_t available_periodic_measurement_data() const override \
947 { \
948 return _data->size(); \
949 } \
950 inline virtual bool empty_periodic_measurement_data() const override \
951 { \
952 return _data->empty(); \
953 } \
954 inline virtual bool full_periodic_measurement_data() const override \
955 { \
956 return _data->full(); \
957 } \
958 inline virtual void discard_periodic_measurement_data() override \
959 { \
960 _data->pop_front(); \
961 } \
962 inline virtual void flush_periodic_measurement_data() override \
963 { \
964 _data->clear(); \
965 }
966
968#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 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:108
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:69
bool selectChannel(const uint8_t ch=8)
Select valid channel if exists.
Definition M5UnitComponent.cpp:268
Component * parent()
Gets the parent unit.
Definition M5UnitComponent.hpp:445
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:426
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
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: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:410
bool hasSiblings() const
Are there any other devices connected to the same parent unit besides yourself?
Definition M5UnitComponent.hpp:418
size_t childrenSize() const
Number of units connected to me.
Definition M5UnitComponent.cpp:33
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 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:230
m5::hal::error::error_t readWithTransaction(uint8_t *data, const size_t len)
Read any data with transaction.
Definition M5UnitComponent.cpp:277
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: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: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:100
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:172
types::category_t category() const
Gets the category.
Definition M5UnitComponent.hpp:164
Interface class for periodic measurement (CRTP)
Definition M5UnitComponent.hpp:818
MD oldest() const
Retrieve oldest stored data.
Definition M5UnitComponent.hpp:866
size_t available() const
Gets the number of stored data.
Definition M5UnitComponent.hpp:851
bool startPeriodicMeasurement(Args &&... args)
Start periodic measurement.
Definition M5UnitComponent.hpp:829
void discard()
Discard the oldest data accumulated.
Definition M5UnitComponent.hpp:876
MD latest() const
Retrieve latest stored data.
Definition M5UnitComponent.hpp:871
bool stopPeriodicMeasurement(Args &&... args)
Stop periodic measurement.
Definition M5UnitComponent.hpp:841
bool empty() const
Is empty stored data?
Definition M5UnitComponent.hpp:856
bool full() const
Is stored data full?
Definition M5UnitComponent.hpp:861
void flush()
Discard all data.
Definition M5UnitComponent.hpp:881
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), 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