autd3_driver/firmware/v10/
driver.rs

1use autd3_core::{environment::Environment, link::Link, sleep::Sleep};
2
3use crate::{
4    datagram::{
5        Clear, FixedCompletionSteps, Silencer,
6        implements::{Null, Static},
7    },
8    firmware::{
9        driver::{Driver, FPGAState, Sender, TimerStrategy},
10        version::FirmwareVersion,
11    },
12};
13
14use super::fpga::{
15    FOCI_STM_BUF_SIZE_MAX, FOCI_STM_FIXED_NUM_UNIT, FOCI_STM_FIXED_NUM_WIDTH,
16    FOCI_STM_FOCI_NUM_MAX, GAIN_STM_BUF_SIZE_MAX, MOD_BUF_SIZE_MAX,
17};
18
19/// A driver for firmware version 10.
20pub struct V10;
21
22impl<'a, L: Link, S: Sleep, T: TimerStrategy<S>> Sender<'a, L, S, T>
23    for super::transmission::Sender<'a, L, S, T>
24{
25    fn initialize_devices(mut self) -> Result<(), crate::error::AUTDDriverError> {
26        // If the device is used continuously without powering off, the first data may be ignored because the first msg_id equals to the remaining msg_id in the device.
27        // Therefore, send a meaningless data.
28        self.send(crate::datagram::ReadsFPGAState::new(|_| false))?;
29
30        self.send((
31            crate::datagram::Clear::new(),
32            crate::datagram::Synchronize::new(),
33        ))
34    }
35
36    fn firmware_version(
37        mut self,
38    ) -> Result<Vec<crate::firmware::version::FirmwareVersion>, crate::error::AUTDDriverError> {
39        use crate::{
40            datagram::FirmwareVersionType::*,
41            firmware::version::{CPUVersion, FPGAVersion, Major, Minor},
42        };
43
44        let cpu_major = self.fetch_firminfo(CPUMajor)?;
45        let cpu_minor = self.fetch_firminfo(CPUMinor)?;
46        let fpga_major = self.fetch_firminfo(FPGAMajor)?;
47        let fpga_minor = self.fetch_firminfo(FPGAMinor)?;
48        let fpga_functions = self.fetch_firminfo(FPGAFunctions)?;
49        self.fetch_firminfo(Clear)?;
50
51        Ok(self
52            .geometry
53            .iter()
54            .map(|dev| FirmwareVersion {
55                idx: dev.idx(),
56                cpu: CPUVersion {
57                    major: Major(cpu_major[dev.idx()]),
58                    minor: Minor(cpu_minor[dev.idx()]),
59                },
60                fpga: FPGAVersion {
61                    major: Major(fpga_major[dev.idx()]),
62                    minor: Minor(fpga_minor[dev.idx()]),
63                    function_bits: fpga_functions[dev.idx()],
64                },
65            })
66            .collect())
67    }
68
69    fn close(mut self) -> Result<(), crate::error::AUTDDriverError> {
70        [
71            self.send(Silencer {
72                config: FixedCompletionSteps {
73                    strict: false,
74                    ..Default::default()
75                },
76            }),
77            self.send((Static::default(), Null)),
78            self.send(Clear {}),
79            Ok(self.link.close()?),
80        ]
81        .into_iter()
82        .try_fold((), |_, x| x)
83    }
84}
85
86impl FPGAState for super::fpga::FPGAState {
87    fn from_rx(rx: &autd3_core::link::RxMessage) -> Option<Self> {
88        super::fpga::FPGAState::from_rx(rx)
89    }
90}
91
92impl Driver for V10 {
93    type Sender<'a, L, S, T>
94        = super::transmission::Sender<'a, L, S, T>
95    where
96        L: autd3_core::link::Link + 'a,
97        S: autd3_core::sleep::Sleep,
98        T: TimerStrategy<S>;
99    type FPGAState = super::fpga::FPGAState;
100
101    fn new() -> Self {
102        Self
103    }
104
105    fn firmware_limits(&self) -> autd3_core::derive::FirmwareLimits {
106        autd3_core::derive::FirmwareLimits {
107            mod_buf_size_max: MOD_BUF_SIZE_MAX as _,
108            gain_stm_buf_size_max: GAIN_STM_BUF_SIZE_MAX as _,
109            foci_stm_buf_size_max: FOCI_STM_BUF_SIZE_MAX as _,
110            num_foci_max: FOCI_STM_FOCI_NUM_MAX as _,
111            foci_stm_fixed_num_unit: FOCI_STM_FIXED_NUM_UNIT,
112            foci_stm_fixed_num_width: FOCI_STM_FIXED_NUM_WIDTH as _,
113        }
114    }
115
116    fn sender<'a, L, S, T>(
117        &self,
118        msg_id: &'a mut autd3_core::link::MsgId,
119        link: &'a mut L,
120        geometry: &'a autd3_core::derive::Geometry,
121        sent_flags: &'a mut [bool],
122        rx: &'a mut [autd3_core::link::RxMessage],
123        env: &'a Environment,
124        option: crate::firmware::driver::SenderOption,
125        timer_strategy: T,
126    ) -> Self::Sender<'a, L, S, T>
127    where
128        L: autd3_core::link::Link + 'a,
129        S: autd3_core::sleep::Sleep,
130        T: TimerStrategy<S>,
131    {
132        Self::Sender {
133            msg_id,
134            link,
135            geometry,
136            sent_flags,
137            rx,
138            env,
139            option,
140            timer_strategy,
141            _phantom: std::marker::PhantomData,
142        }
143    }
144}