autd3_firmware_emulator/fpga/emulator/stm/
mod.rs1mod foci;
2mod gain;
3
4use autd3_core::firmware::{Drive, Phase, Segment, transition_mode::TransitionModeParams};
5
6use super::{super::params::*, FPGAEmulator};
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 len = self.mem.num_transducers;
67 let mut phase_corr = Vec::<Phase>::with_capacity(len);
68 let mut output_mask = Vec::<bool>::with_capacity(len);
69 let mut buffer = Vec::with_capacity(len);
70 unsafe {
71 self.drives_at_inplace(
72 segment,
73 idx,
74 phase_corr.as_mut_ptr(),
75 output_mask.as_mut_ptr(),
76 buffer.as_mut_ptr(),
77 );
78 buffer.set_len(len);
79 }
80 buffer
81 }
82
83 pub unsafe fn drives_at_inplace(
84 &self,
85 segment: Segment,
86 idx: usize,
87 phase_corr_buf: *mut Phase,
88 output_mask_buf: *mut bool,
89 dst: *mut Drive,
90 ) {
91 if self.is_stm_gain_mode(segment) {
92 self.gain_stm_drives_inplace(segment, idx, phase_corr_buf, output_mask_buf, dst)
93 } else {
94 self.foci_stm_drives_inplace(segment, idx, phase_corr_buf, output_mask_buf, dst)
95 }
96 }
97}