autd3_firmware_emulator/fpga/emulator/
pwe.rs

1use autd3_core::firmware::{Intensity, PulseWidth};
2
3use super::FPGAEmulator;
4
5impl FPGAEmulator {
6    #[must_use]
7    pub fn pulse_width_encoder_table_at(&self, idx: usize) -> PulseWidth {
8        PulseWidth::new(self.mem.duty_table_bram.read(idx) as _)
9    }
10
11    #[must_use]
12    pub fn pulse_width_encoder_table(&self) -> Vec<PulseWidth> {
13        let mut buffer = Vec::with_capacity(256);
14        unsafe {
15            self.pulse_width_encoder_table_inplace(buffer.as_mut_ptr());
16            buffer.set_len(256);
17        }
18        buffer
19    }
20
21    pub unsafe fn pulse_width_encoder_table_inplace(&self, dst: *mut PulseWidth) {
22        (0..256).for_each(|i| {
23            unsafe { dst.add(i).write(self.pulse_width_encoder_table_at(i)) };
24        });
25    }
26
27    #[must_use]
28    pub fn to_pulse_width(&self, a: Intensity, b: u8) -> PulseWidth {
29        let key = (a.0 as usize * b as usize) / 255;
30        self.pulse_width_encoder_table_at(key)
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37
38    static ASIN_TABLE: &[u8; 512] = include_bytes!("asin.dat");
39
40    fn to_pulse_width_actual(a: u8, b: u8) -> PulseWidth {
41        let idx = (a as usize * b as usize) / 255;
42        PulseWidth::new(u16::from_le_bytes([ASIN_TABLE[(idx << 1) + 1], ASIN_TABLE[idx << 1]]) as _)
43    }
44
45    #[test]
46    fn to_pulse_width() {
47        let fpga = FPGAEmulator::new(249);
48        (0x00..=0xFF).for_each(|a| {
49            (0x00..=0xFF).for_each(|b| {
50                assert_eq!(
51                    to_pulse_width_actual(a, b),
52                    fpga.to_pulse_width(Intensity(a), b)
53                );
54            });
55        });
56    }
57}