summaryrefslogtreecommitdiff
path: root/rivulet.cpp
blob: 5b18bb0af7c0e762c426394fc8dd8b5afe128fb9 (plain) (blame)
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <hardware/gpio.h>
#include <pico/printf.h>
#include <pico/stdio_usb.h>
#include <pico/stdlib.h>

constexpr const unsigned int PERIOD_MS = 3000;

enum {
    PIN_CLOCK,

    PIN_DATA,

    PIN_CS0,
    PIN_CS1,
    PIN_CS2,
    PIN_CS3,
    PIN_CS4,
    PIN_CS5,
    PIN_CS6,
    PIN_CS7,

    PIN_LED = 25,
};

constexpr unsigned int MASK(unsigned int pin) { return 1 << pin; }

enum {
    MASK_CLOCK = MASK(PIN_CLOCK),

    MASK_DATA = MASK(PIN_DATA),

    MASK_CS0 = MASK(PIN_CS0),
    MASK_CS1 = MASK(PIN_CS1),
    MASK_CS2 = MASK(PIN_CS2),
    MASK_CS3 = MASK(PIN_CS3),
    MASK_CS4 = MASK(PIN_CS4),
    MASK_CS5 = MASK(PIN_CS5),
    MASK_CS6 = MASK(PIN_CS6),
    MASK_CS7 = MASK(PIN_CS7),

    MASK_LED = MASK(PIN_LED),

    MASK_CSALL = MASK_CS0 | MASK_CS1 | MASK_CS2 | MASK_CS3 | MASK_CS4 | MASK_CS5 | MASK_CS6 | MASK_CS7,
    MASK_IN = MASK_DATA,
    MASK_OUT = MASK_CLOCK | MASK_CSALL | MASK_LED,
    MASK_ALL = MASK_IN | MASK_OUT,
};

unsigned int read_bit() {
    gpio_set_mask(MASK_CLOCK);
    sleep_us(1);
    gpio_clr_mask(MASK_CLOCK);
    auto bit = gpio_get(PIN_DATA);
    sleep_us(1);
    return bit;
}

unsigned int read_sensor(unsigned int i) {
    unsigned int cs;
    switch (i) {
        case 0: cs = PIN_CS0; break;
        case 1: cs = PIN_CS1; break;
        case 2: cs = PIN_CS2; break;
        case 3: cs = PIN_CS3; break;
        case 4: cs = PIN_CS4; break;
        case 5: cs = PIN_CS5; break;
        case 6: cs = PIN_CS6; break;
        case 7: cs = PIN_CS7; break;
        default: return 0;
    }

    gpio_clr_mask(MASK(cs));
    sleep_us(1);

    // 3 leading zero bits
    for (unsigned int i = 0; i < 3; ++i)
        read_bit();

    // 12 data bits; big endian
    unsigned int result = 0;
    for (unsigned int i = 0; i < 12; ++i)
        result = (result << 1) | read_bit();

    gpio_set_mask(MASK(cs));
    sleep_us(1);

    return result;
}

int main() {
    stdio_usb_init();
    gpio_init_mask(MASK_ALL);
    gpio_set_dir_in_masked(MASK_IN);
    gpio_set_dir_out_masked(MASK_OUT);
    gpio_set_mask(MASK_CSALL);
    gpio_clr_mask(MASK_CLOCK | MASK_LED);

    while (true) {
        if (!stdio_usb_connected()) {
            sleep_ms(1000);
            continue;
        }

        gpio_set_mask(MASK_LED);

        while (stdio_usb_connected()) {
            printf("[");
            for (unsigned int i = 0; i < 8; ++i)
                printf(" %u", read_sensor(i));
            printf(" ]\n");
            sleep_ms(PERIOD_MS);
        }

        gpio_clr_mask(MASK_LED);
    }

    return 0;
}