autd3_firmware_emulator/fpga/emulator/
modulation.rs

1use std::num::NonZeroU16;
2
3use autd3_driver::{
4    ethercat::DcSysTime,
5    firmware::fpga::{GPIOIn, LoopBehavior, Segment, TransitionMode},
6};
7
8use super::{super::params::*, FPGAEmulator, memory::Memory};
9
10impl FPGAEmulator {
11    #[must_use]
12    pub fn modulation_freq_division(&self, segment: Segment) -> u16 {
13        Memory::read_bram_as::<u16>(
14            &self.mem.controller_bram.borrow(),
15            match segment {
16                Segment::S0 => ADDR_MOD_FREQ_DIV0,
17                Segment::S1 => ADDR_MOD_FREQ_DIV1,
18            },
19        )
20    }
21
22    #[must_use]
23    pub fn modulation_cycle(&self, segment: Segment) -> usize {
24        self.mem.controller_bram.borrow()[match segment {
25            Segment::S0 => ADDR_MOD_CYCLE0,
26            Segment::S1 => ADDR_MOD_CYCLE1,
27        }] as usize
28            + 1
29    }
30
31    #[must_use]
32    pub fn modulation_loop_behavior(&self, segment: Segment) -> LoopBehavior {
33        match Memory::read_bram_as::<u16>(
34            &self.mem.controller_bram.borrow(),
35            match segment {
36                Segment::S0 => ADDR_MOD_REP0,
37                Segment::S1 => ADDR_MOD_REP1,
38            },
39        ) {
40            0xFFFF => LoopBehavior::Infinite,
41            v => LoopBehavior::Finite(NonZeroU16::new(v + 1).unwrap()),
42        }
43    }
44
45    #[must_use]
46    pub fn modulation(&self) -> u8 {
47        self.modulation_at(self.current_mod_segment(), self.current_mod_idx())
48    }
49
50    #[must_use]
51    pub fn modulation_at(&self, segment: Segment, idx: usize) -> u8 {
52        let m = &self.mem.modulation_bram.borrow()[&segment][idx >> 1];
53        let m = if idx % 2 == 0 { m & 0xFF } else { m >> 8 };
54        m as u8
55    }
56
57    #[must_use]
58    pub fn modulation_buffer(&self, segment: Segment) -> Vec<u8> {
59        let mut dst = vec![0; self.modulation_cycle(segment)];
60        self.modulation_buffer_inplace(segment, &mut dst);
61        dst
62    }
63
64    pub fn modulation_buffer_inplace(&self, segment: Segment, dst: &mut [u8]) {
65        (0..self.modulation_cycle(segment)).for_each(|i| dst[i] = self.modulation_at(segment, i));
66    }
67
68    #[must_use]
69    pub fn modulation_transition_mode(&self) -> TransitionMode {
70        match self.mem.controller_bram.borrow()[ADDR_MOD_TRANSITION_MODE] as u8 {
71            TRANSITION_MODE_SYNC_IDX => TransitionMode::SyncIdx,
72            TRANSITION_MODE_SYS_TIME => TransitionMode::SysTime(
73                DcSysTime::ZERO
74                    + std::time::Duration::from_nanos(Memory::read_bram_as::<u64>(
75                        &self.mem.controller_bram.borrow(),
76                        ADDR_MOD_TRANSITION_VALUE_0,
77                    )),
78            ),
79            TRANSITION_MODE_GPIO => TransitionMode::GPIO(
80                match Memory::read_bram_as::<u64>(
81                    &self.mem.controller_bram.borrow(),
82                    ADDR_MOD_TRANSITION_VALUE_0,
83                ) {
84                    0 => GPIOIn::I0,
85                    1 => GPIOIn::I1,
86                    2 => GPIOIn::I2,
87                    3 => GPIOIn::I3,
88                    _ => unreachable!(),
89                },
90            ),
91            TRANSITION_MODE_EXT => TransitionMode::Ext,
92            TRANSITION_MODE_IMMEDIATE => TransitionMode::Immediate,
93            _ => unreachable!(),
94        }
95    }
96
97    #[must_use]
98    pub fn req_modulation_segment(&self) -> Segment {
99        match self.mem.controller_bram.borrow()[ADDR_MOD_REQ_RD_SEGMENT] {
100            0 => Segment::S0,
101            1 => Segment::S1,
102            _ => unreachable!(),
103        }
104    }
105}
106
107#[cfg(test)]
108mod tests {
109    use super::*;
110
111    #[test]
112    fn modulation() {
113        let fpga = FPGAEmulator::new(249);
114        fpga.mem
115            .modulation_bram
116            .borrow_mut()
117            .get_mut(&Segment::S0)
118            .unwrap()[0] = 0x1234;
119        fpga.mem
120            .modulation_bram
121            .borrow_mut()
122            .get_mut(&Segment::S0)
123            .unwrap()[1] = 0x5678;
124        fpga.mem.controller_bram.borrow_mut()[ADDR_MOD_CYCLE0] = 3 - 1;
125        assert_eq!(3, fpga.modulation_cycle(Segment::S0));
126        assert_eq!(0x34, fpga.modulation());
127        assert_eq!(0x34, fpga.modulation_at(Segment::S0, 0));
128        assert_eq!(0x12, fpga.modulation_at(Segment::S0, 1));
129        assert_eq!(0x78, fpga.modulation_at(Segment::S0, 2));
130        assert_eq!(vec![0x34, 0x12, 0x78], fpga.modulation_buffer(Segment::S0));
131    }
132}