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;
}
|