diff --git a/CMakeLists.txt b/CMakeLists.txt index 62ec2bd..980e8cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,5 +21,6 @@ else() src/led.cpp src/temp.cpp src/watdog.cpp + src/com.cpp ) endif() diff --git a/boards/dr2501a_g070rb.overlay b/boards/dr2501a_g070rb.overlay deleted file mode 100644 index e69de29..0000000 diff --git a/boards/use_ms.overlay b/boards/use_ms.overlay new file mode 100644 index 0000000..4c888d1 --- /dev/null +++ b/boards/use_ms.overlay @@ -0,0 +1,71 @@ +&ch9438_uart0 { + status = "okay"; + current-speed = <9600>; +}; + +&gd_sensor0 { + mode = "wrist"; +}; + +&ch9438_uart1 { + status = "okay"; + current-speed = <9600>; +}; + +&gd_sensor1 { + mode = "wrist"; +}; + +&ch9438_uart2 { + status = "okay"; + current-speed = <9600>; +}; + +&gd_sensor2 { + mode = "wrist"; +}; + +&ch9438_uart3 { + status = "okay"; + current-speed = <9600>; +}; + +&gd_sensor3 { + mode = "wrist"; +}; + +&ch9438_uart4 { + status = "okay"; + current-speed = <9600>; +}; + +&gd_sensor4 { + mode = "wrist"; +}; + +&ch9438_uart5 { + status = "okay"; + current-speed = <9600>; +}; + +&gd_sensor5 { + mode = "wrist"; +}; + +&ch9438_uart6 { + status = "okay"; + current-speed = <9600>; +}; + +&gd_sensor6 { + mode = "wrist"; +}; + +&ch9438_uart7 { + status = "okay"; + current-speed = <9600>; +}; + +&gd_sensor7 { + mode = "wrist"; +}; diff --git a/include/infrared.hpp b/include/infrared.hpp index b1614ef..8d552e1 100644 --- a/include/infrared.hpp +++ b/include/infrared.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -71,6 +72,17 @@ public: return out; } + /* Bitmask of channels that have received at least one sample (diag). */ + static auto GetChannelValidMask() -> uint32_t { + uint32_t mask = 0; + for (size_t id = 0; id < s_dev.size(); ++id) { + if (s_latest_valid[id]) { + mask |= (1u << id); + } + } + return mask; + } + private: /* Per-sensor trigger handler; the channel index is a compile-time * constant. Runs in the UART trigger context (workqueue thread for @@ -121,9 +133,20 @@ private: return ret != 0 ? zpp::error{-ENODEV} : zpp::ok(); } -#define INFRARED_DEV(node) DEVICE_DT_GET(node), +/* Channel order: ch0~7 = CH9438 SPI-UART ports, ch8 = on-chip usart2 inner + * sensor. DT_FOREACH follows .dtsi soc node order (usart2 before spi2), so + * split by parent compatible instead of relying on node order. */ +#define INFRARED_DEV(node) \ + COND_CODE_1(DT_NODE_HAS_COMPAT(DT_PARENT(node), wch_ch9438_uart), \ + (DEVICE_DT_GET(node), ), ()) +#define INFRARED_INNER_DEV(node) \ + COND_CODE_1(DT_NODE_HAS_COMPAT(DT_PARENT(node), st_stm32_usart), \ + (DEVICE_DT_GET(node), ), ()) inline static etl::array s_dev{ - DT_FOREACH_STATUS_OKAY(godtek_temp_uart, INFRARED_DEV)}; + DT_FOREACH_STATUS_OKAY(godtek_temp_uart, INFRARED_DEV) + DT_FOREACH_STATUS_OKAY(godtek_temp_uart, INFRARED_INNER_DEV)}; +#undef INFRARED_DEV +#undef INFRARED_INNER_DEV /* Field-level volatile caches: written by the trigger handlers, read by * GetMaxSensorValue. sensor_value itself cannot be volatile (no volatile * copy/assign), so the two 32-bit fields are cached separately. A torn diff --git a/src/com.cpp b/src/com.cpp new file mode 100644 index 0000000..b46796f --- /dev/null +++ b/src/com.cpp @@ -0,0 +1,6 @@ + +#include +#include +static auto Init() -> int { return static_cast(ther::Com::Init()); } + +inline SYS_INIT(Init, APPLICATION, 50); diff --git a/src/main.cpp b/src/main.cpp index fd9b4cb..4751dfa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,7 @@ -#include +#include #include auto main(void) -> int { - ther::Com::Init(); printk("[main] init on %s\n", CONFIG_BOARD); while (1) { k_sleep(K_SECONDS(1)); diff --git a/src/temp.cpp b/src/temp.cpp index 511e8a3..8d89547 100644 --- a/src/temp.cpp +++ b/src/temp.cpp @@ -4,6 +4,11 @@ #include #include +/* 1 = enable verbose diagnostics (per-second channel dump). */ +#ifndef APP_DEBUG_PRINT +#define APP_DEBUG_PRINT 0 +#endif + using namespace ther; /* 调试打印开关: @@ -42,6 +47,18 @@ static void OnSendTick(struct k_work *work) { if (auto r = Infrared::GetMaxSensorValue(); r.ok()) { Com::SendTemp(r.value().second); } +#if APP_DEBUG_PRINT + static uint32_t s_send_tick; /* diag: send counter, ~1s cadence */ + if (++s_send_tick % 50 == 0) { /* every ~1 s */ + const auto all = Infrared::GetAllSensorValues(); + printk("[%s]diag tick=%u mask=0x%02X val:", MODULE, (unsigned)s_send_tick, + (unsigned)Infrared::GetChannelValidMask()); + for (size_t i = 0; i < all.size(); ++i) { + printk(" %u=%d.%d", (unsigned)i, all[i].val1, all[i].val2); + } + printk("\n"); + } +#endif /* APP_DEBUG_PRINT */ k_work_schedule(&s_send_work, K_MSEC(kPeriodSend.count())); } } // namespace diff --git a/testcase.yaml b/testcase.yaml index aaf757f..159f104 100644 --- a/testcase.yaml +++ b/testcase.yaml @@ -9,3 +9,7 @@ tests: sample.ntc: extra_configs: - CONFIG_SAMPLE_NTC=y + sample.ms: + extra_args: + - DTC_OVERLAY_FILE=boards/use_ms.overlay + extra_configs: