zhangyisong a9e8885ec8 Refactor thermistor components and update board dependencies
- Remove heating and NTC functionality from communication module
- Convert Infrared from template to runtime array-based implementation
- Refactor Led to support multiple LEDs with compile-time name
  validation
- Simplify main to remove direct hardware initialization
- Update west manifest for dr2501a board and add ch9438 module
2026-08-02 21:59:50 +08:00

97 lines
3.0 KiB
C++

#ifndef __THER_LED_HPP__
#define __THER_LED_HPP__
#include <etl/algorithm.h>
#include <etl/array.h>
#include <zephyr/drivers/led.h>
#include <zpp/ct_string.hpp>
#include <zpp/work_queue.hpp>
namespace ther {
/* Compile-time check: every LED name must be distinct so that
* Led::On/Off/Flash<kName> name lookup stays unambiguous. */
template <typename T, std::size_t N>
consteval auto AreUniqueNames(const etl::array<T, N> &names) -> bool {
for (std::size_t i = 0; i < N; ++i) {
for (std::size_t j = i + 1; j < N; ++j) {
if (names[i] == names[j]) {
return false;
}
}
}
return true;
}
#define LED_SPEC(node) led_dt_spec LED_DT_SPEC_GET(node)
#define LED_DEV_CHILD_SPEC(node) DT_FOREACH_CHILD_SEP(node, LED_SPEC, (, )),
#define LED_NODE_NAME(node) DT_FOREACH_CHILD_SEP(node, DEVICE_DT_NAME, (, ))
class Led {
private:
template <led_dt_spec> struct Periodic {
static auto Flash(led_dt_spec *spec) -> void {
bool flag = false;
if (flag) {
led_on_dt(spec);
} else {
led_off_dt(spec);
}
flag = !flag;
}
static inline zpp::periodic_work<led_dt_spec *> work{Flash};
};
public:
template <zpp::ct_string kName> static auto On() -> zpp::error {
static_assert(IsDeviceName<kName>());
const auto id = etl::find(s_led_node_name.begin(), s_led_node_name.end(),
std::string_view(kName)) -
s_led_node_name.begin();
return led_on_dt(&s_led_dev[id]);
}
template <zpp::ct_string kName> static auto Off() -> zpp::error {
static_assert(IsDeviceName<kName>());
const auto id = etl::find(s_led_node_name.begin(), s_led_node_name.end(),
std::string_view(kName)) -
s_led_node_name.begin();
return led_off_dt(&s_led_dev[id]);
}
template <zpp::ct_string kName, typename TRep, typename TPeriod>
static auto Flash(std::chrono::duration<TRep, TPeriod> period) {
static_assert(IsDeviceName<kName>());
const auto id = etl::find(s_led_node_name.begin(), s_led_node_name.end(),
std::string_view(kName)) -
s_led_node_name.begin();
Periodic<s_led_dev[id]>::work.submit(period);
}
private:
template <zpp::ct_string kName> static consteval auto IsDeviceName() {
for (size_t i = 0; i < s_led_node_name.size(); ++i) {
if (s_led_node_name[i] == std::string_view(kName)) {
return true;
}
}
return false;
}
static auto Flash(led_dt_spec *spec) -> void {
static bool flag = false;
if (flag) {
led_off_dt(spec);
} else {
led_on_dt(spec);
}
flag = !flag;
}
inline static constexpr etl::array s_led_dev{
DT_FOREACH_STATUS_OKAY(gpio_leds, LED_DEV_CHILD_SPEC)};
inline static constexpr auto s_led_node_name =
etl::make_array<std::string_view>(
DT_FOREACH_STATUS_OKAY(gpio_leds, LED_NODE_NAME));
static_assert(AreUniqueNames(s_led_node_name),
"LED node names must be unique");
};
} // namespace ther
#endif