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