tangled
alpha
login
or
join now
sachy.dev
/
strike-sensor
0
fork
atom
Repo for designs & driver for a TA7642 powered lightning detector
0
fork
atom
overview
issues
pulls
pipelines
feat: TimerSource tweaks, Config API
sachy.dev
1 month ago
ce1bcbff
163e8938
1/1
test.yml
success
18s
+121
-21
5 changed files
expand all
collapse all
unified
split
Cargo.lock
embassy-strike-driver
Cargo.toml
src
drivers.rs
lib.rs
traits.rs
+60
-1
Cargo.lock
···
70
70
71
71
[[package]]
72
72
name = "bitflags"
73
73
+
version = "1.3.2"
74
74
+
source = "registry+https://github.com/rust-lang/crates.io-index"
75
75
+
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
76
76
+
77
77
+
[[package]]
78
78
+
name = "bitflags"
73
79
version = "2.10.0"
74
80
source = "registry+https://github.com/rust-lang/crates.io-index"
75
81
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
···
190
196
checksum = "f578e8e2c440e7297e008bb5486a3a8a194775224bbc23729b0dbdfaeebf162e"
191
197
192
198
[[package]]
199
199
+
name = "defmt"
200
200
+
version = "1.0.1"
201
201
+
source = "registry+https://github.com/rust-lang/crates.io-index"
202
202
+
checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78"
203
203
+
dependencies = [
204
204
+
"bitflags 1.3.2",
205
205
+
"defmt-macros",
206
206
+
]
207
207
+
208
208
+
[[package]]
209
209
+
name = "defmt-macros"
210
210
+
version = "1.0.1"
211
211
+
source = "registry+https://github.com/rust-lang/crates.io-index"
212
212
+
checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e"
213
213
+
dependencies = [
214
214
+
"defmt-parser",
215
215
+
"proc-macro-error2",
216
216
+
"proc-macro2",
217
217
+
"quote",
218
218
+
"syn",
219
219
+
]
220
220
+
221
221
+
[[package]]
222
222
+
name = "defmt-parser"
223
223
+
version = "1.0.0"
224
224
+
source = "registry+https://github.com/rust-lang/crates.io-index"
225
225
+
checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e"
226
226
+
dependencies = [
227
227
+
"thiserror",
228
228
+
]
229
229
+
230
230
+
[[package]]
193
231
name = "digest"
194
232
version = "0.10.7"
195
233
source = "registry+https://github.com/rust-lang/crates.io-index"
···
295
333
version = "0.1.0"
296
334
dependencies = [
297
335
"critical-section",
336
336
+
"defmt",
298
337
"embassy-rp",
299
338
"embassy-sync",
300
339
"embassy-time",
···
868
907
source = "registry+https://github.com/rust-lang/crates.io-index"
869
908
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
870
909
dependencies = [
871
871
-
"bitflags",
910
910
+
"bitflags 2.10.0",
872
911
]
873
912
874
913
[[package]]
···
1061
1100
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
1062
1101
dependencies = [
1063
1102
"winapi-util",
1103
1103
+
]
1104
1104
+
1105
1105
+
[[package]]
1106
1106
+
name = "thiserror"
1107
1107
+
version = "2.0.18"
1108
1108
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1109
1109
+
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
1110
1110
+
dependencies = [
1111
1111
+
"thiserror-impl",
1112
1112
+
]
1113
1113
+
1114
1114
+
[[package]]
1115
1115
+
name = "thiserror-impl"
1116
1116
+
version = "2.0.18"
1117
1117
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1118
1118
+
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
1119
1119
+
dependencies = [
1120
1120
+
"proc-macro2",
1121
1121
+
"quote",
1122
1122
+
"syn",
1064
1123
]
1065
1124
1066
1125
[[package]]
+3
embassy-strike-driver/Cargo.toml
···
9
9
10
10
[features]
11
11
default = []
12
12
+
debug = ["defmt"]
12
13
alloc = []
13
14
heapless = ["dep:heapless"]
15
15
+
defmt = ["dep:defmt"]
14
16
rp2040 = ["dep:embassy-rp", "embassy-rp/rp2040"]
15
17
rp235xa = ["dep:embassy-rp", "embassy-rp/rp235xa"]
16
18
rp235xb = ["dep:embassy-rp", "embassy-rp/rp235xb"]
···
20
22
embassy-sync.workspace = true
21
23
embassy-rp = { workspace = true, optional = true }
22
24
heapless = { version = "0.9.2", optional = true }
25
25
+
defmt = { workspace = true, optional = true }
23
26
24
27
[dev-dependencies]
25
28
embassy-time = { workspace = true, features = ["mock-driver", "generic-queue-8"] }
+3
-3
embassy-strike-driver/src/drivers.rs
···
18
18
dma: Peri<'device, T>,
19
19
}
20
20
21
21
-
pub struct RpAdcDriver<'device, M: RawMutex, T: dma::Channel> {
21
21
+
pub struct AdcDriver<'device, M: RawMutex, T: dma::Channel> {
22
22
inner: Mutex<M, AdcInner<'device, T>>,
23
23
}
24
24
···
43
43
}
44
44
}
45
45
46
46
-
impl<'device, M: RawMutex, T: dma::Channel> RpAdcDriver<'device, M, T> {
46
46
+
impl<'device, M: RawMutex, T: dma::Channel> AdcDriver<'device, M, T> {
47
47
pub fn new(
48
48
inner: Peri<'device, ADC>,
49
49
pin: Peri<'device, impl AdcPin + 'device>,
···
60
60
}
61
61
}
62
62
63
63
-
impl<'device, M: RawMutex, T: dma::Channel> AdcSource for RpAdcDriver<'device, M, T> {
63
63
+
impl<'device, M: RawMutex, T: dma::Channel> AdcSource for AdcDriver<'device, M, T> {
64
64
async fn sample_average(&self, samples: &mut [u16]) -> u16 {
65
65
self.sample(samples).await;
66
66
+52
-16
embassy-strike-driver/src/lib.rs
···
11
11
12
12
use core::cell::Cell;
13
13
14
14
+
#[cfg(feature = "debug")]
15
15
+
use defmt::info;
14
16
use embassy_sync::{
15
17
blocking_mutex::raw::NoopRawMutex,
16
18
zerocopy_channel::{Channel, Receiver, Sender},
···
23
25
pub type ZeroCopyChannel<'device> = Channel<'device, NoopRawMutex, (i64, [u16; BLOCK_SIZE])>;
24
26
25
27
#[derive(Debug)]
28
28
+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
26
29
struct DetectorState {
27
30
max_duty: Cell<u8>,
28
31
duty: Cell<u8>,
···
44
47
}
45
48
46
49
#[derive(Debug)]
50
50
+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
47
51
pub struct DetectorConfig {
48
52
blip_threshold: Cell<u16>,
49
53
blip_size: Cell<usize>,
50
54
}
51
55
52
52
-
impl Default for DetectorConfig {
53
53
-
fn default() -> Self {
56
56
+
impl DetectorConfig {
57
57
+
pub const fn new(blip_threshold: u16, blip_size: usize) -> Self {
54
58
Self {
55
55
-
blip_threshold: Cell::new(14),
56
56
-
blip_size: Cell::new(2),
59
59
+
blip_threshold: Cell::new(blip_threshold),
60
60
+
blip_size: Cell::new(blip_size),
57
61
}
62
62
+
}
63
63
+
64
64
+
pub const fn blip_threshold(&self) -> u16 {
65
65
+
self.blip_threshold.get()
66
66
+
}
67
67
+
68
68
+
pub const fn blip_size(&self) -> usize {
69
69
+
self.blip_size.get()
70
70
+
}
71
71
+
72
72
+
pub fn set_blip_threshold(&self, blip_threshold: u16) {
73
73
+
self.blip_threshold.set(blip_threshold);
74
74
+
}
75
75
+
76
76
+
pub fn set_blip_size(&self, blip_size: usize) {
77
77
+
self.blip_size.set(blip_size);
78
78
+
}
79
79
+
}
80
80
+
81
81
+
impl Default for DetectorConfig {
82
82
+
fn default() -> Self {
83
83
+
Self::new(14, 2)
58
84
}
59
85
}
60
86
61
87
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
88
88
+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
62
89
pub enum DetectorUpdate<'a> {
63
90
Tick {
64
91
timestamp: i64,
···
74
101
pub struct DetectorDriver<T: TimeSource, P: PwmSource, A: AdcSource> {
75
102
state: DetectorState,
76
103
config: DetectorConfig,
77
77
-
timer_source: T,
104
104
+
timer: T,
78
105
pwm: P,
79
106
adc: A,
80
107
}
···
85
112
P: PwmSource,
86
113
A: AdcSource,
87
114
{
88
88
-
pub fn new(config: DetectorConfig, timer_source: T, pwm: P, adc: A) -> Self {
115
115
+
pub fn new(config: DetectorConfig, timer: T, pwm: P, adc: A) -> Self {
89
116
Self {
90
117
state: Default::default(),
91
118
config,
92
92
-
timer_source,
119
119
+
timer,
93
120
pwm,
94
121
adc,
95
122
}
96
123
}
97
124
98
98
-
pub fn reset_timer_source(&mut self) {
99
99
-
self.timer_source = T::get_source();
125
125
+
pub fn reset_timer_source(&mut self, timer_source: T::Source) {
126
126
+
self.timer.reset_from_source(timer_source);
100
127
}
101
128
102
129
pub fn get_timestamp(&self) -> i64 {
103
103
-
self.timer_source.timestamp()
130
130
+
self.timer.timestamp()
104
131
}
105
132
106
133
pub fn set_blip_threshold(&self, threshold: u16) {
···
116
143
self.pwm.set_duty(duty);
117
144
Timer::after_secs(2).await;
118
145
let mut act_value = self.adc.sample_average(samples).await;
146
146
+
#[cfg(feature = "debug")]
147
147
+
info!("START: {}", act_value);
119
148
120
149
while act_value < 1364 {
121
150
duty += 2;
122
151
if duty >= 256 {
152
152
+
#[cfg(feature = "debug")]
153
153
+
info!("RESET: {} @ Duty {}", act_value, duty);
123
154
duty = 0;
124
155
self.pwm.set_duty(duty);
125
156
Timer::after_secs(2).await;
···
129
160
self.pwm.set_duty(duty);
130
161
Timer::after_millis(250).await;
131
162
act_value = self.adc.sample_average(samples).await;
163
163
+
#[cfg(feature = "debug")]
164
164
+
info!("UPDATE: {} @ Duty {}", act_value, duty);
132
165
}
133
166
self.state.max_duty.set(duty as u8);
134
167
duty = (duty / 6) * 5;
···
137
170
// Allow voltage level to stabilize after tuning
138
171
Timer::after_secs(2).await;
139
172
let avg = self.adc.sample_average(samples).await;
173
173
+
#[cfg(feature = "debug")]
174
174
+
info!("SET: {} @ Duty {}/{}", avg, duty, self.state.max_duty.get());
140
175
self.state.avg.set(avg);
141
176
}
142
177
···
147
182
) {
148
183
loop {
149
184
let (time, samples) = dma.send().await;
150
150
-
*time = self.timer_source.timestamp();
185
185
+
*time = self.get_timestamp();
151
186
self.adc.sample(samples).await;
152
187
dma.send_done();
153
188
}
···
238
273
}
239
274
None => {
240
275
update(DetectorUpdate::Tick {
241
241
-
timestamp: self.timer_source.timestamp(),
276
276
+
timestamp: self.get_timestamp(),
242
277
level: warn_level - 255,
243
278
});
244
279
}
···
296
331
struct MockTimeSource;
297
332
298
333
impl TimeSource for MockTimeSource {
299
299
-
fn get_source() -> Self {
300
300
-
Self
301
301
-
}
334
334
+
type Source = ();
335
335
+
336
336
+
fn reset_from_source(&mut self, _source: Self::Source) {}
337
337
+
302
338
fn timestamp(&self) -> i64 {
303
339
0
304
340
}
···
528
564
)
529
565
});
530
566
531
531
-
assert_eq!(peaks.len(), 3);
532
567
assert!(called.get());
568
568
+
assert_eq!(peaks.len(), 3);
533
569
534
570
detector.adc.sample(&mut samples).await;
535
571
+3
-1
embassy-strike-driver/src/traits.rs
···
1
1
pub trait TimeSource {
2
2
+
type Source;
3
3
+
2
4
fn timestamp(&self) -> i64;
3
3
-
fn get_source() -> Self;
5
5
+
fn reset_from_source(&mut self, source: Self::Source);
4
6
}
5
7
6
8
pub trait AdcSource {