autd3-rs-core 0.9.0

Core types and link abstraction shared across the AUTD3 phased-array sdk crates.
Documentation
use super::{Cmd, PAYLOAD_BYTES, Seq, TX_FRAME_BYTES};

#[repr(C)]
#[derive(Clone)]
pub struct TxFrame {
    pub seq: Seq,
    pub cmd: Cmd,
    pub payload: [u8; PAYLOAD_BYTES],
}

const _: () = assert!(size_of::<TxFrame>() == TX_FRAME_BYTES);

impl TxFrame {
    #[must_use]
    pub fn new(seq: Seq, cmd: Cmd) -> Self {
        Self {
            seq,
            cmd,
            payload: [0; PAYLOAD_BYTES],
        }
    }

    pub fn write_to(&self, dst: &mut [u8; TX_FRAME_BYTES]) {
        dst[0] = self.seq.get();
        dst[1] = self.cmd.as_u8();
        dst[2..].copy_from_slice(&self.payload);
    }

    pub fn parse(src: &[u8; TX_FRAME_BYTES]) -> Result<Self, u8> {
        let cmd = Cmd::try_from(src[1])?;
        let mut payload = [0u8; PAYLOAD_BYTES];
        payload.copy_from_slice(&src[2..]);
        Ok(Self {
            seq: Seq::new(src[0]),
            cmd,
            payload,
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn tx_frame_round_trips() {
        let mut payload = [0u8; PAYLOAD_BYTES];
        let mut counter: u8 = 0;
        for b in &mut payload {
            *b = counter;
            counter = counter.wrapping_add(1);
        }
        let f = TxFrame {
            seq: Seq::new(0xA5),
            cmd: Cmd::WritePatternBuffer,
            payload,
        };
        let mut bytes = [0u8; TX_FRAME_BYTES];
        f.write_to(&mut bytes);
        assert_eq!(bytes[0], 0xA5);
        assert_eq!(bytes[1], Cmd::WritePatternBuffer.as_u8());

        let parsed = TxFrame::parse(&bytes).unwrap();
        assert_eq!(parsed.seq, Seq::new(0xA5));
        assert_eq!(parsed.cmd, Cmd::WritePatternBuffer);
        assert_eq!(parsed.payload, payload);
    }

    #[test]
    fn tx_frame_parse_rejects_unknown_cmd() {
        let mut bytes = [0u8; TX_FRAME_BYTES];
        bytes[0] = 0x10;
        bytes[1] = 0xFE;
        assert!(matches!(TxFrame::parse(&bytes), Err(0xFE)));
    }
}