neuromorphic_drivers/devices/
inivation_davis346.rs

1use crate::adapters;
2use crate::configuration;
3use crate::device;
4use crate::flag;
5use crate::properties;
6use crate::usb;
7
8use device::Usb;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub struct ApsOrientation {
12    pub flip_x: bool,
13    pub flip_y: bool,
14    pub invert_xy: bool,
15}
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub struct ImuOrientation {
19    pub flip_x: bool,
20    pub flip_y: bool,
21    pub flip_z: bool,
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub enum ImuType {
26    None,
27    InvenSense6050Or6150,
28    InvenSense9250,
29}
30
31impl ImuType {
32    pub fn temperature_celsius(&self, value: i16) -> f32 {
33        match self {
34            ImuType::None => value as f32,
35            ImuType::InvenSense6050Or6150 => (value as f32 / 340.0) + 35.0,
36            ImuType::InvenSense9250 => (value as f32 / 333.87) + 21.0,
37        }
38    }
39}
40
41#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
42pub struct Biases {
43    localbufbn: u16,    // in [0, 2040]
44    padfollbn: u16,     // in [0, 2040]
45    diffbn: u16,        // in [0, 2040]
46    onbn: u16,          // in [0, 2040]
47    offbn: u16,         // in [0, 2040]
48    pixinvbn: u16,      // in [0, 2040]
49    prbp: u16,          // in [0, 2040]
50    prsfbp: u16,        // in [0, 2040]
51    refrbp: u16,        // in [0, 2040]
52    readoutbufbp: u16,  // in [0, 2040]
53    apsrosfbn: u16,     // in [0, 2040]
54    adccompbp: u16,     // in [0, 2040]
55    colsellowbn: u16,   // in [0, 2040]
56    dacbufbp: u16,      // in [0, 2040]
57    lcoltimeoutbn: u16, // in [0, 2040]
58    aepdbn: u16,        // in [0, 2040]
59    aepuxbp: u16,       // in [0, 2040]
60    aepuybp: u16,       // in [0, 2040]
61    ifrefrbn: u16,      // in [0, 2040]
62    ifthrbn: u16,       // in [0, 2040]
63    biasbuffer: u16,    // in [0, 2040]
64}
65
66#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
67pub struct RegionOfInterest {
68    left: u16,
69    top: u16,
70    width: u16,
71    height: u16,
72}
73
74#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
75pub struct ActivityFilter {
76    mask_isolated_enable: bool,
77    mask_isolated_tau: u32, // in 250 µs increments
78    refractory_period_enable: bool,
79    refractory_period_tau: u32, // in 250 µs increments
80}
81
82#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
83pub enum PolarityFilter {
84    Disabled = 0,
85    Flatten = 1, // all the polarities are set to OFF
86    MaskOn = 2,  // implies flatten
87    MaskOff = 3,
88    MaskOffFlatten = 4,
89}
90
91#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
92pub struct Configuration {
93    pub biases: Biases,
94    pub region_of_interest: RegionOfInterest,
95    pub pixel_mask: [u32; 8],
96    pub activity_filter: ActivityFilter,
97    pub skip_events_every: u32,
98    pub polarity_filter: PolarityFilter,
99    pub exposure_us: u32,
100    pub frame_interval_us: u32,
101}
102
103pub struct Device {
104    handle: std::sync::Arc<rusb::DeviceHandle<rusb::Context>>,
105    ring: usb::Ring,
106    configuration_updater: configuration::Updater<Configuration>,
107    vendor_and_product_id: (u16, u16),
108    serial: String,
109    dvs_invert_xy: bool,
110    aps_orientation: ApsOrientation,
111    imu_orientation: ImuOrientation,
112    imu_type: ImuType,
113}
114
115#[derive(thiserror::Error, Debug, Clone)]
116pub enum Error {
117    #[error(transparent)]
118    Usb(#[from] usb::Error),
119
120    #[error("Firmware version not supported (neuromorphic-drivers expects version 0.6 or later, the camera runs on version {minor}.{subminor})")]
121    FirmwareVersion { minor: u8, subminor: u8 },
122
123    #[error("Logic version not supported (neuromorphic-drivers expects version 18, the camera runs on version {0})")]
124    LogicVersion(u32),
125
126    #[error("Logic patch not supported (neuromorphic-drivers expects version 1 or above, the camera runs on version {0})")]
127    LogicPatch(u32),
128
129    #[error("Short SPI read to {module_address:#04X}:{parameter_address:#04X} (expected {expected} bytes, read {count} bytes)")]
130    ShortRead {
131        module_address: u16,
132        parameter_address: u16,
133        expected: usize,
134        count: usize,
135    },
136
137    #[error("Short SPI write to {module_address:#04X}:{parameter_address:#04X} (expected {expected} bytes, wrote {count} bytes)")]
138    ShortWrite {
139        module_address: u16,
140        parameter_address: u16,
141        expected: usize,
142        count: usize,
143    },
144}
145
146impl From<rusb::Error> for Error {
147    fn from(error: rusb::Error) -> Self {
148        usb::Error::from(error).into()
149    }
150}
151
152pub const PROPERTIES: properties::Camera<Configuration> = Device::PROPERTIES;
153pub const DEFAULT_CONFIGURATION: Configuration = Device::PROPERTIES.default_configuration;
154pub const DEFAULT_USB_CONFIGURATION: usb::Configuration = Device::DEFAULT_USB_CONFIGURATION;
155pub fn open<IntoError, IntoWarning>(
156    serial_or_bus_number_and_address: device::SerialOrBusNumberAndAddress,
157    configuration: Configuration,
158    usb_configuration: &usb::Configuration,
159    event_loop: std::sync::Arc<usb::EventLoop>,
160    flag: flag::Flag<IntoError, IntoWarning>,
161) -> Result<Device, Error>
162where
163    IntoError: From<Error> + Clone + Send + 'static,
164    IntoWarning: From<usb::Overflow> + Clone + Send + 'static,
165{
166    Device::open(
167        serial_or_bus_number_and_address,
168        configuration,
169        usb_configuration,
170        event_loop,
171        flag,
172    )
173}
174
175impl device::Usb for Device {
176    type Adapter = adapters::davis346::Adapter;
177
178    type Configuration = Configuration;
179
180    type Error = Error;
181
182    type Properties = properties::Camera<Self::Configuration>;
183
184    const VENDOR_AND_PRODUCT_IDS: &'static [(u16, u16)] = &[(0x152A, 0x841A)];
185
186    const PROPERTIES: Self::Properties = Self::Properties {
187        name: "iniVation DAVIS 346",
188        width: 346,
189        height: 260,
190        default_configuration: Self::Configuration {
191            biases: Biases {
192                localbufbn: 1461,
193                padfollbn: 2000,
194                diffbn: 1063,
195                onbn: 1564,
196                offbn: 583,
197                pixinvbn: 1691,
198                prbp: 575,
199                prsfbp: 153,
200                refrbp: 993,
201                readoutbufbp: 1457,
202                apsrosfbn: 1776,
203                adccompbp: 1202,
204                colsellowbn: 1,
205                dacbufbp: 1597,
206                lcoltimeoutbn: 1330,
207                aepdbn: 1632,
208                aepuxbp: 1110,
209                aepuybp: 1937,
210                ifrefrbn: 1564,
211                ifthrbn: 1564,
212                biasbuffer: 1563,
213            },
214            pixel_mask: [0; 8],
215            region_of_interest: RegionOfInterest {
216                left: 0,
217                top: 0,
218                width: 346,
219                height: 260,
220            },
221            activity_filter: ActivityFilter {
222                mask_isolated_enable: true,
223                mask_isolated_tau: 8,
224                refractory_period_enable: false,
225                refractory_period_tau: 1,
226            },
227            polarity_filter: PolarityFilter::Disabled,
228            skip_events_every: 0,
229            exposure_us: 4000,
230            frame_interval_us: 40000,
231        },
232    };
233
234    const DEFAULT_USB_CONFIGURATION: usb::Configuration = usb::Configuration {
235        buffer_length: 1 << 17,
236        ring_length: 1 << 12,
237        transfer_queue_length: 1 << 5,
238        allow_dma: false,
239    };
240
241    fn read_serial(handle: &mut rusb::DeviceHandle<rusb::Context>) -> rusb::Result<Option<String>> {
242        handle.claim_interface(0)?;
243        let descriptor = handle.device().device_descriptor()?;
244        if let Some(serial_number_string_index) = descriptor.serial_number_string_index() {
245            Ok(Some(handle.read_string_descriptor_ascii(
246                serial_number_string_index,
247            )?))
248        } else {
249            Ok(Some("00000000".to_owned()))
250        }
251    }
252
253    fn default_configuration(&self) -> Self::Configuration {
254        PROPERTIES.default_configuration
255    }
256
257    fn current_configuration(&self) -> Self::Configuration {
258        self.configuration_updater.current_configuration()
259    }
260
261    fn update_configuration(&self, configuration: Self::Configuration) {
262        self.configuration_updater.update(configuration);
263    }
264
265    fn open<IntoError, IntoWarning>(
266        serial_or_bus_number_and_address: device::SerialOrBusNumberAndAddress,
267        configuration: Self::Configuration,
268        usb_configuration: &usb::Configuration,
269        event_loop: std::sync::Arc<usb::EventLoop>,
270        flag: flag::Flag<IntoError, IntoWarning>,
271    ) -> Result<Self, Self::Error>
272    where
273        IntoError: From<Self::Error> + Clone + Send + 'static,
274        IntoWarning: From<usb::Overflow> + Clone + Send + 'static,
275    {
276        let (handle, vendor_and_product_id, serial) = match serial_or_bus_number_and_address {
277            device::SerialOrBusNumberAndAddress::Serial(serial) => {
278                Self::open_serial(event_loop.context(), serial)?
279            }
280            device::SerialOrBusNumberAndAddress::BusNumberAndAddress((bus_number, address)) => {
281                Self::open_bus_number_and_address(event_loop.context(), bus_number, address)?
282            }
283            device::SerialOrBusNumberAndAddress::None => Self::open_any(event_loop.context())?,
284        };
285        let device_version = handle.device().device_descriptor()?.device_version();
286        if device_version.minor() == 0 && device_version.sub_minor() < 6 {
287            return Err(Self::Error::FirmwareVersion {
288                minor: device_version.minor(),
289                subminor: device_version.sub_minor(),
290            });
291        }
292        let logic_version = LOGIC_VERSION.get(&handle)?;
293        if logic_version != 18 {
294            return Err(Error::LogicVersion(logic_version));
295        }
296        let logic_patch = LOGIC_PATCH.get(&handle)?;
297        if logic_patch < 1 {
298            return Err(Error::LogicPatch(logic_patch));
299        }
300        let logic_clock_register = LOGIC_CLOCK.get(&handle)?;
301        let adc_clock_register = ADC_CLOCK.get(&handle)?;
302        let usb_clock_register = USB_CLOCK.get(&handle)?;
303        let clock_deviation = CLOCK_DEVIATION.get(&handle)?;
304        let logic_clock = (logic_clock_register as f64) * (clock_deviation as f64 / 1000.0);
305        let adc_clock = (adc_clock_register as f64) * (clock_deviation as f64 / 1000.0);
306        let usb_clock = (usb_clock_register as f64) * (clock_deviation as f64 / 1000.0);
307        let has_pixel_filter = DVS_HAS_PIXEL_FILTER.get(&handle)? == 1;
308        let has_activity_filter = DVS_HAS_BACKGROUND_ACTIVITY_FILTER.get(&handle)? == 1;
309        let has_roi_filter = DVS_HAS_ROI_FILTER.get(&handle)? == 1;
310        let has_skip_filter = DVS_HAS_SKIP_FILTER.get(&handle)? == 1;
311        let has_polarity_filter = DVS_HAS_POLARITY_FILTER.get(&handle)? == 1;
312        let has_global_shutter = APS_HAS_GLOBAL_SHUTTER.get(&handle)? == 1;
313        let dvs_invert_xy = ((DVS_ORIENTATION.get(&handle)? >> 2) & 1) == 1;
314        let aps_orientation = {
315            let aps_orientation = APS_ORIENTATION.get(&handle)?;
316            ApsOrientation {
317                flip_x: ((aps_orientation >> 1) & 1) == 1,
318                flip_y: (aps_orientation & 1) == 1,
319                invert_xy: ((aps_orientation >> 2) & 1) == 1,
320            }
321        };
322        let imu_orientation = {
323            let imu_orientation = IMU_ORIENTATION.get(&handle)?;
324            ImuOrientation {
325                flip_x: ((imu_orientation >> 2) & 1) == 1,
326                flip_y: ((imu_orientation >> 1) & 1) == 1,
327                flip_z: (imu_orientation & 1) == 1,
328            }
329        };
330        let imu_type = match IMU_TYPE.get(&handle)? {
331            1 => ImuType::InvenSense6050Or6150,
332            2 => ImuType::InvenSense9250,
333            _ => ImuType::None,
334        };
335        DVS_RUN.set(&handle, 0)?;
336        APS_RUN.set(&handle, 0)?;
337        IMU_ACCELEROMETER_RUN.set(&handle, 0)?;
338        IMU_GYROSCOPE_RUN.set(&handle, 0)?;
339        IMU_TEMPERATURE_RUN.set(&handle, 0)?;
340        EXTERNAL_INPUT_DETECTOR_RUN.set(&handle, 0)?;
341        EXTERNAL_INPUT_GENERATOR_RUN.set(&handle, 0)?;
342        MULTIPLEXER_RUN.set(&handle, 0)?;
343        MULTIPLEXER_TIMESTAMP_RUN.set(&handle, 0)?;
344        USB_RUN.set(&handle, 0)?;
345        MULTIPLEXER_CHIP_RUN.set(&handle, 0)?;
346        std::thread::sleep(std::time::Duration::from_millis(100));
347        handle.clear_halt(0x82)?;
348        CHIP_BIAS_APSOVERFLOWLEVEL.set(&handle, 27 | (6 << 6))?;
349        CHIP_BIAS_APSCAS.set(&handle, 21 | (6 << 6))?;
350        CHIP_BIAS_ADCREFHIGH.set(&handle, 32 | (7 << 6))?;
351        CHIP_BIAS_ADCREFLOW.set(&handle, 1 | (7 << 6))?;
352        CHIP_BIAS_ADCTESTVOLTAGE.set(&handle, 21 | (7 << 6))?;
353
354        update_configuration(
355            &handle,
356            None,
357            &configuration,
358            has_pixel_filter,
359            has_activity_filter,
360            has_roi_filter,
361            has_skip_filter,
362            has_polarity_filter,
363            adc_clock,
364        )?;
365
366        CHIP_BIAS_SSP.set(&handle, (1 << 4) | (33 << 10))?;
367        CHIP_BIAS_SSN.set(&handle, (1 << 4) | (33 << 10))?;
368        CHIP_DIGITALMUX0.set(&handle, 0)?;
369        CHIP_DIGITALMUX1.set(&handle, 0)?;
370        CHIP_DIGITALMUX2.set(&handle, 0)?;
371        CHIP_DIGITALMUX3.set(&handle, 0)?;
372        CHIP_ANALOGMUX0.set(&handle, 0)?;
373        CHIP_ANALOGMUX1.set(&handle, 0)?;
374        CHIP_ANALOGMUX2.set(&handle, 0)?;
375        CHIP_BIASMUX0.set(&handle, 0)?;
376        CHIP_RESETCALIBNEURON.set(&handle, 1)?;
377        CHIP_TYPENCALIBNEURON.set(&handle, 0)?;
378        CHIP_RESETTESTPIXEL.set(&handle, 1)?;
379        CHIP_AERNAROW.set(&handle, 0)?;
380        CHIP_USEAOUT.set(&handle, 0)?;
381        CHIP_SELECTGRAYCOUNTER.set(&handle, 1)?;
382        CHIP_TESTADC.set(&handle, 0)?;
383        std::thread::sleep(std::time::Duration::from_millis(10));
384        MULTIPLEXER_CHIP_RUN.set(&handle, 1)?;
385        USB_EARLY_PACKET_DELAY.set(&handle, (1000.0 * usb_clock).round() as u32)?;
386        std::thread::sleep(std::time::Duration::from_millis(200));
387        USB_RUN.set(&handle, 1)?;
388        MULTIPLEXER_DROP_DVS_ON_STALL.set(&handle, 1)?;
389        MULTIPLEXER_DROP_EXTERNAL_INPUT_ON_STALL.set(&handle, 1)?;
390        MULTIPLEXER_TIMESTAMP_RUN.set(&handle, 1)?;
391        MULTIPLEXER_RUN.set(&handle, 1)?;
392        std::thread::sleep(std::time::Duration::from_millis(50));
393        DVS_WAIT_ON_STALL.set(&handle, 0)?;
394        DVS_EXTERNAL_AER_CONTROL.set(&handle, 0)?;
395        DVS_RUN.set(&handle, 1)?;
396        APS_WAIT_ON_STALL.set(&handle, 1)?;
397        APS_GLOBAL_SHUTTER.set(&handle, has_global_shutter as u32)?;
398        CHIP_GLOBAL_SHUTTER.set(&handle, has_global_shutter as u32)?;
399        APS_RUN.set(&handle, 1)?;
400        IMU_SAMPLE_RATE_DIVIDER.set(&handle, 0)?;
401        IMU_ACCELEROMETER_DIGITAL_LOW_PASS_FILTER.set(&handle, 1)?;
402        IMU_ACCELEROMETER_FULL_SCALE.set(&handle, 1)?;
403        if matches!(imu_type, ImuType::InvenSense9250) {
404            IMU_GYROSCOPE_DIGITAL_LOW_PASS_FILTER.set(&handle, 1)?;
405        }
406        IMU_GYROSCOPE_FULL_SCALE.set(&handle, 1)?;
407        IMU_ACCELEROMETER_RUN.set(&handle, 1)?;
408        IMU_GYROSCOPE_RUN.set(&handle, 1)?;
409        IMU_TEMPERATURE_RUN.set(&handle, 1)?;
410        EXTERNAL_INPUT_DETECT_RISING_EDGES.set(&handle, 0)?;
411        EXTERNAL_INPUT_DETECT_FALLING_EDGES.set(&handle, 0)?;
412        EXTERNAL_INPUT_GENERATE_PULSE_LENGTH.set(&handle, (5.0 * logic_clock).round() as u32)?;
413        EXTERNAL_INPUT_GENERATE_PULSE_INTERVAL.set(&handle, (5.0 * logic_clock).round() as u32)?;
414        EXTERNAL_INPUT_GENERATE_INJECT_ON_RISING_EDGE.set(&handle, 0)?;
415        EXTERNAL_INPUT_GENERATE_INJECT_ON_FALLING_EDGE.set(&handle, 0)?;
416        EXTERNAL_INPUT_DETECT_PULSES.set(&handle, 0)?;
417        EXTERNAL_INPUT_DETECT_PULSE_POLARITY.set(&handle, 1)?;
418        EXTERNAL_INPUT_DETECT_PULSE_LENGTH.set(&handle, (10.0 * logic_clock).round() as u32)?;
419        EXTERNAL_INPUT_DETECTOR_RUN.set(&handle, 0)?;
420
421        let handle = std::sync::Arc::new(handle);
422        let error_flag = flag.clone();
423        let warning_flag = flag.clone();
424        Ok(Device {
425            handle: handle.clone(),
426            ring: usb::Ring::new(
427                handle.clone(),
428                usb_configuration,
429                move |usb_error| {
430                    error_flag.store_error_if_not_set(Self::Error::from(usb_error));
431                },
432                move |overflow| {
433                    warning_flag.store_warning_if_not_set(overflow);
434                },
435                event_loop,
436                usb::TransferType::Bulk {
437                    endpoint: 2 | libusb1_sys::constants::LIBUSB_ENDPOINT_IN,
438                    timeout: std::time::Duration::ZERO,
439                },
440            )?,
441            configuration_updater: configuration::Updater::new(
442                configuration,
443                ConfigurationUpdaterContext {
444                    handle,
445                    flag,
446                    has_pixel_filter,
447                    has_activity_filter,
448                    has_roi_filter,
449                    has_skip_filter,
450                    has_polarity_filter,
451                    adc_clock,
452                },
453                |context, previous_configuration, configuration| {
454                    let result = {
455                        update_configuration(
456                            &context.handle,
457                            Some(previous_configuration),
458                            configuration,
459                            context.has_pixel_filter,
460                            context.has_activity_filter,
461                            context.has_roi_filter,
462                            context.has_skip_filter,
463                            context.has_polarity_filter,
464                            context.adc_clock,
465                        )
466                    };
467                    if let Err(error) = result {
468                        context.flag.store_error_if_not_set(error);
469                    }
470                    context
471                },
472            ),
473            vendor_and_product_id,
474            serial,
475            dvs_invert_xy,
476            aps_orientation,
477            imu_orientation,
478            imu_type,
479        })
480    }
481
482    fn next_with_timeout(&'_ self, timeout: &std::time::Duration) -> Option<usb::BufferView<'_>> {
483        self.ring.next_with_timeout(timeout)
484    }
485
486    fn backlog(&self) -> usize {
487        self.ring.backlog()
488    }
489
490    fn clutch(&self) -> usb::Clutch {
491        self.ring.clutch()
492    }
493
494    fn vendor_and_product_id(&self) -> (u16, u16) {
495        self.vendor_and_product_id
496    }
497
498    fn serial(&self) -> String {
499        self.serial.clone()
500    }
501
502    fn chip_firmware_configuration(&self) -> Self::Configuration {
503        Self::PROPERTIES.default_configuration.clone()
504    }
505
506    fn bus_number(&self) -> u8 {
507        self.handle.device().bus_number()
508    }
509
510    fn address(&self) -> u8 {
511        self.handle.device().address()
512    }
513
514    fn speed(&self) -> usb::Speed {
515        self.handle.device().speed().into()
516    }
517
518    fn create_adapter(&self) -> Self::Adapter {
519        Self::Adapter::new(
520            self.dvs_invert_xy,
521            self.aps_orientation,
522            self.imu_orientation,
523            self.imu_type,
524        )
525    }
526}
527
528impl Device {
529    pub fn dvs_invert_xy(&self) -> bool {
530        self.dvs_invert_xy
531    }
532
533    pub fn aps_orientation(&self) -> ApsOrientation {
534        self.aps_orientation
535    }
536
537    pub fn imu_orientation(&self) -> ImuOrientation {
538        self.imu_orientation
539    }
540
541    pub fn imu_type(&self) -> ImuType {
542        self.imu_type
543    }
544}
545
546impl Drop for Device {
547    fn drop(&mut self) {
548        let _ = DVS_RUN.set(&self.handle, 0);
549        let _ = APS_RUN.set(&self.handle, 0);
550        let _ = IMU_ACCELEROMETER_RUN.set(&self.handle, 0);
551        let _ = IMU_GYROSCOPE_RUN.set(&self.handle, 0);
552        let _ = IMU_TEMPERATURE_RUN.set(&self.handle, 0);
553        let _ = EXTERNAL_INPUT_DETECTOR_RUN.set(&self.handle, 0);
554        let _ = MULTIPLEXER_RUN.set(&self.handle, 0);
555        let _ = MULTIPLEXER_TIMESTAMP_RUN.set(&self.handle, 0);
556        let _ = USB_RUN.set(&self.handle, 0);
557        let _ = MULTIPLEXER_CHIP_RUN.set(&self.handle, 0);
558    }
559}
560
561const TIMEOUT: std::time::Duration = std::time::Duration::from_secs(1);
562
563const BIAS_ENABLED: u32 = 0b1;
564const BIAS_SEX_N: u32 = 0b10;
565const BIAS_TYPE_NORMAL: u32 = 0b100;
566const BIAS_CURRENT_LEVEL_NORMAL: u32 = 0b1000;
567const BIAS_P_TYPE: u32 = BIAS_ENABLED | BIAS_TYPE_NORMAL | BIAS_CURRENT_LEVEL_NORMAL;
568const BIAS_N_TYPE: u32 = BIAS_ENABLED | BIAS_SEX_N | BIAS_TYPE_NORMAL | BIAS_CURRENT_LEVEL_NORMAL;
569const BIAS_N_TYPE_OFF: u32 = BIAS_SEX_N | BIAS_TYPE_NORMAL | BIAS_CURRENT_LEVEL_NORMAL;
570
571macro_rules! update_bias {
572    ($name:ident, $register:ident, $bias_type:ident, $handle:ident, $previous_biases:ident, $biases:expr) => {
573        if match $previous_biases {
574            Some(previous_biases) => previous_biases.$name != $biases.$name,
575            None => true,
576        } {
577            let (coarse, fine) =
578                COARSE_FINE_MAP[($biases.$name as usize).min(COARSE_FINE_MAP.len() - 1)];
579            $register.set(
580                $handle,
581                $bias_type | ((fine as u32) << 4) | ((coarse as u32) << 12),
582            )?;
583        }
584    };
585}
586
587fn update_configuration(
588    handle: &rusb::DeviceHandle<rusb::Context>,
589    previous_configuration: Option<&Configuration>,
590    configuration: &Configuration,
591    has_pixel_filter: bool,
592    has_activity_filter: bool,
593    has_roi_filter: bool,
594    has_skip_filter: bool,
595    has_polarity_filter: bool,
596    adc_clock: f64,
597) -> Result<(), Error> {
598    // coarse / fine biases
599    let previous_biases = previous_configuration.map(|configuration| &configuration.biases);
600    update_bias!(
601        localbufbn,
602        CHIP_BIAS_LOCALBUFBN,
603        BIAS_N_TYPE,
604        handle,
605        previous_biases,
606        configuration.biases
607    );
608    update_bias!(
609        padfollbn,
610        CHIP_BIAS_PADFOLLBN,
611        BIAS_N_TYPE_OFF,
612        handle,
613        previous_biases,
614        configuration.biases
615    );
616    update_bias!(
617        diffbn,
618        CHIP_BIAS_DIFFBN,
619        BIAS_N_TYPE,
620        handle,
621        previous_biases,
622        configuration.biases
623    );
624    update_bias!(
625        onbn,
626        CHIP_BIAS_ONBN,
627        BIAS_N_TYPE,
628        handle,
629        previous_biases,
630        configuration.biases
631    );
632    update_bias!(
633        offbn,
634        CHIP_BIAS_OFFBN,
635        BIAS_N_TYPE,
636        handle,
637        previous_biases,
638        configuration.biases
639    );
640    update_bias!(
641        pixinvbn,
642        CHIP_BIAS_PIXINVBN,
643        BIAS_N_TYPE,
644        handle,
645        previous_biases,
646        configuration.biases
647    );
648    update_bias!(
649        prbp,
650        CHIP_BIAS_PRBP,
651        BIAS_P_TYPE,
652        handle,
653        previous_biases,
654        configuration.biases
655    );
656    update_bias!(
657        prsfbp,
658        CHIP_BIAS_PRSFBP,
659        BIAS_P_TYPE,
660        handle,
661        previous_biases,
662        configuration.biases
663    );
664    update_bias!(
665        refrbp,
666        CHIP_BIAS_REFRBP,
667        BIAS_P_TYPE,
668        handle,
669        previous_biases,
670        configuration.biases
671    );
672    update_bias!(
673        readoutbufbp,
674        CHIP_BIAS_READOUTBUFBP,
675        BIAS_P_TYPE,
676        handle,
677        previous_biases,
678        configuration.biases
679    );
680    update_bias!(
681        apsrosfbn,
682        CHIP_BIAS_APSROSFBN,
683        BIAS_N_TYPE,
684        handle,
685        previous_biases,
686        configuration.biases
687    );
688    update_bias!(
689        adccompbp,
690        CHIP_BIAS_ADCCOMPBP,
691        BIAS_P_TYPE,
692        handle,
693        previous_biases,
694        configuration.biases
695    );
696    update_bias!(
697        colsellowbn,
698        CHIP_BIAS_COLSELLOWBN,
699        BIAS_N_TYPE,
700        handle,
701        previous_biases,
702        configuration.biases
703    );
704    update_bias!(
705        dacbufbp,
706        CHIP_BIAS_DACBUFBP,
707        BIAS_P_TYPE,
708        handle,
709        previous_biases,
710        configuration.biases
711    );
712    update_bias!(
713        lcoltimeoutbn,
714        CHIP_BIAS_LCOLTIMEOUTBN,
715        BIAS_N_TYPE,
716        handle,
717        previous_biases,
718        configuration.biases
719    );
720    update_bias!(
721        aepdbn,
722        CHIP_BIAS_AEPDBN,
723        BIAS_N_TYPE,
724        handle,
725        previous_biases,
726        configuration.biases
727    );
728    update_bias!(
729        aepuxbp,
730        CHIP_BIAS_AEPUXBP,
731        BIAS_P_TYPE,
732        handle,
733        previous_biases,
734        configuration.biases
735    );
736    update_bias!(
737        aepuybp,
738        CHIP_BIAS_AEPUYBP,
739        BIAS_P_TYPE,
740        handle,
741        previous_biases,
742        configuration.biases
743    );
744    update_bias!(
745        ifrefrbn,
746        CHIP_BIAS_IFREFRBN,
747        BIAS_N_TYPE,
748        handle,
749        previous_biases,
750        configuration.biases
751    );
752    update_bias!(
753        ifthrbn,
754        CHIP_BIAS_IFTHRBN,
755        BIAS_N_TYPE,
756        handle,
757        previous_biases,
758        configuration.biases
759    );
760    update_bias!(
761        biasbuffer,
762        CHIP_BIAS_BUFFER,
763        BIAS_N_TYPE,
764        handle,
765        previous_biases,
766        configuration.biases
767    );
768
769    if has_pixel_filter {
770        if match previous_configuration {
771            Some(previous_configuration) => {
772                previous_configuration.pixel_mask != configuration.pixel_mask
773            }
774            None => true,
775        } {
776            for (index, code) in configuration.pixel_mask.iter().enumerate() {
777                let (x_value, y_value) = if *code == 0 {
778                    (PROPERTIES.width as u32, PROPERTIES.height as u32)
779                } else {
780                    (
781                        (code - 1) % PROPERTIES.width as u32,
782                        (code - 1) / PROPERTIES.width as u32,
783                    )
784                };
785                SpiRegister::new(ModuleAddress::Dvs, (11 + 2 * index) as u16)
786                    .set(handle, y_value)?;
787                SpiRegister::new(ModuleAddress::Dvs, (12 + 2 * index) as u16)
788                    .set(handle, x_value)?;
789            }
790        }
791    }
792
793    if has_activity_filter {
794        if match previous_configuration {
795            Some(previous_configuration) => {
796                previous_configuration.activity_filter != configuration.activity_filter
797            }
798            None => true,
799        } {
800            DVS_FILTER_BACKGROUND_ACTIVITY.set(
801                handle,
802                configuration.activity_filter.mask_isolated_enable as u32,
803            )?;
804            DVS_FILTER_BACKGROUND_ACTIVITY_TIME
805                .set(handle, configuration.activity_filter.mask_isolated_tau)?;
806            DVS_FILTER_REFRACTORY_PERIOD.set(
807                handle,
808                configuration.activity_filter.refractory_period_enable as u32,
809            )?;
810            DVS_FILTER_REFRACTORY_PERIOD_TIME
811                .set(handle, configuration.activity_filter.refractory_period_tau)?;
812        }
813    }
814
815    if has_roi_filter {
816        if match previous_configuration {
817            Some(previous_configuration) => {
818                previous_configuration.region_of_interest != configuration.region_of_interest
819            }
820            None => true,
821        } {
822            DVS_FILTER_ROI_START_COLUMN
823                .set(handle, configuration.region_of_interest.left as u32)?;
824            DVS_FILTER_ROI_START_ROW.set(handle, configuration.region_of_interest.top as u32)?;
825            DVS_FILTER_ROI_END_COLUMN.set(
826                handle,
827                (configuration.region_of_interest.left + configuration.region_of_interest.width)
828                    .min(PROPERTIES.width - 1) as u32,
829            )?;
830            DVS_FILTER_ROI_END_ROW.set(
831                handle,
832                (configuration.region_of_interest.top + configuration.region_of_interest.height)
833                    .min(PROPERTIES.height - 1) as u32,
834            )?;
835        }
836    }
837
838    if has_skip_filter {
839        if match previous_configuration {
840            Some(previous_configuration) => {
841                previous_configuration.skip_events_every != configuration.skip_events_every
842            }
843            None => true,
844        } {
845            DVS_FILTER_SKIP_EVENTS.set(handle, (configuration.skip_events_every > 0) as u32)?;
846            DVS_FILTER_SKIP_EVENTS_EVERY.set(handle, configuration.skip_events_every)?;
847        }
848    }
849
850    if has_polarity_filter {
851        if match previous_configuration {
852            Some(previous_configuration) => {
853                previous_configuration.polarity_filter != configuration.polarity_filter
854            }
855            None => true,
856        } {
857            DVS_FILTER_POLARITY_FLATTEN.set(
858                handle,
859                match configuration.polarity_filter {
860                    PolarityFilter::Flatten | PolarityFilter::MaskOffFlatten => 1,
861                    _ => 0,
862                },
863            )?;
864            DVS_FILTER_POLARITY_SUPPRESS.set(
865                handle,
866                match configuration.polarity_filter {
867                    PolarityFilter::MaskOn
868                    | PolarityFilter::MaskOff
869                    | PolarityFilter::MaskOffFlatten => 1,
870                    _ => 0,
871                },
872            )?;
873            DVS_FILTER_POLARITY_SUPPRESS_TYPE.set(
874                handle,
875                match configuration.polarity_filter {
876                    PolarityFilter::MaskOn => 1,
877                    _ => 0,
878                },
879            )?;
880        }
881    }
882
883    if has_roi_filter {
884        if match previous_configuration {
885            Some(previous_configuration) => {
886                previous_configuration.region_of_interest != configuration.region_of_interest
887            }
888            None => true,
889        } {
890            set_many(
891                handle,
892                &[
893                    (&APS_RUN, 0),
894                    (
895                        &APS_START_COLUMN_0,
896                        configuration.region_of_interest.left as u32,
897                    ),
898                    (
899                        &APS_START_ROW_0,
900                        configuration.region_of_interest.top as u32,
901                    ),
902                    (
903                        &APS_END_COLUMN_0,
904                        (configuration.region_of_interest.left
905                            + configuration.region_of_interest.width
906                            - 1)
907                        .min(345) as u32,
908                    ),
909                    (
910                        &APS_END_ROW_0,
911                        (configuration.region_of_interest.top
912                            + configuration.region_of_interest.height
913                            - 1)
914                        .min(259) as u32,
915                    ),
916                    (&APS_RUN, 0),
917                ],
918            )?;
919        }
920    }
921
922    if match previous_configuration {
923        Some(previous_configuration) => {
924            previous_configuration.exposure_us != configuration.exposure_us
925        }
926        None => true,
927    } {
928        APS_EXPOSURE.set(
929            handle,
930            (configuration.exposure_us as f64 * adc_clock).round() as u32,
931        )?;
932    }
933    if match previous_configuration {
934        Some(previous_configuration) => {
935            previous_configuration.frame_interval_us != configuration.frame_interval_us
936        }
937        None => true,
938    } {
939        APS_FRAME_INTERVAL.set(
940            handle,
941            (configuration.frame_interval_us as f64 * adc_clock).round() as u32,
942        )?;
943    }
944    Ok(())
945}
946
947struct ConfigurationUpdaterContext<IntoError, IntoWarning>
948where
949    IntoError: From<Error> + Clone + Send,
950    IntoWarning: From<crate::usb::Overflow> + Clone + Send,
951{
952    handle: std::sync::Arc<rusb::DeviceHandle<rusb::Context>>,
953    flag: flag::Flag<IntoError, IntoWarning>,
954    has_pixel_filter: bool,
955    has_activity_filter: bool,
956    has_roi_filter: bool,
957    has_skip_filter: bool,
958    has_polarity_filter: bool,
959    adc_clock: f64,
960}
961
962#[repr(u16)]
963#[derive(Clone, Copy)]
964enum ModuleAddress {
965    Multiplexer = 0,
966    Dvs = 1,
967    Aps = 2,
968    Imu = 3,
969    ExternalInput = 4,
970    Chip = 5,
971    SystemInformation = 6,
972    Usb = 9,
973}
974
975struct SpiRegister {
976    module_address: ModuleAddress,
977    parameter_address: u16,
978}
979
980struct SpiRegister64 {
981    module_address: ModuleAddress,
982    parameter_address: u16,
983}
984
985// multiplexer module registers
986const MULTIPLEXER_RUN: SpiRegister = SpiRegister::new(ModuleAddress::Multiplexer, 0);
987const MULTIPLEXER_TIMESTAMP_RUN: SpiRegister = SpiRegister::new(ModuleAddress::Multiplexer, 1);
988#[allow(dead_code)]
989const MULTIPLEXER_TIMESTAMP_RESET: SpiRegister = SpiRegister::new(ModuleAddress::Multiplexer, 2);
990const MULTIPLEXER_CHIP_RUN: SpiRegister = SpiRegister::new(ModuleAddress::Multiplexer, 3);
991const MULTIPLEXER_DROP_EXTERNAL_INPUT_ON_STALL: SpiRegister =
992    SpiRegister::new(ModuleAddress::Multiplexer, 4);
993const MULTIPLEXER_DROP_DVS_ON_STALL: SpiRegister = SpiRegister::new(ModuleAddress::Multiplexer, 5);
994#[allow(dead_code)]
995const MULTIPLEXER_HAS_STATISTICS: SpiRegister = SpiRegister::new(ModuleAddress::Multiplexer, 80);
996#[allow(dead_code)]
997const MULTIPLEXER_STATISTICS_EXTERNAL_INPUT_DROPPED: SpiRegister64 =
998    SpiRegister64::new(ModuleAddress::Multiplexer, 81);
999#[allow(dead_code)]
1000const MULTIPLEXER_STATISTICS_DVS_DROPPED: SpiRegister64 =
1001    SpiRegister64::new(ModuleAddress::Multiplexer, 83);
1002
1003// dvs module registers
1004const DVS_SIZE_COLUMNS: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 0);
1005const DVS_SIZE_ROWS: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 1);
1006const DVS_ORIENTATION: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 2);
1007const DVS_RUN: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 3);
1008const DVS_WAIT_ON_STALL: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 4);
1009const DVS_EXTERNAL_AER_CONTROL: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 5);
1010const DVS_HAS_PIXEL_FILTER: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 10);
1011const DVS_HAS_BACKGROUND_ACTIVITY_FILTER: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 30);
1012const DVS_FILTER_BACKGROUND_ACTIVITY: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 31);
1013const DVS_FILTER_BACKGROUND_ACTIVITY_TIME: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 32);
1014const DVS_FILTER_REFRACTORY_PERIOD: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 33);
1015const DVS_FILTER_REFRACTORY_PERIOD_TIME: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 34);
1016const DVS_HAS_ROI_FILTER: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 40);
1017const DVS_FILTER_ROI_START_COLUMN: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 41);
1018const DVS_FILTER_ROI_START_ROW: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 42);
1019const DVS_FILTER_ROI_END_COLUMN: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 43);
1020const DVS_FILTER_ROI_END_ROW: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 44);
1021const DVS_HAS_SKIP_FILTER: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 50);
1022const DVS_FILTER_SKIP_EVENTS: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 51);
1023const DVS_FILTER_SKIP_EVENTS_EVERY: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 52);
1024const DVS_HAS_POLARITY_FILTER: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 60);
1025const DVS_FILTER_POLARITY_FLATTEN: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 61);
1026const DVS_FILTER_POLARITY_SUPPRESS: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 62);
1027const DVS_FILTER_POLARITY_SUPPRESS_TYPE: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 63);
1028#[allow(dead_code)]
1029const DVS_HAS_STATISTICS: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 80);
1030#[allow(dead_code)]
1031const DVS_STATISTICS_EVENTS_ROW: SpiRegister64 = SpiRegister64::new(ModuleAddress::Dvs, 81);
1032#[allow(dead_code)]
1033const DVS_STATISTICS_EVENTS_COLUMN: SpiRegister64 = SpiRegister64::new(ModuleAddress::Dvs, 83);
1034#[allow(dead_code)]
1035const DVS_STATISTICS_EVENTS_DROPPED: SpiRegister64 = SpiRegister64::new(ModuleAddress::Dvs, 85);
1036#[allow(dead_code)]
1037const DVS_STATISTICS_FILTERED_PIXELS: SpiRegister64 = SpiRegister64::new(ModuleAddress::Dvs, 87);
1038#[allow(dead_code)]
1039const DVS_STATISTICS_FILTERED_BACKGROUND_ACTIVITY: SpiRegister64 =
1040    SpiRegister64::new(ModuleAddress::Dvs, 89);
1041#[allow(dead_code)]
1042const DVS_STATISTICS_FILTERED_REFRACTORY_PERIOD: SpiRegister64 =
1043    SpiRegister64::new(ModuleAddress::Dvs, 91);
1044#[allow(dead_code)]
1045const DVS_FILTER_PIXEL_AUTO_TRAIN: SpiRegister = SpiRegister::new(ModuleAddress::Dvs, 100);
1046
1047// aps module registers
1048const APS_SIZE_COLUMNS: SpiRegister = SpiRegister::new(ModuleAddress::Aps, 0);
1049const APS_SIZE_ROWS: SpiRegister = SpiRegister::new(ModuleAddress::Aps, 1);
1050const APS_ORIENTATION: SpiRegister = SpiRegister::new(ModuleAddress::Aps, 2);
1051#[allow(dead_code)]
1052const APS_COLOR_FILTER: SpiRegister = SpiRegister::new(ModuleAddress::Aps, 3);
1053const APS_RUN: SpiRegister = SpiRegister::new(ModuleAddress::Aps, 4);
1054const APS_WAIT_ON_STALL: SpiRegister = SpiRegister::new(ModuleAddress::Aps, 5);
1055const APS_HAS_GLOBAL_SHUTTER: SpiRegister = SpiRegister::new(ModuleAddress::Aps, 6);
1056const APS_GLOBAL_SHUTTER: SpiRegister = SpiRegister::new(ModuleAddress::Aps, 7);
1057const APS_START_COLUMN_0: SpiRegister = SpiRegister::new(ModuleAddress::Aps, 8);
1058const APS_START_ROW_0: SpiRegister = SpiRegister::new(ModuleAddress::Aps, 9);
1059const APS_END_COLUMN_0: SpiRegister = SpiRegister::new(ModuleAddress::Aps, 10);
1060const APS_END_ROW_0: SpiRegister = SpiRegister::new(ModuleAddress::Aps, 11);
1061const APS_EXPOSURE: SpiRegister = SpiRegister::new(ModuleAddress::Aps, 12);
1062const APS_FRAME_INTERVAL: SpiRegister = SpiRegister::new(ModuleAddress::Aps, 13);
1063#[allow(dead_code)]
1064const APS_AUTOEXPOSURE: SpiRegister = SpiRegister::new(ModuleAddress::Aps, 101);
1065#[allow(dead_code)]
1066const APS_FRAME_MODE: SpiRegister = SpiRegister::new(ModuleAddress::Aps, 102);
1067
1068// imu module registers
1069const IMU_TYPE: SpiRegister = SpiRegister::new(ModuleAddress::Imu, 0);
1070const IMU_ORIENTATION: SpiRegister = SpiRegister::new(ModuleAddress::Imu, 1);
1071const IMU_ACCELEROMETER_RUN: SpiRegister = SpiRegister::new(ModuleAddress::Imu, 2);
1072const IMU_GYROSCOPE_RUN: SpiRegister = SpiRegister::new(ModuleAddress::Imu, 3);
1073const IMU_TEMPERATURE_RUN: SpiRegister = SpiRegister::new(ModuleAddress::Imu, 4);
1074const IMU_SAMPLE_RATE_DIVIDER: SpiRegister = SpiRegister::new(ModuleAddress::Imu, 5);
1075const IMU_ACCELEROMETER_DIGITAL_LOW_PASS_FILTER: SpiRegister =
1076    SpiRegister::new(ModuleAddress::Imu, 6);
1077const IMU_ACCELEROMETER_FULL_SCALE: SpiRegister = SpiRegister::new(ModuleAddress::Imu, 7);
1078const IMU_GYROSCOPE_DIGITAL_LOW_PASS_FILTER: SpiRegister = SpiRegister::new(ModuleAddress::Imu, 9);
1079const IMU_GYROSCOPE_FULL_SCALE: SpiRegister = SpiRegister::new(ModuleAddress::Imu, 10);
1080
1081// external input module registers
1082const EXTERNAL_INPUT_DETECTOR_RUN: SpiRegister = SpiRegister::new(ModuleAddress::ExternalInput, 0);
1083const EXTERNAL_INPUT_DETECT_RISING_EDGES: SpiRegister =
1084    SpiRegister::new(ModuleAddress::ExternalInput, 1);
1085const EXTERNAL_INPUT_DETECT_FALLING_EDGES: SpiRegister =
1086    SpiRegister::new(ModuleAddress::ExternalInput, 2);
1087const EXTERNAL_INPUT_DETECT_PULSES: SpiRegister = SpiRegister::new(ModuleAddress::ExternalInput, 3);
1088const EXTERNAL_INPUT_DETECT_PULSE_POLARITY: SpiRegister =
1089    SpiRegister::new(ModuleAddress::ExternalInput, 4);
1090const EXTERNAL_INPUT_DETECT_PULSE_LENGTH: SpiRegister =
1091    SpiRegister::new(ModuleAddress::ExternalInput, 5);
1092#[allow(dead_code)]
1093const EXTERNAL_INPUT_HAS_GENERATOR: SpiRegister =
1094    SpiRegister::new(ModuleAddress::ExternalInput, 10);
1095const EXTERNAL_INPUT_GENERATOR_RUN: SpiRegister =
1096    SpiRegister::new(ModuleAddress::ExternalInput, 11);
1097#[allow(dead_code)]
1098const EXTERNAL_INPUT_GENERATE_PULSE_POLARITY: SpiRegister =
1099    SpiRegister::new(ModuleAddress::ExternalInput, 12);
1100const EXTERNAL_INPUT_GENERATE_PULSE_INTERVAL: SpiRegister =
1101    SpiRegister::new(ModuleAddress::ExternalInput, 13);
1102const EXTERNAL_INPUT_GENERATE_PULSE_LENGTH: SpiRegister =
1103    SpiRegister::new(ModuleAddress::ExternalInput, 14);
1104const EXTERNAL_INPUT_GENERATE_INJECT_ON_RISING_EDGE: SpiRegister =
1105    SpiRegister::new(ModuleAddress::ExternalInput, 15);
1106const EXTERNAL_INPUT_GENERATE_INJECT_ON_FALLING_EDGE: SpiRegister =
1107    SpiRegister::new(ModuleAddress::ExternalInput, 16);
1108
1109// chip module registers
1110const CHIP_BIAS_APSOVERFLOWLEVEL: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 0);
1111const CHIP_BIAS_APSCAS: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 1);
1112const CHIP_BIAS_ADCREFHIGH: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 2);
1113const CHIP_BIAS_ADCREFLOW: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 3);
1114const CHIP_BIAS_ADCTESTVOLTAGE: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 4);
1115const CHIP_BIAS_LOCALBUFBN: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 8);
1116const CHIP_BIAS_PADFOLLBN: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 9);
1117const CHIP_BIAS_DIFFBN: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 10);
1118const CHIP_BIAS_ONBN: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 11);
1119const CHIP_BIAS_OFFBN: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 12);
1120const CHIP_BIAS_PIXINVBN: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 13);
1121const CHIP_BIAS_PRBP: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 14);
1122const CHIP_BIAS_PRSFBP: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 15);
1123const CHIP_BIAS_REFRBP: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 16);
1124const CHIP_BIAS_READOUTBUFBP: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 17);
1125const CHIP_BIAS_APSROSFBN: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 18);
1126const CHIP_BIAS_ADCCOMPBP: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 19);
1127const CHIP_BIAS_COLSELLOWBN: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 20);
1128const CHIP_BIAS_DACBUFBP: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 21);
1129const CHIP_BIAS_LCOLTIMEOUTBN: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 22);
1130const CHIP_BIAS_AEPDBN: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 23);
1131const CHIP_BIAS_AEPUXBP: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 24);
1132const CHIP_BIAS_AEPUYBP: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 25);
1133const CHIP_BIAS_IFREFRBN: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 26);
1134const CHIP_BIAS_IFTHRBN: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 27);
1135const CHIP_BIAS_BUFFER: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 34);
1136const CHIP_BIAS_SSP: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 35);
1137const CHIP_BIAS_SSN: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 36);
1138const CHIP_DIGITALMUX0: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 128);
1139const CHIP_DIGITALMUX1: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 129);
1140const CHIP_DIGITALMUX2: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 130);
1141const CHIP_DIGITALMUX3: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 131);
1142const CHIP_ANALOGMUX0: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 132);
1143const CHIP_ANALOGMUX1: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 133);
1144const CHIP_ANALOGMUX2: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 134);
1145const CHIP_BIASMUX0: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 135);
1146const CHIP_RESETCALIBNEURON: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 136);
1147const CHIP_TYPENCALIBNEURON: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 137);
1148const CHIP_RESETTESTPIXEL: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 138);
1149#[allow(dead_code)]
1150const CHIP_SPECIALPIXELCONTROL: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 139);
1151const CHIP_AERNAROW: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 140);
1152const CHIP_USEAOUT: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 141);
1153const CHIP_GLOBAL_SHUTTER: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 142);
1154const CHIP_SELECTGRAYCOUNTER: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 143);
1155const CHIP_TESTADC: SpiRegister = SpiRegister::new(ModuleAddress::Chip, 144);
1156
1157// system information module registers
1158const LOGIC_VERSION: SpiRegister = SpiRegister::new(ModuleAddress::SystemInformation, 0);
1159#[allow(dead_code)]
1160const CHIP_IDENTIFIER: SpiRegister = SpiRegister::new(ModuleAddress::SystemInformation, 1);
1161#[allow(dead_code)]
1162const CHIP_IS_PRIMARY: SpiRegister = SpiRegister::new(ModuleAddress::SystemInformation, 2);
1163const LOGIC_CLOCK: SpiRegister = SpiRegister::new(ModuleAddress::SystemInformation, 3);
1164const ADC_CLOCK: SpiRegister = SpiRegister::new(ModuleAddress::SystemInformation, 4);
1165const USB_CLOCK: SpiRegister = SpiRegister::new(ModuleAddress::SystemInformation, 5);
1166const CLOCK_DEVIATION: SpiRegister = SpiRegister::new(ModuleAddress::SystemInformation, 6);
1167const LOGIC_PATCH: SpiRegister = SpiRegister::new(ModuleAddress::SystemInformation, 7);
1168
1169// usb module registers
1170const USB_RUN: SpiRegister = SpiRegister::new(ModuleAddress::Usb, 0);
1171const USB_EARLY_PACKET_DELAY: SpiRegister = SpiRegister::new(ModuleAddress::Usb, 1);
1172
1173impl SpiRegister {
1174    fn get(&self, handle: &rusb::DeviceHandle<rusb::Context>) -> Result<u32, Error> {
1175        let mut buffer = [0; 4];
1176        let count = handle.read_control(
1177            0xC0,
1178            0xBF,
1179            self.module_address as u16,
1180            self.parameter_address,
1181            &mut buffer,
1182            TIMEOUT,
1183        )?;
1184        if count != 4 {
1185            return Err(Error::ShortRead {
1186                module_address: self.module_address as u16,
1187                parameter_address: self.parameter_address,
1188                expected: 4,
1189                count,
1190            });
1191        }
1192        Ok(u32::from_be_bytes(buffer))
1193    }
1194
1195    fn set(&self, handle: &rusb::DeviceHandle<rusb::Context>, value: u32) -> Result<(), Error> {
1196        let buffer = value.to_be_bytes();
1197        let count = handle.write_control(
1198            0x40,
1199            0xBF,
1200            self.module_address as u16,
1201            self.parameter_address,
1202            &buffer,
1203            TIMEOUT,
1204        )?;
1205        if count != 4 {
1206            return Err(Error::ShortWrite {
1207                module_address: self.module_address as u16,
1208                parameter_address: self.parameter_address,
1209                expected: 4,
1210                count,
1211            });
1212        }
1213        Ok(())
1214    }
1215
1216    const fn new(module_address: ModuleAddress, parameter_address: u16) -> Self {
1217        Self {
1218            module_address,
1219            parameter_address,
1220        }
1221    }
1222}
1223
1224impl SpiRegister64 {
1225    #[allow(dead_code)]
1226    fn get(&self, handle: &rusb::DeviceHandle<rusb::Context>) -> Result<u64, Error> {
1227        let msb = SpiRegister {
1228            module_address: self.module_address,
1229            parameter_address: self.parameter_address,
1230        }
1231        .get(handle)?;
1232        let lsb = SpiRegister {
1233            module_address: self.module_address,
1234            parameter_address: self.parameter_address + 1,
1235        }
1236        .get(handle)?;
1237        Ok(((msb as u64) << 32) | (lsb as u64))
1238    }
1239
1240    const fn new(module_address: ModuleAddress, parameter_address: u16) -> Self {
1241        Self {
1242            module_address,
1243            parameter_address,
1244        }
1245    }
1246}
1247
1248fn set_many(
1249    handle: &rusb::DeviceHandle<rusb::Context>,
1250    registers_and_values: &[(&SpiRegister, u32)],
1251) -> Result<(), Error> {
1252    let mut buffer = vec![0; 6 * registers_and_values.len()];
1253    for (index, (register, value)) in registers_and_values.iter().enumerate() {
1254        buffer[index * 6] = register.module_address as u8;
1255        buffer[index * 6 + 1] = register.parameter_address as u8;
1256        buffer[index * 6 + 2..index * 6 + 6].copy_from_slice(&value.to_be_bytes());
1257    }
1258    let count = handle.write_control(0x40, 0xC2, 0x0006, 0x0000, &buffer, TIMEOUT)?;
1259    if count != buffer.len() {
1260        return Err(Error::ShortWrite {
1261            module_address: 0x0006,
1262            parameter_address: 0x0000,
1263            expected: buffer.len(),
1264            count,
1265        });
1266    }
1267    Ok(())
1268}
1269
1270// The bias current i is given by
1271//     i = C[coarse] * (fine / 255.0)
1272// where:
1273//     - C = [11, 94, 756, 6054, 48437, 387500, 3100000, 24800000] (in pA)
1274//     - coarse, in [0, 7], is the bias coarse value sent to the camera
1275//     - fine, in [0, 255], is the bias fine value sent to the camera
1276// "fine" may only be 0 if "coarse" is 0 as well
1277//
1278// Bias currents are monotonic for a given coarse value,
1279// but not monotonic across them (https://doi.org/10.1109/ISCAS.2012.6271979)
1280// To simplify the user interface,
1281// we re-order the 2041 allowed pairs (coarse, fine) so that the output currents are monotonic.
1282// Users thus have a single interger field to tweak.
1283#[rustfmt::skip]
1284const COARSE_FINE_MAP: [(u8, u8); 2041] = [
1285    (0,   0), (0,   1), (0,   2), (0,   3), (0,   4), (0,   5), (0,   6), (0,   7),
1286    (0,   8), (1,   1), (0,   9), (0,  10), (0,  11), (0,  12), (0,  13), (0,  14),
1287    (0,  15), (0,  16), (0,  17), (1,   2), (0,  18), (0,  19), (0,  20), (0,  21),
1288    (0,  22), (0,  23), (0,  24), (0,  25), (1,   3), (0,  26), (0,  27), (0,  28),
1289    (0,  29), (0,  30), (0,  31), (0,  32), (0,  33), (0,  34), (1,   4), (0,  35),
1290    (0,  36), (0,  37), (0,  38), (0,  39), (0,  40), (0,  41), (0,  42), (1,   5),
1291    (0,  43), (0,  44), (0,  45), (0,  46), (0,  47), (0,  48), (0,  49), (0,  50),
1292    (0,  51), (1,   6), (0,  52), (0,  53), (0,  54), (0,  55), (0,  56), (0,  57),
1293    (0,  58), (0,  59), (1,   7), (0,  60), (0,  61), (0,  62), (0,  63), (0,  64),
1294    (0,  65), (0,  66), (0,  67), (0,  68), (1,   8), (2,   1), (0,  69), (0,  70),
1295    (0,  71), (0,  72), (0,  73), (0,  74), (0,  75), (0,  76), (1,   9), (0,  77),
1296    (0,  78), (0,  79), (0,  80), (0,  81), (0,  82), (0,  83), (0,  84), (0,  85),
1297    (1,  10), (0,  86), (0,  87), (0,  88), (0,  89), (0,  90), (0,  91), (0,  92),
1298    (0,  93), (0,  94), (1,  11), (0,  95), (0,  96), (0,  97), (0,  98), (0,  99),
1299    (0, 100), (0, 101), (0, 102), (1,  12), (0, 103), (0, 104), (0, 105), (0, 106),
1300    (0, 107), (0, 108), (0, 109), (0, 110), (0, 111), (1,  13), (0, 112), (0, 113),
1301    (0, 114), (0, 115), (0, 116), (0, 117), (0, 118), (0, 119), (1,  14), (0, 120),
1302    (0, 121), (0, 122), (0, 123), (0, 124), (0, 125), (0, 126), (0, 127), (0, 128),
1303    (1,  15), (0, 129), (0, 130), (0, 131), (0, 132), (0, 133), (0, 134), (0, 135),
1304    (0, 136), (1,  16), (0, 137), (2,   2), (0, 138), (0, 139), (0, 140), (0, 141),
1305    (0, 142), (0, 143), (0, 144), (0, 145), (1,  17), (0, 146), (0, 147), (0, 148),
1306    (0, 149), (0, 150), (0, 151), (0, 152), (0, 153), (1,  18), (0, 154), (0, 155),
1307    (0, 156), (0, 157), (0, 158), (0, 159), (0, 160), (0, 161), (0, 162), (1,  19),
1308    (0, 163), (0, 164), (0, 165), (0, 166), (0, 167), (0, 168), (0, 169), (0, 170),
1309    (1,  20), (0, 171), (0, 172), (0, 173), (0, 174), (0, 175), (0, 176), (0, 177),
1310    (0, 178), (0, 179), (1,  21), (0, 180), (0, 181), (0, 182), (0, 183), (0, 184),
1311    (0, 185), (0, 186), (0, 187), (0, 188), (1,  22), (0, 189), (0, 190), (0, 191),
1312    (0, 192), (0, 193), (0, 194), (0, 195), (0, 196), (1,  23), (0, 197), (0, 198),
1313    (0, 199), (0, 200), (0, 201), (0, 202), (0, 203), (0, 204), (0, 205), (1,  24),
1314    (0, 206), (2,   3), (0, 207), (0, 208), (0, 209), (0, 210), (0, 211), (0, 212),
1315    (0, 213), (1,  25), (0, 214), (0, 215), (0, 216), (0, 217), (0, 218), (0, 219),
1316    (0, 220), (0, 221), (0, 222), (1,  26), (0, 223), (0, 224), (0, 225), (0, 226),
1317    (0, 227), (0, 228), (0, 229), (0, 230), (1,  27), (0, 231), (0, 232), (0, 233),
1318    (0, 234), (0, 235), (0, 236), (0, 237), (0, 238), (0, 239), (1,  28), (0, 240),
1319    (0, 241), (0, 242), (0, 243), (0, 244), (0, 245), (0, 246), (0, 247), (1,  29),
1320    (0, 248), (0, 249), (0, 250), (0, 251), (0, 252), (0, 253), (0, 254), (0, 255),
1321    (1,  30), (1,  31), (1,  32), (2,   4), (1,  33), (1,  34), (1,  35), (1,  36),
1322    (1,  37), (1,  38), (1,  39), (1,  40), (2,   5), (1,  41), (1,  42), (1,  43),
1323    (1,  44), (1,  45), (1,  46), (1,  47), (1,  48), (2,   6), (1,  49), (1,  50),
1324    (1,  51), (1,  52), (1,  53), (1,  54), (1,  55), (1,  56), (2,   7), (1,  57),
1325    (1,  58), (1,  59), (1,  60), (1,  61), (1,  62), (1,  63), (1,  64), (2,   8),
1326    (3,   1), (1,  65), (1,  66), (1,  67), (1,  68), (1,  69), (1,  70), (1,  71),
1327    (1,  72), (2,   9), (1,  73), (1,  74), (1,  75), (1,  76), (1,  77), (1,  78),
1328    (1,  79), (1,  80), (2,  10), (1,  81), (1,  82), (1,  83), (1,  84), (1,  85),
1329    (1,  86), (1,  87), (1,  88), (2,  11), (1,  89), (1,  90), (1,  91), (1,  92),
1330    (1,  93), (1,  94), (1,  95), (1,  96), (2,  12), (1,  97), (1,  98), (1,  99),
1331    (1, 100), (1, 101), (1, 102), (1, 103), (1, 104), (2,  13), (1, 105), (1, 106),
1332    (1, 107), (1, 108), (1, 109), (1, 110), (1, 111), (1, 112), (2,  14), (1, 113),
1333    (1, 114), (1, 115), (1, 116), (1, 117), (1, 118), (1, 119), (1, 120), (2,  15),
1334    (1, 121), (1, 122), (1, 123), (1, 124), (1, 125), (1, 126), (1, 127), (1, 128),
1335    (2,  16), (3,   2), (1, 129), (1, 130), (1, 131), (1, 132), (1, 133), (1, 134),
1336    (1, 135), (1, 136), (2,  17), (1, 137), (1, 138), (1, 139), (1, 140), (1, 141),
1337    (1, 142), (1, 143), (1, 144), (2,  18), (1, 145), (1, 146), (1, 147), (1, 148),
1338    (1, 149), (1, 150), (1, 151), (1, 152), (2,  19), (1, 153), (1, 154), (1, 155),
1339    (1, 156), (1, 157), (1, 158), (1, 159), (1, 160), (2,  20), (1, 161), (1, 162),
1340    (1, 163), (1, 164), (1, 165), (1, 166), (1, 167), (1, 168), (2,  21), (1, 169),
1341    (1, 170), (1, 171), (1, 172), (1, 173), (1, 174), (1, 175), (1, 176), (2,  22),
1342    (1, 177), (1, 178), (1, 179), (1, 180), (1, 181), (1, 182), (1, 183), (1, 184),
1343    (2,  23), (1, 185), (1, 186), (1, 187), (1, 188), (1, 189), (1, 190), (1, 191),
1344    (1, 192), (1, 193), (2,  24), (3,   3), (1, 194), (1, 195), (1, 196), (1, 197),
1345    (1, 198), (1, 199), (1, 200), (1, 201), (2,  25), (1, 202), (1, 203), (1, 204),
1346    (1, 205), (1, 206), (1, 207), (1, 208), (1, 209), (2,  26), (1, 210), (1, 211),
1347    (1, 212), (1, 213), (1, 214), (1, 215), (1, 216), (1, 217), (2,  27), (1, 218),
1348    (1, 219), (1, 220), (1, 221), (1, 222), (1, 223), (1, 224), (1, 225), (2,  28),
1349    (1, 226), (1, 227), (1, 228), (1, 229), (1, 230), (1, 231), (1, 232), (1, 233),
1350    (2,  29), (1, 234), (1, 235), (1, 236), (1, 237), (1, 238), (1, 239), (1, 240),
1351    (1, 241), (2,  30), (1, 242), (1, 243), (1, 244), (1, 245), (1, 246), (1, 247),
1352    (1, 248), (1, 249), (2,  31), (1, 250), (1, 251), (1, 252), (1, 253), (1, 254),
1353    (1, 255), (2,  32), (3,   4), (2,  33), (2,  34), (2,  35), (2,  36), (2,  37),
1354    (2,  38), (2,  39), (2,  40), (3,   5), (2,  41), (2,  42), (2,  43), (2,  44),
1355    (2,  45), (2,  46), (2,  47), (2,  48), (3,   6), (2,  49), (2,  50), (2,  51),
1356    (2,  52), (2,  53), (2,  54), (2,  55), (2,  56), (3,   7), (2,  57), (2,  58),
1357    (2,  59), (2,  60), (2,  61), (2,  62), (2,  63), (2,  64), (3,   8), (4,   1),
1358    (2,  65), (2,  66), (2,  67), (2,  68), (2,  69), (2,  70), (2,  71), (2,  72),
1359    (3,   9), (2,  73), (2,  74), (2,  75), (2,  76), (2,  77), (2,  78), (2,  79),
1360    (2,  80), (3,  10), (2,  81), (2,  82), (2,  83), (2,  84), (2,  85), (2,  86),
1361    (2,  87), (2,  88), (3,  11), (2,  89), (2,  90), (2,  91), (2,  92), (2,  93),
1362    (2,  94), (2,  95), (2,  96), (3,  12), (2,  97), (2,  98), (2,  99), (2, 100),
1363    (2, 101), (2, 102), (2, 103), (2, 104), (3,  13), (2, 105), (2, 106), (2, 107),
1364    (2, 108), (2, 109), (2, 110), (2, 111), (2, 112), (3,  14), (2, 113), (2, 114),
1365    (2, 115), (2, 116), (2, 117), (2, 118), (2, 119), (2, 120), (3,  15), (2, 121),
1366    (2, 122), (2, 123), (2, 124), (2, 125), (2, 126), (2, 127), (2, 128), (3,  16),
1367    (4,   2), (2, 129), (2, 130), (2, 131), (2, 132), (2, 133), (2, 134), (2, 135),
1368    (2, 136), (3,  17), (2, 137), (2, 138), (2, 139), (2, 140), (2, 141), (2, 142),
1369    (2, 143), (2, 144), (3,  18), (2, 145), (2, 146), (2, 147), (2, 148), (2, 149),
1370    (2, 150), (2, 151), (2, 152), (3,  19), (2, 153), (2, 154), (2, 155), (2, 156),
1371    (2, 157), (2, 158), (2, 159), (2, 160), (3,  20), (2, 161), (2, 162), (2, 163),
1372    (2, 164), (2, 165), (2, 166), (2, 167), (2, 168), (3,  21), (2, 169), (2, 170),
1373    (2, 171), (2, 172), (2, 173), (2, 174), (2, 175), (2, 176), (3,  22), (2, 177),
1374    (2, 178), (2, 179), (2, 180), (2, 181), (2, 182), (2, 183), (2, 184), (3,  23),
1375    (2, 185), (2, 186), (2, 187), (2, 188), (2, 189), (2, 190), (2, 191), (2, 192),
1376    (3,  24), (4,   3), (2, 193), (2, 194), (2, 195), (2, 196), (2, 197), (2, 198),
1377    (2, 199), (2, 200), (3,  25), (2, 201), (2, 202), (2, 203), (2, 204), (2, 205),
1378    (2, 206), (2, 207), (2, 208), (3,  26), (2, 209), (2, 210), (2, 211), (2, 212),
1379    (2, 213), (2, 214), (2, 215), (2, 216), (3,  27), (2, 217), (2, 218), (2, 219),
1380    (2, 220), (2, 221), (2, 222), (2, 223), (2, 224), (3,  28), (2, 225), (2, 226),
1381    (2, 227), (2, 228), (2, 229), (2, 230), (2, 231), (2, 232), (3,  29), (2, 233),
1382    (2, 234), (2, 235), (2, 236), (2, 237), (2, 238), (2, 239), (2, 240), (3,  30),
1383    (2, 241), (2, 242), (2, 243), (2, 244), (2, 245), (2, 246), (2, 247), (2, 248),
1384    (3,  31), (2, 249), (2, 250), (2, 251), (2, 252), (2, 253), (2, 254), (2, 255),
1385    (3,  32), (4,   4), (3,  33), (3,  34), (3,  35), (3,  36), (3,  37), (3,  38),
1386    (3,  39), (3,  40), (4,   5), (3,  41), (3,  42), (3,  43), (3,  44), (3,  45),
1387    (3,  46), (3,  47), (3,  48), (4,   6), (3,  49), (3,  50), (3,  51), (3,  52),
1388    (3,  53), (3,  54), (3,  55), (3,  56), (4,   7), (3,  57), (3,  58), (3,  59),
1389    (3,  60), (3,  61), (3,  62), (3,  63), (3,  64), (4,   8), (5,   1), (3,  65),
1390    (3,  66), (3,  67), (3,  68), (3,  69), (3,  70), (3,  71), (3,  72), (4,   9),
1391    (3,  73), (3,  74), (3,  75), (3,  76), (3,  77), (3,  78), (3,  79), (3,  80),
1392    (4,  10), (3,  81), (3,  82), (3,  83), (3,  84), (3,  85), (3,  86), (3,  87),
1393    (3,  88), (4,  11), (3,  89), (3,  90), (3,  91), (3,  92), (3,  93), (3,  94),
1394    (3,  95), (3,  96), (4,  12), (3,  97), (3,  98), (3,  99), (3, 100), (3, 101),
1395    (3, 102), (3, 103), (3, 104), (4,  13), (3, 105), (3, 106), (3, 107), (3, 108),
1396    (3, 109), (3, 110), (3, 111), (3, 112), (4,  14), (3, 113), (3, 114), (3, 115),
1397    (3, 116), (3, 117), (3, 118), (3, 119), (3, 120), (4,  15), (3, 121), (3, 122),
1398    (3, 123), (3, 124), (3, 125), (3, 126), (3, 127), (3, 128), (4,  16), (5,   2),
1399    (3, 129), (3, 130), (3, 131), (3, 132), (3, 133), (3, 134), (3, 135), (3, 136),
1400    (4,  17), (3, 137), (3, 138), (3, 139), (3, 140), (3, 141), (3, 142), (3, 143),
1401    (3, 144), (4,  18), (3, 145), (3, 146), (3, 147), (3, 148), (3, 149), (3, 150),
1402    (3, 151), (3, 152), (4,  19), (3, 153), (3, 154), (3, 155), (3, 156), (3, 157),
1403    (3, 158), (3, 159), (3, 160), (4,  20), (3, 161), (3, 162), (3, 163), (3, 164),
1404    (3, 165), (3, 166), (3, 167), (3, 168), (4,  21), (3, 169), (3, 170), (3, 171),
1405    (3, 172), (3, 173), (3, 174), (3, 175), (3, 176), (4,  22), (3, 177), (3, 178),
1406    (3, 179), (3, 180), (3, 181), (3, 182), (3, 183), (3, 184), (4,  23), (3, 185),
1407    (3, 186), (3, 187), (3, 188), (3, 189), (3, 190), (3, 191), (3, 192), (4,  24),
1408    (5,   3), (3, 193), (3, 194), (3, 195), (3, 196), (3, 197), (3, 198), (3, 199),
1409    (3, 200), (4,  25), (3, 201), (3, 202), (3, 203), (3, 204), (3, 205), (3, 206),
1410    (3, 207), (3, 208), (4,  26), (3, 209), (3, 210), (3, 211), (3, 212), (3, 213),
1411    (3, 214), (3, 215), (3, 216), (4,  27), (3, 217), (3, 218), (3, 219), (3, 220),
1412    (3, 221), (3, 222), (3, 223), (3, 224), (4,  28), (3, 225), (3, 226), (3, 227),
1413    (3, 228), (3, 229), (3, 230), (3, 231), (3, 232), (4,  29), (3, 233), (3, 234),
1414    (3, 235), (3, 236), (3, 237), (3, 238), (3, 239), (3, 240), (4,  30), (3, 241),
1415    (3, 242), (3, 243), (3, 244), (3, 245), (3, 246), (3, 247), (3, 248), (4,  31),
1416    (3, 249), (3, 250), (3, 251), (3, 252), (3, 253), (3, 254), (3, 255), (4,  32),
1417    (5,   4), (4,  33), (4,  34), (4,  35), (4,  36), (4,  37), (4,  38), (4,  39),
1418    (4,  40), (5,   5), (4,  41), (4,  42), (4,  43), (4,  44), (4,  45), (4,  46),
1419    (4,  47), (4,  48), (5,   6), (4,  49), (4,  50), (4,  51), (4,  52), (4,  53),
1420    (4,  54), (4,  55), (4,  56), (5,   7), (4,  57), (4,  58), (4,  59), (4,  60),
1421    (4,  61), (4,  62), (4,  63), (4,  64), (5,   8), (6,   1), (4,  65), (4,  66),
1422    (4,  67), (4,  68), (4,  69), (4,  70), (4,  71), (4,  72), (5,   9), (4,  73),
1423    (4,  74), (4,  75), (4,  76), (4,  77), (4,  78), (4,  79), (4,  80), (5,  10),
1424    (4,  81), (4,  82), (4,  83), (4,  84), (4,  85), (4,  86), (4,  87), (4,  88),
1425    (5,  11), (4,  89), (4,  90), (4,  91), (4,  92), (4,  93), (4,  94), (4,  95),
1426    (4,  96), (5,  12), (4,  97), (4,  98), (4,  99), (4, 100), (4, 101), (4, 102),
1427    (4, 103), (4, 104), (5,  13), (4, 105), (4, 106), (4, 107), (4, 108), (4, 109),
1428    (4, 110), (4, 111), (4, 112), (5,  14), (4, 113), (4, 114), (4, 115), (4, 116),
1429    (4, 117), (4, 118), (4, 119), (4, 120), (5,  15), (4, 121), (4, 122), (4, 123),
1430    (4, 124), (4, 125), (4, 126), (4, 127), (4, 128), (5,  16), (6,   2), (4, 129),
1431    (4, 130), (4, 131), (4, 132), (4, 133), (4, 134), (4, 135), (4, 136), (5,  17),
1432    (4, 137), (4, 138), (4, 139), (4, 140), (4, 141), (4, 142), (4, 143), (4, 144),
1433    (5,  18), (4, 145), (4, 146), (4, 147), (4, 148), (4, 149), (4, 150), (4, 151),
1434    (4, 152), (5,  19), (4, 153), (4, 154), (4, 155), (4, 156), (4, 157), (4, 158),
1435    (4, 159), (4, 160), (5,  20), (4, 161), (4, 162), (4, 163), (4, 164), (4, 165),
1436    (4, 166), (4, 167), (4, 168), (5,  21), (4, 169), (4, 170), (4, 171), (4, 172),
1437    (4, 173), (4, 174), (4, 175), (4, 176), (5,  22), (4, 177), (4, 178), (4, 179),
1438    (4, 180), (4, 181), (4, 182), (4, 183), (4, 184), (5,  23), (4, 185), (4, 186),
1439    (4, 187), (4, 188), (4, 189), (4, 190), (4, 191), (4, 192), (5,  24), (6,   3),
1440    (4, 193), (4, 194), (4, 195), (4, 196), (4, 197), (4, 198), (4, 199), (4, 200),
1441    (5,  25), (4, 201), (4, 202), (4, 203), (4, 204), (4, 205), (4, 206), (4, 207),
1442    (4, 208), (5,  26), (4, 209), (4, 210), (4, 211), (4, 212), (4, 213), (4, 214),
1443    (4, 215), (4, 216), (5,  27), (4, 217), (4, 218), (4, 219), (4, 220), (4, 221),
1444    (4, 222), (4, 223), (4, 224), (5,  28), (4, 225), (4, 226), (4, 227), (4, 228),
1445    (4, 229), (4, 230), (4, 231), (4, 232), (5,  29), (4, 233), (4, 234), (4, 235),
1446    (4, 236), (4, 237), (4, 238), (4, 239), (4, 240), (5,  30), (4, 241), (4, 242),
1447    (4, 243), (4, 244), (4, 245), (4, 246), (4, 247), (4, 248), (5,  31), (4, 249),
1448    (4, 250), (4, 251), (4, 252), (4, 253), (4, 254), (4, 255), (5,  32), (6,   4),
1449    (5,  33), (5,  34), (5,  35), (5,  36), (5,  37), (5,  38), (5,  39), (5,  40),
1450    (6,   5), (5,  41), (5,  42), (5,  43), (5,  44), (5,  45), (5,  46), (5,  47),
1451    (5,  48), (6,   6), (5,  49), (5,  50), (5,  51), (5,  52), (5,  53), (5,  54),
1452    (5,  55), (5,  56), (6,   7), (5,  57), (5,  58), (5,  59), (5,  60), (5,  61),
1453    (5,  62), (5,  63), (5,  64), (6,   8), (7,   1), (5,  65), (5,  66), (5,  67),
1454    (5,  68), (5,  69), (5,  70), (5,  71), (5,  72), (6,   9), (5,  73), (5,  74),
1455    (5,  75), (5,  76), (5,  77), (5,  78), (5,  79), (5,  80), (6,  10), (5,  81),
1456    (5,  82), (5,  83), (5,  84), (5,  85), (5,  86), (5,  87), (5,  88), (6,  11),
1457    (5,  89), (5,  90), (5,  91), (5,  92), (5,  93), (5,  94), (5,  95), (5,  96),
1458    (6,  12), (5,  97), (5,  98), (5,  99), (5, 100), (5, 101), (5, 102), (5, 103),
1459    (5, 104), (6,  13), (5, 105), (5, 106), (5, 107), (5, 108), (5, 109), (5, 110),
1460    (5, 111), (5, 112), (6,  14), (5, 113), (5, 114), (5, 115), (5, 116), (5, 117),
1461    (5, 118), (5, 119), (5, 120), (6,  15), (5, 121), (5, 122), (5, 123), (5, 124),
1462    (5, 125), (5, 126), (5, 127), (5, 128), (6,  16), (7,   2), (5, 129), (5, 130),
1463    (5, 131), (5, 132), (5, 133), (5, 134), (5, 135), (5, 136), (6,  17), (5, 137),
1464    (5, 138), (5, 139), (5, 140), (5, 141), (5, 142), (5, 143), (5, 144), (6,  18),
1465    (5, 145), (5, 146), (5, 147), (5, 148), (5, 149), (5, 150), (5, 151), (5, 152),
1466    (6,  19), (5, 153), (5, 154), (5, 155), (5, 156), (5, 157), (5, 158), (5, 159),
1467    (5, 160), (6,  20), (5, 161), (5, 162), (5, 163), (5, 164), (5, 165), (5, 166),
1468    (5, 167), (5, 168), (6,  21), (5, 169), (5, 170), (5, 171), (5, 172), (5, 173),
1469    (5, 174), (5, 175), (5, 176), (6,  22), (5, 177), (5, 178), (5, 179), (5, 180),
1470    (5, 181), (5, 182), (5, 183), (5, 184), (6,  23), (5, 185), (5, 186), (5, 187),
1471    (5, 188), (5, 189), (5, 190), (5, 191), (5, 192), (6,  24), (7,   3), (5, 193),
1472    (5, 194), (5, 195), (5, 196), (5, 197), (5, 198), (5, 199), (5, 200), (6,  25),
1473    (5, 201), (5, 202), (5, 203), (5, 204), (5, 205), (5, 206), (5, 207), (5, 208),
1474    (6,  26), (5, 209), (5, 210), (5, 211), (5, 212), (5, 213), (5, 214), (5, 215),
1475    (5, 216), (6,  27), (5, 217), (5, 218), (5, 219), (5, 220), (5, 221), (5, 222),
1476    (5, 223), (5, 224), (6,  28), (5, 225), (5, 226), (5, 227), (5, 228), (5, 229),
1477    (5, 230), (5, 231), (5, 232), (6,  29), (5, 233), (5, 234), (5, 235), (5, 236),
1478    (5, 237), (5, 238), (5, 239), (5, 240), (6,  30), (5, 241), (5, 242), (5, 243),
1479    (5, 244), (5, 245), (5, 246), (5, 247), (5, 248), (6,  31), (5, 249), (5, 250),
1480    (5, 251), (5, 252), (5, 253), (5, 254), (5, 255), (6,  32), (7,   4), (6,  33),
1481    (6,  34), (6,  35), (6,  36), (6,  37), (6,  38), (6,  39), (6,  40), (7,   5),
1482    (6,  41), (6,  42), (6,  43), (6,  44), (6,  45), (6,  46), (6,  47), (6,  48),
1483    (7,   6), (6,  49), (6,  50), (6,  51), (6,  52), (6,  53), (6,  54), (6,  55),
1484    (6,  56), (7,   7), (6,  57), (6,  58), (6,  59), (6,  60), (6,  61), (6,  62),
1485    (6,  63), (6,  64), (7,   8), (6,  65), (6,  66), (6,  67), (6,  68), (6,  69),
1486    (6,  70), (6,  71), (6,  72), (7,   9), (6,  73), (6,  74), (6,  75), (6,  76),
1487    (6,  77), (6,  78), (6,  79), (6,  80), (7,  10), (6,  81), (6,  82), (6,  83),
1488    (6,  84), (6,  85), (6,  86), (6,  87), (6,  88), (7,  11), (6,  89), (6,  90),
1489    (6,  91), (6,  92), (6,  93), (6,  94), (6,  95), (6,  96), (7,  12), (6,  97),
1490    (6,  98), (6,  99), (6, 100), (6, 101), (6, 102), (6, 103), (6, 104), (7,  13),
1491    (6, 105), (6, 106), (6, 107), (6, 108), (6, 109), (6, 110), (6, 111), (6, 112),
1492    (7,  14), (6, 113), (6, 114), (6, 115), (6, 116), (6, 117), (6, 118), (6, 119),
1493    (6, 120), (7,  15), (6, 121), (6, 122), (6, 123), (6, 124), (6, 125), (6, 126),
1494    (6, 127), (6, 128), (7,  16), (6, 129), (6, 130), (6, 131), (6, 132), (6, 133),
1495    (6, 134), (6, 135), (6, 136), (7,  17), (6, 137), (6, 138), (6, 139), (6, 140),
1496    (6, 141), (6, 142), (6, 143), (6, 144), (7,  18), (6, 145), (6, 146), (6, 147),
1497    (6, 148), (6, 149), (6, 150), (6, 151), (6, 152), (7,  19), (6, 153), (6, 154),
1498    (6, 155), (6, 156), (6, 157), (6, 158), (6, 159), (6, 160), (7,  20), (6, 161),
1499    (6, 162), (6, 163), (6, 164), (6, 165), (6, 166), (6, 167), (6, 168), (7,  21),
1500    (6, 169), (6, 170), (6, 171), (6, 172), (6, 173), (6, 174), (6, 175), (6, 176),
1501    (7,  22), (6, 177), (6, 178), (6, 179), (6, 180), (6, 181), (6, 182), (6, 183),
1502    (6, 184), (7,  23), (6, 185), (6, 186), (6, 187), (6, 188), (6, 189), (6, 190),
1503    (6, 191), (6, 192), (7,  24), (6, 193), (6, 194), (6, 195), (6, 196), (6, 197),
1504    (6, 198), (6, 199), (6, 200), (7,  25), (6, 201), (6, 202), (6, 203), (6, 204),
1505    (6, 205), (6, 206), (6, 207), (6, 208), (7,  26), (6, 209), (6, 210), (6, 211),
1506    (6, 212), (6, 213), (6, 214), (6, 215), (6, 216), (7,  27), (6, 217), (6, 218),
1507    (6, 219), (6, 220), (6, 221), (6, 222), (6, 223), (6, 224), (7,  28), (6, 225),
1508    (6, 226), (6, 227), (6, 228), (6, 229), (6, 230), (6, 231), (6, 232), (7,  29),
1509    (6, 233), (6, 234), (6, 235), (6, 236), (6, 237), (6, 238), (6, 239), (6, 240),
1510    (7,  30), (6, 241), (6, 242), (6, 243), (6, 244), (6, 245), (6, 246), (6, 247),
1511    (6, 248), (7,  31), (6, 249), (6, 250), (6, 251), (6, 252), (6, 253), (6, 254),
1512    (6, 255), (7,  32), (7,  33), (7,  34), (7,  35), (7,  36), (7,  37), (7,  38),
1513    (7,  39), (7,  40), (7,  41), (7,  42), (7,  43), (7,  44), (7,  45), (7,  46),
1514    (7,  47), (7,  48), (7,  49), (7,  50), (7,  51), (7,  52), (7,  53), (7,  54),
1515    (7,  55), (7,  56), (7,  57), (7,  58), (7,  59), (7,  60), (7,  61), (7,  62),
1516    (7,  63), (7,  64), (7,  65), (7,  66), (7,  67), (7,  68), (7,  69), (7,  70),
1517    (7,  71), (7,  72), (7,  73), (7,  74), (7,  75), (7,  76), (7,  77), (7,  78),
1518    (7,  79), (7,  80), (7,  81), (7,  82), (7,  83), (7,  84), (7,  85), (7,  86),
1519    (7,  87), (7,  88), (7,  89), (7,  90), (7,  91), (7,  92), (7,  93), (7,  94),
1520    (7,  95), (7,  96), (7,  97), (7,  98), (7,  99), (7, 100), (7, 101), (7, 102),
1521    (7, 103), (7, 104), (7, 105), (7, 106), (7, 107), (7, 108), (7, 109), (7, 110),
1522    (7, 111), (7, 112), (7, 113), (7, 114), (7, 115), (7, 116), (7, 117), (7, 118),
1523    (7, 119), (7, 120), (7, 121), (7, 122), (7, 123), (7, 124), (7, 125), (7, 126),
1524    (7, 127), (7, 128), (7, 129), (7, 130), (7, 131), (7, 132), (7, 133), (7, 134),
1525    (7, 135), (7, 136), (7, 137), (7, 138), (7, 139), (7, 140), (7, 141), (7, 142),
1526    (7, 143), (7, 144), (7, 145), (7, 146), (7, 147), (7, 148), (7, 149), (7, 150),
1527    (7, 151), (7, 152), (7, 153), (7, 154), (7, 155), (7, 156), (7, 157), (7, 158),
1528    (7, 159), (7, 160), (7, 161), (7, 162), (7, 163), (7, 164), (7, 165), (7, 166),
1529    (7, 167), (7, 168), (7, 169), (7, 170), (7, 171), (7, 172), (7, 173), (7, 174),
1530    (7, 175), (7, 176), (7, 177), (7, 178), (7, 179), (7, 180), (7, 181), (7, 182),
1531    (7, 183), (7, 184), (7, 185), (7, 186), (7, 187), (7, 188), (7, 189), (7, 190),
1532    (7, 191), (7, 192), (7, 193), (7, 194), (7, 195), (7, 196), (7, 197), (7, 198),
1533    (7, 199), (7, 200), (7, 201), (7, 202), (7, 203), (7, 204), (7, 205), (7, 206),
1534    (7, 207), (7, 208), (7, 209), (7, 210), (7, 211), (7, 212), (7, 213), (7, 214),
1535    (7, 215), (7, 216), (7, 217), (7, 218), (7, 219), (7, 220), (7, 221), (7, 222),
1536    (7, 223), (7, 224), (7, 225), (7, 226), (7, 227), (7, 228), (7, 229), (7, 230),
1537    (7, 231), (7, 232), (7, 233), (7, 234), (7, 235), (7, 236), (7, 237), (7, 238),
1538    (7, 239), (7, 240), (7, 241), (7, 242), (7, 243), (7, 244), (7, 245), (7, 246),
1539    (7, 247), (7, 248), (7, 249), (7, 250), (7, 251), (7, 252), (7, 253), (7, 254),
1540    (7, 255),
1541];