autd3_firmware_emulator/fpga/emulator/stm/
mod.rs1use 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}