forked from EmbeddedTeam/app_photomagnetic
Add UART sensor support with MS overlay and diagnostics
Group UART sensors into channel slots and add an MS board overlay with per-port speed and sensor mode configuration. Also add optional per-second channel diagnostic output controlled by APP_DEBUG_PRINT.
This commit is contained in:
parent
0e5d15c814
commit
214af410e4
@ -21,5 +21,6 @@ else()
|
||||
src/led.cpp
|
||||
src/temp.cpp
|
||||
src/watdog.cpp
|
||||
src/com.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
71
boards/use_ms.overlay
Normal file
71
boards/use_ms.overlay
Normal file
@ -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";
|
||||
};
|
||||
@ -6,6 +6,7 @@
|
||||
#include <etl/tuple.h>
|
||||
#include <utility>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/sensor.h>
|
||||
#include <zpp/result.hpp>
|
||||
#include <zpp/value.hpp>
|
||||
@ -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
|
||||
|
||||
6
src/com.cpp
Normal file
6
src/com.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
#include <com.hpp>
|
||||
#include <zephyr/init.h>
|
||||
static auto Init() -> int { return static_cast<int>(ther::Com::Init()); }
|
||||
|
||||
inline SYS_INIT(Init, APPLICATION, 50);
|
||||
@ -1,8 +1,7 @@
|
||||
|
||||
#include <com.hpp>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/kernel.h>
|
||||
auto main(void) -> int {
|
||||
ther::Com::Init();
|
||||
printk("[main] init on %s\n", CONFIG_BOARD);
|
||||
while (1) {
|
||||
k_sleep(K_SECONDS(1));
|
||||
|
||||
17
src/temp.cpp
17
src/temp.cpp
@ -4,6 +4,11 @@
|
||||
#include <zephyr/init.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
/* 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
|
||||
|
||||
@ -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:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user