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 mut dst = vec![0; self.modulation_cycle(segment)];
47        self.modulation_buffer_inplace(segment, &mut dst);
48        dst
49    }
50
51    pub fn modulation_buffer_inplace(&self, segment: Segment, dst: &mut [u8]) {
52        (0..self.modulation_cycle(segment)).for_each(|i| dst[i] = self.modulation_at(segment, i));
53    }
54
55    #[must_use]
56    pub fn modulation_transition_mode(&self) -> TransitionModeParams {
57        TransitionModeParams {
58            mode: self.mem.controller_bram.read(ADDR_MOD_TRANSITION_MODE) as u8,
59            value: self
60                .mem
61                .controller_bram
62                .read_bram_as::<u64>(ADDR_MOD_TRANSITION_VALUE_0),
63        }
64    }
65
66    #[must_use]
67    pub fn req_modulation_segment(&self) -> Segment {
68        match self.mem.controller_bram.read(ADDR_MOD_REQ_RD_SEGMENT) {
69            0 => Segment::S0,
70            1 => Segment::S1,
71            _ => unreachable!(),
72        }
73    }
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79
80    #[test]
81    fn modulation() {
82        let fpga = FPGAEmulator::new(249);
83        fpga.mem.modulation_bram[&Segment::S0].write(0, 0x1234);
84        fpga.mem.modulation_bram[&Segment::S0].write(1, 0x5678);
85        fpga.mem.controller_bram.write(ADDR_MOD_CYCLE0, 3 - 1);
86        assert_eq!(3, fpga.modulation_cycle(Segment::S0));
87        assert_eq!(0x34, fpga.modulation());
88        assert_eq!(0x34, fpga.modulation_at(Segment::S0, 0));
89        assert_eq!(0x12, fpga.modulation_at(Segment::S0, 1));
90        assert_eq!(0x78, fpga.modulation_at(Segment::S0, 2));
91        assert_eq!(vec![0x34, 0x12, 0x78], fpga.modulation_buffer(Segment::S0));
92    }
93}