Branch data Line data Source code
1 : : #include "us_sensor.hpp"
2 : : #include "us_driver.hpp"
3 : : #include "us_gpio_hal.hpp"
4 : : #include "us_processor.hpp"
5 : : #include "us_timer_hal.hpp"
6 : : #include <memory>
7 : :
8 : : #define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
9 : : #include "esp_log.h"
10 : :
11 : : static const char *TAG = "UsSensor";
12 : :
13 : : // Production constructor: creates concrete HALs and driver internally
14 : 1 : UsSensor::UsSensor(gpio_num_t trig_pin, gpio_num_t echo_pin, const UsConfig &cfg)
15 : 1 : : cfg_(cfg)
16 [ - + - + ]: 2 : , driver_(std::make_shared<UsDriver>(std::make_shared<GpioHAL>(), std::make_shared<TimerHAL>(), trig_pin, echo_pin))
17 : 2 : , processor_(std::make_shared<UsProcessor>())
18 : : {
19 : 1 : }
20 : :
21 : : // Test constructor: receives dependencies via injection
22 : 12 : UsSensor::UsSensor(const UsConfig &cfg, std::shared_ptr<IUsDriver> driver, std::shared_ptr<IUsProcessor> processor)
23 : 12 : : cfg_(cfg)
24 [ + - ]: 12 : , driver_(driver)
25 [ + - + - ]: 24 : , processor_(processor)
26 : : {
27 : 12 : }
28 : :
29 : 1 : esp_err_t UsSensor::init()
30 : : {
31 : : // Pass warmup_time_ms so the driver waits for sensor stabilization after GPIO setup
32 : 1 : return driver_->init(cfg_.warmup_time_ms);
33 : : }
34 : :
35 : 1 : esp_err_t UsSensor::deinit()
36 : : {
37 : 1 : return driver_->deinit();
38 : : }
39 : :
40 : 11 : Reading UsSensor::read_distance(uint8_t ping_count)
41 : : {
42 : : // Clamp ping_count to valid range
43 [ + + ]: 11 : if (ping_count == 0 || ping_count > MAX_PINGS) {
44 : 2 : ESP_LOGW(TAG, "ping_count %d out of range [1, %d], clamping", ping_count, MAX_PINGS);
45 [ + + ]: 2 : ping_count = (ping_count == 0) ? 1 : MAX_PINGS;
46 : : }
47 : :
48 : 11 : Reading pings[MAX_PINGS];
49 : :
50 [ + + ]: 51 : for (uint8_t i = 0; i < ping_count; i++) {
51 : 42 : pings[i] = driver_->ping_once(cfg_);
52 : :
53 : : // Hardware failures abort the loop immediately — application must act
54 [ + + ]: 42 : if (pings[i].result == UsResult::ECHO_STUCK || pings[i].result == UsResult::HW_FAULT) {
55 : 2 : ESP_LOGE(TAG, "Hardware failure on ping %d: %d — aborting", i, static_cast<int>(pings[i].result));
56 : 2 : return pings[i];
57 : : }
58 : :
59 : : // Logical failures (TIMEOUT, OUT_OF_RANGE) are collected and passed to processor
60 [ + + ]: 40 : if (!is_success(pings[i].result)) {
61 : 12 : ESP_LOGD(TAG, "Ping %d failed: result=%d", i, static_cast<int>(pings[i].result));
62 : : }
63 : :
64 : : // Note: inter-ping delay (cfg_.ping_interval_ms) is applied inside UsDriver::ping_once()
65 : : }
66 : :
67 : : // Delegate processing (including logical error refinement) to the processor
68 : 9 : return processor_->process(pings, ping_count, cfg_);
69 : : }
|