autd3_driver/firmware/cpu/
mod.rs

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
mod gain_stm_mode;

pub use autd3_core::link::{Header, RxMessage, TxMessage};
pub use gain_stm_mode::*;

use crate::error::AUTDDriverError;

pub(crate) const MSG_ID_MAX: u8 = 0x7F;

#[doc(hidden)]
pub fn check_firmware_err(msg: &RxMessage) -> Result<(), AUTDDriverError> {
    if msg.ack() & 0x80 != 0 {
        return Err(AUTDDriverError::firmware_err(msg.ack()));
    }
    Ok(())
}

#[doc(hidden)]
pub fn check_if_msg_is_processed<'a>(
    tx: &'a [TxMessage],
    rx: &'a [RxMessage],
) -> impl Iterator<Item = bool> + 'a {
    tx.iter()
        .zip(rx.iter())
        .map(|(tx, r)| tx.header.msg_id == r.ack())
}

#[cfg(test)]
mod tests {
    use itertools::Itertools;
    use zerocopy::FromZeros;

    use super::*;

    #[rstest::fixture]
    fn tx() -> Vec<TxMessage> {
        let mut tx = vec![TxMessage::new_zeroed(); 3];
        tx[0].header.msg_id = 0;
        tx[1].header.msg_id = 1;
        tx[2].header.msg_id = 2;
        tx
    }

    #[rstest::rstest]
    #[test]
    #[case::success(vec![
        RxMessage::new(0,0),
        RxMessage::new(0,1),
        RxMessage::new(0,2),
    ], vec![true, true, true])]
    #[case::success(vec![
        RxMessage::new(0, 1),
        RxMessage::new(0, 1),
        RxMessage::new(0, 1),
    ], vec![false, true, false])]
    fn test_check_if_msg_is_processed(
        #[case] rx: Vec<RxMessage>,
        #[case] expect: Vec<bool>,
        tx: Vec<TxMessage>,
    ) {
        assert_eq!(expect, check_if_msg_is_processed(&tx, &rx).collect_vec());
    }
}