autd3_firmware_emulator/fpga/emulator/
modulation.rs

1use autd3_core::firmware::{Segment, transition_mode::TransitionModeParams};
2
3use super::{super::params::*, FPGAEmulator};
4
5impl FPGAEmulator {
6    #[must_use]
7    pub fn modulation_freq_divide(&self, segment: Segment) -> u16 {
8        self.mem
9            .controller_bram
10            .read(ADDR_MOD_FREQ_DIV0 + segment as usize)
11    }
12
13    #[must_use]
14    pub fn modulation_cycle(&self, segment: Segment) -> usize {
15        self.mem
16            .controller_bram
17            .read(ADDR_MOD_CYCLE0 + segment as usize) as usize
18            + 1
19    }
20
21    #[must_use]
22    pub fn modulation_loop_count(&self, segment: Segment) -> u16 {
23        self.mem
24            .controller_bram
25            .read(ADDR_MOD_REP0 + segment as usize)
26    }
27
28    #[must_use]
29    pub fn modulation(&self) -> u8 {
30        self.modulation_at(self.current_mod_segment(), self.current_mod_idx())
31    }
32
33    #[must_use]
34    pub fn modulation_at(&self, segment: Segment, idx: usize) -> u8 {
35        let m = &self.mem.modulation_bram[&segment].read(idx >> 1);
36        let m = if idx.is_multiple_of(2) {
37            m & 0xFF
38        } else {
39            m >> 8
40        };
41        m as u8
42    }
43
44    #[must_use]
45    pub fn modulation_buffer(&self, segment: Segment) -> Vec<u8> {
46        let len = self.modulation_cycle(segment);
47        let mut buffer = Vec::with_capacity(len);
48        unsafe {
49            self.modulation_buffer_inplace(segment, buffer.as_mut_ptr());
50            buffer.set_len(len);
51        }
52        buffer
53    }
54
55    pub unsafe fn modulation_buffer_inplace(&self, segment: Segment, dst: *mut u8) {
56        (0..self.modulation_cycle(segment)).for_each(|i| {
57            unsafe { dst.add(i).write(self.modulation_at(segment, i)) };
58        });
59    }
60
61    #[must_use]
62    pub fn modulation_transition_mode(&self) -> TransitionModeParams {
63        TransitionModeParams {
64            mode: self.mem.controller_bram.read(ADDR_MOD_TRANSITION_MODE) as u8,
65            value: self
66                .mem
67                .controller_bram
68                .read_bram_as::<u64>(ADDR_MOD_TRANSITION_VALUE_0),
69        }
70    }
71
72    #[must_use]
73    pub fn req_modulation_segment(&self) -> Segment {
74        match self.mem.controller_bram.read(ADDR_MOD_REQ_RD_SEGMENT) {
75            0 => Segment::S0,
76            1 => Segment::S1,
77            _ => unreachable!(),
78        }
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85
86    #[test]
87    fn modulation() {
88        let fpga = FPGAEmulator::new(249);
89        fpga.mem.modulation_bram[&Segment::S0].write(0, 0x1234);
90        fpga.mem.modulation_bram[&Segment::S0].write(1, 0x5678);
91        fpga.mem.controller_bram.write(ADDR_MOD_CYCLE0, 3 - 1);
92        assert_eq!(3, fpga.modulation_cycle(Segment::S0));
93        assert_eq!(0x34, fpga.modulation());
94        assert_eq!(0x34, fpga.modulation_at(Segment::S0, 0));
95        assert_eq!(0x12, fpga.modulation_at(Segment::S0, 1));
96        assert_eq!(0x78, fpga.modulation_at(Segment::S0, 2));
97        assert_eq!(vec![0x34, 0x12, 0x78], fpga.modulation_buffer(Segment::S0));
98    }
99}