autd3_firmware_emulator/fpga/emulator/stm/
mod.rs

1use autd3_core::firmware::{Drive, Phase, Segment, transition_mode::TransitionModeParams};
2
3use super::{super::params::*, FPGAEmulator};
4
5mod foci;
6mod gain;
7
8impl FPGAEmulator {
9    #[must_use]
10    pub fn is_stm_gain_mode(&self, segment: Segment) -> bool {
11        self.mem
12            .controller_bram
13            .read(ADDR_STM_MODE0 + segment as usize)
14            == STM_MODE_GAIN
15    }
16
17    #[must_use]
18    pub fn stm_freq_divide(&self, segment: Segment) -> u16 {
19        self.mem
20            .controller_bram
21            .read(ADDR_STM_FREQ_DIV0 + segment as usize)
22    }
23
24    #[must_use]
25    pub fn stm_cycle(&self, segment: Segment) -> usize {
26        self.mem
27            .controller_bram
28            .read(ADDR_STM_CYCLE0 + segment as usize) as usize
29            + 1
30    }
31
32    #[must_use]
33    pub fn stm_loop_count(&self, segment: Segment) -> u16 {
34        self.mem
35            .controller_bram
36            .read(ADDR_STM_REP0 + segment as usize)
37    }
38
39    #[must_use]
40    pub fn stm_transition_mode(&self) -> TransitionModeParams {
41        TransitionModeParams {
42            mode: self.mem.controller_bram.read(ADDR_STM_TRANSITION_MODE) as u8,
43            value: self
44                .mem
45                .controller_bram
46                .read_bram_as::<u64>(ADDR_STM_TRANSITION_VALUE_0),
47        }
48    }
49
50    #[must_use]
51    pub fn req_stm_segment(&self) -> Segment {
52        match self.mem.controller_bram.read(ADDR_STM_REQ_RD_SEGMENT) {
53            0 => Segment::S0,
54            1 => Segment::S1,
55            _ => unreachable!(),
56        }
57    }
58
59    #[must_use]
60    pub fn drives(&self) -> Vec<Drive> {
61        self.drives_at(self.current_stm_segment(), self.current_stm_idx())
62    }
63
64    #[must_use]
65    pub fn drives_at(&self, segment: Segment, idx: usize) -> Vec<Drive> {
66        let mut phase_corr_buf = vec![Phase::ZERO; self.mem.num_transducers];
67        let mut output_mask_buf = vec![false; self.mem.num_transducers];
68        let mut dst = vec![Drive::NULL; self.mem.num_transducers];
69        self.drives_at_inplace(
70            segment,
71            idx,
72            &mut phase_corr_buf,
73            &mut output_mask_buf,
74            &mut dst,
75        );
76        dst
77    }
78
79    pub fn drives_at_inplace(
80        &self,
81        segment: Segment,
82        idx: usize,
83        phase_corr_buf: &mut [Phase],
84        output_mask_buf: &mut [bool],
85        dst: &mut [Drive],
86    ) {
87        if self.is_stm_gain_mode(segment) {
88            self.gain_stm_drives_inplace(segment, idx, phase_corr_buf, output_mask_buf, dst)
89        } else {
90            self.foci_stm_drives_inplace(segment, idx, phase_corr_buf, output_mask_buf, dst)
91        }
92    }
93}