aboutsummaryrefslogtreecommitdiff
path: root/embassy-mcxa/src/crc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-mcxa/src/crc.rs')
-rw-r--r--embassy-mcxa/src/crc.rs758
1 files changed, 758 insertions, 0 deletions
diff --git a/embassy-mcxa/src/crc.rs b/embassy-mcxa/src/crc.rs
new file mode 100644
index 000000000..753a59122
--- /dev/null
+++ b/embassy-mcxa/src/crc.rs
@@ -0,0 +1,758 @@
1//! Cyclic Redundancy Check (CRC)
2
3use core::marker::PhantomData;
4
5use embassy_hal_internal::Peri;
6use mcxa_pac::crc0::ctrl::{Fxor, Tcrc, Tot, Totr};
7
8use crate::clocks::enable_and_reset;
9use crate::clocks::periph_helpers::NoConfig;
10use crate::peripherals::CRC0;
11
12/// CRC driver.
13pub struct Crc<'d, M> {
14 _peri: Peri<'d, CRC0>,
15 _phantom: PhantomData<M>,
16}
17
18impl<'d, M: Mode> Crc<'d, M> {
19 fn new_inner(_peri: Peri<'d, CRC0>) -> Self {
20 _ = unsafe { enable_and_reset::<CRC0>(&NoConfig) };
21
22 Crc {
23 _peri,
24 _phantom: PhantomData,
25 }
26 }
27
28 // Configure the underlying peripheral according to the reference manual.
29 fn configure(config: Config, width: Tcrc) {
30 Self::regs().ctrl().modify(|_, w| {
31 w.fxor()
32 .variant(config.complement_out.into())
33 .totr()
34 .variant(config.reflect_out.into())
35 .tot()
36 .variant(config.reflect_in.into())
37 .was()
38 .data()
39 .tcrc()
40 .variant(width)
41 });
42
43 Self::regs().gpoly32().write(|w| unsafe { w.bits(config.polynomial) });
44
45 Self::regs().ctrl().modify(|_, w| w.was().seed());
46 Self::regs().data32().write(|w| unsafe { w.bits(config.seed) });
47 Self::regs().ctrl().modify(|_, w| w.was().data());
48 }
49
50 fn regs() -> &'static crate::pac::crc0::RegisterBlock {
51 unsafe { &*crate::pac::Crc0::ptr() }
52 }
53
54 /// Read the computed CRC value
55 fn finalize_inner<W: Word>(self) -> W {
56 // Reference manual states:
57 //
58 // "After writing all the data, you must wait for at least two
59 // clock cycles to read the data from CRC Data (DATA)
60 // register."
61 cortex_m::asm::delay(2);
62 W::read(Self::regs())
63 }
64
65 fn feed_word<W: Word>(&mut self, word: W) {
66 W::write(Self::regs(), word);
67 }
68
69 /// Feeds a slice of `Word`s into the CRC peripheral. Returns the computed
70 /// checksum.
71 ///
72 /// The input is strided efficiently into as many `u32`s as possible,
73 /// falling back to smaller writes for the remainder.
74 fn feed_inner<W: Word>(&mut self, data: &[W]) {
75 let (prefix, aligned, suffix) = unsafe { data.align_to::<u32>() };
76
77 for w in prefix {
78 self.feed_word(*w);
79 }
80
81 for w in aligned {
82 self.feed_word(*w);
83 }
84
85 for w in suffix {
86 self.feed_word(*w);
87 }
88 }
89}
90
91impl<'d> Crc<'d, Crc16> {
92 /// Instantiates a new CRC peripheral driver in 16-bit mode
93 pub fn new_crc16(peri: Peri<'d, CRC0>, config: Config) -> Self {
94 let inst = Self::new_inner(peri);
95 Self::configure(config, Tcrc::B16);
96 inst
97 }
98
99 /// Instantiates a new CRC peripheral driver for the given `Algorithm16`.
100 pub fn new_algorithm16(peri: Peri<'d, CRC0>, algorithm: Algorithm16) -> Self {
101 Self::new_crc16(peri, algorithm.into_config())
102 }
103
104 /// Instantiates a new CRC peripheral for the `A` algorithm.
105 pub fn new_a(peri: Peri<'d, CRC0>) -> Self {
106 Self::new_algorithm16(peri, Algorithm16::A)
107 }
108
109 /// Instantiates a new CRC peripheral for the `AugCcitt` algorithm.
110 pub fn new_aug_ccitt(peri: Peri<'d, CRC0>) -> Self {
111 Self::new_algorithm16(peri, Algorithm16::AugCcitt)
112 }
113
114 /// Instantiates a new CRC peripheral for the `Arc` algorithm.
115 pub fn new_arc(peri: Peri<'d, CRC0>) -> Self {
116 Self::new_algorithm16(peri, Algorithm16::Arc)
117 }
118
119 /// Instantiates a new CRC peripheral for the `Buypass` algorithm.
120 pub fn new_buypass(peri: Peri<'d, CRC0>) -> Self {
121 Self::new_algorithm16(peri, Algorithm16::Buypass)
122 }
123
124 /// Instantiates a new CRC peripheral for the `CcittFalse` algorithm.
125 pub fn new_ccitt_false(peri: Peri<'d, CRC0>) -> Self {
126 Self::new_algorithm16(peri, Algorithm16::CcittFalse)
127 }
128
129 /// Instantiates a new CRC peripheral for the `CcittZero` algorithm.
130 pub fn new_ccitt_zero(peri: Peri<'d, CRC0>) -> Self {
131 Self::new_algorithm16(peri, Algorithm16::CcittZero)
132 }
133
134 /// Instantiates a new CRC peripheral for the `Cdma2000` algorithm.
135 pub fn new_cdma_2000(peri: Peri<'d, CRC0>) -> Self {
136 Self::new_algorithm16(peri, Algorithm16::Cdma2000)
137 }
138
139 /// Instantiates a new CRC peripheral for the `Dds110` algorithm.
140 pub fn new_dds_110(peri: Peri<'d, CRC0>) -> Self {
141 Self::new_algorithm16(peri, Algorithm16::Dds110)
142 }
143
144 /// Instantiates a new CRC peripheral for the `DectX` algorithm.
145 pub fn new_dect_x(peri: Peri<'d, CRC0>) -> Self {
146 Self::new_algorithm16(peri, Algorithm16::DectX)
147 }
148
149 /// Instantiates a new CRC peripheral for the `Dnp` algorithm.
150 pub fn new_dnp(peri: Peri<'d, CRC0>) -> Self {
151 Self::new_algorithm16(peri, Algorithm16::Dnp)
152 }
153
154 /// Instantiates a new CRC peripheral for the `En13757` algorithm.
155 pub fn new_en13757(peri: Peri<'d, CRC0>) -> Self {
156 Self::new_algorithm16(peri, Algorithm16::En13757)
157 }
158
159 /// Instantiates a new CRC peripheral for the `Genibus` algorithm.
160 pub fn new_genibus(peri: Peri<'d, CRC0>) -> Self {
161 Self::new_algorithm16(peri, Algorithm16::Genibus)
162 }
163
164 /// Instantiates a new CRC peripheral for the `Kermit` algorithm.
165 pub fn new_kermit(peri: Peri<'d, CRC0>) -> Self {
166 Self::new_algorithm16(peri, Algorithm16::Kermit)
167 }
168
169 /// Instantiates a new CRC peripheral for the `Maxim` algorithm.
170 pub fn new_maxim(peri: Peri<'d, CRC0>) -> Self {
171 Self::new_algorithm16(peri, Algorithm16::Maxim)
172 }
173
174 /// Instantiates a new CRC peripheral for the `Mcrf4xx` algorithm.
175 pub fn new_mcrf4xx(peri: Peri<'d, CRC0>) -> Self {
176 Self::new_algorithm16(peri, Algorithm16::Mcrf4xx)
177 }
178
179 /// Instantiates a new CRC peripheral for the `Modbus` algorithm.
180 pub fn new_modbus(peri: Peri<'d, CRC0>) -> Self {
181 Self::new_algorithm16(peri, Algorithm16::Modbus)
182 }
183
184 /// Instantiates a new CRC peripheral for the `Riello` algorithm.
185 pub fn new_riello(peri: Peri<'d, CRC0>) -> Self {
186 Self::new_algorithm16(peri, Algorithm16::Riello)
187 }
188
189 /// Instantiates a new CRC peripheral for the `T10Dif` algorithm.
190 pub fn new_t10_dif(peri: Peri<'d, CRC0>) -> Self {
191 Self::new_algorithm16(peri, Algorithm16::T10Dif)
192 }
193
194 /// Instantiates a new CRC peripheral for the `Teledisk` algorithm.
195 pub fn new_teledisk(peri: Peri<'d, CRC0>) -> Self {
196 Self::new_algorithm16(peri, Algorithm16::Teledisk)
197 }
198
199 /// Instantiates a new CRC peripheral for the `Tms37157` algorithm.
200 pub fn new_tms_37157(peri: Peri<'d, CRC0>) -> Self {
201 Self::new_algorithm16(peri, Algorithm16::Tms37157)
202 }
203
204 /// Instantiates a new CRC peripheral for the `Usb` algorithm.
205 pub fn new_usb(peri: Peri<'d, CRC0>) -> Self {
206 Self::new_algorithm16(peri, Algorithm16::Usb)
207 }
208
209 /// Instantiates a new CRC peripheral for the `X25` algorithm.
210 pub fn new_x25(peri: Peri<'d, CRC0>) -> Self {
211 Self::new_algorithm16(peri, Algorithm16::X25)
212 }
213
214 /// Instantiates a new CRC peripheral for the `Xmodem` algorithm.
215 pub fn new_xmodem(peri: Peri<'d, CRC0>) -> Self {
216 Self::new_algorithm16(peri, Algorithm16::Xmodem)
217 }
218
219 /// Feeds a slice of `Word`s into the CRC peripheral.
220 ///
221 /// The input is strided efficiently into as many `u32`s as possible,
222 /// falling back to smaller writes for the remainder.
223 pub fn feed<W: Word>(&mut self, data: &[W]) {
224 self.feed_inner(data);
225 }
226
227 /// Finalizes the CRC calculation and reads the resulting CRC from the
228 /// hardware consuming `self`.
229 pub fn finalize(self) -> u16 {
230 self.finalize_inner()
231 }
232}
233
234impl<'d> Crc<'d, Crc32> {
235 /// Instantiates a new CRC peripheral driver in 32-bit mode
236 pub fn new_crc32(peri: Peri<'d, CRC0>, config: Config) -> Self {
237 let inst = Self::new_inner(peri);
238 Self::configure(config, Tcrc::B32);
239 inst
240 }
241
242 /// Instantiates a new CRC peripheral driver for the given `Algorithm32`.
243 pub fn new_algorithm32(peri: Peri<'d, CRC0>, algorithm: Algorithm32) -> Self {
244 Self::new_crc32(peri, algorithm.into_config())
245 }
246
247 /// Instantiates a new CRC peripheral for the `Bzip2` algorithm.
248 pub fn new_bzip2(peri: Peri<'d, CRC0>) -> Self {
249 Self::new_algorithm32(peri, Algorithm32::Bzip2)
250 }
251
252 /// Instantiates a new CRC peripheral for the `C` algorithm.
253 pub fn new_c(peri: Peri<'d, CRC0>) -> Self {
254 Self::new_algorithm32(peri, Algorithm32::C)
255 }
256
257 /// Instantiates a new CRC peripheral for the `D` algorithm.
258 pub fn new_d(peri: Peri<'d, CRC0>) -> Self {
259 Self::new_algorithm32(peri, Algorithm32::D)
260 }
261
262 /// Instantiates a new CRC peripheral for the `IsoHdlc` algorithm.
263 pub fn new_iso_hdlc(peri: Peri<'d, CRC0>) -> Self {
264 Self::new_algorithm32(peri, Algorithm32::IsoHdlc)
265 }
266
267 /// Instantiates a new CRC peripheral for the `JamCrc` algorithm.
268 pub fn new_jam_crc(peri: Peri<'d, CRC0>) -> Self {
269 Self::new_algorithm32(peri, Algorithm32::JamCrc)
270 }
271
272 /// Instantiates a new CRC peripheral for the `Mpeg2` algorithm.
273 pub fn new_mpeg2(peri: Peri<'d, CRC0>) -> Self {
274 Self::new_algorithm32(peri, Algorithm32::Mpeg2)
275 }
276
277 /// Instantiates a new CRC peripheral for the `Posix` algorithm.
278 pub fn new_posix(peri: Peri<'d, CRC0>) -> Self {
279 Self::new_algorithm32(peri, Algorithm32::Posix)
280 }
281
282 /// Instantiates a new CRC peripheral for the `Q` algorithm.
283 pub fn new_q(peri: Peri<'d, CRC0>) -> Self {
284 Self::new_algorithm32(peri, Algorithm32::Q)
285 }
286
287 /// Instantiates a new CRC peripheral for the `Xfer` algorithm.
288 pub fn new_xfer(peri: Peri<'d, CRC0>) -> Self {
289 Self::new_algorithm32(peri, Algorithm32::Xfer)
290 }
291
292 /// Feeds a slice of `Word`s into the CRC peripheral.
293 ///
294 /// The input is strided efficiently into as many `u32`s as possible,
295 /// falling back to smaller writes for the remainder.
296 pub fn feed<W: Word>(&mut self, data: &[W]) {
297 self.feed_inner(data);
298 }
299
300 /// Finalizes the CRC calculation and reads the resulting CRC from the
301 /// hardware consuming `self`.
302 pub fn finalize(self) -> u32 {
303 self.finalize_inner()
304 }
305}
306
307mod sealed {
308 pub trait SealedMode {}
309
310 pub trait SealedWord: Copy {
311 fn write(regs: &'static crate::pac::crc0::RegisterBlock, word: Self);
312 fn read(regs: &'static crate::pac::crc0::RegisterBlock) -> Self;
313 }
314}
315
316/// Mode of operation: 32 or 16-bit CRC.
317#[allow(private_bounds)]
318pub trait Mode: sealed::SealedMode {}
319
320/// 16-bit CRC.
321pub struct Crc16;
322impl sealed::SealedMode for Crc16 {}
323impl Mode for Crc16 {}
324
325/// 32-bit CRC.
326pub struct Crc32;
327impl sealed::SealedMode for Crc32 {}
328impl Mode for Crc32 {}
329
330/// Word size for the CRC.
331#[allow(private_bounds)]
332pub trait Word: sealed::SealedWord {}
333
334macro_rules! impl_word {
335 ($t:ty, $width:literal, $write:expr, $read:expr) => {
336 impl sealed::SealedWord for $t {
337 #[inline]
338 fn write(regs: &'static crate::pac::crc0::RegisterBlock, word: Self) {
339 $write(regs, word)
340 }
341
342 #[inline]
343 fn read(regs: &'static crate::pac::crc0::RegisterBlock) -> Self {
344 $read(regs)
345 }
346 }
347
348 impl Word for $t {}
349 };
350}
351
352impl_word!(u8, 8, write_u8, read_u8);
353impl_word!(u16, 16, write_u16, read_u16);
354impl_word!(u32, 32, write_u32, read_u32);
355
356fn write_u8(regs: &'static crate::pac::crc0::RegisterBlock, word: u8) {
357 regs.data8().write(|w| unsafe { w.bits(word) });
358}
359
360fn read_u8(regs: &'static crate::pac::crc0::RegisterBlock) -> u8 {
361 regs.data8().read().bits()
362}
363
364fn write_u16(regs: &'static crate::pac::crc0::RegisterBlock, word: u16) {
365 regs.data16().write(|w| unsafe { w.bits(word) });
366}
367
368fn read_u16(regs: &'static crate::pac::crc0::RegisterBlock) -> u16 {
369 let ctrl = regs.ctrl().read();
370
371 // if transposition is enabled, result sits in the upper 16 bits
372 if ctrl.totr().is_byts_trnps() || ctrl.totr().is_byts_bts_trnps() {
373 (regs.data32().read().bits() >> 16) as u16
374 } else {
375 regs.data16().read().bits()
376 }
377}
378
379fn write_u32(regs: &'static crate::pac::crc0::RegisterBlock, word: u32) {
380 regs.data32().write(|w| unsafe { w.bits(word) });
381}
382
383fn read_u32(regs: &'static crate::pac::crc0::RegisterBlock) -> u32 {
384 regs.data32().read().bits()
385}
386
387/// CRC configuration.
388#[derive(Copy, Clone, Debug)]
389#[non_exhaustive]
390pub struct Config {
391 /// The CRC polynomial to be used.
392 pub polynomial: u32,
393
394 /// Reflect bit order of input?
395 pub reflect_in: Reflect,
396
397 /// Reflect CRC bit order?
398 pub reflect_out: Reflect,
399
400 /// 1's complement CRC?
401 pub complement_out: Complement,
402
403 /// CRC Seed
404 pub seed: u32,
405}
406
407impl Config {
408 /// Create a new CRC config.
409 #[must_use]
410 pub fn new(
411 polynomial: u32,
412 reflect_in: Reflect,
413 reflect_out: Reflect,
414 complement_out: Complement,
415 seed: u32,
416 ) -> Self {
417 Config {
418 polynomial,
419 reflect_in,
420 reflect_out,
421 complement_out,
422 seed,
423 }
424 }
425}
426
427impl Default for Config {
428 fn default() -> Self {
429 Self {
430 polynomial: 0,
431 reflect_in: Reflect::No,
432 reflect_out: Reflect::No,
433 complement_out: Complement::No,
434 seed: 0xffff_ffff,
435 }
436 }
437}
438
439/// Supported standard CRC16 algorithms.
440#[derive(Copy, Clone, Debug)]
441pub enum Algorithm16 {
442 A,
443 Arc,
444 AugCcitt,
445 Buypass,
446 CcittFalse,
447 CcittZero,
448 Cdma2000,
449 Dds110,
450 DectX,
451 Dnp,
452 En13757,
453 Genibus,
454 Kermit,
455 Maxim,
456 Mcrf4xx,
457 Modbus,
458 Riello,
459 T10Dif,
460 Teledisk,
461 Tms37157,
462 Usb,
463 X25,
464 Xmodem,
465}
466
467impl Algorithm16 {
468 fn into_config(self) -> Config {
469 match self {
470 Algorithm16::A => Config {
471 polynomial: 0x1021,
472 reflect_in: Reflect::Yes,
473 reflect_out: Reflect::Yes,
474 complement_out: Complement::No,
475 seed: 0xc6c6,
476 },
477 Algorithm16::Arc => Config {
478 polynomial: 0x8005,
479 reflect_in: Reflect::Yes,
480 reflect_out: Reflect::Yes,
481 complement_out: Complement::No,
482 seed: 0,
483 },
484 Algorithm16::AugCcitt => Config {
485 polynomial: 0x1021,
486 reflect_in: Reflect::No,
487 reflect_out: Reflect::No,
488 complement_out: Complement::No,
489 seed: 0x1d0f,
490 },
491 Algorithm16::Buypass => Config {
492 polynomial: 0x8005,
493 reflect_in: Reflect::No,
494 reflect_out: Reflect::No,
495 complement_out: Complement::No,
496 seed: 0,
497 },
498 Algorithm16::CcittFalse => Config {
499 polynomial: 0x1021,
500 reflect_in: Reflect::No,
501 reflect_out: Reflect::No,
502 complement_out: Complement::No,
503 seed: 0xffff,
504 },
505 Algorithm16::CcittZero => Config {
506 polynomial: 0x1021,
507 reflect_in: Reflect::No,
508 reflect_out: Reflect::No,
509 complement_out: Complement::No,
510 seed: 0,
511 },
512 Algorithm16::Cdma2000 => Config {
513 polynomial: 0xc867,
514 reflect_in: Reflect::No,
515 reflect_out: Reflect::No,
516 complement_out: Complement::No,
517 seed: 0xffff,
518 },
519 Algorithm16::Dds110 => Config {
520 polynomial: 0x8005,
521 reflect_in: Reflect::No,
522 reflect_out: Reflect::No,
523 complement_out: Complement::No,
524 seed: 0x800d,
525 },
526 Algorithm16::DectX => Config {
527 polynomial: 0x0589,
528 reflect_in: Reflect::No,
529 reflect_out: Reflect::No,
530 complement_out: Complement::No,
531 seed: 0,
532 },
533 Algorithm16::Dnp => Config {
534 polynomial: 0x3d65,
535 reflect_in: Reflect::Yes,
536 reflect_out: Reflect::Yes,
537 complement_out: Complement::Yes,
538 seed: 0,
539 },
540 Algorithm16::En13757 => Config {
541 polynomial: 0x3d65,
542 reflect_in: Reflect::No,
543 reflect_out: Reflect::No,
544 complement_out: Complement::Yes,
545 seed: 0,
546 },
547 Algorithm16::Genibus => Config {
548 polynomial: 0x1021,
549 reflect_in: Reflect::No,
550 reflect_out: Reflect::No,
551 complement_out: Complement::Yes,
552 seed: 0xffff,
553 },
554 Algorithm16::Kermit => Config {
555 polynomial: 0x1021,
556 reflect_in: Reflect::Yes,
557 reflect_out: Reflect::Yes,
558 complement_out: Complement::No,
559 seed: 0,
560 },
561 Algorithm16::Maxim => Config {
562 polynomial: 0x8005,
563 reflect_in: Reflect::Yes,
564 reflect_out: Reflect::Yes,
565 complement_out: Complement::Yes,
566 seed: 0,
567 },
568 Algorithm16::Mcrf4xx => Config {
569 polynomial: 0x1021,
570 reflect_in: Reflect::Yes,
571 reflect_out: Reflect::Yes,
572 complement_out: Complement::No,
573 seed: 0xffff,
574 },
575 Algorithm16::Modbus => Config {
576 polynomial: 0x8005,
577 reflect_in: Reflect::Yes,
578 reflect_out: Reflect::Yes,
579 complement_out: Complement::No,
580 seed: 0xffff,
581 },
582 Algorithm16::Riello => Config {
583 polynomial: 0x1021,
584 reflect_in: Reflect::Yes,
585 reflect_out: Reflect::Yes,
586 complement_out: Complement::No,
587 seed: 0xb2aa,
588 },
589 Algorithm16::T10Dif => Config {
590 polynomial: 0x8bb7,
591 reflect_in: Reflect::No,
592 reflect_out: Reflect::No,
593 complement_out: Complement::No,
594 seed: 0,
595 },
596 Algorithm16::Teledisk => Config {
597 polynomial: 0xa097,
598 reflect_in: Reflect::No,
599 reflect_out: Reflect::No,
600 complement_out: Complement::No,
601 seed: 0,
602 },
603 Algorithm16::Tms37157 => Config {
604 polynomial: 0x1021,
605 reflect_in: Reflect::Yes,
606 reflect_out: Reflect::Yes,
607 complement_out: Complement::No,
608 seed: 0x89ec,
609 },
610 Algorithm16::Usb => Config {
611 polynomial: 0x8005,
612 reflect_in: Reflect::Yes,
613 reflect_out: Reflect::Yes,
614 complement_out: Complement::No,
615 seed: 0xffff,
616 },
617 Algorithm16::X25 => Config {
618 polynomial: 0x1021,
619 reflect_in: Reflect::Yes,
620 reflect_out: Reflect::Yes,
621 complement_out: Complement::Yes,
622 seed: 0xffff,
623 },
624 Algorithm16::Xmodem => Config {
625 polynomial: 0x1021,
626 reflect_in: Reflect::No,
627 reflect_out: Reflect::No,
628 complement_out: Complement::No,
629 seed: 0,
630 },
631 }
632 }
633}
634
635/// Supported standard CRC32 algorithms.
636#[derive(Copy, Clone, Debug)]
637pub enum Algorithm32 {
638 Bzip2,
639 C,
640 D,
641 IsoHdlc,
642 JamCrc,
643 Mpeg2,
644 Posix,
645 Q,
646 Xfer,
647}
648
649impl Algorithm32 {
650 fn into_config(self) -> Config {
651 match self {
652 Algorithm32::Bzip2 => Config {
653 polynomial: 0x04c1_1db7,
654 reflect_in: Reflect::No,
655 reflect_out: Reflect::No,
656 complement_out: Complement::Yes,
657 seed: 0xffff_ffff,
658 },
659 Algorithm32::C => Config {
660 polynomial: 0x1edc_6f41,
661 reflect_in: Reflect::Yes,
662 reflect_out: Reflect::Yes,
663 complement_out: Complement::Yes,
664 seed: 0xffff_ffff,
665 },
666 Algorithm32::D => Config {
667 polynomial: 0xa833_982b,
668 reflect_in: Reflect::Yes,
669 reflect_out: Reflect::Yes,
670 complement_out: Complement::Yes,
671 seed: 0xffff_ffff,
672 },
673 Algorithm32::IsoHdlc => Config {
674 polynomial: 0x04c1_1db7,
675 reflect_in: Reflect::Yes,
676 reflect_out: Reflect::Yes,
677 complement_out: Complement::Yes,
678 seed: 0xffff_ffff,
679 },
680 Algorithm32::JamCrc => Config {
681 polynomial: 0x04c1_1db7,
682 reflect_in: Reflect::Yes,
683 reflect_out: Reflect::Yes,
684 complement_out: Complement::No,
685 seed: 0xffff_ffff,
686 },
687 Algorithm32::Mpeg2 => Config {
688 polynomial: 0x04c1_1db7,
689 reflect_in: Reflect::No,
690 reflect_out: Reflect::No,
691 complement_out: Complement::No,
692 seed: 0xffff_ffff,
693 },
694 Algorithm32::Posix => Config {
695 polynomial: 0x04c1_1db7,
696 reflect_in: Reflect::No,
697 reflect_out: Reflect::No,
698 complement_out: Complement::Yes,
699 seed: 0,
700 },
701 Algorithm32::Q => Config {
702 polynomial: 0x8141_41ab,
703 reflect_in: Reflect::No,
704 reflect_out: Reflect::No,
705 complement_out: Complement::No,
706 seed: 0,
707 },
708 Algorithm32::Xfer => Config {
709 polynomial: 0x0000_00af,
710 reflect_in: Reflect::No,
711 reflect_out: Reflect::No,
712 complement_out: Complement::No,
713 seed: 0,
714 },
715 }
716 }
717}
718
719/// Reflect bit order.
720#[derive(Copy, Clone, Debug)]
721pub enum Reflect {
722 No,
723 Yes,
724}
725
726impl From<Reflect> for Tot {
727 fn from(value: Reflect) -> Tot {
728 match value {
729 Reflect::No => Tot::BytsTrnps,
730 Reflect::Yes => Tot::BytsBtsTrnps,
731 }
732 }
733}
734
735impl From<Reflect> for Totr {
736 fn from(value: Reflect) -> Totr {
737 match value {
738 Reflect::No => Totr::Notrnps,
739 Reflect::Yes => Totr::BytsBtsTrnps,
740 }
741 }
742}
743
744/// 1's complement output.
745#[derive(Copy, Clone, Debug)]
746pub enum Complement {
747 No,
748 Yes,
749}
750
751impl From<Complement> for Fxor {
752 fn from(value: Complement) -> Fxor {
753 match value {
754 Complement::No => Fxor::Noxor,
755 Complement::Yes => Fxor::Invert,
756 }
757 }
758}