1use serde::{Deserialize, Serialize};
2
3macro_rules! trait_alias {
4 (pub trait $name:ident = $($traits:tt)+) => {
5 pub trait $name: $($traits)* {}
6 impl<T: $($traits)*> $name for T {}
7 };
8}
9
10pub(crate) use trait_alias;
11
12#[derive(Default, Serialize, Deserialize)]
13pub struct ClockDivider {
14 count: u64,
15 period: u64,
16}
17
18impl ClockDivider {
19 pub fn new() -> Self {
20 Self {
21 count: 0,
22 period: 0,
23 }
24 }
25
26 pub fn with_period(period: u64) -> Self {
27 Self { count: 0, period }
28 }
29
30 pub fn reset(&mut self) {
31 self.count = 0;
32 }
33
34 pub fn set_period(&mut self, period: u64) {
35 self.count = 0;
36 self.period = period;
37 }
38
39 pub fn tick(&mut self) -> bool {
40 self.count += 1;
41 if self.count >= self.period {
42 self.count = 0;
43 true
44 } else {
45 false
46 }
47 }
48}
49
50pub struct ConstEval<const V: u8>;
51
52impl<const V: u8> ConstEval<V> {
53 pub const VALUE: u8 = V;
54}
55
56macro_rules! pack {
57 (@packing $view:ident $x:literal..=$y:literal => $v:expr $(, $($rest:tt)*)?) => {
58 $view[$x..=$y].store($v);
59 pack!(@packing $view $($($rest)*)*);
60 };
61 (@packing $view:ident $x:literal => $v:expr $(, $($rest:tt)*)?) => {
62 $view.set($x, $v);
63 pack!(@packing $view $($($rest)*)*);
64 };
65 (@packing $view:ident $(,)?) => {};
66 (@packing $($rest:tt)*) => {
67 compile_error!("Invalid input for macro pack!");
68 };
69 ($($input:tt)*) => {{
70 use bitvec::prelude::*;
71 let mut data = 0;
72 let view = data.view_bits_mut::<bitvec::prelude::Lsb0>();
73 pack!(@packing view $($input)*);
74 data
75 }};
76}
77
78pub(crate) use pack;
79
80#[test]
81fn test_pack() {
82 let v: u8 = pack! {
83 0..=2 => 0b101_u8,
84 3 => true,
85 4..=6 => 0b100_u8
86 };
87 assert_eq!(v, 0b01001101);
88}
89
90pub fn to_si_bytesize(x: u64) -> String {
91 bytesize::ByteSize(x).to_string_as(true)
92}