summaryrefslogtreecommitdiff
path: root/firmware/c1224/src/common/sense.c
blob: 6bd33a43515583bbeb8a5fa9e76c88ccaefe60a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
 * 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 <stdint.h>

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;
}
git clone -b <branch> https://cgit.mode42.com/<repo>.git
git clone -b <branch> git://cgit.mode42.com/<repo>.git

info@mode42.com