Skip to main content

neuromorphic_drivers/adapters/
evt3.rs

1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2pub struct State {
3    pub t: u64,
4    pub overflows: u32,
5    pub previous_msb_t: u16,
6    pub previous_lsb_t: u16,
7    pub x: u16,
8    pub y: u16,
9    pub polarity: neuromorphic_types::Polarity,
10}
11
12pub struct Adapter {
13    width: u16,
14    height: u16,
15    state: State,
16}
17
18#[derive(Default)]
19pub struct EventsLengths {
20    pub on: usize,
21    pub off: usize,
22    pub trigger_rising: usize,
23    pub trigger_falling: usize,
24}
25
26impl Adapter {
27    pub fn from_dimensions(width: u16, height: u16) -> Self {
28        Self {
29            width,
30            height,
31            state: State {
32                t: 0,
33                overflows: 0,
34                previous_msb_t: 0,
35                previous_lsb_t: 0,
36                x: 0,
37                y: 0,
38                polarity: neuromorphic_types::Polarity::Off,
39            },
40        }
41    }
42
43    pub fn from_dimensions_and_state(width: u16, height: u16, state: State) -> Self {
44        Self {
45            width,
46            height,
47            state,
48        }
49    }
50
51    pub fn width(&self) -> u16 {
52        self.width
53    }
54
55    pub fn height(&self) -> u16 {
56        self.height
57    }
58
59    pub fn state(&self) -> &State {
60        &self.state
61    }
62
63    pub fn current_t(&self) -> u64 {
64        self.state.t
65    }
66
67    pub fn events_lengths(&self, slice: &[u8]) -> EventsLengths {
68        let mut lengths = EventsLengths::default();
69        let mut x = self.state.x;
70        let mut y = self.state.y;
71        let mut polarity = self.state.polarity;
72        for index in 0..slice.len() / 2 {
73            let word = u16::from_le_bytes([slice[index * 2], slice[index * 2 + 1]]);
74            match word >> 12 {
75                0b0000 => {
76                    y = word & 0b11111111111;
77                }
78                0b0001 => (),
79                0b0010 => {
80                    x = word & 0b11111111111;
81                    polarity = if (word & (1 << 11)) > 0 {
82                        neuromorphic_types::Polarity::On
83                    } else {
84                        neuromorphic_types::Polarity::Off
85                    };
86                    if x < self.width && y < self.height {
87                        match polarity {
88                            neuromorphic_types::Polarity::On => {
89                                lengths.on += 1;
90                            }
91                            neuromorphic_types::Polarity::Off => {
92                                lengths.off += 1;
93                            }
94                        }
95                    }
96                }
97                0b0011 => {
98                    x = word & 0b11111111111;
99                    polarity = if (word & (1 << 11)) > 0 {
100                        neuromorphic_types::Polarity::On
101                    } else {
102                        neuromorphic_types::Polarity::Off
103                    };
104                }
105                0b0100 => {
106                    if x < self.width && y < self.height {
107                        match polarity {
108                            neuromorphic_types::Polarity::On => {
109                                lengths.on +=
110                                    (word & ((1 << std::cmp::min(12, self.width - x)) - 1))
111                                        .count_ones() as usize;
112                            }
113                            neuromorphic_types::Polarity::Off => {
114                                lengths.off +=
115                                    (word & ((1 << std::cmp::min(12, self.width - x)) - 1))
116                                        .count_ones() as usize;
117                            }
118                        }
119                        x = x.overflowing_add(12).0;
120                    }
121                }
122                0b0101 => {
123                    if x < self.width && y < self.height {
124                        match polarity {
125                            neuromorphic_types::Polarity::On => {
126                                lengths.on += (word & ((1 << std::cmp::min(8, self.width - x)) - 1))
127                                    .count_ones()
128                                    as usize;
129                            }
130                            neuromorphic_types::Polarity::Off => {
131                                lengths.off +=
132                                    (word & ((1 << std::cmp::min(8, self.width - x)) - 1))
133                                        .count_ones() as usize;
134                            }
135                        }
136                        x = x.overflowing_add(8).0;
137                    }
138                }
139                0b1010 => {
140                    if (word & 1) > 0 {
141                        lengths.trigger_rising += 1;
142                    } else {
143                        lengths.trigger_falling += 1;
144                    }
145                }
146                _ => (),
147            }
148        }
149        lengths
150    }
151
152    pub fn events_lengths_until(
153        &mut self,
154        slice: &[u8],
155        threshold_t: u64,
156    ) -> (EventsLengths, usize) {
157        let mut lengths = EventsLengths::default();
158        let mut index = 0;
159        while index < slice.len() / 2 {
160            let word = u16::from_le_bytes([slice[index * 2], slice[index * 2 + 1]]);
161            index += 1;
162            match word >> 12 {
163                0b0000 => {
164                    self.state.y = word & 0b11111111111;
165                }
166                0b0001 => (),
167                0b0010 => {
168                    self.state.x = word & 0b11111111111;
169                    self.state.polarity = if (word & (1 << 11)) > 0 {
170                        neuromorphic_types::Polarity::On
171                    } else {
172                        neuromorphic_types::Polarity::Off
173                    };
174                    if self.state.x < self.width && self.state.y < self.height {
175                        match self.state.polarity {
176                            neuromorphic_types::Polarity::On => {
177                                lengths.on += 1;
178                            }
179                            neuromorphic_types::Polarity::Off => {
180                                lengths.off += 1;
181                            }
182                        }
183                    }
184                }
185                0b0011 => {
186                    self.state.x = word & 0b11111111111;
187                    self.state.polarity = if (word & (1 << 11)) > 0 {
188                        neuromorphic_types::Polarity::On
189                    } else {
190                        neuromorphic_types::Polarity::Off
191                    };
192                }
193                0b0100 => {
194                    if self.state.x < self.width && self.state.y < self.height {
195                        match self.state.polarity {
196                            neuromorphic_types::Polarity::On => {
197                                lengths.on += (word
198                                    & ((1 << std::cmp::min(12, self.width - self.state.x)) - 1))
199                                    .count_ones()
200                                    as usize;
201                            }
202                            neuromorphic_types::Polarity::Off => {
203                                lengths.off += (word
204                                    & ((1 << std::cmp::min(12, self.width - self.state.x)) - 1))
205                                    .count_ones()
206                                    as usize;
207                            }
208                        }
209                        self.state.x = self.state.x.overflowing_add(12).0;
210                    }
211                }
212                0b0101 => {
213                    if self.state.x < self.width && self.state.y < self.height {
214                        match self.state.polarity {
215                            neuromorphic_types::Polarity::On => {
216                                lengths.on += (word
217                                    & ((1 << std::cmp::min(8, self.width - self.state.x)) - 1))
218                                    .count_ones()
219                                    as usize;
220                            }
221                            neuromorphic_types::Polarity::Off => {
222                                lengths.off += (word
223                                    & ((1 << std::cmp::min(8, self.width - self.state.x)) - 1))
224                                    .count_ones()
225                                    as usize;
226                            }
227                        }
228                        self.state.x = self.state.x.overflowing_add(8).0;
229                    }
230                }
231                0b0110 => {
232                    let lsb_t = word & 0b111111111111;
233                    if lsb_t != self.state.previous_lsb_t {
234                        self.state.previous_lsb_t = lsb_t;
235                        let t = (((self.state.previous_lsb_t as u32)
236                            | ((self.state.previous_msb_t as u32) << 12))
237                            as u64)
238                            | ((self.state.overflows as u64) << 24);
239                        if t >= self.state.t {
240                            self.state.t = t;
241                            if self.state.t >= threshold_t {
242                                break;
243                            }
244                        }
245                    }
246                }
247                0b0111 => (),
248                0b1000 => {
249                    let msb_t = word & 0b111111111111;
250                    if msb_t != self.state.previous_msb_t {
251                        if msb_t > self.state.previous_msb_t {
252                            if (msb_t - self.state.previous_msb_t) < (1 << 11) {
253                                self.state.previous_lsb_t = 0;
254                                self.state.previous_msb_t = msb_t;
255                            }
256                        } else if (self.state.previous_msb_t - msb_t) > (1 << 11) {
257                            self.state.overflows += 1;
258                            self.state.previous_lsb_t = 0;
259                            self.state.previous_msb_t = msb_t;
260                        }
261                        let t = (((self.state.previous_lsb_t as u32)
262                            | ((self.state.previous_msb_t as u32) << 12))
263                            as u64)
264                            | ((self.state.overflows as u64) << 24);
265                        if t >= self.state.t {
266                            self.state.t = t;
267                            if self.state.t >= threshold_t {
268                                break;
269                            }
270                        }
271                    }
272                }
273                0b1001 => (),
274                0b1010 => {
275                    if (word & 1) > 0 {
276                        lengths.trigger_rising += 1;
277                    } else {
278                        lengths.trigger_falling += 1;
279                    }
280                }
281                #[allow(clippy::manual_range_patterns)]
282                0b1011 | 0b1100 | 0b1101 | 0b1110 | 0b1111 => (),
283                _ => (),
284            }
285        }
286        (lengths, index * 2)
287    }
288
289    pub fn convert<HandlePolarityEvent, HandleTriggerEvent>(
290        &mut self,
291        slice: &[u8],
292        mut handle_polarity_event: HandlePolarityEvent,
293        mut handle_trigger_event: HandleTriggerEvent,
294    ) where
295        HandlePolarityEvent: FnMut(neuromorphic_types::PolarityEvent<u64, u16, u16>),
296        HandleTriggerEvent: FnMut(neuromorphic_types::TriggerEvent<u64, u8>),
297    {
298        for index in 0..slice.len() / 2 {
299            let word = u16::from_le_bytes([slice[index * 2], slice[index * 2 + 1]]);
300            match word >> 12 {
301                0b0000 => {
302                    self.state.y = word & 0b11111111111;
303                }
304                0b0001 => (),
305                0b0010 => {
306                    self.state.x = word & 0b11111111111;
307                    self.state.polarity = if (word & (1 << 11)) > 0 {
308                        neuromorphic_types::Polarity::On
309                    } else {
310                        neuromorphic_types::Polarity::Off
311                    };
312                    if self.state.x < self.width && self.state.y < self.height {
313                        handle_polarity_event(neuromorphic_types::PolarityEvent {
314                            t: self.state.t,
315                            x: self.state.x,
316                            y: self.state.y,
317                            polarity: self.state.polarity,
318                        });
319                    }
320                }
321                0b0011 => {
322                    self.state.x = word & 0b11111111111;
323                    self.state.polarity = if (word & (1 << 11)) > 0 {
324                        neuromorphic_types::Polarity::On
325                    } else {
326                        neuromorphic_types::Polarity::Off
327                    };
328                }
329                0b0100 => {
330                    if self.state.x < self.width && self.state.y < self.height {
331                        let set = word & ((1 << std::cmp::min(12, self.width - self.state.x)) - 1);
332                        for bit in 0..12 {
333                            if (set & (1 << bit)) > 0 {
334                                handle_polarity_event(neuromorphic_types::PolarityEvent {
335                                    t: self.state.t,
336                                    x: self.state.x + bit,
337                                    y: self.state.y,
338                                    polarity: self.state.polarity,
339                                });
340                            }
341                        }
342                        self.state.x = self.state.x.overflowing_add(12).0;
343                    }
344                }
345                0b0101 => {
346                    if self.state.x < self.width && self.state.y < self.height {
347                        let set = word & ((1 << std::cmp::min(8, self.width - self.state.x)) - 1);
348                        for bit in 0..8 {
349                            if (set & (1 << bit)) > 0 {
350                                handle_polarity_event(neuromorphic_types::PolarityEvent {
351                                    t: self.state.t,
352                                    x: self.state.x + bit,
353                                    y: self.state.y,
354                                    polarity: self.state.polarity,
355                                });
356                            }
357                        }
358                        self.state.x = self.state.x.overflowing_add(8).0;
359                    }
360                }
361                0b0110 => {
362                    let lsb_t = word & 0b111111111111;
363                    if lsb_t != self.state.previous_lsb_t {
364                        self.state.previous_lsb_t = lsb_t;
365                        let t = (((self.state.previous_lsb_t as u32)
366                            | ((self.state.previous_msb_t as u32) << 12))
367                            as u64)
368                            | ((self.state.overflows as u64) << 24);
369                        if t >= self.state.t {
370                            self.state.t = t;
371                        }
372                    }
373                }
374                0b0111 => (),
375                0b1000 => {
376                    let msb_t = word & 0b111111111111;
377                    if msb_t != self.state.previous_msb_t {
378                        if msb_t > self.state.previous_msb_t {
379                            if (msb_t - self.state.previous_msb_t) < (1 << 11) {
380                                self.state.previous_lsb_t = 0;
381                                self.state.previous_msb_t = msb_t;
382                            }
383                        } else if (self.state.previous_msb_t - msb_t) > (1 << 11) {
384                            self.state.overflows += 1;
385                            self.state.previous_lsb_t = 0;
386                            self.state.previous_msb_t = msb_t;
387                        }
388                        let t = (((self.state.previous_lsb_t as u32)
389                            | ((self.state.previous_msb_t as u32) << 12))
390                            as u64)
391                            | ((self.state.overflows as u64) << 24);
392                        if t >= self.state.t {
393                            self.state.t = t;
394                        }
395                    }
396                }
397                0b1001 => (),
398                0b1010 => handle_trigger_event(neuromorphic_types::TriggerEvent {
399                    t: self.state.t,
400                    id: ((word >> 8) & 0b1111) as u8,
401                    polarity: if (word & 1) > 0 {
402                        neuromorphic_types::TriggerPolarity::Rising
403                    } else {
404                        neuromorphic_types::TriggerPolarity::Falling
405                    },
406                }),
407                #[allow(clippy::manual_range_patterns)]
408                0b1011 | 0b1100 | 0b1101 | 0b1110 | 0b1111 => (),
409                _ => (),
410            }
411        }
412    }
413}