/* * Dual sense: CDT (Signal) + RXD packet heuristic (edges + HDLC 0x7E). * SPDX-License-Identifier: GPL-3.0-or-later */ #include "sense.h" #include "board_pins.h" #include "config.h" #include "hardware/gpio.h" #include "pico/stdlib.h" #include static bool g_signal; static bool g_packet; static bool g_flag; static absolute_time_t g_packet_until; static absolute_time_t g_window_start; static uint16_t g_edges; static bool g_last_rxd; static bool g_hold_valid; static void try_flag_sample(void) { uint16_t sh = 0; for (int i = 0; i < 16; i++) { bool b = gpio_get(PIN_MODEM_RXD); sh = (uint16_t)((sh << 1) | (b ? 1u : 0u)); if ((uint8_t)(sh & 0xFFu) == 0x7Eu) { g_flag = true; return; } sleep_us(833); } } void sense_init(void) { g_signal = false; g_packet = false; g_flag = false; g_hold_valid = false; g_window_start = get_absolute_time(); g_edges = 0; g_last_rxd = gpio_get(PIN_MODEM_RXD); } void sense_poll(void) { const c1224_config_t *cfg = config_get(); bool cdt = gpio_get(PIN_MODEM_CDT); g_signal = cfg->cdt_active_high ? cdt : !cdt; bool rxd = gpio_get(PIN_MODEM_RXD); if (rxd != g_last_rxd) { g_edges++; g_last_rxd = rxd; } uint32_t win_ms = cfg->packet_window_ms ? cfg->packet_window_ms : 50; if (absolute_time_diff_us(g_window_start, get_absolute_time()) >= (int64_t)win_ms * 1000) { if (g_edges >= cfg->packet_edge_min) { g_flag = false; try_flag_sample(); g_packet_until = make_timeout_time_ms( cfg->packet_hold_ms ? cfg->packet_hold_ms : 500); g_hold_valid = true; } g_edges = 0; g_window_start = get_absolute_time(); } if (g_hold_valid) { if (time_reached(g_packet_until)) { g_hold_valid = false; g_packet = false; g_flag = false; } else { g_packet = true; } } else { g_packet = false; } } bool sense_signal_active(void) { return g_signal; } bool sense_packet_active(void) { return g_packet; } bool sense_packet_flag(void) { return g_flag; }