82 uint16_t sender_preamble,
83 uint16_t min_symbols = 8,
86 if (min_symbols == 0 || 2 *
static_cast<uint32_t
>(min_symbols) >= sender_preamble) {
93 const int64_t bw = airtime_detail::bandwidth_hz(mod.bw);
94 const int64_t sym_x_1e6 = (int64_t{1} << std::to_underlying(mod.sf)) * 1'000'000;
95 const auto symbols_floor = [&](int64_t n) {
return n * sym_x_1e6 / bw; };
96 const auto symbols_ceil = [&](int64_t n) {
return (n * sym_x_1e6 + bw - 1) / bw; };
98 const int64_t sleep_us = symbols_floor(sender_preamble - 2 * min_symbols);
99 if (sleep_us < min_sleep.count()) {
103 constexpr int64_t margin_us = 1'000;
104 const int64_t worst_case_us = (symbols_ceil(sender_preamble + 1) - (sleep_us - margin_us) + 1) / 2;
105 const int64_t detect_us = symbols_ceil(min_symbols + 1);
106 const int64_t rx_us = worst_case_us > detect_us ? worst_case_us : detect_us;
108 return rx_duty_cycle{std::chrono::microseconds{rx_us}, std::chrono::microseconds{sleep_us}};
constexpr std::optional< rx_duty_cycle > rx_duty_cycle_for(const lora_modulation &mod, uint16_t sender_preamble, uint16_t min_symbols=8, std::chrono::microseconds min_sleep=default_min_rx_sleep) noexcept
Computes duty-cycle receive windows that cannot miss a packet.