autd3_firmware_emulator/fpga/emulator/
pwe.rs1use 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}